@aquera/nile-elements 0.1.67-beta-1.4 → 0.1.67-beta-1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/index.html +13 -6
- package/dist/index.js +143 -247
- package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.css.esm.js +68 -172
- package/dist/nile-rich-text-editor/nile-rich-text-editor.esm.js +1 -1
- package/dist/nile-rich-text-editor/nile-rte-select.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rte-select.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rte-select.esm.js +39 -39
- package/dist/nile-rich-text-editor/utils.cjs.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js +68 -172
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.d.ts +0 -3
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js +35 -125
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rte-select.js +62 -57
- package/dist/src/nile-rich-text-editor/nile-rte-select.js.map +1 -1
- package/dist/src/nile-rich-text-editor/rte-utils/content.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/content.js +25 -0
- package/dist/src/nile-rich-text-editor/rte-utils/content.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/css.d.ts +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/css.js +9 -0
- package/dist/src/nile-rich-text-editor/rte-utils/css.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/dom.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/dom.js +48 -0
- package/dist/src/nile-rich-text-editor/rte-utils/dom.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/formatting.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/formatting.js +69 -0
- package/dist/src/nile-rich-text-editor/rte-utils/formatting.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/keys.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/keys.js +38 -0
- package/dist/src/nile-rich-text-editor/rte-utils/keys.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/lists.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/lists.js +28 -0
- package/dist/src/nile-rich-text-editor/rte-utils/lists.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/selection.d.ts +17 -0
- package/dist/src/nile-rich-text-editor/rte-utils/selection.js +39 -0
- package/dist/src/nile-rich-text-editor/rte-utils/selection.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbar.d.ts +28 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbar.js +161 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbar.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbarState.d.ts +13 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbarState.js +119 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbarState.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/vars.d.ts +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/vars.js +14 -0
- package/dist/src/nile-rich-text-editor/rte-utils/vars.js.map +1 -0
- package/dist/src/nile-rich-text-editor/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/nile-rich-text-editor/nile-rich-text-editor.css.ts +68 -172
- package/src/nile-rich-text-editor/nile-rich-text-editor.ts +74 -160
- package/src/nile-rich-text-editor/nile-rte-select.ts +178 -173
- package/src/nile-rich-text-editor/utils.ts +342 -341
- package/vscode-html-custom-data.json +1 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"nile-rte-select.js","sourceRoot":"","sources":["../../../src/nile-rich-text-editor/nile-rte-select.ts"],"names":[],"mappings":"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","sourcesContent":[" // nile-rte-select.ts\n import { LitElement, html } from 'lit';\n import { customElement, property, state } from 'lit/decorators.js';\n\n type HeadingTag = 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n type GenericOption = { value: string; label?: string; icon?: string };\n type HeadingOption = { value: HeadingTag; label?: string; icon?: string };\n type NormalizedOption = { value: string; label: string; icon?: string };\n\n const HEADING_ALLOWLIST: ReadonlySet<HeadingTag> = new Set([\n 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'\n ]);\n\n function isHeadingTag(v: string): v is HeadingTag {\n return HEADING_ALLOWLIST.has(v as HeadingTag);\n }\n\n @customElement('nile-rte-select')\n export class NileRteSelect extends LitElement {\n protected createRenderRoot() { return this; }\n\n /** 'heading' | 'font' | 'align' */\n @property({ type: String }) type = '';\n\n /** JSON: [{ value, label?, icon? }, ...] (attribute-based; runtime-validated) */\n @property({ type: String }) options = '[]';\n\n /** Programmatic options (preferred for TS safety). */\n @property({ attribute: false })\n optionsObj?: Array<GenericOption | HeadingOption>;\n\n /** Fallback label for trigger (e.g., \"Align\") */\n @property({ type: String }) label = '';\n\n @state() private selectedValue = '';\n\n private mapAlignIcon(v: string) {\n const map: Record<string,string> = {\n left: 'format_align_left',\n center: 'format_align_middle',\n right: 'format_align_right',\n justify: 'format_align_justify'\n };\n return map[v] || 'align-left';\n }\n\n private get parsedOptions(): NormalizedOption[] {\n // Prefer programmatic options if present (gives TS compile-time checks)\n const source: unknown = this.optionsObj ?? this.options;\n\n const rawArray: any[] = (() => {\n if (Array.isArray(source)) return source;\n try { return JSON.parse(String(source)); } catch { return []; }\n })();\n\n // Normalize to consistent shape\n let items: NormalizedOption[] = rawArray.map((o: any) => {\n const value: string = o?.value ?? o;\n const label: string = o?.label ?? o?.value ?? o;\n const icon: string | undefined =\n o?.icon ?? (this.type === 'align' ? this.mapAlignIcon(String(value)) : undefined);\n return { value, label, icon };\n });\n\n // If type is heading, enforce allowlist (runtime validation)\n if (this.type === 'heading') {\n const before = items.length;\n items = items.filter(i => isHeadingTag(i.value));\n if (items.length !== before) {\n }\n // If current selection is invalid for heading, reset\n if (this.selectedValue && !isHeadingTag(this.selectedValue)) {\n this.selectedValue = '';\n }\n }\n\n return items;\n }\n\n private ensureDefault() {\n if (!this.selectedValue) {\n const first = this.parsedOptions[0];\n if (first) this.selectedValue = first.value;\n }\n }\n\n private onSelect(value: string) {\n if (this.type === 'heading' && !isHeadingTag(value)) {\n console.warn(`[nile-rte-select] Ignoring invalid heading value: ${value}`);\n return;\n }\n this.selectedValue = value;\n this.dispatchEvent(new CustomEvent('change', {\n detail: value, bubbles: true, composed: true\n }));\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.injectLocalStyles();\n }\n\n private injectLocalStyles() {\n if (this.querySelector('style[data-rte-select-style]')) return;\n\n const style = document.createElement('style');\n style.setAttribute('data-rte-select-style', 'true');\n style.textContent = `\n nile-menu.rte-align-menu::part(menu__items-wrapper) {\n display: flex;\n }\n nile-menu.rte-align-menu,\n nile-menu.rte-default-menu {\n margin-top: 0px;\n }\n nile-button.rte-align-trigger::part(base),\n nile-button.rte-default-trigger::part(base) {\n min-width: 32px;\n height: 32px;\n padding: 0px 6px;\n box-shadow: none;\n }\n `;\n this.insertBefore(style, this.firstChild);\n }\n\n render() {\n const opts = this.parsedOptions;\n this.ensureDefault();\n const current = opts.find(o => o.value === this.selectedValue);\n\n // ► Align: icon-only items + icon trigger\n if (this.type === 'align') {\n const trigger = current?.icon\n ? html`<nile-icon name=\"${current.icon}\"></nile-icon>`\n : (this.label || 'Align');\n\n return html`\n <nile-dropdown class=\"rte-align-dd\">\n <nile-button slot=\"trigger\" variant=\"tertiary\" class=\"rte-align-trigger\">\n ${trigger}\n </nile-button>\n <nile-menu class=\"rte-align-menu\">\n ${opts.map(o => html`\n <nile-menu-item\n class=\"rte-align-item\"\n ?active=${o.value === this.selectedValue}\n @click=${() => this.onSelect(o.value)}>\n <nile-icon name=\"${o.icon}\"></nile-icon>\n </nile-menu-item>\n `)}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n\n // ► Font: show labels, preview fonts in items and trigger\n if (this.type === 'font') {\n const triggerText = current?.label || this.label || 'Font';\n return html`\n <nile-dropdown class=\"rte-default-dd\">\n <nile-button\n slot=\"trigger\"\n variant=\"tertiary\"\n class=\"rte-default-trigger\"\n style=\"font-family: ${current?.value || 'inherit'}\">\n ${triggerText} <nile-icon name=\"arrowdown\"></nile-icon>\n </nile-button>\n <nile-menu class=\"rte-default-menu\">\n ${opts.map(o => html`\n <nile-menu-item\n style=\"font-family: ${o.value}\"\n ?active=${o.value === this.selectedValue}\n @click=${() => this.onSelect(o.value)}>\n ${o.label}\n </nile-menu-item>\n `)}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n\n // ► Default (e.g., heading): text items; heading values are validated already\n const triggerText = current?.label || this.label || 'Select';\n return html`\n <nile-dropdown class=\"rte-default-dd\">\n <nile-button slot=\"trigger\" variant=\"tertiary\" class=\"rte-default-trigger\">\n ${triggerText} <nile-icon name=\"arrowdown\"></nile-icon>\n </nile-button>\n <nile-menu class=\"rte-default-menu\">\n ${opts.map(o => html`\n <nile-menu-item\n ?active=${o.value === this.selectedValue}\n @click=${() => this.onSelect(o.value)}>\n ${o.label}\n </nile-menu-item>\n `)}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n }\n\n declare global {\n interface HTMLElementTagNameMap {\n 'nile-rte-select': NileRteSelect;\n }\n }\n"]}
|
1
|
+
{"version":3,"file":"nile-rte-select.js","sourceRoot":"","sources":["../../../src/nile-rich-text-editor/nile-rte-select.ts"],"names":[],"mappings":"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","sourcesContent":["// nile-rte-select.ts\nimport { LitElement, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\ntype HeadingTag = 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\ntype GenericOption = { value: string; label?: string; icon?: string };\ntype HeadingOption = { value: HeadingTag; label?: string; icon?: string };\ntype NormalizedOption = { value: string; label: string; icon?: string };\n\nconst HEADING_ALLOWLIST: ReadonlySet<HeadingTag> = new Set([\n 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'\n]);\n\nfunction isHeadingTag(v: string): v is HeadingTag {\n return HEADING_ALLOWLIST.has(v as HeadingTag);\n}\n\n@customElement('nile-rte-select')\nexport class NileRteSelect extends LitElement {\n protected createRenderRoot() { return this; }\n\n /** 'heading' | 'font' | 'align' */\n @property({ type: String }) type = '';\n\n /** JSON: [{ value, label?, icon? }, ...] (attribute-based; runtime-validated) */\n @property({ type: String }) options = '[]';\n\n /** Programmatic options (preferred for TS safety). */\n @property({ attribute: false })\n optionsObj?: Array<GenericOption | HeadingOption>;\n\n /** Fallback label for trigger (e.g., \"Align\") */\n @property({ type: String }) label = '';\n\n @state() private selectedValue = '';\n\n private mapAlignIcon(v: string) {\n const map: Record<string,string> = {\n left: 'format_align_left',\n center: 'format_align_middle',\n right: 'format_align_right',\n justify: 'format_align_justify'\n };\n return map[v] || 'format_align_left';\n }\n\n private get parsedOptions(): NormalizedOption[] {\n // Prefer programmatic options if present (gives TS compile-time checks)\n const source: unknown = this.optionsObj ?? this.options;\n\n const rawArray: any[] = (() => {\n if (Array.isArray(source)) return source;\n try { return JSON.parse(String(source)); } catch { return []; }\n })();\n\n // Normalize to consistent shape\n let items: NormalizedOption[] = rawArray.map((o: any) => {\n const value: string = o?.value ?? o;\n const label: string = o?.label ?? o?.value ?? o;\n const icon: string | undefined =\n o?.icon ?? (this.type === 'align' ? this.mapAlignIcon(String(value)) : undefined);\n return { value, label, icon };\n });\n\n // If type is heading, enforce allowlist (runtime validation)\n if (this.type === 'heading') {\n const before = items.length;\n items = items.filter(i => isHeadingTag(i.value));\n if (items.length !== before) {\n }\n // If current selection is invalid for heading, reset\n if (this.selectedValue && !isHeadingTag(this.selectedValue)) {\n this.selectedValue = '';\n }\n }\n\n return items;\n }\n\n private ensureDefault() {\n if (!this.selectedValue) {\n const first = this.parsedOptions[0];\n if (first) this.selectedValue = first.value;\n }\n }\n\n private onSelect(value: string) {\n if (this.type === 'heading' && !isHeadingTag(value)) {\n console.warn(`[nile-rte-select] Ignoring invalid heading value: ${value}`);\n return;\n }\n this.selectedValue = value;\n this.dispatchEvent(new CustomEvent('change', {\n detail: value, bubbles: true, composed: true\n }));\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.injectLocalStyles();\n }\n\n private injectLocalStyles() {\n if (this.querySelector('style[data-rte-select-style]')) return;\n\n const style = document.createElement('style');\n style.setAttribute('data-rte-select-style', 'true');\n style.textContent = `\n nile-menu.rte-align-menu::part(menu__items-wrapper) {\n display: flex;\n }\n nile-menu.rte-align-menu,\n nile-menu.rte-default-menu {\n margin-top: 0px;\n }\n nile-button.rte-align-trigger::part(base),\n nile-button.rte-default-trigger::part(base) {\n min-width: 32px;\n height: 32px;\n padding: 0px 6px;\n box-shadow: none;\n }\n nile-button.rte-align-trigger::part(base) {\n \n\n border: none;\n}\n `;\n this.insertBefore(style, this.firstChild);\n }\n\n render() {\n const opts = this.parsedOptions;\n this.ensureDefault();\n const current = opts.find(o => o.value === this.selectedValue);\n\n // ► Align: icon-only items + icon trigger\n if (this.type === 'align') {\n const trigger = current?.icon\n ? html`<nile-icon name=\"${current.icon}\"></nile-icon>`\n : (this.label || 'Align');\n\n return html`\n <nile-dropdown class=\"rte-align-dd\">\n <nile-button slot=\"trigger\" variant=\"tertiary\" class=\"rte-align-trigger\">\n ${trigger}\n </nile-button>\n <nile-menu class=\"rte-align-menu\">\n ${opts.map(o => html`\n <nile-menu-item\n class=\"rte-align-item\"\n ?active=${o.value === this.selectedValue}\n @click=${() => this.onSelect(o.value)}>\n <nile-icon name=\"${o.icon}\"></nile-icon>\n </nile-menu-item>\n `)}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n\n // ► Font: show labels, preview fonts in items and trigger\n if (this.type === 'font') {\n const triggerText = current?.label || this.label || 'Font';\n return html`\n <nile-dropdown class=\"rte-default-dd\">\n <nile-button\n slot=\"trigger\"\n variant=\"tertiary\"\n class=\"rte-default-trigger\"\n style=\"font-family: ${current?.value || 'inherit'}\">\n ${triggerText} <nile-icon name=\"arrowdown\"></nile-icon>\n </nile-button>\n <nile-menu class=\"rte-default-menu\">\n ${opts.map(o => html`\n <nile-menu-item\n style=\"font-family: ${o.value}\"\n ?active=${o.value === this.selectedValue}\n @click=${() => this.onSelect(o.value)}>\n ${o.label}\n </nile-menu-item>\n `)}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n\n // ► Default (e.g., heading): text items; heading values are validated already\n const triggerText = current?.label || this.label || 'Select';\n return html`\n <nile-dropdown class=\"rte-default-dd\">\n <nile-button slot=\"trigger\" variant=\"tertiary\" class=\"rte-default-trigger\">\n ${triggerText} <nile-icon name=\"arrowdown\"></nile-icon>\n </nile-button>\n <nile-menu class=\"rte-default-menu\">\n ${opts.map(o => html`\n <nile-menu-item\n ?active=${o.value === this.selectedValue}\n @click=${() => this.onSelect(o.value)}>\n ${o.label}\n </nile-menu-item>\n `)}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-rte-select': NileRteSelect;\n }\n}\n"]}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export function inlineComputedStyles(sourceEl) {
|
2
|
+
const clone = sourceEl.cloneNode(true);
|
3
|
+
const origWalker = document.createTreeWalker(sourceEl, NodeFilter.SHOW_ELEMENT);
|
4
|
+
const cloneWalker = document.createTreeWalker(clone, NodeFilter.SHOW_ELEMENT);
|
5
|
+
while (origWalker.nextNode() && cloneWalker.nextNode()) {
|
6
|
+
const origEl = origWalker.currentNode;
|
7
|
+
const cloneEl = cloneWalker.currentNode;
|
8
|
+
const computed = window.getComputedStyle(origEl);
|
9
|
+
const cssText = Array.from(computed).map(prop => `${prop}:${computed.getPropertyValue(prop)}`).join(';');
|
10
|
+
cloneEl.setAttribute('style', cssText);
|
11
|
+
}
|
12
|
+
return clone.innerHTML;
|
13
|
+
}
|
14
|
+
export function updateContentAndEmit(host, editorEl, previewEl) {
|
15
|
+
const content = inlineComputedStyles(editorEl);
|
16
|
+
if (previewEl)
|
17
|
+
previewEl.innerHTML = content;
|
18
|
+
host.dispatchEvent(new CustomEvent('content-changed', {
|
19
|
+
detail: { content },
|
20
|
+
bubbles: true,
|
21
|
+
composed: true,
|
22
|
+
}));
|
23
|
+
return content;
|
24
|
+
}
|
25
|
+
//# sourceMappingURL=content.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/content.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAAC,QAAqB;IACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAgB,CAAC;IAEtD,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAChF,MAAM,WAAW,GAAG,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAE9E,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,UAAU,CAAC,WAA0B,CAAC;QACrD,MAAM,OAAO,GAAG,WAAW,CAAC,WAA0B,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzG,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,KAAK,CAAC,SAAS,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAiB,EAAE,QAAqB,EAAE,SAA6B;IAC1G,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,SAAS;QAAE,SAAS,CAAC,SAAS,GAAG,OAAO,CAAC;IAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,iBAAiB,EAAE;QACpD,MAAM,EAAE,EAAE,OAAO,EAAE;QACnB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,CAAC;IACJ,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["export function inlineComputedStyles(sourceEl: HTMLElement): string {\n const clone = sourceEl.cloneNode(true) as HTMLElement;\n \n const origWalker = document.createTreeWalker(sourceEl, NodeFilter.SHOW_ELEMENT);\n const cloneWalker = document.createTreeWalker(clone, NodeFilter.SHOW_ELEMENT);\n \n while (origWalker.nextNode() && cloneWalker.nextNode()) {\n const origEl = origWalker.currentNode as HTMLElement;\n const cloneEl = cloneWalker.currentNode as HTMLElement;\n const computed = window.getComputedStyle(origEl);\n const cssText = Array.from(computed).map(prop => `${prop}:${computed.getPropertyValue(prop)}`).join(';');\n cloneEl.setAttribute('style', cssText);\n }\n \n return clone.innerHTML;\n }\n \n export function updateContentAndEmit(host: HTMLElement, editorEl: HTMLElement, previewEl: HTMLElement | null): string {\n const content = inlineComputedStyles(editorEl);\n if (previewEl) previewEl.innerHTML = content;\n host.dispatchEvent(new CustomEvent('content-changed', {\n detail: { content },\n bubbles: true,\n composed: true,\n }));\n return content;\n }\n "]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function injectCss(host: HTMLElement, cssText: string): void;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
export function injectCss(host, cssText) {
|
2
|
+
if (host.querySelector('style[data-rte-style]'))
|
3
|
+
return;
|
4
|
+
const style = document.createElement('style');
|
5
|
+
style.setAttribute('data-rte-style', 'true');
|
6
|
+
style.textContent = cssText;
|
7
|
+
host.insertBefore(style, host.firstChild);
|
8
|
+
}
|
9
|
+
//# sourceMappingURL=css.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/css.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAiB,EAAE,OAAe;IACxD,IAAI,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC;QAAE,OAAO;IACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC7C,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;IAC5B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["export function injectCss(host: HTMLElement, cssText: string) {\n if (host.querySelector('style[data-rte-style]')) return;\n const style = document.createElement('style');\n style.setAttribute('data-rte-style', 'true');\n style.textContent = cssText;\n host.insertBefore(style, host.firstChild);\n }"]}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
export function ensureEditor(host, toolbarEl, previewEl) {
|
2
|
+
let editorEl = host.querySelector('.editor');
|
3
|
+
if (!editorEl) {
|
4
|
+
const editor = document.createElement('article');
|
5
|
+
editor.className = 'editor';
|
6
|
+
editor.setAttribute('contenteditable', 'true');
|
7
|
+
if (toolbarEl?.nextSibling) {
|
8
|
+
host.insertBefore(editor, toolbarEl.nextSibling);
|
9
|
+
}
|
10
|
+
else if (previewEl) {
|
11
|
+
host.insertBefore(editor, previewEl);
|
12
|
+
}
|
13
|
+
else {
|
14
|
+
host.appendChild(editor);
|
15
|
+
}
|
16
|
+
editorEl = editor;
|
17
|
+
}
|
18
|
+
if (!editorEl.innerHTML.trim())
|
19
|
+
editorEl.innerHTML = '<p><br></p>';
|
20
|
+
ensureAtLeastOneParagraph(editorEl);
|
21
|
+
return editorEl;
|
22
|
+
}
|
23
|
+
export function ensureAtLeastOneParagraph(el) {
|
24
|
+
if (!el)
|
25
|
+
return;
|
26
|
+
const onlyWhitespace = (el.textContent ?? '').replace(/\u200B/g, '').trim() === '';
|
27
|
+
if (el.childNodes.length === 0 || onlyWhitespace) {
|
28
|
+
el.innerHTML = '<p><br></p>';
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
const hasBlock = el.querySelector('p,h1,h2,h3,h4,h5,h6,ul,ol,table,blockquote,pre');
|
32
|
+
if (!hasBlock) {
|
33
|
+
const p = document.createElement('p');
|
34
|
+
while (el.firstChild)
|
35
|
+
p.appendChild(el.firstChild);
|
36
|
+
if (!p.hasChildNodes())
|
37
|
+
p.appendChild(document.createElement('br'));
|
38
|
+
el.appendChild(p);
|
39
|
+
return;
|
40
|
+
}
|
41
|
+
el.querySelectorAll('p').forEach(p => {
|
42
|
+
if ((p.textContent ?? '').replace(/\u200B/g, '') === '') {
|
43
|
+
if (!p.innerHTML.toLowerCase().includes('<br'))
|
44
|
+
p.innerHTML = '<br>';
|
45
|
+
}
|
46
|
+
});
|
47
|
+
}
|
48
|
+
//# sourceMappingURL=dom.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/dom.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,IAAiB,EAAE,SAA8B,EAAE,SAA8B;IAC1G,IAAI,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAuB,CAAC;IACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC5B,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE,WAAW,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,QAAQ,GAAG,MAAM,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,CAAC;IACnE,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EAAe;IACvD,IAAI,CAAC,EAAE;QAAE,OAAO;IAEhB,MAAM,cAAc,GAAG,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IACnF,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,EAAE,CAAC;QACjD,EAAE,CAAC,SAAS,GAAG,aAAa,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC,aAAa,CAAC,gDAAgD,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,EAAE,CAAC,UAAU;YAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE;YAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;QACpE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClB,OAAO;IACT,CAAC;IAED,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACnC,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;YACxD,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC;QACvE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["export function ensureEditor(host: HTMLElement, toolbarEl?: HTMLElement | null, previewEl?: HTMLElement | null) {\n let editorEl = host.querySelector('.editor') as HTMLElement | null;\n if (!editorEl) {\n const editor = document.createElement('article');\n editor.className = 'editor';\n editor.setAttribute('contenteditable', 'true');\n if (toolbarEl?.nextSibling) {\n host.insertBefore(editor, toolbarEl.nextSibling);\n } else if (previewEl) {\n host.insertBefore(editor, previewEl);\n } else {\n host.appendChild(editor);\n }\n editorEl = editor;\n }\n if (!editorEl.innerHTML.trim()) editorEl.innerHTML = '<p><br></p>';\n ensureAtLeastOneParagraph(editorEl);\n return editorEl;\n }\n \n export function ensureAtLeastOneParagraph(el: HTMLElement) {\n if (!el) return;\n \n const onlyWhitespace = (el.textContent ?? '').replace(/\\u200B/g, '').trim() === '';\n if (el.childNodes.length === 0 || onlyWhitespace) {\n el.innerHTML = '<p><br></p>';\n return;\n }\n \n const hasBlock = el.querySelector('p,h1,h2,h3,h4,h5,h6,ul,ol,table,blockquote,pre');\n if (!hasBlock) {\n const p = document.createElement('p');\n while (el.firstChild) p.appendChild(el.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n el.appendChild(p);\n return;\n }\n \n el.querySelectorAll('p').forEach(p => {\n if ((p.textContent ?? '').replace(/\\u200B/g, '') === '') {\n if (!p.innerHTML.toLowerCase().includes('<br')) p.innerHTML = '<br>';\n }\n });\n }\n "]}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
const FORMATTING_TAGS = new Set(['B', 'STRONG', 'I', 'EM', 'U', 'SPAN', 'FONT', 'A']);
|
2
|
+
function isFormatting(el) {
|
3
|
+
return FORMATTING_TAGS.has(el.tagName) || el.hasAttribute('style');
|
4
|
+
}
|
5
|
+
function liftOutOfFormatting(editorEl, marker) {
|
6
|
+
let p = marker.parentElement;
|
7
|
+
while (p && p !== editorEl && isFormatting(p)) {
|
8
|
+
const before = p.cloneNode(false);
|
9
|
+
const after = p.cloneNode(false);
|
10
|
+
while (p.firstChild && p.firstChild !== marker)
|
11
|
+
before.appendChild(p.firstChild);
|
12
|
+
while (marker.nextSibling)
|
13
|
+
after.appendChild(marker.nextSibling);
|
14
|
+
if (before.firstChild)
|
15
|
+
p.parentNode.insertBefore(before, p);
|
16
|
+
p.parentNode.insertBefore(marker, p);
|
17
|
+
if (after.firstChild)
|
18
|
+
p.parentNode.insertBefore(after, p);
|
19
|
+
const next = p.parentElement;
|
20
|
+
p.remove();
|
21
|
+
p = next;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
export function clearSelectionFormatting(selection, editorEl) {
|
25
|
+
selection.focusAndRestore();
|
26
|
+
const sel = window.getSelection();
|
27
|
+
if (!sel || sel.rangeCount === 0)
|
28
|
+
return;
|
29
|
+
const range = sel.getRangeAt(0);
|
30
|
+
if (!editorEl.contains(range.commonAncestorContainer))
|
31
|
+
return;
|
32
|
+
if (range.collapsed)
|
33
|
+
return;
|
34
|
+
const frag = range.extractContents();
|
35
|
+
const walker = document.createTreeWalker(frag, NodeFilter.SHOW_ELEMENT);
|
36
|
+
const toUnwrap = [];
|
37
|
+
while (walker.nextNode()) {
|
38
|
+
const el = walker.currentNode;
|
39
|
+
el.removeAttribute('style');
|
40
|
+
if (FORMATTING_TAGS.has(el.tagName))
|
41
|
+
toUnwrap.push(el);
|
42
|
+
}
|
43
|
+
for (const el of toUnwrap) {
|
44
|
+
const parent = el.parentNode;
|
45
|
+
while (el.firstChild)
|
46
|
+
parent.insertBefore(el.firstChild, el);
|
47
|
+
parent.removeChild(el);
|
48
|
+
}
|
49
|
+
const marker = document.createElement('span');
|
50
|
+
marker.setAttribute('data-rte-clear', '1');
|
51
|
+
marker.appendChild(frag);
|
52
|
+
range.insertNode(marker);
|
53
|
+
liftOutOfFormatting(editorEl, marker);
|
54
|
+
const last = marker.lastChild;
|
55
|
+
const parent = marker.parentNode;
|
56
|
+
while (marker.firstChild)
|
57
|
+
parent.insertBefore(marker.firstChild, marker);
|
58
|
+
parent.removeChild(marker);
|
59
|
+
const r = document.createRange();
|
60
|
+
if (last)
|
61
|
+
r.setStartAfter(last);
|
62
|
+
else
|
63
|
+
r.setStart(parent, parent.childNodes?.length ?? 0);
|
64
|
+
r.collapse(true);
|
65
|
+
sel.removeAllRanges();
|
66
|
+
sel.addRange(r);
|
67
|
+
selection.save();
|
68
|
+
}
|
69
|
+
//# sourceMappingURL=formatting.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/formatting.ts"],"names":[],"mappings":"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","sourcesContent":["import { SelectionManager } from './selection';\n\nconst FORMATTING_TAGS = new Set(['B','STRONG','I','EM','U','SPAN','FONT','A']);\n\nfunction isFormatting(el: HTMLElement) {\n return FORMATTING_TAGS.has(el.tagName) || el.hasAttribute('style');\n}\n\nfunction liftOutOfFormatting(editorEl: HTMLElement, marker: HTMLElement) {\n let p: HTMLElement | null = marker.parentElement;\n while (p && p !== editorEl && isFormatting(p)) {\n const before = p.cloneNode(false) as HTMLElement;\n const after = p.cloneNode(false) as HTMLElement;\n\n while (p.firstChild && p.firstChild !== marker) before.appendChild(p.firstChild);\n while (marker.nextSibling) after.appendChild(marker.nextSibling);\n\n if (before.firstChild) p.parentNode!.insertBefore(before, p);\n p.parentNode!.insertBefore(marker, p);\n if (after.firstChild) p.parentNode!.insertBefore(after, p);\n\n const next = p.parentElement;\n p.remove();\n p = next;\n }\n}\n\nexport function clearSelectionFormatting(selection: SelectionManager, editorEl: HTMLElement) {\n selection.focusAndRestore();\n\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n\n const range = sel.getRangeAt(0);\n if (!editorEl.contains(range.commonAncestorContainer)) return;\n if (range.collapsed) return;\n\n const frag = range.extractContents();\n\n const walker = document.createTreeWalker(frag, NodeFilter.SHOW_ELEMENT);\n const toUnwrap: HTMLElement[] = [];\n while (walker.nextNode()) {\n const el = walker.currentNode as HTMLElement;\n el.removeAttribute('style');\n if (FORMATTING_TAGS.has(el.tagName)) toUnwrap.push(el);\n }\n for (const el of toUnwrap) {\n const parent = el.parentNode!;\n while (el.firstChild) parent.insertBefore(el.firstChild, el);\n parent.removeChild(el);\n }\n\n const marker = document.createElement('span');\n marker.setAttribute('data-rte-clear', '1');\n marker.appendChild(frag);\n range.insertNode(marker);\n\n liftOutOfFormatting(editorEl, marker);\n\n const last = marker.lastChild;\n const parent = marker.parentNode!;\n while (marker.firstChild) parent.insertBefore(marker.firstChild, marker);\n parent.removeChild(marker);\n\n const r = document.createRange();\n if (last) r.setStartAfter(last); else r.setStart(parent, (parent as any).childNodes?.length ?? 0);\n r.collapse(true);\n sel.removeAllRanges(); sel.addRange(r);\n\n selection.save();\n}"]}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
export function handleTabKey(e, selection, onContent, onToolbar) {
|
2
|
+
e.preventDefault();
|
3
|
+
selection.focusAndRestore();
|
4
|
+
const sel = window.getSelection();
|
5
|
+
if (!sel || sel.rangeCount === 0)
|
6
|
+
return;
|
7
|
+
const range = sel.getRangeAt(0);
|
8
|
+
if (e.shiftKey) {
|
9
|
+
if (range.collapsed && range.startContainer.nodeType === Node.TEXT_NODE) {
|
10
|
+
const t = range.startContainer;
|
11
|
+
const off = range.startOffset;
|
12
|
+
const before = t.data.slice(0, off);
|
13
|
+
const removed = before.replace(/(\t|[ \u00a0]{2})$/, '');
|
14
|
+
if (removed.length !== before.length) {
|
15
|
+
t.data = removed + t.data.slice(off);
|
16
|
+
const r = document.createRange();
|
17
|
+
r.setStart(t, removed.length);
|
18
|
+
r.collapse(true);
|
19
|
+
sel.removeAllRanges();
|
20
|
+
sel.addRange(r);
|
21
|
+
onContent();
|
22
|
+
onToolbar();
|
23
|
+
}
|
24
|
+
}
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
range.deleteContents();
|
28
|
+
const tabNode = document.createTextNode('\t');
|
29
|
+
range.insertNode(tabNode);
|
30
|
+
const r = document.createRange();
|
31
|
+
r.setStartAfter(tabNode);
|
32
|
+
r.collapse(true);
|
33
|
+
sel.removeAllRanges();
|
34
|
+
sel.addRange(r);
|
35
|
+
onContent();
|
36
|
+
onToolbar();
|
37
|
+
}
|
38
|
+
//# sourceMappingURL=keys.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/keys.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAC1B,CAAgB,EAChB,SAA2B,EAC3B,SAAqB,EACrB,SAAqB;IAErB,CAAC,CAAC,cAAc,EAAE,CAAC;IACnB,SAAS,CAAC,eAAe,EAAE,CAAC;IAE5B,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC;QAAE,OAAO;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAEhC,IAAK,CAAS,CAAC,QAAQ,EAAE,CAAC;QACxB,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACxE,MAAM,CAAC,GAAG,KAAK,CAAC,cAAsB,CAAC;YACvC,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC;YAC9B,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;YACzD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;gBACrC,CAAC,CAAC,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACjC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC9B,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,EAAE,CAAC;gBAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACvC,SAAS,EAAE,CAAC;gBAAC,SAAS,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED,KAAK,CAAC,cAAc,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9C,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE1B,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACjC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,GAAG,CAAC,eAAe,EAAE,CAAC;IAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEvC,SAAS,EAAE,CAAC;IAAC,SAAS,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["import { SelectionManager } from './selection';\n\nexport function handleTabKey(\n e: KeyboardEvent,\n selection: SelectionManager,\n onContent: () => void,\n onToolbar: () => void,\n) {\n e.preventDefault();\n selection.focusAndRestore();\n\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n\n if ((e as any).shiftKey) {\n if (range.collapsed && range.startContainer.nodeType === Node.TEXT_NODE) {\n const t = range.startContainer as Text;\n const off = range.startOffset;\n const before = t.data.slice(0, off);\n const removed = before.replace(/(\\t|[ \\u00a0]{2})$/, '');\n if (removed.length !== before.length) {\n t.data = removed + t.data.slice(off);\n const r = document.createRange();\n r.setStart(t, removed.length);\n r.collapse(true);\n sel.removeAllRanges(); sel.addRange(r);\n onContent(); onToolbar();\n }\n }\n return;\n }\n\n range.deleteContents();\n const tabNode = document.createTextNode('\\t');\n range.insertNode(tabNode);\n\n const r = document.createRange();\n r.setStartAfter(tabNode);\n r.collapse(true);\n sel.removeAllRanges(); sel.addRange(r);\n\n onContent(); onToolbar();\n}\n"]}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
export function insertList(type, selection) {
|
2
|
+
selection.restore();
|
3
|
+
if (!selection.lastRange)
|
4
|
+
return;
|
5
|
+
const list = document.createElement(type);
|
6
|
+
const frag = selection.lastRange.extractContents();
|
7
|
+
const temp = document.createElement('div');
|
8
|
+
temp.appendChild(frag);
|
9
|
+
Array.from(temp.childNodes).forEach(n => {
|
10
|
+
if (n.nodeType === Node.TEXT_NODE && !(n.textContent ?? '').trim())
|
11
|
+
return;
|
12
|
+
const li = document.createElement('li');
|
13
|
+
li.appendChild(n); // moves node
|
14
|
+
list.appendChild(li);
|
15
|
+
});
|
16
|
+
selection.lastRange.insertNode(list);
|
17
|
+
afterListEdit(selection, list);
|
18
|
+
}
|
19
|
+
function afterListEdit(selection, node) {
|
20
|
+
const range = document.createRange();
|
21
|
+
range.setStartAfter(node);
|
22
|
+
range.collapse(true);
|
23
|
+
const sel = window.getSelection();
|
24
|
+
sel?.removeAllRanges();
|
25
|
+
sel?.addRange(range);
|
26
|
+
selection.save();
|
27
|
+
}
|
28
|
+
//# sourceMappingURL=lists.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/lists.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,IAAiB,EAAE,SAA2B;IACvE,SAAS,CAAC,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC,SAAS,CAAC,SAAS;QAAE,OAAO;IAEjC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;IACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACtC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YAAE,OAAO;QAC3E,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACxC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa;QAChC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACrC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,aAAa,CAAC,SAA2B,EAAE,IAAU;IAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrB,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IAClC,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrB,SAAS,CAAC,IAAI,EAAE,CAAC;AACnB,CAAC","sourcesContent":["import { SelectionManager } from './selection';\n\nexport function insertList(type: 'ul' | 'ol', selection: SelectionManager) {\n selection.restore();\n if (!selection.lastRange) return;\n\n const list = document.createElement(type);\n const frag = selection.lastRange.extractContents();\n const temp = document.createElement('div');\n temp.appendChild(frag);\n\n Array.from(temp.childNodes).forEach(n => {\n if (n.nodeType === Node.TEXT_NODE && !(n.textContent ?? '').trim()) return;\n const li = document.createElement('li');\n li.appendChild(n); // moves node\n list.appendChild(li);\n });\n\n selection.lastRange.insertNode(list);\n afterListEdit(selection, list);\n}\n\nfunction afterListEdit(selection: SelectionManager, node: Node) {\n const range = document.createRange();\n range.setStartAfter(node);\n range.collapse(true);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n selection.save();\n}"]}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export declare class SelectionManager {
|
2
|
+
private host;
|
3
|
+
private onChange;
|
4
|
+
editorEl: HTMLElement;
|
5
|
+
lastRange: Range | null;
|
6
|
+
private handler;
|
7
|
+
constructor(args: {
|
8
|
+
host: HTMLElement;
|
9
|
+
editorEl: HTMLElement;
|
10
|
+
onChange: () => void;
|
11
|
+
});
|
12
|
+
start(): void;
|
13
|
+
stop(): void;
|
14
|
+
save(): void;
|
15
|
+
restore(): void;
|
16
|
+
focusAndRestore(): void;
|
17
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
export class SelectionManager {
|
2
|
+
constructor(args) {
|
3
|
+
this.lastRange = null;
|
4
|
+
this.host = args.host;
|
5
|
+
this.editorEl = args.editorEl;
|
6
|
+
this.onChange = args.onChange;
|
7
|
+
}
|
8
|
+
start() {
|
9
|
+
this.handler = () => {
|
10
|
+
const sel = document.getSelection();
|
11
|
+
if (!sel || sel.rangeCount === 0)
|
12
|
+
return;
|
13
|
+
const range = sel.getRangeAt(0);
|
14
|
+
if (this.editorEl.contains(range.commonAncestorContainer)) {
|
15
|
+
this.lastRange = range.cloneRange();
|
16
|
+
this.onChange();
|
17
|
+
}
|
18
|
+
};
|
19
|
+
document.addEventListener('selectionchange', this.handler, true);
|
20
|
+
}
|
21
|
+
stop() { if (this.handler)
|
22
|
+
document.removeEventListener('selectionchange', this.handler, true); }
|
23
|
+
save() {
|
24
|
+
const sel = window.getSelection();
|
25
|
+
if (sel && sel.rangeCount)
|
26
|
+
this.lastRange = sel.getRangeAt(0).cloneRange();
|
27
|
+
}
|
28
|
+
restore() {
|
29
|
+
if (!this.lastRange)
|
30
|
+
return;
|
31
|
+
const sel = document.getSelection();
|
32
|
+
if (!sel)
|
33
|
+
return;
|
34
|
+
sel.removeAllRanges();
|
35
|
+
sel.addRange(this.lastRange);
|
36
|
+
}
|
37
|
+
focusAndRestore() { this.editorEl?.focus(); this.restore(); }
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=selection.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../../src/nile-rich-text-editor/rte-utils/selection.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAgB;IAOzB,YAAY,IAAwE;QAH7E,cAAS,GAAiB,IAAI,CAAC;QAIpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE;YAClB,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;YACpC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC;gBAAE,OAAO;YACzC,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAC1D,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;gBACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,KAAK,IAAI,IAAI,CAAC,OAAO;QAAE,QAAQ,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAEjG,IAAI;QACF,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;QAClC,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU;YAAE,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IAC7E,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;QAAC,IAAI,CAAC,GAAG;YAAE,OAAO;QACtD,GAAG,CAAC,eAAe,EAAE,CAAC;QAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,eAAe,KAAK,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;CAC9D","sourcesContent":["export class SelectionManager {\n private host: HTMLElement;\n private onChange: () => void;\n public editorEl: HTMLElement;\n public lastRange: Range | null = null;\n private handler!: () => void;\n \n constructor(args: { host: HTMLElement; editorEl: HTMLElement; onChange: () => void }) {\n this.host = args.host;\n this.editorEl = args.editorEl;\n this.onChange = args.onChange;\n }\n \n start() {\n this.handler = () => {\n const sel = document.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n if (this.editorEl.contains(range.commonAncestorContainer)) {\n this.lastRange = range.cloneRange();\n this.onChange();\n }\n };\n document.addEventListener('selectionchange', this.handler, true);\n }\n \n stop() { if (this.handler) document.removeEventListener('selectionchange', this.handler, true); }\n \n save() {\n const sel = window.getSelection();\n if (sel && sel.rangeCount) this.lastRange = sel.getRangeAt(0).cloneRange();\n }\n \n restore() {\n if (!this.lastRange) return;\n const sel = document.getSelection(); if (!sel) return;\n sel.removeAllRanges(); sel.addRange(this.lastRange);\n }\n \n focusAndRestore() { this.editorEl?.focus(); this.restore(); }\n }\n "]}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
export declare class ToolbarController {
|
2
|
+
buttonMap: Map<string, HTMLElement[]>;
|
3
|
+
headingSelect: HTMLSelectElement | null;
|
4
|
+
fontSelect: HTMLSelectElement | null;
|
5
|
+
colorInput: HTMLInputElement | null;
|
6
|
+
bgColorInput: HTMLInputElement | null;
|
7
|
+
colorSwatchEl: HTMLElement | null;
|
8
|
+
bgSwatchEl: HTMLElement | null;
|
9
|
+
private editorEl;
|
10
|
+
private onCommand;
|
11
|
+
private onChange;
|
12
|
+
private setAlignment;
|
13
|
+
private setBlockTag;
|
14
|
+
private setFontFamily;
|
15
|
+
private setForeColor;
|
16
|
+
private setBackColor;
|
17
|
+
constructor(args: {
|
18
|
+
editorEl: HTMLElement;
|
19
|
+
onCommand: (cmd: string) => void;
|
20
|
+
onChange: () => void;
|
21
|
+
setAlignment: (a: 'left' | 'center' | 'right' | 'justify') => void;
|
22
|
+
setBlockTag: (t: string) => void;
|
23
|
+
setFontFamily: (ff: string) => void;
|
24
|
+
setForeColor: (c: string) => void;
|
25
|
+
setBackColor: (c: string) => void;
|
26
|
+
});
|
27
|
+
wire(tb: HTMLElement): void;
|
28
|
+
}
|
@@ -0,0 +1,161 @@
|
|
1
|
+
import { DEFAULT_ICONS } from './vars';
|
2
|
+
export class ToolbarController {
|
3
|
+
constructor(args) {
|
4
|
+
this.buttonMap = new Map();
|
5
|
+
this.headingSelect = null;
|
6
|
+
this.fontSelect = null;
|
7
|
+
this.colorInput = null;
|
8
|
+
this.bgColorInput = null;
|
9
|
+
this.colorSwatchEl = null;
|
10
|
+
this.bgSwatchEl = null;
|
11
|
+
this.editorEl = args.editorEl;
|
12
|
+
this.onCommand = args.onCommand;
|
13
|
+
this.onChange = args.onChange;
|
14
|
+
this.setAlignment = args.setAlignment;
|
15
|
+
this.setBlockTag = args.setBlockTag;
|
16
|
+
this.setFontFamily = args.setFontFamily;
|
17
|
+
this.setForeColor = args.setForeColor;
|
18
|
+
this.setBackColor = args.setBackColor;
|
19
|
+
}
|
20
|
+
wire(tb) {
|
21
|
+
// reset
|
22
|
+
this.buttonMap.clear();
|
23
|
+
this.headingSelect = null;
|
24
|
+
this.fontSelect = null;
|
25
|
+
this.colorInput = null;
|
26
|
+
this.bgColorInput = null;
|
27
|
+
this.colorSwatchEl = null;
|
28
|
+
this.bgSwatchEl = null;
|
29
|
+
Array.from(tb.children).forEach(child => {
|
30
|
+
const tag = child.tagName.toLowerCase();
|
31
|
+
if (tag === 'nile-rte-select' && child.getAttribute('type') === 'align') {
|
32
|
+
child.addEventListener('change', (e) => {
|
33
|
+
const alignment = e.detail;
|
34
|
+
this.setAlignment(alignment);
|
35
|
+
this.onChange();
|
36
|
+
});
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
if (tag === 'nile-rte-toolbar-item') {
|
40
|
+
let btn = child.querySelector(':scope > nile-button');
|
41
|
+
const cmd = child.getAttribute('name') || '';
|
42
|
+
const label = child.getAttribute('label') || cmd;
|
43
|
+
const iconAttr = child.getAttribute('icon');
|
44
|
+
const authoredHasContent = child.innerHTML.trim().length > 0;
|
45
|
+
if (!btn) {
|
46
|
+
btn = document.createElement('nile-button');
|
47
|
+
btn.variant = 'tertiary';
|
48
|
+
btn.size = 'small';
|
49
|
+
}
|
50
|
+
if (iconAttr) {
|
51
|
+
btn.innerHTML = `<nile-icon name="${iconAttr}" aria-label="${label}"></nile-icon>`;
|
52
|
+
child.innerHTML = '';
|
53
|
+
}
|
54
|
+
else if (!authoredHasContent) {
|
55
|
+
const defaultIcon = DEFAULT_ICONS[cmd];
|
56
|
+
if (defaultIcon) {
|
57
|
+
btn.innerHTML = `<nile-icon name="${defaultIcon}" size="20" color="black" aria-label="${label}"></nile-icon>`;
|
58
|
+
}
|
59
|
+
else {
|
60
|
+
btn.textContent = label || cmd;
|
61
|
+
}
|
62
|
+
child.innerHTML = '';
|
63
|
+
}
|
64
|
+
else {
|
65
|
+
btn.innerHTML = child.innerHTML;
|
66
|
+
child.innerHTML = '';
|
67
|
+
}
|
68
|
+
if (!btn.isConnected)
|
69
|
+
child.appendChild(btn);
|
70
|
+
btn.setAttribute('aria-label', label);
|
71
|
+
btn.addEventListener('mousedown', e => e.preventDefault());
|
72
|
+
btn.addEventListener('click', () => this.onCommand(cmd));
|
73
|
+
const arr = this.buttonMap.get(cmd) ?? [];
|
74
|
+
arr.push(btn);
|
75
|
+
this.buttonMap.set(cmd, arr);
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
if (tag === 'nile-rte-select') {
|
79
|
+
const type = child.getAttribute('type') || '';
|
80
|
+
child.addEventListener('change', (e) => {
|
81
|
+
const val = e.detail;
|
82
|
+
if (type === 'heading')
|
83
|
+
this.setBlockTag(val);
|
84
|
+
else if (type === 'font')
|
85
|
+
this.setFontFamily(val);
|
86
|
+
this.onChange();
|
87
|
+
});
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
if (tag === 'nile-rte-color') {
|
91
|
+
const label = child.getAttribute('label') ?? 'Text color';
|
92
|
+
const value = child.getAttribute('value') ?? '#000000';
|
93
|
+
const mode = child.getAttribute('mode') ?? 'text';
|
94
|
+
let input = child.querySelector(':scope > input[type="color"]');
|
95
|
+
if (!input) {
|
96
|
+
input = document.createElement('input');
|
97
|
+
input.type = 'color';
|
98
|
+
input.style.position = 'absolute';
|
99
|
+
input.style.opacity = '0';
|
100
|
+
input.style.pointerEvents = 'none';
|
101
|
+
child.appendChild(input);
|
102
|
+
}
|
103
|
+
input.title = label;
|
104
|
+
input.value = value;
|
105
|
+
let trigger = child.querySelector(':scope > button.rte-color-trigger');
|
106
|
+
if (!trigger) {
|
107
|
+
trigger = document.createElement('button');
|
108
|
+
trigger.type = 'button';
|
109
|
+
trigger.className = 'rte-color-trigger';
|
110
|
+
trigger.setAttribute('aria-label', label);
|
111
|
+
if (mode === 'background') {
|
112
|
+
trigger.innerHTML = `<span class="swatch-box" aria-hidden="true"></span>`;
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
trigger.innerHTML = `
|
116
|
+
<span class="glyph-stack" aria-hidden="true">
|
117
|
+
<span class="glyph">A</span>
|
118
|
+
<span class="underline"></span>
|
119
|
+
</span>`;
|
120
|
+
}
|
121
|
+
child.appendChild(trigger);
|
122
|
+
}
|
123
|
+
const underline = trigger.querySelector('.underline');
|
124
|
+
const square = trigger.querySelector('.swatch-box');
|
125
|
+
if (mode === 'background') {
|
126
|
+
this.bgColorInput = input;
|
127
|
+
this.bgSwatchEl = square;
|
128
|
+
if (this.bgSwatchEl)
|
129
|
+
this.bgSwatchEl.style.backgroundColor = input.value;
|
130
|
+
}
|
131
|
+
else {
|
132
|
+
this.colorInput = input;
|
133
|
+
this.colorSwatchEl = underline;
|
134
|
+
if (this.colorSwatchEl)
|
135
|
+
this.colorSwatchEl.style.backgroundColor = input.value;
|
136
|
+
}
|
137
|
+
trigger.addEventListener('click', (e) => {
|
138
|
+
e.preventDefault();
|
139
|
+
// Caller will handle selection focus before invoking controller events
|
140
|
+
input.click();
|
141
|
+
});
|
142
|
+
input.addEventListener('input', () => {
|
143
|
+
if (mode === 'background') {
|
144
|
+
this.setBackColor(input.value);
|
145
|
+
if (this.bgSwatchEl)
|
146
|
+
this.bgSwatchEl.style.backgroundColor = input.value;
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
this.setForeColor(input.value);
|
150
|
+
if (this.colorSwatchEl)
|
151
|
+
this.colorSwatchEl.style.backgroundColor = input.value;
|
152
|
+
}
|
153
|
+
this.onChange();
|
154
|
+
});
|
155
|
+
trigger.addEventListener('mousedown', e => e.preventDefault());
|
156
|
+
input.addEventListener('mousedown', e => e.preventDefault());
|
157
|
+
}
|
158
|
+
});
|
159
|
+
}
|
160
|
+
}
|
161
|
+
//# sourceMappingURL=toolbar.js.map
|