create-fesd-app 1.0.21 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fesd-app",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "@tailwindcss/postcss": "^4.1.10",
26
26
  "@tailwindcss/vite": "^4.1.10",
27
- "@xwadex/fesd": "0.0.44",
27
+ "@xwadex/fesd": "0.0.46",
28
28
  "ansi-colors": "^4.1.3",
29
29
  "chalk": "^5.3.0",
30
30
  "clsx": "^2.1.1",
@@ -31,6 +31,9 @@ input
31
31
  [data-noContent]
32
32
  display: none
33
33
 
34
+ [data-cookie]
35
+ cursor: pointer
36
+
34
37
  .lazy
35
38
  opacity: 0
36
39
  &.loaded
@@ -97,7 +97,6 @@
97
97
  display: flex
98
98
  align-items: center
99
99
  gap: 15px
100
- cursor: pointer
101
100
  +rwdmax(767)
102
101
  .cookie-main
103
102
  padding: 50px 25px
@@ -309,7 +308,7 @@
309
308
  color: #4B4B4B
310
309
  pointer-events: none
311
310
  transform: translate3d(calc(-100% - 10px),0,0)
312
- content: "拒絕"
311
+ content: var(--switch-closeText)
313
312
  &::before
314
313
  content: ''
315
314
  position: absolute
@@ -331,7 +330,7 @@
331
330
  transform: translateX(18px)
332
331
  background: #fff
333
332
  input:checked + .switch::after
334
- content: "啟用"
333
+ content: var(--switch-openText)
335
334
  input:checked + .switch:active::before
336
335
  box-shadow: 0 2px 8px rgba(0,0,0,0.28), 0 0 0 20px rgba(128,128,128,0.1)
337
336
 
@@ -20,7 +20,7 @@ nav.navbar
20
20
  align-items: center
21
21
  margin-left: auto
22
22
  li
23
- a
23
+ a, div
24
24
  padding: 0 10px
25
25
  +rwdmax(575)
26
26
  padding: 0 8px
@@ -1,11 +1,10 @@
1
1
  // 此處為 demo 資料, 後端會用相同資料結構洗資料在 #_wcookie 上
2
2
  // 給後端: 基本上進階版細項開關不開, 有需求才開; 若開啟進階版細項, 大分類的 close 開關預設會無效, 會以判斷細項是否有開啟 or 全關為主
3
3
  // close: 0 -> 開啟; close: 1 -> 關閉
4
+ // 說明文件
4
5
  export const cookieData = [
5
6
  {
6
- multiType: true, // 進階版是否開啟個別選項設定
7
- title: "您的 Cookie 偏好設定",
8
- text: "我們使用不同類型的 Cookies 來優化您在我們的網站上的體驗,點擊下面類別以了解其目的與更多訊息。<br>您可以選擇允許的 Cookies 類型,也可以隨時更改您的偏好設定。<br>提醒您,停用 Cookies 可能會影響您在網站上的體驗,您可以瀏覽我們的隱私權政策,進一步了解我們如何使用 Cookie。",
7
+ multiType: true, // 進階版時是否開啟個別選項設定
9
8
  options: [
10
9
  {
11
10
  key: "required",
@@ -159,7 +159,7 @@ export const cookieStep2ListCollapseEl = (
159
159
  num
160
160
  )=> {
161
161
  const isDisabled = li.disabled ? " disabled" : ""
162
- const isListChecked = cookieNewObj[parentKey].list[li.key].close == 0 ? "checked" : ""
162
+ const isListChecked = cookieNewObj[parentKey].list?.[li.key].close == 0 ? "checked" : ""
163
163
  return `
164
164
  <div class="list collapseItem list-option ${isListChecked}" data-collapse>
165
165
  <div class="title collapseTitle" data-collapse-click>
@@ -223,7 +223,7 @@ export const cookieStep2ListNormalEl = (
223
223
  index,
224
224
  parentKey
225
225
  ) => {
226
- const isListChecked = cookieNewObj[parentKey].list[li.key].close == 0 ? "checked" : ""
226
+ const isListChecked = cookieNewObj[parentKey].list?.[li.key].close == 0 ? "checked" : ""
227
227
  return `
228
228
  <div class="list list-option ${isListChecked}">
229
229
  <div class="title">
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  methods
3
- } from "@/commons";
3
+ } from "@/commons"
4
4
  import {
5
5
  scrollLock,
6
6
  scrollUnlock
7
- } from '@xwadex/fesd/tools';
8
- import Cookies from "js-cookie";
9
- import { OverlayScrollbars } from 'overlayscrollbars';
10
- import { cookieData } from "./cookieData";
7
+ } from '@xwadex/fesd/tools'
8
+ import Cookies from "js-cookie"
9
+ import { OverlayScrollbars } from 'overlayscrollbars'
10
+ import { cookieData } from "./cookieData"
11
11
  import { cookieStep1El, cookieStep2TittleEl, cookieStep2ContentEl } from "./cookieElement"
12
12
 
13
13
  // 基礎版 cookie
@@ -17,103 +17,87 @@ const cookieAdvanced = {}
17
17
  const cookieSetting = {}
18
18
  const cookieElements = {}
19
19
  // 設定一個預存空間
20
- let cookieNewObj = {};
20
+ let cookieNewObj = {}
21
21
 
22
22
  // 簡易版 cookie 設定
23
- cookieBasic.basicCookiePolicy = () => {
24
- const $cookiePolicy = $(".cookie-check");
25
- if (!$cookiePolicy.length) return;
26
-
27
- const $agreeBtn = $cookiePolicy.find(".agree");
28
- const $closeBtn = $cookiePolicy.find(".close");
23
+ cookieBasic.basicCookiePolicy = (el) => {
24
+ const $cookiePolicy = $(".cookie-check")
25
+ if (!$cookiePolicy.length) return
26
+
27
+ const $agreeBtn = $cookiePolicy.find(".agree")
28
+ const $closeBtn = $cookiePolicy.find(".close")
29
29
 
30
30
  const firstEnterDetect = () => {
31
31
  // 請記得更改 cookie 存入的值
32
- const agreeLocal = localStorage.getItem("frameworkCookie-agree");
33
- const agreeSession = sessionStorage.getItem("frameworkCookie-agree");
34
-
32
+ const agreeLocal = localStorage.getItem(el)
33
+ const agreeSession = sessionStorage.getItem(el)
34
+
35
35
  if (agreeLocal !== "true" && agreeSession !== "false") {
36
- $cookiePolicy.addClass("first-enter");
36
+ $cookiePolicy.addClass("first-enter")
37
37
  setTimeout(() => {
38
- $cookiePolicy.addClass("show");
39
- }, 800);
38
+ $cookiePolicy.addClass("show")
39
+ }, 800)
40
40
  }
41
- };
42
-
41
+ }
42
+
43
43
  // 點擊事件
44
44
  const clickEvent = () => {
45
45
  $agreeBtn.on("click", () => {
46
- $cookiePolicy.addClass("agree");
47
- localStorage.setItem("frameworkCookie-agree", "true");
48
- // 執行後端方法
49
- if (typeof window._wdSetting === 'function') {
50
- window._wdSetting()
51
- }
52
- });
53
-
54
- $closeBtn.on("click", () => {
55
- $cookiePolicy.addClass("hidden");
56
- sessionStorage.setItem("frameworkCookie-agree", "false");
57
- if (typeof window._wdSetting === 'function') {
58
- window._wdSetting()
59
- }
60
- });
46
+ $cookiePolicy.addClass("agree")
47
+ localStorage.setItem(el, "true")
48
+ })
61
49
 
62
- // 開啟 cookie 視窗按鈕
63
- $("[data-cookie-open]").on("click", function() {
64
- $cookiePolicy.addClass("first-enter");
65
- $cookiePolicy.removeClass("agree");
66
- $cookiePolicy.removeClass("hidden");
67
- setTimeout(() => {
68
- $cookiePolicy.addClass("show");
69
- }, 800);
50
+ $closeBtn.on("click", () => {
51
+ $cookiePolicy.addClass("hidden")
52
+ sessionStorage.setItem(el, "false")
70
53
  })
71
- };
54
+ }
72
55
 
73
56
  // 執行事件
74
- firstEnterDetect();
75
- clickEvent();
76
- };
57
+ firstEnterDetect()
58
+ clickEvent()
59
+ }
77
60
 
78
61
  // 產生新物件
79
62
  cookieAdvanced.newObj = () => {
80
- if (Cookies.get('_wd') !== undefined) {
63
+ if (Cookies.get('_wd') !== undefined && $("#_wcookie").val()) {
81
64
  const cloudDdata = JSON.parse(Cookies.get('_wd'))
82
65
  cookieNewObj = { ...cloudDdata }
83
66
  } else {
84
67
  const data = $("#_wcookie").val() ? JSON.parse($("#_wcookie").val())[0] : cookieData[0]
85
- const options = data?.options;
68
+ const options = data?.options
69
+
86
70
  if (options) {
87
71
  // 判斷是否全開 or 全關 (排除 required)
88
- const nonRequiredOptions = options.filter(opt => opt.key !== 'required');
89
- const allNonRequiredAreFalse = nonRequiredOptions.every(opt => opt.close === 1);
90
- const globalCloseValue = allNonRequiredAreFalse == 1 ? 1 : 0;
91
-
92
- cookieNewObj.close = globalCloseValue;
72
+ const nonRequiredOptions = options.filter(opt => opt.key !== 'required')
73
+ const allNonRequiredAreFalse = nonRequiredOptions.every(opt => opt.close === 1)
74
+ const globalCloseValue = allNonRequiredAreFalse == 1 ? 1 : 0
75
+
76
+ cookieNewObj.close = globalCloseValue
93
77
 
94
78
  const categoriesObject = options.reduce((acc, option) => {
95
- const topLevelKey = option.key;
96
- const dataItems = option.data?.items;
79
+ const topLevelKey = option.key
80
+ const dataItems = option.data?.items
97
81
 
98
- acc[topLevelKey] = { close: option.close };
82
+ acc[topLevelKey] = { close: option.close }
99
83
 
100
84
  if (data.multiType && dataItems !== undefined && dataItems.length > 0) {
101
- acc[topLevelKey].list = {};
85
+ acc[topLevelKey].list = {}
102
86
 
103
87
  dataItems.forEach(item => {
104
88
  item.list?.forEach(listItem => {
105
89
  if (listItem.key) {
106
90
  acc[topLevelKey].list[listItem.key] = {
107
91
  close: listItem.close
108
- };
92
+ }
109
93
  }
110
- });
111
- });
94
+ })
95
+ })
112
96
  }
113
- return acc;
114
- }, {});
97
+ return acc
98
+ }, {})
115
99
  // 若無 cookie 紀錄可抓, 直接新建一個新的物件預存
116
- Object.assign(cookieNewObj, categoriesObject);
100
+ Object.assign(cookieNewObj, categoriesObject)
117
101
  }
118
102
  }
119
103
  }
@@ -129,9 +113,6 @@ export const generateHtmlString = (target, fn) => {
129
113
 
130
114
  // 產資料結構
131
115
  cookieAdvanced.dataAppend = () => {
132
- const $block = $(".cookie-setting")
133
- if (!$block.length) return
134
-
135
116
  const val = $("#_wcookie").val()
136
117
  const data = val ? JSON.parse(val)[0] : cookieData[0]
137
118
  const $step1 = $(".setting-container[t4-id='step1']")
@@ -142,7 +123,7 @@ cookieAdvanced.dataAppend = () => {
142
123
  generateHtmlString(data.options, cookieElements.getStep1Element)
143
124
  )
144
125
 
145
- const step2OpenClick = function() {
126
+ const step2OpenClick = function () {
146
127
  const index = $(this).closest(".item").data("index")
147
128
  const opt = data.options[index]
148
129
  const items = opt.data?.items || []
@@ -153,21 +134,23 @@ cookieAdvanced.dataAppend = () => {
153
134
  )
154
135
  // 產 step2 下方結構
155
136
  $step2.find(".content-block").html(
156
- cookieStep2ContentEl(items,cookieNewObj,data,opt)
137
+ cookieStep2ContentEl(items, cookieNewObj, data, opt)
157
138
  )
158
139
  // 換頁
159
- document.body.fesd.cookieGoToNext();
140
+ document.body.fesd.cookieGoToNext()
160
141
  // 重綁收合
161
142
  methods.collapseEvent(
162
- '[data-collapse-click]',
163
- '[data-collapse]',
164
- '[data-collapse-content]',
165
- false,
143
+ '[data-collapse-click]',
144
+ '[data-collapse]',
145
+ '[data-collapse-content]',
146
+ false,
166
147
  true
167
148
  )
168
149
  }
169
150
  // step2 點擊打開
170
- $step1.off('click.step2Open', '[data-open]').on('click.step2Open', '[data-open]', step2OpenClick)
151
+ $step1
152
+ .off('click.step2Open', '[data-open]')
153
+ .on('click.step2Open', '[data-open]', step2OpenClick)
171
154
  }
172
155
 
173
156
  // switch 的一些狀態
@@ -176,178 +159,256 @@ cookieAdvanced.switchState = () => {
176
159
  const $step2contentSwitch = `[t4-id='step2'] .content-block input[type="checkbox"][data-parent][data-name]:not(.disabled)`
177
160
  const $step2topSwitch = `[t4-id='step2'] .top-block input[type="checkbox"][data-name]:not(.disabled)`
178
161
 
179
- let isSyncing = false
162
+ let isSyncing = false
180
163
 
181
164
  // 開關同步連動控制
182
- $(document).off('change.switch').on('change.switch', 'input[type="checkbox"][data-name]:not(:disabled)', function () {
183
- if (isSyncing) return
184
- isSyncing = true
185
-
186
- const $this = $(this)
187
- const key = $this.data('name')
188
- const val = $this.prop('checked')
189
-
190
- $(`input[type="checkbox"][data-name="${key}"]`).not(this).prop('checked', val)
191
- if (!val) {
192
- $($this).parents(".main-option,.list-option").removeClass("checked")
193
- } else {
194
- $($this).parents(".main-option,.list-option").addClass("checked")
195
- }
196
- isSyncing = false
197
- })
165
+ $(document)
166
+ .off('change.switch')
167
+ .on('change.switch', 'input[type="checkbox"][data-name]:not(:disabled)', function () {
168
+ if (isSyncing) return
169
+ isSyncing = true
170
+
171
+ const $this = $(this)
172
+ const key = $this.data('name')
173
+ const val = $this.prop('checked')
174
+
175
+ $(`input[type="checkbox"][data-name="${key}"]`).not(this).prop('checked', val)
176
+ if (!val) {
177
+ $($this).parents(".main-option,.list-option").removeClass("checked")
178
+ } else {
179
+ $($this).parents(".main-option,.list-option").addClass("checked")
180
+ }
181
+ isSyncing = false
182
+ })
198
183
 
199
184
  // step1 變動 → 更新 cookieNewObj
200
- $(document).off('change.cookieStep1').on('change.cookieStep1', `[t4-id='step1'] input[type="checkbox"][data-name]`, function () {
201
- if (isSyncing) return
202
- isSyncing = true
203
-
204
- const $this = $(this)
205
- const key = $this.data("name")
206
- const val = $this.prop('checked') ? 0 : 1
207
-
208
- if (cookieNewObj[key]) {
209
- cookieNewObj[key].close = val
210
- const targetList = cookieNewObj[key].list;
211
- if (targetList && typeof targetList === 'object') {
212
- Object.keys(targetList).forEach(childKey => {
213
- if (targetList[childKey].close !== undefined) {
214
- targetList[childKey].close = val;
215
- }
216
- });
217
- }
218
- }
185
+ $(document)
186
+ .off('change.cookieStep1')
187
+ .on('change.cookieStep1', `[t4-id='step1'] input[type="checkbox"][data-name]`, function () {
188
+ if ($(this).closest("[t4-id='step2']").length) return
189
+ if (isSyncing) return
190
+ isSyncing = true
191
+
192
+ const $this = $(this)
193
+ const key = $this.data("name")
194
+ const val = $this.prop('checked') ? 0 : 1
195
+
196
+ if (cookieNewObj[key]) {
197
+ cookieNewObj[key].close = val
198
+ const targetList = cookieNewObj[key].list
199
+ if (targetList && typeof targetList === 'object') {
200
+ Object.keys(targetList).forEach(childKey => {
201
+ if (targetList[childKey].close !== undefined) {
202
+ targetList[childKey].close = val
203
+ }
204
+ })
205
+ }
206
+ }
219
207
  isSyncing = false
220
208
  })
221
209
 
222
- $(document).off("change.step2content").on("change.step2content", $step2contentSwitch, function () {
223
- if (isSyncing) return
224
- isSyncing = true
225
-
226
- const key = $(this).data("name")
227
- const parent = $(this).data("parent")
228
- const val = $(this).prop('checked') ? 0 : 1
229
- const $step1Switch = $(`[t4-id='step1'] input[type="checkbox"][data-name='${parent}']:not(.disabled)`)
230
- const total = $($step2contentSwitch).length
231
- const checked = $($step2contentSwitch).filter(':checked').length
232
-
233
-
234
- // 改變 cookieNewObj 的值
235
- cookieNewObj[parent].list[key].close = val
236
-
237
- // Step2 子項全部打開
238
- if (checked === total || checked > 0) {
239
- cookieNewObj[parent].close = 0
240
- $($step2topSwitch).prop("checked", true)
241
- $step1Switch.prop("checked", true)
242
- $step2.find(".main-option").addClass("checked")
243
- }
244
-
245
- // Step2 子項全部關閉
246
- else if (checked === 0) {
247
- cookieNewObj[parent].close = 1
248
- $($step2topSwitch).prop("checked", false)
249
- $step1Switch.prop("checked", false)
250
- $step2.find(".main-option").removeClass("checked")
251
- }
210
+ $(document)
211
+ .off("change.step2content")
212
+ .on("change.step2content", $step2contentSwitch, function () {
213
+ // if ($(this).closest("[t4-id='step2']").length) return
214
+ if (isSyncing) return
215
+ isSyncing = true
216
+
217
+ const key = $(this).data("name")
218
+ const parent = $(this).data("parent")
219
+ const val = $(this).prop('checked') ? 0 : 1
220
+ const $step1Switch = $(`[t4-id='step1'] input[type="checkbox"][data-name='${parent}']:not(.disabled)`)
221
+ const total = $($step2contentSwitch).length
222
+ const checked = $($step2contentSwitch).filter(':checked').length
223
+
224
+ // 改變 cookieNewObj 的值
225
+ cookieNewObj[parent].list[key].close = val
226
+
227
+ // Step2 子項全部打開
228
+ if (checked === total || checked > 0) {
229
+ cookieNewObj[parent].close = 0
230
+ $($step2topSwitch).prop("checked", true)
231
+ $step1Switch.prop("checked", true)
232
+ $step2.find(".main-option").addClass("checked")
233
+ }
252
234
 
253
- isSyncing = false
254
- })
235
+ // Step2 子項全部關閉
236
+ else if (checked === 0) {
237
+ cookieNewObj[parent].close = 1
238
+ $($step2topSwitch).prop("checked", false)
239
+ $step1Switch.prop("checked", false)
240
+ $step2.find(".main-option").removeClass("checked")
241
+ }
255
242
 
256
- $(document).off("change.step2top").on("change.step2top", $step2topSwitch, function () {
257
- if (isSyncing) return
258
- isSyncing = true
259
- const $this = $(this)
260
- const key = $this.data("name")
261
- const isChecked = $this.prop("checked")
262
- const detectVal = $this.prop('checked')
263
- const val = isChecked ? 0 : 1
264
-
265
- // 改所有子項
266
- $($step2contentSwitch).prop('checked', isChecked)
267
- if (!detectVal) {
268
- $step2.find(".list-option").removeClass("checked")
269
- } else {
270
- $step2.find(".list-option").addClass("checked")
271
- }
272
- // cookie main
273
- if (cookieNewObj[key]) {
274
- const list = cookieNewObj[key].list
275
- cookieNewObj[key].close = val
276
- if (list) {
277
- Object.keys(list).forEach(childKey => {
278
- list[childKey].close = val
279
- })
243
+ isSyncing = false
244
+ })
245
+
246
+ $(document)
247
+ .off("change.step2top")
248
+ .on("change.step2top", $step2topSwitch, function () {
249
+ if (isSyncing) return
250
+ isSyncing = true
251
+ const $this = $(this)
252
+ const key = $this.data("name")
253
+ const isChecked = $this.prop("checked")
254
+ const detectVal = $this.prop('checked')
255
+ const val = isChecked ? 0 : 1
256
+
257
+ // 改所有子項
258
+ $($step2contentSwitch).prop('checked', isChecked)
259
+ if (!detectVal) {
260
+ $step2.find(".list-option").removeClass("checked")
261
+ } else {
262
+ $step2.find(".list-option").addClass("checked")
280
263
  }
281
- }
282
- isSyncing = false
283
- })
264
+ // 改 cookie main
265
+ if (cookieNewObj[key]) {
266
+ const list = cookieNewObj[key].list
267
+ cookieNewObj[key].close = val
268
+ if (list) {
269
+ Object.keys(list).forEach(childKey => {
270
+ list[childKey].close = val
271
+ })
272
+ }
273
+ }
274
+ isSyncing = false
275
+ })
284
276
  }
285
277
 
286
278
  // 存 cookie
287
279
  cookieAdvanced.cookieSaveFn = () => {
288
280
  const nonRequiredValues = Object.entries(cookieNewObj)
289
- .filter(([key]) => key !== 'required' && key !== 'close')
290
- .map(([, value]) => value);
281
+ .filter(
282
+ ([key]) => key !== 'required' && key !== 'close'
283
+ )
284
+ .map(
285
+ ([, value]) => value
286
+ )
291
287
 
292
- const allNonRequiredAreClosed = nonRequiredValues.every(opt => opt.close === 1);
293
- const globalCloseValue = allNonRequiredAreClosed ? 1 : 0;
288
+ const allNonRequiredAreClosed = nonRequiredValues.every(opt => opt.close === 1)
289
+ const globalCloseValue = allNonRequiredAreClosed ? 1 : 0
294
290
 
295
291
  // 判斷設定第一層的 close 值
296
- cookieNewObj.close = globalCloseValue;
292
+ cookieNewObj.close = globalCloseValue
297
293
 
298
294
  // 存入 cookie
299
295
  Cookies.set('_wd', JSON.stringify(cookieNewObj), {
300
296
  expires: 180,
301
297
  path: '/',
302
298
  sameSite: true,
303
- });
299
+ })
304
300
  }
305
301
 
306
302
  // 點擊方法
307
- cookieAdvanced.clickEvent = () => {
303
+ cookieAdvanced.clickEvent = (el) => {
308
304
  const $settingBlock = $(".cookie-setting")
305
+ const $cookiePolicy = $(".cookie-check")
309
306
 
310
- // 打開進階版 cookie 介面
311
- $(document).on("click",".cookie-setting-btn", () => cookieSetting.openEvent($settingBlock));
312
- // 全開
313
- $(document).on('click',"[data-cookie-all]", cookieSetting.enableAll)
314
- // 儲存
315
- $(document).on('click',"[data-cookie-save]", cookieAdvanced.cookieSaveFn)
316
- // 關閉視窗
317
- $(document).on('click',"[data-cookie-close]", () => cookieSetting.closeEvent($settingBlock))
318
- // 我拒絕
319
- $(document).on('click',"[data-cookie-reject]", function() {
320
- cookieSetting.rejectAll()
321
- cookieAdvanced.cookieSaveFn()
322
- })
307
+ let scrollInstance = null
308
+
309
+ $(document)
310
+ .off("click.cookie", "[data-cookie]")
311
+ .on("click.cookie", "[data-cookie]", function (e) {
312
+ const $this = $(this)
313
+
314
+ // 打開 cookie 介面
315
+ if ($this.is("[data-cookie-open]")) {
316
+ const mode = $this.attr("data-cookie-open")
317
+ const targets = new Set(mode === "all" ? ["advance", "basic"] : [mode])
318
+
319
+ const openAdvance = () => {
320
+ cookieSetting.openEvent($settingBlock, () => {
321
+ if (scrollInstance) return
322
+ const scrollerEl = $settingBlock.find(".scroller")[0]
323
+ if (scrollerEl) scrollInstance = OverlayScrollbars(scrollerEl, {})
324
+ })
325
+ }
326
+
327
+ const openBasic = () => {
328
+ $cookiePolicy
329
+ .addClass("first-enter")
330
+ .removeClass("agree hidden")
331
+
332
+ // 如果你只是要等動畫再 show,建議先清掉舊的 timer,避免連點造成閃爍
333
+ clearTimeout(cookieAdvanced._basicTimer)
334
+ cookieAdvanced._basicTimer = setTimeout(() => {
335
+ $cookiePolicy.addClass("show")
336
+ }, 800)
337
+ }
338
+
339
+ if (targets.has("advance")) openAdvance()
340
+ if (targets.has("basic")) openBasic()
341
+ }
342
+
343
+ // 啟用進階版 cookie 所有選項
344
+ if ($this.is("[data-cookie-all]")) {
345
+ cookieSetting.enableAll()
346
+ }
347
+
348
+ // 關閉進階版 cookie 所有選項
349
+ if ($this.is("[data-cookie-reject]")) {
350
+ cookieSetting.rejectAll()
351
+ cookieAdvanced.cookieSaveFn()
352
+ }
353
+
354
+ // 關閉進階版 cookie 視窗
355
+ if ($this.is("[data-cookie-close]")) {
356
+ const mode = $this.attr("data-cookie-close")
357
+ const targets = new Set(mode === "all" ? ["basic", "advance"] : [mode])
358
+
359
+ const closeAdvance = () => {
360
+ cookieSetting.closeEvent($settingBlock)
361
+ }
362
+
363
+ const closeBasic = () => {
364
+ $cookiePolicy.addClass("hidden")
365
+ sessionStorage.setItem(el, "true")
366
+ }
367
+
368
+ if (targets.has("advance")) closeAdvance()
369
+ if (targets.has("basic")) closeBasic()
370
+ }
371
+
372
+ // 儲存, 放在預存當前選項的按鈕上(功能:將目前選項紀錄預存至 cookie 中, 尚未真正啟用)
373
+ if ($this.is("[data-cookie-save]")) {
374
+ cookieAdvanced.cookieSaveFn()
375
+ }
376
+
377
+ // 放在真正要啟動 cookie 功能的儲存按鈕上(功能:依照目前 save 的 cookie 選項, 執行後端程式)
378
+ if ($this.is("[data-cookie-run]")) {
379
+ if (typeof window._wdSetting === "function") {
380
+ window._wdSetting()
381
+ }
382
+ }
383
+ })
323
384
  }
324
385
 
325
386
  // ** --- 工具們 --- **
326
387
  // cookie 開啟方法
327
- cookieSetting.openEvent = (el) => {
388
+ cookieSetting.openEvent = (el, scrollInit) => {
328
389
  $(el).addClass("active")
329
390
  setTimeout(() => {
330
391
  $(el).addClass("show")
331
- scrollLock();
332
- const scrollers = $(".cookie-setting").find('.scroller')[0]
333
- OverlayScrollbars(scrollers, {})
334
- }, 500);
392
+ scrollLock()
393
+ scrollInit?.()
394
+ }, 500)
335
395
  }
336
396
 
337
397
  // cookie 關閉方法
338
398
  cookieSetting.closeEvent = (el) => {
339
399
  $(el).removeClass("show")
400
+
340
401
  setTimeout(() => {
341
402
  $(el).removeClass("active")
342
- scrollUnlock();
343
- }, 500);
403
+ scrollUnlock()
404
+ }, 500)
344
405
  }
345
406
 
346
407
  // 全部打開
347
408
  cookieSetting.enableAll = () => {
348
409
  $(`input[type="checkbox"][data-name]:not(.disabled)`).prop('checked', true).trigger('change')
349
410
  $('.main-option:not([data-name="required"]),.list-option:not([data-name="required"])').addClass("checked")
350
- cookieNewObj.close == 0
411
+ cookieNewObj.close = 0
351
412
  Object.keys(cookieNewObj).forEach(data => {
352
413
  cookieNewObj[data].close == 0
353
414
  })
@@ -365,73 +426,73 @@ cookieSetting.rejectAll = () => {
365
426
 
366
427
  // 判斷該分類底下細項按鈕狀態
367
428
  cookieSetting.hasAnyListItemsOpen = (key) => {
368
- const category = cookieNewObj[key];
369
- if (!category) return false;
429
+ const category = cookieNewObj[key]
430
+ if (!category) return false
370
431
 
371
- const targetList = category.list;
432
+ const targetList = category.list
372
433
 
373
434
  // 沒有子 list,就看自己這一層
374
435
  if (!targetList) {
375
- return category.close === 0;
436
+ return category.close === 0
376
437
  }
377
438
 
378
439
  // 有子 list,就看子項目有沒有任何一個是 open
379
- return Object.values(targetList).some(item => item?.close === 0);
380
- };
440
+ return Object.values(targetList).some(item => item?.close === 0)
441
+ }
381
442
 
382
443
  cookieSetting.isCategoryChecked = (key) => {
383
- if (key === "required") return true;
384
- return cookieSetting.hasAnyListItemsOpen(key);
385
- };
444
+ if (key === "required") return true
445
+ return cookieSetting.hasAnyListItemsOpen(key)
446
+ }
386
447
 
387
448
  // 共用:產生 step 元件用的 getter
388
449
  const createStepElement = (templateFn) => {
389
450
  return (opt, index) => {
390
- const isDisabled = opt.disabled ? "disabled" : "";
451
+ const isDisabled = opt.disabled ? "disabled" : ""
391
452
  const isChecked = () =>
392
- cookieSetting.isCategoryChecked(opt.key) ? "checked" : "";
453
+ cookieSetting.isCategoryChecked(opt.key) ? "checked" : ""
393
454
 
394
- return templateFn(opt, index, isDisabled, isChecked);
395
- };
396
- };
455
+ return templateFn(opt, index, isDisabled, isChecked)
456
+ }
457
+ }
397
458
 
398
459
  // step 1 結構
399
- cookieElements.getStep1Element = createStepElement(cookieStep1El);
460
+ cookieElements.getStep1Element = createStepElement(cookieStep1El)
400
461
  // step 2 上面結構
401
- cookieElements.getStep2TopElement = createStepElement(cookieStep2TittleEl);
462
+ cookieElements.getStep2TopElement = createStepElement(cookieStep2TittleEl)
402
463
 
403
464
  // 頁籤
404
465
  cookieSetting.goToTab = (el = true) => {
405
466
  const tab = $('tab-el[t4-name="cookie-tab"]')
406
467
  const $step2 = $(".setting-container[t4-id='step2']")
407
468
  if (el) {
408
- tab[0].goNext();
469
+ tab[0].goNext()
409
470
  } else {
410
- tab[0].goPrev();
411
- $step2.find(".top-block, .content-block").empty();
471
+ tab[0].goPrev()
472
+ $step2.find(".top-block, .content-block").empty()
412
473
  }
413
474
  }
414
475
 
415
- methods.toBackend({
476
+ methods.toBackend({
416
477
  getCookieValue: (el) => Cookies.get(el),
417
478
  cookieGoToNext: (el) => cookieSetting.goToTab(el),
418
- });
479
+ })
419
480
 
420
481
  // init
421
- cookieAdvanced.init = () => {
422
- cookieAdvanced.newObj();
423
- cookieAdvanced.dataAppend();
424
- // cookieAdvanced.initialState();
425
- cookieAdvanced.clickEvent();
426
- cookieAdvanced.cookieSaveFn();
427
- cookieAdvanced.switchState();
482
+ cookieAdvanced.init = (el) => {
483
+ cookieAdvanced.newObj()
484
+ cookieAdvanced.dataAppend()
485
+ // cookieAdvanced.initialState()
486
+ cookieAdvanced.clickEvent(el)
487
+ cookieAdvanced.cookieSaveFn()
488
+ cookieAdvanced.switchState()
428
489
  }
429
490
 
430
491
  // 預設為 false -> 基礎版, true -> 進階版
431
- export const init = (isOpenAdvanced = false) => {
492
+ export const init = (isOpenAdvanced = false, el) => {
432
493
  // cookie 基本版
433
- cookieBasic.basicCookiePolicy();
494
+ cookieBasic.basicCookiePolicy(el)
434
495
  if (!isOpenAdvanced) return
435
496
  // cookie 進階版
436
- cookieAdvanced.init();
497
+ cookieAdvanced.init(el)
437
498
  }
@@ -54,8 +54,8 @@ export const inits = () => {
54
54
  new ImageValidate();
55
55
  // uiInit
56
56
  navbar.init();
57
- // 預設為 false -> 基礎版, true -> 進階版
58
- cookie.init(true);
57
+ // 預設為 false -> 基礎版, true -> 進階版, 各專案 key 名要記得更改
58
+ cookie.init(true,"frameworkCookie-agree");
59
59
  // coding...
60
60
  firstEntryHandler.init();
61
61
  }
@@ -12,7 +12,9 @@ nav.navbar
12
12
  li
13
13
  a(href="./play.html") Play
14
14
  li
15
- a(href="javascript:;" data-cookie-open) cookie 設定
15
+ div(data-cookie data-cookie-open="basic") cookie 設定
16
+ li
17
+ div(data-cookie data-cookie-open="advance") cookie 進階設定
16
18
  li
17
19
  a(href="javascript:;" data-modal-target="my-modal") 燈箱
18
20
  li
@@ -52,3 +52,8 @@ html(lang="zh-Hant-TW" data-overlayscrollbars-initialize)
52
52
  modern-modal(data-modal-id="my-modal" data-modal-animate="clip-right")
53
53
  .close-btn(data-modal-close)
54
54
  .title Modal4
55
+ .photo-box(video-target video-id="5bMdjkfvONE" video-type="youtube" video-mode="onPage")
56
+ picture
57
+ source(srcset="https://cdn.wdd.idv.tw/image/video-cover02.webp" type="image/webp")
58
+ source(srcset="https://cdn.wdd.idv.tw/image/video-cover02.jpg" type="image/jpeg")
59
+ img(src="https://cdn.wdd.idv.tw/image/video-cover02.jpg" alt="")
@@ -1,4 +1,12 @@
1
1
  // 基本版 cookie
2
+ //- .close & .agree 按鈕名字需保留, 不可更改
3
+ //- 若需要以下按鈕功能, 按鈕必須加上 [data-cookie]
4
+ //- [data-cookie-open="xxx"] -> 開啟 cookie 介面按鈕功能綁定, 值: basic(基本)/advance(進階)/all(所有)
5
+ //- [data-cookie-close="xxx"] -> 關閉 cookie 視窗, 值: basic(基本)/advance(進階)/all(所有)
6
+ //- [data-cookie-reject] -> 關閉進階版 cookie 所有選項
7
+ //- [data-cookie-all] -> 啟用進階版 cookie 所有選項
8
+ //- [data-cookie-save] -> 放在預存當前選項的按鈕上(功能:將目前選項紀錄預存至 cookie 中, 尚未真正啟用)
9
+ //- [data-cookie-run] -> 放在真正要啟動 cookie 功能的儲存按鈕上(功能:依照目前 save 的 cookie 選項, 執行後端程式)
2
10
  .cookie-check
3
11
  .cookie-main
4
12
  .cookie-container
@@ -7,10 +15,10 @@
7
15
  p.text 關於本網站使用瀏覽器紀錄 Cookie 來提供您最好的使用體驗,我們使用的 Cookie 也包括了第三方 Cookie 。<br>相關資訊請訪問我們的隱私權與 Cookie 政策。如果您選擇繼續瀏覽或關閉這個提示,便表示您已接受我們的網站使用條款。
8
16
  .button-group
9
17
  // [data-cookie-reject] -> 全部關閉; [data-cookie-save] -> 儲存 cookie
10
- .cookie-btn.close(data-cookie-reject) Reject 我拒絕
11
- .cookie-btn.agree(data-cookie-save) OK 我接受
18
+ .cookie-btn.close(data-cookie data-cookie-reject) Reject 我拒絕
19
+ .cookie-btn.agree(data-cookie data-cookie-save) OK 我接受
12
20
  // 若此專案無開進階版 cookie, 請移除以下結構!
13
- .cookie-setting-btn
21
+ .cookie-setting-btn(data-cookie data-cookie-open="advance")
14
22
  span Cookie 偏好設定
15
23
  .icon
16
24
  i.icon-arrow
@@ -19,7 +27,8 @@
19
27
  // 若此專案無開進階版 cookie, 請移除以下結構!
20
28
  .cookie-setting
21
29
  .scroller
22
- .setting-main
30
+ // 多語系 ** --switch-openText: 開啟按鈕文字設定 / --switch-closeText: 關閉按鈕文字設定
31
+ .setting-main(style=`--switch-openText: "啟用";--switch-closeText: "拒絕";`)
23
32
  tab-el(t4-name="cookie-tab" t4-type="process" t4-group='false')
24
33
  // 步驟 1
25
34
  .setting-container(t4-role="tabPanel" t4-id='step1')
@@ -29,8 +38,8 @@
29
38
  .content-block
30
39
  // JS append 結構 (cookieStep1El)
31
40
  .button-group
32
- .cookie-btn.open(data-cookie-all) 啟用所有 Cookie
33
- .cookie-btn.save(data-cookie-close) SAVE 儲存本次變更
41
+ .cookie-btn.open(data-cookie data-cookie-all) 啟用所有 Cookie
42
+ .cookie-btn.save(data-cookie data-cookie-close="advance") SAVE 儲存本次變更
34
43
  // 步驟 2
35
44
  .setting-container(t4-role="tabPanel" t4-id='step2')
36
45
  .back(onClick=`document.body.fesd.cookieGoToNext(false)`)
@@ -41,6 +50,7 @@
41
50
  // JS append 結構 (cookieStep2TittleEl)
42
51
  .content-block
43
52
  // JS append 結構 (cookieStep2ContentEl)
53
+
44
54
  // 後端 cookie 資料放這兒, 先放假結構
45
55
  // 若此專案無開進階版 cookie, 請移除以下結構!
46
56
  input(type="hidden" id="_wcookie" value='')
@@ -24,11 +24,11 @@ block content
24
24
  .text
25
25
  .box
26
26
  span 您可前往
27
- span(data-cookie-open) Cookie 偏好設定
27
+ span(data-cookie data-cookie-open="advance") Cookie 偏好設定
28
28
  span 進行修改
29
29
  .box
30
30
  span Modify your
31
- span(data-cookie-open) cookie preferences.
31
+ span(data-cookie data-cookie-open="advance") cookie preferences.
32
32
  .swiper-slide
33
33
  .media-box
34
34
  video(src="https://cdn.wdd.idv.tw/video/chappie_Video1.mp4" muted playsinline)
@@ -93,13 +93,13 @@ block content
93
93
  h3 Video4 👇
94
94
  .row
95
95
  .grid
96
- .photo-box(video-target="video-ig-template" video-target-route="./ajax/ajax_igDemo.html" video-id="../../public/assets/img/banner.jpg" video-type="instagram")
96
+ .photo-box(video-target="video-ig-template" video-button="playing" video-target-route="./ajax/ajax_igDemo.html" video-id="../../public/assets/img/banner.jpg" video-type="instagram")
97
97
  picture
98
98
  source(srcset="https://cdn.wdd.idv.tw/image/video-cover01.webp" type="image/webp")
99
99
  source(srcset="https://cdn.wdd.idv.tw/image/video-cover01.jpg" type="image/jpeg")
100
100
  img(src="https://cdn.wdd.idv.tw/image/video-cover01.jpg" alt="")
101
101
  .grid
102
- .photo-box(video-target video-id="5bMdjkfvONE" video-type="youtube" video-mode="onPage")
102
+ .photo-box(video-target video-id="5bMdjkfvONE" video-type="youtube")
103
103
  picture
104
104
  source(srcset="https://cdn.wdd.idv.tw/image/video-cover02.webp" type="image/webp")
105
105
  source(srcset="https://cdn.wdd.idv.tw/image/video-cover02.jpg" type="image/jpeg")