PluginProbe ʕ •ᴥ•ʔ
VK Blocks / trunk
VK Blocks vtrunk
1.123.0 1.122.0 1.121.0 1.120.0 1.119.2 1.119.1 1.119.0 1.118.7 1.82.0.0 1.82.0.1 1.83.0.0 1.83.0.1 1.84.0.0 1.84.0.1 1.85.0.2 1.85.0.3 1.85.1.0 1.85.1.1 1.86.0.0 1.86.0.1 1.86.1.0 1.87.0.0 1.87.0.1 1.88.0.1 1.88.0.2 1.89.0.0 1.9.2 1.90.0.0 1.90.0.1 1.90.1.1 1.91.0.0 1.91.1.1 1.92.0.0 1.92.0.1 1.92.1.0 1.92.1.1 1.93.0.0 trunk 1.93.0.1 0.1.1 1.93.1.0 0.10.3 1.93.1.1 0.11.0 1.94.0.0 0.12.6 1.94.0.1 0.15.1 1.94.1.0 0.16.2 1.94.2.1 0.17.6 1.94.2.2 0.2.2 1.95.0.3 0.22.4 1.95.0.4 0.26.7 1.96.2.0 0.3.2 1.96.2.1 0.31.0 1.97.0.1 0.35.5 1.97.0.2 0.37.5 1.99.0.0 0.38.8 1.99.0.1 0.39.4 0.4.7 0.41.0 0.42.0 0.44.13 0.45.2 0.46.1 0.47.0 0.48.0 0.49.8 0.5.2 0.50.3 0.51.0 0.52.2 0.53.2 0.54.0 0.55.0 0.56.2 0.56.3 0.57.6 0.58.10 0.59.0 0.6.0 0.60.1 0.61.2 0.7.1 0.8.2 1.0.16 1.10.0 1.100.0.0 1.100.0.1 1.102.0.0 1.102.0.1 1.103.0.0 1.104.0.0 1.104.0.1 1.105.1.0 1.105.1.1 1.106.0.0 1.106.0.1 1.107.0.0 1.107.0.1 1.107.0.2 1.108.0.0 1.108.0.1 1.109.0.0 1.109.0.1 1.11.4 1.110.0.0 1.110.0.1 1.111.0.0 1.111.0.1 1.111.0.2 1.112.0.0 1.112.0.1 1.113.0.0 1.113.0.1 1.114.0.0 1.114.0.1 1.114.2.0 1.114.2.1 1.115.0.0 1.115.0.1 1.115.1.0 1.115.1.1 1.115.2.0 1.115.2.1 1.116.0.0 1.116.0.1 1.116.1.0 1.116.1.1 1.116.2.0 1.117.0.0 1.117.0.1 1.117.1.0 1.118.2 1.118.5 1.12.0 1.13.2 1.14.1 1.15.1 1.16.11 1.17.0 1.18.6 1.19.0 1.19.1 1.2.3 1.20.7 1.21.0 1.22.4 1.23.0 1.24.5 1.25.1 1.26.2 1.27.7.2 1.28.0.1 1.29.2.0 1.3.9 1.30.0.1 1.31.0.1 1.32.0.2 1.33.2.1 1.36.1.5 1.37.0.0 1.39.2.1 1.4.6 1.40.0.1 1.40.1.0 1.40.1.1 1.41.0.0 1.41.0.1 1.41.2.2 1.41.2.3 1.43.0.0 1.43.0.1 1.43.0.2 1.44.0.0 1.44.0.1 1.45.0.0 1.45.0.1 1.46.0.0 1.46.0.1 1.47.0.0 1.47.0.1 1.47.1.0 1.48.0.0 1.48.0.1 1.48.0.2 1.48.1.0 1.48.1.1 1.5.0 1.50.0.0 1.50.0.1 1.51.0.0 1.51.0.1 1.52.0.0 1.52.0.1 1.53.0.0 1.53.0.1 1.54.0.0 1.54.0.1 1.55.0.0 1.55.0.1 1.56.0.0 1.56.0.1 1.57.0.0 1.57.0.2 1.57.0.3 1.57.0.4 1.57.0.5 1.57.1.0 1.57.1.1 1.57.1.2 1.58.0.0 1.58.0.1 1.59.0.0 1.59.0.1 1.6.0 1.60.0.0 1.60.0.1 1.63.0.0 1.63.0.1 1.64.0.0 1.64.0.1 1.64.1.0 1.64.1.2 1.67.0.0 1.67.0.1 1.68.0.0 1.68.0.1 1.69.0.0 1.69.0.1 1.69.1.1 1.69.1.2 1.7.1 1.70.0.0 1.70.0.1 1.71.0.0 1.71.0.1 1.72.0.0 1.72.1.0 1.72.1.1 1.73.0.0 1.73.0.1 1.74.0.0 1.74.0.1 1.75.0.0 1.75.1.0 1.75.1.1 1.76.0.0 1.76.0.1 1.76.1.0 1.76.1.1 1.76.2.0 1.76.2.1 1.77.0.0 1.77.0.1 1.78.0.0 1.78.0.1 1.79.0.0 1.79.0.1 1.79.0.2 1.79.0.3 1.79.1.0 1.79.1.1 1.8.2 1.80.1.0 1.80.1.1 1.80.1.2 1.81.0.1 1.81.0.2
vk-blocks / src / blocks / slider / edit-slider.js
vk-blocks / src / blocks / slider Last commit date
deprecated 2 weeks ago _swiper._scss 2 months ago block.json 2 weeks ago edit-multiItem.js 2 weeks ago edit-slider.js 2 weeks ago edit.js 6 days ago icon.svg 2 months ago index.js 2 months ago index.php 2 months ago loop-min-slides.js 2 months ago pause-button.js 6 days ago save.js 6 days ago style.scss 2 months ago view.js 6 days ago
edit-slider.js
372 lines
1 import Swiper from 'swiper/bundle';
2
3 // スライダーの格納
4 const swiper = {};
5
6 // 監視中の editorRoot を管理
7 const observedRoots = new Set();
8
9 // swiper クラスを削除
10 const removeSwiperClassName = (targetElement) => {
11 if (targetElement) {
12 const classNames = targetElement.className.split(' ');
13 for (let i = 0; i < classNames.length; i++) {
14 if (classNames[i].match(/swiper(\w|-)*/)) {
15 // クラスを削除
16 targetElement.classList.remove(classNames[i]);
17 }
18 }
19 targetElement.id = targetElement.id.replace(/swiper(\w|-)*/g, '');
20 targetElement.style.width = '';
21 }
22 };
23
24 // スライダーブロック単体の処理
25 const LaunchSwiper = (slider) => {
26 // 値を取得して�
27 �列に格納
28 const attributes = JSON.parse(slider.getAttribute('data-vkb-slider'));
29 // Backward compatibility: handle typo in old attribute name.
30 if (
31 attributes.zoomFinalScale === undefined &&
32 attributes.zoomFinalScal !== undefined
33 ) {
34 attributes.zoomFinalScale = attributes.zoomFinalScal;
35 }
36
37 // スライダーの ID を取得
38 if (attributes && (attributes.blockId || attributes.clientId)) {
39 // 対象の ID を取得
40 let sliderId = '';
41 if (attributes.blockId !== undefined) {
42 sliderId = attributes.blockId;
43 } else if (attributes.clientId !== undefined) {
44 // 1.36.0 より古い状�
45 �で保存されてる場合の互換処理
46 sliderId = attributes.clientId;
47 }
48
49 // 編集モードに応じた処理を実行
50 if (attributes.editorMode && attributes.editorMode === 'slide') {
51 if (!swiper[sliderId]) {
52 // swiper クラスを追加
53 const newSwiperDiv = slider.querySelector(
54 '.block-editor-inner-blocks'
55 );
56 if (newSwiperDiv) {
57 newSwiperDiv.classList.add('swiper');
58 }
59
60 // swiper-wrapper クラスを追加
61 const newSwiperWrapper = slider.querySelector(
62 '.block-editor-block-list__layout'
63 );
64 if (newSwiperWrapper) {
65 newSwiperWrapper.classList.add('swiper-wrapper');
66 }
67
68 // スライダーアイテムのクラス処理
69 const newSwiperSlide =
70 slider.querySelectorAll('.vk_slider_item');
71 if (newSwiperSlide.length > 0) {
72 newSwiperSlide.forEach((slide) => {
73 slide.classList.add('swiper-slide'); // swiper-slide クラスを追加
74 slide.classList.remove('is-highlighted'); // 誤動作防止の為 is-highlighted クラスを削除
75 });
76 }
77
78 const swiperButtonPrev = slider.querySelector(
79 '.swiper-button-prev'
80 );
81 if (swiperButtonPrev) {
82 swiperButtonPrev.style.display = '';
83 }
84 const swiperButtonNext = slider.querySelector(
85 '.swiper-button-next'
86 );
87 if (swiperButtonNext) {
88 swiperButtonNext.style.display = '';
89 }
90 const swiperPagination =
91 slider.querySelector('.swiper-pagination');
92 if (swiperPagination) {
93 swiperPagination.style.display = '';
94 }
95
96 // Sloder の設定を作成
97 const SwiperSetting = {};
98
99 // ループの設定
100 if (attributes.loop) {
101 SwiperSetting.loop = attributes.loop;
102 }
103
104 // エフェクトの設定
105 if (attributes.effect) {
106 SwiperSetting.effect = attributes.effect;
107 }
108
109 // ナビゲーションの設定
110 SwiperSetting.navigation = {
111 nextEl: slider.querySelector('.swiper-button-next'),
112 prevEl: slider.querySelector('.swiper-button-prev'),
113 };
114
115 // ページネーションの設定
116 if (attributes.pagination && attributes.pagination !== 'hide') {
117 SwiperSetting.pagination = {
118 el: slider.querySelector('.swiper-pagination'),
119 clickable: true,
120 type: `${attributes.pagination}`,
121 renderFraction(currentClass, totalClass) {
122 return (
123 '<span class="' +
124 currentClass +
125 '"></span>' +
126 ' / ' +
127 '<span class="' +
128 totalClass +
129 '"></span>'
130 );
131 },
132 };
133 }
134
135 // 複数枚表示の設定
136 if (attributes.effect && attributes.effect !== 'fade') {
137 if (attributes.slidesPerViewMobile) {
138 SwiperSetting.slidesPerView =
139 attributes.slidesPerViewMobile;
140 if (
141 attributes.slidesPerGroup &&
142 attributes.slidesPerGroup === 'slides-per-view' &&
143 Number.isInteger(attributes.slidesPerViewMobile)
144 ) {
145 SwiperSetting.slidesPerGroup =
146 attributes.slidesPerViewMobile;
147 } else {
148 SwiperSetting.slidesPerGroup = 1;
149 }
150 } else if (attributes.slidesPerView) {
151 SwiperSetting.slidesPerView = attributes.slidesPerView;
152 if (
153 attributes.slidesPerGroup &&
154 attributes.slidesPerGroup === 'slides-per-view' &&
155 Number.isInteger(attributes.slidesPerView)
156 ) {
157 SwiperSetting.slidesPerGroup =
158 attributes.slidesPerView;
159 } else {
160 SwiperSetting.slidesPerGroup = 1;
161 }
162 } else {
163 SwiperSetting.slidesPerView = 1;
164 SwiperSetting.slidesPerGroup = 1;
165 }
166 if (
167 attributes.slidesPerViewTablet ||
168 attributes.slidesPerViewPC
169 ) {
170 // Responsive breakpoints
171 SwiperSetting.breakpoints = {};
172 if (attributes.slidesPerViewTablet) {
173 SwiperSetting.breakpoints[576] = {
174 slidesPerView: attributes.slidesPerViewTablet,
175 };
176 if (
177 attributes.slidesPerGroup &&
178 attributes.slidesPerGroup ===
179 'slides-per-view' &&
180 Number.isInteger(attributes.slidesPerViewTablet)
181 ) {
182 SwiperSetting.breakpoints[576].slidesPerGroup =
183 attributes.slidesPerViewTablet;
184 } else {
185 SwiperSetting.breakpoints[576].slidesPerGroup = 1;
186 }
187 }
188 if (attributes.slidesPerViewPC) {
189 SwiperSetting.breakpoints[992] = {
190 slidesPerView: attributes.slidesPerViewPC,
191 };
192 if (
193 attributes.slidesPerGroup &&
194 attributes.slidesPerGroup ===
195 'slides-per-view' &&
196 Number.isInteger(attributes.slidesPerViewPC)
197 ) {
198 SwiperSetting.breakpoints[992].slidesPerGroup =
199 attributes.slidesPerViewPC;
200 } else {
201 SwiperSetting.breakpoints[992].slidesPerGroup = 1;
202 }
203 }
204 }
205
206 if (attributes.centeredSlides) {
207 SwiperSetting.centeredSlides =
208 attributes.centeredSlides;
209 }
210
211 SwiperSetting.slideActiveClass = 'is-selected';
212 }
213
214 swiper[sliderId] = new Swiper(
215 slider.querySelector(
216 'div > div > div.block-editor-inner-blocks'
217 ),
218 SwiperSetting
219 );
220 } else if (swiper[sliderId]) {
221 // 既存の Swiper インスタンスがある場合は、スライド要素が変わっている可能性があるため更新
222 swiper[sliderId].update();
223 }
224 } else {
225 // 不要な swiper クラスを削除
226 const newSwiperDiv = slider.querySelector(
227 '.block-editor-inner-blocks'
228 );
229 if (newSwiperDiv) {
230 removeSwiperClassName(newSwiperDiv);
231 }
232
233 // 不要な swiper-wrapper クラスを削除
234 const newSwiperWrapper = slider.querySelector(
235 '.block-editor-block-list__layout'
236 );
237 if (newSwiperWrapper) {
238 removeSwiperClassName(newSwiperWrapper);
239 }
240
241 // 不要な swiper-slide クラスを削除
242 const newSwiperSlide = slider.querySelectorAll('.vk_slider_item');
243 if (newSwiperSlide.length > 0) {
244 newSwiperSlide.forEach((slide) => {
245 slide.classList.remove('is-selected');
246 slide.classList.remove('is-highlighted');
247 removeSwiperClassName(slide);
248 });
249 newSwiperSlide[0].classList.add('is-selected');
250 }
251
252 // ナビゲーションの非表示
253 const swiperButtonPrev = slider.querySelector(
254 '.swiper-button-prev'
255 );
256 if (swiperButtonPrev) {
257 swiperButtonPrev.style.display = 'none';
258 }
259 const swiperButtonNext = slider.querySelector(
260 '.swiper-button-next'
261 );
262 if (swiperButtonNext) {
263 swiperButtonNext.style.display = 'none';
264 }
265
266 // ページネーションの非表示
267 const swiperPagination = slider.querySelector('.swiper-pagination');
268 if (swiperPagination) {
269 swiperPagination.style.display = 'none';
270 }
271
272 if (swiper[sliderId]) {
273 swiper[sliderId].destroy();
274 swiper[sliderId] = null;
275 }
276 }
277 }
278 };
279
280 // スライダーブロック�
281 �体の処理
282 export const LaunchSwiperAll = (editorRoot) => {
283 const sliders = editorRoot.querySelectorAll('.vk_slider');
284 if (sliders.length > 0) {
285 sliders.forEach((slider) => {
286 LaunchSwiper(slider);
287 });
288 }
289 };
290
291 // スライダーの監視
292 export const SliderObserver = (editorRoot) => {
293 // 既に監視中の場合はスキップ
294 if (observedRoots.has(editorRoot)) {
295 return;
296 }
297
298 // このルートを監視中として記録
299 observedRoots.add(editorRoot);
300
301 const config = { childList: true, subtree: true, attributes: true };
302
303 const callback = (mutationsList) => {
304 // Use traditional 'for loops' for IE 11
305 for (const mutation of mutationsList) {
306 if (mutation.type === 'childList') {
307 if (mutation.addedNodes.length > 0) {
308 mutation.addedNodes.forEach((addedNode) => {
309 if (
310 addedNode.classList &&
311 addedNode.classList.contains('vk_slider')
312 ) {
313 LaunchSwiper(addedNode);
314 } else if (
315 addedNode.classList &&
316 addedNode.classList.contains('vk_slider_item')
317 ) {
318 const parentSlider =
319 addedNode.closest('.vk_slider');
320 LaunchSwiper(parentSlider);
321 }
322 });
323 }
324 } else if (mutation.type === 'attributes') {
325 if (
326 mutation.target.classList.contains('vk_slider') &&
327 mutation.attributeName === 'data-vkb-slider'
328 ) {
329 LaunchSwiper(mutation.target);
330 }
331 }
332 }
333 };
334
335 const observer = new MutationObserver(callback);
336 observer.observe(editorRoot, config);
337 };
338
339 const editorRootLaunch = (editorRoot) => {
340 LaunchSwiperAll(editorRoot);
341
342 // editorRoot ごとに1回だけ Observer をセットアップ
343
344 if (!editorRoot.dataset.vkSliderObserverInitialized) {
345 SliderObserver(editorRoot);
346
347 editorRoot.dataset.vkSliderObserverInitialized = 'true';
348 }
349 };
350
351 export const editSliderLaunch = () => {
352 const iframe = document.querySelector(
353 '.block-editor-iframe__container iframe'
354 );
355 const iframeDoc = iframe?.contentWindow?.document;
356 const editorRoot =
357 iframeDoc?.querySelector('.block-editor-block-list__layout') ||
358 document.querySelector('.block-editor-block-list__layout');
359
360 if (editorRoot) {
361 editorRootLaunch(editorRoot);
362 }
363
364 const siteIframe = document.querySelector('#site-editor iframe');
365 const siteEditorRoot =
366 siteIframe?.contentWindow?.document.querySelector('.is-root-container');
367
368 if (siteEditorRoot) {
369 editorRootLaunch(siteEditorRoot);
370 }
371 };
372