|
1 | 1 | /* global django,ContentEditor */
|
2 | 2 | ;(() => {
|
3 |
| - const _contentEditorContext = document.getElementById( |
4 |
| - "content-editor-context", |
5 |
| - ).textContent |
6 |
| - |
| 3 | + /* |
| 4 | + * GENERAL UTILITIES |
| 5 | + */ |
7 | 6 | function qs(sel, ctx = document) {
|
8 | 7 | return ctx.querySelector(sel)
|
9 | 8 | }
|
10 | 9 | function qsa(sel, ctx = document) {
|
11 | 10 | return Array.from(ctx.querySelectorAll(sel))
|
12 | 11 | }
|
13 | 12 |
|
| 13 | + function buildDropdown(contents, title) { |
| 14 | + const select = document.createElement("select") |
| 15 | + let idx = 0 |
| 16 | + |
| 17 | + if (title) { |
| 18 | + select.options[idx++] = new Option(title, "", true) |
| 19 | + } |
| 20 | + |
| 21 | + for (const content of contents) { |
| 22 | + // Option _values_ may either be the prefix (for plugins) or keys (for |
| 23 | + // regions) |
| 24 | + select.options[idx++] = new Option( |
| 25 | + content.title, |
| 26 | + content.prefix || content.key, |
| 27 | + ) |
| 28 | + } |
| 29 | + return select |
| 30 | + } |
| 31 | + |
14 | 32 | const safeStorage = (storage, prefix = "ContentEditor:") => {
|
15 | 33 | return {
|
16 | 34 | set(name, value) {
|
|
32 | 50 |
|
33 | 51 | const LS = safeStorage(localStorage)
|
34 | 52 |
|
35 |
| - const prepareContentEditorObject = () => { |
36 |
| - Object.assign(ContentEditor, JSON.parse(_contentEditorContext)) |
| 53 | + /* |
| 54 | + * CONTENT EDITOR UTILITIES */ |
| 55 | + |
| 56 | + const prepareContentEditorObject = ($) => { |
| 57 | + const _contentEditorContext = document.getElementById( |
| 58 | + "content-editor-context", |
| 59 | + ).textContent |
| 60 | + |
| 61 | + const ContentEditor = JSON.parse(_contentEditorContext) |
37 | 62 | Object.assign(ContentEditor, {
|
38 | 63 | declaredRegions: [...ContentEditor.regions],
|
39 | 64 | pluginsByPrefix: Object.fromEntries(
|
|
43 | 68 | ContentEditor.regions.map((region) => [region.key, region]),
|
44 | 69 | ),
|
45 | 70 | hasSections: ContentEditor.plugins.some((plugin) => plugin.sections),
|
| 71 | + |
| 72 | + addContent(prefix) { |
| 73 | + $(`#${prefix}-group .add-row a`).click() |
| 74 | + }, |
46 | 75 | })
|
| 76 | + |
| 77 | + return ContentEditor |
47 | 78 | }
|
48 | 79 |
|
| 80 | + function defineContentEditorStyles(ContentEditor) { |
| 81 | + const style = document.createElement("style") |
| 82 | + style.textContent = ` |
| 83 | +.order-machine .inline-related .inline_label::after { |
| 84 | + content: "(${window.gettext("Hide")})"; |
| 85 | + opacity: 0.7; |
| 86 | + margin-left: 0.5ch; |
| 87 | + cursor: pointer; |
| 88 | +} |
| 89 | +.order-machine .inline-related .inline_label:hover::after { |
| 90 | + text-decoration: underline; |
| 91 | +} |
| 92 | +.order-machine .inline-related.collapsed .inline_label::after { |
| 93 | + content: "(${window.gettext("Show")})"; |
| 94 | + color: var(--link-fg, #447e9b); |
| 95 | + opacity: 1; |
| 96 | +} |
| 97 | +.order-machine .inline-related.for-deletion .inline_label::after { |
| 98 | + opacity: 0.5; |
| 99 | + content: " (${ContentEditor.messages.forDeletion})"; |
| 100 | +} |
| 101 | +.order-machine .inline-related:not(:where(${ContentEditor.declaredRegions.map((region) => `[data-region="${region.key}"]`).join(", ")})) .inline_move_to_region { |
| 102 | + border-color: red; |
| 103 | +} |
| 104 | + ` |
| 105 | + document.head.append(style) |
| 106 | + } |
| 107 | + |
| 108 | + /* |
| 109 | + * CONTENT EDITOR INITIALIZATION |
| 110 | + */ |
| 111 | + |
49 | 112 | django.jQuery(($) => {
|
50 |
| - window.ContentEditor = { |
51 |
| - addContent: function addContent(prefix) { |
52 |
| - $(`#${prefix}-group .add-row a`).click() |
53 |
| - }, |
54 |
| - addPluginButton: function addPluginButton(prefix, iconHTML) { |
55 |
| - const plugin = ContentEditor.pluginsByPrefix[prefix] |
56 |
| - if (!plugin) return |
57 |
| - |
58 |
| - const button = document.createElement("a") |
59 |
| - button.dataset.pluginPrefix = plugin.prefix |
60 |
| - button.className = "plugin-button" |
61 |
| - button.title = plugin.title |
62 |
| - button.addEventListener("click", (e) => { |
63 |
| - e.preventDefault() |
64 |
| - ContentEditor.addContent(plugin.prefix) |
65 |
| - hidePluginButtons() |
66 |
| - }) |
| 113 | + window.ContentEditor = prepareContentEditorObject($) |
67 | 114 |
|
68 |
| - const icon = document.createElement("span") |
69 |
| - icon.className = "plugin-button-icon" |
70 |
| - icon.innerHTML = |
71 |
| - iconHTML || '<span class="material-icons">extension</span>' |
72 |
| - button.appendChild(icon) |
73 |
| - if (plugin.color) { |
74 |
| - icon.style.color = plugin.color |
75 |
| - } |
| 115 | + ContentEditor.addPluginButton = (prefix, iconHTML) => { |
| 116 | + const plugin = ContentEditor.pluginsByPrefix[prefix] |
| 117 | + if (!plugin) return |
76 | 118 |
|
77 |
| - const title = document.createElement("span") |
78 |
| - title.className = "plugin-button-title" |
79 |
| - title.textContent = plugin.title |
80 |
| - button.appendChild(title) |
| 119 | + const button = document.createElement("a") |
| 120 | + button.dataset.pluginPrefix = plugin.prefix |
| 121 | + button.className = "plugin-button" |
| 122 | + button.title = plugin.title |
| 123 | + button.addEventListener("click", (e) => { |
| 124 | + e.preventDefault() |
| 125 | + ContentEditor.addContent(plugin.prefix) |
| 126 | + hidePluginButtons() |
| 127 | + }) |
81 | 128 |
|
82 |
| - const unit = qs(".plugin-buttons") |
83 |
| - unit.appendChild(button) |
| 129 | + const icon = document.createElement("span") |
| 130 | + icon.className = "plugin-button-icon" |
| 131 | + icon.innerHTML = |
| 132 | + iconHTML || '<span class="material-icons">extension</span>' |
| 133 | + button.appendChild(icon) |
| 134 | + if (plugin.color) { |
| 135 | + icon.style.color = plugin.color |
| 136 | + } |
84 | 137 |
|
85 |
| - hideNotAllowedPluginButtons([button]) |
86 |
| - }, |
87 |
| - } |
| 138 | + const title = document.createElement("span") |
| 139 | + title.className = "plugin-button-title" |
| 140 | + title.textContent = plugin.title |
| 141 | + button.appendChild(title) |
88 | 142 |
|
89 |
| - prepareContentEditorObject() |
| 143 | + const unit = qs(".plugin-buttons") |
| 144 | + unit.appendChild(button) |
| 145 | + |
| 146 | + hideNotAllowedPluginButtons([button]) |
| 147 | + } |
90 | 148 |
|
91 | 149 | // Add basic structure. There is always at least one inline group if
|
92 | 150 | // we even have any plugins.
|
|
423 | 481 | })
|
424 | 482 | }
|
425 | 483 |
|
426 |
| - function buildDropdown(contents, title) { |
427 |
| - const select = document.createElement("select") |
428 |
| - let idx = 0 |
429 |
| - |
430 |
| - if (title) { |
431 |
| - select.options[idx++] = new Option(title, "", true) |
432 |
| - } |
433 |
| - |
434 |
| - for (const content of contents) { |
435 |
| - // Option _values_ may either be the prefix (for plugins) or keys (for |
436 |
| - // regions) |
437 |
| - select.options[idx++] = new Option( |
438 |
| - content.title, |
439 |
| - content.prefix || content.key, |
440 |
| - ) |
441 |
| - } |
442 |
| - return select |
443 |
| - } |
444 |
| - |
445 | 484 | function pluginInCurrentRegion(prefix) {
|
446 | 485 | if (!ContentEditor.regions.length) return false
|
447 | 486 |
|
|
967 | 1006 | ContentEditor.addPluginButton(plugin.prefix, plugin.button)
|
968 | 1007 | }
|
969 | 1008 |
|
970 |
| - const style = document.createElement("style") |
971 |
| - style.textContent = ` |
972 |
| -.order-machine .inline-related .inline_label::after { |
973 |
| - content: "(${window.gettext("Hide")})"; |
974 |
| - opacity: 0.7; |
975 |
| - margin-left: 0.5ch; |
976 |
| - cursor: pointer; |
977 |
| -} |
978 |
| -.order-machine .inline-related .inline_label:hover::after { |
979 |
| - text-decoration: underline; |
980 |
| -} |
981 |
| -.order-machine .inline-related.collapsed .inline_label::after { |
982 |
| - content: "(${window.gettext("Show")})"; |
983 |
| - color: var(--link-fg, #447e9b); |
984 |
| - opacity: 1; |
985 |
| -} |
986 |
| -.order-machine .inline-related.for-deletion .inline_label::after { |
987 |
| - opacity: 0.5; |
988 |
| - content: " (${ContentEditor.messages.forDeletion})"; |
989 |
| -} |
990 |
| -.order-machine .inline-related:not(:where(${ContentEditor.declaredRegions.map((region) => `[data-region="${region.key}"]`).join(", ")})) .inline_move_to_region { |
991 |
| - border-color: red; |
992 |
| -} |
993 |
| - ` |
994 |
| - document.head.appendChild(style) |
995 |
| - |
996 | 1009 | if (!ContentEditor.allowChange) {
|
997 | 1010 | $(".order-machine-wrapper").addClass("order-machine-readonly")
|
998 | 1011 | }
|
999 | 1012 |
|
| 1013 | + defineContentEditorStyles(ContentEditor) |
| 1014 | + |
1000 | 1015 | $(document).trigger("content-editor:ready")
|
1001 | 1016 | })
|
1002 | 1017 | })()
|
0 commit comments