UNPKG

@exadel/esl

Version:

Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components

194 lines (193 loc) 7.26 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var ESLFootnotes_1; import { ExportNs } from '../../esl-utils/environment/export-ns'; import { bind, memoize, attr, listen, prop } from '../../esl-utils/decorators'; import { debounce } from '../../esl-utils/async/debounce'; import { ESLBaseElement } from '../../esl-base-element/core'; import { ESLEventUtils } from '../../esl-utils/dom/events'; import { ENTER, SPACE } from '../../esl-utils/dom/keys'; import { sequentialUID } from '../../esl-utils/misc/uid'; import { compileFootnotesGroupedList, compileFootnotesNongroupedList, sortFootnotes } from './esl-footnotes-data'; let ESLFootnotes = ESLFootnotes_1 = class ESLFootnotes extends ESLBaseElement { constructor() { super(...arguments); this._notes = []; this.deferredOnUpdate = debounce(() => this._onUpdate(), 150); } /** Scope element */ get scopeEl() { return this.$$find(this.scopeTarget); } /** Notes that are allowed to be processed by footnotes */ get notes() { return this._notes.filter((note) => note.allowFootnotes); } /** List of notes to show */ get footnotesList() { this.reindex(); return this.grouping !== 'enable' ? compileFootnotesNongroupedList(this._notes) : compileFootnotesGroupedList(this._notes); } connectedCallback() { super.connectedCallback(); if (!this.id) { this.id = sequentialUID(this.baseTagName, this.baseTagName + '-'); } this._notifyNotes(); } disconnectedCallback() { super.disconnectedCallback(); this._notes.forEach((el) => el.unlink()); this._notes = []; } /** Adds the note to the footnotes list */ linkNote(note) { if (this._notes.includes(note)) return; this._notes.push(note); const index = +sequentialUID(ESLFootnotes_1.is, ''); note.link(this, index); } /** Reindexes the list of notes */ reindex() { this._sortNotes(); this.notes.forEach((note, index) => note.index = index + 1); } /** Removes the note from the footnotes list */ unlinkNote(note) { this._notes = this._notes.filter((el) => el !== note); this.deferredOnUpdate(); } /** Updates the content of footnotes */ update() { this.deferredOnUpdate(); } /** Sorts list of notes */ _sortNotes() { this._notes = sortFootnotes(this._notes); } /** Builds content of footnotes */ buildItems() { const items = this.footnotesList.map((footnote) => this.buildItem(footnote)).join(''); return `<ul class="esl-footnotes-items">${items}</ul>`; } /** Builds one item from footnotes list */ buildItem(footnote) { const item = `${this.buildItemIndex(footnote)}${this.buildItemText(footnote)}${this.buildItemBack(footnote)}`; return `<li class="esl-footnotes-item" data-order="${footnote.index}">${item}</li>`; } /** Builds item index */ buildItemIndex(footnote) { return `<span class="esl-footnotes-index">${footnote.renderedIndex.map(this.buildWrappedItemIndex).join(', ')}</span>`; } /** Builds item index wrapped with span related to esl-note by id */ buildWrappedItemIndex(index) { return `<span id="${this.id}-${index}">${index}</span>`; } /** Builds item text */ buildItemText(footnote) { return `<span class="esl-footnotes-text">${footnote.text}</span>`; } /** Builds item back-to-note button */ buildItemBack(footnote) { return `<span class="esl-footnotes-back-to-note" tabindex="0" title="${this.backToNoteLabel}"></span>`; } /** Actions on update footnotes */ _onUpdate() { this.innerHTML = this.buildItems(); } /** Handles `response` event from note */ _onNoteSubscribe(e) { const note = e.target; this.linkNote(note); this.deferredOnUpdate(); e.stopImmediatePropagation(); } /** Handles `click` event */ _onItemClick(e) { var _a; const target = e.target; const orderAttr = (_a = target.closest('.esl-footnotes-item')) === null || _a === void 0 ? void 0 : _a.getAttribute('data-order'); const order = orderAttr === null || orderAttr === void 0 ? void 0 : orderAttr.split(',').map((item) => +item); order && this._onBackToNote(order); e.preventDefault(); e.stopPropagation(); } /** Handles `keydown` event */ _onKeydown(event) { if ([ENTER, SPACE].includes(event.key)) this._onItemClick(event); } /** Actions on back-to-note click */ _onBackToNote(order) { const index = order[order.length - 1]; this.notes.forEach((note) => { note.highlight(order.includes(note.index)); if (note.index === index) { note.activate(); } }); } /** Turns off highlight for notes with the same text */ turnOffHighlight(note) { this._notes .filter((item) => note.html === item.html) .forEach((item) => item.highlight(false)); } /** * Sends a request to all notes, expecting to get a response from * the unlinked ones and link up with them */ _notifyNotes() { ESLEventUtils.dispatch(this, this.FOOTNOTE_REQUEST_EVENT); } }; ESLFootnotes.is = 'esl-footnotes'; __decorate([ prop('esl:footnotes:request') ], ESLFootnotes.prototype, "FOOTNOTE_REQUEST_EVENT", void 0); __decorate([ prop('esl:footnotes:response') ], ESLFootnotes.prototype, "FOOTNOTE_RESPONSE_EVENT", void 0); __decorate([ attr({ defaultValue: '::parent' }) ], ESLFootnotes.prototype, "scopeTarget", void 0); __decorate([ attr({ defaultValue: 'enable' }) ], ESLFootnotes.prototype, "grouping", void 0); __decorate([ attr({ defaultValue: 'Back to note' }) ], ESLFootnotes.prototype, "backToNoteLabel", void 0); __decorate([ memoize() ], ESLFootnotes.prototype, "scopeEl", null); __decorate([ bind ], ESLFootnotes.prototype, "buildWrappedItemIndex", null); __decorate([ bind ], ESLFootnotes.prototype, "_onUpdate", null); __decorate([ listen({ event: (el) => el.FOOTNOTE_RESPONSE_EVENT, target: (el) => el.scopeEl }) ], ESLFootnotes.prototype, "_onNoteSubscribe", null); __decorate([ listen({ event: 'click', selector: '.esl-footnotes-back-to-note' }) ], ESLFootnotes.prototype, "_onItemClick", null); __decorate([ listen('keydown') ], ESLFootnotes.prototype, "_onKeydown", null); ESLFootnotes = ESLFootnotes_1 = __decorate([ ExportNs('Footnotes') ], ESLFootnotes); export { ESLFootnotes };