native-document 1.0.150 → 1.0.151
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/devtools/plugin/dev-tools-plugin.js +1 -1
- package/devtools/widget/Widget.js +2 -1
- package/devtools/widget.js +1 -1
- package/dist/native-document.components.min.js +1146 -2721
- package/dist/native-document.dev.js +2862 -2862
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.min.js +1 -1
- package/package.json +1 -1
- package/rollup.config.js +1 -1
- package/src/components/$traits/has-items/HasItems.js +1 -1
- package/src/components/BaseComponent.js +1 -1
- package/src/components/accordion/AccordionItem.js +1 -1
- package/src/components/avatar/Avatar.js +0 -2
- package/src/components/breadcrumb/BreadCrumb.js +1 -1
- package/src/components/context-menu/ContextMenu.js +1 -1
- package/src/components/dropdown/Dropdown.js +1 -1
- package/src/components/dropdown/DropdownGroup.js +1 -1
- package/src/components/form/FormControl.js +2 -1
- package/src/components/form/field/DefaultRender.js +1 -1
- package/src/components/form/field/Field.js +2 -1
- package/src/components/form/field/FieldCollection.js +2 -1
- package/src/components/form/field/types/CheckboxField.js +1 -1
- package/src/components/form/field/types/FileField.js +1 -1
- package/src/components/form/field/types/RadioField.js +1 -1
- package/src/components/form/field/types/file-field-mode/FileItemPreview.js +1 -1
- package/src/components/form/validation/Validation.js +1 -1
- package/src/components/list/ListItem.js +1 -1
- package/src/components/menu/Menu.js +1 -1
- package/src/components/menu/MenuGroup.js +1 -1
- package/src/components/menu/MenuItem.js +1 -1
- package/src/components/modal/Modal.js +1 -1
- package/src/components/pagination/Pagination.js +1 -1
- package/src/components/popover/Popover.js +1 -1
- package/src/components/progress/Progress.js +0 -1
- package/src/components/splitter/Splitter.js +1 -1
- package/src/components/splitter/SplitterGutter.js +1 -1
- package/src/components/splitter/SplitterPanel.js +1 -1
- package/src/components/stepper/Stepper.js +1 -1
- package/src/components/stepper/StepperStep.js +1 -1
- package/src/components/switch/Switch.js +1 -1
- package/src/components/table/DataTable.js +1 -1
- package/src/components/table/index.js +0 -2
- package/src/components/tabs/Tabs.js +1 -1
- package/src/components/toast/Toast.js +1 -1
- package/src/components/tooltip/Tooltip.js +1 -1
- package/src/core/elements/anchor/one-child-anchor-overwriting.js +1 -1
- package/src/i18n/service/I18nService.js +1 -1
- package/src/i18n/service/functions.js +1 -1
- package/cdn.components.js +0 -28
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
var NativeComponents = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
let DebugManager$
|
|
4
|
+
let DebugManager$1 = {};
|
|
5
5
|
{
|
|
6
|
-
DebugManager$
|
|
6
|
+
DebugManager$1 = {
|
|
7
7
|
log() {},
|
|
8
8
|
warn() {},
|
|
9
9
|
error() {},
|
|
10
10
|
disable() {}
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
var DebugManager$
|
|
13
|
+
var DebugManager$2 = DebugManager$1;
|
|
14
14
|
|
|
15
15
|
class NativeDocumentError extends Error {
|
|
16
16
|
constructor(message, context = {}) {
|
|
@@ -68,7 +68,7 @@ var NativeComponents = (function (exports) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
if (cleanedCount > 0) {
|
|
71
|
-
DebugManager$
|
|
71
|
+
DebugManager$2.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
};
|
|
@@ -159,19 +159,6 @@ var NativeComponents = (function (exports) {
|
|
|
159
159
|
}
|
|
160
160
|
};
|
|
161
161
|
|
|
162
|
-
const nextTick = function(fn) {
|
|
163
|
-
let pending = false;
|
|
164
|
-
return function(...args) {
|
|
165
|
-
if (pending) return;
|
|
166
|
-
pending = true;
|
|
167
|
-
|
|
168
|
-
Promise.resolve().then(() => {
|
|
169
|
-
fn.apply(this, args);
|
|
170
|
-
pending = false;
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
};
|
|
174
|
-
|
|
175
162
|
const deepClone = (value, onObservableFound) => {
|
|
176
163
|
try {
|
|
177
164
|
if(window.structuredClone !== undefined) {
|
|
@@ -1706,2655 +1693,1093 @@ var NativeComponents = (function (exports) {
|
|
|
1706
1693
|
};
|
|
1707
1694
|
};
|
|
1708
1695
|
|
|
1709
|
-
|
|
1710
|
-
"Click",
|
|
1711
|
-
"DblClick",
|
|
1712
|
-
"MouseDown",
|
|
1713
|
-
"MouseEnter",
|
|
1714
|
-
"MouseLeave",
|
|
1715
|
-
"MouseMove",
|
|
1716
|
-
"MouseOut",
|
|
1717
|
-
"MouseOver",
|
|
1718
|
-
"MouseUp",
|
|
1719
|
-
"Wheel",
|
|
1720
|
-
"KeyDown",
|
|
1721
|
-
"KeyPress",
|
|
1722
|
-
"KeyUp",
|
|
1723
|
-
"Blur",
|
|
1724
|
-
"Change",
|
|
1725
|
-
"Focus",
|
|
1726
|
-
"Input",
|
|
1727
|
-
"Invalid",
|
|
1728
|
-
"Reset",
|
|
1729
|
-
"Search",
|
|
1730
|
-
"Select",
|
|
1731
|
-
"Submit",
|
|
1732
|
-
"Drag",
|
|
1733
|
-
"DragEnd",
|
|
1734
|
-
"DragEnter",
|
|
1735
|
-
"DragLeave",
|
|
1736
|
-
"DragOver",
|
|
1737
|
-
"DragStart",
|
|
1738
|
-
"Drop",
|
|
1739
|
-
"AfterPrint",
|
|
1740
|
-
"BeforePrint",
|
|
1741
|
-
"BeforeUnload",
|
|
1742
|
-
"Error",
|
|
1743
|
-
"HashChange",
|
|
1744
|
-
"Load",
|
|
1745
|
-
"Offline",
|
|
1746
|
-
"Online",
|
|
1747
|
-
"PageHide",
|
|
1748
|
-
"PageShow",
|
|
1749
|
-
"Resize",
|
|
1750
|
-
"Scroll",
|
|
1751
|
-
"Unload",
|
|
1752
|
-
"Abort",
|
|
1753
|
-
"CanPlay",
|
|
1754
|
-
"CanPlayThrough",
|
|
1755
|
-
"DurationChange",
|
|
1756
|
-
"Emptied",
|
|
1757
|
-
"Ended",
|
|
1758
|
-
"LoadedData",
|
|
1759
|
-
"LoadedMetadata",
|
|
1760
|
-
"LoadStart",
|
|
1761
|
-
"Pause",
|
|
1762
|
-
"Play",
|
|
1763
|
-
"Playing",
|
|
1764
|
-
"Progress",
|
|
1765
|
-
"RateChange",
|
|
1766
|
-
"Seeked",
|
|
1767
|
-
"Seeking",
|
|
1768
|
-
"Stalled",
|
|
1769
|
-
"Suspend",
|
|
1770
|
-
"TimeUpdate",
|
|
1771
|
-
"VolumeChange",
|
|
1772
|
-
"Waiting",
|
|
1773
|
-
|
|
1774
|
-
"TouchCancel",
|
|
1775
|
-
"TouchEnd",
|
|
1776
|
-
"TouchMove",
|
|
1777
|
-
"TouchStart",
|
|
1778
|
-
"AnimationEnd",
|
|
1779
|
-
"AnimationIteration",
|
|
1780
|
-
"AnimationStart",
|
|
1781
|
-
"TransitionEnd",
|
|
1782
|
-
"Copy",
|
|
1783
|
-
"Cut",
|
|
1784
|
-
"Paste",
|
|
1785
|
-
"FocusIn",
|
|
1786
|
-
"FocusOut",
|
|
1787
|
-
"ContextMenu"
|
|
1788
|
-
];
|
|
1789
|
-
|
|
1790
|
-
const EVENTS_WITH_PREVENT = [
|
|
1791
|
-
"Click",
|
|
1792
|
-
"DblClick",
|
|
1793
|
-
"MouseDown",
|
|
1794
|
-
"MouseUp",
|
|
1795
|
-
"Wheel",
|
|
1796
|
-
"KeyDown",
|
|
1797
|
-
"KeyPress",
|
|
1798
|
-
"Invalid",
|
|
1799
|
-
"Reset",
|
|
1800
|
-
"Submit",
|
|
1801
|
-
"DragOver",
|
|
1802
|
-
"Drop",
|
|
1803
|
-
"BeforeUnload",
|
|
1804
|
-
"TouchCancel",
|
|
1805
|
-
"TouchEnd",
|
|
1806
|
-
"TouchMove",
|
|
1807
|
-
"TouchStart",
|
|
1808
|
-
"Copy",
|
|
1809
|
-
"Cut",
|
|
1810
|
-
"Paste",
|
|
1811
|
-
"ContextMenu"
|
|
1812
|
-
];
|
|
1696
|
+
function oneChildAnchorOverwriting(anchor, parent) {
|
|
1813
1697
|
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
"MouseMove",
|
|
1819
|
-
"MouseOut",
|
|
1820
|
-
"MouseOver",
|
|
1821
|
-
"MouseUp",
|
|
1822
|
-
"Wheel",
|
|
1823
|
-
"KeyDown",
|
|
1824
|
-
"KeyPress",
|
|
1825
|
-
"KeyUp",
|
|
1826
|
-
"Change",
|
|
1827
|
-
"Input",
|
|
1828
|
-
"Invalid",
|
|
1829
|
-
"Reset",
|
|
1830
|
-
"Search",
|
|
1831
|
-
"Select",
|
|
1832
|
-
"Submit",
|
|
1833
|
-
"Drag",
|
|
1834
|
-
"DragEnd",
|
|
1835
|
-
"DragEnter",
|
|
1836
|
-
"DragLeave",
|
|
1837
|
-
"DragOver",
|
|
1838
|
-
"DragStart",
|
|
1839
|
-
"Drop",
|
|
1840
|
-
"BeforeUnload",
|
|
1841
|
-
"HashChange",
|
|
1842
|
-
"TouchCancel",
|
|
1843
|
-
"TouchEnd",
|
|
1844
|
-
"TouchMove",
|
|
1845
|
-
"TouchStart",
|
|
1846
|
-
"AnimationEnd",
|
|
1847
|
-
"AnimationIteration",
|
|
1848
|
-
"AnimationStart",
|
|
1849
|
-
"TransitionEnd",
|
|
1850
|
-
"Copy",
|
|
1851
|
-
"Cut",
|
|
1852
|
-
"Paste",
|
|
1853
|
-
"FocusIn",
|
|
1854
|
-
"FocusOut",
|
|
1855
|
-
"ContextMenu"
|
|
1856
|
-
];
|
|
1698
|
+
anchor.remove = () => {
|
|
1699
|
+
anchor.append.apply(anchor, parent.childNodes);
|
|
1700
|
+
};
|
|
1701
|
+
anchor.getParent = () => parent;
|
|
1857
1702
|
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1703
|
+
anchor.appendChild = (child) => {
|
|
1704
|
+
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1705
|
+
parent.appendChild(child);
|
|
1706
|
+
};
|
|
1864
1707
|
|
|
1865
|
-
|
|
1708
|
+
anchor.appendChildRaw = parent.appendChild.bind(parent);
|
|
1709
|
+
anchor.append = anchor.appendChild;
|
|
1710
|
+
anchor.appendRaw = anchor.appendChildRaw;
|
|
1866
1711
|
|
|
1867
|
-
|
|
1712
|
+
anchor.insertAtStart = (child) => {
|
|
1713
|
+
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1714
|
+
parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
|
|
1715
|
+
};
|
|
1716
|
+
anchor.insertAtStartRaw = (child) => {
|
|
1717
|
+
parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
|
|
1718
|
+
};
|
|
1868
1719
|
|
|
1869
|
-
|
|
1870
|
-
configurable: true,
|
|
1871
|
-
get: function() {
|
|
1872
|
-
return this;
|
|
1873
|
-
}
|
|
1874
|
-
});
|
|
1720
|
+
anchor.appendElement = anchor.appendChild;
|
|
1875
1721
|
|
|
1722
|
+
anchor.removeChildren = () => {
|
|
1723
|
+
parent.textContent = '';
|
|
1724
|
+
};
|
|
1876
1725
|
|
|
1726
|
+
anchor.replaceContent = function(content) {
|
|
1727
|
+
const child = Validator.isElement(content) ? content : ElementCreator.getChild(content);
|
|
1728
|
+
parent.replaceChildren(child);
|
|
1729
|
+
};
|
|
1877
1730
|
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
// ----------------------------------------------------------------
|
|
1881
|
-
EVENTS.forEach(eventSourceName => {
|
|
1882
|
-
const eventName = eventSourceName.toLowerCase();
|
|
1883
|
-
NDElement.prototype['on'+eventSourceName] = function(callback = null) {
|
|
1884
|
-
this.$element.addEventListener(eventName, callback);
|
|
1885
|
-
return this;
|
|
1731
|
+
anchor.replaceContentRaw = function(child) {
|
|
1732
|
+
parent.replaceChildren(child);
|
|
1886
1733
|
};
|
|
1887
|
-
|
|
1734
|
+
anchor.setContent = anchor.replaceContent;
|
|
1888
1735
|
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
_stop(this.$element, eventName, callback);
|
|
1893
|
-
return this;
|
|
1736
|
+
anchor.insertBefore = (child, anchor) => {
|
|
1737
|
+
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1738
|
+
parent.insertBefore(child, anchor);
|
|
1894
1739
|
};
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
return this;
|
|
1740
|
+
anchor.insertBeforeRaw = (child, anchor) => {
|
|
1741
|
+
parent.insertBefore(child, anchor);
|
|
1898
1742
|
};
|
|
1899
|
-
});
|
|
1900
1743
|
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
NDElement.prototype['onPrevent'+eventSourceName] = function(callback = null) {
|
|
1904
|
-
_prevent(this.$element, eventName, callback);
|
|
1905
|
-
return this;
|
|
1906
|
-
};
|
|
1907
|
-
});
|
|
1744
|
+
anchor.appendChildBefore = anchor.insertBefore;
|
|
1745
|
+
anchor.appendChildBeforeRaw = anchor.insertBeforeRaw;
|
|
1908
1746
|
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
return this;
|
|
1912
|
-
};
|
|
1747
|
+
anchor.clear = anchor.remove;
|
|
1748
|
+
anchor.detach = anchor.remove;
|
|
1913
1749
|
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
event.preventDefault();
|
|
1917
|
-
callback && callback.call(element, event);
|
|
1750
|
+
anchor.replaceChildren = function() {
|
|
1751
|
+
parent.replaceChildren(...arguments);
|
|
1918
1752
|
};
|
|
1919
|
-
element.addEventListener(eventName, handler);
|
|
1920
|
-
return this;
|
|
1921
|
-
};
|
|
1922
1753
|
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
event.stopPropagation();
|
|
1926
|
-
callback && callback.call(element, event);
|
|
1754
|
+
anchor.getByIndex = (index) => {
|
|
1755
|
+
return parent.childNodes[index];
|
|
1927
1756
|
};
|
|
1928
|
-
|
|
1929
|
-
return this;
|
|
1930
|
-
};
|
|
1931
|
-
|
|
1932
|
-
const _preventStop = function(element, eventName, callback) {
|
|
1933
|
-
const handler = (event) => {
|
|
1934
|
-
event.stopPropagation();
|
|
1935
|
-
event.preventDefault();
|
|
1936
|
-
callback && callback.call(element, event);
|
|
1937
|
-
};
|
|
1938
|
-
element.addEventListener(eventName, handler);
|
|
1939
|
-
return this;
|
|
1940
|
-
};
|
|
1941
|
-
|
|
1757
|
+
}
|
|
1942
1758
|
|
|
1759
|
+
function Anchor(name, isUniqueChild = false) {
|
|
1760
|
+
const anchorFragment = new AnchorWithSentinel(name);
|
|
1943
1761
|
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
const classListMethods = {
|
|
1948
|
-
getClasses() {
|
|
1949
|
-
return this.$element.className?.split(' ').filter(Boolean);
|
|
1950
|
-
},
|
|
1951
|
-
add(value) {
|
|
1952
|
-
const classes = this.getClasses();
|
|
1953
|
-
if(classes.indexOf(value) >= 0) {
|
|
1954
|
-
return;
|
|
1955
|
-
}
|
|
1956
|
-
classes.push(value);
|
|
1957
|
-
this.$element.className = classes.join(' ');
|
|
1958
|
-
},
|
|
1959
|
-
remove(value) {
|
|
1960
|
-
const classes = this.getClasses();
|
|
1961
|
-
const index = classes.indexOf(value);
|
|
1962
|
-
if(index < 0) {
|
|
1963
|
-
return;
|
|
1964
|
-
}
|
|
1965
|
-
classes.splice(index, 1);
|
|
1966
|
-
this.$element.className = classes.join(' ');
|
|
1967
|
-
},
|
|
1968
|
-
toggle(value, force = undefined) {
|
|
1969
|
-
const classes = this.getClasses();
|
|
1970
|
-
const index = classes.indexOf(value);
|
|
1971
|
-
if(index >= 0) {
|
|
1972
|
-
if(force === true) {
|
|
1973
|
-
return;
|
|
1974
|
-
}
|
|
1975
|
-
classes.splice(index, 1);
|
|
1976
|
-
}
|
|
1977
|
-
else {
|
|
1978
|
-
if(force === false) {
|
|
1979
|
-
return;
|
|
1980
|
-
}
|
|
1981
|
-
classes.push(value);
|
|
1762
|
+
anchorFragment.onConnectedOnce((parent) => {
|
|
1763
|
+
if(isUniqueChild) {
|
|
1764
|
+
oneChildAnchorOverwriting(anchorFragment, parent);
|
|
1982
1765
|
}
|
|
1983
|
-
|
|
1984
|
-
},
|
|
1985
|
-
contains(value) {
|
|
1986
|
-
return this.getClasses().indexOf(value) >= 0;
|
|
1987
|
-
}
|
|
1988
|
-
};
|
|
1989
|
-
|
|
1990
|
-
Object.defineProperty(HTMLElement.prototype, 'classes', {
|
|
1991
|
-
configurable: true,
|
|
1992
|
-
get() {
|
|
1993
|
-
return {
|
|
1994
|
-
$element: this,
|
|
1995
|
-
...classListMethods
|
|
1996
|
-
};
|
|
1997
|
-
}
|
|
1998
|
-
});
|
|
1999
|
-
|
|
2000
|
-
let withValidation = (fn) => fn;
|
|
2001
|
-
|
|
2002
|
-
const normalizeComponentArgs = function(props, children = null) {
|
|
2003
|
-
if(props && children) {
|
|
2004
|
-
return { props, children };
|
|
2005
|
-
}
|
|
2006
|
-
if(typeof props !== 'object' || Array.isArray(props) || props === null || props.constructor.name !== 'Object' || props.$hydrate) { // IF it's not a JSON
|
|
2007
|
-
return { props: children, children: props }
|
|
2008
|
-
}
|
|
2009
|
-
return { props, children };
|
|
2010
|
-
};
|
|
1766
|
+
});
|
|
2011
1767
|
|
|
2012
|
-
|
|
2013
|
-
*
|
|
2014
|
-
* @param {*} value
|
|
2015
|
-
* @returns {Text}
|
|
2016
|
-
*/
|
|
2017
|
-
const createTextNode = (value) => {
|
|
2018
|
-
if(value) {
|
|
2019
|
-
return value.toNdElement();
|
|
2020
|
-
}
|
|
2021
|
-
return ElementCreator.createTextNode();
|
|
2022
|
-
};
|
|
1768
|
+
anchorFragment.__Anchor__ = true;
|
|
2023
1769
|
|
|
1770
|
+
const anchorStart = anchorFragment.$start;
|
|
1771
|
+
const anchorEnd = anchorFragment.$end;
|
|
2024
1772
|
|
|
2025
|
-
|
|
2026
|
-
|
|
1773
|
+
anchorFragment.nativeInsertBefore = anchorFragment.insertBefore;
|
|
1774
|
+
anchorFragment.nativeAppendChild = anchorFragment.appendChild;
|
|
1775
|
+
anchorFragment.nativeAppend = anchorFragment.append;
|
|
2027
1776
|
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
return element;
|
|
2031
|
-
};
|
|
1777
|
+
const isParentUniqueChild = isUniqueChild
|
|
1778
|
+
? () => true: (parent) => (parent.firstChild === anchorStart && parent.lastChild === anchorEnd);
|
|
2032
1779
|
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
* @returns {Function}
|
|
2038
|
-
*/
|
|
2039
|
-
function HtmlElementWrapper(name, customWrapper = null) {
|
|
2040
|
-
if(name) {
|
|
2041
|
-
if(customWrapper) {
|
|
2042
|
-
let node = null;
|
|
2043
|
-
let createElement = (attr, children) => {
|
|
2044
|
-
node = document.createElement(name);
|
|
2045
|
-
createElement = (attr, children) => {
|
|
2046
|
-
return createHtmlElement(customWrapper(node.cloneNode()), attr, children);
|
|
2047
|
-
};
|
|
2048
|
-
return createHtmlElement(customWrapper(node.cloneNode()), attr, children); };
|
|
1780
|
+
const insertBefore = (parent, child, target) => {
|
|
1781
|
+
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1782
|
+
insertBeforeRaw(parent, childElement, target);
|
|
1783
|
+
};
|
|
2049
1784
|
|
|
2050
|
-
|
|
1785
|
+
const insertBeforeRaw = (parent, child, target) => {
|
|
1786
|
+
if(parent === anchorFragment) {
|
|
1787
|
+
parent.nativeInsertBefore(child, target);
|
|
1788
|
+
return;
|
|
2051
1789
|
}
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
return createHtmlElement(node.cloneNode(), attr, children);
|
|
2058
|
-
};
|
|
2059
|
-
return createHtmlElement(node.cloneNode(), attr, children);
|
|
2060
|
-
};
|
|
2061
|
-
|
|
2062
|
-
return (attr, children) => createElement(attr, children)
|
|
2063
|
-
}
|
|
2064
|
-
return (children, name = '') => {
|
|
2065
|
-
const anchor = Anchor(name);
|
|
2066
|
-
anchor.append(children);
|
|
2067
|
-
return anchor;
|
|
1790
|
+
if(isParentUniqueChild(parent) && target === anchorEnd) {
|
|
1791
|
+
parent.append(child, target);
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
parent.insertBefore(child, target);
|
|
2068
1795
|
};
|
|
2069
|
-
}
|
|
2070
1796
|
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
1797
|
+
anchorFragment.appendElement = function(child) {
|
|
1798
|
+
const parentNode = anchorStart.parentNode;
|
|
1799
|
+
if(parentNode === anchorFragment) {
|
|
1800
|
+
parentNode.nativeInsertBefore(child, anchorEnd);
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
parentNode.insertBefore(child, anchorEnd);
|
|
1804
|
+
};
|
|
2078
1805
|
|
|
1806
|
+
anchorFragment.appendChild = function(child, before = null) {
|
|
1807
|
+
const parent = anchorEnd.parentNode;
|
|
1808
|
+
if(!parent) {
|
|
1809
|
+
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
before = before ?? anchorEnd;
|
|
1813
|
+
insertBefore(parent, child, before);
|
|
1814
|
+
};
|
|
2079
1815
|
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
*/
|
|
2090
|
-
NDElement.prototype.attach = function(methodName, bindingHydrator) {
|
|
2091
|
-
if(typeof bindingHydrator === 'function') {
|
|
2092
|
-
const element = this.$element;
|
|
2093
|
-
element.nodeCloner = element.nodeCloner || new NodeCloner(element);
|
|
2094
|
-
element.nodeCloner.attach(methodName, bindingHydrator);
|
|
2095
|
-
return element;
|
|
2096
|
-
}
|
|
2097
|
-
bindingHydrator.$hydrate(this.$element, methodName);
|
|
2098
|
-
return this.$element;
|
|
2099
|
-
};
|
|
1816
|
+
anchorFragment.appendChildRaw = function(child, before = null) {
|
|
1817
|
+
const parent = anchorEnd.parentNode;
|
|
1818
|
+
if(!parent) {
|
|
1819
|
+
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
before = before ?? anchorEnd;
|
|
1823
|
+
insertBeforeRaw(parent, child, before);
|
|
1824
|
+
};
|
|
2100
1825
|
|
|
2101
|
-
|
|
1826
|
+
anchorFragment.getParent = () => anchorEnd.parentNode;
|
|
1827
|
+
anchorFragment.append = anchorFragment.appendChild;
|
|
1828
|
+
anchorFragment.appendRaw = anchorFragment.appendChildRaw;
|
|
2102
1829
|
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
}
|
|
2107
|
-
return cache;
|
|
2108
|
-
};
|
|
1830
|
+
anchorFragment.insertAtStart = function(child) {
|
|
1831
|
+
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1832
|
+
anchorFragment.insertAtStartRaw(child);
|
|
1833
|
+
};
|
|
2109
1834
|
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
if(this.$ndMethods) {
|
|
2116
|
-
const methods = Object.keys(this.$ndMethods);
|
|
2117
|
-
if(methods.length === 1) {
|
|
2118
|
-
const methodName = methods[0];
|
|
2119
|
-
const callback = this.$ndMethods[methodName];
|
|
2120
|
-
steps.push((clonedNode, data) => {
|
|
2121
|
-
clonedNode.nd[methodName](callback.bind(clonedNode, ...data));
|
|
2122
|
-
});
|
|
2123
|
-
} else {
|
|
2124
|
-
steps.push((clonedNode, data) => {
|
|
2125
|
-
const nd = clonedNode.nd;
|
|
2126
|
-
for(const methodName in this.$ndMethods) {
|
|
2127
|
-
nd[methodName](this.$ndMethods[methodName].bind(clonedNode, ...data));
|
|
2128
|
-
}
|
|
2129
|
-
});
|
|
1835
|
+
anchorFragment.insertAtStartRaw = function(child) {
|
|
1836
|
+
const parentNode = anchorStart.parentNode;
|
|
1837
|
+
if(parentNode === anchorFragment) {
|
|
1838
|
+
parentNode.nativeInsertBefore(child, anchorStart);
|
|
1839
|
+
return;
|
|
2130
1840
|
}
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
const cache = {};
|
|
2134
|
-
const keys = Object.keys(this.$classes);
|
|
1841
|
+
parentNode.insertBefore(child, anchorStart);
|
|
1842
|
+
};
|
|
2135
1843
|
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
cache[key] = callback.apply(null, data);
|
|
2141
|
-
ElementCreator.processClassAttribute(clonedNode, cache);
|
|
2142
|
-
});
|
|
2143
|
-
} else {
|
|
2144
|
-
steps.push((clonedNode, data) => {
|
|
2145
|
-
ElementCreator.processClassAttribute(clonedNode, buildProperties(cache, this.$classes, data));
|
|
2146
|
-
});
|
|
1844
|
+
anchorFragment.removeChildren = function() {
|
|
1845
|
+
const parent = anchorEnd.parentNode;
|
|
1846
|
+
if(parent === anchorFragment) {
|
|
1847
|
+
return;
|
|
2147
1848
|
}
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
const keys = Object.keys(this.$styles);
|
|
2152
|
-
|
|
2153
|
-
if(keys.length === 1) {
|
|
2154
|
-
const key = keys[0];
|
|
2155
|
-
const callback = this.$styles[key];
|
|
2156
|
-
steps.push((clonedNode, data) => {
|
|
2157
|
-
cache[key] = callback.apply(null, data);
|
|
2158
|
-
ElementCreator.processStyleAttribute(clonedNode, cache);
|
|
2159
|
-
});
|
|
2160
|
-
} else {
|
|
2161
|
-
steps.push((clonedNode, data) => {
|
|
2162
|
-
ElementCreator.processStyleAttribute(clonedNode, buildProperties(cache, this.$styles, data));
|
|
2163
|
-
});
|
|
1849
|
+
if(isParentUniqueChild(parent)) {
|
|
1850
|
+
parent.replaceChildren(anchorStart, anchorEnd);
|
|
1851
|
+
return;
|
|
2164
1852
|
}
|
|
2165
|
-
}
|
|
2166
|
-
if(this.$attrs) {
|
|
2167
|
-
const cache = {};
|
|
2168
|
-
const keys = Object.keys(this.$attrs);
|
|
2169
1853
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
ElementCreator.processAttributes(clonedNode, cache);
|
|
2176
|
-
});
|
|
2177
|
-
} else {
|
|
2178
|
-
steps.push((clonedNode, data) => {
|
|
2179
|
-
ElementCreator.processAttributes(clonedNode, buildProperties(cache, this.$attrs, data));
|
|
2180
|
-
});
|
|
1854
|
+
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
1855
|
+
while(itemToRemove && itemToRemove !== anchorEnd) {
|
|
1856
|
+
tempItem = itemToRemove.nextSibling;
|
|
1857
|
+
itemToRemove.remove();
|
|
1858
|
+
itemToRemove = tempItem;
|
|
2181
1859
|
}
|
|
2182
|
-
}
|
|
2183
|
-
|
|
2184
|
-
const stepsCount = steps.length;
|
|
2185
|
-
const $element = this.$element;
|
|
1860
|
+
};
|
|
2186
1861
|
|
|
2187
|
-
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2190
|
-
|
|
1862
|
+
anchorFragment.remove = function() {
|
|
1863
|
+
const parent = anchorEnd.parentNode;
|
|
1864
|
+
if(parent === anchorFragment) {
|
|
1865
|
+
return;
|
|
1866
|
+
}
|
|
1867
|
+
if(isParentUniqueChild(parent)) {
|
|
1868
|
+
anchorFragment.nativeAppend.apply(anchorFragment, parent.childNodes);
|
|
1869
|
+
parent.replaceChildren(anchorStart, anchorEnd);
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1872
|
+
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
1873
|
+
while(itemToRemove && itemToRemove !== anchorEnd) {
|
|
1874
|
+
tempItem = itemToRemove.nextSibling;
|
|
1875
|
+
anchorFragment.nativeAppend(itemToRemove);
|
|
1876
|
+
itemToRemove = tempItem;
|
|
2191
1877
|
}
|
|
2192
|
-
return clonedNode;
|
|
2193
1878
|
};
|
|
2194
|
-
};
|
|
2195
1879
|
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
1880
|
+
anchorFragment.removeWithAnchors = function() {
|
|
1881
|
+
anchorFragment.removeChildren();
|
|
1882
|
+
anchorStart.remove();
|
|
1883
|
+
anchorEnd.remove();
|
|
1884
|
+
};
|
|
1885
|
+
anchorFragment.delete = anchorFragment.removeWithAnchors;
|
|
2199
1886
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
};
|
|
2205
|
-
|
|
2206
|
-
NodeCloner.prototype.text = function(value) {
|
|
2207
|
-
this.$content = value;
|
|
2208
|
-
if(typeof value === 'function') {
|
|
2209
|
-
this.cloneNode = (data) => createTextNode(value.apply(null, data));
|
|
2210
|
-
return this;
|
|
2211
|
-
}
|
|
2212
|
-
this.cloneNode = (data) => createTextNode(data[0][value]);
|
|
2213
|
-
return this;
|
|
2214
|
-
};
|
|
1887
|
+
anchorFragment.replaceContent = function(child) {
|
|
1888
|
+
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1889
|
+
anchorFragment.replaceContentRaw(childElement);
|
|
1890
|
+
};
|
|
2215
1891
|
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
this.$attrs[attrName] = value.value;
|
|
2229
|
-
return this;
|
|
2230
|
-
};
|
|
1892
|
+
anchorFragment.replaceContentRaw = function(child) {
|
|
1893
|
+
const parent = anchorEnd.parentNode;
|
|
1894
|
+
if(!parent) {
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
if(isParentUniqueChild(parent)) {
|
|
1898
|
+
parent.replaceChildren(anchorStart, child, anchorEnd);
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
anchorFragment.removeChildren();
|
|
1902
|
+
parent.insertBefore(child, anchorEnd);
|
|
1903
|
+
};
|
|
2231
1904
|
|
|
2232
|
-
|
|
1905
|
+
anchorFragment.setContent = anchorFragment.replaceContent;
|
|
1906
|
+
anchorFragment.setContentRaw = anchorFragment.replaceContentRaw;
|
|
2233
1907
|
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
};
|
|
1908
|
+
anchorFragment.insertBefore = anchorFragment.appendChild;
|
|
1909
|
+
anchorFragment.insertBeforeRaw = anchorFragment.appendChildRaw;
|
|
2237
1910
|
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
try {
|
|
2241
|
-
return this.apply(this, args);
|
|
2242
|
-
} catch(e) {
|
|
2243
|
-
return callback(e, {caller: handler, args: args });
|
|
2244
|
-
}
|
|
1911
|
+
anchorFragment.endElement = function() {
|
|
1912
|
+
return anchorEnd;
|
|
2245
1913
|
};
|
|
2246
|
-
return handler;
|
|
2247
|
-
};
|
|
2248
1914
|
|
|
2249
|
-
|
|
2250
|
-
|
|
1915
|
+
anchorFragment.startElement = function() {
|
|
1916
|
+
return anchorStart;
|
|
1917
|
+
};
|
|
2251
1918
|
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
if(Array.isArray(data)) {
|
|
2255
|
-
data.push(key+': '+value);
|
|
2256
|
-
return;
|
|
2257
|
-
}
|
|
2258
|
-
if(Validator.isObject(key)) {
|
|
2259
|
-
value = key;
|
|
2260
|
-
for(const property in value) {
|
|
2261
|
-
data[property] = value[property];
|
|
2262
|
-
}
|
|
2263
|
-
return;
|
|
2264
|
-
}
|
|
2265
|
-
data[key] = value;
|
|
2266
|
-
},
|
|
2267
|
-
value() {
|
|
2268
|
-
if(Array.isArray(data)) {
|
|
2269
|
-
return data.join(';').concat(';');
|
|
2270
|
-
}
|
|
2271
|
-
return { ...data };
|
|
2272
|
-
},
|
|
1919
|
+
anchorFragment.restore = function() {
|
|
1920
|
+
anchorFragment.appendChild(anchorFragment);
|
|
2273
1921
|
};
|
|
2274
|
-
};
|
|
2275
1922
|
|
|
2276
|
-
|
|
2277
|
-
|
|
1923
|
+
anchorFragment.clear = anchorFragment.remove;
|
|
1924
|
+
anchorFragment.detach = anchorFragment.remove;
|
|
2278
1925
|
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
data[property] = key[property];
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
return;
|
|
2288
|
-
}
|
|
2289
|
-
if(value != null || key.__$Observable) {
|
|
2290
|
-
if(Array.isArray(data)) {
|
|
2291
|
-
data = data.reduce((acc, item) => {
|
|
2292
|
-
acc[item] = true;
|
|
2293
|
-
return acc;
|
|
2294
|
-
}, {});
|
|
2295
|
-
}
|
|
2296
|
-
if(key.__$Observable) {
|
|
2297
|
-
const uniqueId = `obs-${Math.random().toString(36).substr(2, 9)}`;
|
|
2298
|
-
data[uniqueId] = key;
|
|
2299
|
-
}
|
|
2300
|
-
else {
|
|
2301
|
-
data[key] = value;
|
|
2302
|
-
}
|
|
2303
|
-
return;
|
|
2304
|
-
}
|
|
2305
|
-
if(Array.isArray(data)) {
|
|
2306
|
-
data.push(key);
|
|
2307
|
-
return;
|
|
2308
|
-
}
|
|
2309
|
-
data[key] = value;
|
|
2310
|
-
},
|
|
2311
|
-
value() {
|
|
2312
|
-
if(Array.isArray(data)) {
|
|
2313
|
-
return data.join(' ');
|
|
1926
|
+
anchorFragment.getByIndex = function(index) {
|
|
1927
|
+
let currentNode = anchorStart;
|
|
1928
|
+
for(let i = 0; i <= index; i++) {
|
|
1929
|
+
if(!currentNode.nextSibling) {
|
|
1930
|
+
return null;
|
|
2314
1931
|
}
|
|
2315
|
-
|
|
2316
|
-
}
|
|
1932
|
+
currentNode = currentNode.nextSibling;
|
|
1933
|
+
}
|
|
1934
|
+
return currentNode !== anchorStart ? currentNode : null;
|
|
2317
1935
|
};
|
|
2318
|
-
};
|
|
2319
1936
|
|
|
2320
|
-
|
|
2321
|
-
|
|
1937
|
+
return anchorFragment;
|
|
1938
|
+
}
|
|
1939
|
+
DocumentFragment.prototype.setAttribute = () => {};
|
|
2322
1940
|
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
* @constructor
|
|
2328
|
-
*/
|
|
2329
|
-
const ObservableArray = function (target, configs = null) {
|
|
2330
|
-
if(!Array.isArray(target)) {
|
|
2331
|
-
throw new NativeDocumentError('Observable.array : target must be an array');
|
|
2332
|
-
}
|
|
1941
|
+
function NDElement(element) {
|
|
1942
|
+
this.$element = element;
|
|
1943
|
+
this.$attachements = null;
|
|
1944
|
+
}
|
|
2333
1945
|
|
|
2334
|
-
|
|
2335
|
-
};
|
|
1946
|
+
NDElement.prototype.__$isNDElement = true;
|
|
2336
1947
|
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
1948
|
+
NDElement.prototype.ghostDom = function(element) {
|
|
1949
|
+
if(!this.$attachements) {
|
|
1950
|
+
this.$attachements = document.createDocumentFragment();
|
|
1951
|
+
}
|
|
1952
|
+
this.$attachements.appendChild(ElementCreator.getChild(element));
|
|
1953
|
+
return this;
|
|
1954
|
+
};
|
|
2340
1955
|
|
|
1956
|
+
NDElement.prototype.valueOf = function() {
|
|
1957
|
+
return this.$element;
|
|
1958
|
+
};
|
|
2341
1959
|
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
});
|
|
1960
|
+
NDElement.prototype.ref = function(target, name) {
|
|
1961
|
+
target[name] = this.$element;
|
|
1962
|
+
return this;
|
|
1963
|
+
};
|
|
2347
1964
|
|
|
1965
|
+
NDElement.prototype.refSelf = function(target, name) {
|
|
1966
|
+
target[name] = this;
|
|
1967
|
+
// TODO: @DIM to check
|
|
1968
|
+
// target[name] = new NDElement(this.$element);
|
|
1969
|
+
return this;
|
|
1970
|
+
};
|
|
2348
1971
|
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
1972
|
+
NDElement.prototype.unmountChildren = function() {
|
|
1973
|
+
let element = this.$element;
|
|
1974
|
+
for(let i = 0, length = element.children.length; i < length; i++) {
|
|
1975
|
+
let elementChildren = element.children[i];
|
|
1976
|
+
if(!elementChildren.$ndProx) {
|
|
1977
|
+
elementChildren.nd?.remove();
|
|
2354
1978
|
}
|
|
1979
|
+
elementChildren = null;
|
|
2355
1980
|
}
|
|
2356
|
-
|
|
1981
|
+
element = null;
|
|
1982
|
+
return this;
|
|
2357
1983
|
};
|
|
2358
1984
|
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
this.trigger({ action: method, args: argsToUse, result });
|
|
2364
|
-
return result;
|
|
2365
|
-
})
|
|
2366
|
-
};
|
|
2367
|
-
});
|
|
1985
|
+
NDElement.prototype.remove = function() {
|
|
1986
|
+
let element = this.$element;
|
|
1987
|
+
element.nd.unmountChildren();
|
|
1988
|
+
element.$ndProx = null;
|
|
2368
1989
|
|
|
2369
|
-
|
|
2370
|
-
ObservableArray.prototype[method] = function(...values) {
|
|
2371
|
-
return this.$currentValue[method].apply(this.$currentValue, values);
|
|
2372
|
-
};
|
|
2373
|
-
});
|
|
1990
|
+
$lifeCycleObservers.delete(element);
|
|
2374
1991
|
|
|
1992
|
+
element = null;
|
|
1993
|
+
return this;
|
|
1994
|
+
};
|
|
2375
1995
|
|
|
2376
|
-
const $
|
|
1996
|
+
const $lifeCycleObservers = new WeakMap();
|
|
1997
|
+
NDElement.prototype.lifecycle = function(states) {
|
|
1998
|
+
const el = this.$element;
|
|
1999
|
+
if (!$lifeCycleObservers.has(el)) {
|
|
2000
|
+
$lifeCycleObservers.set(el, DocumentObserver.watch(el));
|
|
2001
|
+
}
|
|
2002
|
+
const observer = $lifeCycleObservers.get(el);
|
|
2377
2003
|
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
* @returns {boolean} True if array was cleared, false if it was already empty
|
|
2382
|
-
* @example
|
|
2383
|
-
* const items = Observable.array([1, 2, 3]);
|
|
2384
|
-
* items.clear(); // []
|
|
2385
|
-
*/
|
|
2386
|
-
ObservableArray.prototype.clear = function() {
|
|
2387
|
-
if(this.$currentValue.length === 0) {
|
|
2388
|
-
return;
|
|
2004
|
+
if(states.mounted) {
|
|
2005
|
+
this.$element.setAttribute('data--nd-mounted', '1');
|
|
2006
|
+
observer.mounted(states.mounted);
|
|
2389
2007
|
}
|
|
2390
|
-
|
|
2391
|
-
this.$
|
|
2392
|
-
|
|
2393
|
-
}
|
|
2394
|
-
return
|
|
2008
|
+
if(states.unmounted) {
|
|
2009
|
+
this.$element.setAttribute('data--nd-unmounted', '1');
|
|
2010
|
+
observer.unmounted(states.unmounted);
|
|
2011
|
+
}
|
|
2012
|
+
return this;
|
|
2395
2013
|
};
|
|
2396
2014
|
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
*
|
|
2400
|
-
* @param {number} index - Zero-based index of the element to retrieve
|
|
2401
|
-
* @returns {*} The element at the specified index
|
|
2402
|
-
* @example
|
|
2403
|
-
* const items = Observable.array(['a', 'b', 'c']);
|
|
2404
|
-
* items.at(1); // 'b'
|
|
2405
|
-
*/
|
|
2406
|
-
ObservableArray.prototype.at = function(index) {
|
|
2407
|
-
return this.$currentValue[index];
|
|
2015
|
+
NDElement.prototype.mounted = function(callback) {
|
|
2016
|
+
return this.lifecycle({ mounted: callback });
|
|
2408
2017
|
};
|
|
2409
2018
|
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
* Merges multiple values into the array and triggers an update.
|
|
2413
|
-
* Similar to push but with a different operation name.
|
|
2414
|
-
*
|
|
2415
|
-
* @param {Array} values - Array of values to merge
|
|
2416
|
-
* @example
|
|
2417
|
-
* const items = Observable.array([1, 2]);
|
|
2418
|
-
* items.merge([3, 4]); // [1, 2, 3, 4]
|
|
2419
|
-
*/
|
|
2420
|
-
ObservableArray.prototype.merge = function(values) {
|
|
2421
|
-
this.$mutate('merge', values, (valuesToMerge) => {
|
|
2422
|
-
this.$currentValue.push.apply(this.$currentValue, valuesToMerge);
|
|
2423
|
-
this.trigger({ action: 'merge', args: valuesToMerge });
|
|
2424
|
-
});
|
|
2019
|
+
NDElement.prototype.unmounted = function(callback) {
|
|
2020
|
+
return this.lifecycle({ unmounted: callback });
|
|
2425
2021
|
};
|
|
2426
2022
|
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
*
|
|
2430
|
-
* @param {(value: *, index: number) => Boolean} condition - Function that tests each element (item, index) => boolean
|
|
2431
|
-
* @returns {number} The count of elements that satisfy the condition
|
|
2432
|
-
* @example
|
|
2433
|
-
* const numbers = Observable.array([1, 2, 3, 4, 5]);
|
|
2434
|
-
* numbers.count(n => n > 3); // 2
|
|
2435
|
-
*/
|
|
2436
|
-
ObservableArray.prototype.count = function(condition) {
|
|
2437
|
-
let count = 0;
|
|
2438
|
-
this.$currentValue.forEach((item, index) => {
|
|
2439
|
-
if(condition(item, index)) {
|
|
2440
|
-
count++;
|
|
2441
|
-
}
|
|
2442
|
-
});
|
|
2443
|
-
return count;
|
|
2444
|
-
};
|
|
2023
|
+
NDElement.prototype.beforeUnmount = function(id, callback) {
|
|
2024
|
+
const el = this.$element;
|
|
2445
2025
|
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
* @param {number} indexA - Index of the first element
|
|
2450
|
-
* @param {number} indexB - Index of the second element
|
|
2451
|
-
* @returns {boolean} True if swap was successful, false if indices are out of bounds
|
|
2452
|
-
* @example
|
|
2453
|
-
* const items = Observable.array(['a', 'b', 'c']);
|
|
2454
|
-
* items.swap(0, 2); // ['c', 'b', 'a']
|
|
2455
|
-
*/
|
|
2456
|
-
ObservableArray.prototype.swap = function(indexA, indexB) {
|
|
2457
|
-
this.$mutate('swap', [indexA, indexB], ([indexA, indexB]) => {
|
|
2458
|
-
const value = this.$currentValue;
|
|
2459
|
-
const length = value.length;
|
|
2460
|
-
if(indexB < indexA) {
|
|
2461
|
-
const temp = indexA;
|
|
2462
|
-
indexA = indexB;
|
|
2463
|
-
indexB = temp;
|
|
2464
|
-
}
|
|
2465
|
-
if(length < indexA || length < indexB) {
|
|
2466
|
-
return false;
|
|
2467
|
-
}
|
|
2468
|
-
const elementA = value[indexA];
|
|
2469
|
-
const elementB = value[indexB];
|
|
2026
|
+
if(!DocumentObserver.beforeUnmount.has(el)) {
|
|
2027
|
+
DocumentObserver.beforeUnmount.set(el, new Map());
|
|
2028
|
+
const originalRemove = el.remove.bind(el);
|
|
2470
2029
|
|
|
2471
|
-
|
|
2472
|
-
value[indexB] = elementA;
|
|
2473
|
-
this.trigger({ action: 'swap', args: [indexA, indexB], result: [elementA, elementB] });
|
|
2474
|
-
});
|
|
2475
|
-
return true;
|
|
2476
|
-
};
|
|
2030
|
+
let $isUnmounting = false;
|
|
2477
2031
|
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2032
|
+
el.remove = async () => {
|
|
2033
|
+
if($isUnmounting) {
|
|
2034
|
+
return;
|
|
2035
|
+
}
|
|
2036
|
+
$isUnmounting = true;
|
|
2037
|
+
|
|
2038
|
+
try {
|
|
2039
|
+
const callbacks = DocumentObserver.beforeUnmount.get(el);
|
|
2040
|
+
for (const cb of callbacks.values()) {
|
|
2041
|
+
await cb.call(this, el);
|
|
2042
|
+
}
|
|
2043
|
+
} finally {
|
|
2044
|
+
originalRemove();
|
|
2045
|
+
$isUnmounting = false;
|
|
2046
|
+
}
|
|
2047
|
+
};
|
|
2048
|
+
}
|
|
2481
2049
|
|
|
2482
|
-
|
|
2050
|
+
DocumentObserver.beforeUnmount.get(el).set(id, callback);
|
|
2051
|
+
return this;
|
|
2483
2052
|
};
|
|
2484
2053
|
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
return this.splice(targetIndex + 1, 0, data);
|
|
2054
|
+
NDElement.prototype.htmlElement = function() {
|
|
2055
|
+
return this.$element;
|
|
2488
2056
|
};
|
|
2489
2057
|
|
|
2490
|
-
|
|
2491
|
-
* Removes the element at the specified index and triggers an update.
|
|
2492
|
-
*
|
|
2493
|
-
* @param {number} index - Index of the element to remove
|
|
2494
|
-
* @returns {Array} Array containing the removed element, or empty array if index is invalid
|
|
2495
|
-
* @example
|
|
2496
|
-
* const items = Observable.array(['a', 'b', 'c']);
|
|
2497
|
-
* items.remove(1); // ['b'] - Array is now ['a', 'c']
|
|
2498
|
-
*/
|
|
2499
|
-
ObservableArray.prototype.remove = function(index) {
|
|
2500
|
-
let deleted = [];
|
|
2501
|
-
this.$mutate('remove', [index], ([idx]) => {
|
|
2502
|
-
deleted = this.$currentValue.splice(idx, 1);
|
|
2503
|
-
if(deleted.length === 0) {
|
|
2504
|
-
return;
|
|
2505
|
-
}
|
|
2506
|
-
this.trigger({action: 'remove', args: [idx], result: deleted[0]});
|
|
2507
|
-
});
|
|
2508
|
-
return deleted;
|
|
2509
|
-
};
|
|
2058
|
+
NDElement.prototype.node = NDElement.prototype.htmlElement;
|
|
2510
2059
|
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
*/
|
|
2520
|
-
ObservableArray.prototype.removeItem = function(item) {
|
|
2521
|
-
const indexOfItem = this.$currentValue.indexOf(item);
|
|
2522
|
-
if(indexOfItem === -1) {
|
|
2523
|
-
return [];
|
|
2060
|
+
NDElement.prototype.shadow = function(mode, style = null) {
|
|
2061
|
+
const $element = this.$element;
|
|
2062
|
+
const children = Array.from($element.childNodes);
|
|
2063
|
+
const shadowRoot = $element.attachShadow({ mode });
|
|
2064
|
+
if(style) {
|
|
2065
|
+
const styleNode = document.createElement("style");
|
|
2066
|
+
styleNode.textContent = style;
|
|
2067
|
+
shadowRoot.appendChild(styleNode);
|
|
2524
2068
|
}
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
/**
|
|
2529
|
-
* Checks if the array is empty.
|
|
2530
|
-
*
|
|
2531
|
-
* @returns {boolean} True if array has no elements
|
|
2532
|
-
* @example
|
|
2533
|
-
* const items = Observable.array([]);
|
|
2534
|
-
* items.isEmpty(); // true
|
|
2535
|
-
*/
|
|
2536
|
-
ObservableArray.prototype.empty = function() {
|
|
2537
|
-
return this.$currentValue.length === 0;
|
|
2538
|
-
};
|
|
2069
|
+
$element.append = shadowRoot.append.bind(shadowRoot);
|
|
2070
|
+
$element.appendChild = shadowRoot.appendChild.bind(shadowRoot);
|
|
2071
|
+
shadowRoot.append(...children);
|
|
2539
2072
|
|
|
2540
|
-
|
|
2541
|
-
* Triggers a populate operation with the current array, iteration count, and callback.
|
|
2542
|
-
* Used internally for rendering optimizations.
|
|
2543
|
-
*
|
|
2544
|
-
* @param {number} iteration - Iteration count for rendering
|
|
2545
|
-
* @param {Function} callback - Callback function for rendering items
|
|
2546
|
-
*/
|
|
2547
|
-
ObservableArray.prototype.populateAndRender = function(iteration, callback) {
|
|
2548
|
-
this.trigger({ action: 'populate', args: [this.$currentValue, iteration, callback] });
|
|
2073
|
+
return this;
|
|
2549
2074
|
};
|
|
2550
2075
|
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
* Creates a filtered view of the array based on predicates.
|
|
2554
|
-
* The filtered array updates automatically when source data or predicates change.
|
|
2555
|
-
*
|
|
2556
|
-
* @param {Object} predicates - Object mapping property names to filter conditions or functions
|
|
2557
|
-
* @returns {ObservableArray} A new observable array containing filtered items
|
|
2558
|
-
* @example
|
|
2559
|
-
* const users = Observable.array([
|
|
2560
|
-
* { name: 'John', age: 25 },
|
|
2561
|
-
* { name: 'Jane', age: 30 }
|
|
2562
|
-
* ]);
|
|
2563
|
-
*
|
|
2564
|
-
* const adults = users.where({ age: (val) => val >= 18 });
|
|
2565
|
-
*/
|
|
2566
|
-
ObservableArray.prototype.where = function(predicates) {
|
|
2567
|
-
if(typeof predicates === 'function') {
|
|
2568
|
-
predicates = { _: predicates };
|
|
2569
|
-
}
|
|
2570
|
-
const sourceArray = this;
|
|
2571
|
-
const observableDependencies = [sourceArray];
|
|
2572
|
-
const filterCallbacks = {};
|
|
2573
|
-
|
|
2574
|
-
for (const [key, rawPredicate] of Object.entries(predicates)) {
|
|
2575
|
-
const predicate = Validator.isObservable(rawPredicate) ? match(rawPredicate, false) : rawPredicate;
|
|
2576
|
-
if (predicate && typeof predicate === 'object' && 'callback' in predicate) {
|
|
2577
|
-
filterCallbacks[key] = predicate.callback;
|
|
2578
|
-
|
|
2579
|
-
if (predicate.dependencies) {
|
|
2580
|
-
const deps = Array.isArray(predicate.dependencies)
|
|
2581
|
-
? predicate.dependencies
|
|
2582
|
-
: [predicate.dependencies];
|
|
2583
|
-
observableDependencies.push.apply(observableDependencies, deps);
|
|
2584
|
-
}
|
|
2585
|
-
} else if(typeof predicate === 'function') {
|
|
2586
|
-
filterCallbacks[key] = predicate;
|
|
2587
|
-
} else {
|
|
2588
|
-
filterCallbacks[key] = (value) => value === predicate;
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
|
|
2592
|
-
const viewArray = Observable.array();
|
|
2593
|
-
|
|
2594
|
-
const filters = Object.entries(filterCallbacks);
|
|
2595
|
-
const updateView = () => {
|
|
2596
|
-
const filtered = sourceArray.val().filter(item => {
|
|
2597
|
-
for (const [key, callback] of filters) {
|
|
2598
|
-
if(key === '_') {
|
|
2599
|
-
if (!callback(item)) return false;
|
|
2600
|
-
} else {
|
|
2601
|
-
if (!callback(item[key])) return false;
|
|
2602
|
-
}
|
|
2603
|
-
}
|
|
2604
|
-
return true;
|
|
2605
|
-
});
|
|
2606
|
-
|
|
2607
|
-
viewArray.set(filtered);
|
|
2608
|
-
};
|
|
2609
|
-
|
|
2610
|
-
observableDependencies.forEach(dep => dep.subscribe(updateView));
|
|
2611
|
-
|
|
2612
|
-
updateView();
|
|
2613
|
-
|
|
2614
|
-
return viewArray;
|
|
2076
|
+
NDElement.prototype.openShadow = function(style = null) {
|
|
2077
|
+
return this.shadow('open', style);
|
|
2615
2078
|
};
|
|
2616
2079
|
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
*
|
|
2620
|
-
* @param {Array<string>} fields - Array of field names to check
|
|
2621
|
-
* @param {FilterResult} filter - Filter condition with callback and dependencies
|
|
2622
|
-
* @returns {ObservableArray} A new observable array containing filtered items
|
|
2623
|
-
* @example
|
|
2624
|
-
* const products = Observable.array([
|
|
2625
|
-
* { name: 'Apple', category: 'Fruit' },
|
|
2626
|
-
* { name: 'Carrot', category: 'Vegetable' }
|
|
2627
|
-
* ]);
|
|
2628
|
-
* const searchTerm = Observable('App');
|
|
2629
|
-
* const filtered = products.whereSome(['name', 'category'], match(searchTerm));
|
|
2630
|
-
*/
|
|
2631
|
-
ObservableArray.prototype.whereSome = function(fields, filter) {
|
|
2632
|
-
return this.where({
|
|
2633
|
-
_: {
|
|
2634
|
-
dependencies: filter.dependencies,
|
|
2635
|
-
callback: (item) => fields.some(field => filter.callback(item[field]))
|
|
2636
|
-
}
|
|
2637
|
-
});
|
|
2080
|
+
NDElement.prototype.closedShadow = function(style = null) {
|
|
2081
|
+
return this.shadow('closed', style);
|
|
2638
2082
|
};
|
|
2639
2083
|
|
|
2640
2084
|
/**
|
|
2641
|
-
*
|
|
2085
|
+
* Extends the current NDElement instance with custom methods.
|
|
2086
|
+
* Methods are bound to the instance and available for chaining.
|
|
2642
2087
|
*
|
|
2643
|
-
* @param {
|
|
2644
|
-
* @
|
|
2645
|
-
* @returns {ObservableArray} A new observable array containing filtered items
|
|
2088
|
+
* @param {Object} methods - Object containing method definitions
|
|
2089
|
+
* @returns {this} The NDElement instance with added methods for chaining
|
|
2646
2090
|
* @example
|
|
2647
|
-
*
|
|
2648
|
-
* {
|
|
2649
|
-
*
|
|
2650
|
-
*
|
|
2651
|
-
*
|
|
2652
|
-
*
|
|
2653
|
-
*/
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
dependencies: filter.dependencies,
|
|
2658
|
-
callback: (item) => fields.every(field => filter.callback(item[field]))
|
|
2659
|
-
}
|
|
2660
|
-
});
|
|
2661
|
-
};
|
|
2662
|
-
|
|
2663
|
-
ObservableArray.prototype.deepSubscribe = function(callback) {
|
|
2664
|
-
const updatedValue = nextTick(() => callback(this.val()));
|
|
2665
|
-
const $listeners = new WeakMap();
|
|
2666
|
-
|
|
2667
|
-
const bindItem = (item) => {
|
|
2668
|
-
if ($listeners.has(item)) {
|
|
2669
|
-
return;
|
|
2670
|
-
}
|
|
2671
|
-
if (item?.__$isObservableArray) {
|
|
2672
|
-
$listeners.set(item, item.deepSubscribe(updatedValue));
|
|
2673
|
-
return;
|
|
2674
|
-
}
|
|
2675
|
-
if (item?.__$isObservable) {
|
|
2676
|
-
item.subscribe(updatedValue);
|
|
2677
|
-
$listeners.set(item, () => item.unsubscribe(updatedValue));
|
|
2678
|
-
}
|
|
2679
|
-
};
|
|
2680
|
-
|
|
2681
|
-
const unbindItem = (item) => {
|
|
2682
|
-
const unsub = $listeners.get(item);
|
|
2683
|
-
if (unsub) {
|
|
2684
|
-
unsub();
|
|
2685
|
-
$listeners.delete(item);
|
|
2686
|
-
}
|
|
2687
|
-
};
|
|
2688
|
-
|
|
2689
|
-
this.$currentValue.forEach(bindItem);
|
|
2690
|
-
this.subscribe(updatedValue);
|
|
2691
|
-
|
|
2692
|
-
this.subscribe((items, _, operations) => {
|
|
2693
|
-
switch (operations?.action) {
|
|
2694
|
-
case 'push':
|
|
2695
|
-
case 'unshift':
|
|
2696
|
-
operations.args.forEach(bindItem);
|
|
2697
|
-
break;
|
|
2698
|
-
|
|
2699
|
-
case 'splice': {
|
|
2700
|
-
const [start, deleteCount, ...newItems] = operations.args;
|
|
2701
|
-
operations.result?.forEach(unbindItem);
|
|
2702
|
-
newItems.forEach(bindItem);
|
|
2703
|
-
break;
|
|
2704
|
-
}
|
|
2705
|
-
|
|
2706
|
-
case 'remove':
|
|
2707
|
-
unbindItem(operations.result);
|
|
2708
|
-
break;
|
|
2709
|
-
|
|
2710
|
-
case 'merge':
|
|
2711
|
-
operations.args.forEach(bindItem);
|
|
2712
|
-
break;
|
|
2713
|
-
|
|
2714
|
-
case 'clear':
|
|
2715
|
-
this.$currentValue.forEach(unbindItem);
|
|
2716
|
-
break;
|
|
2717
|
-
}
|
|
2718
|
-
});
|
|
2719
|
-
|
|
2720
|
-
return () => {
|
|
2721
|
-
this.$currentValue.forEach(unbindItem);
|
|
2722
|
-
};
|
|
2723
|
-
};
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
ObservableArray.prototype.sync = function(targetObservable) {
|
|
2727
|
-
if (!targetObservable || !targetObservable.__$isObservableArray) {
|
|
2728
|
-
throw new NativeDocumentError('ObservableArray.sync : target must be an ObservableArray');
|
|
2091
|
+
* element.nd.with({
|
|
2092
|
+
* highlight() {
|
|
2093
|
+
* this.$element.style.background = 'yellow';
|
|
2094
|
+
* return this;
|
|
2095
|
+
* }
|
|
2096
|
+
* }).highlight().onClick(() => console.log('Clicked'));
|
|
2097
|
+
*/
|
|
2098
|
+
NDElement.prototype.with = function(methods) {
|
|
2099
|
+
if (!methods || typeof methods !== 'object') {
|
|
2100
|
+
throw new NativeDocumentError('extend() requires an object of methods');
|
|
2729
2101
|
}
|
|
2730
2102
|
|
|
2731
|
-
|
|
2103
|
+
for (const name in methods) {
|
|
2104
|
+
const method = methods[name];
|
|
2732
2105
|
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
return;
|
|
2106
|
+
if (typeof method !== 'function') {
|
|
2107
|
+
DebugManager$2.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
|
|
2108
|
+
continue;
|
|
2737
2109
|
}
|
|
2738
2110
|
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
};
|
|
2742
|
-
this.subscribe(sync);
|
|
2743
|
-
|
|
2744
|
-
return () => this.unsubscribe(sync);
|
|
2745
|
-
};
|
|
2111
|
+
this[name] = method.bind(this);
|
|
2112
|
+
}
|
|
2746
2113
|
|
|
2747
|
-
|
|
2748
|
-
return new ObservableArray(this.resolve());
|
|
2114
|
+
return this;
|
|
2749
2115
|
};
|
|
2750
2116
|
|
|
2751
2117
|
/**
|
|
2752
|
-
*
|
|
2753
|
-
*
|
|
2118
|
+
* Extends the NDElement prototype with new methods available to all NDElement instances.
|
|
2119
|
+
* Use this to add global methods to all NDElements.
|
|
2754
2120
|
*
|
|
2755
|
-
* @param {
|
|
2756
|
-
* @
|
|
2757
|
-
*
|
|
2758
|
-
* // @param {boolean} [configs.deep=false] - Whether to make nested objects observable
|
|
2759
|
-
* @param {boolean} [configs.reset=false] - Whether to store initial value for reset()
|
|
2760
|
-
* @returns {ObservableArray} An observable array with reactive methods
|
|
2121
|
+
* @param {Object} methods - Object containing method definitions to add to prototype
|
|
2122
|
+
* @returns {typeof NDElement} The NDElement constructor
|
|
2123
|
+
* @throws {NativeDocumentError} If methods is not an object or contains non-function values
|
|
2761
2124
|
* @example
|
|
2762
|
-
*
|
|
2763
|
-
*
|
|
2764
|
-
*
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
/**
|
|
2771
|
-
*
|
|
2772
|
-
* @param {Function} callback
|
|
2773
|
-
* @returns {Function}
|
|
2125
|
+
* NDElement.extend({
|
|
2126
|
+
* fadeIn() {
|
|
2127
|
+
* this.$element.style.opacity = '1';
|
|
2128
|
+
* return this;
|
|
2129
|
+
* }
|
|
2130
|
+
* });
|
|
2131
|
+
* // Now all NDElements have .fadeIn() method
|
|
2132
|
+
* Div().nd.fadeIn();
|
|
2774
2133
|
*/
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
if(Validator.isAsyncFunction(callback)) {
|
|
2779
|
-
return (callback(...arguments)).then(() => {
|
|
2780
|
-
$observer.trigger();
|
|
2781
|
-
}).catch(error => { throw error; });
|
|
2782
|
-
}
|
|
2783
|
-
callback(...arguments);
|
|
2784
|
-
$observer.trigger();
|
|
2785
|
-
};
|
|
2786
|
-
batch.$observer = $observer;
|
|
2787
|
-
return batch;
|
|
2788
|
-
};
|
|
2789
|
-
|
|
2790
|
-
const ObservableObject = function(target, configs) {
|
|
2791
|
-
ObservableItem.call(this, target);
|
|
2792
|
-
this.$observables = {};
|
|
2793
|
-
this.configs = configs;
|
|
2794
|
-
|
|
2795
|
-
this.$load(target);
|
|
2796
|
-
|
|
2797
|
-
for(const name in target) {
|
|
2798
|
-
if(!Object.hasOwn(this, name)) {
|
|
2799
|
-
Object.defineProperty(this, name, {
|
|
2800
|
-
get: () => this.$observables[name],
|
|
2801
|
-
set: (value) => this.$observables[name].set(value)
|
|
2802
|
-
});
|
|
2803
|
-
}
|
|
2134
|
+
NDElement.extend = function(methods) {
|
|
2135
|
+
if (!methods || typeof methods !== 'object') {
|
|
2136
|
+
throw new NativeDocumentError('NDElement.extend() requires an object of methods');
|
|
2804
2137
|
}
|
|
2805
2138
|
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
ObservableObject.prototype = Object.create(ObservableItem.prototype);
|
|
2809
|
-
|
|
2810
|
-
Object.defineProperty(ObservableObject, '$value', {
|
|
2811
|
-
get() {
|
|
2812
|
-
return this.val();
|
|
2813
|
-
},
|
|
2814
|
-
set(value) {
|
|
2815
|
-
this.set(value);
|
|
2139
|
+
if (Array.isArray(methods)) {
|
|
2140
|
+
throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
|
|
2816
2141
|
}
|
|
2817
|
-
});
|
|
2818
2142
|
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
for(const key in initialValue) {
|
|
2825
|
-
const itemValue = initialValue[key];
|
|
2826
|
-
if(Array.isArray(itemValue)) {
|
|
2827
|
-
if(configs?.deep !== false) {
|
|
2828
|
-
const mappedItemValue = itemValue.map(item => {
|
|
2829
|
-
if(Validator.isJson(item)) {
|
|
2830
|
-
return Observable.json(item, configs);
|
|
2831
|
-
}
|
|
2832
|
-
if(Validator.isArray(item)) {
|
|
2833
|
-
return Observable.array(item, configs);
|
|
2834
|
-
}
|
|
2835
|
-
return Observable(item, configs);
|
|
2836
|
-
});
|
|
2837
|
-
this.$observables[key] = Observable.array(mappedItemValue, configs);
|
|
2838
|
-
continue;
|
|
2839
|
-
}
|
|
2840
|
-
this.$observables[key] = Observable.array(itemValue, configs);
|
|
2841
|
-
continue;
|
|
2842
|
-
}
|
|
2843
|
-
if(Validator.isObservable(itemValue) || Validator.isProxy(itemValue)) {
|
|
2844
|
-
this.$observables[key] = itemValue;
|
|
2845
|
-
continue;
|
|
2846
|
-
}
|
|
2847
|
-
this.$observables[key] = (typeof itemValue === 'object') ? Observable.object(itemValue, configs) : Observable(itemValue, configs);
|
|
2848
|
-
}
|
|
2849
|
-
};
|
|
2143
|
+
const protectedMethods = new Set([
|
|
2144
|
+
'constructor', 'valueOf', '$element', '$observer',
|
|
2145
|
+
'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
|
|
2146
|
+
'lifecycle', 'mounted', 'unmounted', 'unmountChildren'
|
|
2147
|
+
]);
|
|
2850
2148
|
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
const dataItem = this.$observables[key];
|
|
2855
|
-
if(Validator.isObservable(dataItem)) {
|
|
2856
|
-
let value = dataItem.val();
|
|
2857
|
-
if(Array.isArray(value)) {
|
|
2858
|
-
value = value.map(item => {
|
|
2859
|
-
if(Validator.isObservable(item)) {
|
|
2860
|
-
return item.val();
|
|
2861
|
-
}
|
|
2862
|
-
if(Validator.isProxy(item)) {
|
|
2863
|
-
return item.$value;
|
|
2864
|
-
}
|
|
2865
|
-
return item;
|
|
2866
|
-
});
|
|
2867
|
-
}
|
|
2868
|
-
result[key] = value;
|
|
2869
|
-
} else if(Validator.isProxy(dataItem)) {
|
|
2870
|
-
result[key] = dataItem.$value;
|
|
2871
|
-
} else {
|
|
2872
|
-
result[key] = dataItem;
|
|
2149
|
+
for (const name in methods) {
|
|
2150
|
+
if (!Object.hasOwn(methods, name)) {
|
|
2151
|
+
continue;
|
|
2873
2152
|
}
|
|
2874
|
-
}
|
|
2875
|
-
return result;
|
|
2876
|
-
};
|
|
2877
|
-
ObservableObject.prototype.$val = ObservableObject.prototype.val;
|
|
2878
|
-
|
|
2879
|
-
ObservableObject.prototype.get = function(property) {
|
|
2880
|
-
const item = this.$observables[property];
|
|
2881
|
-
if(Validator.isObservable(item)) {
|
|
2882
|
-
return item.val();
|
|
2883
|
-
}
|
|
2884
|
-
if(Validator.isProxy(item)) {
|
|
2885
|
-
return item.$value;
|
|
2886
|
-
}
|
|
2887
|
-
return item;
|
|
2888
|
-
};
|
|
2889
|
-
ObservableObject.prototype.$get = ObservableObject.prototype.get;
|
|
2890
2153
|
|
|
2891
|
-
|
|
2892
|
-
const data = Validator.isProxy(newData) ? newData.$value : newData;
|
|
2893
|
-
const configs = this.configs;
|
|
2894
|
-
|
|
2895
|
-
for(const key in data) {
|
|
2896
|
-
const targetItem = this.$observables[key];
|
|
2897
|
-
const newValueOrigin = newData[key];
|
|
2898
|
-
const newValue = data[key];
|
|
2154
|
+
const method = methods[name];
|
|
2899
2155
|
|
|
2900
|
-
if(
|
|
2901
|
-
|
|
2902
|
-
targetItem.set(newValue);
|
|
2903
|
-
continue;
|
|
2904
|
-
}
|
|
2905
|
-
const firstElementFromOriginalValue = newValueOrigin.at(0);
|
|
2906
|
-
if(Validator.isObservable(firstElementFromOriginalValue) || Validator.isProxy(firstElementFromOriginalValue)) {
|
|
2907
|
-
const newValues = newValue.map(item => {
|
|
2908
|
-
if(Validator.isProxy(firstElementFromOriginalValue)) {
|
|
2909
|
-
return Observable.init(item, configs);
|
|
2910
|
-
}
|
|
2911
|
-
return Observable(item, configs);
|
|
2912
|
-
});
|
|
2913
|
-
targetItem.set(newValues);
|
|
2914
|
-
continue;
|
|
2915
|
-
}
|
|
2916
|
-
targetItem.set([...newValue]);
|
|
2917
|
-
continue;
|
|
2918
|
-
}
|
|
2919
|
-
if(Validator.isProxy(targetItem)) {
|
|
2920
|
-
targetItem.update(newValue);
|
|
2156
|
+
if (typeof method !== 'function') {
|
|
2157
|
+
DebugManager$2.warn('NDElement.extend', `"${name}" is not a function, skipping`);
|
|
2921
2158
|
continue;
|
|
2922
2159
|
}
|
|
2923
|
-
this[key] = newValue;
|
|
2924
|
-
}
|
|
2925
|
-
};
|
|
2926
|
-
ObservableObject.prototype.$set = ObservableObject.prototype.set;
|
|
2927
|
-
ObservableObject.prototype.$updateWith = ObservableObject.prototype.set;
|
|
2928
|
-
|
|
2929
|
-
ObservableObject.prototype.observables = function() {
|
|
2930
|
-
return Object.values(this.$observables);
|
|
2931
|
-
};
|
|
2932
|
-
ObservableObject.prototype.$observables = ObservableObject.prototype.observables;
|
|
2933
|
-
|
|
2934
|
-
ObservableObject.prototype.keys = function() {
|
|
2935
|
-
return Object.keys(this.$observables);
|
|
2936
|
-
};
|
|
2937
|
-
ObservableObject.prototype.$keys = ObservableObject.prototype.keys;
|
|
2938
|
-
ObservableObject.prototype.clone = function() {
|
|
2939
|
-
return Observable.init(this.val(), this.configs);
|
|
2940
|
-
};
|
|
2941
|
-
ObservableObject.prototype.$clone = ObservableObject.prototype.clone;
|
|
2942
|
-
ObservableObject.prototype.reset = function() {
|
|
2943
|
-
for(const key in this.$observables) {
|
|
2944
|
-
this.$observables[key].reset();
|
|
2945
|
-
}
|
|
2946
|
-
};
|
|
2947
|
-
ObservableObject.prototype.originalSubscribe = ObservableObject.prototype.subscribe;
|
|
2948
|
-
ObservableObject.prototype.subscribe = function(callback) {
|
|
2949
|
-
const observables = this.observables();
|
|
2950
|
-
const updatedValue = nextTick(() => this.trigger());
|
|
2951
2160
|
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
const observable = observables[i];
|
|
2956
|
-
if (observable.__$isObservableArray) {
|
|
2957
|
-
observable.deepSubscribe(updatedValue);
|
|
2958
|
-
continue
|
|
2161
|
+
if (protectedMethods.has(name)) {
|
|
2162
|
+
DebugManager$2.error('NDElement.extend', `Cannot override protected method "${name}"`);
|
|
2163
|
+
throw new NativeDocumentError(`Cannot override protected method "${name}"`);
|
|
2959
2164
|
}
|
|
2960
|
-
observable.subscribe(updatedValue);
|
|
2961
|
-
}
|
|
2962
|
-
};
|
|
2963
|
-
ObservableObject.prototype.configs = function() {
|
|
2964
|
-
return this.configs;
|
|
2965
|
-
};
|
|
2966
|
-
|
|
2967
|
-
ObservableObject.prototype.update = ObservableObject.prototype.set;
|
|
2968
|
-
|
|
2969
|
-
Observable.init = function(initialValue, configs = null) {
|
|
2970
|
-
return new ObservableObject(initialValue, configs)
|
|
2971
|
-
};
|
|
2972
|
-
|
|
2973
|
-
/**
|
|
2974
|
-
*
|
|
2975
|
-
* @param {any[]} data
|
|
2976
|
-
* @return Proxy[]
|
|
2977
|
-
*/
|
|
2978
|
-
Observable.arrayOfObject = function(data) {
|
|
2979
|
-
return data.map(item => Observable.object(item));
|
|
2980
|
-
};
|
|
2981
2165
|
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
* @param {ObservableItem|Object<ObservableItem>} data
|
|
2985
|
-
* @returns {{}|*|null}
|
|
2986
|
-
*/
|
|
2987
|
-
Observable.value = function(data) {
|
|
2988
|
-
if(data?.__$isObservableArray) {
|
|
2989
|
-
const result = [];
|
|
2990
|
-
for(let i = 0, length = data.length; i < length; i++) {
|
|
2991
|
-
const item = data.at(i);
|
|
2992
|
-
result.push(Observable.value(item));
|
|
2166
|
+
if (NDElement.prototype[name]) {
|
|
2167
|
+
DebugManager$2.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
|
|
2993
2168
|
}
|
|
2994
|
-
return result;
|
|
2995
|
-
}
|
|
2996
|
-
if(data?.__$Observable) {
|
|
2997
|
-
return data.val();
|
|
2998
|
-
}
|
|
2999
|
-
if(Validator.isProxy(data)) {
|
|
3000
|
-
return data.$value;
|
|
3001
|
-
}
|
|
3002
|
-
return data;
|
|
3003
|
-
};
|
|
3004
2169
|
|
|
3005
|
-
|
|
3006
|
-
return Observable.value(this);
|
|
3007
|
-
};
|
|
3008
|
-
|
|
3009
|
-
Observable.object = Observable.init;
|
|
3010
|
-
Observable.json = Observable.init;
|
|
3011
|
-
|
|
3012
|
-
/**
|
|
3013
|
-
* Creates a computed observable that automatically updates when its dependencies change.
|
|
3014
|
-
* The callback is re-executed whenever any dependency observable changes.
|
|
3015
|
-
*
|
|
3016
|
-
* @param {Function} callback - Function that returns the computed value
|
|
3017
|
-
* @param {Array<ObservableItem|ObservableChecker|ObservableProxy>|Function} [dependencies=[]] - Array of observables to watch, or batch function
|
|
3018
|
-
* @returns {ObservableItem} A new observable that updates automatically
|
|
3019
|
-
* @example
|
|
3020
|
-
* const firstName = Observable('John');
|
|
3021
|
-
* const lastName = Observable('Doe');
|
|
3022
|
-
* const fullName = Observable.computed(
|
|
3023
|
-
* () => `${firstName.val()} ${lastName.val()}`,
|
|
3024
|
-
* [firstName, lastName]
|
|
3025
|
-
* );
|
|
3026
|
-
*
|
|
3027
|
-
* // With batch function
|
|
3028
|
-
* const batch = Observable.batch(() => { ... });
|
|
3029
|
-
* const computed = Observable.computed(() => { ... }, batch);
|
|
3030
|
-
*/
|
|
3031
|
-
Observable.computed = function(callback, dependencies = []) {
|
|
3032
|
-
const initialValue = callback();
|
|
3033
|
-
const observable = new ObservableItem(initialValue);
|
|
3034
|
-
const getValues = () => dependencies.map((item) => item.val());
|
|
3035
|
-
const updatedValue = nextTick(() => observable.set(callback(...getValues())));
|
|
3036
|
-
|
|
3037
|
-
if(Validator.isFunction(dependencies)) {
|
|
3038
|
-
if(!Validator.isObservable(dependencies.$observer)) {
|
|
3039
|
-
throw new NativeDocumentError('Observable.computed : dependencies must be valid batch function');
|
|
3040
|
-
}
|
|
3041
|
-
dependencies.$observer.subscribe(updatedValue);
|
|
3042
|
-
return observable;
|
|
2170
|
+
NDElement.prototype[name] = method;
|
|
3043
2171
|
}
|
|
3044
2172
|
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
dependency.$observables.forEach((observable) => {
|
|
3048
|
-
observable.subscribe(updatedValue);
|
|
3049
|
-
});
|
|
3050
|
-
return;
|
|
3051
|
-
}
|
|
3052
|
-
dependency.subscribe(updatedValue);
|
|
3053
|
-
});
|
|
2173
|
+
return NDElement;
|
|
2174
|
+
};
|
|
3054
2175
|
|
|
3055
|
-
|
|
2176
|
+
const COMMON_NODE_TYPES = {
|
|
2177
|
+
ELEMENT: 1,
|
|
2178
|
+
TEXT: 3,
|
|
2179
|
+
COMMENT: 8,
|
|
2180
|
+
DOCUMENT_FRAGMENT: 11
|
|
3056
2181
|
};
|
|
3057
2182
|
|
|
3058
|
-
const
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
//
|
|
3064
|
-
|
|
3065
|
-
ObservableItem.prototype.isEqualTo = function (value) {
|
|
3066
|
-
if (value?.__$Observable) {
|
|
3067
|
-
return $computed((a, b) => a === b, [this, value]);
|
|
3068
|
-
}
|
|
3069
|
-
return $checker(this, x => x === value);
|
|
3070
|
-
};
|
|
3071
|
-
|
|
3072
|
-
ObservableItem.prototype.isNotEqualTo = function (value) {
|
|
3073
|
-
if (value?.__$Observable) {
|
|
3074
|
-
return $computed((a, b) => a !== b, [this, value]);
|
|
3075
|
-
}
|
|
3076
|
-
return $checker(this, x => x !== value);
|
|
3077
|
-
};
|
|
2183
|
+
const VALID_TYPES = [];
|
|
2184
|
+
VALID_TYPES[COMMON_NODE_TYPES.ELEMENT] = true;
|
|
2185
|
+
VALID_TYPES[COMMON_NODE_TYPES.TEXT] = true;
|
|
2186
|
+
VALID_TYPES[COMMON_NODE_TYPES.DOCUMENT_FRAGMENT] = true;
|
|
2187
|
+
VALID_TYPES[COMMON_NODE_TYPES.COMMENT] = true;
|
|
3078
2188
|
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
return $
|
|
3082
|
-
}
|
|
3083
|
-
|
|
3084
|
-
|
|
2189
|
+
const Validator = {
|
|
2190
|
+
isObservable(value) {
|
|
2191
|
+
return value && (value.__$isObservable || value.__$Observable);
|
|
2192
|
+
},
|
|
2193
|
+
isTemplateBinding(value) {
|
|
2194
|
+
return value?.__$isTemplateBinding;
|
|
2195
|
+
},
|
|
2196
|
+
isObservableWhenResult(value) {
|
|
2197
|
+
return value && (value.__$isObservableWhen || (typeof value === 'object' && '$target' in value && '$observer' in value));
|
|
2198
|
+
},
|
|
2199
|
+
isArrayObservable(value) {
|
|
2200
|
+
return value?.__$isObservableArray;
|
|
2201
|
+
},
|
|
2202
|
+
isProxy(value) {
|
|
2203
|
+
return value?.__isProxy__
|
|
2204
|
+
},
|
|
2205
|
+
isObservableOrProxy(value) {
|
|
2206
|
+
return Validator.isObservable(value) || Validator.isProxy(value);
|
|
2207
|
+
},
|
|
2208
|
+
isAnchor(value) {
|
|
2209
|
+
return value?.__Anchor__
|
|
2210
|
+
},
|
|
2211
|
+
isObservableChecker(value) {
|
|
2212
|
+
return value?.__$isObservableChecker || value instanceof ObservableChecker;
|
|
2213
|
+
},
|
|
2214
|
+
isArray(value) {
|
|
2215
|
+
return Array.isArray(value);
|
|
2216
|
+
},
|
|
2217
|
+
isString(value) {
|
|
2218
|
+
return typeof value === 'string';
|
|
2219
|
+
},
|
|
2220
|
+
isNumber(value) {
|
|
2221
|
+
return typeof value === 'number';
|
|
2222
|
+
},
|
|
2223
|
+
isBoolean(value) {
|
|
2224
|
+
return typeof value === 'boolean';
|
|
2225
|
+
},
|
|
2226
|
+
isFunction(value) {
|
|
2227
|
+
return typeof value === 'function';
|
|
2228
|
+
},
|
|
2229
|
+
isAsyncFunction(value) {
|
|
2230
|
+
return typeof value === 'function' && value.constructor.name === 'AsyncFunction';
|
|
2231
|
+
},
|
|
2232
|
+
isObject(value) {
|
|
2233
|
+
return typeof value === 'object' && value !== null;
|
|
2234
|
+
},
|
|
2235
|
+
isJson(value) {
|
|
2236
|
+
return !(typeof value !== 'object' || value === null || Array.isArray(value) || value.constructor.name !== 'Object')
|
|
2237
|
+
},
|
|
2238
|
+
isElement(value) {
|
|
2239
|
+
return value && VALID_TYPES[value.nodeType];
|
|
2240
|
+
},
|
|
2241
|
+
isDOMNode(value) {
|
|
2242
|
+
return VALID_TYPES[value.nodeType];
|
|
2243
|
+
},
|
|
2244
|
+
isFragment(value) {
|
|
2245
|
+
return value?.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT;
|
|
2246
|
+
},
|
|
2247
|
+
isStringOrObservable(value) {
|
|
2248
|
+
return this.isString(value) || this.isObservable(value);
|
|
2249
|
+
},
|
|
2250
|
+
isValidChild(child) {
|
|
2251
|
+
return child === null ||
|
|
2252
|
+
this.isElement(child) ||
|
|
2253
|
+
this.isObservable(child) ||
|
|
2254
|
+
this.isNDElement(child) ||
|
|
2255
|
+
['string', 'number', 'boolean'].includes(typeof child);
|
|
2256
|
+
},
|
|
2257
|
+
isNDElement(child) {
|
|
2258
|
+
return child?.__$isNDElement || child instanceof NDElement;
|
|
2259
|
+
},
|
|
2260
|
+
isValidChildren(children) {
|
|
2261
|
+
if (!Array.isArray(children)) {
|
|
2262
|
+
children = [children];
|
|
2263
|
+
}
|
|
3085
2264
|
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
2265
|
+
const invalid = children.filter(child => !this.isValidChild(child));
|
|
2266
|
+
return invalid.length === 0;
|
|
2267
|
+
},
|
|
2268
|
+
validateChildren(children) {
|
|
2269
|
+
if (!Array.isArray(children)) {
|
|
2270
|
+
children = [children];
|
|
2271
|
+
}
|
|
3092
2272
|
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
return $checker(this, x => x < value);
|
|
3098
|
-
};
|
|
2273
|
+
const invalid = children.filter(child => !this.isValidChild(child));
|
|
2274
|
+
if (invalid.length > 0) {
|
|
2275
|
+
throw new NativeDocumentError(`Invalid children detected: ${invalid.map(i => typeof i).join(', ')}`);
|
|
2276
|
+
}
|
|
3099
2277
|
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
2278
|
+
return children;
|
|
2279
|
+
},
|
|
2280
|
+
/**
|
|
2281
|
+
* Check if the data contains observables.
|
|
2282
|
+
* @param {Array|Object} data
|
|
2283
|
+
* @returns {boolean}
|
|
2284
|
+
*/
|
|
2285
|
+
containsObservables(data) {
|
|
2286
|
+
if(!data) {
|
|
2287
|
+
return false;
|
|
2288
|
+
}
|
|
2289
|
+
return Validator.isObject(data)
|
|
2290
|
+
&& Object.values(data).some(value => Validator.isObservable(value));
|
|
2291
|
+
},
|
|
2292
|
+
/**
|
|
2293
|
+
* Check if the data contains an observable reference.
|
|
2294
|
+
* @param {string} data
|
|
2295
|
+
* @returns {boolean}
|
|
2296
|
+
*/
|
|
2297
|
+
containsObservableReference(data) {
|
|
2298
|
+
if(!data || typeof data !== 'string') {
|
|
2299
|
+
return false;
|
|
2300
|
+
}
|
|
2301
|
+
return /\{\{#ObItem::\([0-9]+\)\}\}/.test(data);
|
|
2302
|
+
},
|
|
2303
|
+
validateAttributes(attributes) {},
|
|
3106
2304
|
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
if (min.__$Observable) {
|
|
3112
|
-
return $computed((x, a) => x >= a && x <= max, [this, min]);
|
|
3113
|
-
}
|
|
3114
|
-
if (max.__$Observable) {
|
|
3115
|
-
return $computed((x, b) => x >= min && x <= b, [this, max]);
|
|
2305
|
+
validateEventCallback(callback) {
|
|
2306
|
+
if (typeof callback !== 'function') {
|
|
2307
|
+
throw new NativeDocumentError('Event callback must be a function');
|
|
2308
|
+
}
|
|
3116
2309
|
}
|
|
3117
|
-
return $checker(this, x => x >= min && x <= max);
|
|
3118
2310
|
};
|
|
3119
2311
|
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
};
|
|
2312
|
+
const cssPropertyAccumulator = function(initialValue = {}) {
|
|
2313
|
+
let data = Validator.isString(initialValue) ? initialValue.split(';').filter(Boolean) : initialValue;
|
|
3123
2314
|
|
|
3124
|
-
|
|
3125
|
-
|
|
2315
|
+
return {
|
|
2316
|
+
add(key, value) {
|
|
2317
|
+
if(Array.isArray(data)) {
|
|
2318
|
+
data.push(key+': '+value);
|
|
2319
|
+
return;
|
|
2320
|
+
}
|
|
2321
|
+
if(Validator.isObject(key)) {
|
|
2322
|
+
value = key;
|
|
2323
|
+
for(const property in value) {
|
|
2324
|
+
data[property] = value[property];
|
|
2325
|
+
}
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
data[key] = value;
|
|
2329
|
+
},
|
|
2330
|
+
value() {
|
|
2331
|
+
if(Array.isArray(data)) {
|
|
2332
|
+
return data.join(';').concat(';');
|
|
2333
|
+
}
|
|
2334
|
+
return { ...data };
|
|
2335
|
+
},
|
|
2336
|
+
};
|
|
3126
2337
|
};
|
|
3127
2338
|
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
};
|
|
2339
|
+
const classPropertyAccumulator = function(initialValue = []) {
|
|
2340
|
+
let data = Validator.isString(initialValue) ? initialValue.split(" ").filter(Boolean) : initialValue;
|
|
3131
2341
|
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
2342
|
+
return {
|
|
2343
|
+
add(key, value = true) {
|
|
2344
|
+
if(Validator.isJson(key)) {
|
|
2345
|
+
for(const property in key) {
|
|
2346
|
+
if(key[property]) {
|
|
2347
|
+
data[property] = key[property];
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
if(value != null || key.__$Observable) {
|
|
2353
|
+
if(Array.isArray(data)) {
|
|
2354
|
+
data = data.reduce((acc, item) => {
|
|
2355
|
+
acc[item] = true;
|
|
2356
|
+
return acc;
|
|
2357
|
+
}, {});
|
|
2358
|
+
}
|
|
2359
|
+
if(key.__$Observable) {
|
|
2360
|
+
const uniqueId = `obs-${Math.random().toString(36).substr(2, 9)}`;
|
|
2361
|
+
data[uniqueId] = key;
|
|
2362
|
+
}
|
|
2363
|
+
else {
|
|
2364
|
+
data[key] = value;
|
|
2365
|
+
}
|
|
2366
|
+
return;
|
|
2367
|
+
}
|
|
2368
|
+
if(Array.isArray(data)) {
|
|
2369
|
+
data.push(key);
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
data[key] = value;
|
|
2373
|
+
},
|
|
2374
|
+
value() {
|
|
2375
|
+
if(Array.isArray(data)) {
|
|
2376
|
+
return data.join(' ');
|
|
2377
|
+
}
|
|
2378
|
+
return { ...data };
|
|
2379
|
+
},
|
|
2380
|
+
};
|
|
3137
2381
|
};
|
|
3138
2382
|
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
2383
|
+
/**
|
|
2384
|
+
* Conditionally shows an element based on an observable condition.
|
|
2385
|
+
* The element is mounted/unmounted from the DOM as the condition changes.
|
|
2386
|
+
*
|
|
2387
|
+
* @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
|
|
2388
|
+
* @param {NdChild|(() => NdChild)} child - Element or content to show/hide
|
|
2389
|
+
* @param {Object} [options={}] - Configuration options
|
|
2390
|
+
* @param {string|null} [options.comment=null] - Comment for debugging
|
|
2391
|
+
* @param {boolean} [options.shouldKeepInCache=true] - Whether to cache the element when hidden
|
|
2392
|
+
* @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
|
|
2393
|
+
* @example
|
|
2394
|
+
* const isVisible = Observable(false);
|
|
2395
|
+
* ShowIf(isVisible, Div({}, 'Hello World'));
|
|
2396
|
+
*/
|
|
2397
|
+
const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
|
|
2398
|
+
if(!Validator.isObservable(condition)) {
|
|
2399
|
+
if(typeof condition === "boolean") {
|
|
2400
|
+
return condition ? ElementCreator.getChild(child) : null;
|
|
2401
|
+
}
|
|
3145
2402
|
|
|
3146
|
-
|
|
3147
|
-
if (regex?.__$Observable) {
|
|
3148
|
-
return $computed((a, b) => new RegExp(b).test(String(a)), [this, regex]);
|
|
2403
|
+
return DebugManager$2.warn('ShowIf', "ShowIf : condition must be an Observable or boolean / "+comment, condition);
|
|
3149
2404
|
}
|
|
3150
|
-
|
|
3151
|
-
};
|
|
2405
|
+
const element = Anchor('Show if : '+(comment || ''));
|
|
3152
2406
|
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
2407
|
+
let childElement = null;
|
|
2408
|
+
const getChildElement = () => {
|
|
2409
|
+
if(childElement && shouldKeepInCache) {
|
|
2410
|
+
return childElement;
|
|
2411
|
+
}
|
|
2412
|
+
childElement = ElementCreator.getChild(child);
|
|
2413
|
+
if(Validator.isFragment(childElement)) {
|
|
2414
|
+
childElement = Array.from(childElement.childNodes);
|
|
2415
|
+
}
|
|
2416
|
+
return childElement;
|
|
2417
|
+
};
|
|
3156
2418
|
|
|
3157
|
-
|
|
3158
|
-
return $checker(this, x => x == null || x === '' || (Array.isArray(x) && x.length !== 0));
|
|
3159
|
-
};
|
|
2419
|
+
const currentValue = condition.val();
|
|
3160
2420
|
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
return $computed((a, b) => {
|
|
3164
|
-
if (Array.isArray(a)) return a.includes(b);
|
|
3165
|
-
return String(a).includes(String(b));
|
|
3166
|
-
}, [this, value]);
|
|
2421
|
+
if(currentValue) {
|
|
2422
|
+
element.appendChild(getChildElement());
|
|
3167
2423
|
}
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
2424
|
+
|
|
2425
|
+
condition.subscribe((value) => {
|
|
2426
|
+
if(!!value) {
|
|
2427
|
+
element.appendChild(getChildElement());
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
element.remove();
|
|
3171
2431
|
});
|
|
3172
|
-
};
|
|
3173
2432
|
|
|
3174
|
-
|
|
3175
|
-
if (array?.__$Observable) {
|
|
3176
|
-
return $computed((a, b) => b.includes(a), [this, array]);
|
|
3177
|
-
}
|
|
3178
|
-
return $checker(this, x => array.includes(x));
|
|
2433
|
+
return element;
|
|
3179
2434
|
};
|
|
3180
2435
|
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
2436
|
+
const EVENTS = [
|
|
2437
|
+
"Click",
|
|
2438
|
+
"DblClick",
|
|
2439
|
+
"MouseDown",
|
|
2440
|
+
"MouseEnter",
|
|
2441
|
+
"MouseLeave",
|
|
2442
|
+
"MouseMove",
|
|
2443
|
+
"MouseOut",
|
|
2444
|
+
"MouseOver",
|
|
2445
|
+
"MouseUp",
|
|
2446
|
+
"Wheel",
|
|
2447
|
+
"KeyDown",
|
|
2448
|
+
"KeyPress",
|
|
2449
|
+
"KeyUp",
|
|
2450
|
+
"Blur",
|
|
2451
|
+
"Change",
|
|
2452
|
+
"Focus",
|
|
2453
|
+
"Input",
|
|
2454
|
+
"Invalid",
|
|
2455
|
+
"Reset",
|
|
2456
|
+
"Search",
|
|
2457
|
+
"Select",
|
|
2458
|
+
"Submit",
|
|
2459
|
+
"Drag",
|
|
2460
|
+
"DragEnd",
|
|
2461
|
+
"DragEnter",
|
|
2462
|
+
"DragLeave",
|
|
2463
|
+
"DragOver",
|
|
2464
|
+
"DragStart",
|
|
2465
|
+
"Drop",
|
|
2466
|
+
"AfterPrint",
|
|
2467
|
+
"BeforePrint",
|
|
2468
|
+
"BeforeUnload",
|
|
2469
|
+
"Error",
|
|
2470
|
+
"HashChange",
|
|
2471
|
+
"Load",
|
|
2472
|
+
"Offline",
|
|
2473
|
+
"Online",
|
|
2474
|
+
"PageHide",
|
|
2475
|
+
"PageShow",
|
|
2476
|
+
"Resize",
|
|
2477
|
+
"Scroll",
|
|
2478
|
+
"Unload",
|
|
2479
|
+
"Abort",
|
|
2480
|
+
"CanPlay",
|
|
2481
|
+
"CanPlayThrough",
|
|
2482
|
+
"DurationChange",
|
|
2483
|
+
"Emptied",
|
|
2484
|
+
"Ended",
|
|
2485
|
+
"LoadedData",
|
|
2486
|
+
"LoadedMetadata",
|
|
2487
|
+
"LoadStart",
|
|
2488
|
+
"Pause",
|
|
2489
|
+
"Play",
|
|
2490
|
+
"Playing",
|
|
2491
|
+
"Progress",
|
|
2492
|
+
"RateChange",
|
|
2493
|
+
"Seeked",
|
|
2494
|
+
"Seeking",
|
|
2495
|
+
"Stalled",
|
|
2496
|
+
"Suspend",
|
|
2497
|
+
"TimeUpdate",
|
|
2498
|
+
"VolumeChange",
|
|
2499
|
+
"Waiting",
|
|
3189
2500
|
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
2501
|
+
"TouchCancel",
|
|
2502
|
+
"TouchEnd",
|
|
2503
|
+
"TouchMove",
|
|
2504
|
+
"TouchStart",
|
|
2505
|
+
"AnimationEnd",
|
|
2506
|
+
"AnimationIteration",
|
|
2507
|
+
"AnimationStart",
|
|
2508
|
+
"TransitionEnd",
|
|
2509
|
+
"Copy",
|
|
2510
|
+
"Cut",
|
|
2511
|
+
"Paste",
|
|
2512
|
+
"FocusIn",
|
|
2513
|
+
"FocusOut",
|
|
2514
|
+
"ContextMenu"
|
|
2515
|
+
];
|
|
3193
2516
|
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
2517
|
+
const EVENTS_WITH_PREVENT = [
|
|
2518
|
+
"Click",
|
|
2519
|
+
"DblClick",
|
|
2520
|
+
"MouseDown",
|
|
2521
|
+
"MouseUp",
|
|
2522
|
+
"Wheel",
|
|
2523
|
+
"KeyDown",
|
|
2524
|
+
"KeyPress",
|
|
2525
|
+
"Invalid",
|
|
2526
|
+
"Reset",
|
|
2527
|
+
"Submit",
|
|
2528
|
+
"DragOver",
|
|
2529
|
+
"Drop",
|
|
2530
|
+
"BeforeUnload",
|
|
2531
|
+
"TouchCancel",
|
|
2532
|
+
"TouchEnd",
|
|
2533
|
+
"TouchMove",
|
|
2534
|
+
"TouchStart",
|
|
2535
|
+
"Copy",
|
|
2536
|
+
"Cut",
|
|
2537
|
+
"Paste",
|
|
2538
|
+
"ContextMenu"
|
|
2539
|
+
];
|
|
3197
2540
|
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
2541
|
+
const EVENTS_WITH_STOP = [
|
|
2542
|
+
"Click",
|
|
2543
|
+
"DblClick",
|
|
2544
|
+
"MouseDown",
|
|
2545
|
+
"MouseMove",
|
|
2546
|
+
"MouseOut",
|
|
2547
|
+
"MouseOver",
|
|
2548
|
+
"MouseUp",
|
|
2549
|
+
"Wheel",
|
|
2550
|
+
"KeyDown",
|
|
2551
|
+
"KeyPress",
|
|
2552
|
+
"KeyUp",
|
|
2553
|
+
"Change",
|
|
2554
|
+
"Input",
|
|
2555
|
+
"Invalid",
|
|
2556
|
+
"Reset",
|
|
2557
|
+
"Search",
|
|
2558
|
+
"Select",
|
|
2559
|
+
"Submit",
|
|
2560
|
+
"Drag",
|
|
2561
|
+
"DragEnd",
|
|
2562
|
+
"DragEnter",
|
|
2563
|
+
"DragLeave",
|
|
2564
|
+
"DragOver",
|
|
2565
|
+
"DragStart",
|
|
2566
|
+
"Drop",
|
|
2567
|
+
"BeforeUnload",
|
|
2568
|
+
"HashChange",
|
|
2569
|
+
"TouchCancel",
|
|
2570
|
+
"TouchEnd",
|
|
2571
|
+
"TouchMove",
|
|
2572
|
+
"TouchStart",
|
|
2573
|
+
"AnimationEnd",
|
|
2574
|
+
"AnimationIteration",
|
|
2575
|
+
"AnimationStart",
|
|
2576
|
+
"TransitionEnd",
|
|
2577
|
+
"Copy",
|
|
2578
|
+
"Cut",
|
|
2579
|
+
"Paste",
|
|
2580
|
+
"FocusIn",
|
|
2581
|
+
"FocusOut",
|
|
2582
|
+
"ContextMenu"
|
|
2583
|
+
];
|
|
3201
2584
|
|
|
3202
|
-
|
|
3203
|
-
|
|
2585
|
+
const property = {
|
|
2586
|
+
configurable: true,
|
|
2587
|
+
get() {
|
|
2588
|
+
return new NDElement(this);
|
|
2589
|
+
}
|
|
3204
2590
|
};
|
|
3205
2591
|
|
|
3206
|
-
|
|
3207
|
-
return $checker(this, x => !!x);
|
|
3208
|
-
};
|
|
2592
|
+
Object.defineProperty(HTMLElement.prototype, 'nd', property);
|
|
3209
2593
|
|
|
3210
|
-
|
|
3211
|
-
return $checker(this, x => template.replace(placeholder, x));
|
|
3212
|
-
};
|
|
2594
|
+
Object.defineProperty(DocumentFragment.prototype, 'nd', property);
|
|
3213
2595
|
|
|
3214
|
-
|
|
2596
|
+
Object.defineProperty(NDElement.prototype, 'nd', {
|
|
2597
|
+
configurable: true,
|
|
2598
|
+
get: function() {
|
|
2599
|
+
return this;
|
|
2600
|
+
}
|
|
2601
|
+
});
|
|
3215
2602
|
|
|
3216
|
-
ObservableItem.prototype.toProperty = function (key) {
|
|
3217
|
-
const keys = key.split('.');
|
|
3218
|
-
return $checker(this, x => {
|
|
3219
|
-
let value = x;
|
|
3220
|
-
for (const k of keys) {
|
|
3221
|
-
if (value == null) return undefined;
|
|
3222
|
-
value = value[k];
|
|
3223
|
-
}
|
|
3224
|
-
return value;
|
|
3225
|
-
});
|
|
3226
|
-
};
|
|
3227
2603
|
|
|
3228
|
-
ObservableItem.prototype.toLength = function () {
|
|
3229
|
-
return $checker(this, x => (x == null ? 0 : x.length));
|
|
3230
|
-
};
|
|
3231
2604
|
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
return $checker(this, x => Math.min(Math.max(x, min), max));
|
|
3243
|
-
};
|
|
2605
|
+
// ----------------------------------------------------------------
|
|
2606
|
+
// Events helpers
|
|
2607
|
+
// ----------------------------------------------------------------
|
|
2608
|
+
EVENTS.forEach(eventSourceName => {
|
|
2609
|
+
const eventName = eventSourceName.toLowerCase();
|
|
2610
|
+
NDElement.prototype['on'+eventSourceName] = function(callback = null) {
|
|
2611
|
+
this.$element.addEventListener(eventName, callback);
|
|
2612
|
+
return this;
|
|
2613
|
+
};
|
|
2614
|
+
});
|
|
3244
2615
|
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
2616
|
+
EVENTS_WITH_STOP.forEach(eventSourceName => {
|
|
2617
|
+
const eventName = eventSourceName.toLowerCase();
|
|
2618
|
+
NDElement.prototype['onStop'+eventSourceName] = function(callback = null) {
|
|
2619
|
+
_stop(this.$element, eventName, callback);
|
|
2620
|
+
return this;
|
|
2621
|
+
};
|
|
2622
|
+
NDElement.prototype['onPreventStop'+eventSourceName] = function(callback = null) {
|
|
2623
|
+
_preventStop(this.$element, eventName, callback);
|
|
2624
|
+
return this;
|
|
2625
|
+
};
|
|
2626
|
+
});
|
|
3251
2627
|
|
|
3252
|
-
|
|
2628
|
+
EVENTS_WITH_PREVENT.forEach(eventSourceName => {
|
|
2629
|
+
const eventName = eventSourceName.toLowerCase();
|
|
2630
|
+
NDElement.prototype['onPrevent'+eventSourceName] = function(callback = null) {
|
|
2631
|
+
_prevent(this.$element, eventName, callback);
|
|
2632
|
+
return this;
|
|
2633
|
+
};
|
|
2634
|
+
});
|
|
3253
2635
|
|
|
3254
|
-
|
|
3255
|
-
|
|
2636
|
+
NDElement.prototype.on = function(name, callback, options) {
|
|
2637
|
+
this.$element.addEventListener(name.toLowerCase(), callback, options);
|
|
2638
|
+
return this;
|
|
2639
|
+
};
|
|
3256
2640
|
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
const item = $stores.get(name);
|
|
3262
|
-
if (!item) {
|
|
3263
|
-
DebugManager$1.error('Store', `Store.${method}('${name}') : store not found. Did you call Store.create('${name}') first?`);
|
|
3264
|
-
throw new NativeDocumentError(
|
|
3265
|
-
`Store.${method}('${name}') : store not found.`
|
|
3266
|
-
);
|
|
3267
|
-
}
|
|
3268
|
-
return item;
|
|
2641
|
+
const _prevent = function(element, eventName, callback) {
|
|
2642
|
+
const handler = (event) => {
|
|
2643
|
+
event.preventDefault();
|
|
2644
|
+
callback && callback.call(element, event);
|
|
3269
2645
|
};
|
|
2646
|
+
element.addEventListener(eventName, handler);
|
|
2647
|
+
return this;
|
|
2648
|
+
};
|
|
3270
2649
|
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
const readOnlyError = (method) => () => {
|
|
3276
|
-
DebugManager$1.error('Store', `Store.${context}('${name}') is read-only. '${method}()' is not allowed.`);
|
|
3277
|
-
throw new NativeDocumentError(
|
|
3278
|
-
`Store.${context}('${name}') is read-only.`
|
|
3279
|
-
);
|
|
3280
|
-
};
|
|
3281
|
-
observer.set = readOnlyError('set');
|
|
3282
|
-
observer.toggle = readOnlyError('toggle');
|
|
3283
|
-
observer.reset = readOnlyError('reset');
|
|
2650
|
+
const _stop = function(element, eventName, callback) {
|
|
2651
|
+
const handler = (event) => {
|
|
2652
|
+
event.stopPropagation();
|
|
2653
|
+
callback && callback.call(element, event);
|
|
3284
2654
|
};
|
|
2655
|
+
element.addEventListener(eventName, handler);
|
|
2656
|
+
return this;
|
|
2657
|
+
};
|
|
3285
2658
|
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
return Observable.object(value, options);
|
|
3292
|
-
}
|
|
3293
|
-
return Observable(value, options);
|
|
2659
|
+
const _preventStop = function(element, eventName, callback) {
|
|
2660
|
+
const handler = (event) => {
|
|
2661
|
+
event.stopPropagation();
|
|
2662
|
+
event.preventDefault();
|
|
2663
|
+
callback && callback.call(element, event);
|
|
3294
2664
|
};
|
|
2665
|
+
element.addEventListener(eventName, handler);
|
|
2666
|
+
return this;
|
|
2667
|
+
};
|
|
3295
2668
|
|
|
3296
|
-
const $api = {
|
|
3297
|
-
/**
|
|
3298
|
-
* Create a new state and return the observer.
|
|
3299
|
-
* Throws if a store with the same name already exists.
|
|
3300
|
-
*
|
|
3301
|
-
* @param {string} name
|
|
3302
|
-
* @param {*} value
|
|
3303
|
-
* @returns {ObservableItem}
|
|
3304
|
-
*/
|
|
3305
|
-
create(name, value) {
|
|
3306
|
-
if ($stores.has(name)) {
|
|
3307
|
-
DebugManager$1.warn('Store', `Store.create('${name}') : a store with this name already exists. Use Store.get('${name}') to retrieve it.`);
|
|
3308
|
-
throw new NativeDocumentError(
|
|
3309
|
-
`Store.create('${name}') : a store with this name already exists.`
|
|
3310
|
-
);
|
|
3311
|
-
}
|
|
3312
|
-
const observer = $createObservable(value);
|
|
3313
|
-
$stores.set(name, { observer, subscribers: new Set(), resettable: false, composed: false });
|
|
3314
|
-
return observer;
|
|
3315
|
-
},
|
|
3316
|
-
|
|
3317
|
-
/**
|
|
3318
|
-
* Create a new resettable state and return the observer.
|
|
3319
|
-
* The store can be reset to its initial value via Store.reset(name).
|
|
3320
|
-
* Throws if a store with the same name already exists.
|
|
3321
|
-
*
|
|
3322
|
-
* @param {string} name
|
|
3323
|
-
* @param {*} value
|
|
3324
|
-
* @returns {ObservableItem}
|
|
3325
|
-
*/
|
|
3326
|
-
createResettable(name, value) {
|
|
3327
|
-
if ($stores.has(name)) {
|
|
3328
|
-
DebugManager$1.warn('Store', `Store.createResettable('${name}') : a store with this name already exists.`);
|
|
3329
|
-
throw new NativeDocumentError(
|
|
3330
|
-
`Store.createResettable('${name}') : a store with this name already exists.`
|
|
3331
|
-
);
|
|
3332
|
-
}
|
|
3333
|
-
const observer = $createObservable(value, { reset: true });
|
|
3334
|
-
$stores.set(name, { observer, subscribers: new Set(), resettable: true, composed: false });
|
|
3335
|
-
return observer;
|
|
3336
|
-
},
|
|
3337
2669
|
|
|
3338
|
-
/**
|
|
3339
|
-
* Create a computed store derived from other stores.
|
|
3340
|
-
* The value is automatically recalculated when any dependency changes.
|
|
3341
|
-
* This store is read-only — Store.use() and Store.set() will throw.
|
|
3342
|
-
* Throws if a store with the same name already exists.
|
|
3343
|
-
*
|
|
3344
|
-
* @param {string} name
|
|
3345
|
-
* @param {() => *} computation - Function that returns the computed value
|
|
3346
|
-
* @param {string[]} dependencies - Names of the stores to watch
|
|
3347
|
-
* @returns {ObservableItem}
|
|
3348
|
-
*
|
|
3349
|
-
* @example
|
|
3350
|
-
* Store.create('products', [{ id: 1, price: 10 }]);
|
|
3351
|
-
* Store.create('cart', [{ productId: 1, quantity: 2 }]);
|
|
3352
|
-
*
|
|
3353
|
-
* Store.createComposed('total', () => {
|
|
3354
|
-
* const products = Store.get('products').val();
|
|
3355
|
-
* const cart = Store.get('cart').val();
|
|
3356
|
-
* return cart.reduce((sum, item) => {
|
|
3357
|
-
* const product = products.find(p => p.id === item.productId);
|
|
3358
|
-
* return sum + (product.price * item.quantity);
|
|
3359
|
-
* }, 0);
|
|
3360
|
-
* }, ['products', 'cart']);
|
|
3361
|
-
*/
|
|
3362
|
-
createComposed(name, computation, dependencies) {
|
|
3363
|
-
if ($stores.has(name)) {
|
|
3364
|
-
DebugManager$1.warn('Store', `Store.createComposed('${name}') : a store with this name already exists.`);
|
|
3365
|
-
throw new NativeDocumentError(
|
|
3366
|
-
`Store.createComposed('${name}') : a store with this name already exists.`
|
|
3367
|
-
);
|
|
3368
|
-
}
|
|
3369
|
-
if (typeof computation !== 'function') {
|
|
3370
|
-
throw new NativeDocumentError(
|
|
3371
|
-
`Store.createComposed('${name}') : computation must be a function.`
|
|
3372
|
-
);
|
|
3373
|
-
}
|
|
3374
|
-
if (!Array.isArray(dependencies) || dependencies.length === 0) {
|
|
3375
|
-
throw new NativeDocumentError(
|
|
3376
|
-
`Store.createComposed('${name}') : dependencies must be a non-empty array of store names.`
|
|
3377
|
-
);
|
|
3378
|
-
}
|
|
3379
2670
|
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
if (!depItem) {
|
|
3387
|
-
DebugManager$1.error('Store', `Store.createComposed('${name}') : dependency '${depName}' not found. Create it first.`);
|
|
3388
|
-
throw new NativeDocumentError(
|
|
3389
|
-
`Store.createComposed('${name}') : dependency store '${depName}' not found.`
|
|
3390
|
-
);
|
|
3391
|
-
}
|
|
3392
|
-
return depItem.observer;
|
|
3393
|
-
});
|
|
3394
|
-
|
|
3395
|
-
// Create computed observable from dependency observers
|
|
3396
|
-
const observer = Observable.computed(computation, depObservers);
|
|
3397
|
-
|
|
3398
|
-
$stores.set(name, { observer, subscribers: new Set(), resettable: false, composed: true });
|
|
3399
|
-
return observer;
|
|
3400
|
-
},
|
|
3401
|
-
|
|
3402
|
-
/**
|
|
3403
|
-
* Returns true if a store with the given name exists.
|
|
3404
|
-
*
|
|
3405
|
-
* @param {string} name
|
|
3406
|
-
* @returns {boolean}
|
|
3407
|
-
*/
|
|
3408
|
-
has(name) {
|
|
3409
|
-
return $stores.has(name);
|
|
3410
|
-
},
|
|
3411
|
-
|
|
3412
|
-
/**
|
|
3413
|
-
* Resets a resettable store to its initial value and notifies all subscribers.
|
|
3414
|
-
* Throws if the store was not created with createResettable().
|
|
3415
|
-
*
|
|
3416
|
-
* @param {string} name
|
|
3417
|
-
*/
|
|
3418
|
-
reset(name) {
|
|
3419
|
-
const item = $getStoreOrThrow('reset', name);
|
|
3420
|
-
if (item.composed) {
|
|
3421
|
-
DebugManager$1.error('Store', `Store.reset('${name}') : composed stores cannot be reset. Their value is derived from dependencies.`);
|
|
3422
|
-
throw new NativeDocumentError(
|
|
3423
|
-
`Store.reset('${name}') : composed stores cannot be reset.`
|
|
3424
|
-
);
|
|
3425
|
-
}
|
|
3426
|
-
if (!item.resettable) {
|
|
3427
|
-
DebugManager$1.error('Store', `Store.reset('${name}') : this store is not resettable. Use Store.createResettable('${name}', value) instead of Store.create().`);
|
|
3428
|
-
throw new NativeDocumentError(
|
|
3429
|
-
`Store.reset('${name}') : this store is not resettable. Use Store.createResettable('${name}', value) instead of Store.create().`
|
|
3430
|
-
);
|
|
3431
|
-
}
|
|
3432
|
-
item.observer.reset();
|
|
3433
|
-
},
|
|
3434
|
-
|
|
3435
|
-
/**
|
|
3436
|
-
* Returns a two-way synchronized follower of the store.
|
|
3437
|
-
* Writing to the follower propagates the value back to the store and all its subscribers.
|
|
3438
|
-
* Throws if called on a composed store — use Store.follow() instead.
|
|
3439
|
-
* Call follower.destroy() or follower.dispose() to unsubscribe.
|
|
3440
|
-
*
|
|
3441
|
-
* @param {string} name
|
|
3442
|
-
* @returns {ObservableItem}
|
|
3443
|
-
*/
|
|
3444
|
-
use(name) {
|
|
3445
|
-
const item = $getStoreOrThrow('use', name);
|
|
3446
|
-
|
|
3447
|
-
if (item.composed) {
|
|
3448
|
-
DebugManager$1.error('Store', `Store.use('${name}') : composed stores are read-only. Use Store.follow('${name}') instead.`);
|
|
3449
|
-
throw new NativeDocumentError(
|
|
3450
|
-
`Store.use('${name}') : composed stores are read-only. Use Store.follow('${name}') instead.`
|
|
3451
|
-
);
|
|
3452
|
-
}
|
|
3453
|
-
|
|
3454
|
-
const { observer: originalObserver, subscribers } = item;
|
|
3455
|
-
const observerFollower = $createObservable(originalObserver.val());
|
|
3456
|
-
|
|
3457
|
-
const onStoreChange = value => observerFollower.set(value);
|
|
3458
|
-
const onFollowerChange = value => originalObserver.set(value);
|
|
3459
|
-
|
|
3460
|
-
originalObserver.subscribe(onStoreChange);
|
|
3461
|
-
observerFollower.subscribe(onFollowerChange);
|
|
3462
|
-
|
|
3463
|
-
observerFollower.destroy = () => {
|
|
3464
|
-
originalObserver.unsubscribe(onStoreChange);
|
|
3465
|
-
observerFollower.unsubscribe(onFollowerChange);
|
|
3466
|
-
subscribers.delete(observerFollower);
|
|
3467
|
-
observerFollower.cleanup();
|
|
3468
|
-
};
|
|
3469
|
-
observerFollower.dispose = observerFollower.destroy;
|
|
3470
|
-
|
|
3471
|
-
subscribers.add(observerFollower);
|
|
3472
|
-
return observerFollower;
|
|
3473
|
-
},
|
|
3474
|
-
|
|
3475
|
-
/**
|
|
3476
|
-
* Returns a read-only follower of the store.
|
|
3477
|
-
* The follower reflects store changes but cannot write back to the store.
|
|
3478
|
-
* Any attempt to call .set(), .toggle() or .reset() will throw.
|
|
3479
|
-
* Call follower.destroy() or follower.dispose() to unsubscribe.
|
|
3480
|
-
*
|
|
3481
|
-
* @param {string} name
|
|
3482
|
-
* @returns {ObservableItem}
|
|
3483
|
-
*/
|
|
3484
|
-
follow(name) {
|
|
3485
|
-
const { observer: originalObserver, subscribers } = $getStoreOrThrow('follow', name);
|
|
3486
|
-
const observerFollower = $createObservable(originalObserver.val());
|
|
3487
|
-
|
|
3488
|
-
const onStoreChange = value => observerFollower.set(value);
|
|
3489
|
-
originalObserver.subscribe(onStoreChange);
|
|
3490
|
-
|
|
3491
|
-
$applyReadOnly(observerFollower, name, 'follow');
|
|
3492
|
-
|
|
3493
|
-
observerFollower.destroy = () => {
|
|
3494
|
-
originalObserver.unsubscribe(onStoreChange);
|
|
3495
|
-
subscribers.delete(observerFollower);
|
|
3496
|
-
observerFollower.cleanup();
|
|
3497
|
-
};
|
|
3498
|
-
observerFollower.dispose = observerFollower.destroy;
|
|
3499
|
-
|
|
3500
|
-
subscribers.add(observerFollower);
|
|
3501
|
-
return observerFollower;
|
|
3502
|
-
},
|
|
3503
|
-
|
|
3504
|
-
/**
|
|
3505
|
-
* Returns the raw store observer directly (no follower, no cleanup contract).
|
|
3506
|
-
* Use this for direct read access when you don't need to unsubscribe.
|
|
3507
|
-
* WARNING : mutations on this observer impact all subscribers immediately.
|
|
3508
|
-
*
|
|
3509
|
-
* @param {string} name
|
|
3510
|
-
* @returns {ObservableItem|null}
|
|
3511
|
-
*/
|
|
3512
|
-
get(name) {
|
|
3513
|
-
const item = $stores.get(name);
|
|
3514
|
-
if (!item) {
|
|
3515
|
-
DebugManager$1.warn('Store', `Store.get('${name}') : store not found.`);
|
|
3516
|
-
return null;
|
|
3517
|
-
}
|
|
3518
|
-
return item.observer;
|
|
3519
|
-
},
|
|
3520
|
-
|
|
3521
|
-
/**
|
|
3522
|
-
* @param {string} name
|
|
3523
|
-
* @returns {{ observer: ObservableItem, subscribers: Set } | null}
|
|
3524
|
-
*/
|
|
3525
|
-
getWithSubscribers(name) {
|
|
3526
|
-
return $stores.get(name) ?? null;
|
|
3527
|
-
},
|
|
3528
|
-
|
|
3529
|
-
/**
|
|
3530
|
-
* Destroys a store : cleans up the observer, destroys all followers, and removes the entry.
|
|
3531
|
-
*
|
|
3532
|
-
* @param {string} name
|
|
3533
|
-
*/
|
|
3534
|
-
delete(name) {
|
|
3535
|
-
const item = $stores.get(name);
|
|
3536
|
-
if (!item) {
|
|
3537
|
-
DebugManager$1.warn('Store', `Store.delete('${name}') : store not found, nothing to delete.`);
|
|
3538
|
-
return;
|
|
3539
|
-
}
|
|
3540
|
-
item.subscribers.forEach(follower => follower.destroy());
|
|
3541
|
-
item.subscribers.clear();
|
|
3542
|
-
item.observer.cleanup();
|
|
3543
|
-
$stores.delete(name);
|
|
3544
|
-
},
|
|
3545
|
-
/**
|
|
3546
|
-
* Creates an isolated store group with its own state namespace.
|
|
3547
|
-
* Each group is a fully independent StoreFactory instance —
|
|
3548
|
-
* no key conflicts, no shared state with the parent store.
|
|
3549
|
-
*
|
|
3550
|
-
* @param {string | ((group: ReturnType<typeof StoreFactory>) => void)} name - Group name for debugging, or setup callback if no name is provided
|
|
3551
|
-
* @param {((group: ReturnType<typeof StoreFactory>) => void)} [callback] - Setup function receiving the isolated store instance
|
|
3552
|
-
* @returns {ReturnType<typeof StoreFactory>}
|
|
3553
|
-
*
|
|
3554
|
-
* @example
|
|
3555
|
-
* // With name (recommended)
|
|
3556
|
-
* const EventStore = Store.group('events', (group) => {
|
|
3557
|
-
* group.create('catalog', []);
|
|
3558
|
-
* group.create('filters', { category: null, date: null });
|
|
3559
|
-
* group.createResettable('selected', null);
|
|
3560
|
-
* group.createComposed('filtered', () => {
|
|
3561
|
-
* const catalog = EventStore.get('catalog').val();
|
|
3562
|
-
* const filters = EventStore.get('filters').val();
|
|
3563
|
-
* return catalog.filter(event => {
|
|
3564
|
-
* if (filters.category && event.category !== filters.category) return false;
|
|
3565
|
-
* return true;
|
|
3566
|
-
* });
|
|
3567
|
-
* }, ['catalog', 'filters']);
|
|
3568
|
-
* });
|
|
3569
|
-
*
|
|
3570
|
-
* // Without name
|
|
3571
|
-
* const CartStore = Store.group((group) => {
|
|
3572
|
-
* group.create('items', []);
|
|
3573
|
-
* });
|
|
3574
|
-
*
|
|
3575
|
-
* // Usage
|
|
3576
|
-
* EventStore.use('catalog'); // two-way follower
|
|
3577
|
-
* EventStore.follow('filtered'); // read-only follower
|
|
3578
|
-
* EventStore.get('filters'); // raw observable
|
|
3579
|
-
*
|
|
3580
|
-
* // Cross-group composed
|
|
3581
|
-
* const OrderStore = Store.group('orders', (group) => {
|
|
3582
|
-
* group.createComposed('summary', () => {
|
|
3583
|
-
* const items = CartStore.get('items').val();
|
|
3584
|
-
* const events = EventStore.get('catalog').val();
|
|
3585
|
-
* return { items, events };
|
|
3586
|
-
* }, [CartStore.get('items'), EventStore.get('catalog')]);
|
|
3587
|
-
* });
|
|
3588
|
-
*/
|
|
3589
|
-
group(name, callback) {
|
|
3590
|
-
if (typeof name === 'function') {
|
|
3591
|
-
callback = name;
|
|
3592
|
-
name = 'anonymous';
|
|
3593
|
-
}
|
|
3594
|
-
const store = StoreFactory();
|
|
3595
|
-
callback && callback(store);
|
|
3596
|
-
return store;
|
|
3597
|
-
},
|
|
3598
|
-
createPersistent(name, value, localstorage_key) {
|
|
3599
|
-
localstorage_key = localstorage_key || name;
|
|
3600
|
-
const observer = this.create(name, $getFromStorage(localstorage_key, value));
|
|
3601
|
-
const saver = $saveToStorage(value);
|
|
3602
|
-
|
|
3603
|
-
observer.subscribe((val) => saver(localstorage_key, val));
|
|
3604
|
-
return observer;
|
|
3605
|
-
},
|
|
3606
|
-
createPersistentResettable(name, value, localstorage_key) {
|
|
3607
|
-
localstorage_key = localstorage_key || name;
|
|
3608
|
-
const observer = this.createResettable(name, $getFromStorage(localstorage_key, value));
|
|
3609
|
-
const saver = $saveToStorage(value);
|
|
3610
|
-
observer.subscribe((val) => saver(localstorage_key, val));
|
|
3611
|
-
|
|
3612
|
-
const originalReset = observer.reset.bind(observer);
|
|
3613
|
-
observer.reset = () => {
|
|
3614
|
-
LocalStorage.remove(localstorage_key);
|
|
3615
|
-
originalReset();
|
|
3616
|
-
};
|
|
3617
|
-
|
|
3618
|
-
return observer;
|
|
3619
|
-
}
|
|
3620
|
-
};
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
return new Proxy($api, {
|
|
3624
|
-
get(target, prop) {
|
|
3625
|
-
if (typeof prop === 'symbol' || prop.startsWith('$') || prop in target) {
|
|
3626
|
-
return target[prop];
|
|
3627
|
-
}
|
|
3628
|
-
if (target.has(prop)) {
|
|
3629
|
-
if ($followersCache.has(prop)) {
|
|
3630
|
-
return $followersCache.get(prop);
|
|
3631
|
-
}
|
|
3632
|
-
const follower = target.follow(prop);
|
|
3633
|
-
$followersCache.set(prop, follower);
|
|
3634
|
-
return follower;
|
|
3635
|
-
}
|
|
3636
|
-
return undefined;
|
|
3637
|
-
},
|
|
3638
|
-
set(target, prop, value) {
|
|
3639
|
-
DebugManager$1.error('Store', `Forbidden: You cannot overwrite the store key '${String(prop)}'. Use .use('${String(prop)}').set(value) instead.`);
|
|
3640
|
-
throw new NativeDocumentError(`Store structure is immutable. Use .set() on the observable.`);
|
|
3641
|
-
},
|
|
3642
|
-
deleteProperty(target, prop) {
|
|
3643
|
-
throw new NativeDocumentError(`Store keys cannot be deleted.`);
|
|
3644
|
-
}
|
|
3645
|
-
});
|
|
3646
|
-
};
|
|
3647
|
-
|
|
3648
|
-
const Store = StoreFactory();
|
|
3649
|
-
|
|
3650
|
-
Store.create('locale', navigator.language.split('-')[0] || 'en');
|
|
3651
|
-
|
|
3652
|
-
function oneChildAnchorOverwriting(anchor, parent) {
|
|
3653
|
-
|
|
3654
|
-
anchor.remove = () => {
|
|
3655
|
-
anchor.append.apply(anchor, parent.childNodes);
|
|
3656
|
-
};
|
|
3657
|
-
anchor.getParent = () => parent;
|
|
3658
|
-
|
|
3659
|
-
anchor.appendChild = (child) => {
|
|
3660
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3661
|
-
parent.appendChild(child);
|
|
3662
|
-
};
|
|
3663
|
-
|
|
3664
|
-
anchor.appendChildRaw = parent.appendChild.bind(parent);
|
|
3665
|
-
anchor.append = anchor.appendChild;
|
|
3666
|
-
anchor.appendRaw = anchor.appendChildRaw;
|
|
3667
|
-
|
|
3668
|
-
anchor.insertAtStart = (child) => {
|
|
3669
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3670
|
-
parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
|
|
3671
|
-
};
|
|
3672
|
-
anchor.insertAtStartRaw = (child) => {
|
|
3673
|
-
parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
|
|
3674
|
-
};
|
|
3675
|
-
|
|
3676
|
-
anchor.appendElement = anchor.appendChild;
|
|
3677
|
-
|
|
3678
|
-
anchor.removeChildren = () => {
|
|
3679
|
-
parent.textContent = '';
|
|
3680
|
-
};
|
|
3681
|
-
|
|
3682
|
-
anchor.replaceContent = function(content) {
|
|
3683
|
-
const child = Validator.isElement(content) ? content : ElementCreator.getChild(content);
|
|
3684
|
-
parent.replaceChildren(child);
|
|
3685
|
-
};
|
|
3686
|
-
|
|
3687
|
-
anchor.replaceContentRaw = function(child) {
|
|
3688
|
-
parent.replaceChildren(child);
|
|
3689
|
-
};
|
|
3690
|
-
anchor.setContent = anchor.replaceContent;
|
|
3691
|
-
|
|
3692
|
-
anchor.insertBefore = (child, anchor) => {
|
|
3693
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3694
|
-
parent.insertBefore(child, anchor);
|
|
3695
|
-
};
|
|
3696
|
-
anchor.insertBeforeRaw = (child, anchor) => {
|
|
3697
|
-
parent.insertBefore(child, anchor);
|
|
3698
|
-
};
|
|
3699
|
-
|
|
3700
|
-
anchor.appendChildBefore = anchor.insertBefore;
|
|
3701
|
-
anchor.appendChildBeforeRaw = anchor.insertBeforeRaw;
|
|
3702
|
-
|
|
3703
|
-
anchor.clear = anchor.remove;
|
|
3704
|
-
anchor.detach = anchor.remove;
|
|
3705
|
-
|
|
3706
|
-
anchor.replaceChildren = function() {
|
|
3707
|
-
parent.replaceChildren(...arguments);
|
|
3708
|
-
};
|
|
3709
|
-
|
|
3710
|
-
anchor.getByIndex = (index) => {
|
|
3711
|
-
return parent.childNodes[index];
|
|
3712
|
-
};
|
|
3713
|
-
}
|
|
3714
|
-
|
|
3715
|
-
function Anchor(name, isUniqueChild = false) {
|
|
3716
|
-
const anchorFragment = new AnchorWithSentinel(name);
|
|
3717
|
-
|
|
3718
|
-
anchorFragment.onConnectedOnce((parent) => {
|
|
3719
|
-
if(isUniqueChild) {
|
|
3720
|
-
oneChildAnchorOverwriting(anchorFragment, parent);
|
|
3721
|
-
}
|
|
3722
|
-
});
|
|
3723
|
-
|
|
3724
|
-
anchorFragment.__Anchor__ = true;
|
|
3725
|
-
|
|
3726
|
-
const anchorStart = anchorFragment.$start;
|
|
3727
|
-
const anchorEnd = anchorFragment.$end;
|
|
3728
|
-
|
|
3729
|
-
anchorFragment.nativeInsertBefore = anchorFragment.insertBefore;
|
|
3730
|
-
anchorFragment.nativeAppendChild = anchorFragment.appendChild;
|
|
3731
|
-
anchorFragment.nativeAppend = anchorFragment.append;
|
|
3732
|
-
|
|
3733
|
-
const isParentUniqueChild = isUniqueChild
|
|
3734
|
-
? () => true: (parent) => (parent.firstChild === anchorStart && parent.lastChild === anchorEnd);
|
|
3735
|
-
|
|
3736
|
-
const insertBefore = (parent, child, target) => {
|
|
3737
|
-
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3738
|
-
insertBeforeRaw(parent, childElement, target);
|
|
3739
|
-
};
|
|
3740
|
-
|
|
3741
|
-
const insertBeforeRaw = (parent, child, target) => {
|
|
3742
|
-
if(parent === anchorFragment) {
|
|
3743
|
-
parent.nativeInsertBefore(child, target);
|
|
3744
|
-
return;
|
|
3745
|
-
}
|
|
3746
|
-
if(isParentUniqueChild(parent) && target === anchorEnd) {
|
|
3747
|
-
parent.append(child, target);
|
|
3748
|
-
return;
|
|
3749
|
-
}
|
|
3750
|
-
parent.insertBefore(child, target);
|
|
3751
|
-
};
|
|
3752
|
-
|
|
3753
|
-
anchorFragment.appendElement = function(child) {
|
|
3754
|
-
const parentNode = anchorStart.parentNode;
|
|
3755
|
-
if(parentNode === anchorFragment) {
|
|
3756
|
-
parentNode.nativeInsertBefore(child, anchorEnd);
|
|
3757
|
-
return;
|
|
3758
|
-
}
|
|
3759
|
-
parentNode.insertBefore(child, anchorEnd);
|
|
3760
|
-
};
|
|
3761
|
-
|
|
3762
|
-
anchorFragment.appendChild = function(child, before = null) {
|
|
3763
|
-
const parent = anchorEnd.parentNode;
|
|
3764
|
-
if(!parent) {
|
|
3765
|
-
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
3766
|
-
return;
|
|
3767
|
-
}
|
|
3768
|
-
before = before ?? anchorEnd;
|
|
3769
|
-
insertBefore(parent, child, before);
|
|
3770
|
-
};
|
|
3771
|
-
|
|
3772
|
-
anchorFragment.appendChildRaw = function(child, before = null) {
|
|
3773
|
-
const parent = anchorEnd.parentNode;
|
|
3774
|
-
if(!parent) {
|
|
3775
|
-
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
3776
|
-
return;
|
|
3777
|
-
}
|
|
3778
|
-
before = before ?? anchorEnd;
|
|
3779
|
-
insertBeforeRaw(parent, child, before);
|
|
3780
|
-
};
|
|
3781
|
-
|
|
3782
|
-
anchorFragment.getParent = () => anchorEnd.parentNode;
|
|
3783
|
-
anchorFragment.append = anchorFragment.appendChild;
|
|
3784
|
-
anchorFragment.appendRaw = anchorFragment.appendChildRaw;
|
|
3785
|
-
|
|
3786
|
-
anchorFragment.insertAtStart = function(child) {
|
|
3787
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3788
|
-
anchorFragment.insertAtStartRaw(child);
|
|
3789
|
-
};
|
|
3790
|
-
|
|
3791
|
-
anchorFragment.insertAtStartRaw = function(child) {
|
|
3792
|
-
const parentNode = anchorStart.parentNode;
|
|
3793
|
-
if(parentNode === anchorFragment) {
|
|
3794
|
-
parentNode.nativeInsertBefore(child, anchorStart);
|
|
3795
|
-
return;
|
|
3796
|
-
}
|
|
3797
|
-
parentNode.insertBefore(child, anchorStart);
|
|
3798
|
-
};
|
|
3799
|
-
|
|
3800
|
-
anchorFragment.removeChildren = function() {
|
|
3801
|
-
const parent = anchorEnd.parentNode;
|
|
3802
|
-
if(parent === anchorFragment) {
|
|
3803
|
-
return;
|
|
3804
|
-
}
|
|
3805
|
-
if(isParentUniqueChild(parent)) {
|
|
3806
|
-
parent.replaceChildren(anchorStart, anchorEnd);
|
|
3807
|
-
return;
|
|
3808
|
-
}
|
|
3809
|
-
|
|
3810
|
-
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
3811
|
-
while(itemToRemove && itemToRemove !== anchorEnd) {
|
|
3812
|
-
tempItem = itemToRemove.nextSibling;
|
|
3813
|
-
itemToRemove.remove();
|
|
3814
|
-
itemToRemove = tempItem;
|
|
3815
|
-
}
|
|
3816
|
-
};
|
|
3817
|
-
|
|
3818
|
-
anchorFragment.remove = function() {
|
|
3819
|
-
const parent = anchorEnd.parentNode;
|
|
3820
|
-
if(parent === anchorFragment) {
|
|
3821
|
-
return;
|
|
3822
|
-
}
|
|
3823
|
-
if(isParentUniqueChild(parent)) {
|
|
3824
|
-
anchorFragment.nativeAppend.apply(anchorFragment, parent.childNodes);
|
|
3825
|
-
parent.replaceChildren(anchorStart, anchorEnd);
|
|
3826
|
-
return;
|
|
3827
|
-
}
|
|
3828
|
-
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
3829
|
-
while(itemToRemove && itemToRemove !== anchorEnd) {
|
|
3830
|
-
tempItem = itemToRemove.nextSibling;
|
|
3831
|
-
anchorFragment.nativeAppend(itemToRemove);
|
|
3832
|
-
itemToRemove = tempItem;
|
|
3833
|
-
}
|
|
3834
|
-
};
|
|
3835
|
-
|
|
3836
|
-
anchorFragment.removeWithAnchors = function() {
|
|
3837
|
-
anchorFragment.removeChildren();
|
|
3838
|
-
anchorStart.remove();
|
|
3839
|
-
anchorEnd.remove();
|
|
3840
|
-
};
|
|
3841
|
-
anchorFragment.delete = anchorFragment.removeWithAnchors;
|
|
3842
|
-
|
|
3843
|
-
anchorFragment.replaceContent = function(child) {
|
|
3844
|
-
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3845
|
-
anchorFragment.replaceContentRaw(childElement);
|
|
3846
|
-
};
|
|
3847
|
-
|
|
3848
|
-
anchorFragment.replaceContentRaw = function(child) {
|
|
3849
|
-
const parent = anchorEnd.parentNode;
|
|
3850
|
-
if(!parent) {
|
|
3851
|
-
return;
|
|
3852
|
-
}
|
|
3853
|
-
if(isParentUniqueChild(parent)) {
|
|
3854
|
-
parent.replaceChildren(anchorStart, child, anchorEnd);
|
|
3855
|
-
return;
|
|
3856
|
-
}
|
|
3857
|
-
anchorFragment.removeChildren();
|
|
3858
|
-
parent.insertBefore(child, anchorEnd);
|
|
3859
|
-
};
|
|
3860
|
-
|
|
3861
|
-
anchorFragment.setContent = anchorFragment.replaceContent;
|
|
3862
|
-
anchorFragment.setContentRaw = anchorFragment.replaceContentRaw;
|
|
3863
|
-
|
|
3864
|
-
anchorFragment.insertBefore = anchorFragment.appendChild;
|
|
3865
|
-
anchorFragment.insertBeforeRaw = anchorFragment.appendChildRaw;
|
|
3866
|
-
|
|
3867
|
-
anchorFragment.endElement = function() {
|
|
3868
|
-
return anchorEnd;
|
|
3869
|
-
};
|
|
3870
|
-
|
|
3871
|
-
anchorFragment.startElement = function() {
|
|
3872
|
-
return anchorStart;
|
|
3873
|
-
};
|
|
3874
|
-
|
|
3875
|
-
anchorFragment.restore = function() {
|
|
3876
|
-
anchorFragment.appendChild(anchorFragment);
|
|
3877
|
-
};
|
|
3878
|
-
|
|
3879
|
-
anchorFragment.clear = anchorFragment.remove;
|
|
3880
|
-
anchorFragment.detach = anchorFragment.remove;
|
|
3881
|
-
|
|
3882
|
-
anchorFragment.getByIndex = function(index) {
|
|
3883
|
-
let currentNode = anchorStart;
|
|
3884
|
-
for(let i = 0; i <= index; i++) {
|
|
3885
|
-
if(!currentNode.nextSibling) {
|
|
3886
|
-
return null;
|
|
3887
|
-
}
|
|
3888
|
-
currentNode = currentNode.nextSibling;
|
|
3889
|
-
}
|
|
3890
|
-
return currentNode !== anchorStart ? currentNode : null;
|
|
3891
|
-
};
|
|
3892
|
-
|
|
3893
|
-
return anchorFragment;
|
|
3894
|
-
}
|
|
3895
|
-
DocumentFragment.prototype.setAttribute = () => {};
|
|
3896
|
-
|
|
3897
|
-
function NDElement(element) {
|
|
3898
|
-
this.$element = element;
|
|
3899
|
-
this.$attachements = null;
|
|
3900
|
-
}
|
|
3901
|
-
|
|
3902
|
-
NDElement.prototype.__$isNDElement = true;
|
|
3903
|
-
|
|
3904
|
-
NDElement.prototype.ghostDom = function(element) {
|
|
3905
|
-
if(!this.$attachements) {
|
|
3906
|
-
this.$attachements = document.createDocumentFragment();
|
|
3907
|
-
}
|
|
3908
|
-
this.$attachements.appendChild(ElementCreator.getChild(element));
|
|
3909
|
-
return this;
|
|
3910
|
-
};
|
|
3911
|
-
|
|
3912
|
-
NDElement.prototype.valueOf = function() {
|
|
3913
|
-
return this.$element;
|
|
3914
|
-
};
|
|
3915
|
-
|
|
3916
|
-
NDElement.prototype.ref = function(target, name) {
|
|
3917
|
-
target[name] = this.$element;
|
|
3918
|
-
return this;
|
|
3919
|
-
};
|
|
3920
|
-
|
|
3921
|
-
NDElement.prototype.refSelf = function(target, name) {
|
|
3922
|
-
target[name] = this;
|
|
3923
|
-
// TODO: @DIM to check
|
|
3924
|
-
// target[name] = new NDElement(this.$element);
|
|
3925
|
-
return this;
|
|
3926
|
-
};
|
|
3927
|
-
|
|
3928
|
-
NDElement.prototype.unmountChildren = function() {
|
|
3929
|
-
let element = this.$element;
|
|
3930
|
-
for(let i = 0, length = element.children.length; i < length; i++) {
|
|
3931
|
-
let elementChildren = element.children[i];
|
|
3932
|
-
if(!elementChildren.$ndProx) {
|
|
3933
|
-
elementChildren.nd?.remove();
|
|
3934
|
-
}
|
|
3935
|
-
elementChildren = null;
|
|
3936
|
-
}
|
|
3937
|
-
element = null;
|
|
3938
|
-
return this;
|
|
3939
|
-
};
|
|
3940
|
-
|
|
3941
|
-
NDElement.prototype.remove = function() {
|
|
3942
|
-
let element = this.$element;
|
|
3943
|
-
element.nd.unmountChildren();
|
|
3944
|
-
element.$ndProx = null;
|
|
3945
|
-
|
|
3946
|
-
$lifeCycleObservers.delete(element);
|
|
3947
|
-
|
|
3948
|
-
element = null;
|
|
3949
|
-
return this;
|
|
3950
|
-
};
|
|
3951
|
-
|
|
3952
|
-
const $lifeCycleObservers = new WeakMap();
|
|
3953
|
-
NDElement.prototype.lifecycle = function(states) {
|
|
3954
|
-
const el = this.$element;
|
|
3955
|
-
if (!$lifeCycleObservers.has(el)) {
|
|
3956
|
-
$lifeCycleObservers.set(el, DocumentObserver.watch(el));
|
|
3957
|
-
}
|
|
3958
|
-
const observer = $lifeCycleObservers.get(el);
|
|
3959
|
-
|
|
3960
|
-
if(states.mounted) {
|
|
3961
|
-
this.$element.setAttribute('data--nd-mounted', '1');
|
|
3962
|
-
observer.mounted(states.mounted);
|
|
3963
|
-
}
|
|
3964
|
-
if(states.unmounted) {
|
|
3965
|
-
this.$element.setAttribute('data--nd-unmounted', '1');
|
|
3966
|
-
observer.unmounted(states.unmounted);
|
|
3967
|
-
}
|
|
3968
|
-
return this;
|
|
3969
|
-
};
|
|
3970
|
-
|
|
3971
|
-
NDElement.prototype.mounted = function(callback) {
|
|
3972
|
-
return this.lifecycle({ mounted: callback });
|
|
3973
|
-
};
|
|
3974
|
-
|
|
3975
|
-
NDElement.prototype.unmounted = function(callback) {
|
|
3976
|
-
return this.lifecycle({ unmounted: callback });
|
|
3977
|
-
};
|
|
3978
|
-
|
|
3979
|
-
NDElement.prototype.beforeUnmount = function(id, callback) {
|
|
3980
|
-
const el = this.$element;
|
|
3981
|
-
|
|
3982
|
-
if(!DocumentObserver.beforeUnmount.has(el)) {
|
|
3983
|
-
DocumentObserver.beforeUnmount.set(el, new Map());
|
|
3984
|
-
const originalRemove = el.remove.bind(el);
|
|
3985
|
-
|
|
3986
|
-
let $isUnmounting = false;
|
|
3987
|
-
|
|
3988
|
-
el.remove = async () => {
|
|
3989
|
-
if($isUnmounting) {
|
|
3990
|
-
return;
|
|
3991
|
-
}
|
|
3992
|
-
$isUnmounting = true;
|
|
3993
|
-
|
|
3994
|
-
try {
|
|
3995
|
-
const callbacks = DocumentObserver.beforeUnmount.get(el);
|
|
3996
|
-
for (const cb of callbacks.values()) {
|
|
3997
|
-
await cb.call(this, el);
|
|
3998
|
-
}
|
|
3999
|
-
} finally {
|
|
4000
|
-
originalRemove();
|
|
4001
|
-
$isUnmounting = false;
|
|
4002
|
-
}
|
|
4003
|
-
};
|
|
4004
|
-
}
|
|
4005
|
-
|
|
4006
|
-
DocumentObserver.beforeUnmount.get(el).set(id, callback);
|
|
4007
|
-
return this;
|
|
4008
|
-
};
|
|
4009
|
-
|
|
4010
|
-
NDElement.prototype.htmlElement = function() {
|
|
4011
|
-
return this.$element;
|
|
4012
|
-
};
|
|
4013
|
-
|
|
4014
|
-
NDElement.prototype.node = NDElement.prototype.htmlElement;
|
|
4015
|
-
|
|
4016
|
-
NDElement.prototype.shadow = function(mode, style = null) {
|
|
4017
|
-
const $element = this.$element;
|
|
4018
|
-
const children = Array.from($element.childNodes);
|
|
4019
|
-
const shadowRoot = $element.attachShadow({ mode });
|
|
4020
|
-
if(style) {
|
|
4021
|
-
const styleNode = document.createElement("style");
|
|
4022
|
-
styleNode.textContent = style;
|
|
4023
|
-
shadowRoot.appendChild(styleNode);
|
|
4024
|
-
}
|
|
4025
|
-
$element.append = shadowRoot.append.bind(shadowRoot);
|
|
4026
|
-
$element.appendChild = shadowRoot.appendChild.bind(shadowRoot);
|
|
4027
|
-
shadowRoot.append(...children);
|
|
4028
|
-
|
|
4029
|
-
return this;
|
|
4030
|
-
};
|
|
4031
|
-
|
|
4032
|
-
NDElement.prototype.openShadow = function(style = null) {
|
|
4033
|
-
return this.shadow('open', style);
|
|
4034
|
-
};
|
|
4035
|
-
|
|
4036
|
-
NDElement.prototype.closedShadow = function(style = null) {
|
|
4037
|
-
return this.shadow('closed', style);
|
|
4038
|
-
};
|
|
4039
|
-
|
|
4040
|
-
/**
|
|
4041
|
-
* Extends the current NDElement instance with custom methods.
|
|
4042
|
-
* Methods are bound to the instance and available for chaining.
|
|
4043
|
-
*
|
|
4044
|
-
* @param {Object} methods - Object containing method definitions
|
|
4045
|
-
* @returns {this} The NDElement instance with added methods for chaining
|
|
4046
|
-
* @example
|
|
4047
|
-
* element.nd.with({
|
|
4048
|
-
* highlight() {
|
|
4049
|
-
* this.$element.style.background = 'yellow';
|
|
4050
|
-
* return this;
|
|
4051
|
-
* }
|
|
4052
|
-
* }).highlight().onClick(() => console.log('Clicked'));
|
|
4053
|
-
*/
|
|
4054
|
-
NDElement.prototype.with = function(methods) {
|
|
4055
|
-
if (!methods || typeof methods !== 'object') {
|
|
4056
|
-
throw new NativeDocumentError('extend() requires an object of methods');
|
|
4057
|
-
}
|
|
4058
|
-
|
|
4059
|
-
for (const name in methods) {
|
|
4060
|
-
const method = methods[name];
|
|
4061
|
-
|
|
4062
|
-
if (typeof method !== 'function') {
|
|
4063
|
-
DebugManager$1.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
|
|
4064
|
-
continue;
|
|
4065
|
-
}
|
|
4066
|
-
|
|
4067
|
-
this[name] = method.bind(this);
|
|
4068
|
-
}
|
|
4069
|
-
|
|
4070
|
-
return this;
|
|
4071
|
-
};
|
|
4072
|
-
|
|
4073
|
-
/**
|
|
4074
|
-
* Extends the NDElement prototype with new methods available to all NDElement instances.
|
|
4075
|
-
* Use this to add global methods to all NDElements.
|
|
4076
|
-
*
|
|
4077
|
-
* @param {Object} methods - Object containing method definitions to add to prototype
|
|
4078
|
-
* @returns {typeof NDElement} The NDElement constructor
|
|
4079
|
-
* @throws {NativeDocumentError} If methods is not an object or contains non-function values
|
|
4080
|
-
* @example
|
|
4081
|
-
* NDElement.extend({
|
|
4082
|
-
* fadeIn() {
|
|
4083
|
-
* this.$element.style.opacity = '1';
|
|
4084
|
-
* return this;
|
|
4085
|
-
* }
|
|
4086
|
-
* });
|
|
4087
|
-
* // Now all NDElements have .fadeIn() method
|
|
4088
|
-
* Div().nd.fadeIn();
|
|
4089
|
-
*/
|
|
4090
|
-
NDElement.extend = function(methods) {
|
|
4091
|
-
if (!methods || typeof methods !== 'object') {
|
|
4092
|
-
throw new NativeDocumentError('NDElement.extend() requires an object of methods');
|
|
4093
|
-
}
|
|
4094
|
-
|
|
4095
|
-
if (Array.isArray(methods)) {
|
|
4096
|
-
throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
|
|
4097
|
-
}
|
|
4098
|
-
|
|
4099
|
-
const protectedMethods = new Set([
|
|
4100
|
-
'constructor', 'valueOf', '$element', '$observer',
|
|
4101
|
-
'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
|
|
4102
|
-
'lifecycle', 'mounted', 'unmounted', 'unmountChildren'
|
|
4103
|
-
]);
|
|
4104
|
-
|
|
4105
|
-
for (const name in methods) {
|
|
4106
|
-
if (!Object.hasOwn(methods, name)) {
|
|
4107
|
-
continue;
|
|
4108
|
-
}
|
|
4109
|
-
|
|
4110
|
-
const method = methods[name];
|
|
4111
|
-
|
|
4112
|
-
if (typeof method !== 'function') {
|
|
4113
|
-
DebugManager$1.warn('NDElement.extend', `"${name}" is not a function, skipping`);
|
|
4114
|
-
continue;
|
|
4115
|
-
}
|
|
4116
|
-
|
|
4117
|
-
if (protectedMethods.has(name)) {
|
|
4118
|
-
DebugManager$1.error('NDElement.extend', `Cannot override protected method "${name}"`);
|
|
4119
|
-
throw new NativeDocumentError(`Cannot override protected method "${name}"`);
|
|
4120
|
-
}
|
|
4121
|
-
|
|
4122
|
-
if (NDElement.prototype[name]) {
|
|
4123
|
-
DebugManager$1.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
|
|
4124
|
-
}
|
|
4125
|
-
|
|
4126
|
-
NDElement.prototype[name] = method;
|
|
4127
|
-
}
|
|
4128
|
-
|
|
4129
|
-
return NDElement;
|
|
4130
|
-
};
|
|
4131
|
-
|
|
4132
|
-
const COMMON_NODE_TYPES = {
|
|
4133
|
-
ELEMENT: 1,
|
|
4134
|
-
TEXT: 3,
|
|
4135
|
-
COMMENT: 8,
|
|
4136
|
-
DOCUMENT_FRAGMENT: 11
|
|
4137
|
-
};
|
|
4138
|
-
|
|
4139
|
-
const VALID_TYPES = [];
|
|
4140
|
-
VALID_TYPES[COMMON_NODE_TYPES.ELEMENT] = true;
|
|
4141
|
-
VALID_TYPES[COMMON_NODE_TYPES.TEXT] = true;
|
|
4142
|
-
VALID_TYPES[COMMON_NODE_TYPES.DOCUMENT_FRAGMENT] = true;
|
|
4143
|
-
VALID_TYPES[COMMON_NODE_TYPES.COMMENT] = true;
|
|
4144
|
-
|
|
4145
|
-
const Validator = {
|
|
4146
|
-
isObservable(value) {
|
|
4147
|
-
return value && (value.__$isObservable || value.__$Observable);
|
|
4148
|
-
},
|
|
4149
|
-
isTemplateBinding(value) {
|
|
4150
|
-
return value?.__$isTemplateBinding;
|
|
4151
|
-
},
|
|
4152
|
-
isObservableWhenResult(value) {
|
|
4153
|
-
return value && (value.__$isObservableWhen || (typeof value === 'object' && '$target' in value && '$observer' in value));
|
|
4154
|
-
},
|
|
4155
|
-
isArrayObservable(value) {
|
|
4156
|
-
return value?.__$isObservableArray;
|
|
4157
|
-
},
|
|
4158
|
-
isProxy(value) {
|
|
4159
|
-
return value?.__isProxy__
|
|
4160
|
-
},
|
|
4161
|
-
isObservableOrProxy(value) {
|
|
4162
|
-
return Validator.isObservable(value) || Validator.isProxy(value);
|
|
4163
|
-
},
|
|
4164
|
-
isAnchor(value) {
|
|
4165
|
-
return value?.__Anchor__
|
|
4166
|
-
},
|
|
4167
|
-
isObservableChecker(value) {
|
|
4168
|
-
return value?.__$isObservableChecker || value instanceof ObservableChecker;
|
|
4169
|
-
},
|
|
4170
|
-
isArray(value) {
|
|
4171
|
-
return Array.isArray(value);
|
|
4172
|
-
},
|
|
4173
|
-
isString(value) {
|
|
4174
|
-
return typeof value === 'string';
|
|
4175
|
-
},
|
|
4176
|
-
isNumber(value) {
|
|
4177
|
-
return typeof value === 'number';
|
|
4178
|
-
},
|
|
4179
|
-
isBoolean(value) {
|
|
4180
|
-
return typeof value === 'boolean';
|
|
4181
|
-
},
|
|
4182
|
-
isFunction(value) {
|
|
4183
|
-
return typeof value === 'function';
|
|
4184
|
-
},
|
|
4185
|
-
isAsyncFunction(value) {
|
|
4186
|
-
return typeof value === 'function' && value.constructor.name === 'AsyncFunction';
|
|
4187
|
-
},
|
|
4188
|
-
isObject(value) {
|
|
4189
|
-
return typeof value === 'object' && value !== null;
|
|
4190
|
-
},
|
|
4191
|
-
isJson(value) {
|
|
4192
|
-
return !(typeof value !== 'object' || value === null || Array.isArray(value) || value.constructor.name !== 'Object')
|
|
4193
|
-
},
|
|
4194
|
-
isElement(value) {
|
|
4195
|
-
return value && VALID_TYPES[value.nodeType];
|
|
4196
|
-
},
|
|
4197
|
-
isDOMNode(value) {
|
|
4198
|
-
return VALID_TYPES[value.nodeType];
|
|
4199
|
-
},
|
|
4200
|
-
isFragment(value) {
|
|
4201
|
-
return value?.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT;
|
|
4202
|
-
},
|
|
4203
|
-
isStringOrObservable(value) {
|
|
4204
|
-
return this.isString(value) || this.isObservable(value);
|
|
4205
|
-
},
|
|
4206
|
-
isValidChild(child) {
|
|
4207
|
-
return child === null ||
|
|
4208
|
-
this.isElement(child) ||
|
|
4209
|
-
this.isObservable(child) ||
|
|
4210
|
-
this.isNDElement(child) ||
|
|
4211
|
-
['string', 'number', 'boolean'].includes(typeof child);
|
|
4212
|
-
},
|
|
4213
|
-
isNDElement(child) {
|
|
4214
|
-
return child?.__$isNDElement || child instanceof NDElement;
|
|
2671
|
+
// ----------------------------------------------------------------
|
|
2672
|
+
// Class attributes binder
|
|
2673
|
+
// ----------------------------------------------------------------
|
|
2674
|
+
const classListMethods = {
|
|
2675
|
+
getClasses() {
|
|
2676
|
+
return this.$element.className?.split(' ').filter(Boolean);
|
|
4215
2677
|
},
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
2678
|
+
add(value) {
|
|
2679
|
+
const classes = this.getClasses();
|
|
2680
|
+
if(classes.indexOf(value) >= 0) {
|
|
2681
|
+
return;
|
|
4219
2682
|
}
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
return invalid.length === 0;
|
|
2683
|
+
classes.push(value);
|
|
2684
|
+
this.$element.className = classes.join(' ');
|
|
4223
2685
|
},
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
const invalid = children.filter(child => !this.isValidChild(child));
|
|
4230
|
-
if (invalid.length > 0) {
|
|
4231
|
-
throw new NativeDocumentError(`Invalid children detected: ${invalid.map(i => typeof i).join(', ')}`);
|
|
2686
|
+
remove(value) {
|
|
2687
|
+
const classes = this.getClasses();
|
|
2688
|
+
const index = classes.indexOf(value);
|
|
2689
|
+
if(index < 0) {
|
|
2690
|
+
return;
|
|
4232
2691
|
}
|
|
4233
|
-
|
|
4234
|
-
|
|
2692
|
+
classes.splice(index, 1);
|
|
2693
|
+
this.$element.className = classes.join(' ');
|
|
4235
2694
|
},
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
2695
|
+
toggle(value, force = undefined) {
|
|
2696
|
+
const classes = this.getClasses();
|
|
2697
|
+
const index = classes.indexOf(value);
|
|
2698
|
+
if(index >= 0) {
|
|
2699
|
+
if(force === true) {
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
classes.splice(index, 1);
|
|
4244
2703
|
}
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
* @param {string} data
|
|
4251
|
-
* @returns {boolean}
|
|
4252
|
-
*/
|
|
4253
|
-
containsObservableReference(data) {
|
|
4254
|
-
if(!data || typeof data !== 'string') {
|
|
4255
|
-
return false;
|
|
2704
|
+
else {
|
|
2705
|
+
if(force === false) {
|
|
2706
|
+
return;
|
|
2707
|
+
}
|
|
2708
|
+
classes.push(value);
|
|
4256
2709
|
}
|
|
4257
|
-
|
|
2710
|
+
this.$element.className = classes.join(' ');
|
|
4258
2711
|
},
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
validateEventCallback(callback) {
|
|
4262
|
-
if (typeof callback !== 'function') {
|
|
4263
|
-
throw new NativeDocumentError('Event callback must be a function');
|
|
4264
|
-
}
|
|
2712
|
+
contains(value) {
|
|
2713
|
+
return this.getClasses().indexOf(value) >= 0;
|
|
4265
2714
|
}
|
|
4266
2715
|
};
|
|
4267
2716
|
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
return {
|
|
4276
|
-
dependencies: observables.length > 0 ? observables : null,
|
|
4277
|
-
callback: (value) => callbackFn(value, getValues())
|
|
4278
|
-
};
|
|
4279
|
-
}
|
|
4280
|
-
|
|
4281
|
-
function match(patternObservableOrValue, asRegexObservableOrValue = true, flagsObservableOrValue = ''){
|
|
4282
|
-
return createMultiSourceFilter(
|
|
4283
|
-
[patternObservableOrValue, asRegexObservableOrValue, flagsObservableOrValue],
|
|
4284
|
-
(value, [pattern, asRegex, flags]) => {
|
|
4285
|
-
if (!pattern) return true;
|
|
4286
|
-
|
|
4287
|
-
if (asRegex){
|
|
4288
|
-
try {
|
|
4289
|
-
const regex = new RegExp(pattern, flags);
|
|
4290
|
-
return regex.test(String(value));
|
|
4291
|
-
} catch (error){
|
|
4292
|
-
DebugManager$1.warn('Invalid regex pattern:', pattern, error);
|
|
4293
|
-
return false;
|
|
4294
|
-
}
|
|
4295
|
-
}
|
|
4296
|
-
|
|
4297
|
-
if (!flags || flags === ''){
|
|
4298
|
-
return String(value).toLowerCase().includes(String(pattern).toLowerCase());
|
|
4299
|
-
}
|
|
4300
|
-
return String(value).includes(String(pattern));
|
|
4301
|
-
}
|
|
4302
|
-
);
|
|
4303
|
-
}
|
|
4304
|
-
|
|
4305
|
-
/**
|
|
4306
|
-
* Conditionally shows an element based on an observable condition.
|
|
4307
|
-
* The element is mounted/unmounted from the DOM as the condition changes.
|
|
4308
|
-
*
|
|
4309
|
-
* @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
|
|
4310
|
-
* @param {NdChild|(() => NdChild)} child - Element or content to show/hide
|
|
4311
|
-
* @param {Object} [options={}] - Configuration options
|
|
4312
|
-
* @param {string|null} [options.comment=null] - Comment for debugging
|
|
4313
|
-
* @param {boolean} [options.shouldKeepInCache=true] - Whether to cache the element when hidden
|
|
4314
|
-
* @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
|
|
4315
|
-
* @example
|
|
4316
|
-
* const isVisible = Observable(false);
|
|
4317
|
-
* ShowIf(isVisible, Div({}, 'Hello World'));
|
|
4318
|
-
*/
|
|
4319
|
-
const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
|
|
4320
|
-
if(!Validator.isObservable(condition)) {
|
|
4321
|
-
if(typeof condition === "boolean") {
|
|
4322
|
-
return condition ? ElementCreator.getChild(child) : null;
|
|
4323
|
-
}
|
|
4324
|
-
|
|
4325
|
-
return DebugManager$1.warn('ShowIf', "ShowIf : condition must be an Observable or boolean / "+comment, condition);
|
|
2717
|
+
Object.defineProperty(HTMLElement.prototype, 'classes', {
|
|
2718
|
+
configurable: true,
|
|
2719
|
+
get() {
|
|
2720
|
+
return {
|
|
2721
|
+
$element: this,
|
|
2722
|
+
...classListMethods
|
|
2723
|
+
};
|
|
4326
2724
|
}
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
let childElement = null;
|
|
4330
|
-
const getChildElement = () => {
|
|
4331
|
-
if(childElement && shouldKeepInCache) {
|
|
4332
|
-
return childElement;
|
|
4333
|
-
}
|
|
4334
|
-
childElement = ElementCreator.getChild(child);
|
|
4335
|
-
if(Validator.isFragment(childElement)) {
|
|
4336
|
-
childElement = Array.from(childElement.childNodes);
|
|
4337
|
-
}
|
|
4338
|
-
return childElement;
|
|
4339
|
-
};
|
|
4340
|
-
|
|
4341
|
-
const currentValue = condition.val();
|
|
2725
|
+
});
|
|
4342
2726
|
|
|
4343
|
-
|
|
4344
|
-
|
|
2727
|
+
const normalizeComponentArgs = function(props, children = null) {
|
|
2728
|
+
if(props && children) {
|
|
2729
|
+
return { props, children };
|
|
2730
|
+
}
|
|
2731
|
+
if(typeof props !== 'object' || Array.isArray(props) || props === null || props.constructor.name !== 'Object' || props.$hydrate) { // IF it's not a JSON
|
|
2732
|
+
return { props: children, children: props }
|
|
4345
2733
|
}
|
|
2734
|
+
return { props, children };
|
|
2735
|
+
};
|
|
4346
2736
|
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
element.appendChild(getChildElement());
|
|
4350
|
-
return;
|
|
4351
|
-
}
|
|
4352
|
-
element.remove();
|
|
4353
|
-
});
|
|
2737
|
+
const createHtmlElement = (element, _attributes, _children = null) => {
|
|
2738
|
+
let { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
|
|
4354
2739
|
|
|
2740
|
+
ElementCreator.processAttributes(element, attributes);
|
|
2741
|
+
ElementCreator.processChildren(children, element);
|
|
4355
2742
|
return element;
|
|
4356
2743
|
};
|
|
4357
2744
|
|
|
2745
|
+
/**
|
|
2746
|
+
*
|
|
2747
|
+
* @param {string} name
|
|
2748
|
+
* @param {?Function=} customWrapper
|
|
2749
|
+
* @returns {Function}
|
|
2750
|
+
*/
|
|
2751
|
+
function HtmlElementWrapper(name, customWrapper = null) {
|
|
2752
|
+
if(name) {
|
|
2753
|
+
if(customWrapper) {
|
|
2754
|
+
let node = null;
|
|
2755
|
+
let createElement = (attr, children) => {
|
|
2756
|
+
node = document.createElement(name);
|
|
2757
|
+
createElement = (attr, children) => {
|
|
2758
|
+
return createHtmlElement(customWrapper(node.cloneNode()), attr, children);
|
|
2759
|
+
};
|
|
2760
|
+
return createHtmlElement(customWrapper(node.cloneNode()), attr, children); };
|
|
2761
|
+
|
|
2762
|
+
return (attr, children) => createElement(attr, children)
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
let node = null;
|
|
2766
|
+
let createElement = (attr, children) => {
|
|
2767
|
+
node = document.createElement(name);
|
|
2768
|
+
createElement = (attr, children) => {
|
|
2769
|
+
return createHtmlElement(node.cloneNode(), attr, children);
|
|
2770
|
+
};
|
|
2771
|
+
return createHtmlElement(node.cloneNode(), attr, children);
|
|
2772
|
+
};
|
|
2773
|
+
|
|
2774
|
+
return (attr, children) => createElement(attr, children)
|
|
2775
|
+
}
|
|
2776
|
+
return (children, name = '') => {
|
|
2777
|
+
const anchor = Anchor(name);
|
|
2778
|
+
anchor.append(children);
|
|
2779
|
+
return anchor;
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
|
|
4358
2783
|
/**
|
|
4359
2784
|
* Creates a `<div>` element.
|
|
4360
2785
|
* @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLDivElement}
|
|
@@ -5074,7 +3499,7 @@ var NativeComponents = (function (exports) {
|
|
|
5074
3499
|
|
|
5075
3500
|
Alert.preset = function(name, callback) {
|
|
5076
3501
|
if (Alert.prototype[name] || Alert[name]) {
|
|
5077
|
-
DebugManager$
|
|
3502
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Alert.`);
|
|
5078
3503
|
return;
|
|
5079
3504
|
}
|
|
5080
3505
|
Alert[name] = (content, props) => callback(new Alert(content, props));
|
|
@@ -5259,253 +3684,90 @@ var NativeComponents = (function (exports) {
|
|
|
5259
3684
|
* @param {ValidChildren} icon - The icon to display
|
|
5260
3685
|
* @returns {Alert}
|
|
5261
3686
|
*/
|
|
5262
|
-
Alert.prototype.icon = function(icon) {
|
|
5263
|
-
this.$description.icon = icon;
|
|
5264
|
-
return this;
|
|
5265
|
-
};
|
|
5266
|
-
|
|
5267
|
-
/**
|
|
5268
|
-
* Shows or hides the icon
|
|
5269
|
-
* @param {boolean} [show=true] - Whether to show the icon
|
|
5270
|
-
* @returns {Alert}
|
|
5271
|
-
*/
|
|
5272
|
-
Alert.prototype.showIcon = function(show = true) {
|
|
5273
|
-
this.$description.showIcon = show;
|
|
5274
|
-
};
|
|
5275
|
-
|
|
5276
|
-
/**
|
|
5277
|
-
* Sets whether the alert can be closed
|
|
5278
|
-
* @param {boolean} [closable=true] - Whether the alert is closable
|
|
5279
|
-
* @returns {Alert}
|
|
5280
|
-
*/
|
|
5281
|
-
Alert.prototype.closable = function(closable = true) {
|
|
5282
|
-
this.$description.closable = !!closable;
|
|
5283
|
-
if(closable) {
|
|
5284
|
-
this.showIf(closable);
|
|
5285
|
-
}
|
|
5286
|
-
return this;
|
|
5287
|
-
};
|
|
5288
|
-
|
|
5289
|
-
/**
|
|
5290
|
-
* Sets whether the alert is dismissible (alias for closable)
|
|
5291
|
-
* @param {boolean} [dismissible=true] - Whether the alert is dismissible
|
|
5292
|
-
* @returns {Alert}
|
|
5293
|
-
*/
|
|
5294
|
-
Alert.prototype.dismissible = function(dismissible = true) {
|
|
5295
|
-
return this.closable(dismissible);
|
|
5296
|
-
};
|
|
5297
|
-
|
|
5298
|
-
/**
|
|
5299
|
-
* Sets auto-dismiss delay for the alert
|
|
5300
|
-
* @param {number} delay - Delay in milliseconds before auto-dismissing
|
|
5301
|
-
* @returns {Alert}
|
|
5302
|
-
*/
|
|
5303
|
-
Alert.prototype.autoDismiss = function(delay) {
|
|
5304
|
-
this.$description.autoDismiss = delay;
|
|
5305
|
-
return this;
|
|
5306
|
-
};
|
|
5307
|
-
|
|
5308
|
-
/**
|
|
5309
|
-
* Closes the alert
|
|
5310
|
-
*/
|
|
5311
|
-
Alert.prototype.close = function() {
|
|
5312
|
-
this.$description.showIf?.set(false);
|
|
5313
|
-
this.emit('hide');
|
|
5314
|
-
};
|
|
5315
|
-
|
|
5316
|
-
/**
|
|
5317
|
-
* Shows the alert
|
|
5318
|
-
*/
|
|
5319
|
-
Alert.prototype.show = function() {
|
|
5320
|
-
this.$description.showIf?.set(true);
|
|
5321
|
-
this.emit('show');
|
|
5322
|
-
};
|
|
5323
|
-
|
|
5324
|
-
/**
|
|
5325
|
-
* Hides the alert
|
|
5326
|
-
*/
|
|
5327
|
-
Alert.prototype.hide = Alert.prototype.close;
|
|
5328
|
-
|
|
5329
|
-
/**
|
|
5330
|
-
* Registers a handler for the close event
|
|
5331
|
-
* @param {(element: Alert) => void} handler - The event handler
|
|
5332
|
-
* @returns {Alert}
|
|
5333
|
-
*/
|
|
5334
|
-
Alert.prototype.onClose = function(handler) {
|
|
5335
|
-
this.on('close', handler);
|
|
5336
|
-
return this;
|
|
5337
|
-
};
|
|
5338
|
-
|
|
5339
|
-
/**
|
|
5340
|
-
* Registers a handler for the show event
|
|
5341
|
-
* @param {(element: Alert) => void} handler - The event handler
|
|
5342
|
-
* @returns {Alert}
|
|
5343
|
-
*/
|
|
5344
|
-
Alert.prototype.onShow = function(handler) {
|
|
5345
|
-
this.on('show', handler);
|
|
5346
|
-
return this;
|
|
5347
|
-
};
|
|
5348
|
-
|
|
5349
|
-
function Button(label, props = {}) {
|
|
5350
|
-
if(!(this instanceof Button)) {
|
|
5351
|
-
return new Button(label, props);
|
|
5352
|
-
}
|
|
5353
|
-
|
|
5354
|
-
BaseComponent.call(this, props);
|
|
5355
|
-
|
|
5356
|
-
this.$description = {
|
|
5357
|
-
label: label,
|
|
5358
|
-
type: null,
|
|
5359
|
-
variant: null,
|
|
5360
|
-
size: null,
|
|
5361
|
-
icon: null,
|
|
5362
|
-
iconPosition: 'left',
|
|
5363
|
-
loading: null,
|
|
5364
|
-
disabled: null,
|
|
5365
|
-
template: null,
|
|
5366
|
-
block: null,
|
|
5367
|
-
borderRadiusType: null,
|
|
5368
|
-
outline: null,
|
|
5369
|
-
props
|
|
5370
|
-
};
|
|
5371
|
-
|
|
5372
|
-
this.$element = null;
|
|
5373
|
-
}
|
|
5374
|
-
|
|
5375
|
-
Button.defaultTemplate = null;
|
|
5376
|
-
|
|
5377
|
-
Button.use = function(template = {}) {
|
|
5378
|
-
Button.defaultTemplate = template;
|
|
5379
|
-
};
|
|
5380
|
-
|
|
5381
|
-
BaseComponent.extends(Button);
|
|
5382
|
-
|
|
5383
|
-
Button.preset = function(name, callback) {
|
|
5384
|
-
if (Button.prototype[name] || Button[name]) {
|
|
5385
|
-
DebugManager$1.warn(`Warning: the ${name} method already exist in Button.`);
|
|
5386
|
-
return;
|
|
5387
|
-
}
|
|
5388
|
-
Button[name] = (label, props) => callback(new Button(label, props));
|
|
5389
|
-
};
|
|
5390
|
-
|
|
5391
|
-
Button.presets = function(presets) {
|
|
5392
|
-
for (const name in presets) {
|
|
5393
|
-
Button.preset(name, presets[name]);
|
|
5394
|
-
}
|
|
5395
|
-
};
|
|
5396
|
-
|
|
5397
|
-
Button.prototype.type = function(type) {
|
|
5398
|
-
this.$description.type = type;
|
|
5399
|
-
return this;
|
|
5400
|
-
};
|
|
5401
|
-
|
|
5402
|
-
Button.prototype.variant = function(variant) {
|
|
5403
|
-
this.$description.variant = variant;
|
|
5404
|
-
return this;
|
|
5405
|
-
};
|
|
5406
|
-
Button.prototype.primary = function() {
|
|
5407
|
-
return this.variant('primary');
|
|
5408
|
-
};
|
|
5409
|
-
Button.prototype.secondary = function() {
|
|
5410
|
-
return this.variant('secondary');
|
|
5411
|
-
};
|
|
5412
|
-
Button.prototype.danger = function() {
|
|
5413
|
-
return this.variant('danger');
|
|
5414
|
-
};
|
|
5415
|
-
Button.prototype.success = function() {
|
|
5416
|
-
return this.variant('success');
|
|
5417
|
-
};
|
|
5418
|
-
Button.prototype.warning = function() {
|
|
5419
|
-
return this.variant('warning');
|
|
5420
|
-
};
|
|
5421
|
-
Button.prototype.ghost = function() {
|
|
5422
|
-
return this.variant('ghost');
|
|
5423
|
-
};
|
|
5424
|
-
Button.prototype.link = function() {
|
|
5425
|
-
return this.variant('link');
|
|
5426
|
-
};
|
|
5427
|
-
Button.prototype.outline = function() {
|
|
5428
|
-
this.$description.outline = true;
|
|
5429
|
-
return this;
|
|
5430
|
-
};
|
|
5431
|
-
|
|
5432
|
-
Button.prototype.size = function(size) {
|
|
5433
|
-
this.$description.size = size;
|
|
5434
|
-
return this;
|
|
5435
|
-
};
|
|
5436
|
-
Button.prototype.small = function() {
|
|
5437
|
-
return this.size('small');
|
|
5438
|
-
};
|
|
5439
|
-
Button.prototype.large = function() {
|
|
5440
|
-
return this.size('large');
|
|
5441
|
-
};
|
|
5442
|
-
Button.prototype.medium = function() {
|
|
5443
|
-
return this.size('medium');
|
|
5444
|
-
};
|
|
5445
|
-
|
|
5446
|
-
Button.prototype.icon = function(icon, iconPosition = 'leading') {
|
|
5447
|
-
this.$description.icon = icon;
|
|
5448
|
-
this.$description.iconPosition = iconPosition;
|
|
5449
|
-
return this;
|
|
5450
|
-
};
|
|
5451
|
-
|
|
5452
|
-
Button.prototype.iconAtLeading = function() {
|
|
5453
|
-
this.$description.iconPosition = 'leading';
|
|
5454
|
-
return this;
|
|
5455
|
-
};
|
|
5456
|
-
|
|
5457
|
-
Button.prototype.iconAtTrailing = function() {
|
|
5458
|
-
this.$description.iconPosition = 'trailing';
|
|
5459
|
-
return this;
|
|
5460
|
-
};
|
|
5461
|
-
Button.prototype.iconAtTop = function() {
|
|
5462
|
-
this.$description.iconPosition = 'top';
|
|
3687
|
+
Alert.prototype.icon = function(icon) {
|
|
3688
|
+
this.$description.icon = icon;
|
|
5463
3689
|
return this;
|
|
5464
3690
|
};
|
|
5465
3691
|
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
3692
|
+
/**
|
|
3693
|
+
* Shows or hides the icon
|
|
3694
|
+
* @param {boolean} [show=true] - Whether to show the icon
|
|
3695
|
+
* @returns {Alert}
|
|
3696
|
+
*/
|
|
3697
|
+
Alert.prototype.showIcon = function(show = true) {
|
|
3698
|
+
this.$description.showIcon = show;
|
|
5469
3699
|
};
|
|
5470
3700
|
|
|
5471
|
-
|
|
5472
|
-
|
|
3701
|
+
/**
|
|
3702
|
+
* Sets whether the alert can be closed
|
|
3703
|
+
* @param {boolean} [closable=true] - Whether the alert is closable
|
|
3704
|
+
* @returns {Alert}
|
|
3705
|
+
*/
|
|
3706
|
+
Alert.prototype.closable = function(closable = true) {
|
|
3707
|
+
this.$description.closable = !!closable;
|
|
3708
|
+
if(closable) {
|
|
3709
|
+
this.showIf(closable);
|
|
3710
|
+
}
|
|
5473
3711
|
return this;
|
|
5474
3712
|
};
|
|
5475
3713
|
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
3714
|
+
/**
|
|
3715
|
+
* Sets whether the alert is dismissible (alias for closable)
|
|
3716
|
+
* @param {boolean} [dismissible=true] - Whether the alert is dismissible
|
|
3717
|
+
* @returns {Alert}
|
|
3718
|
+
*/
|
|
3719
|
+
Alert.prototype.dismissible = function(dismissible = true) {
|
|
3720
|
+
return this.closable(dismissible);
|
|
5479
3721
|
};
|
|
5480
3722
|
|
|
5481
|
-
|
|
5482
|
-
|
|
3723
|
+
/**
|
|
3724
|
+
* Sets auto-dismiss delay for the alert
|
|
3725
|
+
* @param {number} delay - Delay in milliseconds before auto-dismissing
|
|
3726
|
+
* @returns {Alert}
|
|
3727
|
+
*/
|
|
3728
|
+
Alert.prototype.autoDismiss = function(delay) {
|
|
3729
|
+
this.$description.autoDismiss = delay;
|
|
5483
3730
|
return this;
|
|
5484
3731
|
};
|
|
5485
3732
|
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
3733
|
+
/**
|
|
3734
|
+
* Closes the alert
|
|
3735
|
+
*/
|
|
3736
|
+
Alert.prototype.close = function() {
|
|
3737
|
+
this.$description.showIf?.set(false);
|
|
3738
|
+
this.emit('hide');
|
|
5489
3739
|
};
|
|
5490
3740
|
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
this
|
|
5497
|
-
return this;
|
|
5498
|
-
};
|
|
5499
|
-
Button.prototype.circle = function() {
|
|
5500
|
-
this.$description.borderRadiusType = 'circle';
|
|
5501
|
-
return this;
|
|
3741
|
+
/**
|
|
3742
|
+
* Shows the alert
|
|
3743
|
+
*/
|
|
3744
|
+
Alert.prototype.show = function() {
|
|
3745
|
+
this.$description.showIf?.set(true);
|
|
3746
|
+
this.emit('show');
|
|
5502
3747
|
};
|
|
5503
|
-
|
|
5504
|
-
|
|
3748
|
+
|
|
3749
|
+
/**
|
|
3750
|
+
* Hides the alert
|
|
3751
|
+
*/
|
|
3752
|
+
Alert.prototype.hide = Alert.prototype.close;
|
|
3753
|
+
|
|
3754
|
+
/**
|
|
3755
|
+
* Registers a handler for the close event
|
|
3756
|
+
* @param {(element: Alert) => void} handler - The event handler
|
|
3757
|
+
* @returns {Alert}
|
|
3758
|
+
*/
|
|
3759
|
+
Alert.prototype.onClose = function(handler) {
|
|
3760
|
+
this.on('close', handler);
|
|
5505
3761
|
return this;
|
|
5506
3762
|
};
|
|
5507
|
-
|
|
5508
|
-
|
|
3763
|
+
|
|
3764
|
+
/**
|
|
3765
|
+
* Registers a handler for the show event
|
|
3766
|
+
* @param {(element: Alert) => void} handler - The event handler
|
|
3767
|
+
* @returns {Alert}
|
|
3768
|
+
*/
|
|
3769
|
+
Alert.prototype.onShow = function(handler) {
|
|
3770
|
+
this.on('show', handler);
|
|
5509
3771
|
return this;
|
|
5510
3772
|
};
|
|
5511
3773
|
|
|
@@ -5551,7 +3813,7 @@ var NativeComponents = (function (exports) {
|
|
|
5551
3813
|
|
|
5552
3814
|
Avatar.preset = function(name, callback) {
|
|
5553
3815
|
if (Avatar.prototype[name] || Avatar[name]) {
|
|
5554
|
-
DebugManager$
|
|
3816
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in Avatar.`);
|
|
5555
3817
|
return;
|
|
5556
3818
|
}
|
|
5557
3819
|
Avatar[name] = (label, props) => callback(new Avatar(label, props));
|
|
@@ -5973,7 +4235,7 @@ var NativeComponents = (function (exports) {
|
|
|
5973
4235
|
|
|
5974
4236
|
Badge.preset = function(name, callback) {
|
|
5975
4237
|
if (Badge.prototype[name] || Badge[name]) {
|
|
5976
|
-
DebugManager$
|
|
4238
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in Badge.`);
|
|
5977
4239
|
return;
|
|
5978
4240
|
}
|
|
5979
4241
|
Badge[name] = (content, props) => callback(new Badge(content, props));
|
|
@@ -6091,7 +4353,7 @@ var NativeComponents = (function (exports) {
|
|
|
6091
4353
|
|
|
6092
4354
|
Breadcrumb.preset = function(name, callback) {
|
|
6093
4355
|
if (Breadcrumb.prototype[name] || Breadcrumb[name]) {
|
|
6094
|
-
DebugManager$
|
|
4356
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Breadcrumb.`);
|
|
6095
4357
|
return;
|
|
6096
4358
|
}
|
|
6097
4359
|
Breadcrumb[name] = (props) => callback(new Breadcrumb(props));
|
|
@@ -6145,6 +4407,169 @@ var NativeComponents = (function (exports) {
|
|
|
6145
4407
|
return this;
|
|
6146
4408
|
};
|
|
6147
4409
|
|
|
4410
|
+
function Button(label, props = {}) {
|
|
4411
|
+
if(!(this instanceof Button)) {
|
|
4412
|
+
return new Button(label, props);
|
|
4413
|
+
}
|
|
4414
|
+
|
|
4415
|
+
BaseComponent.call(this, props);
|
|
4416
|
+
|
|
4417
|
+
this.$description = {
|
|
4418
|
+
label: label,
|
|
4419
|
+
type: null,
|
|
4420
|
+
variant: null,
|
|
4421
|
+
size: null,
|
|
4422
|
+
icon: null,
|
|
4423
|
+
iconPosition: 'left',
|
|
4424
|
+
loading: null,
|
|
4425
|
+
disabled: null,
|
|
4426
|
+
template: null,
|
|
4427
|
+
block: null,
|
|
4428
|
+
borderRadiusType: null,
|
|
4429
|
+
outline: null,
|
|
4430
|
+
props
|
|
4431
|
+
};
|
|
4432
|
+
|
|
4433
|
+
this.$element = null;
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
Button.defaultTemplate = null;
|
|
4437
|
+
|
|
4438
|
+
Button.use = function(template = {}) {
|
|
4439
|
+
Button.defaultTemplate = template;
|
|
4440
|
+
};
|
|
4441
|
+
|
|
4442
|
+
BaseComponent.extends(Button);
|
|
4443
|
+
|
|
4444
|
+
Button.preset = function(name, callback) {
|
|
4445
|
+
if (Button.prototype[name] || Button[name]) {
|
|
4446
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Button.`);
|
|
4447
|
+
return;
|
|
4448
|
+
}
|
|
4449
|
+
Button[name] = (label, props) => callback(new Button(label, props));
|
|
4450
|
+
};
|
|
4451
|
+
|
|
4452
|
+
Button.presets = function(presets) {
|
|
4453
|
+
for (const name in presets) {
|
|
4454
|
+
Button.preset(name, presets[name]);
|
|
4455
|
+
}
|
|
4456
|
+
};
|
|
4457
|
+
|
|
4458
|
+
Button.prototype.type = function(type) {
|
|
4459
|
+
this.$description.type = type;
|
|
4460
|
+
return this;
|
|
4461
|
+
};
|
|
4462
|
+
|
|
4463
|
+
Button.prototype.variant = function(variant) {
|
|
4464
|
+
this.$description.variant = variant;
|
|
4465
|
+
return this;
|
|
4466
|
+
};
|
|
4467
|
+
Button.prototype.primary = function() {
|
|
4468
|
+
return this.variant('primary');
|
|
4469
|
+
};
|
|
4470
|
+
Button.prototype.secondary = function() {
|
|
4471
|
+
return this.variant('secondary');
|
|
4472
|
+
};
|
|
4473
|
+
Button.prototype.danger = function() {
|
|
4474
|
+
return this.variant('danger');
|
|
4475
|
+
};
|
|
4476
|
+
Button.prototype.success = function() {
|
|
4477
|
+
return this.variant('success');
|
|
4478
|
+
};
|
|
4479
|
+
Button.prototype.warning = function() {
|
|
4480
|
+
return this.variant('warning');
|
|
4481
|
+
};
|
|
4482
|
+
Button.prototype.ghost = function() {
|
|
4483
|
+
return this.variant('ghost');
|
|
4484
|
+
};
|
|
4485
|
+
Button.prototype.link = function() {
|
|
4486
|
+
return this.variant('link');
|
|
4487
|
+
};
|
|
4488
|
+
Button.prototype.outline = function() {
|
|
4489
|
+
this.$description.outline = true;
|
|
4490
|
+
return this;
|
|
4491
|
+
};
|
|
4492
|
+
|
|
4493
|
+
Button.prototype.size = function(size) {
|
|
4494
|
+
this.$description.size = size;
|
|
4495
|
+
return this;
|
|
4496
|
+
};
|
|
4497
|
+
Button.prototype.small = function() {
|
|
4498
|
+
return this.size('small');
|
|
4499
|
+
};
|
|
4500
|
+
Button.prototype.large = function() {
|
|
4501
|
+
return this.size('large');
|
|
4502
|
+
};
|
|
4503
|
+
Button.prototype.medium = function() {
|
|
4504
|
+
return this.size('medium');
|
|
4505
|
+
};
|
|
4506
|
+
|
|
4507
|
+
Button.prototype.icon = function(icon, iconPosition = 'leading') {
|
|
4508
|
+
this.$description.icon = icon;
|
|
4509
|
+
this.$description.iconPosition = iconPosition;
|
|
4510
|
+
return this;
|
|
4511
|
+
};
|
|
4512
|
+
|
|
4513
|
+
Button.prototype.iconAtLeading = function() {
|
|
4514
|
+
this.$description.iconPosition = 'leading';
|
|
4515
|
+
return this;
|
|
4516
|
+
};
|
|
4517
|
+
|
|
4518
|
+
Button.prototype.iconAtTrailing = function() {
|
|
4519
|
+
this.$description.iconPosition = 'trailing';
|
|
4520
|
+
return this;
|
|
4521
|
+
};
|
|
4522
|
+
Button.prototype.iconAtTop = function() {
|
|
4523
|
+
this.$description.iconPosition = 'top';
|
|
4524
|
+
return this;
|
|
4525
|
+
};
|
|
4526
|
+
|
|
4527
|
+
Button.prototype.iconAtBottom = function() {
|
|
4528
|
+
this.$description.iconPosition = 'bottom';
|
|
4529
|
+
return this;
|
|
4530
|
+
};
|
|
4531
|
+
|
|
4532
|
+
Button.prototype.iconOnly = function() {
|
|
4533
|
+
this.$description.iconOnly = true;
|
|
4534
|
+
return this;
|
|
4535
|
+
};
|
|
4536
|
+
|
|
4537
|
+
Button.prototype.loading = function(loading = true) {
|
|
4538
|
+
this.$description.loading = BaseComponent.obs(loading);
|
|
4539
|
+
return this;
|
|
4540
|
+
};
|
|
4541
|
+
|
|
4542
|
+
Button.prototype.disabled = function(disabled = true) {
|
|
4543
|
+
this.$description.disabled = BaseComponent.obs(disabled);
|
|
4544
|
+
return this;
|
|
4545
|
+
};
|
|
4546
|
+
|
|
4547
|
+
Button.prototype.render = function(renderFunction) {
|
|
4548
|
+
this.$description.render = renderFunction;
|
|
4549
|
+
return this;
|
|
4550
|
+
};
|
|
4551
|
+
|
|
4552
|
+
Button.prototype.rounded = function() {
|
|
4553
|
+
this.$description.borderRadiusType = 'rounded';
|
|
4554
|
+
return this;
|
|
4555
|
+
};
|
|
4556
|
+
Button.prototype.pill = function() {
|
|
4557
|
+
this.$description.borderRadiusType = 'pill';
|
|
4558
|
+
return this;
|
|
4559
|
+
};
|
|
4560
|
+
Button.prototype.circle = function() {
|
|
4561
|
+
this.$description.borderRadiusType = 'circle';
|
|
4562
|
+
return this;
|
|
4563
|
+
};
|
|
4564
|
+
Button.prototype.smooth = function() {
|
|
4565
|
+
this.$description.borderRadiusType = 'smooth';
|
|
4566
|
+
return this;
|
|
4567
|
+
};
|
|
4568
|
+
Button.prototype.block = function() {
|
|
4569
|
+
this.$description.block = true;
|
|
4570
|
+
return this;
|
|
4571
|
+
};
|
|
4572
|
+
|
|
6148
4573
|
function Card(config = {}) {
|
|
6149
4574
|
if(!(this instanceof Card)) {
|
|
6150
4575
|
return new Card(config);
|
|
@@ -6900,7 +5325,7 @@ var NativeComponents = (function (exports) {
|
|
|
6900
5325
|
|
|
6901
5326
|
Divider.preset = function(name, callback) {
|
|
6902
5327
|
if (Divider.prototype[name] || Divider[name]) {
|
|
6903
|
-
DebugManager$
|
|
5328
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in Divider.`);
|
|
6904
5329
|
return;
|
|
6905
5330
|
}
|
|
6906
5331
|
Divider[name] = (label, props) => callback(new Divider(label, props));
|
|
@@ -7319,7 +5744,7 @@ var NativeComponents = (function (exports) {
|
|
|
7319
5744
|
|
|
7320
5745
|
Dropdown.preset = function(name, callback) {
|
|
7321
5746
|
if (Dropdown.prototype[name] || Dropdown[name]) {
|
|
7322
|
-
DebugManager$
|
|
5747
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Dropdown.`);
|
|
7323
5748
|
return;
|
|
7324
5749
|
}
|
|
7325
5750
|
Dropdown[name] = (props) => callback(new Dropdown(props));
|
|
@@ -8540,10 +6965,10 @@ var NativeComponents = (function (exports) {
|
|
|
8540
6965
|
errorsPosition: 'bottom',
|
|
8541
6966
|
errorsMapper: null,
|
|
8542
6967
|
renderErrors: null,
|
|
8543
|
-
submitting:
|
|
8544
|
-
errors:
|
|
8545
|
-
isDirty:
|
|
8546
|
-
isValid:
|
|
6968
|
+
submitting: $$1(false),
|
|
6969
|
+
errors: $$1(null),
|
|
6970
|
+
isDirty: $$1(false),
|
|
6971
|
+
isValid: $$1(false),
|
|
8547
6972
|
props
|
|
8548
6973
|
};
|
|
8549
6974
|
}
|
|
@@ -8585,7 +7010,7 @@ var NativeComponents = (function (exports) {
|
|
|
8585
7010
|
dirties.push(field.$description.isDirty);
|
|
8586
7011
|
}
|
|
8587
7012
|
|
|
8588
|
-
|
|
7013
|
+
$$1.computed(() => {
|
|
8589
7014
|
const isDirty = dirties.some((item) => item.val());
|
|
8590
7015
|
this.$description.isDirty.set(isDirty);
|
|
8591
7016
|
}, dirties);
|
|
@@ -11374,7 +9799,7 @@ var NativeComponents = (function (exports) {
|
|
|
11374
9799
|
|
|
11375
9800
|
Modal.preset = function(name, callback) {
|
|
11376
9801
|
if (Modal.prototype[name] || Modal[name]) {
|
|
11377
|
-
DebugManager$
|
|
9802
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Modal.`);
|
|
11378
9803
|
return;
|
|
11379
9804
|
}
|
|
11380
9805
|
Modal[name] = (content, props) => callback(new Modal(content, props));
|
|
@@ -11625,7 +10050,7 @@ var NativeComponents = (function (exports) {
|
|
|
11625
10050
|
|
|
11626
10051
|
Pagination.preset = function(name, callback) {
|
|
11627
10052
|
if (Pagination.prototype[name] || Pagination[name]) {
|
|
11628
|
-
DebugManager$
|
|
10053
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Pagination.`);
|
|
11629
10054
|
return;
|
|
11630
10055
|
}
|
|
11631
10056
|
Pagination[name] = (props) => callback(new Pagination(props));
|
|
@@ -11920,7 +10345,7 @@ var NativeComponents = (function (exports) {
|
|
|
11920
10345
|
|
|
11921
10346
|
Popover.preset = function(name, callback) {
|
|
11922
10347
|
if (Popover.prototype[name] || Popover[name]) {
|
|
11923
|
-
DebugManager$
|
|
10348
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Popover.`);
|
|
11924
10349
|
return;
|
|
11925
10350
|
}
|
|
11926
10351
|
Popover[name] = (content, props) => callback(new Popover(content, props));
|
|
@@ -12222,7 +10647,7 @@ var NativeComponents = (function (exports) {
|
|
|
12222
10647
|
|
|
12223
10648
|
Progress.preset = function(name, callback) {
|
|
12224
10649
|
if (Progress.prototype[name] || Progress[name]) {
|
|
12225
|
-
DebugManager$
|
|
10650
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in Progress.`);
|
|
12226
10651
|
return;
|
|
12227
10652
|
}
|
|
12228
10653
|
Progress[name] = (props) => callback(new Progress(props));
|
|
@@ -12524,7 +10949,7 @@ var NativeComponents = (function (exports) {
|
|
|
12524
10949
|
|
|
12525
10950
|
VStack.preset = function(name, callback) {
|
|
12526
10951
|
if (VStack.prototype[name] || VStack[name]) {
|
|
12527
|
-
DebugManager$
|
|
10952
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in VStack.`);
|
|
12528
10953
|
return;
|
|
12529
10954
|
}
|
|
12530
10955
|
VStack[name] = (content, props) => callback(new VStack(content, props));
|
|
@@ -12699,7 +11124,7 @@ var NativeComponents = (function (exports) {
|
|
|
12699
11124
|
|
|
12700
11125
|
FixedStack.preset = function(name, callback) {
|
|
12701
11126
|
if(FixedStack.prototype[name] || FixedStack[name]) {
|
|
12702
|
-
DebugManager$
|
|
11127
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in FixedStack.`);
|
|
12703
11128
|
return;
|
|
12704
11129
|
}
|
|
12705
11130
|
FixedStack[name] = (content, props) => callback(new FixedStack(content, props));
|
|
@@ -12729,7 +11154,7 @@ var NativeComponents = (function (exports) {
|
|
|
12729
11154
|
|
|
12730
11155
|
HStack.preset = function(name, callback) {
|
|
12731
11156
|
if (HStack.prototype[name] || HStack[name]) {
|
|
12732
|
-
DebugManager$
|
|
11157
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in HStack.`);
|
|
12733
11158
|
return;
|
|
12734
11159
|
}
|
|
12735
11160
|
HStack[name] = (content, props) => callback(new HStack(content, props));
|
|
@@ -12759,7 +11184,7 @@ var NativeComponents = (function (exports) {
|
|
|
12759
11184
|
|
|
12760
11185
|
AbsoluteStack.preset = function(name, callback) {
|
|
12761
11186
|
if(AbsoluteStack.prototype[name] || AbsoluteStack[name]) {
|
|
12762
|
-
DebugManager$
|
|
11187
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in AbsoluteStack.`);
|
|
12763
11188
|
return;
|
|
12764
11189
|
}
|
|
12765
11190
|
AbsoluteStack[name] = (content, props) => callback(new AbsoluteStack(content, props));
|
|
@@ -12789,7 +11214,7 @@ var NativeComponents = (function (exports) {
|
|
|
12789
11214
|
|
|
12790
11215
|
RelativeStack.preset = function(name, callback) {
|
|
12791
11216
|
if(RelativeStack.prototype[name] || RelativeStack[name]) {
|
|
12792
|
-
DebugManager$
|
|
11217
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in RelativeStack.`);
|
|
12793
11218
|
return;
|
|
12794
11219
|
}
|
|
12795
11220
|
RelativeStack[name] = (content, props) => callback(new RelativeStack(content, props));
|
|
@@ -12834,7 +11259,7 @@ var NativeComponents = (function (exports) {
|
|
|
12834
11259
|
|
|
12835
11260
|
Skeleton.preset = function(name, callback) {
|
|
12836
11261
|
if (Skeleton.prototype[name] || Skeleton[name]) {
|
|
12837
|
-
DebugManager$
|
|
11262
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in Skeleton.`);
|
|
12838
11263
|
return;
|
|
12839
11264
|
}
|
|
12840
11265
|
Skeleton[name] = (props) => callback(new Skeleton(props));
|
|
@@ -13198,7 +11623,7 @@ var NativeComponents = (function (exports) {
|
|
|
13198
11623
|
|
|
13199
11624
|
Spinner.preset = function(name, callback) {
|
|
13200
11625
|
if (Spinner.prototype[name] || Spinner[name]) {
|
|
13201
|
-
DebugManager$
|
|
11626
|
+
DebugManager$2.warn(`Warning: the ${name} method already exists in Spinner.`);
|
|
13202
11627
|
return;
|
|
13203
11628
|
}
|
|
13204
11629
|
Spinner[name] = (props) => callback(new Spinner(props));
|
|
@@ -13768,7 +12193,7 @@ var NativeComponents = (function (exports) {
|
|
|
13768
12193
|
|
|
13769
12194
|
Stepper.preset = function(name, callback) {
|
|
13770
12195
|
if (Stepper.prototype[name] || Stepper[name]) {
|
|
13771
|
-
DebugManager$
|
|
12196
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Stepper.`);
|
|
13772
12197
|
return;
|
|
13773
12198
|
}
|
|
13774
12199
|
Stepper[name] = (props) => callback(new Stepper(props));
|
|
@@ -14721,7 +13146,7 @@ var NativeComponents = (function (exports) {
|
|
|
14721
13146
|
|
|
14722
13147
|
DataTable.prototype.selectedRows = function($obs) {
|
|
14723
13148
|
if(!$obs.__$isObservableArray) {
|
|
14724
|
-
DebugManager$
|
|
13149
|
+
DebugManager$2.warn('Database', 'selectedRow should take an Observable array');
|
|
14725
13150
|
}
|
|
14726
13151
|
this.$description.$selectedRows = $obs;
|
|
14727
13152
|
return this;
|
|
@@ -15268,7 +13693,7 @@ var NativeComponents = (function (exports) {
|
|
|
15268
13693
|
|
|
15269
13694
|
Tooltip.preset = function(name, callback) {
|
|
15270
13695
|
if (Tooltip.prototype[name] || Tooltip[name]) {
|
|
15271
|
-
DebugManager$
|
|
13696
|
+
DebugManager$2.warn(`Warning: the ${name} method already exist in Tooltip.`);
|
|
15272
13697
|
return;
|
|
15273
13698
|
}
|
|
15274
13699
|
Tooltip[name] = (content, props) => callback(new Tooltip(content, props));
|