diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4addb1688eb..5255f903830 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -15,6 +15,7 @@ jobs: run: ./vendor/bin/php-cs-fixer fix --dry-run --diff coding-style-js: + name: JavaScript Coding Style runs-on: ubuntu-latest steps: - uses: actions/checkout@master @@ -33,6 +34,7 @@ jobs: - run: yarn check-format js-dist-current: + name: Check for UnBuilt JS Dist Files runs-on: ubuntu-latest steps: - uses: actions/checkout@master @@ -49,12 +51,18 @@ jobs: - run: yarn && yarn build - name: Check if js dist files are current id: changes - uses: UnicornGlobal/has-changes-action@v1.0.11 + run: | + echo "STATUS=$(git status --porcelain)" >> $GITHUB_OUTPUT - - name: Ensure no changes - if: steps.changes.outputs.changed == 1 + - name: No changes found + if: steps.changes.outputs.STATUS == '' + run: | + echo "git status is clean" + - name: Changes were found + if: steps.changes.outputs.STATUS != '' run: | echo "JS dist files need to be rebuilt" + echo "${{ steps.changes.outputs.STATUS }}" exit 1 tests-php-low-deps: diff --git a/src/Autocomplete/assets/dist/controller.js b/src/Autocomplete/assets/dist/controller.js index 855dee71074..f60c89418ba 100644 --- a/src/Autocomplete/assets/dist/controller.js +++ b/src/Autocomplete/assets/dist/controller.js @@ -1,25 +1,25 @@ import { Controller } from '@hotwired/stimulus'; import TomSelect from 'tom-select'; -/****************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ - -function __classPrivateFieldGet(receiver, state, kind, f) { - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ + +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } var _default_1_instances, _default_1_getCommonConfig, _default_1_createAutocomplete, _default_1_createAutocompleteWithHtmlContents, _default_1_createAutocompleteWithRemoteData, _default_1_stripTags, _default_1_mergeObjects, _default_1_createTomSelect; @@ -193,7 +193,7 @@ class default_1 extends Controller { this.resetTomSelect(); } if (changeDisabledState) { - this.changeTomSelectDisabledState((this.formElement.disabled)); + this.changeTomSelectDisabledState(this.formElement.disabled); } if (changePlaceholder) { this.updateTomSelectPlaceholder(); diff --git a/src/Chartjs/assets/dist/controller.js b/src/Chartjs/assets/dist/controller.js index 3002291f03a..76f0db9fe7c 100644 --- a/src/Chartjs/assets/dist/controller.js +++ b/src/Chartjs/assets/dist/controller.js @@ -30,7 +30,7 @@ class default_1 extends Controller { const parentElement = this.element.parentElement; if (parentElement && this.chart.options.responsive) { const originalWidth = parentElement.style.width; - parentElement.style.width = (parentElement.offsetWidth + 1) + 'px'; + parentElement.style.width = parentElement.offsetWidth + 1 + 'px'; setTimeout(() => { parentElement.style.width = originalWidth; }, 0); diff --git a/src/LiveComponent/assets/dist/ComponentRegistry.d.ts b/src/LiveComponent/assets/dist/ComponentRegistry.d.ts new file mode 100644 index 00000000000..216bfe53bd1 --- /dev/null +++ b/src/LiveComponent/assets/dist/ComponentRegistry.d.ts @@ -0,0 +1,9 @@ +import Component from './Component'; +declare class ComponentRegistry { + private components; + registerComponent(element: HTMLElement, definition: Component): void; + unregisterComponent(element: HTMLElement): void; + getComponent(element: HTMLElement): Promise; +} +declare const _default: ComponentRegistry; +export default _default; diff --git a/src/LiveComponent/assets/dist/live_controller.js b/src/LiveComponent/assets/dist/live_controller.js index a4771f33fd8..23a1c21c048 100644 --- a/src/LiveComponent/assets/dist/live_controller.js +++ b/src/LiveComponent/assets/dist/live_controller.js @@ -720,458 +720,463 @@ function noop() {} function defaultGetNodeKey(node) { if (node) { - return (node.getAttribute && node.getAttribute('id')) || node.id; + return (node.getAttribute && node.getAttribute('id')) || node.id; } } function morphdomFactory(morphAttrs) { - return function morphdom(fromNode, toNode, options) { - if (!options) { - options = {}; - } - - if (typeof toNode === 'string') { - if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML' || fromNode.nodeName === 'BODY') { - var toNodeHtml = toNode; - toNode = doc.createElement('html'); - toNode.innerHTML = toNodeHtml; - } else { - toNode = toElement(toNode); - } - } - - var getNodeKey = options.getNodeKey || defaultGetNodeKey; - var onBeforeNodeAdded = options.onBeforeNodeAdded || noop; - var onNodeAdded = options.onNodeAdded || noop; - var onBeforeElUpdated = options.onBeforeElUpdated || noop; - var onElUpdated = options.onElUpdated || noop; - var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop; - var onNodeDiscarded = options.onNodeDiscarded || noop; - var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop; - var childrenOnly = options.childrenOnly === true; - - // This object is used as a lookup to quickly find all keyed elements in the original DOM tree. - var fromNodesLookup = Object.create(null); - var keyedRemovalList = []; - - function addKeyedRemoval(key) { - keyedRemovalList.push(key); - } - - function walkDiscardedChildNodes(node, skipKeyedNodes) { - if (node.nodeType === ELEMENT_NODE) { - var curChild = node.firstChild; - while (curChild) { - - var key = undefined; - - if (skipKeyedNodes && (key = getNodeKey(curChild))) { - // If we are skipping keyed nodes then we add the key - // to a list so that it can be handled at the very end. - addKeyedRemoval(key); - } else { - // Only report the node as discarded if it is not keyed. We do this because - // at the end we loop through all keyed elements that were unmatched - // and then discard them in one final pass. - onNodeDiscarded(curChild); - if (curChild.firstChild) { - walkDiscardedChildNodes(curChild, skipKeyedNodes); - } - } - - curChild = curChild.nextSibling; - } - } - } - - /** - * Removes a DOM node out of the original DOM - * - * @param {Node} node The node to remove - * @param {Node} parentNode The nodes parent - * @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded. - * @return {undefined} - */ - function removeNode(node, parentNode, skipKeyedNodes) { - if (onBeforeNodeDiscarded(node) === false) { - return; - } - - if (parentNode) { - parentNode.removeChild(node); - } - - onNodeDiscarded(node); - walkDiscardedChildNodes(node, skipKeyedNodes); - } - - // // TreeWalker implementation is no faster, but keeping this around in case this changes in the future - // function indexTree(root) { - // var treeWalker = document.createTreeWalker( - // root, - // NodeFilter.SHOW_ELEMENT); - // - // var el; - // while((el = treeWalker.nextNode())) { - // var key = getNodeKey(el); - // if (key) { - // fromNodesLookup[key] = el; - // } - // } - // } - - // // NodeIterator implementation is no faster, but keeping this around in case this changes in the future - // - // function indexTree(node) { - // var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT); - // var el; - // while((el = nodeIterator.nextNode())) { - // var key = getNodeKey(el); - // if (key) { - // fromNodesLookup[key] = el; - // } - // } - // } - - function indexTree(node) { - if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) { - var curChild = node.firstChild; - while (curChild) { - var key = getNodeKey(curChild); - if (key) { - fromNodesLookup[key] = curChild; - } + return function morphdom(fromNode, toNode, options) { + if (!options) { + options = {}; + } - // Walk recursively - indexTree(curChild); + if (typeof toNode === 'string') { + if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML' || fromNode.nodeName === 'BODY') { + var toNodeHtml = toNode; + toNode = doc.createElement('html'); + toNode.innerHTML = toNodeHtml; + } else { + toNode = toElement(toNode); + } + } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) { + toNode = toNode.firstElementChild; + } - curChild = curChild.nextSibling; - } - } - } + var getNodeKey = options.getNodeKey || defaultGetNodeKey; + var onBeforeNodeAdded = options.onBeforeNodeAdded || noop; + var onNodeAdded = options.onNodeAdded || noop; + var onBeforeElUpdated = options.onBeforeElUpdated || noop; + var onElUpdated = options.onElUpdated || noop; + var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop; + var onNodeDiscarded = options.onNodeDiscarded || noop; + var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop; + var skipFromChildren = options.skipFromChildren || noop; + var addChild = options.addChild || function(parent, child){ return parent.appendChild(child); }; + var childrenOnly = options.childrenOnly === true; - indexTree(fromNode); + // This object is used as a lookup to quickly find all keyed elements in the original DOM tree. + var fromNodesLookup = Object.create(null); + var keyedRemovalList = []; - function handleNodeAdded(el) { - onNodeAdded(el); + function addKeyedRemoval(key) { + keyedRemovalList.push(key); + } - var curChild = el.firstChild; - while (curChild) { - var nextSibling = curChild.nextSibling; + function walkDiscardedChildNodes(node, skipKeyedNodes) { + if (node.nodeType === ELEMENT_NODE) { + var curChild = node.firstChild; + while (curChild) { - var key = getNodeKey(curChild); - if (key) { - var unmatchedFromEl = fromNodesLookup[key]; - // if we find a duplicate #id node in cache, replace `el` with cache value - // and morph it to the child node. - if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) { - curChild.parentNode.replaceChild(unmatchedFromEl, curChild); - morphEl(unmatchedFromEl, curChild); - } else { - handleNodeAdded(curChild); - } - } else { - // recursively call for curChild and it's children to see if we find something in - // fromNodesLookup - handleNodeAdded(curChild); - } + var key = undefined; - curChild = nextSibling; + if (skipKeyedNodes && (key = getNodeKey(curChild))) { + // If we are skipping keyed nodes then we add the key + // to a list so that it can be handled at the very end. + addKeyedRemoval(key); + } else { + // Only report the node as discarded if it is not keyed. We do this because + // at the end we loop through all keyed elements that were unmatched + // and then discard them in one final pass. + onNodeDiscarded(curChild); + if (curChild.firstChild) { + walkDiscardedChildNodes(curChild, skipKeyedNodes); } - } + } - function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) { - // We have processed all of the "to nodes". If curFromNodeChild is - // non-null then we still have some from nodes left over that need - // to be removed - while (curFromNodeChild) { - var fromNextSibling = curFromNodeChild.nextSibling; - if ((curFromNodeKey = getNodeKey(curFromNodeChild))) { - // Since the node is keyed it might be matched up later so we defer - // the actual removal to later - addKeyedRemoval(curFromNodeKey); - } else { - // NOTE: we skip nested keyed nodes from being removed since there is - // still a chance they will be matched up later - removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); - } - curFromNodeChild = fromNextSibling; - } + curChild = curChild.nextSibling; } + } + } - function morphEl(fromEl, toEl, childrenOnly) { - var toElKey = getNodeKey(toEl); - - if (toElKey) { - // If an element with an ID is being morphed then it will be in the final - // DOM so clear it out of the saved elements collection - delete fromNodesLookup[toElKey]; - } - - if (!childrenOnly) { - // optional - if (onBeforeElUpdated(fromEl, toEl) === false) { - return; - } - - // update attributes on original DOM element first - morphAttrs(fromEl, toEl); - // optional - onElUpdated(fromEl); - - if (onBeforeElChildrenUpdated(fromEl, toEl) === false) { - return; - } - } - - if (fromEl.nodeName !== 'TEXTAREA') { - morphChildren(fromEl, toEl); - } else { - specialElHandlers.TEXTAREA(fromEl, toEl); - } + /** + * Removes a DOM node out of the original DOM + * + * @param {Node} node The node to remove + * @param {Node} parentNode The nodes parent + * @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded. + * @return {undefined} + */ + function removeNode(node, parentNode, skipKeyedNodes) { + if (onBeforeNodeDiscarded(node) === false) { + return; + } + + if (parentNode) { + parentNode.removeChild(node); + } + + onNodeDiscarded(node); + walkDiscardedChildNodes(node, skipKeyedNodes); + } + + // // TreeWalker implementation is no faster, but keeping this around in case this changes in the future + // function indexTree(root) { + // var treeWalker = document.createTreeWalker( + // root, + // NodeFilter.SHOW_ELEMENT); + // + // var el; + // while((el = treeWalker.nextNode())) { + // var key = getNodeKey(el); + // if (key) { + // fromNodesLookup[key] = el; + // } + // } + // } + + // // NodeIterator implementation is no faster, but keeping this around in case this changes in the future + // + // function indexTree(node) { + // var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT); + // var el; + // while((el = nodeIterator.nextNode())) { + // var key = getNodeKey(el); + // if (key) { + // fromNodesLookup[key] = el; + // } + // } + // } + + function indexTree(node) { + if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) { + var curChild = node.firstChild; + while (curChild) { + var key = getNodeKey(curChild); + if (key) { + fromNodesLookup[key] = curChild; + } + + // Walk recursively + indexTree(curChild); + + curChild = curChild.nextSibling; + } + } + } + + indexTree(fromNode); + + function handleNodeAdded(el) { + onNodeAdded(el); + + var curChild = el.firstChild; + while (curChild) { + var nextSibling = curChild.nextSibling; + + var key = getNodeKey(curChild); + if (key) { + var unmatchedFromEl = fromNodesLookup[key]; + // if we find a duplicate #id node in cache, replace `el` with cache value + // and morph it to the child node. + if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) { + curChild.parentNode.replaceChild(unmatchedFromEl, curChild); + morphEl(unmatchedFromEl, curChild); + } else { + handleNodeAdded(curChild); + } + } else { + // recursively call for curChild and it's children to see if we find something in + // fromNodesLookup + handleNodeAdded(curChild); } - function morphChildren(fromEl, toEl) { - var curToNodeChild = toEl.firstChild; - var curFromNodeChild = fromEl.firstChild; - var curToNodeKey; - var curFromNodeKey; - - var fromNextSibling; - var toNextSibling; - var matchingFromEl; - - // walk the children - outer: while (curToNodeChild) { - toNextSibling = curToNodeChild.nextSibling; - curToNodeKey = getNodeKey(curToNodeChild); + curChild = nextSibling; + } + } - // walk the fromNode children all the way through - while (curFromNodeChild) { - fromNextSibling = curFromNodeChild.nextSibling; + function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) { + // We have processed all of the "to nodes". If curFromNodeChild is + // non-null then we still have some from nodes left over that need + // to be removed + while (curFromNodeChild) { + var fromNextSibling = curFromNodeChild.nextSibling; + if ((curFromNodeKey = getNodeKey(curFromNodeChild))) { + // Since the node is keyed it might be matched up later so we defer + // the actual removal to later + addKeyedRemoval(curFromNodeKey); + } else { + // NOTE: we skip nested keyed nodes from being removed since there is + // still a chance they will be matched up later + removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); + } + curFromNodeChild = fromNextSibling; + } + } + + function morphEl(fromEl, toEl, childrenOnly) { + var toElKey = getNodeKey(toEl); + + if (toElKey) { + // If an element with an ID is being morphed then it will be in the final + // DOM so clear it out of the saved elements collection + delete fromNodesLookup[toElKey]; + } + + if (!childrenOnly) { + // optional + if (onBeforeElUpdated(fromEl, toEl) === false) { + return; + } + + // update attributes on original DOM element first + morphAttrs(fromEl, toEl); + // optional + onElUpdated(fromEl); + + if (onBeforeElChildrenUpdated(fromEl, toEl) === false) { + return; + } + } + + if (fromEl.nodeName !== 'TEXTAREA') { + morphChildren(fromEl, toEl); + } else { + specialElHandlers.TEXTAREA(fromEl, toEl); + } + } + + function morphChildren(fromEl, toEl) { + var skipFrom = skipFromChildren(fromEl); + var curToNodeChild = toEl.firstChild; + var curFromNodeChild = fromEl.firstChild; + var curToNodeKey; + var curFromNodeKey; + + var fromNextSibling; + var toNextSibling; + var matchingFromEl; + + // walk the children + outer: while (curToNodeChild) { + toNextSibling = curToNodeChild.nextSibling; + curToNodeKey = getNodeKey(curToNodeChild); + + // walk the fromNode children all the way through + while (!skipFrom && curFromNodeChild) { + fromNextSibling = curFromNodeChild.nextSibling; + + if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) { + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + continue outer; + } + + curFromNodeKey = getNodeKey(curFromNodeChild); + + var curFromNodeType = curFromNodeChild.nodeType; + + // this means if the curFromNodeChild doesnt have a match with the curToNodeChild + var isCompatible = undefined; + + if (curFromNodeType === curToNodeChild.nodeType) { + if (curFromNodeType === ELEMENT_NODE) { + // Both nodes being compared are Element nodes + + if (curToNodeKey) { + // The target node has a key so we want to match it up with the correct element + // in the original DOM tree + if (curToNodeKey !== curFromNodeKey) { + // The current element in the original DOM tree does not have a matching key so + // let's check our lookup to see if there is a matching element in the original + // DOM tree + if ((matchingFromEl = fromNodesLookup[curToNodeKey])) { + if (fromNextSibling === matchingFromEl) { + // Special case for single element removals. To avoid removing the original + // DOM node out of the tree (since that can break CSS transitions, etc.), + // we will instead discard the current node and wait until the next + // iteration to properly match up the keyed target element with its matching + // element in the original tree + isCompatible = false; + } else { + // We found a matching keyed element somewhere in the original DOM tree. + // Let's move the original DOM node into the current position and morph + // it. - if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) { - curToNodeChild = toNextSibling; - curFromNodeChild = fromNextSibling; - continue outer; - } + // NOTE: We use insertBefore instead of replaceChild because we want to go through + // the `removeNode()` function for the node that is being discarded so that + // all lifecycle hooks are correctly invoked + fromEl.insertBefore(matchingFromEl, curFromNodeChild); - curFromNodeKey = getNodeKey(curFromNodeChild); - - var curFromNodeType = curFromNodeChild.nodeType; - - // this means if the curFromNodeChild doesnt have a match with the curToNodeChild - var isCompatible = undefined; - - if (curFromNodeType === curToNodeChild.nodeType) { - if (curFromNodeType === ELEMENT_NODE) { - // Both nodes being compared are Element nodes - - if (curToNodeKey) { - // The target node has a key so we want to match it up with the correct element - // in the original DOM tree - if (curToNodeKey !== curFromNodeKey) { - // The current element in the original DOM tree does not have a matching key so - // let's check our lookup to see if there is a matching element in the original - // DOM tree - if ((matchingFromEl = fromNodesLookup[curToNodeKey])) { - if (fromNextSibling === matchingFromEl) { - // Special case for single element removals. To avoid removing the original - // DOM node out of the tree (since that can break CSS transitions, etc.), - // we will instead discard the current node and wait until the next - // iteration to properly match up the keyed target element with its matching - // element in the original tree - isCompatible = false; - } else { - // We found a matching keyed element somewhere in the original DOM tree. - // Let's move the original DOM node into the current position and morph - // it. - - // NOTE: We use insertBefore instead of replaceChild because we want to go through - // the `removeNode()` function for the node that is being discarded so that - // all lifecycle hooks are correctly invoked - fromEl.insertBefore(matchingFromEl, curFromNodeChild); - - // fromNextSibling = curFromNodeChild.nextSibling; - - if (curFromNodeKey) { - // Since the node is keyed it might be matched up later so we defer - // the actual removal to later - addKeyedRemoval(curFromNodeKey); - } else { - // NOTE: we skip nested keyed nodes from being removed since there is - // still a chance they will be matched up later - removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); - } - - curFromNodeChild = matchingFromEl; - } - } else { - // The nodes are not compatible since the "to" node has a key and there - // is no matching keyed node in the source tree - isCompatible = false; - } - } - } else if (curFromNodeKey) { - // The original has a key - isCompatible = false; - } - - isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild); - if (isCompatible) { - // We found compatible DOM elements so transform - // the current "from" node to match the current - // target DOM node. - // MORPH - morphEl(curFromNodeChild, curToNodeChild); - } - - } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) { - // Both nodes being compared are Text or Comment nodes - isCompatible = true; - // Simply update nodeValue on the original node to - // change the text value - if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) { - curFromNodeChild.nodeValue = curToNodeChild.nodeValue; - } + // fromNextSibling = curFromNodeChild.nextSibling; - } - } - - if (isCompatible) { - // Advance both the "to" child and the "from" child since we found a match - // Nothing else to do as we already recursively called morphChildren above - curToNodeChild = toNextSibling; - curFromNodeChild = fromNextSibling; - continue outer; - } - - // No compatible match so remove the old node from the DOM and continue trying to find a - // match in the original DOM. However, we only do this if the from node is not keyed - // since it is possible that a keyed node might match up with a node somewhere else in the - // target tree and we don't want to discard it just yet since it still might find a - // home in the final DOM tree. After everything is done we will remove any keyed nodes - // that didn't find a home - if (curFromNodeKey) { + if (curFromNodeKey) { // Since the node is keyed it might be matched up later so we defer // the actual removal to later addKeyedRemoval(curFromNodeKey); - } else { + } else { // NOTE: we skip nested keyed nodes from being removed since there is // still a chance they will be matched up later removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); - } - - curFromNodeChild = fromNextSibling; - } // END: while(curFromNodeChild) {} - - // If we got this far then we did not find a candidate match for - // our "to node" and we exhausted all of the children "from" - // nodes. Therefore, we will just append the current "to" node - // to the end - if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) { - fromEl.appendChild(matchingFromEl); - // MORPH - morphEl(matchingFromEl, curToNodeChild); - } else { - var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild); - if (onBeforeNodeAddedResult !== false) { - if (onBeforeNodeAddedResult) { - curToNodeChild = onBeforeNodeAddedResult; - } + } - if (curToNodeChild.actualize) { - curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc); - } - fromEl.appendChild(curToNodeChild); - handleNodeAdded(curToNodeChild); + curFromNodeChild = matchingFromEl; } + } else { + // The nodes are not compatible since the "to" node has a key and there + // is no matching keyed node in the source tree + isCompatible = false; + } } - - curToNodeChild = toNextSibling; - curFromNodeChild = fromNextSibling; + } else if (curFromNodeKey) { + // The original has a key + isCompatible = false; + } + + isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild); + if (isCompatible) { + // We found compatible DOM elements so transform + // the current "from" node to match the current + // target DOM node. + // MORPH + morphEl(curFromNodeChild, curToNodeChild); + } + + } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) { + // Both nodes being compared are Text or Comment nodes + isCompatible = true; + // Simply update nodeValue on the original node to + // change the text value + if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) { + curFromNodeChild.nodeValue = curToNodeChild.nodeValue; + } + + } + } + + if (isCompatible) { + // Advance both the "to" child and the "from" child since we found a match + // Nothing else to do as we already recursively called morphChildren above + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + continue outer; + } + + // No compatible match so remove the old node from the DOM and continue trying to find a + // match in the original DOM. However, we only do this if the from node is not keyed + // since it is possible that a keyed node might match up with a node somewhere else in the + // target tree and we don't want to discard it just yet since it still might find a + // home in the final DOM tree. After everything is done we will remove any keyed nodes + // that didn't find a home + if (curFromNodeKey) { + // Since the node is keyed it might be matched up later so we defer + // the actual removal to later + addKeyedRemoval(curFromNodeKey); + } else { + // NOTE: we skip nested keyed nodes from being removed since there is + // still a chance they will be matched up later + removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); + } + + curFromNodeChild = fromNextSibling; + } // END: while(curFromNodeChild) {} + + // If we got this far then we did not find a candidate match for + // our "to node" and we exhausted all of the children "from" + // nodes. Therefore, we will just append the current "to" node + // to the end + if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) { + // MORPH + if(!skipFrom){ addChild(fromEl, matchingFromEl); } + morphEl(matchingFromEl, curToNodeChild); + } else { + var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild); + if (onBeforeNodeAddedResult !== false) { + if (onBeforeNodeAddedResult) { + curToNodeChild = onBeforeNodeAddedResult; } - cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey); - - var specialElHandler = specialElHandlers[fromEl.nodeName]; - if (specialElHandler) { - specialElHandler(fromEl, toEl); + if (curToNodeChild.actualize) { + curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc); } - } // END: morphChildren(...) + addChild(fromEl, curToNodeChild); + handleNodeAdded(curToNodeChild); + } + } - var morphedNode = fromNode; - var morphedNodeType = morphedNode.nodeType; - var toNodeType = toNode.nodeType; + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + } - if (!childrenOnly) { - // Handle the case where we are given two DOM nodes that are not - // compatible (e.g.
--> or
--> TEXT) - if (morphedNodeType === ELEMENT_NODE) { - if (toNodeType === ELEMENT_NODE) { - if (!compareNodeNames(fromNode, toNode)) { - onNodeDiscarded(fromNode); - morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI)); - } - } else { - // Going from an element node to a text node - morphedNode = toNode; - } - } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { // Text or comment node - if (toNodeType === morphedNodeType) { - if (morphedNode.nodeValue !== toNode.nodeValue) { - morphedNode.nodeValue = toNode.nodeValue; - } + cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey); - return morphedNode; - } else { - // Text node to something else - morphedNode = toNode; - } - } - } + var specialElHandler = specialElHandlers[fromEl.nodeName]; + if (specialElHandler) { + specialElHandler(fromEl, toEl); + } + } // END: morphChildren(...) + + var morphedNode = fromNode; + var morphedNodeType = morphedNode.nodeType; + var toNodeType = toNode.nodeType; - if (morphedNode === toNode) { - // The "to node" was not compatible with the "from node" so we had to - // toss out the "from node" and use the "to node" + if (!childrenOnly) { + // Handle the case where we are given two DOM nodes that are not + // compatible (e.g.
--> or
--> TEXT) + if (morphedNodeType === ELEMENT_NODE) { + if (toNodeType === ELEMENT_NODE) { + if (!compareNodeNames(fromNode, toNode)) { onNodeDiscarded(fromNode); + morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI)); + } } else { - if (toNode.isSameNode && toNode.isSameNode(morphedNode)) { - return; - } - - morphEl(morphedNode, toNode, childrenOnly); - - // We now need to loop over any keyed nodes that might need to be - // removed. We only do the removal if we know that the keyed node - // never found a match. When a keyed node is matched up we remove - // it out of fromNodesLookup and we use fromNodesLookup to determine - // if a keyed node has been matched up or not - if (keyedRemovalList) { - for (var i=0, len=keyedRemovalList.length; i ComponentRegistry$1.getComponent(element); diff --git a/src/LiveComponent/assets/src/ComponentRegistry.ts b/src/LiveComponent/assets/src/ComponentRegistry.ts index b1c87b68965..154f05aa838 100644 --- a/src/LiveComponent/assets/src/ComponentRegistry.ts +++ b/src/LiveComponent/assets/src/ComponentRegistry.ts @@ -1,7 +1,7 @@ import Component from './Component'; import { getElementAsTagText } from './dom_utils'; -const ComponentRegistry = class { +class ComponentRegistry { private components = new WeakMap(); public registerComponent(element: HTMLElement, definition: Component) { @@ -30,6 +30,6 @@ const ComponentRegistry = class { }, 5); }); } -}; +} export default new ComponentRegistry(); diff --git a/src/Notify/assets/dist/controller.d.ts b/src/Notify/assets/dist/controller.d.ts index 1ceb30e1577..73ba68163eb 100644 --- a/src/Notify/assets/dist/controller.d.ts +++ b/src/Notify/assets/dist/controller.d.ts @@ -4,7 +4,12 @@ export default class extends Controller { hub: StringConstructor; topics: ArrayConstructor; }; + hubValue: string; + topicsValue: Array; + readonly hasHubValue: boolean; + readonly hasTopicsValue: boolean; eventSources: Array; + listeners: WeakMap void>; initialize(): void; connect(): void; disconnect(): void; diff --git a/src/Notify/assets/dist/controller.js b/src/Notify/assets/dist/controller.js index d48f7c961a0..7350487c71d 100644 --- a/src/Notify/assets/dist/controller.js +++ b/src/Notify/assets/dist/controller.js @@ -4,6 +4,7 @@ class default_1 extends Controller { constructor() { super(...arguments); this.eventSources = []; + this.listeners = new WeakMap(); } initialize() { const errorMessages = []; @@ -25,13 +26,18 @@ class default_1 extends Controller { return; } this.eventSources.forEach((eventSource) => { - eventSource.addEventListener('message', (event) => this._notify(JSON.parse(event.data).summary)); + const listener = (event) => this._notify(JSON.parse(event.data).summary); + eventSource.addEventListener('message', listener); + this.listeners.set(eventSource, listener); }); this.dispatchEvent('connect', { eventSources: this.eventSources }); } disconnect() { this.eventSources.forEach((eventSource) => { - eventSource.removeEventListener('message', this._notify); + const listener = this.listeners.get(eventSource); + if (listener) { + eventSource.removeEventListener('message', listener); + } eventSource.close(); }); this.eventSources = []; diff --git a/src/Notify/assets/src/controller.ts b/src/Notify/assets/src/controller.ts index 01ab6f97807..45dc0d1da24 100644 --- a/src/Notify/assets/src/controller.ts +++ b/src/Notify/assets/src/controller.ts @@ -19,8 +19,13 @@ export default class extends Controller { hub: String, topics: Array, }; + declare hubValue: string; + declare topicsValue: Array; + declare readonly hasHubValue: boolean; + declare readonly hasTopicsValue: boolean; eventSources: Array = []; + listeners: WeakMap void> = new WeakMap(); initialize() { const errorMessages: Array = []; @@ -46,7 +51,9 @@ export default class extends Controller { } this.eventSources.forEach((eventSource) => { - eventSource.addEventListener('message', (event) => this._notify(JSON.parse(event.data).summary)); + const listener = (event: MessageEvent) => this._notify(JSON.parse(event.data).summary); + eventSource.addEventListener('message', listener); + this.listeners.set(eventSource, listener); }); this.dispatchEvent('connect', { eventSources: this.eventSources }); @@ -54,7 +61,11 @@ export default class extends Controller { disconnect() { this.eventSources.forEach((eventSource) => { - eventSource.removeEventListener('message', this._notify); + const listener = this.listeners.get(eventSource); + if (listener) { + eventSource.removeEventListener('message', listener); + } + eventSource.close(); }); diff --git a/src/Swup/assets/src/index.d.ts b/src/Swup/assets/src/index.d.ts new file mode 100644 index 00000000000..784797fca74 --- /dev/null +++ b/src/Swup/assets/src/index.d.ts @@ -0,0 +1,5 @@ +declare module 'swup'; +declare module '@swup/debug-plugin'; +declare module '@swup/forms-plugin'; +declare module '@swup/fade-theme'; +declare module '@swup/slide-theme';