@xwadex/fesd 0.0.1 → 0.0.3

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.
Files changed (43) hide show
  1. package/package.json +4 -1
  2. package/20240328-video4-setting.png +0 -0
  3. package/CHANGELOG.md +0 -41
  4. package/index.html +0 -25
  5. package/prepros.config +0 -883
  6. package/src/fesd/anchor4/anchor4.js +0 -179
  7. package/src/fesd/aost4/_aost4.sass +0 -64
  8. package/src/fesd/aost4/aost4.js +0 -138
  9. package/src/fesd/article4/article4.js +0 -280
  10. package/src/fesd/article4/article4.md +0 -1
  11. package/src/fesd/category-slider/_category-slider.sass +0 -33
  12. package/src/fesd/category-slider/category-slider.js +0 -332
  13. package/src/fesd/collapse4/collapse4.js +0 -159
  14. package/src/fesd/detect4/detect4.js +0 -70
  15. package/src/fesd/dropdown4/_dropdown4.sass +0 -185
  16. package/src/fesd/dropdown4/cityData.js +0 -830
  17. package/src/fesd/dropdown4/dropdown4.js +0 -647
  18. package/src/fesd/image-preview/_image-preview.sass +0 -26
  19. package/src/fesd/image-preview/image-preview.js +0 -209
  20. package/src/fesd/image-validate/_image-validate.sass +0 -21
  21. package/src/fesd/image-validate/image-validate.js +0 -84
  22. package/src/fesd/marquee4/_marquee4.sass +0 -45
  23. package/src/fesd/marquee4/marquee4.js +0 -371
  24. package/src/fesd/modal4/_modal4.sass +0 -134
  25. package/src/fesd/modal4/modal4.js +0 -236
  26. package/src/fesd/modal4/modernModal.js +0 -182
  27. package/src/fesd/multipurpose4/_multipurpose4.sass +0 -282
  28. package/src/fesd/multipurpose4/multipurpose4.js +0 -562
  29. package/src/fesd/ripple4/_ripple4.sass +0 -44
  30. package/src/fesd/ripple4/ripple4.js +0 -138
  31. package/src/fesd/share4/share4.js +0 -191
  32. package/src/fesd/shared/shared.js +0 -59
  33. package/src/fesd/shared/utils.js +0 -98
  34. package/src/fesd/tab4/_tab4.sass +0 -25
  35. package/src/fesd/tab4/tab4.js +0 -473
  36. package/src/fesd/video4/README.md +0 -3
  37. package/src/fesd/video4/_video4.sass +0 -117
  38. package/src/fesd/video4/video4.js +0 -237
  39. package/src/fesd/video4/videoPlayer.js +0 -195
  40. package/src/fesd.js +0 -53
  41. package/src/fesd.sass +0 -29
  42. package/src/fesdDB.js +0 -282
  43. package/vite.config.js +0 -37
@@ -1,237 +0,0 @@
1
- import Modal4 from '../modal4/modal4';
2
- import videoPlayer from './videoPlayer';
3
- import SHARED from './../shared/shared';
4
-
5
- import { isString, isElement, isNodeList, getAllElements, warn, error, insert } from './../shared/utils';
6
-
7
- ('use strict');
8
-
9
- // define custom element
10
- if (!customElements.get('video-player')) {
11
- customElements.define('video-player', videoPlayer);
12
- }
13
-
14
- // 判斷影片物件有沒有 video-id
15
- const hasVideoID = data => {
16
- return data.videoId !== '' || typeof data.videoId !== 'undefined' ? true : false;
17
- };
18
-
19
- // 判斷影片物件是否已經啟用
20
- const isActive = data => {
21
- return data.$selector.getAttribute('video4-active') === 'on' ? true : false;
22
- };
23
-
24
- const createPlayer = params => {
25
- return `<video-player video-id="${params.videoId}" video-type="${params.videoType}" video-autoplay="${params.videoAutoplay}"></video-player>`;
26
- };
27
-
28
- class video4 {
29
- constructor(el, options = {}) {
30
- // 可傳 string 或 element 或 nodeList
31
- if (!isString(el) && !isElement(el) && !isNodeList(el)) {
32
- error('video4', `找不到該物件 -> ${el}`);
33
- return;
34
- }
35
-
36
- this.__storage__ = {
37
- el,
38
- options,
39
- };
40
-
41
- this.#create();
42
- }
43
-
44
- #create() {
45
- const { el, options } = this.__storage__;
46
- // 從 fesdDB 提取設定
47
- const { SETTINGS, EVENTS } = fesdDB.video4;
48
-
49
- this.elements = getAllElements(el);
50
- this.options = Object.assign({}, SETTINGS, options);
51
- this.__events__ = Object.assign({}, EVENTS);
52
-
53
- if (this.options.on) {
54
- for (const [k, v] of Object.entries(this.options.on)) {
55
- this.__events__[k] = [v];
56
- }
57
- }
58
-
59
- this.#init();
60
- }
61
-
62
- #init() {
63
- const { elements, options } = this;
64
-
65
- elements.forEach(el => {
66
- el.video = {};
67
- el.video.instance = this;
68
- el.video.defaultOptions = options;
69
- el.video.params = this.#getVideoData(el);
70
-
71
- if (hasVideoID(el.video.params) && !isActive(el.video.params)) {
72
- el.setAttribute('video4-active', 'on');
73
- this.#createCover(el);
74
- }
75
-
76
- if (!hasVideoID(el.video.params)) {
77
- error('video4', `無法取得影片 ID`);
78
- }
79
- });
80
-
81
- this.emit('init');
82
- }
83
-
84
- #createCover(el) {
85
- const { LAYOUT } = fesdDB.video4;
86
- const params = el.video.params;
87
- const { $selector, videoLayoutNo, videoId, videoType, videoMode, videoButton, videoCover } = params;
88
-
89
- if (videoMode === 'onBox') {
90
- let $target = null;
91
- if (videoCover === 'on') {
92
- el.classList.add('video4-cover');
93
- // 無圖片結構放置圖片結構
94
- if (!$selector.querySelector('img')) {
95
- $selector.insertAdjacentHTML(insert.prepend, '<picture><source srcset="" type="image/webp"><source srcset="" type="image/jpeg"><img src="" alt></picture>');
96
- warn('video4', `若啟用 [videoCover] 且選擇 onBox 模式必須於 video-target 內放置 img 結構,若無結構則自動加入圖片結構`);
97
- }
98
-
99
- const $cover = $selector.querySelector('img');
100
- $cover.insertAdjacentHTML(insert.after, LAYOUT[videoLayoutNo]);
101
-
102
- const src = $cover?.getAttribute('src') || $cover?.getAttribute('data-src');
103
-
104
- // 無圖片時放置預設封面畫面,僅 youtube & vimeo 提供
105
- if (!src && videoType == 'youtube') {
106
- $cover.setAttribute('src', `https://img.youtube.com/vi/${videoId}/0.jpg`);
107
- } else if (!src && videoType == 'vimeo') {
108
- $cover.setAttribute('src', `https://vumbnail.com/${videoId}_large.jpg`);
109
- } else {
110
- warn('video4', `僅 youtube & vimeo 提供,無圖片時放置預設封面畫面,其他影片平台請自行上傳封面照片`);
111
- }
112
- }
113
-
114
- // 若無設定撥放按鈕,則點擊物件轉移為物件本身
115
- if (videoButton == 'off') {
116
- $target = $selector;
117
- } else {
118
- $target = $selector.querySelector(videoButton) ?? $selector;
119
- if (!$selector.querySelector(videoButton)) {
120
- warn('video4', `找不到 videoButton 設定的 element -> '${videoButton}' , 點擊物件轉移至 '${this.__storage__.el}'`);
121
- }
122
- }
123
-
124
- if (!$target.video) {
125
- $target.video = {};
126
- $target.video.params = params;
127
- }
128
-
129
- $target.video.eventHandler = this.#trigger;
130
- $target.addEventListener('click', $target.video.eventHandler);
131
- } else if (videoMode === 'onPage') {
132
- let $target = null;
133
- if (videoCover == 'on') {
134
- el.classList.add('video4-cover');
135
- // 無圖片結構放置圖片結構
136
- if (!$selector.querySelector('img')) {
137
- $selector.insertAdjacentHTML(insert.prepend, '<picture><source srcset="" type="image/webp"><source srcset="" type="image/jpeg"><img src="" alt></picture>');
138
- warn('video', `若啟用 [videoCover] 且選擇 onBox 模式必須於 video-target 內放置 img 結構`);
139
- }
140
-
141
- const $cover = $selector.querySelector('img');
142
- $cover.insertAdjacentHTML(insert.after, LAYOUT[videoLayoutNo]);
143
-
144
- const src = $cover?.getAttribute('src') || $cover?.getAttribute('data-src');
145
-
146
- // 無圖片時放置預設封面畫面,僅 youtube 提供
147
- if (!src && videoType == 'youtube') {
148
- $cover.setAttribute('src', `https://img.youtube.com/vi/${videoId}/0.jpg`);
149
- } else if (!src && videoType == 'vimeo') {
150
- $cover.setAttribute('src', `https://vumbnail.com/${videoId}_large.jpg`);
151
- } else if (!src) {
152
- warn('video4', `僅 youtube & vimeo 提供,無圖片時放置預設封面畫面,其他影片平台請自行上傳封面照片`);
153
- }
154
-
155
- // 若無設定撥放按鈕,則點擊物件轉移為物件本身
156
- if (videoButton == 'off') {
157
- $target = $selector;
158
- } else {
159
- $target = $selector.querySelector(videoButton) ?? $selector;
160
- if (!$selector.querySelector(videoButton)) {
161
- warn('video4', `找不到 videoButton 設定的 element -> '${videoButton}', 點擊物件轉移至 '${this.__storage__.el}'`);
162
- }
163
- }
164
- } else {
165
- $selector.innerHTML = createPlayer(params);
166
- return;
167
- }
168
-
169
- if (!$target.video) {
170
- $target.video = {};
171
- $target.video.params = params;
172
- }
173
-
174
- $target.video.eventHandler = this.#trigger;
175
- $target.addEventListener('click', $target.video.eventHandler);
176
- }
177
- }
178
-
179
- #trigger(e) {
180
- const { video } = this;
181
- const { $selector, videoMode, videoTarget, videoTargetRoute } = video.params;
182
-
183
- if (videoMode == 'onBox') {
184
- const options = {
185
- target: videoTarget,
186
- route: videoTargetRoute,
187
- on: {
188
- complete(modal) {
189
- modal.querySelector('.modal-content').insertAdjacentHTML('beforeend', createPlayer(video.params));
190
- },
191
- open(modal) {
192
- const scrollers = modal.querySelectorAll('[data-overlayscrollbars-viewport]');
193
- _g.lazy.update();
194
- _g.scrollLock([...scrollers]);
195
- },
196
- close(modal) {
197
- const scrollers = modal.querySelectorAll('[data-overlayscrollbars-viewport]');
198
- _g.scrollUnlock([...scrollers]);
199
- },
200
- destroy(modal) {},
201
- },
202
- };
203
-
204
- Modal4.open(options);
205
- } else if (videoMode == 'onPage') {
206
- // onPage 點擊後應自動撥放影片
207
- video.params.videoAutoplay = 'on';
208
- // 直接替換 cover & playButton
209
- $selector.innerHTML = createPlayer(video.params);
210
- }
211
- }
212
-
213
- #getVideoData(el) {
214
- const { SETTINGS } = fesdDB.video4;
215
-
216
- return {
217
- $selector: el,
218
- videoId: el.getAttribute('video-id'),
219
- videoType: el.getAttribute('video-type'),
220
- videoAutoplay: el.getAttribute('video-autoplay') || SETTINGS.videoAutoplay,
221
- videoMode: el.getAttribute('video-mode') || SETTINGS.videoMode,
222
- videoButton: el.getAttribute('video-button') || SETTINGS.videoButton,
223
- videoCover: el.getAttribute('video-cover') || SETTINGS.videoCover,
224
- videoLayoutNo: el.getAttribute('video-layout-no') || SETTINGS.videoLayoutNo,
225
- videoTarget: el.getAttribute('video-target') || SETTINGS.videoTarget,
226
- videoTargetRoute: el.getAttribute('video-target-route') || SETTINGS.videoTargetRoute,
227
- };
228
- }
229
-
230
- update() {
231
- this.#create();
232
- }
233
- }
234
-
235
- Object.assign(video4.prototype, SHARED);
236
-
237
- export default video4;
@@ -1,195 +0,0 @@
1
-
2
- import { insert, warn } from './../shared/utils';
3
-
4
- 'use strict'
5
-
6
- // create template method
7
- const createTemplate = (el) => {
8
- const { TEMPLATE } = fesdDB.video4
9
- const { childDom } = el
10
- const container = document.createElement('div')
11
- container.innerHTML = TEMPLATE();
12
-
13
- const content = container.querySelector('.player-wrapper');
14
- [...childDom].forEach((child) => {
15
- content.append(child);
16
- });
17
-
18
- return container.children[0];
19
- };
20
-
21
- // class
22
- class videoPlayer extends HTMLElement {
23
- constructor() {
24
- super();
25
-
26
- this.#create();
27
- }
28
-
29
- #create() {
30
- if (!this.getAttribute('video-id')) {
31
- warn('videoPlayer', `video-render needs a ['video-id'] attribute to creat player.`);
32
- return;
33
- }
34
-
35
- this.videoId = this.getAttribute('video-id');
36
- this.videoType = this.getAttribute('video-type');
37
- this.autoplay = this.getAttribute('video-autoplay');
38
-
39
- this.#mount();
40
- }
41
-
42
- #mount() {
43
- this.childDom = this.childNodes;
44
- this.template = createTemplate(this);
45
-
46
- // 清空原本結構
47
- this.innerHTML = '';
48
- // 放置整理過後的結構
49
- this.append(this.template);
50
-
51
- this.#init();
52
- }
53
-
54
- #init() {
55
- const { videoType } = this;
56
- let layout = '';
57
-
58
- switch (videoType) {
59
- case 'youtubeAPI':
60
- // this.#youtubeAPI();
61
- break;
62
- case 'youtube':
63
- layout = this.#youtube();
64
- break;
65
- case 'youkuAPI':
66
- // this.#youkuAPI();
67
- break;
68
- case 'youku':
69
- layout = this.#youku();
70
- break;
71
- case 'vimeo':
72
- layout = this.#vimeo();
73
- break;
74
- case 'bilibili':
75
- layout = this.#bilibili();
76
- break;
77
- case 'videojs':
78
- // this.#videoJs();
79
- break;
80
- default:
81
- break;
82
- }
83
-
84
- this.querySelector('.player-wrapper').insertAdjacentHTML(insert.prepend, layout);
85
- }
86
-
87
- // youtube iframe
88
- #youtube() {
89
- const { videoId, autoplay } = this;
90
- return `<iframe src="https://www.youtube.com/embed/${videoId}?rel=0&${
91
- autoplay === 'on' ? 'autoplay=1' : ''
92
- }&mute=1&loop=1&enablejsapi=1" frameborder="0" allowfullscreen="0" volumn="0" allow="${
93
- autoplay === 'on' ? 'autoplay;' : ''
94
- } encrypted-media; gyroscope; picture-in-picture;"></iframe>`;
95
- }
96
-
97
- // vimeo iframe
98
- #vimeo() {
99
- const { videoId, autoplay, hash } = this;
100
-
101
- return `<iframe src="https://player.vimeo.com/video/${videoId}?h=${hash}&${
102
- autoplay === 'on' ? 'autoplay=1' : ''
103
- }&loop=1&color=ffffff&title=0&byline=0&portrait=0" frameborder="0" allow="${
104
- autoplay === 'on' ? 'autoplay;' : ''
105
- } fullscreen; picture-in-picture" allowfullscreen></iframe><script src="https://player.vimeo.com/api/player.js"></script>`;
106
- }
107
-
108
- // youku iframe
109
- #youku() {
110
- const { videoId, autoplay } = this;
111
-
112
- return `<iframe src="https://player.youku.com/embed/${videoId}?rel=0&${
113
- autoplay === 'on' ? 'autoplay=1' : ''
114
- }" frameborder=0 "allowfullscreen"></iframe>`;
115
- }
116
-
117
- #bilibili() {
118
- const { videoId, autoplay } = this;
119
- return `<iframe src="//player.bilibili.com/player.html?bvid=${videoId}&page=1&as_wide=1&high_quality=1&danmaku=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>`
120
- }
121
-
122
- play() {
123
- const { videoType } = this;
124
-
125
- switch (videoType) {
126
- case 'youtubeAPI':
127
- // 無可用 functione
128
- break;
129
- case 'youtube':
130
- this.querySelector('iframe').contentWindow.postMessage(
131
- JSON.stringify({ event: 'command', func: 'playVideo' }),
132
- '*'
133
- );
134
- break;
135
- case 'youkuAPI':
136
- // 無可用 functione
137
- break;
138
- case 'youku':
139
- // 無可用 functione
140
- break;
141
- case 'vimeo':
142
- this.querySelector('iframe').contentWindow.postMessage(
143
- JSON.stringify({ value: 'true', method: 'play' }),
144
- '*'
145
- );
146
- break;
147
- case 'bilibili':
148
- // 無可用 functione
149
- break;
150
- case 'videojs':
151
- // 無可用 functione
152
- break;
153
- default:
154
- break;
155
- }
156
- }
157
-
158
- pause() {
159
- const { videoType } = this;
160
-
161
- switch (videoType) {
162
- case 'youtubeAPI':
163
- // 無可用 functione
164
- break;
165
- case 'youtube':
166
- this.querySelector('iframe').contentWindow.postMessage(
167
- JSON.stringify({ event: 'command', func: 'pauseVideo' }),
168
- '*'
169
- );
170
- break;
171
- case 'youkuAPI':
172
- // 無可用 functione
173
- break;
174
- case 'youku':
175
- // 無可用 functione
176
- break;
177
- case 'vimeo':
178
- this.querySelector('iframe').contentWindow.postMessage(
179
- JSON.stringify({ value: 'true', method: 'pause' }),
180
- '*'
181
- );
182
- break;
183
- case 'bilibili':
184
- // 無可用 functione
185
- break;
186
- case 'videojs':
187
- // 無可用 functione
188
- break;
189
- default:
190
- break;
191
- }
192
- }
193
- }
194
-
195
- export default videoPlayer;
package/src/fesd.js DELETED
@@ -1,53 +0,0 @@
1
- import './fesd.sass';
2
- // 卷軸套件
3
- import 'overlayscrollbars/overlayscrollbars.css';
4
- // Swiper_V8
5
- import 'swiper/css/bundle';
6
-
7
- // FESD_DB
8
- export { default as FESD_DB } from './fesdDB.js';
9
-
10
- // Detect4
11
- export { default as Detect4 } from './fesd/detect4/detect4';
12
-
13
- // Anchor4
14
- export { default as Anchor4 } from './fesd/anchor4/anchor4';
15
-
16
- // Modal4
17
- export { default as Modal4 } from './fesd/modal4/modal4';
18
-
19
- // Aost4
20
- export { default as Aost4 } from './fesd/aost4/aost4';
21
-
22
- // Article4
23
- export { default as Article4 } from './fesd/article4/article4';
24
-
25
- // Video4
26
- export { default as Video4 } from './fesd/video4/video4';
27
-
28
- // Share4
29
- export { default as Share4 } from './fesd/share4/share4';
30
-
31
- // Dropdown4
32
- export { default as Dropdown4 } from './fesd/dropdown4/dropdown4';
33
-
34
- // Marquee4
35
- export { default as Marquee4 } from './fesd/marquee4/marquee4';
36
-
37
- // Multipurpose4
38
- export { default as Multipurpose4 } from './fesd/multipurpose4/multipurpose4';
39
-
40
- // Tab4
41
- export { default as Tab4 } from './fesd/tab4/tab4';
42
-
43
- // Collapse4
44
- export { default as Collapse4 } from './fesd/collapse4/collapse4';
45
-
46
- // Ripple4
47
- export { default as Ripple4 } from './fesd/ripple4/ripple4';
48
-
49
- // image-validate
50
- export { default as ImageValidate } from './fesd/image-validate/image-validate';
51
-
52
- // image-preview
53
- export { default as ImagePreview } from './fesd/image-preview/image-preview';
package/src/fesd.sass DELETED
@@ -1,29 +0,0 @@
1
- // Modal4
2
- @import './fesd/modal4/_modal4.sass'
3
-
4
- // Aost4
5
- @import './fesd/aost4/_aost4.sass'
6
-
7
- // Video4
8
- @import './fesd/video4/_video4.sass'
9
-
10
- // Dropdown4
11
- @import './fesd/dropdown4/_dropdown4.sass'
12
-
13
- // Marquee4
14
- @import './fesd/marquee4/_marquee4.sass'
15
-
16
- // Multipurpose4
17
- @import './fesd/multipurpose4/_multipurpose4.sass'
18
-
19
- // Tab4
20
- @import './fesd/tab4/_tab4.sass'
21
-
22
- // Ripple4
23
- @import './fesd/ripple4/_ripple4.sass'
24
-
25
- // image-validate
26
- @import './fesd/image-validate/_image-validate.sass'
27
-
28
- // image-preview
29
- @import './fesd/image-preview/_image-preview.sass'