jsf.js_next_gen 4.1.0-beta.15 → 4.1.0-beta.17
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/README.md +25 -0
- package/dist/docs/index.html +18 -1
- package/dist/window/faces-development.js +41 -31
- package/dist/window/faces-development.js.map +1 -1
- package/dist/window/faces.d.ts +16 -0
- package/dist/window/faces.js +1 -1
- package/dist/window/faces.js.map +1 -1
- package/dist/window/jsf-development.js +41 -31
- package/dist/window/jsf-development.js.map +1 -1
- package/dist/window/jsf.d.ts +16 -0
- package/dist/window/jsf.js +1 -1
- package/dist/window/jsf.js.map +1 -1
- package/package.json +2 -2
- package/scripts/build-dts.mjs +34 -0
- package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +115 -0
package/README.md
CHANGED
|
@@ -281,6 +281,31 @@ Tests
|
|
|
281
281
|
- Added tests for HiddenInputBuilder, Lang, and async queue
|
|
282
282
|
|
|
283
283
|
|
|
284
|
+
## 4.1.0-beta.17
|
|
285
|
+
|
|
286
|
+
- Bugfix: caret position regression on partial updates
|
|
287
|
+
- After typing into an input that triggers an ajax request, the keyboard caret jumped to
|
|
288
|
+
the beginning of the field (e.g. typing `123` resulted in `321`). This regressed in
|
|
289
|
+
`mona-dish` `0.50.0-beta.3`'s caret restoration and is fixed there; the focused input now
|
|
290
|
+
keeps its caret whether a partial response re-renders a different component or the input
|
|
291
|
+
itself.
|
|
292
|
+
- Dependency update
|
|
293
|
+
- Updated `mona-dish` to `0.50.0-beta.3`
|
|
294
|
+
- Tests added
|
|
295
|
+
- Added two protocol-level regression tests (`ResponseTest`) reproducing the Tobago
|
|
296
|
+
`<tc:in>`/`<tc:out>` scenario: typing `123` keeps the caret in order for both the
|
|
297
|
+
"re-render only the output" and the "re-render the input itself" cases.
|
|
298
|
+
|
|
299
|
+
## 4.1.0-beta.16
|
|
300
|
+
|
|
301
|
+
- Dependency update
|
|
302
|
+
- Updated `mona-dish` to `0.50.0-beta.2`
|
|
303
|
+
|
|
304
|
+
- Build / tooling improvements
|
|
305
|
+
- `dist/**`, `target/**`, `**/*.d.ts`, and `**/*.mjs` are now excluded from the `nyc` coverage report so only the implementation source is measured.
|
|
306
|
+
- Apache license header added to `dist/window/faces.d.ts` and `dist/window/jsf.d.ts` (prepended by the `build-dts` post-processing step).
|
|
307
|
+
- Apache license header added to `scripts/build-dts.mjs` and `webpack.config.ts`.
|
|
308
|
+
|
|
284
309
|
## 4.1.0-beta.15
|
|
285
310
|
|
|
286
311
|
- Tests added or expanded
|
package/dist/docs/index.html
CHANGED
|
@@ -249,6 +249,23 @@ enqueues on separate instances to cancel each other's debounce window</li>
|
|
|
249
249
|
<li>Added tests for ExtDomQuery (nonce DOM fallback, runHeadInserts text-node path) and ExtConfig (append, appendIf, deepCopy)</li>
|
|
250
250
|
<li>Added tests for HiddenInputBuilder, Lang, and async queue</li>
|
|
251
251
|
</ul>
|
|
252
|
+
<h2 id="410-beta16" class="tsd-anchor-link">4.1.0-beta.16<a href="#410-beta16" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
|
|
253
|
+
<ul>
|
|
254
|
+
<li>
|
|
255
|
+
<p>Dependency update</p>
|
|
256
|
+
<ul>
|
|
257
|
+
<li>Updated <code>mona-dish</code> to <code>0.50.0-beta.2</code></li>
|
|
258
|
+
</ul>
|
|
259
|
+
</li>
|
|
260
|
+
<li>
|
|
261
|
+
<p>Build / tooling improvements</p>
|
|
262
|
+
<ul>
|
|
263
|
+
<li><code>dist/**</code>, <code>target/**</code>, <code>**/*.d.ts</code>, and <code>**/*.mjs</code> are now excluded from the <code>nyc</code> coverage report so only the implementation source is measured.</li>
|
|
264
|
+
<li>Apache license header added to <code>dist/window/faces.d.ts</code> and <code>dist/window/jsf.d.ts</code> (prepended by the <code>build-dts</code> post-processing step).</li>
|
|
265
|
+
<li>Apache license header added to <code>scripts/build-dts.mjs</code> and <code>webpack.config.ts</code>.</li>
|
|
266
|
+
</ul>
|
|
267
|
+
</li>
|
|
268
|
+
</ul>
|
|
252
269
|
<h2 id="410-beta15" class="tsd-anchor-link">4.1.0-beta.15<a href="#410-beta15" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
|
|
253
270
|
<ul>
|
|
254
271
|
<li>
|
|
@@ -289,4 +306,4 @@ enqueues on separate instances to cancel each other's debounce window</li>
|
|
|
289
306
|
generative AI Tooling, as per <a href="https://www.apache.org/legal/generative-tooling.html">https://www.apache.org/legal/generative-tooling.html</a>
|
|
290
307
|
disclosures now are added!
|
|
291
308
|
See AI_CONTRIBUTIONS.md for full disclosure</p>
|
|
292
|
-
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#🚀-scratchpad-for-the-typescript-based-reimplementation-of-jsfjs"><span>🚀 <wbr/>Scratchpad for the <wbr/>Type<wbr/>Script-<wbr/>based reimplementation of jsf.js</span></a><ul><li><a href="#what-is-this"><span>What is this?</span></a></li><li><a href="#status"><span>Status</span></a></li><li><ul><li><a href="#special-info"><span>Special <wbr/>Info</span></a></li><li><a href="#general-build"><span>General <wbr/>Build</span></a></li><li><ul><li><a href="#on-windows"><span>On <wbr/>Windows</span></a></li></ul></li><li><a href="#tests"><span>Tests</span></a></li><li><a href="#test-coverage"><span>Test <wbr/>Coverage</span></a></li><li><a href="#changelist-compared-to-the-original-implementation"><span>Changelist compared to the original implementation</span></a></li></ul></li><li><a href="#upload-support"><span>Upload <wbr/>Support</span></a></li><li><a href="#changes-since-40"><span>Changes since 4.0</span></a></li><li><a href="#changes-since-410-beta-10"><span>Changes since 4.1.0-<wbr/>beta-<wbr/>10</span></a></li><li><a href="#410-beta15"><span>4.1.0-<wbr/>beta.15</span></a></li><li><a href="#410-beta13-410-beta14"><span>4.1.0-<wbr/>beta.13 / 4.1.0-<wbr/>beta.14</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">jsf.js_next_gen</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
309
|
+
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#🚀-scratchpad-for-the-typescript-based-reimplementation-of-jsfjs"><span>🚀 <wbr/>Scratchpad for the <wbr/>Type<wbr/>Script-<wbr/>based reimplementation of jsf.js</span></a><ul><li><a href="#what-is-this"><span>What is this?</span></a></li><li><a href="#status"><span>Status</span></a></li><li><ul><li><a href="#special-info"><span>Special <wbr/>Info</span></a></li><li><a href="#general-build"><span>General <wbr/>Build</span></a></li><li><ul><li><a href="#on-windows"><span>On <wbr/>Windows</span></a></li></ul></li><li><a href="#tests"><span>Tests</span></a></li><li><a href="#test-coverage"><span>Test <wbr/>Coverage</span></a></li><li><a href="#changelist-compared-to-the-original-implementation"><span>Changelist compared to the original implementation</span></a></li></ul></li><li><a href="#upload-support"><span>Upload <wbr/>Support</span></a></li><li><a href="#changes-since-40"><span>Changes since 4.0</span></a></li><li><a href="#changes-since-410-beta-10"><span>Changes since 4.1.0-<wbr/>beta-<wbr/>10</span></a></li><li><a href="#410-beta16"><span>4.1.0-<wbr/>beta.16</span></a></li><li><a href="#410-beta15"><span>4.1.0-<wbr/>beta.15</span></a></li><li><a href="#410-beta13-410-beta14"><span>4.1.0-<wbr/>beta.13 / 4.1.0-<wbr/>beta.14</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">jsf.js_next_gen</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
@@ -784,7 +784,9 @@ function waitUntilDom(root, condition, options = {
|
|
|
784
784
|
});
|
|
785
785
|
}
|
|
786
786
|
else { // fallback for legacy browsers without mutation observer
|
|
787
|
-
let interval
|
|
787
|
+
let interval;
|
|
788
|
+
let timeout;
|
|
789
|
+
interval = setInterval(() => {
|
|
788
790
|
let found = findElement(root, condition);
|
|
789
791
|
if (!!found) {
|
|
790
792
|
if (timeout) {
|
|
@@ -795,7 +797,7 @@ function waitUntilDom(root, condition, options = {
|
|
|
795
797
|
success(new DomQuery(found || root));
|
|
796
798
|
}
|
|
797
799
|
}, options.interval);
|
|
798
|
-
|
|
800
|
+
timeout = setTimeout(() => {
|
|
799
801
|
if (interval) {
|
|
800
802
|
clearInterval(interval);
|
|
801
803
|
error(MUT_ERROR);
|
|
@@ -823,7 +825,6 @@ class ElementAttribute extends _Monad__WEBPACK_IMPORTED_MODULE_0__.ValueEmbedder
|
|
|
823
825
|
for (let cnt = 0; cnt < val.length; cnt++) {
|
|
824
826
|
val[cnt].setAttribute(this.name, value);
|
|
825
827
|
}
|
|
826
|
-
val[0].setAttribute(this.name, value);
|
|
827
828
|
}
|
|
828
829
|
getClass() {
|
|
829
830
|
return ElementAttribute;
|
|
@@ -853,10 +854,10 @@ class Style extends _Monad__WEBPACK_IMPORTED_MODULE_0__.ValueEmbedder {
|
|
|
853
854
|
}
|
|
854
855
|
}
|
|
855
856
|
getClass() {
|
|
856
|
-
return
|
|
857
|
+
return Style;
|
|
857
858
|
}
|
|
858
859
|
static fromNullable(value, valueKey = "value") {
|
|
859
|
-
return new
|
|
860
|
+
return new Style(value, valueKey);
|
|
860
861
|
}
|
|
861
862
|
}
|
|
862
863
|
/**
|
|
@@ -1017,10 +1018,10 @@ class DomQuery {
|
|
|
1017
1018
|
}
|
|
1018
1019
|
get elements() {
|
|
1019
1020
|
// a simple querySelectorAll should suffice
|
|
1020
|
-
return this.querySelectorAll("input,
|
|
1021
|
+
return this.querySelectorAll("input, select, textarea, fieldset");
|
|
1021
1022
|
}
|
|
1022
1023
|
get deepElements() {
|
|
1023
|
-
let elemStr = "input, select, textarea,
|
|
1024
|
+
let elemStr = "input, select, textarea, fieldset";
|
|
1024
1025
|
return this.querySelectorAllDeep(elemStr);
|
|
1025
1026
|
}
|
|
1026
1027
|
/**
|
|
@@ -1165,7 +1166,6 @@ class DomQuery {
|
|
|
1165
1166
|
* @param markup the markup code to be executed from
|
|
1166
1167
|
*/
|
|
1167
1168
|
static fromMarkup(markup) {
|
|
1168
|
-
// https:// developer.mozilla.org/de/docs/Web/API/DOMParser license creative commons
|
|
1169
1169
|
const doc = document.implementation.createHTMLDocument("");
|
|
1170
1170
|
markup = trim(markup);
|
|
1171
1171
|
let lowerMarkup = markup.toLowerCase();
|
|
@@ -1184,19 +1184,17 @@ class DomQuery {
|
|
|
1184
1184
|
};
|
|
1185
1185
|
let dummyPlaceHolder = new DomQuery(document.createElement("div"));
|
|
1186
1186
|
// table needs special treatment due to the browsers auto creation
|
|
1187
|
-
if (startsWithTag(lowerMarkup, "thead")
|
|
1187
|
+
if (startsWithTag(lowerMarkup, "thead")
|
|
1188
|
+
|| startsWithTag(lowerMarkup, "tbody")
|
|
1189
|
+
|| startsWithTag(lowerMarkup, "tfoot")) {
|
|
1188
1190
|
dummyPlaceHolder.html(`<table>${markup}</table>`);
|
|
1189
1191
|
return dummyPlaceHolder.querySelectorAll("table").get(0).childNodes.detach();
|
|
1190
1192
|
}
|
|
1191
|
-
else if (startsWithTag(lowerMarkup, "tfoot")) {
|
|
1192
|
-
dummyPlaceHolder.html(`<table><thead></thead><tbody><tbody${markup}</table>`);
|
|
1193
|
-
return dummyPlaceHolder.querySelectorAll("table").get(2).childNodes.detach();
|
|
1194
|
-
}
|
|
1195
1193
|
else if (startsWithTag(lowerMarkup, "tr")) {
|
|
1196
1194
|
dummyPlaceHolder.html(`<table><tbody>${markup}</tbody></table>`);
|
|
1197
1195
|
return dummyPlaceHolder.querySelectorAll("tbody").get(0).childNodes.detach();
|
|
1198
1196
|
}
|
|
1199
|
-
else if (startsWithTag(lowerMarkup, "td")) {
|
|
1197
|
+
else if (startsWithTag(lowerMarkup, "td") || startsWithTag(lowerMarkup, "th")) {
|
|
1200
1198
|
dummyPlaceHolder.html(`<table><tbody><tr>${markup}</tr></tbody></table>`);
|
|
1201
1199
|
return dummyPlaceHolder.querySelectorAll("tr").get(0).childNodes.detach();
|
|
1202
1200
|
}
|
|
@@ -1502,14 +1500,14 @@ class DomQuery {
|
|
|
1502
1500
|
return this;
|
|
1503
1501
|
}
|
|
1504
1502
|
firstElem(func = item => item) {
|
|
1505
|
-
if (this.rootNode.length >
|
|
1503
|
+
if (this.rootNode.length > 0) {
|
|
1506
1504
|
func(this.rootNode[0], 0);
|
|
1507
1505
|
}
|
|
1508
1506
|
return this;
|
|
1509
1507
|
}
|
|
1510
1508
|
lastElem(func = item => item) {
|
|
1511
|
-
if (this.rootNode.length >
|
|
1512
|
-
func(this.rootNode[this.rootNode.length - 1],
|
|
1509
|
+
if (this.rootNode.length > 0) {
|
|
1510
|
+
func(this.rootNode[this.rootNode.length - 1], this.rootNode.length - 1);
|
|
1513
1511
|
}
|
|
1514
1512
|
return this;
|
|
1515
1513
|
}
|
|
@@ -1829,11 +1827,16 @@ class DomQuery {
|
|
|
1829
1827
|
if (this.isAbsent()) {
|
|
1830
1828
|
return undefined;
|
|
1831
1829
|
}
|
|
1832
|
-
let
|
|
1833
|
-
let
|
|
1830
|
+
let toReplace = this.getAsElem(0).value;
|
|
1831
|
+
let activeElement = document === null || document === void 0 ? void 0 : document.activeElement;
|
|
1832
|
+
let focusElementId = activeElement === null || activeElement === void 0 ? void 0 : activeElement.id;
|
|
1833
|
+
// only save/restore the caret if the focused element is actually part of the
|
|
1834
|
+
// subtree that gets replaced. Otherwise updating an unrelated component would
|
|
1835
|
+
// reset the caret of a different, still focused input field.
|
|
1836
|
+
let restoreFocus = !!focusElementId && !!((_a = toReplace === null || toReplace === void 0 ? void 0 : toReplace.contains) === null || _a === void 0 ? void 0 : _a.call(toReplace, activeElement));
|
|
1837
|
+
let caretPosition = restoreFocus ? DomQuery.getCaretPosition(activeElement) : null;
|
|
1834
1838
|
let nodes = DomQuery.fromMarkup(markup);
|
|
1835
1839
|
let res = [];
|
|
1836
|
-
let toReplace = this.getAsElem(0).value;
|
|
1837
1840
|
let firstInsert = nodes.get(0);
|
|
1838
1841
|
let parentNode = toReplace.parentNode;
|
|
1839
1842
|
let replaced = firstInsert.getAsElem(0).value;
|
|
@@ -1854,10 +1857,12 @@ class DomQuery {
|
|
|
1854
1857
|
if (runEmbeddedCss) {
|
|
1855
1858
|
this.runCss();
|
|
1856
1859
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1860
|
+
if (restoreFocus) {
|
|
1861
|
+
let focusElement = DomQuery.byId(focusElementId);
|
|
1862
|
+
if (focusElement.isPresent() &&
|
|
1863
|
+
caretPosition != null && "undefined" != typeof caretPosition) {
|
|
1864
|
+
focusElement.eachElem(item => DomQuery.setCaretPosition(item, caretPosition));
|
|
1865
|
+
}
|
|
1861
1866
|
}
|
|
1862
1867
|
return nodes;
|
|
1863
1868
|
}
|
|
@@ -2329,7 +2334,12 @@ class DomQuery {
|
|
|
2329
2334
|
static getCaretPosition(ctrl) {
|
|
2330
2335
|
let caretPos = 0;
|
|
2331
2336
|
try {
|
|
2332
|
-
if (
|
|
2337
|
+
if (typeof (ctrl === null || ctrl === void 0 ? void 0 : ctrl.selectionStart) === "number") {
|
|
2338
|
+
// modern browsers expose the caret position directly via selectionStart
|
|
2339
|
+
caretPos = ctrl.selectionStart;
|
|
2340
|
+
}
|
|
2341
|
+
else if (document === null || document === void 0 ? void 0 : document.selection) {
|
|
2342
|
+
// legacy IE fallback
|
|
2333
2343
|
ctrl.focus();
|
|
2334
2344
|
let selection = document.selection.createRange();
|
|
2335
2345
|
// the selection now is start zero
|
|
@@ -2357,7 +2367,7 @@ class DomQuery {
|
|
|
2357
2367
|
static setCaretPosition(ctrl, pos) {
|
|
2358
2368
|
(ctrl === null || ctrl === void 0 ? void 0 : ctrl.focus) ? ctrl === null || ctrl === void 0 ? void 0 : ctrl.focus() : null;
|
|
2359
2369
|
// the selection range is our caret position
|
|
2360
|
-
(ctrl === null || ctrl === void 0 ? void 0 : ctrl.
|
|
2370
|
+
(ctrl === null || ctrl === void 0 ? void 0 : ctrl.setSelectionRange) ? ctrl === null || ctrl === void 0 ? void 0 : ctrl.setSelectionRange(pos, pos) : null;
|
|
2361
2371
|
}
|
|
2362
2372
|
/**
|
|
2363
2373
|
* Implementation of an iterator
|
|
@@ -2975,8 +2985,6 @@ var Lang;
|
|
|
2975
2985
|
return it instanceof Function || typeof it === "function";
|
|
2976
2986
|
}
|
|
2977
2987
|
Lang.isFunc = isFunc;
|
|
2978
|
-
// code from https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
|
2979
|
-
// license https://creativecommons.org/licenses/by-sa/2.5/
|
|
2980
2988
|
function objAssign(target, ...theArgs) {
|
|
2981
2989
|
if (target == null) { // TypeError if undefined or null
|
|
2982
2990
|
throw new TypeError('Cannot convert undefined or null to object');
|
|
@@ -2988,9 +2996,11 @@ var Lang;
|
|
|
2988
2996
|
}
|
|
2989
2997
|
theArgs.filter(item => item != null).forEach(item => {
|
|
2990
2998
|
let nextSource = item;
|
|
2991
|
-
Object.keys(nextSource)
|
|
2992
|
-
|
|
2993
|
-
.
|
|
2999
|
+
const stringKeys = Object.keys(nextSource);
|
|
3000
|
+
const symbolKeys = Object.getOwnPropertySymbols(nextSource)
|
|
3001
|
+
.filter(sym => Object.prototype.propertyIsEnumerable.call(nextSource, sym));
|
|
3002
|
+
[...stringKeys, ...symbolKeys]
|
|
3003
|
+
.forEach(key => to[key] = nextSource[key]);
|
|
2994
3004
|
});
|
|
2995
3005
|
return to;
|
|
2996
3006
|
}
|