native-document 1.0.149 → 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 +1120 -2738
- package/dist/native-document.dev.js +5148 -5191
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.min.js +1 -1
- package/elements.js +1 -4
- package/index.js +0 -4
- 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/core/elements/fragment.js +8 -0
- package/src/core/elements/index.js +1 -9
- package/src/core/utils/prototypes.js +0 -46
- package/src/i18n/service/I18nService.js +1 -1
- package/src/i18n/service/functions.js +1 -1
- package/src/ui/components/accordion/AccordionRender.js +1 -0
- package/src/ui/components/alert/AlertRender.js +2 -1
- package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +1 -0
- package/src/ui/components/badge/BadgeRender.js +1 -0
- package/src/ui/components/breadcrumb/BreadcrumbRender.js +1 -0
- package/src/ui/components/contextmenu/ContextmenuRender.js +0 -2
- package/src/ui/components/dropdown/DropdownRender.js +1 -1
- package/src/ui/components/form/FieldCollectionRender.js +1 -1
- package/src/ui/components/form/FormControlRender.js +2 -1
- package/src/ui/components/form/fields/AutocompleteFieldRender.js +3 -3
- package/src/ui/components/form/fields/CheckboxFieldRender.js +1 -1
- package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +1 -1
- package/src/ui/components/form/fields/DateFieldRender.js +2 -1
- package/src/ui/components/form/fields/FieldRender.js +2 -1
- package/src/ui/components/form/fields/HiddenFieldRender.js +0 -1
- package/src/ui/components/form/fields/PasswordFieldRender.js +1 -1
- package/src/ui/components/form/fields/RadioFieldRender.js +1 -1
- package/src/ui/components/form/fields/RangeFieldRender.js +1 -0
- package/src/ui/components/form/fields/SelectFieldRender.js +2 -2
- package/src/ui/components/form/fields/SliderFieldRender.js +2 -2
- package/src/ui/components/form/fields/TimeFieldRender.js +1 -0
- package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +2 -2
- package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +2 -2
- package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +1 -2
- package/src/ui/components/menu/MenuGroupRender.js +0 -1
- package/src/ui/components/menu/MenuItemRender.js +1 -1
- package/src/ui/components/menu/MenuLinkRender.js +1 -1
- package/src/ui/components/menu/MenuRender.js +1 -0
- package/src/ui/components/modal/ModalRender.js +1 -2
- package/src/ui/components/pagination/PaginationRender.js +2 -2
- package/src/ui/components/popover/PopoverRender.js +1 -2
- package/src/ui/components/skeleton/SkeletonRender.js +1 -0
- package/src/ui/components/spinner/SpinnerRender.js +2 -1
- package/src/ui/components/splitter/SplitterRender.js +1 -0
- package/src/ui/components/stacks/PositionStackRender.js +1 -0
- package/src/ui/components/stacks/StackRender.js +0 -1
- package/src/ui/components/stacks/v-stack/VStackRender.js +1 -0
- package/src/ui/components/stepper/StepperRender.js +2 -1
- package/src/ui/components/stepper/StepperStepRender.js +1 -1
- package/src/ui/components/switch/SwitchRender.js +1 -0
- package/src/ui/components/table/data-table/DataTableRender.js +2 -1
- package/src/ui/components/table/data-table/bulk-actions.js +1 -2
- package/src/ui/components/table/data-table/pagination.js +1 -1
- package/src/ui/components/table/data-table/tables.js +1 -1
- package/src/ui/components/table/simple-table/SimpleTableRender.js +3 -2
- package/src/ui/components/tabs/TabsRender.js +1 -1
- package/src/ui/components/toast/ToastRender.js +2 -1
- package/src/ui/theme.js +0 -6
- package/src/ui/theme.scss +1 -0
|
@@ -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,2704 +1693,1099 @@ 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
|
-
|
|
2196
|
-
NodeCloner.prototype.cloneNode = function(data) {
|
|
2197
|
-
return this.$element.cloneNode(false);
|
|
2198
|
-
};
|
|
2199
1879
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
1880
|
+
anchorFragment.removeWithAnchors = function() {
|
|
1881
|
+
anchorFragment.removeChildren();
|
|
1882
|
+
anchorStart.remove();
|
|
1883
|
+
anchorEnd.remove();
|
|
1884
|
+
};
|
|
1885
|
+
anchorFragment.delete = anchorFragment.removeWithAnchors;
|
|
2205
1886
|
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
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
|
-
};
|
|
2215
|
-
|
|
2216
|
-
NodeCloner.prototype.attr = function(attrName, value) {
|
|
2217
|
-
if(attrName === 'class') {
|
|
2218
|
-
this.$classes = this.$classes || {};
|
|
2219
|
-
this.$classes[value.property] = value.value;
|
|
2220
|
-
return this;
|
|
2221
|
-
}
|
|
2222
|
-
if(attrName === 'style') {
|
|
2223
|
-
this.$styles = this.$styles || {};
|
|
2224
|
-
this.$styles[value.property] = value.value;
|
|
2225
|
-
return this;
|
|
2226
|
-
}
|
|
2227
|
-
this.$attrs = this.$attrs || {};
|
|
2228
|
-
this.$attrs[attrName] = value.value;
|
|
2229
|
-
return this;
|
|
2230
|
-
};
|
|
2231
|
-
|
|
2232
|
-
DocumentFragment.prototype.__IS_FRAGMENT = true;
|
|
2233
|
-
|
|
2234
|
-
Function.prototype.args = function(...args) {
|
|
2235
|
-
return withValidation(this);
|
|
2236
|
-
};
|
|
2237
|
-
|
|
2238
|
-
Function.prototype.cached = function(...args) {
|
|
2239
|
-
let $cache;
|
|
2240
|
-
let getCache = () => $cache;
|
|
2241
|
-
return () => {
|
|
2242
|
-
if(!$cache) {
|
|
2243
|
-
$cache = this.apply(this, args);
|
|
2244
|
-
if($cache.cloneNode) {
|
|
2245
|
-
getCache = () => $cache.cloneNode(true);
|
|
2246
|
-
} else if($cache.$element) {
|
|
2247
|
-
getCache = () => new NDElement($cache.$element.cloneNode(true));
|
|
2248
|
-
}
|
|
2249
|
-
}
|
|
2250
|
-
return getCache();
|
|
1887
|
+
anchorFragment.replaceContent = function(child) {
|
|
1888
|
+
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
1889
|
+
anchorFragment.replaceContentRaw(childElement);
|
|
2251
1890
|
};
|
|
2252
|
-
};
|
|
2253
1891
|
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
return
|
|
2258
|
-
}
|
|
2259
|
-
|
|
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;
|
|
2260
1900
|
}
|
|
1901
|
+
anchorFragment.removeChildren();
|
|
1902
|
+
parent.insertBefore(child, anchorEnd);
|
|
2261
1903
|
};
|
|
2262
|
-
return handler;
|
|
2263
|
-
};
|
|
2264
|
-
|
|
2265
|
-
String.prototype.use = function(args) {
|
|
2266
|
-
const value = this;
|
|
2267
|
-
|
|
2268
|
-
return Observable.computed(() => {
|
|
2269
|
-
return value.replace(/\$\{(.*?)}/g, (match, key) => {
|
|
2270
|
-
const data = args[key];
|
|
2271
|
-
if(Validator.isObservable(data)) {
|
|
2272
|
-
return data.val();
|
|
2273
|
-
}
|
|
2274
|
-
return data;
|
|
2275
|
-
});
|
|
2276
|
-
}, Object.values(args));
|
|
2277
|
-
};
|
|
2278
1904
|
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
return this.valueOf();
|
|
2282
|
-
}
|
|
2283
|
-
return this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map((value) => {
|
|
2284
|
-
if(!Validator.containsObservableReference(value)) {
|
|
2285
|
-
return value;
|
|
2286
|
-
}
|
|
2287
|
-
const [_, id] = value.match(/\{\{#ObItem::\(([0-9]+)\)\}\}/);
|
|
2288
|
-
return Observable.getById(id);
|
|
2289
|
-
});
|
|
2290
|
-
};
|
|
1905
|
+
anchorFragment.setContent = anchorFragment.replaceContent;
|
|
1906
|
+
anchorFragment.setContentRaw = anchorFragment.replaceContentRaw;
|
|
2291
1907
|
|
|
2292
|
-
|
|
2293
|
-
|
|
1908
|
+
anchorFragment.insertBefore = anchorFragment.appendChild;
|
|
1909
|
+
anchorFragment.insertBeforeRaw = anchorFragment.appendChildRaw;
|
|
2294
1910
|
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
if(Array.isArray(data)) {
|
|
2298
|
-
data.push(key+': '+value);
|
|
2299
|
-
return;
|
|
2300
|
-
}
|
|
2301
|
-
if(Validator.isObject(key)) {
|
|
2302
|
-
value = key;
|
|
2303
|
-
for(const property in value) {
|
|
2304
|
-
data[property] = value[property];
|
|
2305
|
-
}
|
|
2306
|
-
return;
|
|
2307
|
-
}
|
|
2308
|
-
data[key] = value;
|
|
2309
|
-
},
|
|
2310
|
-
value() {
|
|
2311
|
-
if(Array.isArray(data)) {
|
|
2312
|
-
return data.join(';').concat(';');
|
|
2313
|
-
}
|
|
2314
|
-
return { ...data };
|
|
2315
|
-
},
|
|
1911
|
+
anchorFragment.endElement = function() {
|
|
1912
|
+
return anchorEnd;
|
|
2316
1913
|
};
|
|
2317
|
-
};
|
|
2318
|
-
|
|
2319
|
-
const classPropertyAccumulator = function(initialValue = []) {
|
|
2320
|
-
let data = Validator.isString(initialValue) ? initialValue.split(" ").filter(Boolean) : initialValue;
|
|
2321
1914
|
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
if(Validator.isJson(key)) {
|
|
2325
|
-
for(const property in key) {
|
|
2326
|
-
if(key[property]) {
|
|
2327
|
-
data[property] = key[property];
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
return;
|
|
2331
|
-
}
|
|
2332
|
-
if(value != null || key.__$Observable) {
|
|
2333
|
-
if(Array.isArray(data)) {
|
|
2334
|
-
data = data.reduce((acc, item) => {
|
|
2335
|
-
acc[item] = true;
|
|
2336
|
-
return acc;
|
|
2337
|
-
}, {});
|
|
2338
|
-
}
|
|
2339
|
-
if(key.__$Observable) {
|
|
2340
|
-
const uniqueId = `obs-${Math.random().toString(36).substr(2, 9)}`;
|
|
2341
|
-
data[uniqueId] = key;
|
|
2342
|
-
}
|
|
2343
|
-
else {
|
|
2344
|
-
data[key] = value;
|
|
2345
|
-
}
|
|
2346
|
-
return;
|
|
2347
|
-
}
|
|
2348
|
-
if(Array.isArray(data)) {
|
|
2349
|
-
data.push(key);
|
|
2350
|
-
return;
|
|
2351
|
-
}
|
|
2352
|
-
data[key] = value;
|
|
2353
|
-
},
|
|
2354
|
-
value() {
|
|
2355
|
-
if(Array.isArray(data)) {
|
|
2356
|
-
return data.join(' ');
|
|
2357
|
-
}
|
|
2358
|
-
return { ...data };
|
|
2359
|
-
},
|
|
1915
|
+
anchorFragment.startElement = function() {
|
|
1916
|
+
return anchorStart;
|
|
2360
1917
|
};
|
|
2361
|
-
};
|
|
2362
|
-
|
|
2363
|
-
const mutationMethods = ['push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice'];
|
|
2364
|
-
const noMutationMethods = ['map', 'forEach', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat', 'includes', 'indexOf'];
|
|
2365
|
-
|
|
2366
|
-
/**
|
|
2367
|
-
*
|
|
2368
|
-
* @param target
|
|
2369
|
-
* @param {{propagation: boolean, deep: boolean, reset: boolean}|null} configs
|
|
2370
|
-
* @constructor
|
|
2371
|
-
*/
|
|
2372
|
-
const ObservableArray = function (target, configs = null) {
|
|
2373
|
-
if(!Array.isArray(target)) {
|
|
2374
|
-
throw new NativeDocumentError('Observable.array : target must be an array');
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
|
-
ObservableItem.call(this, target, configs);
|
|
2378
|
-
};
|
|
2379
|
-
|
|
2380
|
-
ObservableArray.prototype = Object.create(ObservableItem.prototype);
|
|
2381
|
-
ObservableArray.prototype.constructor = ObservableArray;
|
|
2382
|
-
ObservableArray.prototype.__$isObservableArray = true;
|
|
2383
|
-
|
|
2384
1918
|
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
}
|
|
2389
|
-
});
|
|
1919
|
+
anchorFragment.restore = function() {
|
|
1920
|
+
anchorFragment.appendChild(anchorFragment);
|
|
1921
|
+
};
|
|
2390
1922
|
|
|
1923
|
+
anchorFragment.clear = anchorFragment.remove;
|
|
1924
|
+
anchorFragment.detach = anchorFragment.remove;
|
|
2391
1925
|
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
1926
|
+
anchorFragment.getByIndex = function(index) {
|
|
1927
|
+
let currentNode = anchorStart;
|
|
1928
|
+
for(let i = 0; i <= index; i++) {
|
|
1929
|
+
if(!currentNode.nextSibling) {
|
|
1930
|
+
return null;
|
|
1931
|
+
}
|
|
1932
|
+
currentNode = currentNode.nextSibling;
|
|
2397
1933
|
}
|
|
2398
|
-
|
|
2399
|
-
mutateFn(args);
|
|
2400
|
-
};
|
|
2401
|
-
|
|
2402
|
-
mutationMethods.forEach((method) => {
|
|
2403
|
-
ObservableArray.prototype[method] = function(...values) {
|
|
2404
|
-
return this.$mutate(method, values, (argsToUse) => {
|
|
2405
|
-
const result = this.$currentValue[method].apply(this.$currentValue, argsToUse);
|
|
2406
|
-
this.trigger({ action: method, args: argsToUse, result });
|
|
2407
|
-
return result;
|
|
2408
|
-
})
|
|
1934
|
+
return currentNode !== anchorStart ? currentNode : null;
|
|
2409
1935
|
};
|
|
2410
|
-
});
|
|
2411
1936
|
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
};
|
|
2416
|
-
});
|
|
1937
|
+
return anchorFragment;
|
|
1938
|
+
}
|
|
1939
|
+
DocumentFragment.prototype.setAttribute = () => {};
|
|
2417
1940
|
|
|
1941
|
+
function NDElement(element) {
|
|
1942
|
+
this.$element = element;
|
|
1943
|
+
this.$attachements = null;
|
|
1944
|
+
}
|
|
2418
1945
|
|
|
2419
|
-
|
|
1946
|
+
NDElement.prototype.__$isNDElement = true;
|
|
2420
1947
|
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
* @returns {boolean} True if array was cleared, false if it was already empty
|
|
2425
|
-
* @example
|
|
2426
|
-
* const items = Observable.array([1, 2, 3]);
|
|
2427
|
-
* items.clear(); // []
|
|
2428
|
-
*/
|
|
2429
|
-
ObservableArray.prototype.clear = function() {
|
|
2430
|
-
if(this.$currentValue.length === 0) {
|
|
2431
|
-
return;
|
|
1948
|
+
NDElement.prototype.ghostDom = function(element) {
|
|
1949
|
+
if(!this.$attachements) {
|
|
1950
|
+
this.$attachements = document.createDocumentFragment();
|
|
2432
1951
|
}
|
|
2433
|
-
this.$
|
|
2434
|
-
|
|
2435
|
-
this.trigger($clearEvent);
|
|
2436
|
-
});
|
|
2437
|
-
return true;
|
|
1952
|
+
this.$attachements.appendChild(ElementCreator.getChild(element));
|
|
1953
|
+
return this;
|
|
2438
1954
|
};
|
|
2439
1955
|
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
*
|
|
2443
|
-
* @param {number} index - Zero-based index of the element to retrieve
|
|
2444
|
-
* @returns {*} The element at the specified index
|
|
2445
|
-
* @example
|
|
2446
|
-
* const items = Observable.array(['a', 'b', 'c']);
|
|
2447
|
-
* items.at(1); // 'b'
|
|
2448
|
-
*/
|
|
2449
|
-
ObservableArray.prototype.at = function(index) {
|
|
2450
|
-
return this.$currentValue[index];
|
|
1956
|
+
NDElement.prototype.valueOf = function() {
|
|
1957
|
+
return this.$element;
|
|
2451
1958
|
};
|
|
2452
1959
|
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
* Similar to push but with a different operation name.
|
|
2457
|
-
*
|
|
2458
|
-
* @param {Array} values - Array of values to merge
|
|
2459
|
-
* @example
|
|
2460
|
-
* const items = Observable.array([1, 2]);
|
|
2461
|
-
* items.merge([3, 4]); // [1, 2, 3, 4]
|
|
2462
|
-
*/
|
|
2463
|
-
ObservableArray.prototype.merge = function(values) {
|
|
2464
|
-
this.$mutate('merge', values, (valuesToMerge) => {
|
|
2465
|
-
this.$currentValue.push.apply(this.$currentValue, valuesToMerge);
|
|
2466
|
-
this.trigger({ action: 'merge', args: valuesToMerge });
|
|
2467
|
-
});
|
|
1960
|
+
NDElement.prototype.ref = function(target, name) {
|
|
1961
|
+
target[name] = this.$element;
|
|
1962
|
+
return this;
|
|
2468
1963
|
};
|
|
2469
1964
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
* @example
|
|
2476
|
-
* const numbers = Observable.array([1, 2, 3, 4, 5]);
|
|
2477
|
-
* numbers.count(n => n > 3); // 2
|
|
2478
|
-
*/
|
|
2479
|
-
ObservableArray.prototype.count = function(condition) {
|
|
2480
|
-
let count = 0;
|
|
2481
|
-
this.$currentValue.forEach((item, index) => {
|
|
2482
|
-
if(condition(item, index)) {
|
|
2483
|
-
count++;
|
|
2484
|
-
}
|
|
2485
|
-
});
|
|
2486
|
-
return count;
|
|
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;
|
|
2487
1970
|
};
|
|
2488
1971
|
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
* @example
|
|
2496
|
-
* const items = Observable.array(['a', 'b', 'c']);
|
|
2497
|
-
* items.swap(0, 2); // ['c', 'b', 'a']
|
|
2498
|
-
*/
|
|
2499
|
-
ObservableArray.prototype.swap = function(indexA, indexB) {
|
|
2500
|
-
this.$mutate('swap', [indexA, indexB], ([indexA, indexB]) => {
|
|
2501
|
-
const value = this.$currentValue;
|
|
2502
|
-
const length = value.length;
|
|
2503
|
-
if(indexB < indexA) {
|
|
2504
|
-
const temp = indexA;
|
|
2505
|
-
indexA = indexB;
|
|
2506
|
-
indexB = temp;
|
|
2507
|
-
}
|
|
2508
|
-
if(length < indexA || length < indexB) {
|
|
2509
|
-
return false;
|
|
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();
|
|
2510
1978
|
}
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
value[indexB] = elementA;
|
|
2516
|
-
this.trigger({ action: 'swap', args: [indexA, indexB], result: [elementA, elementB] });
|
|
2517
|
-
});
|
|
2518
|
-
return true;
|
|
1979
|
+
elementChildren = null;
|
|
1980
|
+
}
|
|
1981
|
+
element = null;
|
|
1982
|
+
return this;
|
|
2519
1983
|
};
|
|
2520
1984
|
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
1985
|
+
NDElement.prototype.remove = function() {
|
|
1986
|
+
let element = this.$element;
|
|
1987
|
+
element.nd.unmountChildren();
|
|
1988
|
+
element.$ndProx = null;
|
|
2524
1989
|
|
|
2525
|
-
|
|
2526
|
-
};
|
|
1990
|
+
$lifeCycleObservers.delete(element);
|
|
2527
1991
|
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
return this.splice(targetIndex + 1, 0, data);
|
|
1992
|
+
element = null;
|
|
1993
|
+
return this;
|
|
2531
1994
|
};
|
|
2532
1995
|
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
* items.remove(1); // ['b'] - Array is now ['a', 'c']
|
|
2541
|
-
*/
|
|
2542
|
-
ObservableArray.prototype.remove = function(index) {
|
|
2543
|
-
let deleted = [];
|
|
2544
|
-
this.$mutate('remove', [index], ([idx]) => {
|
|
2545
|
-
deleted = this.$currentValue.splice(idx, 1);
|
|
2546
|
-
if(deleted.length === 0) {
|
|
2547
|
-
return;
|
|
2548
|
-
}
|
|
2549
|
-
this.trigger({action: 'remove', args: [idx], result: deleted[0]});
|
|
2550
|
-
});
|
|
2551
|
-
return deleted;
|
|
2552
|
-
};
|
|
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);
|
|
2553
2003
|
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
* items.removeItem('b'); // ['b'] - Array is now ['a', 'c']
|
|
2562
|
-
*/
|
|
2563
|
-
ObservableArray.prototype.removeItem = function(item) {
|
|
2564
|
-
const indexOfItem = this.$currentValue.indexOf(item);
|
|
2565
|
-
if(indexOfItem === -1) {
|
|
2566
|
-
return [];
|
|
2004
|
+
if(states.mounted) {
|
|
2005
|
+
this.$element.setAttribute('data--nd-mounted', '1');
|
|
2006
|
+
observer.mounted(states.mounted);
|
|
2007
|
+
}
|
|
2008
|
+
if(states.unmounted) {
|
|
2009
|
+
this.$element.setAttribute('data--nd-unmounted', '1');
|
|
2010
|
+
observer.unmounted(states.unmounted);
|
|
2567
2011
|
}
|
|
2568
|
-
return this
|
|
2012
|
+
return this;
|
|
2569
2013
|
};
|
|
2570
2014
|
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
*
|
|
2574
|
-
* @returns {boolean} True if array has no elements
|
|
2575
|
-
* @example
|
|
2576
|
-
* const items = Observable.array([]);
|
|
2577
|
-
* items.isEmpty(); // true
|
|
2578
|
-
*/
|
|
2579
|
-
ObservableArray.prototype.empty = function() {
|
|
2580
|
-
return this.$currentValue.length === 0;
|
|
2015
|
+
NDElement.prototype.mounted = function(callback) {
|
|
2016
|
+
return this.lifecycle({ mounted: callback });
|
|
2581
2017
|
};
|
|
2582
2018
|
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
* Used internally for rendering optimizations.
|
|
2586
|
-
*
|
|
2587
|
-
* @param {number} iteration - Iteration count for rendering
|
|
2588
|
-
* @param {Function} callback - Callback function for rendering items
|
|
2589
|
-
*/
|
|
2590
|
-
ObservableArray.prototype.populateAndRender = function(iteration, callback) {
|
|
2591
|
-
this.trigger({ action: 'populate', args: [this.$currentValue, iteration, callback] });
|
|
2019
|
+
NDElement.prototype.unmounted = function(callback) {
|
|
2020
|
+
return this.lifecycle({ unmounted: callback });
|
|
2592
2021
|
};
|
|
2593
2022
|
|
|
2023
|
+
NDElement.prototype.beforeUnmount = function(id, callback) {
|
|
2024
|
+
const el = this.$element;
|
|
2594
2025
|
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
*
|
|
2599
|
-
* @param {Object} predicates - Object mapping property names to filter conditions or functions
|
|
2600
|
-
* @returns {ObservableArray} A new observable array containing filtered items
|
|
2601
|
-
* @example
|
|
2602
|
-
* const users = Observable.array([
|
|
2603
|
-
* { name: 'John', age: 25 },
|
|
2604
|
-
* { name: 'Jane', age: 30 }
|
|
2605
|
-
* ]);
|
|
2606
|
-
*
|
|
2607
|
-
* const adults = users.where({ age: (val) => val >= 18 });
|
|
2608
|
-
*/
|
|
2609
|
-
ObservableArray.prototype.where = function(predicates) {
|
|
2610
|
-
if(typeof predicates === 'function') {
|
|
2611
|
-
predicates = { _: predicates };
|
|
2612
|
-
}
|
|
2613
|
-
const sourceArray = this;
|
|
2614
|
-
const observableDependencies = [sourceArray];
|
|
2615
|
-
const filterCallbacks = {};
|
|
2616
|
-
|
|
2617
|
-
for (const [key, rawPredicate] of Object.entries(predicates)) {
|
|
2618
|
-
const predicate = Validator.isObservable(rawPredicate) ? match(rawPredicate, false) : rawPredicate;
|
|
2619
|
-
if (predicate && typeof predicate === 'object' && 'callback' in predicate) {
|
|
2620
|
-
filterCallbacks[key] = predicate.callback;
|
|
2621
|
-
|
|
2622
|
-
if (predicate.dependencies) {
|
|
2623
|
-
const deps = Array.isArray(predicate.dependencies)
|
|
2624
|
-
? predicate.dependencies
|
|
2625
|
-
: [predicate.dependencies];
|
|
2626
|
-
observableDependencies.push.apply(observableDependencies, deps);
|
|
2627
|
-
}
|
|
2628
|
-
} else if(typeof predicate === 'function') {
|
|
2629
|
-
filterCallbacks[key] = predicate;
|
|
2630
|
-
} else {
|
|
2631
|
-
filterCallbacks[key] = (value) => value === predicate;
|
|
2632
|
-
}
|
|
2633
|
-
}
|
|
2026
|
+
if(!DocumentObserver.beforeUnmount.has(el)) {
|
|
2027
|
+
DocumentObserver.beforeUnmount.set(el, new Map());
|
|
2028
|
+
const originalRemove = el.remove.bind(el);
|
|
2634
2029
|
|
|
2635
|
-
|
|
2030
|
+
let $isUnmounting = false;
|
|
2636
2031
|
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
for (const [key, callback] of filters) {
|
|
2641
|
-
if(key === '_') {
|
|
2642
|
-
if (!callback(item)) return false;
|
|
2643
|
-
} else {
|
|
2644
|
-
if (!callback(item[key])) return false;
|
|
2645
|
-
}
|
|
2032
|
+
el.remove = async () => {
|
|
2033
|
+
if($isUnmounting) {
|
|
2034
|
+
return;
|
|
2646
2035
|
}
|
|
2647
|
-
|
|
2648
|
-
});
|
|
2649
|
-
|
|
2650
|
-
viewArray.set(filtered);
|
|
2651
|
-
};
|
|
2652
|
-
|
|
2653
|
-
observableDependencies.forEach(dep => dep.subscribe(updateView));
|
|
2654
|
-
|
|
2655
|
-
updateView();
|
|
2656
|
-
|
|
2657
|
-
return viewArray;
|
|
2658
|
-
};
|
|
2659
|
-
|
|
2660
|
-
/**
|
|
2661
|
-
* Creates a filtered view where at least one of the specified fields matches the filter.
|
|
2662
|
-
*
|
|
2663
|
-
* @param {Array<string>} fields - Array of field names to check
|
|
2664
|
-
* @param {FilterResult} filter - Filter condition with callback and dependencies
|
|
2665
|
-
* @returns {ObservableArray} A new observable array containing filtered items
|
|
2666
|
-
* @example
|
|
2667
|
-
* const products = Observable.array([
|
|
2668
|
-
* { name: 'Apple', category: 'Fruit' },
|
|
2669
|
-
* { name: 'Carrot', category: 'Vegetable' }
|
|
2670
|
-
* ]);
|
|
2671
|
-
* const searchTerm = Observable('App');
|
|
2672
|
-
* const filtered = products.whereSome(['name', 'category'], match(searchTerm));
|
|
2673
|
-
*/
|
|
2674
|
-
ObservableArray.prototype.whereSome = function(fields, filter) {
|
|
2675
|
-
return this.where({
|
|
2676
|
-
_: {
|
|
2677
|
-
dependencies: filter.dependencies,
|
|
2678
|
-
callback: (item) => fields.some(field => filter.callback(item[field]))
|
|
2679
|
-
}
|
|
2680
|
-
});
|
|
2681
|
-
};
|
|
2682
|
-
|
|
2683
|
-
/**
|
|
2684
|
-
* Creates a filtered view where all specified fields match the filter.
|
|
2685
|
-
*
|
|
2686
|
-
* @param {Array<string>} fields - Array of field names to check
|
|
2687
|
-
* @param {FilterResult} filter - Filter condition with callback and dependencies
|
|
2688
|
-
* @returns {ObservableArray} A new observable array containing filtered items
|
|
2689
|
-
* @example
|
|
2690
|
-
* const items = Observable.array([
|
|
2691
|
-
* { status: 'active', verified: true },
|
|
2692
|
-
* { status: 'active', verified: false }
|
|
2693
|
-
* ]);
|
|
2694
|
-
* const activeFilter = equals('active');
|
|
2695
|
-
* const filtered = items.whereEvery(['status', 'verified'], activeFilter);
|
|
2696
|
-
*/
|
|
2697
|
-
ObservableArray.prototype.whereEvery = function(fields, filter) {
|
|
2698
|
-
return this.where({
|
|
2699
|
-
_: {
|
|
2700
|
-
dependencies: filter.dependencies,
|
|
2701
|
-
callback: (item) => fields.every(field => filter.callback(item[field]))
|
|
2702
|
-
}
|
|
2703
|
-
});
|
|
2704
|
-
};
|
|
2705
|
-
|
|
2706
|
-
ObservableArray.prototype.deepSubscribe = function(callback) {
|
|
2707
|
-
const updatedValue = nextTick(() => callback(this.val()));
|
|
2708
|
-
const $listeners = new WeakMap();
|
|
2709
|
-
|
|
2710
|
-
const bindItem = (item) => {
|
|
2711
|
-
if ($listeners.has(item)) {
|
|
2712
|
-
return;
|
|
2713
|
-
}
|
|
2714
|
-
if (item?.__$isObservableArray) {
|
|
2715
|
-
$listeners.set(item, item.deepSubscribe(updatedValue));
|
|
2716
|
-
return;
|
|
2717
|
-
}
|
|
2718
|
-
if (item?.__$isObservable) {
|
|
2719
|
-
item.subscribe(updatedValue);
|
|
2720
|
-
$listeners.set(item, () => item.unsubscribe(updatedValue));
|
|
2721
|
-
}
|
|
2722
|
-
};
|
|
2723
|
-
|
|
2724
|
-
const unbindItem = (item) => {
|
|
2725
|
-
const unsub = $listeners.get(item);
|
|
2726
|
-
if (unsub) {
|
|
2727
|
-
unsub();
|
|
2728
|
-
$listeners.delete(item);
|
|
2729
|
-
}
|
|
2730
|
-
};
|
|
2731
|
-
|
|
2732
|
-
this.$currentValue.forEach(bindItem);
|
|
2733
|
-
this.subscribe(updatedValue);
|
|
2734
|
-
|
|
2735
|
-
this.subscribe((items, _, operations) => {
|
|
2736
|
-
switch (operations?.action) {
|
|
2737
|
-
case 'push':
|
|
2738
|
-
case 'unshift':
|
|
2739
|
-
operations.args.forEach(bindItem);
|
|
2740
|
-
break;
|
|
2036
|
+
$isUnmounting = true;
|
|
2741
2037
|
|
|
2742
|
-
|
|
2743
|
-
const
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
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;
|
|
2747
2046
|
}
|
|
2047
|
+
};
|
|
2048
|
+
}
|
|
2748
2049
|
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
case 'merge':
|
|
2754
|
-
operations.args.forEach(bindItem);
|
|
2755
|
-
break;
|
|
2756
|
-
|
|
2757
|
-
case 'clear':
|
|
2758
|
-
this.$currentValue.forEach(unbindItem);
|
|
2759
|
-
break;
|
|
2760
|
-
}
|
|
2761
|
-
});
|
|
2050
|
+
DocumentObserver.beforeUnmount.get(el).set(id, callback);
|
|
2051
|
+
return this;
|
|
2052
|
+
};
|
|
2762
2053
|
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
};
|
|
2054
|
+
NDElement.prototype.htmlElement = function() {
|
|
2055
|
+
return this.$element;
|
|
2766
2056
|
};
|
|
2767
2057
|
|
|
2058
|
+
NDElement.prototype.node = NDElement.prototype.htmlElement;
|
|
2768
2059
|
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
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);
|
|
2772
2068
|
}
|
|
2069
|
+
$element.append = shadowRoot.append.bind(shadowRoot);
|
|
2070
|
+
$element.appendChild = shadowRoot.appendChild.bind(shadowRoot);
|
|
2071
|
+
shadowRoot.append(...children);
|
|
2773
2072
|
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
const sync = (currentValue, _, operations) => {
|
|
2777
|
-
if (!operations) {
|
|
2778
|
-
targetObservable.set([...currentValue]);
|
|
2779
|
-
return;
|
|
2780
|
-
}
|
|
2781
|
-
|
|
2782
|
-
const { action, args } = operations;
|
|
2783
|
-
targetObservable[action].apply(targetObservable, args);
|
|
2784
|
-
};
|
|
2785
|
-
this.subscribe(sync);
|
|
2786
|
-
|
|
2787
|
-
return () => this.unsubscribe(sync);
|
|
2073
|
+
return this;
|
|
2788
2074
|
};
|
|
2789
2075
|
|
|
2790
|
-
|
|
2791
|
-
return
|
|
2076
|
+
NDElement.prototype.openShadow = function(style = null) {
|
|
2077
|
+
return this.shadow('open', style);
|
|
2792
2078
|
};
|
|
2793
2079
|
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
* All mutations trigger updates automatically.
|
|
2797
|
-
*
|
|
2798
|
-
* @param {Array} [target=[]] - Initial array value
|
|
2799
|
-
* @param {Object|null} [configs=null] - Configuration options
|
|
2800
|
-
* // @param {boolean} [configs.propagation=true] - Whether to propagate changes to parent observables
|
|
2801
|
-
* // @param {boolean} [configs.deep=false] - Whether to make nested objects observable
|
|
2802
|
-
* @param {boolean} [configs.reset=false] - Whether to store initial value for reset()
|
|
2803
|
-
* @returns {ObservableArray} An observable array with reactive methods
|
|
2804
|
-
* @example
|
|
2805
|
-
* const items = Observable.array([1, 2, 3]);
|
|
2806
|
-
* items.push(4); // Triggers update
|
|
2807
|
-
* items.subscribe((arr) => console.log(arr));
|
|
2808
|
-
*/
|
|
2809
|
-
Observable.array = function(target = [], configs = null) {
|
|
2810
|
-
return new ObservableArray(target, configs);
|
|
2080
|
+
NDElement.prototype.closedShadow = function(style = null) {
|
|
2081
|
+
return this.shadow('closed', style);
|
|
2811
2082
|
};
|
|
2812
2083
|
|
|
2813
2084
|
/**
|
|
2085
|
+
* Extends the current NDElement instance with custom methods.
|
|
2086
|
+
* Methods are bound to the instance and available for chaining.
|
|
2814
2087
|
*
|
|
2815
|
-
* @param {
|
|
2816
|
-
* @returns {
|
|
2088
|
+
* @param {Object} methods - Object containing method definitions
|
|
2089
|
+
* @returns {this} The NDElement instance with added methods for chaining
|
|
2090
|
+
* @example
|
|
2091
|
+
* element.nd.with({
|
|
2092
|
+
* highlight() {
|
|
2093
|
+
* this.$element.style.background = 'yellow';
|
|
2094
|
+
* return this;
|
|
2095
|
+
* }
|
|
2096
|
+
* }).highlight().onClick(() => console.log('Clicked'));
|
|
2817
2097
|
*/
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
if(Validator.isAsyncFunction(callback)) {
|
|
2822
|
-
return (callback(...arguments)).then(() => {
|
|
2823
|
-
$observer.trigger();
|
|
2824
|
-
}).catch(error => { throw error; });
|
|
2825
|
-
}
|
|
2826
|
-
callback(...arguments);
|
|
2827
|
-
$observer.trigger();
|
|
2828
|
-
};
|
|
2829
|
-
batch.$observer = $observer;
|
|
2830
|
-
return batch;
|
|
2831
|
-
};
|
|
2832
|
-
|
|
2833
|
-
const ObservableObject = function(target, configs) {
|
|
2834
|
-
ObservableItem.call(this, target);
|
|
2835
|
-
this.$observables = {};
|
|
2836
|
-
this.configs = configs;
|
|
2837
|
-
|
|
2838
|
-
this.$load(target);
|
|
2839
|
-
|
|
2840
|
-
for(const name in target) {
|
|
2841
|
-
if(!Object.hasOwn(this, name)) {
|
|
2842
|
-
Object.defineProperty(this, name, {
|
|
2843
|
-
get: () => this.$observables[name],
|
|
2844
|
-
set: (value) => this.$observables[name].set(value)
|
|
2845
|
-
});
|
|
2846
|
-
}
|
|
2098
|
+
NDElement.prototype.with = function(methods) {
|
|
2099
|
+
if (!methods || typeof methods !== 'object') {
|
|
2100
|
+
throw new NativeDocumentError('extend() requires an object of methods');
|
|
2847
2101
|
}
|
|
2848
2102
|
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
ObservableObject.prototype = Object.create(ObservableItem.prototype);
|
|
2852
|
-
|
|
2853
|
-
Object.defineProperty(ObservableObject, '$value', {
|
|
2854
|
-
get() {
|
|
2855
|
-
return this.val();
|
|
2856
|
-
},
|
|
2857
|
-
set(value) {
|
|
2858
|
-
this.set(value);
|
|
2859
|
-
}
|
|
2860
|
-
});
|
|
2103
|
+
for (const name in methods) {
|
|
2104
|
+
const method = methods[name];
|
|
2861
2105
|
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
ObservableObject.prototype.$load = function(initialValue) {
|
|
2866
|
-
const configs = this.configs;
|
|
2867
|
-
for(const key in initialValue) {
|
|
2868
|
-
const itemValue = initialValue[key];
|
|
2869
|
-
if(Array.isArray(itemValue)) {
|
|
2870
|
-
if(configs?.deep !== false) {
|
|
2871
|
-
const mappedItemValue = itemValue.map(item => {
|
|
2872
|
-
if(Validator.isJson(item)) {
|
|
2873
|
-
return Observable.json(item, configs);
|
|
2874
|
-
}
|
|
2875
|
-
if(Validator.isArray(item)) {
|
|
2876
|
-
return Observable.array(item, configs);
|
|
2877
|
-
}
|
|
2878
|
-
return Observable(item, configs);
|
|
2879
|
-
});
|
|
2880
|
-
this.$observables[key] = Observable.array(mappedItemValue, configs);
|
|
2881
|
-
continue;
|
|
2882
|
-
}
|
|
2883
|
-
this.$observables[key] = Observable.array(itemValue, configs);
|
|
2884
|
-
continue;
|
|
2885
|
-
}
|
|
2886
|
-
if(Validator.isObservable(itemValue) || Validator.isProxy(itemValue)) {
|
|
2887
|
-
this.$observables[key] = itemValue;
|
|
2106
|
+
if (typeof method !== 'function') {
|
|
2107
|
+
DebugManager$2.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
|
|
2888
2108
|
continue;
|
|
2889
2109
|
}
|
|
2890
|
-
this.$observables[key] = (typeof itemValue === 'object') ? Observable.object(itemValue, configs) : Observable(itemValue, configs);
|
|
2891
|
-
}
|
|
2892
|
-
};
|
|
2893
2110
|
|
|
2894
|
-
|
|
2895
|
-
const result = {};
|
|
2896
|
-
for(const key in this.$observables) {
|
|
2897
|
-
const dataItem = this.$observables[key];
|
|
2898
|
-
if(Validator.isObservable(dataItem)) {
|
|
2899
|
-
let value = dataItem.val();
|
|
2900
|
-
if(Array.isArray(value)) {
|
|
2901
|
-
value = value.map(item => {
|
|
2902
|
-
if(Validator.isObservable(item)) {
|
|
2903
|
-
return item.val();
|
|
2904
|
-
}
|
|
2905
|
-
if(Validator.isProxy(item)) {
|
|
2906
|
-
return item.$value;
|
|
2907
|
-
}
|
|
2908
|
-
return item;
|
|
2909
|
-
});
|
|
2910
|
-
}
|
|
2911
|
-
result[key] = value;
|
|
2912
|
-
} else if(Validator.isProxy(dataItem)) {
|
|
2913
|
-
result[key] = dataItem.$value;
|
|
2914
|
-
} else {
|
|
2915
|
-
result[key] = dataItem;
|
|
2916
|
-
}
|
|
2111
|
+
this[name] = method.bind(this);
|
|
2917
2112
|
}
|
|
2918
|
-
|
|
2113
|
+
|
|
2114
|
+
return this;
|
|
2919
2115
|
};
|
|
2920
|
-
ObservableObject.prototype.$val = ObservableObject.prototype.val;
|
|
2921
2116
|
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2117
|
+
/**
|
|
2118
|
+
* Extends the NDElement prototype with new methods available to all NDElement instances.
|
|
2119
|
+
* Use this to add global methods to all NDElements.
|
|
2120
|
+
*
|
|
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
|
|
2124
|
+
* @example
|
|
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();
|
|
2133
|
+
*/
|
|
2134
|
+
NDElement.extend = function(methods) {
|
|
2135
|
+
if (!methods || typeof methods !== 'object') {
|
|
2136
|
+
throw new NativeDocumentError('NDElement.extend() requires an object of methods');
|
|
2929
2137
|
}
|
|
2930
|
-
return item;
|
|
2931
|
-
};
|
|
2932
|
-
ObservableObject.prototype.$get = ObservableObject.prototype.get;
|
|
2933
2138
|
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2139
|
+
if (Array.isArray(methods)) {
|
|
2140
|
+
throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
|
|
2141
|
+
}
|
|
2937
2142
|
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2143
|
+
const protectedMethods = new Set([
|
|
2144
|
+
'constructor', 'valueOf', '$element', '$observer',
|
|
2145
|
+
'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
|
|
2146
|
+
'lifecycle', 'mounted', 'unmounted', 'unmountChildren'
|
|
2147
|
+
]);
|
|
2942
2148
|
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
targetItem.set(newValue);
|
|
2946
|
-
continue;
|
|
2947
|
-
}
|
|
2948
|
-
const firstElementFromOriginalValue = newValueOrigin.at(0);
|
|
2949
|
-
if(Validator.isObservable(firstElementFromOriginalValue) || Validator.isProxy(firstElementFromOriginalValue)) {
|
|
2950
|
-
const newValues = newValue.map(item => {
|
|
2951
|
-
if(Validator.isProxy(firstElementFromOriginalValue)) {
|
|
2952
|
-
return Observable.init(item, configs);
|
|
2953
|
-
}
|
|
2954
|
-
return Observable(item, configs);
|
|
2955
|
-
});
|
|
2956
|
-
targetItem.set(newValues);
|
|
2957
|
-
continue;
|
|
2958
|
-
}
|
|
2959
|
-
targetItem.set([...newValue]);
|
|
2960
|
-
continue;
|
|
2961
|
-
}
|
|
2962
|
-
if(Validator.isProxy(targetItem)) {
|
|
2963
|
-
targetItem.update(newValue);
|
|
2149
|
+
for (const name in methods) {
|
|
2150
|
+
if (!Object.hasOwn(methods, name)) {
|
|
2964
2151
|
continue;
|
|
2965
2152
|
}
|
|
2966
|
-
this[key] = newValue;
|
|
2967
|
-
}
|
|
2968
|
-
};
|
|
2969
|
-
ObservableObject.prototype.$set = ObservableObject.prototype.set;
|
|
2970
|
-
ObservableObject.prototype.$updateWith = ObservableObject.prototype.set;
|
|
2971
|
-
|
|
2972
|
-
ObservableObject.prototype.observables = function() {
|
|
2973
|
-
return Object.values(this.$observables);
|
|
2974
|
-
};
|
|
2975
|
-
ObservableObject.prototype.$observables = ObservableObject.prototype.observables;
|
|
2976
2153
|
|
|
2977
|
-
|
|
2978
|
-
return Object.keys(this.$observables);
|
|
2979
|
-
};
|
|
2980
|
-
ObservableObject.prototype.$keys = ObservableObject.prototype.keys;
|
|
2981
|
-
ObservableObject.prototype.clone = function() {
|
|
2982
|
-
return Observable.init(this.val(), this.configs);
|
|
2983
|
-
};
|
|
2984
|
-
ObservableObject.prototype.$clone = ObservableObject.prototype.clone;
|
|
2985
|
-
ObservableObject.prototype.reset = function() {
|
|
2986
|
-
for(const key in this.$observables) {
|
|
2987
|
-
this.$observables[key].reset();
|
|
2988
|
-
}
|
|
2989
|
-
};
|
|
2990
|
-
ObservableObject.prototype.originalSubscribe = ObservableObject.prototype.subscribe;
|
|
2991
|
-
ObservableObject.prototype.subscribe = function(callback) {
|
|
2992
|
-
const observables = this.observables();
|
|
2993
|
-
const updatedValue = nextTick(() => this.trigger());
|
|
2154
|
+
const method = methods[name];
|
|
2994
2155
|
|
|
2995
|
-
|
|
2156
|
+
if (typeof method !== 'function') {
|
|
2157
|
+
DebugManager$2.warn('NDElement.extend', `"${name}" is not a function, skipping`);
|
|
2158
|
+
continue;
|
|
2159
|
+
}
|
|
2996
2160
|
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
observable.deepSubscribe(updatedValue);
|
|
3001
|
-
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}"`);
|
|
3002
2164
|
}
|
|
3003
|
-
observable.subscribe(updatedValue);
|
|
3004
|
-
}
|
|
3005
|
-
};
|
|
3006
|
-
ObservableObject.prototype.configs = function() {
|
|
3007
|
-
return this.configs;
|
|
3008
|
-
};
|
|
3009
2165
|
|
|
3010
|
-
|
|
2166
|
+
if (NDElement.prototype[name]) {
|
|
2167
|
+
DebugManager$2.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
|
|
2168
|
+
}
|
|
3011
2169
|
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
};
|
|
2170
|
+
NDElement.prototype[name] = method;
|
|
2171
|
+
}
|
|
3015
2172
|
|
|
3016
|
-
|
|
3017
|
-
*
|
|
3018
|
-
* @param {any[]} data
|
|
3019
|
-
* @return Proxy[]
|
|
3020
|
-
*/
|
|
3021
|
-
Observable.arrayOfObject = function(data) {
|
|
3022
|
-
return data.map(item => Observable.object(item));
|
|
2173
|
+
return NDElement;
|
|
3023
2174
|
};
|
|
3024
2175
|
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
Observable.value = function(data) {
|
|
3031
|
-
if(data?.__$isObservableArray) {
|
|
3032
|
-
const result = [];
|
|
3033
|
-
for(let i = 0, length = data.length; i < length; i++) {
|
|
3034
|
-
const item = data.at(i);
|
|
3035
|
-
result.push(Observable.value(item));
|
|
3036
|
-
}
|
|
3037
|
-
return result;
|
|
3038
|
-
}
|
|
3039
|
-
if(data?.__$Observable) {
|
|
3040
|
-
return data.val();
|
|
3041
|
-
}
|
|
3042
|
-
if(Validator.isProxy(data)) {
|
|
3043
|
-
return data.$value;
|
|
3044
|
-
}
|
|
3045
|
-
return data;
|
|
2176
|
+
const COMMON_NODE_TYPES = {
|
|
2177
|
+
ELEMENT: 1,
|
|
2178
|
+
TEXT: 3,
|
|
2179
|
+
COMMENT: 8,
|
|
2180
|
+
DOCUMENT_FRAGMENT: 11
|
|
3046
2181
|
};
|
|
3047
2182
|
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
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;
|
|
3051
2188
|
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
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];
|
|
3083
2263
|
}
|
|
3084
|
-
dependencies.$observer.subscribe(updatedValue);
|
|
3085
|
-
return observable;
|
|
3086
|
-
}
|
|
3087
2264
|
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
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];
|
|
3094
2271
|
}
|
|
3095
|
-
dependency.subscribe(updatedValue);
|
|
3096
|
-
});
|
|
3097
|
-
|
|
3098
|
-
return observable;
|
|
3099
|
-
};
|
|
3100
2272
|
|
|
3101
|
-
|
|
3102
|
-
|
|
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
|
+
}
|
|
3103
2277
|
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
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) {},
|
|
3107
2304
|
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
2305
|
+
validateEventCallback(callback) {
|
|
2306
|
+
if (typeof callback !== 'function') {
|
|
2307
|
+
throw new NativeDocumentError('Event callback must be a function');
|
|
2308
|
+
}
|
|
3111
2309
|
}
|
|
3112
|
-
return $checker(this, x => x === value);
|
|
3113
2310
|
};
|
|
3114
2311
|
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
return $computed((a, b) => a !== b, [this, value]);
|
|
3118
|
-
}
|
|
3119
|
-
return $checker(this, x => x !== value);
|
|
3120
|
-
};
|
|
2312
|
+
const cssPropertyAccumulator = function(initialValue = {}) {
|
|
2313
|
+
let data = Validator.isString(initialValue) ? initialValue.split(';').filter(Boolean) : initialValue;
|
|
3121
2314
|
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
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
|
+
};
|
|
3127
2337
|
};
|
|
3128
2338
|
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
return $computed((a, b) => a >= b, [this, value]);
|
|
3132
|
-
}
|
|
3133
|
-
return $checker(this, x => x >= value);
|
|
3134
|
-
};
|
|
2339
|
+
const classPropertyAccumulator = function(initialValue = []) {
|
|
2340
|
+
let data = Validator.isString(initialValue) ? initialValue.split(" ").filter(Boolean) : initialValue;
|
|
3135
2341
|
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
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
|
+
};
|
|
3141
2381
|
};
|
|
3142
2382
|
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
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
|
+
}
|
|
3149
2402
|
|
|
3150
|
-
|
|
3151
|
-
if (min.__$Observable && max.__$Observable) {
|
|
3152
|
-
return $computed((x, a, b) => x >= a && x <= b, [this, min, max]);
|
|
3153
|
-
}
|
|
3154
|
-
if (min.__$Observable) {
|
|
3155
|
-
return $computed((x, a) => x >= a && x <= max, [this, min]);
|
|
3156
|
-
}
|
|
3157
|
-
if (max.__$Observable) {
|
|
3158
|
-
return $computed((x, b) => x >= min && x <= b, [this, max]);
|
|
2403
|
+
return DebugManager$2.warn('ShowIf', "ShowIf : condition must be an Observable or boolean / "+comment, condition);
|
|
3159
2404
|
}
|
|
3160
|
-
|
|
3161
|
-
};
|
|
3162
|
-
|
|
3163
|
-
ObservableItem.prototype.isNull = function () {
|
|
3164
|
-
return $checker(this, x => x == null);
|
|
3165
|
-
};
|
|
3166
|
-
|
|
3167
|
-
ObservableItem.prototype.isTruthy = function () {
|
|
3168
|
-
return $checker(this, x => !!x);
|
|
3169
|
-
};
|
|
3170
|
-
|
|
3171
|
-
ObservableItem.prototype.isFalsy = function () {
|
|
3172
|
-
return $checker(this, x => !x);
|
|
3173
|
-
};
|
|
2405
|
+
const element = Anchor('Show if : '+(comment || ''));
|
|
3174
2406
|
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
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
|
+
};
|
|
3181
2418
|
|
|
3182
|
-
|
|
3183
|
-
if (str?.__$Observable) {
|
|
3184
|
-
return $computed((a, b) => String(a).endsWith(b), [this, str]);
|
|
3185
|
-
}
|
|
3186
|
-
return $checker(this, x => String(x).endsWith(str));
|
|
3187
|
-
};
|
|
2419
|
+
const currentValue = condition.val();
|
|
3188
2420
|
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
return $computed((a, b) => new RegExp(b).test(String(a)), [this, regex]);
|
|
2421
|
+
if(currentValue) {
|
|
2422
|
+
element.appendChild(getChildElement());
|
|
3192
2423
|
}
|
|
3193
|
-
return $checker(this, x => regex.test(String(x)));
|
|
3194
|
-
};
|
|
3195
2424
|
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
2425
|
+
condition.subscribe((value) => {
|
|
2426
|
+
if(!!value) {
|
|
2427
|
+
element.appendChild(getChildElement());
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
element.remove();
|
|
2431
|
+
});
|
|
3199
2432
|
|
|
3200
|
-
|
|
3201
|
-
return $checker(this, x => x == null || x === '' || (Array.isArray(x) && x.length !== 0));
|
|
2433
|
+
return element;
|
|
3202
2434
|
};
|
|
3203
2435
|
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
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",
|
|
3223
2500
|
|
|
3224
|
-
|
|
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
|
+
];
|
|
3225
2516
|
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
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
|
+
];
|
|
3232
2540
|
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
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
|
+
];
|
|
3236
2584
|
|
|
3237
|
-
|
|
3238
|
-
|
|
2585
|
+
const property = {
|
|
2586
|
+
configurable: true,
|
|
2587
|
+
get() {
|
|
2588
|
+
return new NDElement(this);
|
|
2589
|
+
}
|
|
3239
2590
|
};
|
|
3240
2591
|
|
|
3241
|
-
|
|
3242
|
-
return $checker(this, x => String(x).toLowerCase());
|
|
3243
|
-
};
|
|
2592
|
+
Object.defineProperty(HTMLElement.prototype, 'nd', property);
|
|
3244
2593
|
|
|
3245
|
-
|
|
3246
|
-
return $checker(this, x => String(x).trim());
|
|
3247
|
-
};
|
|
2594
|
+
Object.defineProperty(DocumentFragment.prototype, 'nd', property);
|
|
3248
2595
|
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
2596
|
+
Object.defineProperty(NDElement.prototype, 'nd', {
|
|
2597
|
+
configurable: true,
|
|
2598
|
+
get: function() {
|
|
2599
|
+
return this;
|
|
2600
|
+
}
|
|
2601
|
+
});
|
|
3252
2602
|
|
|
3253
|
-
ObservableItem.prototype.toLiteral = function (template, placeholder = '${v}') {
|
|
3254
|
-
return $checker(this, x => template.replace(placeholder, x));
|
|
3255
|
-
};
|
|
3256
2603
|
|
|
3257
|
-
ObservableItem.prototype.toFormatted = ObservableItem.prototype.toLiteral;
|
|
3258
2604
|
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
};
|
|
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
|
+
});
|
|
3270
2615
|
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
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
|
+
});
|
|
3274
2627
|
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
if (max.__$Observable) {
|
|
3283
|
-
return $computed((x, b) => Math.min(Math.max(x, min), b), [this, max]);
|
|
3284
|
-
}
|
|
3285
|
-
return $checker(this, x => Math.min(Math.max(x, min), max));
|
|
3286
|
-
};
|
|
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
|
+
});
|
|
3287
2635
|
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
}
|
|
3292
|
-
return $checker(this, x => (total === 0 ? 0 : (x / total) * 100));
|
|
2636
|
+
NDElement.prototype.on = function(name, callback, options) {
|
|
2637
|
+
this.$element.addEventListener(name.toLowerCase(), callback, options);
|
|
2638
|
+
return this;
|
|
3293
2639
|
};
|
|
3294
2640
|
|
|
3295
|
-
const
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
/**
|
|
3301
|
-
* Internal helper — retrieves a store entry or throws if not found.
|
|
3302
|
-
*/
|
|
3303
|
-
const $getStoreOrThrow = (method, name) => {
|
|
3304
|
-
const item = $stores.get(name);
|
|
3305
|
-
if (!item) {
|
|
3306
|
-
DebugManager$2.error('Store', `Store.${method}('${name}') : store not found. Did you call Store.create('${name}') first?`);
|
|
3307
|
-
throw new NativeDocumentError(
|
|
3308
|
-
`Store.${method}('${name}') : store not found.`
|
|
3309
|
-
);
|
|
3310
|
-
}
|
|
3311
|
-
return item;
|
|
2641
|
+
const _prevent = function(element, eventName, callback) {
|
|
2642
|
+
const handler = (event) => {
|
|
2643
|
+
event.preventDefault();
|
|
2644
|
+
callback && callback.call(element, event);
|
|
3312
2645
|
};
|
|
2646
|
+
element.addEventListener(eventName, handler);
|
|
2647
|
+
return this;
|
|
2648
|
+
};
|
|
3313
2649
|
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
const readOnlyError = (method) => () => {
|
|
3319
|
-
DebugManager$2.error('Store', `Store.${context}('${name}') is read-only. '${method}()' is not allowed.`);
|
|
3320
|
-
throw new NativeDocumentError(
|
|
3321
|
-
`Store.${context}('${name}') is read-only.`
|
|
3322
|
-
);
|
|
3323
|
-
};
|
|
3324
|
-
observer.set = readOnlyError('set');
|
|
3325
|
-
observer.toggle = readOnlyError('toggle');
|
|
3326
|
-
observer.reset = readOnlyError('reset');
|
|
2650
|
+
const _stop = function(element, eventName, callback) {
|
|
2651
|
+
const handler = (event) => {
|
|
2652
|
+
event.stopPropagation();
|
|
2653
|
+
callback && callback.call(element, event);
|
|
3327
2654
|
};
|
|
2655
|
+
element.addEventListener(eventName, handler);
|
|
2656
|
+
return this;
|
|
2657
|
+
};
|
|
3328
2658
|
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
return Observable.object(value, options);
|
|
3335
|
-
}
|
|
3336
|
-
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);
|
|
3337
2664
|
};
|
|
2665
|
+
element.addEventListener(eventName, handler);
|
|
2666
|
+
return this;
|
|
2667
|
+
};
|
|
3338
2668
|
|
|
3339
|
-
const $api = {
|
|
3340
|
-
/**
|
|
3341
|
-
* Create a new state and return the observer.
|
|
3342
|
-
* Throws if a store with the same name already exists.
|
|
3343
|
-
*
|
|
3344
|
-
* @param {string} name
|
|
3345
|
-
* @param {*} value
|
|
3346
|
-
* @returns {ObservableItem}
|
|
3347
|
-
*/
|
|
3348
|
-
create(name, value) {
|
|
3349
|
-
if ($stores.has(name)) {
|
|
3350
|
-
DebugManager$2.warn('Store', `Store.create('${name}') : a store with this name already exists. Use Store.get('${name}') to retrieve it.`);
|
|
3351
|
-
throw new NativeDocumentError(
|
|
3352
|
-
`Store.create('${name}') : a store with this name already exists.`
|
|
3353
|
-
);
|
|
3354
|
-
}
|
|
3355
|
-
const observer = $createObservable(value);
|
|
3356
|
-
$stores.set(name, { observer, subscribers: new Set(), resettable: false, composed: false });
|
|
3357
|
-
return observer;
|
|
3358
|
-
},
|
|
3359
2669
|
|
|
3360
|
-
/**
|
|
3361
|
-
* Create a new resettable state and return the observer.
|
|
3362
|
-
* The store can be reset to its initial value via Store.reset(name).
|
|
3363
|
-
* Throws if a store with the same name already exists.
|
|
3364
|
-
*
|
|
3365
|
-
* @param {string} name
|
|
3366
|
-
* @param {*} value
|
|
3367
|
-
* @returns {ObservableItem}
|
|
3368
|
-
*/
|
|
3369
|
-
createResettable(name, value) {
|
|
3370
|
-
if ($stores.has(name)) {
|
|
3371
|
-
DebugManager$2.warn('Store', `Store.createResettable('${name}') : a store with this name already exists.`);
|
|
3372
|
-
throw new NativeDocumentError(
|
|
3373
|
-
`Store.createResettable('${name}') : a store with this name already exists.`
|
|
3374
|
-
);
|
|
3375
|
-
}
|
|
3376
|
-
const observer = $createObservable(value, { reset: true });
|
|
3377
|
-
$stores.set(name, { observer, subscribers: new Set(), resettable: true, composed: false });
|
|
3378
|
-
return observer;
|
|
3379
|
-
},
|
|
3380
2670
|
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
);
|
|
3411
|
-
}
|
|
3412
|
-
if (typeof computation !== 'function') {
|
|
3413
|
-
throw new NativeDocumentError(
|
|
3414
|
-
`Store.createComposed('${name}') : computation must be a function.`
|
|
3415
|
-
);
|
|
3416
|
-
}
|
|
3417
|
-
if (!Array.isArray(dependencies) || dependencies.length === 0) {
|
|
3418
|
-
throw new NativeDocumentError(
|
|
3419
|
-
`Store.createComposed('${name}') : dependencies must be a non-empty array of store names.`
|
|
3420
|
-
);
|
|
3421
|
-
}
|
|
3422
|
-
|
|
3423
|
-
// Resolve dependency observers
|
|
3424
|
-
const depObservers = dependencies.map(depName => {
|
|
3425
|
-
if(typeof depName !== 'string') {
|
|
3426
|
-
return depName;
|
|
3427
|
-
}
|
|
3428
|
-
const depItem = $stores.get(depName);
|
|
3429
|
-
if (!depItem) {
|
|
3430
|
-
DebugManager$2.error('Store', `Store.createComposed('${name}') : dependency '${depName}' not found. Create it first.`);
|
|
3431
|
-
throw new NativeDocumentError(
|
|
3432
|
-
`Store.createComposed('${name}') : dependency store '${depName}' not found.`
|
|
3433
|
-
);
|
|
3434
|
-
}
|
|
3435
|
-
return depItem.observer;
|
|
3436
|
-
});
|
|
3437
|
-
|
|
3438
|
-
// Create computed observable from dependency observers
|
|
3439
|
-
const observer = Observable.computed(computation, depObservers);
|
|
3440
|
-
|
|
3441
|
-
$stores.set(name, { observer, subscribers: new Set(), resettable: false, composed: true });
|
|
3442
|
-
return observer;
|
|
3443
|
-
},
|
|
3444
|
-
|
|
3445
|
-
/**
|
|
3446
|
-
* Returns true if a store with the given name exists.
|
|
3447
|
-
*
|
|
3448
|
-
* @param {string} name
|
|
3449
|
-
* @returns {boolean}
|
|
3450
|
-
*/
|
|
3451
|
-
has(name) {
|
|
3452
|
-
return $stores.has(name);
|
|
3453
|
-
},
|
|
3454
|
-
|
|
3455
|
-
/**
|
|
3456
|
-
* Resets a resettable store to its initial value and notifies all subscribers.
|
|
3457
|
-
* Throws if the store was not created with createResettable().
|
|
3458
|
-
*
|
|
3459
|
-
* @param {string} name
|
|
3460
|
-
*/
|
|
3461
|
-
reset(name) {
|
|
3462
|
-
const item = $getStoreOrThrow('reset', name);
|
|
3463
|
-
if (item.composed) {
|
|
3464
|
-
DebugManager$2.error('Store', `Store.reset('${name}') : composed stores cannot be reset. Their value is derived from dependencies.`);
|
|
3465
|
-
throw new NativeDocumentError(
|
|
3466
|
-
`Store.reset('${name}') : composed stores cannot be reset.`
|
|
3467
|
-
);
|
|
3468
|
-
}
|
|
3469
|
-
if (!item.resettable) {
|
|
3470
|
-
DebugManager$2.error('Store', `Store.reset('${name}') : this store is not resettable. Use Store.createResettable('${name}', value) instead of Store.create().`);
|
|
3471
|
-
throw new NativeDocumentError(
|
|
3472
|
-
`Store.reset('${name}') : this store is not resettable. Use Store.createResettable('${name}', value) instead of Store.create().`
|
|
3473
|
-
);
|
|
3474
|
-
}
|
|
3475
|
-
item.observer.reset();
|
|
3476
|
-
},
|
|
3477
|
-
|
|
3478
|
-
/**
|
|
3479
|
-
* Returns a two-way synchronized follower of the store.
|
|
3480
|
-
* Writing to the follower propagates the value back to the store and all its subscribers.
|
|
3481
|
-
* Throws if called on a composed store — use Store.follow() instead.
|
|
3482
|
-
* Call follower.destroy() or follower.dispose() to unsubscribe.
|
|
3483
|
-
*
|
|
3484
|
-
* @param {string} name
|
|
3485
|
-
* @returns {ObservableItem}
|
|
3486
|
-
*/
|
|
3487
|
-
use(name) {
|
|
3488
|
-
const item = $getStoreOrThrow('use', name);
|
|
3489
|
-
|
|
3490
|
-
if (item.composed) {
|
|
3491
|
-
DebugManager$2.error('Store', `Store.use('${name}') : composed stores are read-only. Use Store.follow('${name}') instead.`);
|
|
3492
|
-
throw new NativeDocumentError(
|
|
3493
|
-
`Store.use('${name}') : composed stores are read-only. Use Store.follow('${name}') instead.`
|
|
3494
|
-
);
|
|
3495
|
-
}
|
|
3496
|
-
|
|
3497
|
-
const { observer: originalObserver, subscribers } = item;
|
|
3498
|
-
const observerFollower = $createObservable(originalObserver.val());
|
|
3499
|
-
|
|
3500
|
-
const onStoreChange = value => observerFollower.set(value);
|
|
3501
|
-
const onFollowerChange = value => originalObserver.set(value);
|
|
3502
|
-
|
|
3503
|
-
originalObserver.subscribe(onStoreChange);
|
|
3504
|
-
observerFollower.subscribe(onFollowerChange);
|
|
3505
|
-
|
|
3506
|
-
observerFollower.destroy = () => {
|
|
3507
|
-
originalObserver.unsubscribe(onStoreChange);
|
|
3508
|
-
observerFollower.unsubscribe(onFollowerChange);
|
|
3509
|
-
subscribers.delete(observerFollower);
|
|
3510
|
-
observerFollower.cleanup();
|
|
3511
|
-
};
|
|
3512
|
-
observerFollower.dispose = observerFollower.destroy;
|
|
3513
|
-
|
|
3514
|
-
subscribers.add(observerFollower);
|
|
3515
|
-
return observerFollower;
|
|
3516
|
-
},
|
|
3517
|
-
|
|
3518
|
-
/**
|
|
3519
|
-
* Returns a read-only follower of the store.
|
|
3520
|
-
* The follower reflects store changes but cannot write back to the store.
|
|
3521
|
-
* Any attempt to call .set(), .toggle() or .reset() will throw.
|
|
3522
|
-
* Call follower.destroy() or follower.dispose() to unsubscribe.
|
|
3523
|
-
*
|
|
3524
|
-
* @param {string} name
|
|
3525
|
-
* @returns {ObservableItem}
|
|
3526
|
-
*/
|
|
3527
|
-
follow(name) {
|
|
3528
|
-
const { observer: originalObserver, subscribers } = $getStoreOrThrow('follow', name);
|
|
3529
|
-
const observerFollower = $createObservable(originalObserver.val());
|
|
3530
|
-
|
|
3531
|
-
const onStoreChange = value => observerFollower.set(value);
|
|
3532
|
-
originalObserver.subscribe(onStoreChange);
|
|
3533
|
-
|
|
3534
|
-
$applyReadOnly(observerFollower, name, 'follow');
|
|
3535
|
-
|
|
3536
|
-
observerFollower.destroy = () => {
|
|
3537
|
-
originalObserver.unsubscribe(onStoreChange);
|
|
3538
|
-
subscribers.delete(observerFollower);
|
|
3539
|
-
observerFollower.cleanup();
|
|
3540
|
-
};
|
|
3541
|
-
observerFollower.dispose = observerFollower.destroy;
|
|
3542
|
-
|
|
3543
|
-
subscribers.add(observerFollower);
|
|
3544
|
-
return observerFollower;
|
|
3545
|
-
},
|
|
3546
|
-
|
|
3547
|
-
/**
|
|
3548
|
-
* Returns the raw store observer directly (no follower, no cleanup contract).
|
|
3549
|
-
* Use this for direct read access when you don't need to unsubscribe.
|
|
3550
|
-
* WARNING : mutations on this observer impact all subscribers immediately.
|
|
3551
|
-
*
|
|
3552
|
-
* @param {string} name
|
|
3553
|
-
* @returns {ObservableItem|null}
|
|
3554
|
-
*/
|
|
3555
|
-
get(name) {
|
|
3556
|
-
const item = $stores.get(name);
|
|
3557
|
-
if (!item) {
|
|
3558
|
-
DebugManager$2.warn('Store', `Store.get('${name}') : store not found.`);
|
|
3559
|
-
return null;
|
|
3560
|
-
}
|
|
3561
|
-
return item.observer;
|
|
3562
|
-
},
|
|
3563
|
-
|
|
3564
|
-
/**
|
|
3565
|
-
* @param {string} name
|
|
3566
|
-
* @returns {{ observer: ObservableItem, subscribers: Set } | null}
|
|
3567
|
-
*/
|
|
3568
|
-
getWithSubscribers(name) {
|
|
3569
|
-
return $stores.get(name) ?? null;
|
|
3570
|
-
},
|
|
3571
|
-
|
|
3572
|
-
/**
|
|
3573
|
-
* Destroys a store : cleans up the observer, destroys all followers, and removes the entry.
|
|
3574
|
-
*
|
|
3575
|
-
* @param {string} name
|
|
3576
|
-
*/
|
|
3577
|
-
delete(name) {
|
|
3578
|
-
const item = $stores.get(name);
|
|
3579
|
-
if (!item) {
|
|
3580
|
-
DebugManager$2.warn('Store', `Store.delete('${name}') : store not found, nothing to delete.`);
|
|
2671
|
+
// ----------------------------------------------------------------
|
|
2672
|
+
// Class attributes binder
|
|
2673
|
+
// ----------------------------------------------------------------
|
|
2674
|
+
const classListMethods = {
|
|
2675
|
+
getClasses() {
|
|
2676
|
+
return this.$element.className?.split(' ').filter(Boolean);
|
|
2677
|
+
},
|
|
2678
|
+
add(value) {
|
|
2679
|
+
const classes = this.getClasses();
|
|
2680
|
+
if(classes.indexOf(value) >= 0) {
|
|
2681
|
+
return;
|
|
2682
|
+
}
|
|
2683
|
+
classes.push(value);
|
|
2684
|
+
this.$element.className = classes.join(' ');
|
|
2685
|
+
},
|
|
2686
|
+
remove(value) {
|
|
2687
|
+
const classes = this.getClasses();
|
|
2688
|
+
const index = classes.indexOf(value);
|
|
2689
|
+
if(index < 0) {
|
|
2690
|
+
return;
|
|
2691
|
+
}
|
|
2692
|
+
classes.splice(index, 1);
|
|
2693
|
+
this.$element.className = classes.join(' ');
|
|
2694
|
+
},
|
|
2695
|
+
toggle(value, force = undefined) {
|
|
2696
|
+
const classes = this.getClasses();
|
|
2697
|
+
const index = classes.indexOf(value);
|
|
2698
|
+
if(index >= 0) {
|
|
2699
|
+
if(force === true) {
|
|
3581
2700
|
return;
|
|
3582
2701
|
}
|
|
3583
|
-
|
|
3584
|
-
item.subscribers.clear();
|
|
3585
|
-
item.observer.cleanup();
|
|
3586
|
-
$stores.delete(name);
|
|
3587
|
-
},
|
|
3588
|
-
/**
|
|
3589
|
-
* Creates an isolated store group with its own state namespace.
|
|
3590
|
-
* Each group is a fully independent StoreFactory instance —
|
|
3591
|
-
* no key conflicts, no shared state with the parent store.
|
|
3592
|
-
*
|
|
3593
|
-
* @param {string | ((group: ReturnType<typeof StoreFactory>) => void)} name - Group name for debugging, or setup callback if no name is provided
|
|
3594
|
-
* @param {((group: ReturnType<typeof StoreFactory>) => void)} [callback] - Setup function receiving the isolated store instance
|
|
3595
|
-
* @returns {ReturnType<typeof StoreFactory>}
|
|
3596
|
-
*
|
|
3597
|
-
* @example
|
|
3598
|
-
* // With name (recommended)
|
|
3599
|
-
* const EventStore = Store.group('events', (group) => {
|
|
3600
|
-
* group.create('catalog', []);
|
|
3601
|
-
* group.create('filters', { category: null, date: null });
|
|
3602
|
-
* group.createResettable('selected', null);
|
|
3603
|
-
* group.createComposed('filtered', () => {
|
|
3604
|
-
* const catalog = EventStore.get('catalog').val();
|
|
3605
|
-
* const filters = EventStore.get('filters').val();
|
|
3606
|
-
* return catalog.filter(event => {
|
|
3607
|
-
* if (filters.category && event.category !== filters.category) return false;
|
|
3608
|
-
* return true;
|
|
3609
|
-
* });
|
|
3610
|
-
* }, ['catalog', 'filters']);
|
|
3611
|
-
* });
|
|
3612
|
-
*
|
|
3613
|
-
* // Without name
|
|
3614
|
-
* const CartStore = Store.group((group) => {
|
|
3615
|
-
* group.create('items', []);
|
|
3616
|
-
* });
|
|
3617
|
-
*
|
|
3618
|
-
* // Usage
|
|
3619
|
-
* EventStore.use('catalog'); // two-way follower
|
|
3620
|
-
* EventStore.follow('filtered'); // read-only follower
|
|
3621
|
-
* EventStore.get('filters'); // raw observable
|
|
3622
|
-
*
|
|
3623
|
-
* // Cross-group composed
|
|
3624
|
-
* const OrderStore = Store.group('orders', (group) => {
|
|
3625
|
-
* group.createComposed('summary', () => {
|
|
3626
|
-
* const items = CartStore.get('items').val();
|
|
3627
|
-
* const events = EventStore.get('catalog').val();
|
|
3628
|
-
* return { items, events };
|
|
3629
|
-
* }, [CartStore.get('items'), EventStore.get('catalog')]);
|
|
3630
|
-
* });
|
|
3631
|
-
*/
|
|
3632
|
-
group(name, callback) {
|
|
3633
|
-
if (typeof name === 'function') {
|
|
3634
|
-
callback = name;
|
|
3635
|
-
name = 'anonymous';
|
|
3636
|
-
}
|
|
3637
|
-
const store = StoreFactory();
|
|
3638
|
-
callback && callback(store);
|
|
3639
|
-
return store;
|
|
3640
|
-
},
|
|
3641
|
-
createPersistent(name, value, localstorage_key) {
|
|
3642
|
-
localstorage_key = localstorage_key || name;
|
|
3643
|
-
const observer = this.create(name, $getFromStorage(localstorage_key, value));
|
|
3644
|
-
const saver = $saveToStorage(value);
|
|
3645
|
-
|
|
3646
|
-
observer.subscribe((val) => saver(localstorage_key, val));
|
|
3647
|
-
return observer;
|
|
3648
|
-
},
|
|
3649
|
-
createPersistentResettable(name, value, localstorage_key) {
|
|
3650
|
-
localstorage_key = localstorage_key || name;
|
|
3651
|
-
const observer = this.createResettable(name, $getFromStorage(localstorage_key, value));
|
|
3652
|
-
const saver = $saveToStorage(value);
|
|
3653
|
-
observer.subscribe((val) => saver(localstorage_key, val));
|
|
3654
|
-
|
|
3655
|
-
const originalReset = observer.reset.bind(observer);
|
|
3656
|
-
observer.reset = () => {
|
|
3657
|
-
LocalStorage.remove(localstorage_key);
|
|
3658
|
-
originalReset();
|
|
3659
|
-
};
|
|
3660
|
-
|
|
3661
|
-
return observer;
|
|
2702
|
+
classes.splice(index, 1);
|
|
3662
2703
|
}
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
return new Proxy($api, {
|
|
3667
|
-
get(target, prop) {
|
|
3668
|
-
if (typeof prop === 'symbol' || prop.startsWith('$') || prop in target) {
|
|
3669
|
-
return target[prop];
|
|
3670
|
-
}
|
|
3671
|
-
if (target.has(prop)) {
|
|
3672
|
-
if ($followersCache.has(prop)) {
|
|
3673
|
-
return $followersCache.get(prop);
|
|
3674
|
-
}
|
|
3675
|
-
const follower = target.follow(prop);
|
|
3676
|
-
$followersCache.set(prop, follower);
|
|
3677
|
-
return follower;
|
|
2704
|
+
else {
|
|
2705
|
+
if(force === false) {
|
|
2706
|
+
return;
|
|
3678
2707
|
}
|
|
3679
|
-
|
|
3680
|
-
},
|
|
3681
|
-
set(target, prop, value) {
|
|
3682
|
-
DebugManager$2.error('Store', `Forbidden: You cannot overwrite the store key '${String(prop)}'. Use .use('${String(prop)}').set(value) instead.`);
|
|
3683
|
-
throw new NativeDocumentError(`Store structure is immutable. Use .set() on the observable.`);
|
|
3684
|
-
},
|
|
3685
|
-
deleteProperty(target, prop) {
|
|
3686
|
-
throw new NativeDocumentError(`Store keys cannot be deleted.`);
|
|
2708
|
+
classes.push(value);
|
|
3687
2709
|
}
|
|
3688
|
-
|
|
2710
|
+
this.$element.className = classes.join(' ');
|
|
2711
|
+
},
|
|
2712
|
+
contains(value) {
|
|
2713
|
+
return this.getClasses().indexOf(value) >= 0;
|
|
2714
|
+
}
|
|
3689
2715
|
};
|
|
3690
2716
|
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
*
|
|
3699
|
-
* @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
|
|
3700
|
-
* @param {NdChild|(() => NdChild)} child - Element or content to show/hide
|
|
3701
|
-
* @param {Object} [options={}] - Configuration options
|
|
3702
|
-
* @param {string|null} [options.comment=null] - Comment for debugging
|
|
3703
|
-
* @param {boolean} [options.shouldKeepInCache=true] - Whether to cache the element when hidden
|
|
3704
|
-
* @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
|
|
3705
|
-
* @example
|
|
3706
|
-
* const isVisible = Observable(false);
|
|
3707
|
-
* ShowIf(isVisible, Div({}, 'Hello World'));
|
|
3708
|
-
*/
|
|
3709
|
-
const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
|
|
3710
|
-
if(!Validator.isObservable(condition)) {
|
|
3711
|
-
if(typeof condition === "boolean") {
|
|
3712
|
-
return condition ? ElementCreator.getChild(child) : null;
|
|
3713
|
-
}
|
|
3714
|
-
|
|
3715
|
-
return DebugManager$2.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
|
+
};
|
|
3716
2724
|
}
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
let childElement = null;
|
|
3720
|
-
const getChildElement = () => {
|
|
3721
|
-
if(childElement && shouldKeepInCache) {
|
|
3722
|
-
return childElement;
|
|
3723
|
-
}
|
|
3724
|
-
childElement = ElementCreator.getChild(child);
|
|
3725
|
-
if(Validator.isFragment(childElement)) {
|
|
3726
|
-
childElement = Array.from(childElement.childNodes);
|
|
3727
|
-
}
|
|
3728
|
-
return childElement;
|
|
3729
|
-
};
|
|
3730
|
-
|
|
3731
|
-
const currentValue = condition.val();
|
|
2725
|
+
});
|
|
3732
2726
|
|
|
3733
|
-
|
|
3734
|
-
|
|
2727
|
+
const normalizeComponentArgs = function(props, children = null) {
|
|
2728
|
+
if(props && children) {
|
|
2729
|
+
return { props, children };
|
|
3735
2730
|
}
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
if(!!value) {
|
|
3739
|
-
element.appendChild(getChildElement());
|
|
3740
|
-
return;
|
|
3741
|
-
}
|
|
3742
|
-
element.remove();
|
|
3743
|
-
});
|
|
3744
|
-
|
|
3745
|
-
return element;
|
|
3746
|
-
};
|
|
3747
|
-
|
|
3748
|
-
/**
|
|
3749
|
-
* Creates a `<div>` element.
|
|
3750
|
-
* @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLDivElement}
|
|
3751
|
-
*/
|
|
3752
|
-
const Div = HtmlElementWrapper('div');
|
|
3753
|
-
|
|
3754
|
-
function oneChildAnchorOverwriting(anchor, parent) {
|
|
3755
|
-
|
|
3756
|
-
anchor.remove = () => {
|
|
3757
|
-
anchor.append.apply(anchor, parent.childNodes);
|
|
3758
|
-
};
|
|
3759
|
-
anchor.getParent = () => parent;
|
|
3760
|
-
|
|
3761
|
-
anchor.appendChild = (child) => {
|
|
3762
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3763
|
-
parent.appendChild(child);
|
|
3764
|
-
};
|
|
3765
|
-
|
|
3766
|
-
anchor.appendChildRaw = parent.appendChild.bind(parent);
|
|
3767
|
-
anchor.append = anchor.appendChild;
|
|
3768
|
-
anchor.appendRaw = anchor.appendChildRaw;
|
|
3769
|
-
|
|
3770
|
-
anchor.insertAtStart = (child) => {
|
|
3771
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3772
|
-
parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
|
|
3773
|
-
};
|
|
3774
|
-
anchor.insertAtStartRaw = (child) => {
|
|
3775
|
-
parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
|
|
3776
|
-
};
|
|
3777
|
-
|
|
3778
|
-
anchor.appendElement = anchor.appendChild;
|
|
3779
|
-
|
|
3780
|
-
anchor.removeChildren = () => {
|
|
3781
|
-
parent.textContent = '';
|
|
3782
|
-
};
|
|
3783
|
-
|
|
3784
|
-
anchor.replaceContent = function(content) {
|
|
3785
|
-
const child = Validator.isElement(content) ? content : ElementCreator.getChild(content);
|
|
3786
|
-
parent.replaceChildren(child);
|
|
3787
|
-
};
|
|
3788
|
-
|
|
3789
|
-
anchor.replaceContentRaw = function(child) {
|
|
3790
|
-
parent.replaceChildren(child);
|
|
3791
|
-
};
|
|
3792
|
-
anchor.setContent = anchor.replaceContent;
|
|
3793
|
-
|
|
3794
|
-
anchor.insertBefore = (child, anchor) => {
|
|
3795
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3796
|
-
parent.insertBefore(child, anchor);
|
|
3797
|
-
};
|
|
3798
|
-
anchor.insertBeforeRaw = (child, anchor) => {
|
|
3799
|
-
parent.insertBefore(child, anchor);
|
|
3800
|
-
};
|
|
3801
|
-
|
|
3802
|
-
anchor.appendChildBefore = anchor.insertBefore;
|
|
3803
|
-
anchor.appendChildBeforeRaw = anchor.insertBeforeRaw;
|
|
3804
|
-
|
|
3805
|
-
anchor.clear = anchor.remove;
|
|
3806
|
-
anchor.detach = anchor.remove;
|
|
3807
|
-
|
|
3808
|
-
anchor.replaceChildren = function() {
|
|
3809
|
-
parent.replaceChildren(...arguments);
|
|
3810
|
-
};
|
|
3811
|
-
|
|
3812
|
-
anchor.getByIndex = (index) => {
|
|
3813
|
-
return parent.childNodes[index];
|
|
3814
|
-
};
|
|
3815
|
-
}
|
|
3816
|
-
|
|
3817
|
-
function Anchor(name, isUniqueChild = false) {
|
|
3818
|
-
const anchorFragment = new AnchorWithSentinel(name);
|
|
3819
|
-
|
|
3820
|
-
anchorFragment.onConnectedOnce((parent) => {
|
|
3821
|
-
if(isUniqueChild) {
|
|
3822
|
-
oneChildAnchorOverwriting(anchorFragment, parent);
|
|
3823
|
-
}
|
|
3824
|
-
});
|
|
3825
|
-
|
|
3826
|
-
anchorFragment.__Anchor__ = true;
|
|
3827
|
-
|
|
3828
|
-
const anchorStart = anchorFragment.$start;
|
|
3829
|
-
const anchorEnd = anchorFragment.$end;
|
|
3830
|
-
|
|
3831
|
-
anchorFragment.nativeInsertBefore = anchorFragment.insertBefore;
|
|
3832
|
-
anchorFragment.nativeAppendChild = anchorFragment.appendChild;
|
|
3833
|
-
anchorFragment.nativeAppend = anchorFragment.append;
|
|
3834
|
-
|
|
3835
|
-
const isParentUniqueChild = isUniqueChild
|
|
3836
|
-
? () => true: (parent) => (parent.firstChild === anchorStart && parent.lastChild === anchorEnd);
|
|
3837
|
-
|
|
3838
|
-
const insertBefore = (parent, child, target) => {
|
|
3839
|
-
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3840
|
-
insertBeforeRaw(parent, childElement, target);
|
|
3841
|
-
};
|
|
3842
|
-
|
|
3843
|
-
const insertBeforeRaw = (parent, child, target) => {
|
|
3844
|
-
if(parent === anchorFragment) {
|
|
3845
|
-
parent.nativeInsertBefore(child, target);
|
|
3846
|
-
return;
|
|
3847
|
-
}
|
|
3848
|
-
if(isParentUniqueChild(parent) && target === anchorEnd) {
|
|
3849
|
-
parent.append(child, target);
|
|
3850
|
-
return;
|
|
3851
|
-
}
|
|
3852
|
-
parent.insertBefore(child, target);
|
|
3853
|
-
};
|
|
3854
|
-
|
|
3855
|
-
anchorFragment.appendElement = function(child) {
|
|
3856
|
-
const parentNode = anchorStart.parentNode;
|
|
3857
|
-
if(parentNode === anchorFragment) {
|
|
3858
|
-
parentNode.nativeInsertBefore(child, anchorEnd);
|
|
3859
|
-
return;
|
|
3860
|
-
}
|
|
3861
|
-
parentNode.insertBefore(child, anchorEnd);
|
|
3862
|
-
};
|
|
3863
|
-
|
|
3864
|
-
anchorFragment.appendChild = function(child, before = null) {
|
|
3865
|
-
const parent = anchorEnd.parentNode;
|
|
3866
|
-
if(!parent) {
|
|
3867
|
-
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
3868
|
-
return;
|
|
3869
|
-
}
|
|
3870
|
-
before = before ?? anchorEnd;
|
|
3871
|
-
insertBefore(parent, child, before);
|
|
3872
|
-
};
|
|
3873
|
-
|
|
3874
|
-
anchorFragment.appendChildRaw = function(child, before = null) {
|
|
3875
|
-
const parent = anchorEnd.parentNode;
|
|
3876
|
-
if(!parent) {
|
|
3877
|
-
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
3878
|
-
return;
|
|
3879
|
-
}
|
|
3880
|
-
before = before ?? anchorEnd;
|
|
3881
|
-
insertBeforeRaw(parent, child, before);
|
|
3882
|
-
};
|
|
3883
|
-
|
|
3884
|
-
anchorFragment.getParent = () => anchorEnd.parentNode;
|
|
3885
|
-
anchorFragment.append = anchorFragment.appendChild;
|
|
3886
|
-
anchorFragment.appendRaw = anchorFragment.appendChildRaw;
|
|
3887
|
-
|
|
3888
|
-
anchorFragment.insertAtStart = function(child) {
|
|
3889
|
-
child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3890
|
-
anchorFragment.insertAtStartRaw(child);
|
|
3891
|
-
};
|
|
3892
|
-
|
|
3893
|
-
anchorFragment.insertAtStartRaw = function(child) {
|
|
3894
|
-
const parentNode = anchorStart.parentNode;
|
|
3895
|
-
if(parentNode === anchorFragment) {
|
|
3896
|
-
parentNode.nativeInsertBefore(child, anchorStart);
|
|
3897
|
-
return;
|
|
3898
|
-
}
|
|
3899
|
-
parentNode.insertBefore(child, anchorStart);
|
|
3900
|
-
};
|
|
3901
|
-
|
|
3902
|
-
anchorFragment.removeChildren = function() {
|
|
3903
|
-
const parent = anchorEnd.parentNode;
|
|
3904
|
-
if(parent === anchorFragment) {
|
|
3905
|
-
return;
|
|
3906
|
-
}
|
|
3907
|
-
if(isParentUniqueChild(parent)) {
|
|
3908
|
-
parent.replaceChildren(anchorStart, anchorEnd);
|
|
3909
|
-
return;
|
|
3910
|
-
}
|
|
3911
|
-
|
|
3912
|
-
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
3913
|
-
while(itemToRemove && itemToRemove !== anchorEnd) {
|
|
3914
|
-
tempItem = itemToRemove.nextSibling;
|
|
3915
|
-
itemToRemove.remove();
|
|
3916
|
-
itemToRemove = tempItem;
|
|
3917
|
-
}
|
|
3918
|
-
};
|
|
3919
|
-
|
|
3920
|
-
anchorFragment.remove = function() {
|
|
3921
|
-
const parent = anchorEnd.parentNode;
|
|
3922
|
-
if(parent === anchorFragment) {
|
|
3923
|
-
return;
|
|
3924
|
-
}
|
|
3925
|
-
if(isParentUniqueChild(parent)) {
|
|
3926
|
-
anchorFragment.nativeAppend.apply(anchorFragment, parent.childNodes);
|
|
3927
|
-
parent.replaceChildren(anchorStart, anchorEnd);
|
|
3928
|
-
return;
|
|
3929
|
-
}
|
|
3930
|
-
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
3931
|
-
while(itemToRemove && itemToRemove !== anchorEnd) {
|
|
3932
|
-
tempItem = itemToRemove.nextSibling;
|
|
3933
|
-
anchorFragment.nativeAppend(itemToRemove);
|
|
3934
|
-
itemToRemove = tempItem;
|
|
3935
|
-
}
|
|
3936
|
-
};
|
|
3937
|
-
|
|
3938
|
-
anchorFragment.removeWithAnchors = function() {
|
|
3939
|
-
anchorFragment.removeChildren();
|
|
3940
|
-
anchorStart.remove();
|
|
3941
|
-
anchorEnd.remove();
|
|
3942
|
-
};
|
|
3943
|
-
anchorFragment.delete = anchorFragment.removeWithAnchors;
|
|
3944
|
-
|
|
3945
|
-
anchorFragment.replaceContent = function(child) {
|
|
3946
|
-
const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
3947
|
-
anchorFragment.replaceContentRaw(childElement);
|
|
3948
|
-
};
|
|
3949
|
-
|
|
3950
|
-
anchorFragment.replaceContentRaw = function(child) {
|
|
3951
|
-
const parent = anchorEnd.parentNode;
|
|
3952
|
-
if(!parent) {
|
|
3953
|
-
return;
|
|
3954
|
-
}
|
|
3955
|
-
if(isParentUniqueChild(parent)) {
|
|
3956
|
-
parent.replaceChildren(anchorStart, child, anchorEnd);
|
|
3957
|
-
return;
|
|
3958
|
-
}
|
|
3959
|
-
anchorFragment.removeChildren();
|
|
3960
|
-
parent.insertBefore(child, anchorEnd);
|
|
3961
|
-
};
|
|
3962
|
-
|
|
3963
|
-
anchorFragment.setContent = anchorFragment.replaceContent;
|
|
3964
|
-
anchorFragment.setContentRaw = anchorFragment.replaceContentRaw;
|
|
3965
|
-
|
|
3966
|
-
anchorFragment.insertBefore = anchorFragment.appendChild;
|
|
3967
|
-
anchorFragment.insertBeforeRaw = anchorFragment.appendChildRaw;
|
|
3968
|
-
|
|
3969
|
-
anchorFragment.endElement = function() {
|
|
3970
|
-
return anchorEnd;
|
|
3971
|
-
};
|
|
3972
|
-
|
|
3973
|
-
anchorFragment.startElement = function() {
|
|
3974
|
-
return anchorStart;
|
|
3975
|
-
};
|
|
3976
|
-
|
|
3977
|
-
anchorFragment.restore = function() {
|
|
3978
|
-
anchorFragment.appendChild(anchorFragment);
|
|
3979
|
-
};
|
|
3980
|
-
|
|
3981
|
-
anchorFragment.clear = anchorFragment.remove;
|
|
3982
|
-
anchorFragment.detach = anchorFragment.remove;
|
|
3983
|
-
|
|
3984
|
-
anchorFragment.getByIndex = function(index) {
|
|
3985
|
-
let currentNode = anchorStart;
|
|
3986
|
-
for(let i = 0; i <= index; i++) {
|
|
3987
|
-
if(!currentNode.nextSibling) {
|
|
3988
|
-
return null;
|
|
3989
|
-
}
|
|
3990
|
-
currentNode = currentNode.nextSibling;
|
|
3991
|
-
}
|
|
3992
|
-
return currentNode !== anchorStart ? currentNode : null;
|
|
3993
|
-
};
|
|
3994
|
-
|
|
3995
|
-
return anchorFragment;
|
|
3996
|
-
}
|
|
3997
|
-
DocumentFragment.prototype.setAttribute = () => {};
|
|
3998
|
-
|
|
3999
|
-
function NDElement(element) {
|
|
4000
|
-
this.$element = element;
|
|
4001
|
-
this.$attachements = null;
|
|
4002
|
-
}
|
|
4003
|
-
|
|
4004
|
-
NDElement.prototype.__$isNDElement = true;
|
|
4005
|
-
|
|
4006
|
-
NDElement.prototype.ghostDom = function(element) {
|
|
4007
|
-
if(!this.$attachements) {
|
|
4008
|
-
this.$attachements = document.createDocumentFragment();
|
|
4009
|
-
}
|
|
4010
|
-
this.$attachements.appendChild(ElementCreator.getChild(element));
|
|
4011
|
-
return this;
|
|
4012
|
-
};
|
|
4013
|
-
|
|
4014
|
-
NDElement.prototype.valueOf = function() {
|
|
4015
|
-
return this.$element;
|
|
4016
|
-
};
|
|
4017
|
-
|
|
4018
|
-
NDElement.prototype.ref = function(target, name) {
|
|
4019
|
-
target[name] = this.$element;
|
|
4020
|
-
return this;
|
|
4021
|
-
};
|
|
4022
|
-
|
|
4023
|
-
NDElement.prototype.refSelf = function(target, name) {
|
|
4024
|
-
target[name] = this;
|
|
4025
|
-
// TODO: @DIM to check
|
|
4026
|
-
// target[name] = new NDElement(this.$element);
|
|
4027
|
-
return this;
|
|
4028
|
-
};
|
|
4029
|
-
|
|
4030
|
-
NDElement.prototype.unmountChildren = function() {
|
|
4031
|
-
let element = this.$element;
|
|
4032
|
-
for(let i = 0, length = element.children.length; i < length; i++) {
|
|
4033
|
-
let elementChildren = element.children[i];
|
|
4034
|
-
if(!elementChildren.$ndProx) {
|
|
4035
|
-
elementChildren.nd?.remove();
|
|
4036
|
-
}
|
|
4037
|
-
elementChildren = null;
|
|
4038
|
-
}
|
|
4039
|
-
element = null;
|
|
4040
|
-
return this;
|
|
4041
|
-
};
|
|
4042
|
-
|
|
4043
|
-
NDElement.prototype.remove = function() {
|
|
4044
|
-
let element = this.$element;
|
|
4045
|
-
element.nd.unmountChildren();
|
|
4046
|
-
element.$ndProx = null;
|
|
4047
|
-
|
|
4048
|
-
$lifeCycleObservers.delete(element);
|
|
4049
|
-
|
|
4050
|
-
element = null;
|
|
4051
|
-
return this;
|
|
4052
|
-
};
|
|
4053
|
-
|
|
4054
|
-
const $lifeCycleObservers = new WeakMap();
|
|
4055
|
-
NDElement.prototype.lifecycle = function(states) {
|
|
4056
|
-
const el = this.$element;
|
|
4057
|
-
if (!$lifeCycleObservers.has(el)) {
|
|
4058
|
-
$lifeCycleObservers.set(el, DocumentObserver.watch(el));
|
|
4059
|
-
}
|
|
4060
|
-
const observer = $lifeCycleObservers.get(el);
|
|
4061
|
-
|
|
4062
|
-
if(states.mounted) {
|
|
4063
|
-
this.$element.setAttribute('data--nd-mounted', '1');
|
|
4064
|
-
observer.mounted(states.mounted);
|
|
4065
|
-
}
|
|
4066
|
-
if(states.unmounted) {
|
|
4067
|
-
this.$element.setAttribute('data--nd-unmounted', '1');
|
|
4068
|
-
observer.unmounted(states.unmounted);
|
|
4069
|
-
}
|
|
4070
|
-
return this;
|
|
4071
|
-
};
|
|
4072
|
-
|
|
4073
|
-
NDElement.prototype.mounted = function(callback) {
|
|
4074
|
-
return this.lifecycle({ mounted: callback });
|
|
4075
|
-
};
|
|
4076
|
-
|
|
4077
|
-
NDElement.prototype.unmounted = function(callback) {
|
|
4078
|
-
return this.lifecycle({ unmounted: callback });
|
|
4079
|
-
};
|
|
4080
|
-
|
|
4081
|
-
NDElement.prototype.beforeUnmount = function(id, callback) {
|
|
4082
|
-
const el = this.$element;
|
|
4083
|
-
|
|
4084
|
-
if(!DocumentObserver.beforeUnmount.has(el)) {
|
|
4085
|
-
DocumentObserver.beforeUnmount.set(el, new Map());
|
|
4086
|
-
const originalRemove = el.remove.bind(el);
|
|
4087
|
-
|
|
4088
|
-
let $isUnmounting = false;
|
|
4089
|
-
|
|
4090
|
-
el.remove = async () => {
|
|
4091
|
-
if($isUnmounting) {
|
|
4092
|
-
return;
|
|
4093
|
-
}
|
|
4094
|
-
$isUnmounting = true;
|
|
4095
|
-
|
|
4096
|
-
try {
|
|
4097
|
-
const callbacks = DocumentObserver.beforeUnmount.get(el);
|
|
4098
|
-
for (const cb of callbacks.values()) {
|
|
4099
|
-
await cb.call(this, el);
|
|
4100
|
-
}
|
|
4101
|
-
} finally {
|
|
4102
|
-
originalRemove();
|
|
4103
|
-
$isUnmounting = false;
|
|
4104
|
-
}
|
|
4105
|
-
};
|
|
4106
|
-
}
|
|
4107
|
-
|
|
4108
|
-
DocumentObserver.beforeUnmount.get(el).set(id, callback);
|
|
4109
|
-
return this;
|
|
4110
|
-
};
|
|
4111
|
-
|
|
4112
|
-
NDElement.prototype.htmlElement = function() {
|
|
4113
|
-
return this.$element;
|
|
4114
|
-
};
|
|
4115
|
-
|
|
4116
|
-
NDElement.prototype.node = NDElement.prototype.htmlElement;
|
|
4117
|
-
|
|
4118
|
-
NDElement.prototype.shadow = function(mode, style = null) {
|
|
4119
|
-
const $element = this.$element;
|
|
4120
|
-
const children = Array.from($element.childNodes);
|
|
4121
|
-
const shadowRoot = $element.attachShadow({ mode });
|
|
4122
|
-
if(style) {
|
|
4123
|
-
const styleNode = document.createElement("style");
|
|
4124
|
-
styleNode.textContent = style;
|
|
4125
|
-
shadowRoot.appendChild(styleNode);
|
|
4126
|
-
}
|
|
4127
|
-
$element.append = shadowRoot.append.bind(shadowRoot);
|
|
4128
|
-
$element.appendChild = shadowRoot.appendChild.bind(shadowRoot);
|
|
4129
|
-
shadowRoot.append(...children);
|
|
4130
|
-
|
|
4131
|
-
return this;
|
|
4132
|
-
};
|
|
4133
|
-
|
|
4134
|
-
NDElement.prototype.openShadow = function(style = null) {
|
|
4135
|
-
return this.shadow('open', style);
|
|
4136
|
-
};
|
|
4137
|
-
|
|
4138
|
-
NDElement.prototype.closedShadow = function(style = null) {
|
|
4139
|
-
return this.shadow('closed', style);
|
|
4140
|
-
};
|
|
4141
|
-
|
|
4142
|
-
/**
|
|
4143
|
-
* Extends the current NDElement instance with custom methods.
|
|
4144
|
-
* Methods are bound to the instance and available for chaining.
|
|
4145
|
-
*
|
|
4146
|
-
* @param {Object} methods - Object containing method definitions
|
|
4147
|
-
* @returns {this} The NDElement instance with added methods for chaining
|
|
4148
|
-
* @example
|
|
4149
|
-
* element.nd.with({
|
|
4150
|
-
* highlight() {
|
|
4151
|
-
* this.$element.style.background = 'yellow';
|
|
4152
|
-
* return this;
|
|
4153
|
-
* }
|
|
4154
|
-
* }).highlight().onClick(() => console.log('Clicked'));
|
|
4155
|
-
*/
|
|
4156
|
-
NDElement.prototype.with = function(methods) {
|
|
4157
|
-
if (!methods || typeof methods !== 'object') {
|
|
4158
|
-
throw new NativeDocumentError('extend() requires an object of methods');
|
|
4159
|
-
}
|
|
4160
|
-
|
|
4161
|
-
for (const name in methods) {
|
|
4162
|
-
const method = methods[name];
|
|
4163
|
-
|
|
4164
|
-
if (typeof method !== 'function') {
|
|
4165
|
-
DebugManager$2.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
|
|
4166
|
-
continue;
|
|
4167
|
-
}
|
|
4168
|
-
|
|
4169
|
-
this[name] = method.bind(this);
|
|
4170
|
-
}
|
|
4171
|
-
|
|
4172
|
-
return this;
|
|
4173
|
-
};
|
|
4174
|
-
|
|
4175
|
-
/**
|
|
4176
|
-
* Extends the NDElement prototype with new methods available to all NDElement instances.
|
|
4177
|
-
* Use this to add global methods to all NDElements.
|
|
4178
|
-
*
|
|
4179
|
-
* @param {Object} methods - Object containing method definitions to add to prototype
|
|
4180
|
-
* @returns {typeof NDElement} The NDElement constructor
|
|
4181
|
-
* @throws {NativeDocumentError} If methods is not an object or contains non-function values
|
|
4182
|
-
* @example
|
|
4183
|
-
* NDElement.extend({
|
|
4184
|
-
* fadeIn() {
|
|
4185
|
-
* this.$element.style.opacity = '1';
|
|
4186
|
-
* return this;
|
|
4187
|
-
* }
|
|
4188
|
-
* });
|
|
4189
|
-
* // Now all NDElements have .fadeIn() method
|
|
4190
|
-
* Div().nd.fadeIn();
|
|
4191
|
-
*/
|
|
4192
|
-
NDElement.extend = function(methods) {
|
|
4193
|
-
if (!methods || typeof methods !== 'object') {
|
|
4194
|
-
throw new NativeDocumentError('NDElement.extend() requires an object of methods');
|
|
4195
|
-
}
|
|
4196
|
-
|
|
4197
|
-
if (Array.isArray(methods)) {
|
|
4198
|
-
throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
|
|
4199
|
-
}
|
|
4200
|
-
|
|
4201
|
-
const protectedMethods = new Set([
|
|
4202
|
-
'constructor', 'valueOf', '$element', '$observer',
|
|
4203
|
-
'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
|
|
4204
|
-
'lifecycle', 'mounted', 'unmounted', 'unmountChildren'
|
|
4205
|
-
]);
|
|
4206
|
-
|
|
4207
|
-
for (const name in methods) {
|
|
4208
|
-
if (!Object.hasOwn(methods, name)) {
|
|
4209
|
-
continue;
|
|
4210
|
-
}
|
|
4211
|
-
|
|
4212
|
-
const method = methods[name];
|
|
4213
|
-
|
|
4214
|
-
if (typeof method !== 'function') {
|
|
4215
|
-
DebugManager$2.warn('NDElement.extend', `"${name}" is not a function, skipping`);
|
|
4216
|
-
continue;
|
|
4217
|
-
}
|
|
4218
|
-
|
|
4219
|
-
if (protectedMethods.has(name)) {
|
|
4220
|
-
DebugManager$2.error('NDElement.extend', `Cannot override protected method "${name}"`);
|
|
4221
|
-
throw new NativeDocumentError(`Cannot override protected method "${name}"`);
|
|
4222
|
-
}
|
|
4223
|
-
|
|
4224
|
-
if (NDElement.prototype[name]) {
|
|
4225
|
-
DebugManager$2.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
|
|
4226
|
-
}
|
|
4227
|
-
|
|
4228
|
-
NDElement.prototype[name] = method;
|
|
4229
|
-
}
|
|
4230
|
-
|
|
4231
|
-
return NDElement;
|
|
4232
|
-
};
|
|
4233
|
-
|
|
4234
|
-
const COMMON_NODE_TYPES = {
|
|
4235
|
-
ELEMENT: 1,
|
|
4236
|
-
TEXT: 3,
|
|
4237
|
-
COMMENT: 8,
|
|
4238
|
-
DOCUMENT_FRAGMENT: 11
|
|
4239
|
-
};
|
|
4240
|
-
|
|
4241
|
-
const VALID_TYPES = [];
|
|
4242
|
-
VALID_TYPES[COMMON_NODE_TYPES.ELEMENT] = true;
|
|
4243
|
-
VALID_TYPES[COMMON_NODE_TYPES.TEXT] = true;
|
|
4244
|
-
VALID_TYPES[COMMON_NODE_TYPES.DOCUMENT_FRAGMENT] = true;
|
|
4245
|
-
VALID_TYPES[COMMON_NODE_TYPES.COMMENT] = true;
|
|
4246
|
-
|
|
4247
|
-
const Validator = {
|
|
4248
|
-
isObservable(value) {
|
|
4249
|
-
return value && (value.__$isObservable || value.__$Observable);
|
|
4250
|
-
},
|
|
4251
|
-
isTemplateBinding(value) {
|
|
4252
|
-
return value?.__$isTemplateBinding;
|
|
4253
|
-
},
|
|
4254
|
-
isObservableWhenResult(value) {
|
|
4255
|
-
return value && (value.__$isObservableWhen || (typeof value === 'object' && '$target' in value && '$observer' in value));
|
|
4256
|
-
},
|
|
4257
|
-
isArrayObservable(value) {
|
|
4258
|
-
return value?.__$isObservableArray;
|
|
4259
|
-
},
|
|
4260
|
-
isProxy(value) {
|
|
4261
|
-
return value?.__isProxy__
|
|
4262
|
-
},
|
|
4263
|
-
isObservableOrProxy(value) {
|
|
4264
|
-
return Validator.isObservable(value) || Validator.isProxy(value);
|
|
4265
|
-
},
|
|
4266
|
-
isAnchor(value) {
|
|
4267
|
-
return value?.__Anchor__
|
|
4268
|
-
},
|
|
4269
|
-
isObservableChecker(value) {
|
|
4270
|
-
return value?.__$isObservableChecker || value instanceof ObservableChecker;
|
|
4271
|
-
},
|
|
4272
|
-
isArray(value) {
|
|
4273
|
-
return Array.isArray(value);
|
|
4274
|
-
},
|
|
4275
|
-
isString(value) {
|
|
4276
|
-
return typeof value === 'string';
|
|
4277
|
-
},
|
|
4278
|
-
isNumber(value) {
|
|
4279
|
-
return typeof value === 'number';
|
|
4280
|
-
},
|
|
4281
|
-
isBoolean(value) {
|
|
4282
|
-
return typeof value === 'boolean';
|
|
4283
|
-
},
|
|
4284
|
-
isFunction(value) {
|
|
4285
|
-
return typeof value === 'function';
|
|
4286
|
-
},
|
|
4287
|
-
isAsyncFunction(value) {
|
|
4288
|
-
return typeof value === 'function' && value.constructor.name === 'AsyncFunction';
|
|
4289
|
-
},
|
|
4290
|
-
isObject(value) {
|
|
4291
|
-
return typeof value === 'object' && value !== null;
|
|
4292
|
-
},
|
|
4293
|
-
isJson(value) {
|
|
4294
|
-
return !(typeof value !== 'object' || value === null || Array.isArray(value) || value.constructor.name !== 'Object')
|
|
4295
|
-
},
|
|
4296
|
-
isElement(value) {
|
|
4297
|
-
return value && VALID_TYPES[value.nodeType];
|
|
4298
|
-
},
|
|
4299
|
-
isDOMNode(value) {
|
|
4300
|
-
return VALID_TYPES[value.nodeType];
|
|
4301
|
-
},
|
|
4302
|
-
isFragment(value) {
|
|
4303
|
-
return value?.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT;
|
|
4304
|
-
},
|
|
4305
|
-
isStringOrObservable(value) {
|
|
4306
|
-
return this.isString(value) || this.isObservable(value);
|
|
4307
|
-
},
|
|
4308
|
-
isValidChild(child) {
|
|
4309
|
-
return child === null ||
|
|
4310
|
-
this.isElement(child) ||
|
|
4311
|
-
this.isObservable(child) ||
|
|
4312
|
-
this.isNDElement(child) ||
|
|
4313
|
-
['string', 'number', 'boolean'].includes(typeof child);
|
|
4314
|
-
},
|
|
4315
|
-
isNDElement(child) {
|
|
4316
|
-
return child?.__$isNDElement || child instanceof NDElement;
|
|
4317
|
-
},
|
|
4318
|
-
isValidChildren(children) {
|
|
4319
|
-
if (!Array.isArray(children)) {
|
|
4320
|
-
children = [children];
|
|
4321
|
-
}
|
|
4322
|
-
|
|
4323
|
-
const invalid = children.filter(child => !this.isValidChild(child));
|
|
4324
|
-
return invalid.length === 0;
|
|
4325
|
-
},
|
|
4326
|
-
validateChildren(children) {
|
|
4327
|
-
if (!Array.isArray(children)) {
|
|
4328
|
-
children = [children];
|
|
4329
|
-
}
|
|
4330
|
-
|
|
4331
|
-
const invalid = children.filter(child => !this.isValidChild(child));
|
|
4332
|
-
if (invalid.length > 0) {
|
|
4333
|
-
throw new NativeDocumentError(`Invalid children detected: ${invalid.map(i => typeof i).join(', ')}`);
|
|
4334
|
-
}
|
|
4335
|
-
|
|
4336
|
-
return children;
|
|
4337
|
-
},
|
|
4338
|
-
/**
|
|
4339
|
-
* Check if the data contains observables.
|
|
4340
|
-
* @param {Array|Object} data
|
|
4341
|
-
* @returns {boolean}
|
|
4342
|
-
*/
|
|
4343
|
-
containsObservables(data) {
|
|
4344
|
-
if(!data) {
|
|
4345
|
-
return false;
|
|
4346
|
-
}
|
|
4347
|
-
return Validator.isObject(data)
|
|
4348
|
-
&& Object.values(data).some(value => Validator.isObservable(value));
|
|
4349
|
-
},
|
|
4350
|
-
/**
|
|
4351
|
-
* Check if the data contains an observable reference.
|
|
4352
|
-
* @param {string} data
|
|
4353
|
-
* @returns {boolean}
|
|
4354
|
-
*/
|
|
4355
|
-
containsObservableReference(data) {
|
|
4356
|
-
if(!data || typeof data !== 'string') {
|
|
4357
|
-
return false;
|
|
4358
|
-
}
|
|
4359
|
-
return /\{\{#ObItem::\([0-9]+\)\}\}/.test(data);
|
|
4360
|
-
},
|
|
4361
|
-
validateAttributes(attributes) {},
|
|
4362
|
-
|
|
4363
|
-
validateEventCallback(callback) {
|
|
4364
|
-
if (typeof callback !== 'function') {
|
|
4365
|
-
throw new NativeDocumentError('Event callback must be a function');
|
|
4366
|
-
}
|
|
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 }
|
|
4367
2733
|
}
|
|
2734
|
+
return { props, children };
|
|
4368
2735
|
};
|
|
4369
2736
|
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
const getValues = () => sources.map(src =>
|
|
4374
|
-
Validator.isObservable(src) ? src.val() : src
|
|
4375
|
-
);
|
|
2737
|
+
const createHtmlElement = (element, _attributes, _children = null) => {
|
|
2738
|
+
let { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
|
|
4376
2739
|
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
}
|
|
2740
|
+
ElementCreator.processAttributes(element, attributes);
|
|
2741
|
+
ElementCreator.processChildren(children, element);
|
|
2742
|
+
return element;
|
|
2743
|
+
};
|
|
4382
2744
|
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
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); };
|
|
4398
2761
|
|
|
4399
|
-
|
|
4400
|
-
return String(value).toLowerCase().includes(String(pattern).toLowerCase());
|
|
4401
|
-
}
|
|
4402
|
-
return String(value).includes(String(pattern));
|
|
2762
|
+
return (attr, children) => createElement(attr, children)
|
|
4403
2763
|
}
|
|
4404
|
-
|
|
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
|
+
};
|
|
4405
2781
|
}
|
|
4406
2782
|
|
|
2783
|
+
/**
|
|
2784
|
+
* Creates a `<div>` element.
|
|
2785
|
+
* @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLDivElement}
|
|
2786
|
+
*/
|
|
2787
|
+
const Div = HtmlElementWrapper('div');
|
|
2788
|
+
|
|
4407
2789
|
/**
|
|
4408
2790
|
*
|
|
4409
2791
|
* @class
|
|
@@ -5303,252 +3685,89 @@ var NativeComponents = (function (exports) {
|
|
|
5303
3685
|
* @returns {Alert}
|
|
5304
3686
|
*/
|
|
5305
3687
|
Alert.prototype.icon = function(icon) {
|
|
5306
|
-
this.$description.icon = icon;
|
|
5307
|
-
return this;
|
|
5308
|
-
};
|
|
5309
|
-
|
|
5310
|
-
/**
|
|
5311
|
-
* Shows or hides the icon
|
|
5312
|
-
* @param {boolean} [show=true] - Whether to show the icon
|
|
5313
|
-
* @returns {Alert}
|
|
5314
|
-
*/
|
|
5315
|
-
Alert.prototype.showIcon = function(show = true) {
|
|
5316
|
-
this.$description.showIcon = show;
|
|
5317
|
-
};
|
|
5318
|
-
|
|
5319
|
-
/**
|
|
5320
|
-
* Sets whether the alert can be closed
|
|
5321
|
-
* @param {boolean} [closable=true] - Whether the alert is closable
|
|
5322
|
-
* @returns {Alert}
|
|
5323
|
-
*/
|
|
5324
|
-
Alert.prototype.closable = function(closable = true) {
|
|
5325
|
-
this.$description.closable = !!closable;
|
|
5326
|
-
if(closable) {
|
|
5327
|
-
this.showIf(closable);
|
|
5328
|
-
}
|
|
5329
|
-
return this;
|
|
5330
|
-
};
|
|
5331
|
-
|
|
5332
|
-
/**
|
|
5333
|
-
* Sets whether the alert is dismissible (alias for closable)
|
|
5334
|
-
* @param {boolean} [dismissible=true] - Whether the alert is dismissible
|
|
5335
|
-
* @returns {Alert}
|
|
5336
|
-
*/
|
|
5337
|
-
Alert.prototype.dismissible = function(dismissible = true) {
|
|
5338
|
-
return this.closable(dismissible);
|
|
5339
|
-
};
|
|
5340
|
-
|
|
5341
|
-
/**
|
|
5342
|
-
* Sets auto-dismiss delay for the alert
|
|
5343
|
-
* @param {number} delay - Delay in milliseconds before auto-dismissing
|
|
5344
|
-
* @returns {Alert}
|
|
5345
|
-
*/
|
|
5346
|
-
Alert.prototype.autoDismiss = function(delay) {
|
|
5347
|
-
this.$description.autoDismiss = delay;
|
|
5348
|
-
return this;
|
|
5349
|
-
};
|
|
5350
|
-
|
|
5351
|
-
/**
|
|
5352
|
-
* Closes the alert
|
|
5353
|
-
*/
|
|
5354
|
-
Alert.prototype.close = function() {
|
|
5355
|
-
this.$description.showIf?.set(false);
|
|
5356
|
-
this.emit('hide');
|
|
5357
|
-
};
|
|
5358
|
-
|
|
5359
|
-
/**
|
|
5360
|
-
* Shows the alert
|
|
5361
|
-
*/
|
|
5362
|
-
Alert.prototype.show = function() {
|
|
5363
|
-
this.$description.showIf?.set(true);
|
|
5364
|
-
this.emit('show');
|
|
5365
|
-
};
|
|
5366
|
-
|
|
5367
|
-
/**
|
|
5368
|
-
* Hides the alert
|
|
5369
|
-
*/
|
|
5370
|
-
Alert.prototype.hide = Alert.prototype.close;
|
|
5371
|
-
|
|
5372
|
-
/**
|
|
5373
|
-
* Registers a handler for the close event
|
|
5374
|
-
* @param {(element: Alert) => void} handler - The event handler
|
|
5375
|
-
* @returns {Alert}
|
|
5376
|
-
*/
|
|
5377
|
-
Alert.prototype.onClose = function(handler) {
|
|
5378
|
-
this.on('close', handler);
|
|
5379
|
-
return this;
|
|
5380
|
-
};
|
|
5381
|
-
|
|
5382
|
-
/**
|
|
5383
|
-
* Registers a handler for the show event
|
|
5384
|
-
* @param {(element: Alert) => void} handler - The event handler
|
|
5385
|
-
* @returns {Alert}
|
|
5386
|
-
*/
|
|
5387
|
-
Alert.prototype.onShow = function(handler) {
|
|
5388
|
-
this.on('show', handler);
|
|
5389
|
-
return this;
|
|
5390
|
-
};
|
|
5391
|
-
|
|
5392
|
-
function Button(label, props = {}) {
|
|
5393
|
-
if(!(this instanceof Button)) {
|
|
5394
|
-
return new Button(label, props);
|
|
5395
|
-
}
|
|
5396
|
-
|
|
5397
|
-
BaseComponent.call(this, props);
|
|
5398
|
-
|
|
5399
|
-
this.$description = {
|
|
5400
|
-
label: label,
|
|
5401
|
-
type: null,
|
|
5402
|
-
variant: null,
|
|
5403
|
-
size: null,
|
|
5404
|
-
icon: null,
|
|
5405
|
-
iconPosition: 'left',
|
|
5406
|
-
loading: null,
|
|
5407
|
-
disabled: null,
|
|
5408
|
-
template: null,
|
|
5409
|
-
block: null,
|
|
5410
|
-
borderRadiusType: null,
|
|
5411
|
-
outline: null,
|
|
5412
|
-
props
|
|
5413
|
-
};
|
|
5414
|
-
|
|
5415
|
-
this.$element = null;
|
|
5416
|
-
}
|
|
5417
|
-
|
|
5418
|
-
Button.defaultTemplate = null;
|
|
5419
|
-
|
|
5420
|
-
Button.use = function(template = {}) {
|
|
5421
|
-
Button.defaultTemplate = template;
|
|
5422
|
-
};
|
|
5423
|
-
|
|
5424
|
-
BaseComponent.extends(Button);
|
|
5425
|
-
|
|
5426
|
-
Button.preset = function(name, callback) {
|
|
5427
|
-
if (Button.prototype[name] || Button[name]) {
|
|
5428
|
-
DebugManager$2.warn(`Warning: the ${name} method already exist in Button.`);
|
|
5429
|
-
return;
|
|
5430
|
-
}
|
|
5431
|
-
Button[name] = (label, props) => callback(new Button(label, props));
|
|
5432
|
-
};
|
|
5433
|
-
|
|
5434
|
-
Button.presets = function(presets) {
|
|
5435
|
-
for (const name in presets) {
|
|
5436
|
-
Button.preset(name, presets[name]);
|
|
5437
|
-
}
|
|
5438
|
-
};
|
|
5439
|
-
|
|
5440
|
-
Button.prototype.type = function(type) {
|
|
5441
|
-
this.$description.type = type;
|
|
5442
|
-
return this;
|
|
5443
|
-
};
|
|
5444
|
-
|
|
5445
|
-
Button.prototype.variant = function(variant) {
|
|
5446
|
-
this.$description.variant = variant;
|
|
5447
|
-
return this;
|
|
5448
|
-
};
|
|
5449
|
-
Button.prototype.primary = function() {
|
|
5450
|
-
return this.variant('primary');
|
|
5451
|
-
};
|
|
5452
|
-
Button.prototype.secondary = function() {
|
|
5453
|
-
return this.variant('secondary');
|
|
5454
|
-
};
|
|
5455
|
-
Button.prototype.danger = function() {
|
|
5456
|
-
return this.variant('danger');
|
|
5457
|
-
};
|
|
5458
|
-
Button.prototype.success = function() {
|
|
5459
|
-
return this.variant('success');
|
|
5460
|
-
};
|
|
5461
|
-
Button.prototype.warning = function() {
|
|
5462
|
-
return this.variant('warning');
|
|
5463
|
-
};
|
|
5464
|
-
Button.prototype.ghost = function() {
|
|
5465
|
-
return this.variant('ghost');
|
|
5466
|
-
};
|
|
5467
|
-
Button.prototype.link = function() {
|
|
5468
|
-
return this.variant('link');
|
|
5469
|
-
};
|
|
5470
|
-
Button.prototype.outline = function() {
|
|
5471
|
-
this.$description.outline = true;
|
|
5472
|
-
return this;
|
|
5473
|
-
};
|
|
5474
|
-
|
|
5475
|
-
Button.prototype.size = function(size) {
|
|
5476
|
-
this.$description.size = size;
|
|
5477
|
-
return this;
|
|
5478
|
-
};
|
|
5479
|
-
Button.prototype.small = function() {
|
|
5480
|
-
return this.size('small');
|
|
5481
|
-
};
|
|
5482
|
-
Button.prototype.large = function() {
|
|
5483
|
-
return this.size('large');
|
|
5484
|
-
};
|
|
5485
|
-
Button.prototype.medium = function() {
|
|
5486
|
-
return this.size('medium');
|
|
5487
|
-
};
|
|
5488
|
-
|
|
5489
|
-
Button.prototype.icon = function(icon, iconPosition = 'leading') {
|
|
5490
|
-
this.$description.icon = icon;
|
|
5491
|
-
this.$description.iconPosition = iconPosition;
|
|
5492
|
-
return this;
|
|
5493
|
-
};
|
|
5494
|
-
|
|
5495
|
-
Button.prototype.iconAtLeading = function() {
|
|
5496
|
-
this.$description.iconPosition = 'leading';
|
|
5497
|
-
return this;
|
|
5498
|
-
};
|
|
5499
|
-
|
|
5500
|
-
Button.prototype.iconAtTrailing = function() {
|
|
5501
|
-
this.$description.iconPosition = 'trailing';
|
|
5502
|
-
return this;
|
|
5503
|
-
};
|
|
5504
|
-
Button.prototype.iconAtTop = function() {
|
|
5505
|
-
this.$description.iconPosition = 'top';
|
|
3688
|
+
this.$description.icon = icon;
|
|
5506
3689
|
return this;
|
|
5507
3690
|
};
|
|
5508
3691
|
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
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;
|
|
5512
3699
|
};
|
|
5513
3700
|
|
|
5514
|
-
|
|
5515
|
-
|
|
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
|
+
}
|
|
5516
3711
|
return this;
|
|
5517
3712
|
};
|
|
5518
3713
|
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
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);
|
|
5522
3721
|
};
|
|
5523
3722
|
|
|
5524
|
-
|
|
5525
|
-
|
|
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;
|
|
5526
3730
|
return this;
|
|
5527
3731
|
};
|
|
5528
3732
|
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
3733
|
+
/**
|
|
3734
|
+
* Closes the alert
|
|
3735
|
+
*/
|
|
3736
|
+
Alert.prototype.close = function() {
|
|
3737
|
+
this.$description.showIf?.set(false);
|
|
3738
|
+
this.emit('hide');
|
|
5532
3739
|
};
|
|
5533
3740
|
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
this
|
|
5540
|
-
return this;
|
|
5541
|
-
};
|
|
5542
|
-
Button.prototype.circle = function() {
|
|
5543
|
-
this.$description.borderRadiusType = 'circle';
|
|
5544
|
-
return this;
|
|
3741
|
+
/**
|
|
3742
|
+
* Shows the alert
|
|
3743
|
+
*/
|
|
3744
|
+
Alert.prototype.show = function() {
|
|
3745
|
+
this.$description.showIf?.set(true);
|
|
3746
|
+
this.emit('show');
|
|
5545
3747
|
};
|
|
5546
|
-
|
|
5547
|
-
|
|
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);
|
|
5548
3761
|
return this;
|
|
5549
3762
|
};
|
|
5550
|
-
|
|
5551
|
-
|
|
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);
|
|
5552
3771
|
return this;
|
|
5553
3772
|
};
|
|
5554
3773
|
|
|
@@ -6188,6 +4407,169 @@ var NativeComponents = (function (exports) {
|
|
|
6188
4407
|
return this;
|
|
6189
4408
|
};
|
|
6190
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
|
+
|
|
6191
4573
|
function Card(config = {}) {
|
|
6192
4574
|
if(!(this instanceof Card)) {
|
|
6193
4575
|
return new Card(config);
|
|
@@ -8583,10 +6965,10 @@ var NativeComponents = (function (exports) {
|
|
|
8583
6965
|
errorsPosition: 'bottom',
|
|
8584
6966
|
errorsMapper: null,
|
|
8585
6967
|
renderErrors: null,
|
|
8586
|
-
submitting:
|
|
8587
|
-
errors:
|
|
8588
|
-
isDirty:
|
|
8589
|
-
isValid:
|
|
6968
|
+
submitting: $$1(false),
|
|
6969
|
+
errors: $$1(null),
|
|
6970
|
+
isDirty: $$1(false),
|
|
6971
|
+
isValid: $$1(false),
|
|
8590
6972
|
props
|
|
8591
6973
|
};
|
|
8592
6974
|
}
|
|
@@ -8628,7 +7010,7 @@ var NativeComponents = (function (exports) {
|
|
|
8628
7010
|
dirties.push(field.$description.isDirty);
|
|
8629
7011
|
}
|
|
8630
7012
|
|
|
8631
|
-
|
|
7013
|
+
$$1.computed(() => {
|
|
8632
7014
|
const isDirty = dirties.some((item) => item.val());
|
|
8633
7015
|
this.$description.isDirty.set(isDirty);
|
|
8634
7016
|
}, dirties);
|