• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

naver / egjs-flicking / 7191752937

12 Dec 2023 09:07AM UTC coverage: 82.638%. Remained the same
7191752937

push

github

malangfox
chore(release): merge 4.11.2-rc

4533 of 7309 branches covered (0.0%)

Branch coverage included in aggregate %.

11388 of 11957 relevant lines covered (95.24%)

259.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.51
/packages/vue-flicking/src/Flicking.ts
1
/*
2
 * Copyright (c) 2015 NAVER Corp.
3
 * egjs projects are licensed under the MIT license
4
 */
5
import ListDiffer, { DiffResult } from "@egjs/list-differ";
5✔
6
import Vue, { CreateElement, VNodeData, VNode } from "vue";
5✔
7
import VanillaFlicking, {
5✔
8
  EVENTS,
9
  withFlickingMethods,
10
  sync,
11
  Plugin,
12
  getRenderingPanels,
13
  getDefaultCameraTransform,
14
  range,
15
  VirtualRenderingStrategy,
16
  NormalRenderingStrategy
17
} from "@egjs/flicking";
18

19
import VueRenderer, { VueRendererOptions } from "./VueRenderer";
5✔
20
import VuePanel from "./VuePanel";
5✔
21
import VueElementProvider from "./VueElementProvider";
5✔
22
import FlickingProps from "./FlickingProps";
5✔
23
import { fillKeys, getSlots } from "./utils";
5✔
24

25
const Flicking = Vue.extend({
5✔
26
  props: FlickingProps,
27
  components: {
28
    Panel: VuePanel
29
  },
30
  data() {
31
    // Mocking the type, as we don't want them to be reactive
32
    return {} as {
14✔
33
      vanillaFlicking: VanillaFlicking;
34
      pluginsDiffer: ListDiffer<Plugin>;
35
      slotDiffer: ListDiffer<VNode>;
36
      diffResult: DiffResult<VNode> | null;
37
    };
38
  },
39
  created() {
40
    this.diffResult = null;
14✔
41

42
    withFlickingMethods(this, "vanillaFlicking");
14✔
43
  },
44
  mounted() {
14✔
45
    const options = this.options;
14✔
46
    const viewportEl = this.$el as HTMLElement;
14✔
47
    const rendererOptions: VueRendererOptions = {
14✔
48
      // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
49
      vueFlicking: this as any,
50
      align: options.align,
51
      strategy: options.virtual && (options.panelsPerView ?? -1) > 0
28!
52
        ? new VirtualRenderingStrategy()
53
        : new NormalRenderingStrategy({
54
          providerCtor: VueElementProvider
55
        })
56
    };
57

58
    const flicking = new VanillaFlicking(viewportEl, {
14✔
59
      ...options,
60
      externalRenderer: new VueRenderer(rendererOptions)
61
    });
62
    this.vanillaFlicking = flicking;
14✔
63

64
    flicking.once(EVENTS.READY, () => {
14✔
65
      this.$forceUpdate();
14✔
66
    });
67

68
    const slots = getSlots(this);
14✔
69
    this.slotDiffer = new ListDiffer<VNode>(slots, vnode => (vnode.key as string));
252✔
70
    this.pluginsDiffer = new ListDiffer<Plugin>();
14✔
71

72
    this._bindEvents();
14✔
73
    this._checkPlugins();
14✔
74

75
    if (this.status) {
14!
76
      flicking.setStatus(this.status);
×
77
    }
78
  },
79
  beforeDestroy() {
80
    this.vanillaFlicking?.destroy();
14!
81
  },
82
  beforeMount() {
83
    fillKeys(this);
14✔
84
  },
85
  beforeUpdate() {
86
    fillKeys(this);
34✔
87

88
    this.diffResult = this.slotDiffer.update(getSlots(this));
34✔
89
  },
90
  updated() {
91
    const flicking = this.vanillaFlicking;
34✔
92
    const diffResult = this.diffResult;
34✔
93

94
    this._checkPlugins();
34✔
95
    this.$emit("render");
34✔
96

97
    if (!diffResult || !flicking.initialized) return;
34!
98

99
    sync(flicking, diffResult, this.$children);
34✔
100

101
    if (diffResult.added.length > 0 || diffResult.removed.length > 0) {
34!
102
      this.$forceUpdate();
×
103
    }
104

105
    this.diffResult = null;
34✔
106
  },
107
  render(h: CreateElement): VNode {
108
    const flicking = this.vanillaFlicking;
48✔
109
    const options = this.options;
48✔
110
    const initialized = !!this.diffResult && flicking && flicking.initialized;
48✔
111
    const isHorizontal = flicking
48✔
112
      ? flicking.horizontal
113
      : options.horizontal ?? true;
42!
114

115
    const viewportData: VNodeData = {
48✔
116
      class: {
117
        "flicking-viewport": true,
118
        "vertical": !isHorizontal,
119
        "flicking-hidden": this.hideBeforeInit && !initialized
48!
120
      }
121
    };
122
    const cameraData: VNodeData = {
48✔
123
      class: {
124
        "flicking-camera": true,
125
        [this.cameraClass]: !!this.cameraClass
126
      },
127
      style: !initialized && this.firstPanelSize
110!
128
        ? { transform: getDefaultCameraTransform(options.align, options.horizontal, this.firstPanelSize) }
129
        : {}
130
    };
131

132
    const panels = options.virtual && (options.panelsPerView ?? -1) > 0
48!
133
      ? this._getVirtualPanels(h, initialized)
134
      : this._getPanels(h, initialized);
135

136
    return h(this.viewportTag, viewportData,
48✔
137
      [h(this.cameraTag, cameraData,
138
        panels,
139
      ), this.$slots.viewport],
140
    );
141
  },
142
  methods: {
143
    /* eslint-disable @typescript-eslint/naming-convention */
144
    _getSlots() {
145
      return this.$slots.default?.filter(slot => slot.tag) ?? [];
54!
146
    },
147
    _fillKeys() {
148
      const vnodes = this._getSlots();
×
149

150
      vnodes.forEach((node, idx) => {
×
151
        if (node.key == null) {
×
152
          node.key = `$_${idx}`;
×
153
        }
154
      });
155
    },
156
    _bindEvents() {
14✔
157
      const flicking = this.vanillaFlicking;
14✔
158
      const events = Object.keys(EVENTS).map(key => EVENTS[key]);
238✔
159

160
      events.forEach(eventName => {
14✔
161
        flicking.on(eventName, (e: any) => {
238✔
162
          e.currentTarget = this;
352✔
163
          // Make events from camelCase to kebab-case
164
          this.$emit(eventName.replace(/([A-Z])/g, "-$1").toLowerCase(), e);
352✔
165
        });
166
      });
167
    },
168
    _checkPlugins() {
169
      const { list, added, removed, prevList } = this.pluginsDiffer.update(this.plugins);
48✔
170

171
      this.vanillaFlicking.addPlugins(...added.map(index => list[index]));
48✔
172
      this.vanillaFlicking.removePlugins(...removed.map(index => prevList[index]));
48✔
173
    },
174
    _getPanels(h: CreateElement, initialized: boolean) {
175
      const slots = initialized
48✔
176
        ? getRenderingPanels(this.vanillaFlicking, this.diffResult!)
177
        : this._getSlots();
178
      return slots.map(slot => h("Panel", { key: slot.key as string }, [slot]));
180✔
179
    },
180
    _getVirtualPanels(h: CreateElement, initialized: boolean) {
181
      const options = this.options;
×
182
      const {
183
        panelClass = "flicking-panel"
×
184
      } = options.virtual!;
×
185
      const panelsPerView = options.panelsPerView as number;
×
186
      const flicking = this.vanillaFlicking;
×
187

188
      const renderingIndexes = initialized
×
189
        ? flicking.renderer.strategy.getRenderingIndexesByOrder(flicking)
190
        : range(panelsPerView + 1);
191

192
      const firstPanel = flicking && flicking.panels[0];
×
193
      const size = firstPanel
×
194
        ? flicking.horizontal
×
195
          ? { width: firstPanel.size }
196
          : { height: firstPanel.size }
197
        : {};
198

199
      return renderingIndexes.map(idx => h("div", {
×
200
        key: idx,
201
        staticClass: panelClass,
202
        style: size,
203
        domProps: {
204
          "data-element-index": idx
205
        }
206
      }));
207
    }
208
  },
209
  watch: {
210
    options: {
211
      handler(newOptions) {
212
        const flicking = this.vanillaFlicking;
14✔
213
        if (!flicking) return;
14✔
214

215
        // Omit 'virtual', as it can't have any setter
216
        const { virtual, ...options } = newOptions; // eslint-disable-line @typescript-eslint/no-unused-vars
×
217

218
        for (const key in options) {
×
219
          if (key in flicking && flicking[key] !== options[key]) {
×
220
            flicking[key] = options[key];
×
221
          }
222
        }
223
      },
224
      deep: true,
225
      immediate: true
226
    }
227
  }
228
});
229

230
type VueFlicking = InstanceType<typeof Flicking>;
231

232
interface Flicking extends VueFlicking, VanillaFlicking {}
233
export default Flicking;
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc