|
|
|
@ -39,29 +39,30 @@ export default class MagazineHierarchyEditorController extends Controller { |
|
|
|
* never reaches the panel (e.g. `stopPropagation` from another listener) or fieldset/legend |
|
|
|
* never reaches the panel (e.g. `stopPropagation` from another listener) or fieldset/legend |
|
|
|
* hit-testing is odd. |
|
|
|
* hit-testing is odd. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
// Bind once: re-binding on every reconnect wraps the already-bound function, and the bound
|
|
|
|
// Bind once using *different* property names than the method names.
|
|
|
|
// reference must be stable so removeEventListener in disconnect() can match it.
|
|
|
|
// ??= would short-circuit for same-name properties because the prototype method is
|
|
|
|
this._onDocClickCapture ??= this._onDocClickCapture.bind(this); |
|
|
|
// already non-null, leaving the handler unbound (this === DOM element at call time).
|
|
|
|
this._onPanelFocusOut ??= this._onPanelFocusOut.bind(this); |
|
|
|
this._boundDocClickCapture ??= this._onDocClickCapture.bind(this); |
|
|
|
this._onDragStart ??= this._onDragStart.bind(this); |
|
|
|
this._boundPanelFocusOut ??= this._onPanelFocusOut.bind(this); |
|
|
|
this._onDragOver ??= this._onDragOver.bind(this); |
|
|
|
this._boundDragStart ??= this._onDragStart.bind(this); |
|
|
|
this._onDrop ??= this._onDrop.bind(this); |
|
|
|
this._boundDragOver ??= this._onDragOver.bind(this); |
|
|
|
this._onDragEnd ??= this._onDragEnd.bind(this); |
|
|
|
this._boundDrop ??= this._onDrop.bind(this); |
|
|
|
document.addEventListener('click', this._onDocClickCapture, true); |
|
|
|
this._boundDragEnd ??= this._onDragEnd.bind(this); |
|
|
|
this.element.addEventListener('focusout', this._onPanelFocusOut); |
|
|
|
document.addEventListener('click', this._boundDocClickCapture, true); |
|
|
|
this.element.addEventListener('dragstart', this._onDragStart); |
|
|
|
this.element.addEventListener('focusout', this._boundPanelFocusOut); |
|
|
|
this.element.addEventListener('dragover', this._onDragOver); |
|
|
|
this.element.addEventListener('dragstart', this._boundDragStart); |
|
|
|
this.element.addEventListener('drop', this._onDrop); |
|
|
|
this.element.addEventListener('dragover', this._boundDragOver); |
|
|
|
this.element.addEventListener('dragend', this._onDragEnd); |
|
|
|
this.element.addEventListener('drop', this._boundDrop); |
|
|
|
|
|
|
|
this.element.addEventListener('dragend', this._boundDragEnd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
disconnect() { |
|
|
|
disconnect() { |
|
|
|
document.removeEventListener('click', this._onDocClickCapture, true); |
|
|
|
document.removeEventListener('click', this._boundDocClickCapture, true); |
|
|
|
this.element.removeEventListener('focusout', this._onPanelFocusOut); |
|
|
|
this.element.removeEventListener('focusout', this._boundPanelFocusOut); |
|
|
|
this.element.removeEventListener('dragstart', this._onDragStart); |
|
|
|
this.element.removeEventListener('dragstart', this._boundDragStart); |
|
|
|
this.element.removeEventListener('dragover', this._onDragOver); |
|
|
|
this.element.removeEventListener('dragover', this._boundDragOver); |
|
|
|
this.element.removeEventListener('drop', this._onDrop); |
|
|
|
this.element.removeEventListener('drop', this._boundDrop); |
|
|
|
this.element.removeEventListener('dragend', this._onDragEnd); |
|
|
|
this.element.removeEventListener('dragend', this._boundDragEnd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -85,6 +86,9 @@ export default class MagazineHierarchyEditorController extends Controller { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
const t = ev.target; |
|
|
|
const t = ev.target; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Publish: handled here via document-capture; the button must NOT also carry a
|
|
|
|
|
|
|
|
// data-action binding or _publish() would fire twice per click.
|
|
|
|
if (t.closest('[data-mag-editor-cmd="publish"]')) { |
|
|
|
if (t.closest('[data-mag-editor-cmd="publish"]')) { |
|
|
|
void this._publish(); |
|
|
|
void this._publish(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
@ -93,34 +97,24 @@ export default class MagazineHierarchyEditorController extends Controller { |
|
|
|
this.addTopLevelCategory(); |
|
|
|
this.addTopLevelCategory(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
const addSubCmd = t.closest('[data-mag-editor-cmd="add-subcategory"]'); |
|
|
|
const addSubBtn = t.closest('[data-mag-editor-cmd="add-subcategory"]'); |
|
|
|
if (addSubCmd instanceof HTMLElement) { |
|
|
|
if (addSubBtn instanceof HTMLElement) { |
|
|
|
this.addSubcategory(ev, addSubCmd); |
|
|
|
this.addSubcategory(ev, addSubBtn); |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const rmCatCmd = t.closest('[data-mag-editor-cmd="remove-category"]'); |
|
|
|
|
|
|
|
if (rmCatCmd instanceof HTMLElement) { |
|
|
|
|
|
|
|
this.removeCategory(ev, rmCatCmd); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const addArticle = t.closest('[data-mag-a-add]'); |
|
|
|
|
|
|
|
if (addArticle instanceof HTMLElement) { |
|
|
|
|
|
|
|
this.addALine(ev, addArticle); |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
const rmArticle = t.closest('.magazine-editor__a-remove-icon'); |
|
|
|
const rmCatBtn = t.closest('[data-mag-editor-cmd="remove-category"]'); |
|
|
|
if (rmArticle instanceof HTMLElement) { |
|
|
|
if (rmCatBtn instanceof HTMLElement) { |
|
|
|
this.removeALine(ev, rmArticle); |
|
|
|
this.removeCategory(ev, rmCatBtn); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
const sub = t.closest('.magazine-editor__add-sub'); |
|
|
|
const addArticleBtn = t.closest('[data-mag-a-add]'); |
|
|
|
if (sub instanceof HTMLElement) { |
|
|
|
if (addArticleBtn instanceof HTMLElement) { |
|
|
|
this.addSubcategory(ev, sub); |
|
|
|
this.addALine(ev, addArticleBtn); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
const rmCat = t.closest('.magazine-editor__remove-node'); |
|
|
|
const rmArticleBtn = t.closest('.magazine-editor__a-remove-icon'); |
|
|
|
if (rmCat instanceof HTMLElement) { |
|
|
|
if (rmArticleBtn instanceof HTMLElement) { |
|
|
|
this.removeCategory(ev, rmCat); |
|
|
|
this.removeALine(ev, rmArticleBtn); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|