uikit 3.16.4-dev.fd2458e3b → 3.16.5-dev.dda1f1b31

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 (120) hide show
  1. package/.eslintrc.json +1 -0
  2. package/CHANGELOG.md +9 -1
  3. package/build/build.js +5 -4
  4. package/build/icons.js +2 -1
  5. package/build/less.js +2 -11
  6. package/build/prefix.js +2 -1
  7. package/build/release.js +4 -3
  8. package/build/scope.js +2 -1
  9. package/build/scss.js +2 -1
  10. package/build/util.js +3 -3
  11. package/dist/css/uikit-core-rtl.css +1 -1
  12. package/dist/css/uikit-core-rtl.min.css +1 -1
  13. package/dist/css/uikit-core.css +1 -1
  14. package/dist/css/uikit-core.min.css +1 -1
  15. package/dist/css/uikit-rtl.css +1 -1
  16. package/dist/css/uikit-rtl.min.css +1 -1
  17. package/dist/css/uikit.css +1 -1
  18. package/dist/css/uikit.min.css +1 -1
  19. package/dist/js/components/countdown.js +12 -14
  20. package/dist/js/components/countdown.min.js +1 -1
  21. package/dist/js/components/filter.js +506 -22
  22. package/dist/js/components/filter.min.js +1 -1
  23. package/dist/js/components/lightbox-panel.js +2601 -310
  24. package/dist/js/components/lightbox-panel.min.js +1 -1
  25. package/dist/js/components/lightbox.js +2612 -323
  26. package/dist/js/components/lightbox.min.js +1 -1
  27. package/dist/js/components/notification.js +1 -1
  28. package/dist/js/components/notification.min.js +1 -1
  29. package/dist/js/components/parallax.js +466 -43
  30. package/dist/js/components/parallax.min.js +1 -1
  31. package/dist/js/components/slider-parallax.js +184 -2
  32. package/dist/js/components/slider-parallax.min.js +1 -1
  33. package/dist/js/components/slider.js +2345 -49
  34. package/dist/js/components/slider.min.js +1 -1
  35. package/dist/js/components/slideshow-parallax.js +184 -2
  36. package/dist/js/components/slideshow-parallax.min.js +1 -1
  37. package/dist/js/components/slideshow.js +2339 -49
  38. package/dist/js/components/slideshow.min.js +1 -1
  39. package/dist/js/components/sortable.js +472 -1
  40. package/dist/js/components/sortable.min.js +1 -1
  41. package/dist/js/components/tooltip.js +2298 -11
  42. package/dist/js/components/tooltip.min.js +1 -1
  43. package/dist/js/components/upload.js +1 -1
  44. package/dist/js/components/upload.min.js +1 -1
  45. package/dist/js/uikit-core.js +951 -931
  46. package/dist/js/uikit-core.min.js +1 -1
  47. package/dist/js/uikit-icons.js +153 -152
  48. package/dist/js/uikit-icons.min.js +1 -1
  49. package/dist/js/uikit.js +979 -954
  50. package/dist/js/uikit.min.js +1 -1
  51. package/package.json +2 -2
  52. package/src/images/icons/mastodon.svg +3 -0
  53. package/src/js/api/app.js +12 -0
  54. package/src/js/api/boot.js +64 -43
  55. package/src/js/api/component.js +60 -61
  56. package/src/js/api/computed.js +39 -0
  57. package/src/js/api/events.js +45 -0
  58. package/src/js/api/global.js +58 -56
  59. package/src/js/api/hooks.js +35 -114
  60. package/src/js/api/index.js +8 -24
  61. package/src/js/api/instance.js +55 -55
  62. package/src/js/api/log.js +10 -0
  63. package/src/js/api/observables.js +125 -0
  64. package/src/js/api/observer.js +76 -0
  65. package/src/js/{util → api}/options.js +38 -1
  66. package/src/js/api/props.js +102 -0
  67. package/src/js/api/state.js +26 -280
  68. package/src/js/api/update.js +77 -0
  69. package/src/js/api/watch.js +34 -0
  70. package/src/js/components/countdown.js +14 -16
  71. package/src/js/components/filter.js +18 -24
  72. package/src/js/components/internal/slider-preload.js +5 -6
  73. package/src/js/components/lightbox-panel.js +1 -1
  74. package/src/js/components/lightbox.js +11 -23
  75. package/src/js/components/parallax.js +8 -6
  76. package/src/js/components/slider.js +10 -0
  77. package/src/js/components/tooltip.js +2 -1
  78. package/src/js/core/accordion.js +5 -6
  79. package/src/js/core/cover.js +9 -9
  80. package/src/js/core/drop.js +13 -6
  81. package/src/js/core/dropnav.js +1 -1
  82. package/src/js/core/grid.js +2 -5
  83. package/src/js/core/height-match.js +9 -16
  84. package/src/js/core/height-viewport.js +5 -7
  85. package/src/js/core/img.js +12 -19
  86. package/src/js/core/leader.js +4 -2
  87. package/src/js/core/margin.js +11 -21
  88. package/src/js/core/modal.js +1 -1
  89. package/src/js/core/offcanvas.js +6 -2
  90. package/src/js/core/overflow-auto.js +5 -5
  91. package/src/js/core/responsive.js +5 -7
  92. package/src/js/core/scroll.js +19 -10
  93. package/src/js/core/scrollspy-nav.js +6 -5
  94. package/src/js/core/scrollspy.js +27 -36
  95. package/src/js/core/sticky.js +12 -10
  96. package/src/js/core/svg.js +4 -2
  97. package/src/js/core/switcher.js +11 -9
  98. package/src/js/core/toggle.js +4 -4
  99. package/src/js/core/video.js +6 -14
  100. package/src/js/mixin/modal.js +2 -1
  101. package/src/js/mixin/parallax.js +1 -1
  102. package/src/js/mixin/slider-nav.js +2 -1
  103. package/src/js/mixin/slider.js +9 -3
  104. package/src/js/util/filter.js +13 -0
  105. package/src/js/util/index.js +0 -1
  106. package/src/js/util/keys.js +11 -0
  107. package/src/js/util/lang.js +7 -7
  108. package/src/js/util/observer.js +4 -2
  109. package/src/js/util/scroll.js +42 -0
  110. package/src/js/util/svg.js +16 -0
  111. package/src/js/util/viewport.js +1 -1
  112. package/src/scss/mixins-theme.scss +1640 -1596
  113. package/src/scss/mixins.scss +1370 -1370
  114. package/src/scss/variables-theme.scss +1255 -1255
  115. package/src/scss/variables.scss +1113 -1113
  116. package/src/js/mixin/lazyload.js +0 -27
  117. package/src/js/mixin/resize.js +0 -11
  118. package/src/js/mixin/scroll.js +0 -32
  119. package/src/js/mixin/swipe.js +0 -72
  120. package/src/js/mixin/utils.js +0 -91
@@ -1,126 +1,47 @@
1
- import { assign, fastdom, hasOwn, isEqual, isPlainObject } from 'uikit-util';
2
-
3
- export default function (UIkit) {
4
- UIkit.prototype._callHook = function (hook) {
5
- this.$options[hook]?.forEach((handler) => handler.call(this));
6
- };
7
-
8
- UIkit.prototype._callConnected = function () {
9
- if (this._connected) {
10
- return;
11
- }
12
-
13
- this._data = {};
14
- this._computed = {};
15
-
16
- this._initProps();
17
-
18
- this._callHook('beforeConnect');
19
- this._connected = true;
20
-
21
- this._initEvents();
22
- this._initObservers();
23
-
24
- this._callHook('connected');
25
- this._callUpdate();
26
- };
27
-
28
- UIkit.prototype._callDisconnected = function () {
29
- if (!this._connected) {
30
- return;
31
- }
32
-
33
- this._callHook('beforeDisconnect');
34
- this._disconnectObservers();
35
- this._unbindEvents();
36
- this._callHook('disconnected');
37
-
38
- this._connected = false;
39
- delete this._watch;
40
- };
41
-
42
- UIkit.prototype._callUpdate = function (e = 'update') {
43
- if (!this._connected) {
44
- return;
45
- }
46
-
47
- if (e === 'update' || e === 'resize') {
48
- this._callWatches();
49
- }
50
-
51
- if (!this.$options.update) {
52
- return;
53
- }
54
-
55
- if (!this._updates) {
56
- this._updates = new Set();
57
- fastdom.read(() => {
58
- if (this._connected) {
59
- runUpdates.call(this, this._updates);
60
- }
61
- delete this._updates;
62
- });
63
- }
1
+ import { log } from './log';
2
+ import { callUpdate, initUpdateObserver } from './update';
3
+ import { initEvents, unbindEvents } from './events';
4
+ import { initProps, initPropsObserver } from './props';
5
+ import { disconnectObservers, initObservers } from './observer';
6
+
7
+ export function callHook(instance, hook) {
8
+ DEBUG && log(instance, hook);
9
+ instance.$options[hook]?.forEach((handler) => handler.call(instance));
10
+ }
64
11
 
65
- this._updates.add(e.type || e);
66
- };
12
+ export function callConnected(instance) {
13
+ if (instance._connected) {
14
+ return;
15
+ }
67
16
 
68
- UIkit.prototype._callWatches = function () {
69
- if (this._watch) {
70
- return;
71
- }
17
+ instance._data = {};
18
+ instance._computed = {};
72
19
 
73
- const initial = !hasOwn(this, '_watch');
20
+ initProps(instance);
74
21
 
75
- this._watch = fastdom.read(() => {
76
- if (this._connected) {
77
- runWatches.call(this, initial);
78
- }
79
- this._watch = null;
80
- });
81
- };
22
+ callHook(instance, 'beforeConnect');
23
+ instance._connected = true;
82
24
 
83
- function runUpdates(types) {
84
- for (const { read, write, events = [] } of this.$options.update) {
85
- if (!types.has('update') && !events.some((type) => types.has(type))) {
86
- continue;
87
- }
25
+ initEvents(instance);
88
26
 
89
- let result;
90
- if (read) {
91
- result = read.call(this, this._data, types);
27
+ initObservers(instance);
28
+ initPropsObserver(instance);
29
+ initUpdateObserver(instance);
92
30
 
93
- if (result && isPlainObject(result)) {
94
- assign(this._data, result);
95
- }
96
- }
31
+ callHook(instance, 'connected');
32
+ callUpdate(instance);
33
+ }
97
34
 
98
- if (write && result !== false) {
99
- fastdom.write(() => {
100
- if (this._connected) {
101
- write.call(this, this._data, types);
102
- }
103
- });
104
- }
105
- }
35
+ export function callDisconnected(instance) {
36
+ if (!instance._connected) {
37
+ return;
106
38
  }
107
39
 
108
- function runWatches(initial) {
109
- const {
110
- $options: { computed },
111
- } = this;
112
- const values = { ...this._computed };
113
- this._computed = {};
40
+ callHook(instance, 'beforeDisconnect');
41
+ disconnectObservers(instance);
42
+ unbindEvents(instance);
43
+ callHook(instance, 'disconnected');
114
44
 
115
- for (const key in computed) {
116
- const { watch, immediate } = computed[key];
117
- if (
118
- watch &&
119
- ((initial && immediate) ||
120
- (hasOwn(values, key) && !isEqual(values[key], this[key])))
121
- ) {
122
- watch.call(this, this[key], values[key]);
123
- }
124
- }
125
- }
45
+ instance._connected = false;
46
+ delete instance._watch;
126
47
  }
@@ -1,24 +1,8 @@
1
- import globalAPI from './global';
2
- import hooksAPI from './hooks';
3
- import stateAPI from './state';
4
- import instanceAPI from './instance';
5
- import componentAPI from './component';
6
- import * as util from 'uikit-util';
7
-
8
- const UIkit = function (options) {
9
- this._init(options);
10
- };
11
-
12
- UIkit.util = util;
13
- UIkit.data = '__uikit__';
14
- UIkit.prefix = 'uk-';
15
- UIkit.options = {};
16
- UIkit.version = VERSION;
17
-
18
- globalAPI(UIkit);
19
- hooksAPI(UIkit);
20
- stateAPI(UIkit);
21
- componentAPI(UIkit);
22
- instanceAPI(UIkit);
23
-
24
- export default UIkit;
1
+ import App from './app';
2
+ import './component';
3
+ import './global';
4
+ import './hooks';
5
+ import './state';
6
+ import './instance';
7
+
8
+ export default App;
@@ -1,74 +1,74 @@
1
- import { isEmpty, remove, within } from 'uikit-util';
1
+ import App from './app';
2
+ import { update } from './global';
3
+ import { callUpdate } from './update';
4
+ import { $, remove, within } from '../util';
5
+ import { callConnected, callDisconnected, callHook } from './hooks';
6
+ import { attachToElement, createComponent, detachFromElement, getComponent } from './component';
2
7
 
3
- export default function (UIkit) {
4
- const DATA = UIkit.data;
8
+ App.prototype.$mount = function (el) {
9
+ const instance = this;
10
+ attachToElement(el, instance);
5
11
 
6
- UIkit.prototype.$create = function (component, element, data) {
7
- return UIkit[component](element, data);
8
- };
12
+ instance.$options.el = el;
9
13
 
10
- UIkit.prototype.$mount = function (el) {
11
- const { name } = this.$options;
14
+ if (within(el, document)) {
15
+ callConnected(instance);
16
+ }
17
+ };
12
18
 
13
- if (!el[DATA]) {
14
- el[DATA] = {};
15
- }
19
+ App.prototype.$destroy = function (removeEl = false) {
20
+ const instance = this;
21
+ const { el } = instance.$options;
16
22
 
17
- if (el[DATA][name]) {
18
- return;
19
- }
23
+ if (el) {
24
+ callDisconnected(instance);
25
+ }
20
26
 
21
- el[DATA][name] = this;
27
+ callHook(instance, 'destroy');
22
28
 
23
- this.$el = this.$options.el = this.$options.el || el;
29
+ detachFromElement(el, instance);
24
30
 
25
- if (within(el, document)) {
26
- this._callConnected();
27
- }
28
- };
31
+ if (removeEl) {
32
+ remove(instance.$el);
33
+ }
34
+ };
29
35
 
30
- UIkit.prototype.$reset = function () {
31
- this._callDisconnected();
32
- this._callConnected();
33
- };
36
+ App.prototype.$create = createComponent;
37
+ App.prototype.$emit = function (e) {
38
+ callUpdate(this, e);
39
+ };
34
40
 
35
- UIkit.prototype.$destroy = function (removeEl = false) {
36
- const { el, name } = this.$options;
41
+ App.prototype.$update = function (element = this.$el, e) {
42
+ update(element, e);
43
+ };
37
44
 
38
- if (el) {
39
- this._callDisconnected();
40
- }
45
+ App.prototype.$reset = function () {
46
+ callDisconnected(this);
47
+ callConnected(this);
48
+ };
41
49
 
42
- this._callHook('destroy');
50
+ App.prototype.$getComponent = getComponent;
43
51
 
44
- if (!el?.[DATA]) {
45
- return;
46
- }
52
+ Object.defineProperties(App.prototype, {
53
+ $el: {
54
+ get() {
55
+ return this.$options.el;
56
+ },
57
+ },
47
58
 
48
- delete el[DATA][name];
59
+ $container: Object.getOwnPropertyDescriptor(App, 'container'),
60
+ });
49
61
 
50
- if (!isEmpty(el[DATA])) {
51
- delete el[DATA];
52
- }
62
+ export function generateId(instance, el = instance.$el, postfix = '') {
63
+ if (el.id) {
64
+ return el.id;
65
+ }
53
66
 
54
- if (removeEl) {
55
- remove(this.$el);
56
- }
57
- };
67
+ let id = `${instance.$options.id}-${instance._uid}${postfix}`;
58
68
 
59
- UIkit.prototype.$emit = function (e) {
60
- this._callUpdate(e);
61
- };
69
+ if ($(`#${id}`)) {
70
+ id = generateId(instance, el, `${postfix}-2`);
71
+ }
62
72
 
63
- UIkit.prototype.$update = function (element = this.$el, e) {
64
- UIkit.update(element, e);
65
- };
66
-
67
- UIkit.prototype.$getComponent = UIkit.getComponent;
68
-
69
- Object.defineProperty(
70
- UIkit.prototype,
71
- '$container',
72
- Object.getOwnPropertyDescriptor(UIkit, 'container')
73
- );
73
+ return id;
74
74
  }
@@ -0,0 +1,10 @@
1
+ export function log(instance, eventName, eventData) {
2
+ console.log(
3
+ `🔔 %s:%d %c%s`,
4
+ instance.$options.name,
5
+ instance._uid,
6
+ 'font-weight:bold;',
7
+ eventName,
8
+ [...(eventData ?? []), instance, instance.$el]
9
+ );
10
+ }
@@ -0,0 +1,125 @@
1
+ import {
2
+ $$,
3
+ getEventPos,
4
+ isFunction,
5
+ isTouch,
6
+ noop,
7
+ observeIntersection,
8
+ observeMutation,
9
+ observeResize,
10
+ on,
11
+ once,
12
+ parent,
13
+ pointerCancel,
14
+ pointerDown,
15
+ pointerUp,
16
+ removeAttr,
17
+ toNodes,
18
+ trigger,
19
+ } from '../util';
20
+
21
+ export function resize(options) {
22
+ return observe(observeResize, options, 'resize');
23
+ }
24
+
25
+ export function intersection(options) {
26
+ return observe(observeIntersection, options);
27
+ }
28
+
29
+ export function mutation(options) {
30
+ return observe(observeMutation, options);
31
+ }
32
+
33
+ export function lazyload(options = {}) {
34
+ return intersection({
35
+ handler: function (entries, observer) {
36
+ const { targets = this.$el, preload = 5 } = options;
37
+ for (const el of toNodes(isFunction(targets) ? targets(this) : targets)) {
38
+ $$('[loading="lazy"]', el)
39
+ .slice(0, preload - 1)
40
+ .forEach((el) => removeAttr(el, 'loading'));
41
+ }
42
+
43
+ for (const el of entries
44
+ .filter(({ isIntersecting }) => isIntersecting)
45
+ .map(({ target }) => target)) {
46
+ observer.unobserve(el);
47
+ }
48
+ },
49
+ ...options,
50
+ });
51
+ }
52
+
53
+ export function scroll(options) {
54
+ return observe(
55
+ function (target, handler) {
56
+ return {
57
+ disconnect: on(target, 'scroll', handler, {
58
+ passive: true,
59
+ capture: true,
60
+ }),
61
+ };
62
+ },
63
+ {
64
+ target: window,
65
+ ...options,
66
+ },
67
+ 'scroll'
68
+ );
69
+ }
70
+
71
+ export function swipe(options) {
72
+ return {
73
+ observe(target, handler) {
74
+ return {
75
+ observe: noop,
76
+ unobserve: noop,
77
+ disconnect: on(target, pointerDown, handler, { passive: true }),
78
+ };
79
+ },
80
+ handler(e) {
81
+ if (!isTouch(e)) {
82
+ return;
83
+ }
84
+
85
+ // Handle Swipe Gesture
86
+ const pos = getEventPos(e);
87
+ const target = 'tagName' in e.target ? e.target : parent(e.target);
88
+ once(document, `${pointerUp} ${pointerCancel} scroll`, (e) => {
89
+ const { x, y } = getEventPos(e);
90
+
91
+ // swipe
92
+ if (
93
+ (e.type !== 'scroll' && target && x && Math.abs(pos.x - x) > 100) ||
94
+ (y && Math.abs(pos.y - y) > 100)
95
+ ) {
96
+ setTimeout(() => {
97
+ trigger(target, 'swipe');
98
+ trigger(target, `swipe${swipeDirection(pos.x, pos.y, x, y)}`);
99
+ });
100
+ }
101
+ });
102
+ },
103
+ ...options,
104
+ };
105
+ }
106
+
107
+ function observe(observe, options, emit) {
108
+ return {
109
+ observe,
110
+ handler() {
111
+ this.$emit(emit);
112
+ },
113
+ ...options,
114
+ };
115
+ }
116
+
117
+ function swipeDirection(x1, y1, x2, y2) {
118
+ return Math.abs(x1 - x2) >= Math.abs(y1 - y2)
119
+ ? x1 - x2 > 0
120
+ ? 'Left'
121
+ : 'Right'
122
+ : y1 - y2 > 0
123
+ ? 'Up'
124
+ : 'Down';
125
+ }
@@ -0,0 +1,76 @@
1
+ import { hasOwn, includes, isArray, isEqual, isFunction, isPlainObject, isString } from '../util';
2
+
3
+ export function initObservers(instance) {
4
+ instance._observers = [];
5
+ instance._observerUpdates = new Map();
6
+ for (const observer of instance.$options.observe || []) {
7
+ if (hasOwn(observer, 'handler')) {
8
+ registerObservable(instance, observer);
9
+ } else {
10
+ for (const key in observer) {
11
+ registerObservable(instance, observer[key], key);
12
+ }
13
+ }
14
+ }
15
+ }
16
+
17
+ export function registerObserver(instance, ...observer) {
18
+ instance._observers.push(...observer);
19
+ }
20
+
21
+ export function disconnectObservers(instance) {
22
+ for (const observer of instance._observers) {
23
+ observer?.disconnect();
24
+ instance._observerUpdates.delete(observer);
25
+ }
26
+ }
27
+
28
+ export function callObserverUpdates(instance) {
29
+ for (const [observer, update] of instance._observerUpdates) {
30
+ update(observer);
31
+ }
32
+ }
33
+
34
+ function registerObservable(instance, observable, key) {
35
+ let {
36
+ observe,
37
+ target = instance.$el,
38
+ handler,
39
+ options,
40
+ filter,
41
+ args,
42
+ } = isPlainObject(observable) ? observable : { type: key, handler: observable };
43
+
44
+ if (filter && !filter.call(instance, instance)) {
45
+ return;
46
+ }
47
+
48
+ const targets = isFunction(target) ? target.call(instance, instance) : target;
49
+ handler = isString(handler) ? instance[handler] : handler.bind(instance);
50
+
51
+ if (isFunction(options)) {
52
+ options = options.call(instance, instance);
53
+ }
54
+
55
+ const observer = observe(targets, handler, options, args);
56
+
57
+ if (isFunction(target) && isArray(targets) && observer.unobserve) {
58
+ instance._observerUpdates.set(observer, watchChange(instance, target, targets));
59
+ }
60
+
61
+ registerObserver(instance, observer);
62
+ }
63
+
64
+ function watchChange(instance, targetFn, targets) {
65
+ return (observer) => {
66
+ const newTargets = targetFn.call(instance, instance);
67
+
68
+ if (isEqual(targets, newTargets)) {
69
+ return;
70
+ }
71
+
72
+ targets.forEach((target) => !includes(newTargets, target) && observer.unobserve(target));
73
+ newTargets.forEach((target) => !includes(targets, target) && observer.observe(target));
74
+ targets.splice(0, targets.length, ...newTargets);
75
+ };
76
+ }
@@ -1,8 +1,21 @@
1
- import { hasOwn, includes, isArray, isFunction, isUndefined, sortBy, startsWith } from './lang';
1
+ import {
2
+ hasOwn,
3
+ includes,
4
+ isArray,
5
+ isFunction,
6
+ isNumeric,
7
+ isString,
8
+ isUndefined,
9
+ sortBy,
10
+ startsWith,
11
+ toBoolean,
12
+ toNumber,
13
+ } from '../util';
2
14
 
3
15
  const strats = {};
4
16
 
5
17
  strats.events =
18
+ strats.observe =
6
19
  strats.created =
7
20
  strats.beforeConnect =
8
21
  strats.connected =
@@ -139,3 +152,27 @@ export function parseOptions(options, args = []) {
139
152
  return {};
140
153
  }
141
154
  }
155
+
156
+ export function coerce(type, value) {
157
+ if (type === Boolean) {
158
+ return toBoolean(value);
159
+ } else if (type === Number) {
160
+ return toNumber(value);
161
+ } else if (type === 'list') {
162
+ return toList(value);
163
+ } else if (type === Object && isString(value)) {
164
+ return parseOptions(value);
165
+ }
166
+
167
+ return type ? type(value) : value;
168
+ }
169
+
170
+ function toList(value) {
171
+ return isArray(value)
172
+ ? value
173
+ : isString(value)
174
+ ? value
175
+ .split(/,(?![^(]*\))/)
176
+ .map((value) => (isNumeric(value) ? toNumber(value) : toBoolean(value.trim())))
177
+ : [value];
178
+ }
@@ -0,0 +1,102 @@
1
+ import { registerObserver } from './observer';
2
+ import { coerce, parseOptions } from './options';
3
+ import {
4
+ camelize,
5
+ data as getData,
6
+ hasOwn,
7
+ hyphenate,
8
+ isArray,
9
+ isUndefined,
10
+ startsWith,
11
+ } from '../util';
12
+
13
+ export function initProps(instance) {
14
+ const props = getProps(instance.$options);
15
+
16
+ for (let key in props) {
17
+ if (!isUndefined(props[key])) {
18
+ instance.$props[key] = props[key];
19
+ }
20
+ }
21
+
22
+ const exclude = [instance.$options.computed, instance.$options.methods];
23
+ for (let key in instance.$props) {
24
+ if (key in props && notIn(exclude, key)) {
25
+ instance[key] = instance.$props[key];
26
+ }
27
+ }
28
+ }
29
+
30
+ export function getProps(opts) {
31
+ const data = {};
32
+ const { args = [], props = {}, el, id } = opts;
33
+
34
+ if (!props) {
35
+ return data;
36
+ }
37
+
38
+ for (const key in props) {
39
+ const prop = hyphenate(key);
40
+ let value = getData(el, prop);
41
+
42
+ if (isUndefined(value)) {
43
+ continue;
44
+ }
45
+
46
+ value = props[key] === Boolean && value === '' ? true : coerce(props[key], value);
47
+
48
+ if (prop === 'target' && startsWith(value, '_')) {
49
+ continue;
50
+ }
51
+
52
+ data[key] = value;
53
+ }
54
+
55
+ const options = parseOptions(getData(el, id), args);
56
+
57
+ for (const key in options) {
58
+ const prop = camelize(key);
59
+ if (!isUndefined(props[prop])) {
60
+ data[prop] = coerce(props[prop], options[key]);
61
+ }
62
+ }
63
+
64
+ return data;
65
+ }
66
+
67
+ function notIn(options, key) {
68
+ return options.every((arr) => !arr || !hasOwn(arr, key));
69
+ }
70
+
71
+ export function initPropsObserver(instance) {
72
+ const { $options, $props } = instance;
73
+ const { id, attrs, props, el } = $options;
74
+
75
+ if (!props || attrs === false) {
76
+ return;
77
+ }
78
+
79
+ const attributes = isArray(attrs) ? attrs : Object.keys(props);
80
+ const filter = attributes.map((key) => hyphenate(key)).concat(id);
81
+
82
+ const observer = new MutationObserver((records) => {
83
+ const data = getProps($options);
84
+ if (
85
+ records.some(({ attributeName }) => {
86
+ const prop = attributeName.replace('data-', '');
87
+ return (prop === id ? attributes : [camelize(prop), camelize(attributeName)]).some(
88
+ (prop) => !isUndefined(data[prop]) && data[prop] !== $props[prop]
89
+ );
90
+ })
91
+ ) {
92
+ instance.$reset();
93
+ }
94
+ });
95
+
96
+ observer.observe(el, {
97
+ attributes: true,
98
+ attributeFilter: filter.concat(filter.map((key) => `data-${key}`)),
99
+ });
100
+
101
+ registerObserver(instance, observer);
102
+ }