katalyst-content 2.1.3 → 2.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/builds/katalyst/content.esm.js +16 -12
- data/app/assets/builds/katalyst/content.js +16 -12
- data/app/assets/builds/katalyst/content.min.js.map +1 -1
- data/app/assets/stylesheets/katalyst/content/editor/_new-items.scss +3 -1
- data/app/controllers/katalyst/content/items_controller.rb +5 -0
- data/app/helpers/katalyst/content/editor_helper.rb +0 -5
- data/app/javascript/content/editor/item.js +2 -2
- data/app/javascript/content/editor/list_controller.js +13 -9
- data/app/javascript/content/editor/rules_engine.js +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b50224f8e89fbbd50126fa63ba778221581ca75d5ed7575769a95aaf04ded1f
|
4
|
+
data.tar.gz: 78606bfded562ff50f64c7869a9ac302049d485c0e7eab4fffea0cb40e5543eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 797dc99adbd0f39847b53230cabd34e715c3b988bd2babc76c19e6e20a6fc2dac93406bdeb14d1773642500c5c031e3ec9370f8aa4109a573e3ec79a1f6f40f5
|
7
|
+
data.tar.gz: ace93a48f4dcd164cc87aecfb13a4ad1e4becb88e431ba08625a2e5835277f4a5b6b51fd92d7ecc7daa2b7da6f795be9abc752df98196bded5323a390436c129
|
@@ -171,7 +171,7 @@ class Item {
|
|
171
171
|
if (!listElement) listElement = createChildrenList(this.node);
|
172
172
|
|
173
173
|
this.#expandedDescendants.forEach((child) =>
|
174
|
-
listElement.appendChild(child.node)
|
174
|
+
listElement.appendChild(child.node),
|
175
175
|
);
|
176
176
|
}
|
177
177
|
|
@@ -262,7 +262,7 @@ class Item {
|
|
262
262
|
if (!this.hasCollapsedDescendants()) return [];
|
263
263
|
|
264
264
|
return Array.from(this.#childrenListElement.children).map(
|
265
|
-
(node) => new Item(node)
|
265
|
+
(node) => new Item(node),
|
266
266
|
);
|
267
267
|
}
|
268
268
|
}
|
@@ -428,7 +428,7 @@ class RulesEngine {
|
|
428
428
|
this.debug(
|
429
429
|
`invalid depth on item ${item.index}: ${item.depth} => ${
|
430
430
|
previous.depth + 1
|
431
|
-
}
|
431
|
+
}`,
|
432
432
|
);
|
433
433
|
|
434
434
|
item.depth = previous.depth + 1;
|
@@ -446,7 +446,7 @@ class RulesEngine {
|
|
446
446
|
const previous = item.previousItem;
|
447
447
|
if (previous && previous.depth < item.depth && !previous.isLayout) {
|
448
448
|
this.debug(
|
449
|
-
`invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}
|
449
|
+
`invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}`,
|
450
450
|
);
|
451
451
|
|
452
452
|
item.depth = previous.depth;
|
@@ -816,7 +816,10 @@ class ListController extends Controller {
|
|
816
816
|
// https://bugs.webkit.org/show_bug.cgi?id=66547
|
817
817
|
this.enterCount--;
|
818
818
|
|
819
|
-
if (
|
819
|
+
if (
|
820
|
+
this.enterCount <= 0 &&
|
821
|
+
this.dragItem.dataset.hasOwnProperty("newItem")
|
822
|
+
) {
|
820
823
|
this.cancelDrag(event);
|
821
824
|
}
|
822
825
|
}
|
@@ -846,11 +849,11 @@ class ListController extends Controller {
|
|
846
849
|
|
847
850
|
this.element.replaceChild(item, placeholder);
|
848
851
|
requestAnimationFrame(() =>
|
849
|
-
item.querySelector("[role='button'][value='edit']").click()
|
852
|
+
item.querySelector("[role='button'][value='edit']").click(),
|
850
853
|
);
|
851
854
|
}
|
852
855
|
|
853
|
-
this.dispatch("drop", {target: item, bubbles: true, prefix: "content"});
|
856
|
+
this.dispatch("drop", { target: item, bubbles: true, prefix: "content" });
|
854
857
|
}
|
855
858
|
|
856
859
|
/**
|
@@ -877,11 +880,11 @@ class ListController extends Controller {
|
|
877
880
|
}
|
878
881
|
|
879
882
|
reindex() {
|
880
|
-
this.dispatch("reindex", {bubbles: true, prefix: "content"});
|
883
|
+
this.dispatch("reindex", { bubbles: true, prefix: "content" });
|
881
884
|
}
|
882
885
|
|
883
886
|
reset() {
|
884
|
-
this.dispatch("reset", {bubbles: true, prefix: "content"});
|
887
|
+
this.dispatch("reset", { bubbles: true, prefix: "content" });
|
885
888
|
}
|
886
889
|
}
|
887
890
|
|
@@ -925,9 +928,10 @@ function copyAllowed(event) {
|
|
925
928
|
* Given an event target, return the closest drop target, if any.
|
926
929
|
*/
|
927
930
|
function dropTarget(e) {
|
928
|
-
return
|
929
|
-
e
|
930
|
-
e.closest("[data-controller='content--editor--list']")
|
931
|
+
return (
|
932
|
+
e &&
|
933
|
+
(e.closest("[data-controller='content--editor--list'] > *") ||
|
934
|
+
e.closest("[data-controller='content--editor--list']"))
|
931
935
|
);
|
932
936
|
}
|
933
937
|
|
@@ -171,7 +171,7 @@ class Item {
|
|
171
171
|
if (!listElement) listElement = createChildrenList(this.node);
|
172
172
|
|
173
173
|
this.#expandedDescendants.forEach((child) =>
|
174
|
-
listElement.appendChild(child.node)
|
174
|
+
listElement.appendChild(child.node),
|
175
175
|
);
|
176
176
|
}
|
177
177
|
|
@@ -262,7 +262,7 @@ class Item {
|
|
262
262
|
if (!this.hasCollapsedDescendants()) return [];
|
263
263
|
|
264
264
|
return Array.from(this.#childrenListElement.children).map(
|
265
|
-
(node) => new Item(node)
|
265
|
+
(node) => new Item(node),
|
266
266
|
);
|
267
267
|
}
|
268
268
|
}
|
@@ -428,7 +428,7 @@ class RulesEngine {
|
|
428
428
|
this.debug(
|
429
429
|
`invalid depth on item ${item.index}: ${item.depth} => ${
|
430
430
|
previous.depth + 1
|
431
|
-
}
|
431
|
+
}`,
|
432
432
|
);
|
433
433
|
|
434
434
|
item.depth = previous.depth + 1;
|
@@ -446,7 +446,7 @@ class RulesEngine {
|
|
446
446
|
const previous = item.previousItem;
|
447
447
|
if (previous && previous.depth < item.depth && !previous.isLayout) {
|
448
448
|
this.debug(
|
449
|
-
`invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}
|
449
|
+
`invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}`,
|
450
450
|
);
|
451
451
|
|
452
452
|
item.depth = previous.depth;
|
@@ -816,7 +816,10 @@ class ListController extends Controller {
|
|
816
816
|
// https://bugs.webkit.org/show_bug.cgi?id=66547
|
817
817
|
this.enterCount--;
|
818
818
|
|
819
|
-
if (
|
819
|
+
if (
|
820
|
+
this.enterCount <= 0 &&
|
821
|
+
this.dragItem.dataset.hasOwnProperty("newItem")
|
822
|
+
) {
|
820
823
|
this.cancelDrag(event);
|
821
824
|
}
|
822
825
|
}
|
@@ -846,11 +849,11 @@ class ListController extends Controller {
|
|
846
849
|
|
847
850
|
this.element.replaceChild(item, placeholder);
|
848
851
|
requestAnimationFrame(() =>
|
849
|
-
item.querySelector("[role='button'][value='edit']").click()
|
852
|
+
item.querySelector("[role='button'][value='edit']").click(),
|
850
853
|
);
|
851
854
|
}
|
852
855
|
|
853
|
-
this.dispatch("drop", {target: item, bubbles: true, prefix: "content"});
|
856
|
+
this.dispatch("drop", { target: item, bubbles: true, prefix: "content" });
|
854
857
|
}
|
855
858
|
|
856
859
|
/**
|
@@ -877,11 +880,11 @@ class ListController extends Controller {
|
|
877
880
|
}
|
878
881
|
|
879
882
|
reindex() {
|
880
|
-
this.dispatch("reindex", {bubbles: true, prefix: "content"});
|
883
|
+
this.dispatch("reindex", { bubbles: true, prefix: "content" });
|
881
884
|
}
|
882
885
|
|
883
886
|
reset() {
|
884
|
-
this.dispatch("reset", {bubbles: true, prefix: "content"});
|
887
|
+
this.dispatch("reset", { bubbles: true, prefix: "content" });
|
885
888
|
}
|
886
889
|
}
|
887
890
|
|
@@ -925,9 +928,10 @@ function copyAllowed(event) {
|
|
925
928
|
* Given an event target, return the closest drop target, if any.
|
926
929
|
*/
|
927
930
|
function dropTarget(e) {
|
928
|
-
return
|
929
|
-
e
|
930
|
-
e.closest("[data-controller='content--editor--list']")
|
931
|
+
return (
|
932
|
+
e &&
|
933
|
+
(e.closest("[data-controller='content--editor--list'] > *") ||
|
934
|
+
e.closest("[data-controller='content--editor--list']"))
|
931
935
|
);
|
932
936
|
}
|
933
937
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"content.min.js","sources":["../../../javascript/content/editor/item.js","../../../javascript/content/editor/container.js","../../../javascript/content/editor/rules_engine.js","../../../javascript/content/editor/container_controller.js","../../../javascript/content/editor/list_controller.js","../../../javascript/content/editor/trix_controller.js","../../../javascript/content/application.js","../../../javascript/content/editor/item_controller.js","../../../javascript/content/editor/new_item_controller.js","../../../javascript/content/editor/status_bar_controller.js"],"sourcesContent":["export default class Item {\n /**\n * Sort items by their index.\n *\n * @param a {Item}\n * @param b {Item}\n * @returns {number}\n */\n static comparator(a, b) {\n return a.index - b.index;\n }\n\n /**\n * @param node {Element} li[data-content-index]\n */\n constructor(node) {\n this.node = node;\n }\n\n /**\n * @returns {String} id of the node's item (from data attributes)\n */\n get itemId() {\n return this.node.dataset[`contentItemId`];\n }\n\n get #itemIdInput() {\n return this.node.querySelector(`input[name$=\"[id]\"]`);\n }\n\n /**\n * @param itemId {String} id\n */\n set itemId(id) {\n if (this.itemId === id) return;\n\n this.node.dataset[`contentItemId`] = `${id}`;\n this.#itemIdInput.value = `${id}`;\n }\n\n /**\n * @returns {number} logical nesting depth of node in container\n */\n get depth() {\n return parseInt(this.node.dataset[`contentDepth`]) || 0;\n }\n\n get #depthInput() {\n return this.node.querySelector(`input[name$=\"[depth]\"]`);\n }\n\n /**\n * @param depth {number} depth >= 0\n */\n set depth(depth) {\n if (this.depth === depth) return;\n\n this.node.dataset[`contentDepth`] = `${depth}`;\n this.#depthInput.value = `${depth}`;\n }\n\n /**\n * @returns {number} logical index of node in container (pre-order traversal)\n */\n get index() {\n return parseInt(this.node.dataset[`contentIndex`]);\n }\n\n get #indexInput() {\n return this.node.querySelector(`input[name$=\"[index]\"]`);\n }\n\n /**\n * @param index {number} index >= 0\n */\n set index(index) {\n if (this.index === index) return;\n\n this.node.dataset[`contentIndex`] = `${index}`;\n this.#indexInput.value = `${index}`;\n }\n\n /**\n * @returns {boolean} true if this item can have children\n */\n get isLayout() {\n return this.node.hasAttribute(\"data-content-layout\");\n }\n\n /**\n * @returns {Item} nearest neighbour (index - 1)\n */\n get previousItem() {\n let sibling = this.node.previousElementSibling;\n if (sibling) return new Item(sibling);\n }\n\n /**\n * @returns {Item} nearest neighbour (index + 1)\n */\n get nextItem() {\n let sibling = this.node.nextElementSibling;\n if (sibling) return new Item(sibling);\n }\n\n /**\n * @returns {boolean} true if this item has any collapsed children\n */\n hasCollapsedDescendants() {\n let childrenList = this.#childrenListElement;\n return !!childrenList && childrenList.children.length > 0;\n }\n\n /**\n * @returns {boolean} true if this item has any expanded children\n */\n hasExpandedDescendants() {\n let sibling = this.nextItem;\n return !!sibling && sibling.depth > this.depth;\n }\n\n /**\n * Recursively traverse the node and its descendants.\n *\n * @callback {Item}\n */\n traverse(callback) {\n // capture descendants before traversal in case of side-effects\n // specifically, setting depth affects calculation\n const expanded = this.#expandedDescendants;\n\n callback(this);\n this.#traverseCollapsed(callback);\n expanded.forEach((item) => item.#traverseCollapsed(callback));\n }\n\n /**\n * Recursively traverse the node's collapsed descendants, if any.\n *\n * @callback {Item}\n */\n #traverseCollapsed(callback) {\n if (!this.hasCollapsedDescendants()) return;\n\n this.#collapsedDescendants.forEach((item) => {\n callback(item);\n item.#traverseCollapsed(callback);\n });\n }\n\n /**\n * Move the given item into this element's hidden children list.\n * Assumes the list already exists.\n *\n * @param item {Item}\n */\n collapseChild(item) {\n this.#childrenListElement.appendChild(item.node);\n }\n\n /**\n * Collapses visible (logical) children into this element's hidden children\n * list, creating it if it doesn't already exist.\n */\n collapse() {\n let listElement = this.#childrenListElement;\n\n if (!listElement) listElement = createChildrenList(this.node);\n\n this.#expandedDescendants.forEach((child) =>\n listElement.appendChild(child.node)\n );\n }\n\n /**\n * Moves any collapsed children back into the parent container.\n */\n expand() {\n if (!this.hasCollapsedDescendants()) return;\n\n Array.from(this.#childrenListElement.children)\n .reverse()\n .forEach((node) => {\n this.node.insertAdjacentElement(\"afterend\", node);\n });\n }\n\n /**\n * Sets the state of a given rule on the target node.\n *\n * @param rule {String}\n * @param deny {boolean}\n */\n toggleRule(rule, deny = false) {\n if (this.node.dataset.hasOwnProperty(rule) && !deny) {\n delete this.node.dataset[rule];\n }\n if (!this.node.dataset.hasOwnProperty(rule) && deny) {\n this.node.dataset[rule] = \"\";\n }\n\n if (rule === \"denyDrag\") {\n if (!this.node.hasAttribute(\"draggable\") && !deny) {\n this.node.setAttribute(\"draggable\", \"true\");\n }\n if (this.node.hasAttribute(\"draggable\") && deny) {\n this.node.removeAttribute(\"draggable\");\n }\n }\n }\n\n /**\n * Detects turbo item changes by comparing the dataset id with the input\n */\n hasItemIdChanged() {\n return !(this.#itemIdInput.value === this.itemId);\n }\n\n /**\n * Updates inputs, in case they don't match the data values, e.g., when the\n * nested inputs have been hot-swapped by turbo with data from the server.\n *\n * Updates itemId from input as that is the canonical source.\n */\n updateAfterChange() {\n this.itemId = this.#itemIdInput.value;\n this.#indexInput.value = this.index;\n this.#depthInput.value = this.depth;\n }\n\n /**\n * Finds the dom container for storing collapsed (hidden) children, if present.\n *\n * @returns {Element} ol[data-content-children]\n */\n get #childrenListElement() {\n return this.node.querySelector(`:scope > [data-content-children]`);\n }\n\n /**\n * @returns {Item[]} all items that follow this element that have a greater depth.\n */\n get #expandedDescendants() {\n const descendants = [];\n\n let sibling = this.nextItem;\n while (sibling && sibling.depth > this.depth) {\n descendants.push(sibling);\n sibling = sibling.nextItem;\n }\n\n return descendants;\n }\n\n /**\n * @returns {Item[]} all items directly contained inside this element's hidden children element.\n */\n get #collapsedDescendants() {\n if (!this.hasCollapsedDescendants()) return [];\n\n return Array.from(this.#childrenListElement.children).map(\n (node) => new Item(node)\n );\n }\n}\n\n/**\n * Finds or creates a dom container for storing collapsed (hidden) children.\n *\n * @param node {Element} li[data-content-index]\n * @returns {Element} ol[data-content-children]\n */\nfunction createChildrenList(node) {\n const childrenList = document.createElement(\"ol\");\n childrenList.setAttribute(\"class\", \"hidden\");\n\n // if objectType is \"rich-content\" set richContentChildren as a data attribute\n childrenList.dataset[`contentChildren`] = \"\";\n\n node.appendChild(childrenList);\n\n return childrenList;\n}\n","import Item from \"./item\";\n\n/**\n * @param nodes {NodeList}\n * @returns {Item[]}\n */\nfunction createItemList(nodes) {\n return Array.from(nodes).map((node) => new Item(node));\n}\n\nexport default class Container {\n /**\n * @param node {Element} content editor list\n */\n constructor(node) {\n this.node = node;\n }\n\n /**\n * @return {Item[]} an ordered list of all items in the container\n */\n get items() {\n return createItemList(this.node.querySelectorAll(\"[data-content-index]\"));\n }\n\n /**\n * @return {String} a serialized description of the structure of the container\n */\n get state() {\n const inputs = this.node.querySelectorAll(\"li input[type=hidden]\");\n return Array.from(inputs)\n .map((e) => e.value)\n .join(\"/\");\n }\n\n /**\n * Set the index of items based on their current position.\n */\n reindex() {\n this.items.map((item, index) => (item.index = index));\n }\n\n /**\n * Resets the order of items to their defined index.\n * Useful after an aborted drag.\n */\n reset() {\n this.items.sort(Item.comparator).forEach((item) => {\n this.node.appendChild(item.node);\n });\n }\n}\n","export default class RulesEngine {\n static rules = [\n \"denyDeNest\",\n \"denyNest\",\n \"denyCollapse\",\n \"denyExpand\",\n \"denyRemove\",\n \"denyDrag\",\n \"denyEdit\",\n ];\n\n constructor(debug = false) {\n if (debug) {\n this.debug = (...args) => console.log(...args);\n } else {\n this.debug = () => {};\n }\n }\n\n /**\n * Enforce structural rules to ensure that the given item is currently in a\n * valid state.\n *\n * @param {Item} item\n */\n normalize(item) {\n // structural rules enforce a valid tree structure\n this.firstItemDepthZero(item);\n this.depthMustBeSet(item);\n this.itemCannotHaveInvalidDepth(item);\n this.parentMustBeLayout(item);\n this.parentCannotHaveExpandedAndCollapsedChildren(item);\n }\n\n /**\n * Apply rules to the given item to determine what operations are permitted.\n *\n * @param {Item} item\n */\n update(item) {\n this.rules = {};\n\n // behavioural rules define what the user is allowed to do\n this.parentsCannotDeNest(item);\n this.rootsCannotDeNest(item);\n this.onlyLastItemCanDeNest(item);\n this.nestingNeedsParent(item);\n this.leavesCannotCollapse(item);\n this.needHiddenItemsToExpand(item);\n this.parentsCannotBeDeleted(item);\n this.parentsCannotBeDragged(item);\n\n RulesEngine.rules.forEach((rule) => {\n item.toggleRule(rule, !!this.rules[rule]);\n });\n }\n\n /**\n * First item can't have a parent, so its depth should always be 0\n */\n firstItemDepthZero(item) {\n if (item.index === 0 && item.depth !== 0) {\n this.debug(`enforce depth on item ${item.index}: ${item.depth} => 0`);\n\n item.depth = 0;\n }\n }\n\n /**\n * Every item should have a non-negative depth set.\n *\n * @param {Item} item\n */\n depthMustBeSet(item) {\n if (isNaN(item.depth) || item.depth < 0) {\n this.debug(`unset depth on item ${item.index}: => 0`);\n\n item.depth = 0;\n }\n }\n\n /**\n * Depth must increase stepwise.\n *\n * @param {Item} item\n */\n itemCannotHaveInvalidDepth(item) {\n const previous = item.previousItem;\n if (previous && previous.depth < item.depth - 1) {\n this.debug(\n `invalid depth on item ${item.index}: ${item.depth} => ${\n previous.depth + 1\n }`\n );\n\n item.depth = previous.depth + 1;\n }\n }\n\n /**\n * Parent item, if any, must be a layout.\n *\n * @param {Item} item\n */\n parentMustBeLayout(item) {\n // if we're the first child, make sure our parent is a layout\n // if we're a sibling, we know the previous item is valid so we must be too\n const previous = item.previousItem;\n if (previous && previous.depth < item.depth && !previous.isLayout) {\n this.debug(\n `invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}`\n );\n\n item.depth = previous.depth;\n }\n }\n\n /**\n * If a parent has expanded and collapsed children, expand.\n *\n * @param {Item} item\n */\n parentCannotHaveExpandedAndCollapsedChildren(item) {\n if (item.hasCollapsedDescendants() && item.hasExpandedDescendants()) {\n this.debug(`expanding collapsed children of item ${item.index}`);\n\n item.expand();\n }\n }\n\n /**\n * De-nesting an item would create a gap of 2 between itself and its children\n *\n * @param {Item} item\n */\n parentsCannotDeNest(item) {\n if (item.hasExpandedDescendants()) this.#deny(\"denyDeNest\");\n }\n\n /**\n * Item depth can't go below 0.\n *\n * @param {Item} item\n */\n rootsCannotDeNest(item) {\n if (item.depth === 0) this.#deny(\"denyDeNest\");\n }\n\n /**\n * De-nesting an item that has siblings would make it a container.\n *\n * @param {Item} item\n */\n onlyLastItemCanDeNest(item) {\n const next = item.nextItem;\n if (next && next.depth === item.depth && !item.isLayout)\n this.#deny(\"denyDeNest\");\n }\n\n /**\n * If an item doesn't have children it can't be collapsed.\n *\n * @param {Item} item\n */\n leavesCannotCollapse(item) {\n if (!item.hasExpandedDescendants()) this.#deny(\"denyCollapse\");\n }\n\n /**\n * If an item doesn't have any hidden descendants then it can't be expanded.\n *\n * @param {Item} item\n */\n needHiddenItemsToExpand(item) {\n if (!item.hasCollapsedDescendants()) this.#deny(\"denyExpand\");\n }\n\n /**\n * An item can't be nested (indented) if it doesn't have a valid parent.\n *\n * @param {Item} item\n */\n nestingNeedsParent(item) {\n const previous = item.previousItem;\n // no previous, so cannot nest\n if (!previous) this.#deny(\"denyNest\");\n // previous is too shallow, nesting would increase depth too much\n else if (previous.depth < item.depth) this.#deny(\"denyNest\");\n // new parent is not a layout\n else if (previous.depth === item.depth && !previous.isLayout)\n this.#deny(\"denyNest\");\n }\n\n /**\n * An item can't be deleted if it has visible children.\n *\n * @param {Item} item\n */\n parentsCannotBeDeleted(item) {\n if (!item.itemId || item.hasExpandedDescendants()) this.#deny(\"denyRemove\");\n }\n\n /**\n * Items cannot be dragged if they have visible children.\n *\n * @param {Item} item\n */\n parentsCannotBeDragged(item) {\n if (item.hasExpandedDescendants()) this.#deny(\"denyDrag\");\n }\n\n /**\n * Record a deny.\n *\n * @param rule {String}\n */\n #deny(rule) {\n this.rules[rule] = true;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport Item from \"./item\";\nimport Container from \"./container\";\nimport RulesEngine from \"./rules_engine\";\n\nexport default class ContainerController extends Controller {\n static targets = [\"container\"];\n\n connect() {\n this.state = this.container.state;\n\n this.reindex();\n }\n\n get container() {\n return new Container(this.containerTarget);\n }\n\n reindex() {\n this.container.reindex();\n this.#update();\n }\n\n reset() {\n this.container.reset();\n }\n\n drop(event) {\n this.container.reindex(); // set indexes before calculating previous\n\n const item = getEventItem(event);\n const previous = item.previousItem;\n\n let delta = 0;\n if (previous === undefined) {\n // if previous does not exist, set depth to 0\n delta = -item.depth;\n } else if (\n previous.isLayout &&\n item.nextItem &&\n item.nextItem.depth > previous.depth\n ) {\n // if previous is a layout and next is a child of previous, make item a child of previous\n delta = previous.depth - item.depth + 1;\n } else {\n // otherwise, make item a sibling of previous\n delta = previous.depth - item.depth;\n }\n\n item.traverse((child) => {\n child.depth += delta;\n });\n\n this.#update();\n event.preventDefault();\n }\n\n remove(event) {\n const item = getEventItem(event);\n\n item.node.remove();\n\n this.#update();\n event.preventDefault();\n }\n\n nest(event) {\n const item = getEventItem(event);\n\n item.traverse((child) => {\n child.depth += 1;\n });\n\n this.#update();\n event.preventDefault();\n }\n\n deNest(event) {\n const item = getEventItem(event);\n\n item.traverse((child) => {\n child.depth -= 1;\n });\n\n this.#update();\n event.preventDefault();\n }\n\n collapse(event) {\n const item = getEventItem(event);\n\n item.collapse();\n\n this.#update();\n event.preventDefault();\n }\n\n expand(event) {\n const item = getEventItem(event);\n\n item.expand();\n\n this.#update();\n event.preventDefault();\n }\n\n /**\n * Re-apply rules to items to enable/disable appropriate actions.\n */\n #update() {\n // debounce requests to ensure that we only update once per tick\n this.updateRequested = true;\n setTimeout(() => {\n if (!this.updateRequested) return;\n\n this.updateRequested = false;\n const engine = new RulesEngine();\n this.container.items.forEach((item) => engine.normalize(item));\n this.container.items.forEach((item) => engine.update(item));\n\n this.#notifyChange();\n }, 0);\n }\n\n #notifyChange() {\n this.dispatch(\"change\", {\n bubbles: true,\n prefix: \"content\",\n detail: { dirty: this.#isDirty() },\n });\n }\n\n #isDirty() {\n return this.container.state !== this.state;\n }\n}\n\nfunction getEventItem(event) {\n return new Item(event.target.closest(\"[data-content-item]\"));\n}\n","import {Controller} from \"@hotwired/stimulus\";\n\nexport default class ListController extends Controller {\n connect() {\n this.enterCount = 0;\n }\n\n /**\n * When the user starts a drag within the list, set the item's dataTransfer\n * properties to indicate that it's being dragged and update its style.\n *\n * We delay setting the dataset property until the next animation frame\n * so that the style updates can be computed before the drag begins.\n *\n * @param event {DragEvent}\n */\n dragstart(event) {\n if (this.element !== event.target.parentElement) return;\n\n const target = event.target;\n event.dataTransfer.effectAllowed = \"move\";\n\n // update element style after drag has begun\n requestAnimationFrame(() => (target.dataset.dragging = \"\"));\n }\n\n /**\n * When the user drags an item over another item in the last, swap the\n * dragging item with the item under the cursor.\n *\n * As a special case, if the item is dragged over placeholder space at the end\n * of the list, move the item to the bottom of the list instead. This allows\n * users to hit the list element more easily when adding new items to an empty\n * list.\n *\n * @param event {DragEvent}\n */\n dragover(event) {\n const item = this.dragItem;\n if (!item) return;\n\n swap(dropTarget(event.target), item);\n\n event.preventDefault();\n return true;\n }\n\n /**\n * When the user drags an item into the list, create a placeholder item to\n * represent the new item. Note that we can't access the drag data\n * until drop, so we assume that this is our template item for now.\n *\n * Users can cancel the drag by dragging the item out of the list or by\n * pressing escape. Both are handled by `cancelDrag`.\n *\n * @param event {DragEvent}\n */\n dragenter(event) {\n event.preventDefault();\n\n // Safari doesn't support relatedTarget, so we count enter/leave pairs\n this.enterCount++;\n\n if (copyAllowed(event) && !this.dragItem) {\n const item = document.createElement(\"li\");\n item.dataset.dragging = \"\";\n item.dataset.newItem = \"\";\n this.element.appendChild(item);\n }\n }\n\n /**\n * When the user drags the item out of the list, remove the placeholder.\n * This allows users to cancel the drag by dragging the item out of the list.\n *\n * @param event {DragEvent}\n */\n dragleave(event) {\n // Safari doesn't support relatedTarget, so we count enter/leave pairs\n // https://bugs.webkit.org/show_bug.cgi?id=66547\n this.enterCount--;\n\n if (this.enterCount <= 0 && this.dragItem.dataset.hasOwnProperty(\"newItem\")) {\n this.cancelDrag(event);\n }\n }\n\n /**\n * When the user drops an item into the list, end the drag and reindex the list.\n *\n * If the item is a new item, we replace the placeholder with the template\n * item data from the dataTransfer API.\n *\n * @param event {DragEvent}\n */\n drop(event) {\n let item = this.dragItem;\n\n if (!item) return;\n\n event.preventDefault();\n delete item.dataset.dragging;\n swap(dropTarget(event.target), item);\n\n if (item.dataset.hasOwnProperty(\"newItem\")) {\n const placeholder = item;\n const template = document.createElement(\"template\");\n template.innerHTML = event.dataTransfer.getData(\"text/html\");\n item = template.content.querySelector(\"li\");\n\n this.element.replaceChild(item, placeholder);\n requestAnimationFrame(() =>\n item.querySelector(\"[role='button'][value='edit']\").click()\n );\n }\n\n this.dispatch(\"drop\", {target: item, bubbles: true, prefix: \"content\"});\n }\n\n /**\n * End an in-progress drag. If the item is a new item, remove it, otherwise\n * reset the item's style and restore its original position in the list.\n */\n dragend() {\n const item = this.dragItem;\n\n if (!item) {\n } else if (item.dataset.hasOwnProperty(\"newItem\")) {\n item.remove();\n } else {\n delete item.dataset.dragging;\n this.reset();\n }\n }\n\n get isDragging() {\n return !!this.dragItem;\n }\n\n get dragItem() {\n return this.element.querySelector(\"[data-dragging]\");\n }\n\n reindex() {\n this.dispatch(\"reindex\", {bubbles: true, prefix: \"content\"});\n }\n\n reset() {\n this.dispatch(\"reset\", {bubbles: true, prefix: \"content\"});\n }\n}\n\n/**\n * Swaps two list items. If target is a list, the item is appended.\n *\n * @param target the target element to swap with\n * @param item the item the user is dragging\n */\nfunction swap(target, item) {\n if (!target) return;\n if (target === item) return;\n\n if (target.nodeName === \"LI\") {\n const positionComparison = target.compareDocumentPosition(item);\n if (positionComparison & Node.DOCUMENT_POSITION_FOLLOWING) {\n target.insertAdjacentElement(\"beforebegin\", item);\n } else if (positionComparison & Node.DOCUMENT_POSITION_PRECEDING) {\n target.insertAdjacentElement(\"afterend\", item);\n }\n }\n\n if (target.nodeName === \"OL\") {\n target.appendChild(item);\n }\n}\n\n/**\n * Returns true if the event supports copy or copy move.\n *\n * Chrome and Firefox use copy, but Safari only supports copyMove.\n */\nfunction copyAllowed(event) {\n return (\n event.dataTransfer.effectAllowed === \"copy\" ||\n event.dataTransfer.effectAllowed === \"copyMove\"\n );\n}\n\n/**\n * Given an event target, return the closest drop target, if any.\n */\nfunction dropTarget(e) {\n return e && (\n e.closest(\"[data-controller='content--editor--list'] > *\") ||\n e.closest(\"[data-controller='content--editor--list']\")\n );\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport \"trix\";\n\n// Note, action_text 7.1.2 changes how Trix is bundled and loaded. This\n// seems to have broken the default export from trix. This is a workaround\n// that relies on the backwards compatibility of the old export to window.Trix.\nconst Trix = window.Trix;\n\n// Stimulus controller doesn't do anything, but having one ensures that trix\n// will be lazy loaded when a trix-editor is added to the dom.\nexport default class TrixController extends Controller {\n trixInitialize(e) {\n // noop, useful as an extension point for registering behaviour on load\n }\n}\n\n// Add H4 as an acceptable tag\nTrix.config.blockAttributes[\"heading4\"] = {\n tagName: \"h4\",\n terminal: true,\n breakOnReturn: true,\n group: false,\n};\n\n// Remove H1 from trix list of acceptable tags\ndelete Trix.config.blockAttributes.heading1;\n\n/**\n * Allow users to enter path and fragment URIs which the input[type=url] browser\n * input does not permit. Uses a permissive regex pattern which is not suitable\n * for untrusted use cases.\n */\nconst LINK_PATTERN = \"(https?|mailto:|tel:|/|#).*?\";\n\n/**\n * Customize default toolbar:\n *\n * * headings: h4 instead of h1\n * * links: use type=text instead of type=url\n *\n * @returns {String} toolbar html fragment\n */\nTrix.config.toolbar.getDefaultHTML = () => {\n const { lang } = Trix.config;\n return `\n<div class=\"trix-button-row\">\n <span class=\"trix-button-group trix-button-group--text-tools\" data-trix-button-group=\"text-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bold\" data-trix-attribute=\"bold\" data-trix-key=\"b\" title=\"${lang.bold}\" tabindex=\"-1\">${lang.bold}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-italic\" data-trix-attribute=\"italic\" data-trix-key=\"i\" title=\"${lang.italic}\" tabindex=\"-1\">${lang.italic}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-strike\" data-trix-attribute=\"strike\" title=\"${lang.strike}\" tabindex=\"-1\">${lang.strike}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-link\" data-trix-attribute=\"href\" data-trix-action=\"link\" data-trix-key=\"k\" title=\"${lang.link}\" tabindex=\"-1\">${lang.link}</button>\n </span>\n <span class=\"trix-button-group trix-button-group--block-tools\" data-trix-button-group=\"block-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-heading-1\" data-trix-attribute=\"heading4\" title=\"${lang.heading1}\" tabindex=\"-1\">${lang.heading1}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-quote\" data-trix-attribute=\"quote\" title=\"${lang.quote}\" tabindex=\"-1\">${lang.quote}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-code\" data-trix-attribute=\"code\" title=\"${lang.code}\" tabindex=\"-1\">${lang.code}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bullet-list\" data-trix-attribute=\"bullet\" title=\"${lang.bullets}\" tabindex=\"-1\">${lang.bullets}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-number-list\" data-trix-attribute=\"number\" title=\"${lang.numbers}\" tabindex=\"-1\">${lang.numbers}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-decrease-nesting-level\" data-trix-action=\"decreaseNestingLevel\" title=\"${lang.outdent}\" tabindex=\"-1\">${lang.outdent}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-increase-nesting-level\" data-trix-action=\"increaseNestingLevel\" title=\"${lang.indent}\" tabindex=\"-1\">${lang.indent}</button>\n </span>\n <span class=\"trix-button-group trix-button-group--file-tools\" data-trix-button-group=\"file-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-attach\" data-trix-action=\"attachFiles\" title=\"${lang.attachFiles}\" tabindex=\"-1\">${lang.attachFiles}</button>\n </span>\n <span class=\"trix-button-group-spacer\"></span>\n <span class=\"trix-button-group trix-button-group--history-tools\" data-trix-button-group=\"history-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-undo\" data-trix-action=\"undo\" data-trix-key=\"z\" title=\"${lang.undo}\" tabindex=\"-1\">${lang.undo}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-redo\" data-trix-action=\"redo\" data-trix-key=\"shift+z\" title=\"${lang.redo}\" tabindex=\"-1\">${lang.redo}</button>\n </span>\n</div>\n<div class=\"trix-dialogs\" data-trix-dialogs>\n <div class=\"trix-dialog trix-dialog--link\" data-trix-dialog=\"href\" data-trix-dialog-attribute=\"href\">\n <div class=\"trix-dialog__link-fields\">\n <input type=\"text\" name=\"href\" pattern=\"${LINK_PATTERN}\" class=\"trix-input trix-input--dialog\" placeholder=\"${lang.urlPlaceholder}\" aria-label=\"${lang.url}\" required data-trix-input>\n <div class=\"trix-button-group\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"${lang.link}\" data-trix-method=\"setAttribute\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"${lang.unlink}\" data-trix-method=\"removeAttribute\">\n </div>\n </div>\n </div>\n</div>\n`;\n};\n\n/**\n * If the <trix-editor> element is in the HTML when Trix loads, then Trix will have already injected the toolbar content\n * before our code gets a chance to run. Fix that now.\n *\n * Note: in Trix 2 this is likely to no longer be necessary.\n */\ndocument.querySelectorAll(\"trix-toolbar\").forEach((e) => {\n e.innerHTML = Trix.config.toolbar.getDefaultHTML();\n});\n","import ContainerController from \"./editor/container_controller\";\nimport ItemController from \"./editor/item_controller\";\nimport ListController from \"./editor/list_controller\";\nimport NewItemController from \"./editor/new_item_controller\";\nimport StatusBarController from \"./editor/status_bar_controller\";\nimport TrixController from \"./editor/trix_controller\";\n\nconst Definitions = [\n {\n identifier: \"content--editor--container\",\n controllerConstructor: ContainerController,\n },\n {\n identifier: \"content--editor--item\",\n controllerConstructor: ItemController,\n },\n {\n identifier: \"content--editor--list\",\n controllerConstructor: ListController,\n },\n {\n identifier: \"content--editor--new-item\",\n controllerConstructor: NewItemController,\n },\n {\n identifier: \"content--editor--status-bar\",\n controllerConstructor: StatusBarController,\n },\n {\n identifier: \"content--editor--trix\",\n controllerConstructor: TrixController,\n },\n];\n\nexport { Definitions as default };\n","import { Controller } from \"@hotwired/stimulus\";\nimport Item from \"./item\";\n\nexport default class ItemController extends Controller {\n get item() {\n return new Item(this.li);\n }\n\n get ol() {\n return this.element.closest(\"ol\");\n }\n\n get li() {\n return this.element.closest(\"li\");\n }\n\n connect() {\n if (this.element.dataset.hasOwnProperty(\"delete\")) {\n this.remove();\n }\n // if index is not already set, re-index will set it\n else if (!(this.item.index >= 0)) {\n this.reindex();\n }\n // if item has been replaced via turbo, re-index will run the rules engine\n // update our depth and index with values from the li's data attributes\n else if (this.item.hasItemIdChanged()) {\n this.item.updateAfterChange();\n this.reindex();\n }\n }\n\n remove() {\n // capture ol\n const ol = this.ol;\n // remove self from dom\n this.li.remove();\n // reindex ol\n this.reindex();\n }\n\n reindex() {\n this.dispatch(\"reindex\", { bubbles: true, prefix: \"content\" });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class NewItemController extends Controller {\n static targets = [\"template\"];\n\n dragstart(event) {\n if (this.element !== event.target) return;\n\n event.dataTransfer.setData(\"text/html\", this.templateTarget.innerHTML);\n event.dataTransfer.effectAllowed = \"copy\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class StatusBarController extends Controller {\n connect() {\n // cache the version's state in the controller on connect\n this.versionState = this.element.dataset.state;\n }\n\n change(e) {\n if (e.detail && e.detail.hasOwnProperty(\"dirty\")) {\n this.update(e.detail);\n }\n }\n\n update({ dirty }) {\n if (dirty) {\n this.element.dataset.state = \"dirty\";\n } else {\n this.element.dataset.state = this.versionState;\n }\n }\n}\n"],"names":["Item","comparator","a","b","index","constructor","node","this","itemId","dataset","itemIdInput","querySelector","id","value","depth","parseInt","depthInput","indexInput","isLayout","hasAttribute","previousItem","sibling","previousElementSibling","nextItem","nextElementSibling","hasCollapsedDescendants","childrenList","childrenListElement","children","length","hasExpandedDescendants","traverse","callback","expanded","expandedDescendants","traverseCollapsed","forEach","item","collapsedDescendants","collapseChild","appendChild","collapse","listElement","document","createElement","setAttribute","createChildrenList","child","expand","Array","from","reverse","insertAdjacentElement","toggleRule","rule","deny","hasOwnProperty","removeAttribute","hasItemIdChanged","updateAfterChange","descendants","push","map","Container","items","nodes","querySelectorAll","state","inputs","e","join","reindex","reset","sort","RulesEngine","static","debug","args","console","log","normalize","firstItemDepthZero","depthMustBeSet","itemCannotHaveInvalidDepth","parentMustBeLayout","parentCannotHaveExpandedAndCollapsedChildren","update","rules","parentsCannotDeNest","rootsCannotDeNest","onlyLastItemCanDeNest","nestingNeedsParent","leavesCannotCollapse","needHiddenItemsToExpand","parentsCannotBeDeleted","parentsCannotBeDragged","isNaN","previous","next","getEventItem","event","target","closest","swap","nodeName","positionComparison","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","DOCUMENT_POSITION_PRECEDING","dropTarget","Trix","window","config","blockAttributes","tagName","terminal","breakOnReturn","group","heading1","toolbar","getDefaultHTML","lang","bold","italic","strike","link","quote","code","bullets","numbers","outdent","indent","attachFiles","undo","redo","urlPlaceholder","url","unlink","innerHTML","Definitions","identifier","controllerConstructor","Controller","connect","container","containerTarget","drop","delta","undefined","preventDefault","remove","nest","deNest","updateRequested","setTimeout","engine","notifyChange","dispatch","bubbles","prefix","detail","dirty","isDirty","li","ol","element","enterCount","dragstart","parentElement","dataTransfer","effectAllowed","requestAnimationFrame","dragging","dragover","dragItem","dragenter","copyAllowed","newItem","dragleave","cancelDrag","placeholder","template","getData","content","replaceChild","click","dragend","isDragging","setData","templateTarget","versionState","change","trixInitialize"],"mappings":"6DAAe,MAAMA,EAQnB,iBAAOC,CAAWC,EAAGC,GACnB,OAAOD,EAAEE,MAAQD,EAAEC,KACpB,CAKD,WAAAC,CAAYC,GACVC,KAAKD,KAAOA,CACb,CAKD,UAAIE,GACF,OAAOD,KAAKD,KAAKG,QAAuB,aACzC,CAED,KAAIC,GACF,OAAOH,KAAKD,KAAKK,cAAc,sBAChC,CAKD,UAAIH,CAAOI,GACLL,KAAKC,SAAWI,IAEpBL,KAAKD,KAAKG,QAAuB,cAAI,GAAGG,IACxCL,MAAKG,EAAaG,MAAQ,GAAGD,IAC9B,CAKD,SAAIE,GACF,OAAOC,SAASR,KAAKD,KAAKG,QAAsB,eAAM,CACvD,CAED,KAAIO,GACF,OAAOT,KAAKD,KAAKK,cAAc,yBAChC,CAKD,SAAIG,CAAMA,GACJP,KAAKO,QAAUA,IAEnBP,KAAKD,KAAKG,QAAsB,aAAI,GAAGK,IACvCP,MAAKS,EAAYH,MAAQ,GAAGC,IAC7B,CAKD,SAAIV,GACF,OAAOW,SAASR,KAAKD,KAAKG,QAAsB,aACjD,CAED,KAAIQ,GACF,OAAOV,KAAKD,KAAKK,cAAc,yBAChC,CAKD,SAAIP,CAAMA,GACJG,KAAKH,QAAUA,IAEnBG,KAAKD,KAAKG,QAAsB,aAAI,GAAGL,IACvCG,MAAKU,EAAYJ,MAAQ,GAAGT,IAC7B,CAKD,YAAIc,GACF,OAAOX,KAAKD,KAAKa,aAAa,sBAC/B,CAKD,gBAAIC,GACF,IAAIC,EAAUd,KAAKD,KAAKgB,uBACxB,GAAID,EAAS,OAAO,IAAIrB,EAAKqB,EAC9B,CAKD,YAAIE,GACF,IAAIF,EAAUd,KAAKD,KAAKkB,mBACxB,GAAIH,EAAS,OAAO,IAAIrB,EAAKqB,EAC9B,CAKD,uBAAAI,GACE,IAAIC,EAAenB,MAAKoB,EACxB,QAASD,GAAgBA,EAAaE,SAASC,OAAS,CACzD,CAKD,sBAAAC,GACE,IAAIT,EAAUd,KAAKgB,SACnB,QAASF,GAAWA,EAAQP,MAAQP,KAAKO,KAC1C,CAOD,QAAAiB,CAASC,GAGP,MAAMC,EAAW1B,MAAK2B,EAEtBF,EAASzB,MACTA,MAAK4B,EAAmBH,GACxBC,EAASG,SAASC,GAASA,GAAKF,EAAmBH,IACpD,CAOD,EAAAG,CAAmBH,GACZzB,KAAKkB,2BAEVlB,MAAK+B,EAAsBF,SAASC,IAClCL,EAASK,GACTA,GAAKF,EAAmBH,EAAS,GAEpC,CAQD,aAAAO,CAAcF,GACZ9B,MAAKoB,EAAqBa,YAAYH,EAAK/B,KAC5C,CAMD,QAAAmC,GACE,IAAIC,EAAcnC,MAAKoB,EAElBe,IAAaA,EAyGtB,SAA4BpC,GAC1B,MAAMoB,EAAeiB,SAASC,cAAc,MAQ5C,OAPAlB,EAAamB,aAAa,QAAS,UAGnCnB,EAAajB,QAAyB,gBAAI,GAE1CH,EAAKkC,YAAYd,GAEVA,CACT,CAnHoCoB,CAAmBvC,KAAKD,OAExDC,MAAK2B,EAAqBE,SAASW,GACjCL,EAAYF,YAAYO,EAAMzC,OAEjC,CAKD,MAAA0C,GACOzC,KAAKkB,2BAEVwB,MAAMC,KAAK3C,MAAKoB,EAAqBC,UAClCuB,UACAf,SAAS9B,IACRC,KAAKD,KAAK8C,sBAAsB,WAAY9C,EAAK,GAEtD,CAQD,UAAA+C,CAAWC,EAAMC,GAAO,GAClBhD,KAAKD,KAAKG,QAAQ+C,eAAeF,KAAUC,UACtChD,KAAKD,KAAKG,QAAQ6C,IAEtB/C,KAAKD,KAAKG,QAAQ+C,eAAeF,IAASC,IAC7ChD,KAAKD,KAAKG,QAAQ6C,GAAQ,IAGf,aAATA,IACG/C,KAAKD,KAAKa,aAAa,cAAiBoC,GAC3ChD,KAAKD,KAAKuC,aAAa,YAAa,QAElCtC,KAAKD,KAAKa,aAAa,cAAgBoC,GACzChD,KAAKD,KAAKmD,gBAAgB,aAG/B,CAKD,gBAAAC,GACE,QAASnD,MAAKG,EAAaG,QAAUN,KAAKC,OAC3C,CAQD,iBAAAmD,GACEpD,KAAKC,OAASD,MAAKG,EAAaG,MAChCN,MAAKU,EAAYJ,MAAQN,KAAKH,MAC9BG,MAAKS,EAAYH,MAAQN,KAAKO,KAC/B,CAOD,KAAIa,GACF,OAAOpB,KAAKD,KAAKK,cAAc,mCAChC,CAKD,KAAIuB,GACF,MAAM0B,EAAc,GAEpB,IAAIvC,EAAUd,KAAKgB,SACnB,KAAOF,GAAWA,EAAQP,MAAQP,KAAKO,OACrC8C,EAAYC,KAAKxC,GACjBA,EAAUA,EAAQE,SAGpB,OAAOqC,CACR,CAKD,KAAItB,GACF,OAAK/B,KAAKkB,0BAEHwB,MAAMC,KAAK3C,MAAKoB,EAAqBC,UAAUkC,KACnDxD,GAAS,IAAIN,EAAKM,KAHuB,EAK7C,EC7PY,MAAMyD,EAInB,WAAA1D,CAAYC,GACVC,KAAKD,KAAOA,CACb,CAKD,SAAI0D,GACF,OAhBoBC,EAgBE1D,KAAKD,KAAK4D,iBAAiB,wBAf5CjB,MAAMC,KAAKe,GAAOH,KAAKxD,GAAS,IAAIN,EAAKM,KADlD,IAAwB2D,CAiBrB,CAKD,SAAIE,GACF,MAAMC,EAAS7D,KAAKD,KAAK4D,iBAAiB,yBAC1C,OAAOjB,MAAMC,KAAKkB,GACfN,KAAKO,GAAMA,EAAExD,QACbyD,KAAK,IACT,CAKD,OAAAC,GACEhE,KAAKyD,MAAMF,KAAI,CAACzB,EAAMjC,IAAWiC,EAAKjC,MAAQA,GAC/C,CAMD,KAAAoE,GACEjE,KAAKyD,MAAMS,KAAKzE,EAAKC,YAAYmC,SAASC,IACxC9B,KAAKD,KAAKkC,YAAYH,EAAK/B,KAAK,GAEnC,EClDY,MAAMoE,EACnBC,aAAe,CACb,aACA,WACA,eACA,aACA,aACA,WACA,YAGF,WAAAtE,CAAYuE,GAAQ,GAEhBrE,KAAKqE,MADHA,EACW,IAAIC,IAASC,QAAQC,OAAOF,GAE5B,MAEhB,CAQD,SAAAG,CAAU3C,GAER9B,KAAK0E,mBAAmB5C,GACxB9B,KAAK2E,eAAe7C,GACpB9B,KAAK4E,2BAA2B9C,GAChC9B,KAAK6E,mBAAmB/C,GACxB9B,KAAK8E,6CAA6ChD,EACnD,CAOD,MAAAiD,CAAOjD,GACL9B,KAAKgF,MAAQ,GAGbhF,KAAKiF,oBAAoBnD,GACzB9B,KAAKkF,kBAAkBpD,GACvB9B,KAAKmF,sBAAsBrD,GAC3B9B,KAAKoF,mBAAmBtD,GACxB9B,KAAKqF,qBAAqBvD,GAC1B9B,KAAKsF,wBAAwBxD,GAC7B9B,KAAKuF,uBAAuBzD,GAC5B9B,KAAKwF,uBAAuB1D,GAE5BqC,EAAYa,MAAMnD,SAASkB,IACzBjB,EAAKgB,WAAWC,IAAQ/C,KAAKgF,MAAMjC,GAAM,GAE5C,CAKD,kBAAA2B,CAAmB5C,GACE,IAAfA,EAAKjC,OAA8B,IAAfiC,EAAKvB,QAC3BP,KAAKqE,MAAM,yBAAyBvC,EAAKjC,UAAUiC,EAAKvB,cAExDuB,EAAKvB,MAAQ,EAEhB,CAOD,cAAAoE,CAAe7C,IACT2D,MAAM3D,EAAKvB,QAAUuB,EAAKvB,MAAQ,KACpCP,KAAKqE,MAAM,uBAAuBvC,EAAKjC,eAEvCiC,EAAKvB,MAAQ,EAEhB,CAOD,0BAAAqE,CAA2B9C,GACzB,MAAM4D,EAAW5D,EAAKjB,aAClB6E,GAAYA,EAASnF,MAAQuB,EAAKvB,MAAQ,IAC5CP,KAAKqE,MACH,yBAAyBvC,EAAKjC,UAAUiC,EAAKvB,YAC3CmF,EAASnF,MAAQ,KAIrBuB,EAAKvB,MAAQmF,EAASnF,MAAQ,EAEjC,CAOD,kBAAAsE,CAAmB/C,GAGjB,MAAM4D,EAAW5D,EAAKjB,aAClB6E,GAAYA,EAASnF,MAAQuB,EAAKvB,QAAUmF,EAAS/E,WACvDX,KAAKqE,MACH,2BAA2BvC,EAAKjC,UAAUiC,EAAKvB,YAAYmF,EAASnF,SAGtEuB,EAAKvB,MAAQmF,EAASnF,MAEzB,CAOD,4CAAAuE,CAA6ChD,GACvCA,EAAKZ,2BAA6BY,EAAKP,2BACzCvB,KAAKqE,MAAM,wCAAwCvC,EAAKjC,SAExDiC,EAAKW,SAER,CAOD,mBAAAwC,CAAoBnD,GACdA,EAAKP,0BAA0BvB,MAAKgD,EAAM,aAC/C,CAOD,iBAAAkC,CAAkBpD,GACG,IAAfA,EAAKvB,OAAaP,MAAKgD,EAAM,aAClC,CAOD,qBAAAmC,CAAsBrD,GACpB,MAAM6D,EAAO7D,EAAKd,SACd2E,GAAQA,EAAKpF,QAAUuB,EAAKvB,QAAUuB,EAAKnB,UAC7CX,MAAKgD,EAAM,aACd,CAOD,oBAAAqC,CAAqBvD,GACdA,EAAKP,0BAA0BvB,MAAKgD,EAAM,eAChD,CAOD,uBAAAsC,CAAwBxD,GACjBA,EAAKZ,2BAA2BlB,MAAKgD,EAAM,aACjD,CAOD,kBAAAoC,CAAmBtD,GACjB,MAAM4D,EAAW5D,EAAKjB,aAEjB6E,EAEIA,EAASnF,MAAQuB,EAAKvB,MAAOP,MAAKgD,EAAM,YAExC0C,EAASnF,QAAUuB,EAAKvB,OAAUmF,EAAS/E,UAClDX,MAAKgD,EAAM,YALEhD,MAAKgD,EAAM,WAM3B,CAOD,sBAAAuC,CAAuBzD,GAChBA,EAAK7B,SAAU6B,EAAKP,0BAA0BvB,MAAKgD,EAAM,aAC/D,CAOD,sBAAAwC,CAAuB1D,GACjBA,EAAKP,0BAA0BvB,MAAKgD,EAAM,WAC/C,CAOD,EAAAA,CAAMD,GACJ/C,KAAKgF,MAAMjC,IAAQ,CACpB,EChFH,SAAS6C,EAAaC,GACpB,OAAO,IAAIpG,EAAKoG,EAAMC,OAAOC,QAAQ,uBACvC,CCkBA,SAASC,EAAKF,EAAQhE,GACpB,GAAKgE,GACDA,IAAWhE,EAAf,CAEA,GAAwB,OAApBgE,EAAOG,SAAmB,CAC5B,MAAMC,EAAqBJ,EAAOK,wBAAwBrE,GACtDoE,EAAqBE,KAAKC,4BAC5BP,EAAOjD,sBAAsB,cAAef,GACnCoE,EAAqBE,KAAKE,6BACnCR,EAAOjD,sBAAsB,WAAYf,EAE5C,CAEuB,OAApBgE,EAAOG,UACTH,EAAO7D,YAAYH,EAZO,CAc9B,CAiBA,SAASyE,EAAWzC,GAClB,OAAOA,IACLA,EAAEiC,QAAQ,kDACVjC,EAAEiC,QAAQ,6CAEd,CC9LA,MAAMS,EAAOC,OAAOD,KAWpBA,EAAKE,OAAOC,gBAA0B,SAAI,CACxCC,QAAS,KACTC,UAAU,EACVC,eAAe,EACfC,OAAO,UAIFP,EAAKE,OAAOC,gBAAgBK,SAiBnCR,EAAKE,OAAOO,QAAQC,eAAiB,KACnC,MAAMC,KAAEA,GAASX,EAAKE,OACtB,MAAO,qRAGoIS,EAAKC,uBAAuBD,EAAKC,iKAC7BD,EAAKE,yBAAyBF,EAAKE,iJACrDF,EAAKG,yBAAyBH,EAAKG,uLACGH,EAAKI,uBAAuBJ,EAAKI,uQAGlEJ,EAAKH,2BAA2BG,EAAKH,iJAC5CG,EAAKK,wBAAwBL,EAAKK,4IACpCL,EAAKM,uBAAuBN,EAAKM,oJACxBN,EAAKO,0BAA0BP,EAAKO,uJACpCP,EAAKQ,0BAA0BR,EAAKQ,6KACdR,EAAKS,0BAA0BT,EAAKS,6KACpCT,EAAKU,yBAAyBV,EAAKU,oQAG5DV,EAAKW,8BAA8BX,EAAKW,0UAI/BX,EAAKY,uBAAuBZ,EAAKY,gKAC3BZ,EAAKa,uBAAuBb,EAAKa,uWAM7Db,EAAKc,+BAA+Bd,EAAKe,sJAE/Ef,EAAKI,uHACLJ,EAAKgB,2FAKlF,EASD/F,SAASuB,iBAAiB,gBAAgB9B,SAASiC,IACjDA,EAAEsE,UAAY5B,EAAKE,OAAOO,QAAQC,gBAAgB,ICpF/C,MAACmB,EAAc,CAClB,CACEC,WAAY,6BACZC,sBHJW,cAAkCC,EAC/CpE,eAAiB,CAAC,aAElB,OAAAqE,GACEzI,KAAK4D,MAAQ5D,KAAK0I,UAAU9E,MAE5B5D,KAAKgE,SACN,CAED,aAAI0E,GACF,OAAO,IAAIlF,EAAUxD,KAAK2I,gBAC3B,CAED,OAAA3E,GACEhE,KAAK0I,UAAU1E,UACfhE,MAAK+E,GACN,CAED,KAAAd,GACEjE,KAAK0I,UAAUzE,OAChB,CAED,IAAA2E,CAAK/C,GACH7F,KAAK0I,UAAU1E,UAEf,MAAMlC,EAAO8D,EAAaC,GACpBH,EAAW5D,EAAKjB,aAEtB,IAAIgI,EAAQ,EAGVA,OAFeC,IAAbpD,GAEO5D,EAAKvB,MAEdmF,EAAS/E,UACTmB,EAAKd,UACLc,EAAKd,SAAST,MAAQmF,EAASnF,MAGvBmF,EAASnF,MAAQuB,EAAKvB,MAAQ,EAG9BmF,EAASnF,MAAQuB,EAAKvB,MAGhCuB,EAAKN,UAAUgB,IACbA,EAAMjC,OAASsI,CAAK,IAGtB7I,MAAK+E,IACLc,EAAMkD,gBACP,CAED,MAAAC,CAAOnD,GACQD,EAAaC,GAErB9F,KAAKiJ,SAEVhJ,MAAK+E,IACLc,EAAMkD,gBACP,CAED,IAAAE,CAAKpD,GACUD,EAAaC,GAErBrE,UAAUgB,IACbA,EAAMjC,OAAS,CAAC,IAGlBP,MAAK+E,IACLc,EAAMkD,gBACP,CAED,MAAAG,CAAOrD,GACQD,EAAaC,GAErBrE,UAAUgB,IACbA,EAAMjC,OAAS,CAAC,IAGlBP,MAAK+E,IACLc,EAAMkD,gBACP,CAED,QAAA7G,CAAS2D,GACMD,EAAaC,GAErB3D,WAELlC,MAAK+E,IACLc,EAAMkD,gBACP,CAED,MAAAtG,CAAOoD,GACQD,EAAaC,GAErBpD,SAELzC,MAAK+E,IACLc,EAAMkD,gBACP,CAKD,EAAAhE,GAEE/E,KAAKmJ,iBAAkB,EACvBC,YAAW,KACT,IAAKpJ,KAAKmJ,gBAAiB,OAE3BnJ,KAAKmJ,iBAAkB,EACvB,MAAME,EAAS,IAAIlF,EACnBnE,KAAK0I,UAAUjF,MAAM5B,SAASC,GAASuH,EAAO5E,UAAU3C,KACxD9B,KAAK0I,UAAUjF,MAAM5B,SAASC,GAASuH,EAAOtE,OAAOjD,KAErD9B,MAAKsJ,GAAe,GACnB,EACJ,CAED,EAAAA,GACEtJ,KAAKuJ,SAAS,SAAU,CACtBC,SAAS,EACTC,OAAQ,UACRC,OAAQ,CAAEC,MAAO3J,MAAK4J,MAEzB,CAED,EAAAA,GACE,OAAO5J,KAAK0I,UAAU9E,QAAU5D,KAAK4D,KACtC,IG3HD,CACE0E,WAAY,wBACZC,sBCXW,cAA6BC,EAC1C,QAAI1G,GACF,OAAO,IAAIrC,EAAKO,KAAK6J,GACtB,CAED,MAAIC,GACF,OAAO9J,KAAK+J,QAAQhE,QAAQ,KAC7B,CAED,MAAI8D,GACF,OAAO7J,KAAK+J,QAAQhE,QAAQ,KAC7B,CAED,OAAA0C,GACMzI,KAAK+J,QAAQ7J,QAAQ+C,eAAe,UACtCjD,KAAKgJ,SAGIhJ,KAAK8B,KAAKjC,OAAS,EAKrBG,KAAK8B,KAAKqB,qBACjBnD,KAAK8B,KAAKsB,oBACVpD,KAAKgE,WANLhE,KAAKgE,SAQR,CAED,MAAAgF,GAEahJ,KAAK8J,GAEhB9J,KAAK6J,GAAGb,SAERhJ,KAAKgE,SACN,CAED,OAAAA,GACEhE,KAAKuJ,SAAS,UAAW,CAAEC,SAAS,EAAMC,OAAQ,WACnD,ID3BD,CACEnB,WAAY,wBACZC,sBFhBW,cAA6BC,EAC1C,OAAAC,GACEzI,KAAKgK,WAAa,CACnB,CAWD,SAAAC,CAAUpE,GACR,GAAI7F,KAAK+J,UAAYlE,EAAMC,OAAOoE,cAAe,OAEjD,MAAMpE,EAASD,EAAMC,OACrBD,EAAMsE,aAAaC,cAAgB,OAGnCC,uBAAsB,IAAOvE,EAAO5F,QAAQoK,SAAW,IACxD,CAaD,QAAAC,CAAS1E,GACP,MAAM/D,EAAO9B,KAAKwK,SAClB,GAAK1I,EAKL,OAHAkE,EAAKO,EAAWV,EAAMC,QAAShE,GAE/B+D,EAAMkD,kBACC,CACR,CAYD,SAAA0B,CAAU5E,GAMR,GALAA,EAAMkD,iBAGN/I,KAAKgK,aAwHT,SAAqBnE,GACnB,MACuC,SAArCA,EAAMsE,aAAaC,eACkB,aAArCvE,EAAMsE,aAAaC,aAEvB,CA3HQM,CAAY7E,KAAW7F,KAAKwK,SAAU,CACxC,MAAM1I,EAAOM,SAASC,cAAc,MACpCP,EAAK5B,QAAQoK,SAAW,GACxBxI,EAAK5B,QAAQyK,QAAU,GACvB3K,KAAK+J,QAAQ9H,YAAYH,EAC1B,CACF,CAQD,SAAA8I,CAAU/E,GAGR7F,KAAKgK,aAEDhK,KAAKgK,YAAc,GAAKhK,KAAKwK,SAAStK,QAAQ+C,eAAe,YAC/DjD,KAAK6K,WAAWhF,EAEnB,CAUD,IAAA+C,CAAK/C,GACH,IAAI/D,EAAO9B,KAAKwK,SAEhB,GAAK1I,EAAL,CAMA,GAJA+D,EAAMkD,wBACCjH,EAAK5B,QAAQoK,SACpBtE,EAAKO,EAAWV,EAAMC,QAAShE,GAE3BA,EAAK5B,QAAQ+C,eAAe,WAAY,CAC1C,MAAM6H,EAAchJ,EACdiJ,EAAW3I,SAASC,cAAc,YACxC0I,EAAS3C,UAAYvC,EAAMsE,aAAaa,QAAQ,aAChDlJ,EAAOiJ,EAASE,QAAQ7K,cAAc,MAEtCJ,KAAK+J,QAAQmB,aAAapJ,EAAMgJ,GAChCT,uBAAsB,IACpBvI,EAAK1B,cAAc,iCAAiC+K,SAEvD,CAEDnL,KAAKuJ,SAAS,OAAQ,CAACzD,OAAQhE,EAAM0H,SAAS,EAAMC,OAAQ,WAlB1C,CAmBnB,CAMD,OAAA2B,GACE,MAAMtJ,EAAO9B,KAAKwK,SAEb1I,IACMA,EAAK5B,QAAQ+C,eAAe,WACrCnB,EAAKkH,iBAEElH,EAAK5B,QAAQoK,SACpBtK,KAAKiE,SAER,CAED,cAAIoH,GACF,QAASrL,KAAKwK,QACf,CAED,YAAIA,GACF,OAAOxK,KAAK+J,QAAQ3J,cAAc,kBACnC,CAED,OAAA4D,GACEhE,KAAKuJ,SAAS,UAAW,CAACC,SAAS,EAAMC,OAAQ,WAClD,CAED,KAAAxF,GACEjE,KAAKuJ,SAAS,QAAS,CAACC,SAAS,EAAMC,OAAQ,WAChD,IEjID,CACEnB,WAAY,4BACZC,sBEpBW,cAAgCC,EAC7CpE,eAAiB,CAAC,YAElB,SAAA6F,CAAUpE,GACJ7F,KAAK+J,UAAYlE,EAAMC,SAE3BD,EAAMsE,aAAamB,QAAQ,YAAatL,KAAKuL,eAAenD,WAC5DvC,EAAMsE,aAAaC,cAAgB,OACpC,IFcD,CACE9B,WAAY,8BACZC,sBGxBW,cAAkCC,EAC/C,OAAAC,GAEEzI,KAAKwL,aAAexL,KAAK+J,QAAQ7J,QAAQ0D,KAC1C,CAED,MAAA6H,CAAO3H,GACDA,EAAE4F,QAAU5F,EAAE4F,OAAOzG,eAAe,UACtCjD,KAAK+E,OAAOjB,EAAE4F,OAEjB,CAED,MAAA3E,EAAO4E,MAAEA,IAEL3J,KAAK+J,QAAQ7J,QAAQ0D,MADnB+F,EAC2B,QAEA3J,KAAKwL,YAErC,IHQD,CACElD,WAAY,wBACZC,sBDpBW,cAA6BC,EAC1C,cAAAkD,CAAe5H,GAEd"}
|
1
|
+
{"version":3,"file":"content.min.js","sources":["../../../javascript/content/editor/item.js","../../../javascript/content/editor/container.js","../../../javascript/content/editor/rules_engine.js","../../../javascript/content/editor/container_controller.js","../../../javascript/content/editor/list_controller.js","../../../javascript/content/editor/trix_controller.js","../../../javascript/content/application.js","../../../javascript/content/editor/item_controller.js","../../../javascript/content/editor/new_item_controller.js","../../../javascript/content/editor/status_bar_controller.js"],"sourcesContent":["export default class Item {\n /**\n * Sort items by their index.\n *\n * @param a {Item}\n * @param b {Item}\n * @returns {number}\n */\n static comparator(a, b) {\n return a.index - b.index;\n }\n\n /**\n * @param node {Element} li[data-content-index]\n */\n constructor(node) {\n this.node = node;\n }\n\n /**\n * @returns {String} id of the node's item (from data attributes)\n */\n get itemId() {\n return this.node.dataset[`contentItemId`];\n }\n\n get #itemIdInput() {\n return this.node.querySelector(`input[name$=\"[id]\"]`);\n }\n\n /**\n * @param itemId {String} id\n */\n set itemId(id) {\n if (this.itemId === id) return;\n\n this.node.dataset[`contentItemId`] = `${id}`;\n this.#itemIdInput.value = `${id}`;\n }\n\n /**\n * @returns {number} logical nesting depth of node in container\n */\n get depth() {\n return parseInt(this.node.dataset[`contentDepth`]) || 0;\n }\n\n get #depthInput() {\n return this.node.querySelector(`input[name$=\"[depth]\"]`);\n }\n\n /**\n * @param depth {number} depth >= 0\n */\n set depth(depth) {\n if (this.depth === depth) return;\n\n this.node.dataset[`contentDepth`] = `${depth}`;\n this.#depthInput.value = `${depth}`;\n }\n\n /**\n * @returns {number} logical index of node in container (pre-order traversal)\n */\n get index() {\n return parseInt(this.node.dataset[`contentIndex`]);\n }\n\n get #indexInput() {\n return this.node.querySelector(`input[name$=\"[index]\"]`);\n }\n\n /**\n * @param index {number} index >= 0\n */\n set index(index) {\n if (this.index === index) return;\n\n this.node.dataset[`contentIndex`] = `${index}`;\n this.#indexInput.value = `${index}`;\n }\n\n /**\n * @returns {boolean} true if this item can have children\n */\n get isLayout() {\n return this.node.hasAttribute(\"data-content-layout\");\n }\n\n /**\n * @returns {Item} nearest neighbour (index - 1)\n */\n get previousItem() {\n let sibling = this.node.previousElementSibling;\n if (sibling) return new Item(sibling);\n }\n\n /**\n * @returns {Item} nearest neighbour (index + 1)\n */\n get nextItem() {\n let sibling = this.node.nextElementSibling;\n if (sibling) return new Item(sibling);\n }\n\n /**\n * @returns {boolean} true if this item has any collapsed children\n */\n hasCollapsedDescendants() {\n let childrenList = this.#childrenListElement;\n return !!childrenList && childrenList.children.length > 0;\n }\n\n /**\n * @returns {boolean} true if this item has any expanded children\n */\n hasExpandedDescendants() {\n let sibling = this.nextItem;\n return !!sibling && sibling.depth > this.depth;\n }\n\n /**\n * Recursively traverse the node and its descendants.\n *\n * @callback {Item}\n */\n traverse(callback) {\n // capture descendants before traversal in case of side-effects\n // specifically, setting depth affects calculation\n const expanded = this.#expandedDescendants;\n\n callback(this);\n this.#traverseCollapsed(callback);\n expanded.forEach((item) => item.#traverseCollapsed(callback));\n }\n\n /**\n * Recursively traverse the node's collapsed descendants, if any.\n *\n * @callback {Item}\n */\n #traverseCollapsed(callback) {\n if (!this.hasCollapsedDescendants()) return;\n\n this.#collapsedDescendants.forEach((item) => {\n callback(item);\n item.#traverseCollapsed(callback);\n });\n }\n\n /**\n * Move the given item into this element's hidden children list.\n * Assumes the list already exists.\n *\n * @param item {Item}\n */\n collapseChild(item) {\n this.#childrenListElement.appendChild(item.node);\n }\n\n /**\n * Collapses visible (logical) children into this element's hidden children\n * list, creating it if it doesn't already exist.\n */\n collapse() {\n let listElement = this.#childrenListElement;\n\n if (!listElement) listElement = createChildrenList(this.node);\n\n this.#expandedDescendants.forEach((child) =>\n listElement.appendChild(child.node),\n );\n }\n\n /**\n * Moves any collapsed children back into the parent container.\n */\n expand() {\n if (!this.hasCollapsedDescendants()) return;\n\n Array.from(this.#childrenListElement.children)\n .reverse()\n .forEach((node) => {\n this.node.insertAdjacentElement(\"afterend\", node);\n });\n }\n\n /**\n * Sets the state of a given rule on the target node.\n *\n * @param rule {String}\n * @param deny {boolean}\n */\n toggleRule(rule, deny = false) {\n if (this.node.dataset.hasOwnProperty(rule) && !deny) {\n delete this.node.dataset[rule];\n }\n if (!this.node.dataset.hasOwnProperty(rule) && deny) {\n this.node.dataset[rule] = \"\";\n }\n\n if (rule === \"denyDrag\") {\n if (!this.node.hasAttribute(\"draggable\") && !deny) {\n this.node.setAttribute(\"draggable\", \"true\");\n }\n if (this.node.hasAttribute(\"draggable\") && deny) {\n this.node.removeAttribute(\"draggable\");\n }\n }\n }\n\n /**\n * Detects turbo item changes by comparing the dataset id with the input\n */\n hasItemIdChanged() {\n return !(this.#itemIdInput.value === this.itemId);\n }\n\n /**\n * Updates inputs, in case they don't match the data values, e.g., when the\n * nested inputs have been hot-swapped by turbo with data from the server.\n *\n * Updates itemId from input as that is the canonical source.\n */\n updateAfterChange() {\n this.itemId = this.#itemIdInput.value;\n this.#indexInput.value = this.index;\n this.#depthInput.value = this.depth;\n }\n\n /**\n * Finds the dom container for storing collapsed (hidden) children, if present.\n *\n * @returns {Element} ol[data-content-children]\n */\n get #childrenListElement() {\n return this.node.querySelector(`:scope > [data-content-children]`);\n }\n\n /**\n * @returns {Item[]} all items that follow this element that have a greater depth.\n */\n get #expandedDescendants() {\n const descendants = [];\n\n let sibling = this.nextItem;\n while (sibling && sibling.depth > this.depth) {\n descendants.push(sibling);\n sibling = sibling.nextItem;\n }\n\n return descendants;\n }\n\n /**\n * @returns {Item[]} all items directly contained inside this element's hidden children element.\n */\n get #collapsedDescendants() {\n if (!this.hasCollapsedDescendants()) return [];\n\n return Array.from(this.#childrenListElement.children).map(\n (node) => new Item(node),\n );\n }\n}\n\n/**\n * Finds or creates a dom container for storing collapsed (hidden) children.\n *\n * @param node {Element} li[data-content-index]\n * @returns {Element} ol[data-content-children]\n */\nfunction createChildrenList(node) {\n const childrenList = document.createElement(\"ol\");\n childrenList.setAttribute(\"class\", \"hidden\");\n\n // if objectType is \"rich-content\" set richContentChildren as a data attribute\n childrenList.dataset[`contentChildren`] = \"\";\n\n node.appendChild(childrenList);\n\n return childrenList;\n}\n","import Item from \"./item\";\n\n/**\n * @param nodes {NodeList}\n * @returns {Item[]}\n */\nfunction createItemList(nodes) {\n return Array.from(nodes).map((node) => new Item(node));\n}\n\nexport default class Container {\n /**\n * @param node {Element} content editor list\n */\n constructor(node) {\n this.node = node;\n }\n\n /**\n * @return {Item[]} an ordered list of all items in the container\n */\n get items() {\n return createItemList(this.node.querySelectorAll(\"[data-content-index]\"));\n }\n\n /**\n * @return {String} a serialized description of the structure of the container\n */\n get state() {\n const inputs = this.node.querySelectorAll(\"li input[type=hidden]\");\n return Array.from(inputs)\n .map((e) => e.value)\n .join(\"/\");\n }\n\n /**\n * Set the index of items based on their current position.\n */\n reindex() {\n this.items.map((item, index) => (item.index = index));\n }\n\n /**\n * Resets the order of items to their defined index.\n * Useful after an aborted drag.\n */\n reset() {\n this.items.sort(Item.comparator).forEach((item) => {\n this.node.appendChild(item.node);\n });\n }\n}\n","export default class RulesEngine {\n static rules = [\n \"denyDeNest\",\n \"denyNest\",\n \"denyCollapse\",\n \"denyExpand\",\n \"denyRemove\",\n \"denyDrag\",\n \"denyEdit\",\n ];\n\n constructor(debug = false) {\n if (debug) {\n this.debug = (...args) => console.log(...args);\n } else {\n this.debug = () => {};\n }\n }\n\n /**\n * Enforce structural rules to ensure that the given item is currently in a\n * valid state.\n *\n * @param {Item} item\n */\n normalize(item) {\n // structural rules enforce a valid tree structure\n this.firstItemDepthZero(item);\n this.depthMustBeSet(item);\n this.itemCannotHaveInvalidDepth(item);\n this.parentMustBeLayout(item);\n this.parentCannotHaveExpandedAndCollapsedChildren(item);\n }\n\n /**\n * Apply rules to the given item to determine what operations are permitted.\n *\n * @param {Item} item\n */\n update(item) {\n this.rules = {};\n\n // behavioural rules define what the user is allowed to do\n this.parentsCannotDeNest(item);\n this.rootsCannotDeNest(item);\n this.onlyLastItemCanDeNest(item);\n this.nestingNeedsParent(item);\n this.leavesCannotCollapse(item);\n this.needHiddenItemsToExpand(item);\n this.parentsCannotBeDeleted(item);\n this.parentsCannotBeDragged(item);\n\n RulesEngine.rules.forEach((rule) => {\n item.toggleRule(rule, !!this.rules[rule]);\n });\n }\n\n /**\n * First item can't have a parent, so its depth should always be 0\n */\n firstItemDepthZero(item) {\n if (item.index === 0 && item.depth !== 0) {\n this.debug(`enforce depth on item ${item.index}: ${item.depth} => 0`);\n\n item.depth = 0;\n }\n }\n\n /**\n * Every item should have a non-negative depth set.\n *\n * @param {Item} item\n */\n depthMustBeSet(item) {\n if (isNaN(item.depth) || item.depth < 0) {\n this.debug(`unset depth on item ${item.index}: => 0`);\n\n item.depth = 0;\n }\n }\n\n /**\n * Depth must increase stepwise.\n *\n * @param {Item} item\n */\n itemCannotHaveInvalidDepth(item) {\n const previous = item.previousItem;\n if (previous && previous.depth < item.depth - 1) {\n this.debug(\n `invalid depth on item ${item.index}: ${item.depth} => ${\n previous.depth + 1\n }`,\n );\n\n item.depth = previous.depth + 1;\n }\n }\n\n /**\n * Parent item, if any, must be a layout.\n *\n * @param {Item} item\n */\n parentMustBeLayout(item) {\n // if we're the first child, make sure our parent is a layout\n // if we're a sibling, we know the previous item is valid so we must be too\n const previous = item.previousItem;\n if (previous && previous.depth < item.depth && !previous.isLayout) {\n this.debug(\n `invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}`,\n );\n\n item.depth = previous.depth;\n }\n }\n\n /**\n * If a parent has expanded and collapsed children, expand.\n *\n * @param {Item} item\n */\n parentCannotHaveExpandedAndCollapsedChildren(item) {\n if (item.hasCollapsedDescendants() && item.hasExpandedDescendants()) {\n this.debug(`expanding collapsed children of item ${item.index}`);\n\n item.expand();\n }\n }\n\n /**\n * De-nesting an item would create a gap of 2 between itself and its children\n *\n * @param {Item} item\n */\n parentsCannotDeNest(item) {\n if (item.hasExpandedDescendants()) this.#deny(\"denyDeNest\");\n }\n\n /**\n * Item depth can't go below 0.\n *\n * @param {Item} item\n */\n rootsCannotDeNest(item) {\n if (item.depth === 0) this.#deny(\"denyDeNest\");\n }\n\n /**\n * De-nesting an item that has siblings would make it a container.\n *\n * @param {Item} item\n */\n onlyLastItemCanDeNest(item) {\n const next = item.nextItem;\n if (next && next.depth === item.depth && !item.isLayout)\n this.#deny(\"denyDeNest\");\n }\n\n /**\n * If an item doesn't have children it can't be collapsed.\n *\n * @param {Item} item\n */\n leavesCannotCollapse(item) {\n if (!item.hasExpandedDescendants()) this.#deny(\"denyCollapse\");\n }\n\n /**\n * If an item doesn't have any hidden descendants then it can't be expanded.\n *\n * @param {Item} item\n */\n needHiddenItemsToExpand(item) {\n if (!item.hasCollapsedDescendants()) this.#deny(\"denyExpand\");\n }\n\n /**\n * An item can't be nested (indented) if it doesn't have a valid parent.\n *\n * @param {Item} item\n */\n nestingNeedsParent(item) {\n const previous = item.previousItem;\n // no previous, so cannot nest\n if (!previous) this.#deny(\"denyNest\");\n // previous is too shallow, nesting would increase depth too much\n else if (previous.depth < item.depth) this.#deny(\"denyNest\");\n // new parent is not a layout\n else if (previous.depth === item.depth && !previous.isLayout)\n this.#deny(\"denyNest\");\n }\n\n /**\n * An item can't be deleted if it has visible children.\n *\n * @param {Item} item\n */\n parentsCannotBeDeleted(item) {\n if (!item.itemId || item.hasExpandedDescendants()) this.#deny(\"denyRemove\");\n }\n\n /**\n * Items cannot be dragged if they have visible children.\n *\n * @param {Item} item\n */\n parentsCannotBeDragged(item) {\n if (item.hasExpandedDescendants()) this.#deny(\"denyDrag\");\n }\n\n /**\n * Record a deny.\n *\n * @param rule {String}\n */\n #deny(rule) {\n this.rules[rule] = true;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport Item from \"./item\";\nimport Container from \"./container\";\nimport RulesEngine from \"./rules_engine\";\n\nexport default class ContainerController extends Controller {\n static targets = [\"container\"];\n\n connect() {\n this.state = this.container.state;\n\n this.reindex();\n }\n\n get container() {\n return new Container(this.containerTarget);\n }\n\n reindex() {\n this.container.reindex();\n this.#update();\n }\n\n reset() {\n this.container.reset();\n }\n\n drop(event) {\n this.container.reindex(); // set indexes before calculating previous\n\n const item = getEventItem(event);\n const previous = item.previousItem;\n\n let delta = 0;\n if (previous === undefined) {\n // if previous does not exist, set depth to 0\n delta = -item.depth;\n } else if (\n previous.isLayout &&\n item.nextItem &&\n item.nextItem.depth > previous.depth\n ) {\n // if previous is a layout and next is a child of previous, make item a child of previous\n delta = previous.depth - item.depth + 1;\n } else {\n // otherwise, make item a sibling of previous\n delta = previous.depth - item.depth;\n }\n\n item.traverse((child) => {\n child.depth += delta;\n });\n\n this.#update();\n event.preventDefault();\n }\n\n remove(event) {\n const item = getEventItem(event);\n\n item.node.remove();\n\n this.#update();\n event.preventDefault();\n }\n\n nest(event) {\n const item = getEventItem(event);\n\n item.traverse((child) => {\n child.depth += 1;\n });\n\n this.#update();\n event.preventDefault();\n }\n\n deNest(event) {\n const item = getEventItem(event);\n\n item.traverse((child) => {\n child.depth -= 1;\n });\n\n this.#update();\n event.preventDefault();\n }\n\n collapse(event) {\n const item = getEventItem(event);\n\n item.collapse();\n\n this.#update();\n event.preventDefault();\n }\n\n expand(event) {\n const item = getEventItem(event);\n\n item.expand();\n\n this.#update();\n event.preventDefault();\n }\n\n /**\n * Re-apply rules to items to enable/disable appropriate actions.\n */\n #update() {\n // debounce requests to ensure that we only update once per tick\n this.updateRequested = true;\n setTimeout(() => {\n if (!this.updateRequested) return;\n\n this.updateRequested = false;\n const engine = new RulesEngine();\n this.container.items.forEach((item) => engine.normalize(item));\n this.container.items.forEach((item) => engine.update(item));\n\n this.#notifyChange();\n }, 0);\n }\n\n #notifyChange() {\n this.dispatch(\"change\", {\n bubbles: true,\n prefix: \"content\",\n detail: { dirty: this.#isDirty() },\n });\n }\n\n #isDirty() {\n return this.container.state !== this.state;\n }\n}\n\nfunction getEventItem(event) {\n return new Item(event.target.closest(\"[data-content-item]\"));\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class ListController extends Controller {\n connect() {\n this.enterCount = 0;\n }\n\n /**\n * When the user starts a drag within the list, set the item's dataTransfer\n * properties to indicate that it's being dragged and update its style.\n *\n * We delay setting the dataset property until the next animation frame\n * so that the style updates can be computed before the drag begins.\n *\n * @param event {DragEvent}\n */\n dragstart(event) {\n if (this.element !== event.target.parentElement) return;\n\n const target = event.target;\n event.dataTransfer.effectAllowed = \"move\";\n\n // update element style after drag has begun\n requestAnimationFrame(() => (target.dataset.dragging = \"\"));\n }\n\n /**\n * When the user drags an item over another item in the last, swap the\n * dragging item with the item under the cursor.\n *\n * As a special case, if the item is dragged over placeholder space at the end\n * of the list, move the item to the bottom of the list instead. This allows\n * users to hit the list element more easily when adding new items to an empty\n * list.\n *\n * @param event {DragEvent}\n */\n dragover(event) {\n const item = this.dragItem;\n if (!item) return;\n\n swap(dropTarget(event.target), item);\n\n event.preventDefault();\n return true;\n }\n\n /**\n * When the user drags an item into the list, create a placeholder item to\n * represent the new item. Note that we can't access the drag data\n * until drop, so we assume that this is our template item for now.\n *\n * Users can cancel the drag by dragging the item out of the list or by\n * pressing escape. Both are handled by `cancelDrag`.\n *\n * @param event {DragEvent}\n */\n dragenter(event) {\n event.preventDefault();\n\n // Safari doesn't support relatedTarget, so we count enter/leave pairs\n this.enterCount++;\n\n if (copyAllowed(event) && !this.dragItem) {\n const item = document.createElement(\"li\");\n item.dataset.dragging = \"\";\n item.dataset.newItem = \"\";\n this.element.appendChild(item);\n }\n }\n\n /**\n * When the user drags the item out of the list, remove the placeholder.\n * This allows users to cancel the drag by dragging the item out of the list.\n *\n * @param event {DragEvent}\n */\n dragleave(event) {\n // Safari doesn't support relatedTarget, so we count enter/leave pairs\n // https://bugs.webkit.org/show_bug.cgi?id=66547\n this.enterCount--;\n\n if (\n this.enterCount <= 0 &&\n this.dragItem.dataset.hasOwnProperty(\"newItem\")\n ) {\n this.cancelDrag(event);\n }\n }\n\n /**\n * When the user drops an item into the list, end the drag and reindex the list.\n *\n * If the item is a new item, we replace the placeholder with the template\n * item data from the dataTransfer API.\n *\n * @param event {DragEvent}\n */\n drop(event) {\n let item = this.dragItem;\n\n if (!item) return;\n\n event.preventDefault();\n delete item.dataset.dragging;\n swap(dropTarget(event.target), item);\n\n if (item.dataset.hasOwnProperty(\"newItem\")) {\n const placeholder = item;\n const template = document.createElement(\"template\");\n template.innerHTML = event.dataTransfer.getData(\"text/html\");\n item = template.content.querySelector(\"li\");\n\n this.element.replaceChild(item, placeholder);\n requestAnimationFrame(() =>\n item.querySelector(\"[role='button'][value='edit']\").click(),\n );\n }\n\n this.dispatch(\"drop\", { target: item, bubbles: true, prefix: \"content\" });\n }\n\n /**\n * End an in-progress drag. If the item is a new item, remove it, otherwise\n * reset the item's style and restore its original position in the list.\n */\n dragend() {\n const item = this.dragItem;\n\n if (!item) {\n } else if (item.dataset.hasOwnProperty(\"newItem\")) {\n item.remove();\n } else {\n delete item.dataset.dragging;\n this.reset();\n }\n }\n\n get isDragging() {\n return !!this.dragItem;\n }\n\n get dragItem() {\n return this.element.querySelector(\"[data-dragging]\");\n }\n\n reindex() {\n this.dispatch(\"reindex\", { bubbles: true, prefix: \"content\" });\n }\n\n reset() {\n this.dispatch(\"reset\", { bubbles: true, prefix: \"content\" });\n }\n}\n\n/**\n * Swaps two list items. If target is a list, the item is appended.\n *\n * @param target the target element to swap with\n * @param item the item the user is dragging\n */\nfunction swap(target, item) {\n if (!target) return;\n if (target === item) return;\n\n if (target.nodeName === \"LI\") {\n const positionComparison = target.compareDocumentPosition(item);\n if (positionComparison & Node.DOCUMENT_POSITION_FOLLOWING) {\n target.insertAdjacentElement(\"beforebegin\", item);\n } else if (positionComparison & Node.DOCUMENT_POSITION_PRECEDING) {\n target.insertAdjacentElement(\"afterend\", item);\n }\n }\n\n if (target.nodeName === \"OL\") {\n target.appendChild(item);\n }\n}\n\n/**\n * Returns true if the event supports copy or copy move.\n *\n * Chrome and Firefox use copy, but Safari only supports copyMove.\n */\nfunction copyAllowed(event) {\n return (\n event.dataTransfer.effectAllowed === \"copy\" ||\n event.dataTransfer.effectAllowed === \"copyMove\"\n );\n}\n\n/**\n * Given an event target, return the closest drop target, if any.\n */\nfunction dropTarget(e) {\n return (\n e &&\n (e.closest(\"[data-controller='content--editor--list'] > *\") ||\n e.closest(\"[data-controller='content--editor--list']\"))\n );\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport \"trix\";\n\n// Note, action_text 7.1.2 changes how Trix is bundled and loaded. This\n// seems to have broken the default export from trix. This is a workaround\n// that relies on the backwards compatibility of the old export to window.Trix.\nconst Trix = window.Trix;\n\n// Stimulus controller doesn't do anything, but having one ensures that trix\n// will be lazy loaded when a trix-editor is added to the dom.\nexport default class TrixController extends Controller {\n trixInitialize(e) {\n // noop, useful as an extension point for registering behaviour on load\n }\n}\n\n// Add H4 as an acceptable tag\nTrix.config.blockAttributes[\"heading4\"] = {\n tagName: \"h4\",\n terminal: true,\n breakOnReturn: true,\n group: false,\n};\n\n// Remove H1 from trix list of acceptable tags\ndelete Trix.config.blockAttributes.heading1;\n\n/**\n * Allow users to enter path and fragment URIs which the input[type=url] browser\n * input does not permit. Uses a permissive regex pattern which is not suitable\n * for untrusted use cases.\n */\nconst LINK_PATTERN = \"(https?|mailto:|tel:|/|#).*?\";\n\n/**\n * Customize default toolbar:\n *\n * * headings: h4 instead of h1\n * * links: use type=text instead of type=url\n *\n * @returns {String} toolbar html fragment\n */\nTrix.config.toolbar.getDefaultHTML = () => {\n const { lang } = Trix.config;\n return `\n<div class=\"trix-button-row\">\n <span class=\"trix-button-group trix-button-group--text-tools\" data-trix-button-group=\"text-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bold\" data-trix-attribute=\"bold\" data-trix-key=\"b\" title=\"${lang.bold}\" tabindex=\"-1\">${lang.bold}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-italic\" data-trix-attribute=\"italic\" data-trix-key=\"i\" title=\"${lang.italic}\" tabindex=\"-1\">${lang.italic}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-strike\" data-trix-attribute=\"strike\" title=\"${lang.strike}\" tabindex=\"-1\">${lang.strike}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-link\" data-trix-attribute=\"href\" data-trix-action=\"link\" data-trix-key=\"k\" title=\"${lang.link}\" tabindex=\"-1\">${lang.link}</button>\n </span>\n <span class=\"trix-button-group trix-button-group--block-tools\" data-trix-button-group=\"block-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-heading-1\" data-trix-attribute=\"heading4\" title=\"${lang.heading1}\" tabindex=\"-1\">${lang.heading1}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-quote\" data-trix-attribute=\"quote\" title=\"${lang.quote}\" tabindex=\"-1\">${lang.quote}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-code\" data-trix-attribute=\"code\" title=\"${lang.code}\" tabindex=\"-1\">${lang.code}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bullet-list\" data-trix-attribute=\"bullet\" title=\"${lang.bullets}\" tabindex=\"-1\">${lang.bullets}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-number-list\" data-trix-attribute=\"number\" title=\"${lang.numbers}\" tabindex=\"-1\">${lang.numbers}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-decrease-nesting-level\" data-trix-action=\"decreaseNestingLevel\" title=\"${lang.outdent}\" tabindex=\"-1\">${lang.outdent}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-increase-nesting-level\" data-trix-action=\"increaseNestingLevel\" title=\"${lang.indent}\" tabindex=\"-1\">${lang.indent}</button>\n </span>\n <span class=\"trix-button-group trix-button-group--file-tools\" data-trix-button-group=\"file-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-attach\" data-trix-action=\"attachFiles\" title=\"${lang.attachFiles}\" tabindex=\"-1\">${lang.attachFiles}</button>\n </span>\n <span class=\"trix-button-group-spacer\"></span>\n <span class=\"trix-button-group trix-button-group--history-tools\" data-trix-button-group=\"history-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-undo\" data-trix-action=\"undo\" data-trix-key=\"z\" title=\"${lang.undo}\" tabindex=\"-1\">${lang.undo}</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-redo\" data-trix-action=\"redo\" data-trix-key=\"shift+z\" title=\"${lang.redo}\" tabindex=\"-1\">${lang.redo}</button>\n </span>\n</div>\n<div class=\"trix-dialogs\" data-trix-dialogs>\n <div class=\"trix-dialog trix-dialog--link\" data-trix-dialog=\"href\" data-trix-dialog-attribute=\"href\">\n <div class=\"trix-dialog__link-fields\">\n <input type=\"text\" name=\"href\" pattern=\"${LINK_PATTERN}\" class=\"trix-input trix-input--dialog\" placeholder=\"${lang.urlPlaceholder}\" aria-label=\"${lang.url}\" required data-trix-input>\n <div class=\"trix-button-group\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"${lang.link}\" data-trix-method=\"setAttribute\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"${lang.unlink}\" data-trix-method=\"removeAttribute\">\n </div>\n </div>\n </div>\n</div>\n`;\n};\n\n/**\n * If the <trix-editor> element is in the HTML when Trix loads, then Trix will have already injected the toolbar content\n * before our code gets a chance to run. Fix that now.\n *\n * Note: in Trix 2 this is likely to no longer be necessary.\n */\ndocument.querySelectorAll(\"trix-toolbar\").forEach((e) => {\n e.innerHTML = Trix.config.toolbar.getDefaultHTML();\n});\n","import ContainerController from \"./editor/container_controller\";\nimport ItemController from \"./editor/item_controller\";\nimport ListController from \"./editor/list_controller\";\nimport NewItemController from \"./editor/new_item_controller\";\nimport StatusBarController from \"./editor/status_bar_controller\";\nimport TrixController from \"./editor/trix_controller\";\n\nconst Definitions = [\n {\n identifier: \"content--editor--container\",\n controllerConstructor: ContainerController,\n },\n {\n identifier: \"content--editor--item\",\n controllerConstructor: ItemController,\n },\n {\n identifier: \"content--editor--list\",\n controllerConstructor: ListController,\n },\n {\n identifier: \"content--editor--new-item\",\n controllerConstructor: NewItemController,\n },\n {\n identifier: \"content--editor--status-bar\",\n controllerConstructor: StatusBarController,\n },\n {\n identifier: \"content--editor--trix\",\n controllerConstructor: TrixController,\n },\n];\n\nexport { Definitions as default };\n","import { Controller } from \"@hotwired/stimulus\";\nimport Item from \"./item\";\n\nexport default class ItemController extends Controller {\n get item() {\n return new Item(this.li);\n }\n\n get ol() {\n return this.element.closest(\"ol\");\n }\n\n get li() {\n return this.element.closest(\"li\");\n }\n\n connect() {\n if (this.element.dataset.hasOwnProperty(\"delete\")) {\n this.remove();\n }\n // if index is not already set, re-index will set it\n else if (!(this.item.index >= 0)) {\n this.reindex();\n }\n // if item has been replaced via turbo, re-index will run the rules engine\n // update our depth and index with values from the li's data attributes\n else if (this.item.hasItemIdChanged()) {\n this.item.updateAfterChange();\n this.reindex();\n }\n }\n\n remove() {\n // capture ol\n const ol = this.ol;\n // remove self from dom\n this.li.remove();\n // reindex ol\n this.reindex();\n }\n\n reindex() {\n this.dispatch(\"reindex\", { bubbles: true, prefix: \"content\" });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class NewItemController extends Controller {\n static targets = [\"template\"];\n\n dragstart(event) {\n if (this.element !== event.target) return;\n\n event.dataTransfer.setData(\"text/html\", this.templateTarget.innerHTML);\n event.dataTransfer.effectAllowed = \"copy\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class StatusBarController extends Controller {\n connect() {\n // cache the version's state in the controller on connect\n this.versionState = this.element.dataset.state;\n }\n\n change(e) {\n if (e.detail && e.detail.hasOwnProperty(\"dirty\")) {\n this.update(e.detail);\n }\n }\n\n update({ dirty }) {\n if (dirty) {\n this.element.dataset.state = \"dirty\";\n } else {\n this.element.dataset.state = this.versionState;\n }\n }\n}\n"],"names":["Item","comparator","a","b","index","constructor","node","this","itemId","dataset","itemIdInput","querySelector","id","value","depth","parseInt","depthInput","indexInput","isLayout","hasAttribute","previousItem","sibling","previousElementSibling","nextItem","nextElementSibling","hasCollapsedDescendants","childrenList","childrenListElement","children","length","hasExpandedDescendants","traverse","callback","expanded","expandedDescendants","traverseCollapsed","forEach","item","collapsedDescendants","collapseChild","appendChild","collapse","listElement","document","createElement","setAttribute","createChildrenList","child","expand","Array","from","reverse","insertAdjacentElement","toggleRule","rule","deny","hasOwnProperty","removeAttribute","hasItemIdChanged","updateAfterChange","descendants","push","map","Container","items","nodes","querySelectorAll","state","inputs","e","join","reindex","reset","sort","RulesEngine","static","debug","args","console","log","normalize","firstItemDepthZero","depthMustBeSet","itemCannotHaveInvalidDepth","parentMustBeLayout","parentCannotHaveExpandedAndCollapsedChildren","update","rules","parentsCannotDeNest","rootsCannotDeNest","onlyLastItemCanDeNest","nestingNeedsParent","leavesCannotCollapse","needHiddenItemsToExpand","parentsCannotBeDeleted","parentsCannotBeDragged","isNaN","previous","next","getEventItem","event","target","closest","swap","nodeName","positionComparison","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","DOCUMENT_POSITION_PRECEDING","dropTarget","Trix","window","config","blockAttributes","tagName","terminal","breakOnReturn","group","heading1","toolbar","getDefaultHTML","lang","bold","italic","strike","link","quote","code","bullets","numbers","outdent","indent","attachFiles","undo","redo","urlPlaceholder","url","unlink","innerHTML","Definitions","identifier","controllerConstructor","Controller","connect","container","containerTarget","drop","delta","undefined","preventDefault","remove","nest","deNest","updateRequested","setTimeout","engine","notifyChange","dispatch","bubbles","prefix","detail","dirty","isDirty","li","ol","element","enterCount","dragstart","parentElement","dataTransfer","effectAllowed","requestAnimationFrame","dragging","dragover","dragItem","dragenter","copyAllowed","newItem","dragleave","cancelDrag","placeholder","template","getData","content","replaceChild","click","dragend","isDragging","setData","templateTarget","versionState","change","trixInitialize"],"mappings":"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"}
|
@@ -168,7 +168,7 @@ export default class Item {
|
|
168
168
|
if (!listElement) listElement = createChildrenList(this.node);
|
169
169
|
|
170
170
|
this.#expandedDescendants.forEach((child) =>
|
171
|
-
listElement.appendChild(child.node)
|
171
|
+
listElement.appendChild(child.node),
|
172
172
|
);
|
173
173
|
}
|
174
174
|
|
@@ -259,7 +259,7 @@ export default class Item {
|
|
259
259
|
if (!this.hasCollapsedDescendants()) return [];
|
260
260
|
|
261
261
|
return Array.from(this.#childrenListElement.children).map(
|
262
|
-
(node) => new Item(node)
|
262
|
+
(node) => new Item(node),
|
263
263
|
);
|
264
264
|
}
|
265
265
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {Controller} from "@hotwired/stimulus";
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
3
|
export default class ListController extends Controller {
|
4
4
|
connect() {
|
@@ -80,7 +80,10 @@ export default class ListController extends Controller {
|
|
80
80
|
// https://bugs.webkit.org/show_bug.cgi?id=66547
|
81
81
|
this.enterCount--;
|
82
82
|
|
83
|
-
if (
|
83
|
+
if (
|
84
|
+
this.enterCount <= 0 &&
|
85
|
+
this.dragItem.dataset.hasOwnProperty("newItem")
|
86
|
+
) {
|
84
87
|
this.cancelDrag(event);
|
85
88
|
}
|
86
89
|
}
|
@@ -110,11 +113,11 @@ export default class ListController extends Controller {
|
|
110
113
|
|
111
114
|
this.element.replaceChild(item, placeholder);
|
112
115
|
requestAnimationFrame(() =>
|
113
|
-
item.querySelector("[role='button'][value='edit']").click()
|
116
|
+
item.querySelector("[role='button'][value='edit']").click(),
|
114
117
|
);
|
115
118
|
}
|
116
119
|
|
117
|
-
this.dispatch("drop", {target: item, bubbles: true, prefix: "content"});
|
120
|
+
this.dispatch("drop", { target: item, bubbles: true, prefix: "content" });
|
118
121
|
}
|
119
122
|
|
120
123
|
/**
|
@@ -142,11 +145,11 @@ export default class ListController extends Controller {
|
|
142
145
|
}
|
143
146
|
|
144
147
|
reindex() {
|
145
|
-
this.dispatch("reindex", {bubbles: true, prefix: "content"});
|
148
|
+
this.dispatch("reindex", { bubbles: true, prefix: "content" });
|
146
149
|
}
|
147
150
|
|
148
151
|
reset() {
|
149
|
-
this.dispatch("reset", {bubbles: true, prefix: "content"});
|
152
|
+
this.dispatch("reset", { bubbles: true, prefix: "content" });
|
150
153
|
}
|
151
154
|
}
|
152
155
|
|
@@ -190,8 +193,9 @@ function copyAllowed(event) {
|
|
190
193
|
* Given an event target, return the closest drop target, if any.
|
191
194
|
*/
|
192
195
|
function dropTarget(e) {
|
193
|
-
return
|
194
|
-
e
|
195
|
-
e.closest("[data-controller='content--editor--list']")
|
196
|
+
return (
|
197
|
+
e &&
|
198
|
+
(e.closest("[data-controller='content--editor--list'] > *") ||
|
199
|
+
e.closest("[data-controller='content--editor--list']"))
|
196
200
|
);
|
197
201
|
}
|
@@ -90,7 +90,7 @@ export default class RulesEngine {
|
|
90
90
|
this.debug(
|
91
91
|
`invalid depth on item ${item.index}: ${item.depth} => ${
|
92
92
|
previous.depth + 1
|
93
|
-
}
|
93
|
+
}`,
|
94
94
|
);
|
95
95
|
|
96
96
|
item.depth = previous.depth + 1;
|
@@ -108,7 +108,7 @@ export default class RulesEngine {
|
|
108
108
|
const previous = item.previousItem;
|
109
109
|
if (previous && previous.depth < item.depth && !previous.isLayout) {
|
110
110
|
this.debug(
|
111
|
-
`invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}
|
111
|
+
`invalid parent for item ${item.index}: ${item.depth} => ${previous.depth}`,
|
112
112
|
);
|
113
113
|
|
114
114
|
item.depth = previous.depth;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: katalyst-content
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katalyst Interactive
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_storage_validations
|
@@ -186,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: '0'
|
188
188
|
requirements: []
|
189
|
-
rubygems_version: 3.4.
|
189
|
+
rubygems_version: 3.4.19
|
190
190
|
signing_key:
|
191
191
|
specification_version: 4
|
192
192
|
summary: Rich content page builder and editor
|