@aquera/nile-elements 0.1.67-beta-1.6 → 0.1.67-beta-1.7
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 +11 -5
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +81 -12
- package/dist/nile-avatar/nile-avatar.test.cjs.js +1 -1
- package/dist/nile-avatar/nile-avatar.test.cjs.js.map +1 -1
- package/dist/nile-avatar/nile-avatar.test.esm.js +1 -1
- package/dist/nile-badge/index.cjs.js +1 -1
- package/dist/nile-badge/index.esm.js +1 -1
- package/dist/nile-badge/nile-badge.cjs.js +1 -1
- package/dist/nile-badge/nile-badge.cjs.js.map +1 -1
- package/dist/nile-badge/nile-badge.esm.js +1 -1
- package/dist/nile-badge/nile-badge.test.cjs.js +1 -1
- package/dist/nile-badge/nile-badge.test.cjs.js.map +1 -1
- package/dist/nile-badge/nile-badge.test.esm.js +1 -1
- package/dist/nile-button/index.cjs.js +1 -1
- package/dist/nile-button/index.esm.js +1 -1
- package/dist/nile-button/nile-button.cjs.js +1 -1
- package/dist/nile-button/nile-button.cjs.js.map +1 -1
- package/dist/nile-button/nile-button.esm.js +1 -1
- package/dist/nile-button/nile-button.test.cjs.js +1 -1
- package/dist/nile-button/nile-button.test.cjs.js.map +1 -1
- package/dist/nile-button/nile-button.test.esm.js +1 -1
- package/dist/nile-calendar/nile-calendar.test.cjs.js +1 -1
- package/dist/nile-calendar/nile-calendar.test.cjs.js.map +1 -1
- package/dist/nile-calendar/nile-calendar.test.esm.js +1 -1
- package/dist/nile-chip/nile-chip.test.cjs.js +1 -1
- package/dist/nile-chip/nile-chip.test.cjs.js.map +1 -1
- package/dist/nile-chip/nile-chip.test.esm.js +1 -1
- package/dist/nile-dialog/index.cjs.js +1 -1
- package/dist/nile-dialog/index.esm.js +1 -1
- package/dist/nile-dialog/nile-dialog.cjs.js +1 -1
- package/dist/nile-dialog/nile-dialog.cjs.js.map +1 -1
- package/dist/nile-dialog/nile-dialog.esm.js +2 -2
- package/dist/nile-dialog/nile-dialog.test.cjs.js +1 -1
- package/dist/nile-dialog/nile-dialog.test.cjs.js.map +1 -1
- package/dist/nile-dialog/nile-dialog.test.esm.js +1 -1
- package/dist/nile-drawer/index.cjs.js +1 -1
- package/dist/nile-drawer/index.esm.js +1 -1
- package/dist/nile-drawer/nile-drawer.cjs.js +1 -1
- package/dist/nile-drawer/nile-drawer.cjs.js.map +1 -1
- package/dist/nile-drawer/nile-drawer.esm.js +1 -1
- package/dist/nile-drawer/nile-drawer.test.cjs.js +1 -1
- package/dist/nile-drawer/nile-drawer.test.cjs.js.map +1 -1
- package/dist/nile-drawer/nile-drawer.test.esm.js +1 -1
- package/dist/nile-icon/icons/svg/format_clear.cjs.js +2 -0
- package/dist/nile-icon/icons/svg/format_clear.cjs.js.map +1 -0
- package/dist/nile-icon/icons/svg/format_clear.esm.js +1 -0
- package/dist/nile-icon/icons/svg/format_list_bulleted.cjs.js +2 -0
- package/dist/nile-icon/icons/svg/format_list_bulleted.cjs.js.map +1 -0
- package/dist/nile-icon/icons/svg/format_list_bulleted.esm.js +1 -0
- package/dist/nile-icon/icons/svg/format_list_numbered.cjs.js +2 -0
- package/dist/nile-icon/icons/svg/format_list_numbered.cjs.js.map +1 -0
- package/dist/nile-icon/icons/svg/format_list_numbered.esm.js +1 -0
- package/dist/nile-icon/icons/svg/index.cjs.js +1 -1
- package/dist/nile-icon/icons/svg/index.esm.js +1 -1
- package/dist/nile-icon/index.cjs.js +1 -1
- package/dist/nile-icon/index.cjs.js.map +1 -1
- package/dist/nile-icon/index.esm.js +2 -2
- package/dist/nile-icon/nile-icon.test.cjs.js +1 -1
- package/dist/nile-icon/nile-icon.test.cjs.js.map +1 -1
- package/dist/nile-icon/nile-icon.test.esm.js +1 -1
- package/dist/nile-icon-button/index.cjs.js +1 -1
- package/dist/nile-icon-button/index.esm.js +1 -1
- package/dist/nile-icon-button/nile-icon-button.cjs.js +1 -1
- package/dist/nile-icon-button/nile-icon-button.cjs.js.map +1 -1
- package/dist/nile-icon-button/nile-icon-button.esm.js +1 -1
- package/dist/nile-input/index.cjs.js +1 -1
- package/dist/nile-input/index.esm.js +1 -1
- package/dist/nile-input/nile-input.cjs.js +1 -1
- package/dist/nile-input/nile-input.cjs.js.map +1 -1
- package/dist/nile-input/nile-input.esm.js +1 -1
- package/dist/nile-input/nile-input.test.cjs.js +1 -1
- package/dist/nile-input/nile-input.test.cjs.js.map +1 -1
- package/dist/nile-input/nile-input.test.esm.js +1 -1
- package/dist/nile-menu-item/index.cjs.js +1 -1
- package/dist/nile-menu-item/index.esm.js +1 -1
- package/dist/nile-menu-item/nile-menu-item.cjs.js +1 -1
- package/dist/nile-menu-item/nile-menu-item.cjs.js.map +1 -1
- package/dist/nile-menu-item/nile-menu-item.esm.js +1 -1
- package/dist/nile-option/index.cjs.js +1 -1
- package/dist/nile-option/index.esm.js +1 -1
- package/dist/nile-option/nile-option.cjs.js +1 -1
- package/dist/nile-option/nile-option.cjs.js.map +1 -1
- package/dist/nile-option/nile-option.esm.js +1 -1
- package/dist/nile-rich-text-editor/index.cjs.js +1 -1
- package/dist/nile-rich-text-editor/index.esm.js +1 -1
- 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 +3 -5
- package/dist/nile-rich-text-editor/nile-rich-text-editor.esm.js +1 -1
- package/dist/nile-rich-text-editor/nile-rte-color.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rte-color.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rte-color.esm.js +54 -1
- package/dist/nile-rich-text-editor/nile-rte-link.cjs.js +2 -0
- package/dist/nile-rich-text-editor/nile-rte-link.cjs.js.map +1 -0
- package/dist/nile-rich-text-editor/nile-rte-link.esm.js +19 -0
- package/dist/nile-rich-text-editor/utils.cjs.js +1 -1
- package/dist/nile-rich-text-editor/utils.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/utils.esm.js +1 -1
- package/dist/nile-select/index.cjs.js +1 -1
- package/dist/nile-select/index.esm.js +1 -1
- package/dist/nile-select/nile-select.cjs.js +1 -1
- package/dist/nile-select/nile-select.cjs.js.map +1 -1
- package/dist/nile-select/nile-select.esm.js +1 -1
- package/dist/nile-select/nile-select.test.cjs.js +1 -1
- package/dist/nile-select/nile-select.test.cjs.js.map +1 -1
- package/dist/nile-select/nile-select.test.esm.js +1 -1
- package/dist/nile-tab/index.cjs.js +1 -1
- package/dist/nile-tab/index.esm.js +1 -1
- package/dist/nile-tab/nile-tab.cjs.js +1 -1
- package/dist/nile-tab/nile-tab.cjs.js.map +1 -1
- package/dist/nile-tab/nile-tab.esm.js +1 -1
- package/dist/nile-tab-group/index.cjs.js +1 -1
- package/dist/nile-tab-group/index.esm.js +1 -1
- package/dist/nile-tab-group/nile-tab-group.cjs.js +1 -1
- package/dist/nile-tab-group/nile-tab-group.cjs.js.map +1 -1
- package/dist/nile-tab-group/nile-tab-group.esm.js +1 -1
- package/dist/nile-tab-group/nile-tab-group.test.cjs.js +1 -1
- package/dist/nile-tab-group/nile-tab-group.test.cjs.js.map +1 -1
- package/dist/nile-tab-group/nile-tab-group.test.esm.js +1 -1
- package/dist/nile-tag/index.cjs.js +1 -1
- package/dist/nile-tag/index.esm.js +1 -1
- package/dist/nile-tag/nile-tag.cjs.js +1 -1
- package/dist/nile-tag/nile-tag.cjs.js.map +1 -1
- package/dist/nile-tag/nile-tag.esm.js +1 -1
- package/dist/nile-toast/index.cjs.js +1 -1
- package/dist/nile-toast/index.esm.js +1 -1
- package/dist/nile-toast/nile-toast.cjs.js +1 -1
- package/dist/nile-toast/nile-toast.cjs.js.map +1 -1
- package/dist/nile-toast/nile-toast.esm.js +1 -1
- package/dist/nile-tree/index.cjs.js +1 -1
- package/dist/nile-tree/index.esm.js +1 -1
- package/dist/nile-tree/nile-tree.cjs.js +1 -1
- package/dist/nile-tree/nile-tree.cjs.js.map +1 -1
- package/dist/nile-tree/nile-tree.esm.js +1 -1
- package/dist/nile-tree-item/index.cjs.js +1 -1
- package/dist/nile-tree-item/index.esm.js +1 -1
- package/dist/nile-tree-item/nile-tree-item.cjs.js +1 -1
- package/dist/nile-tree-item/nile-tree-item.cjs.js.map +1 -1
- package/dist/nile-tree-item/nile-tree-item.esm.js +1 -1
- package/dist/nile-virtual-select/index.cjs.js +1 -1
- package/dist/nile-virtual-select/index.esm.js +1 -1
- package/dist/nile-virtual-select/nile-virtual-select.cjs.js +1 -1
- package/dist/nile-virtual-select/nile-virtual-select.cjs.js.map +1 -1
- package/dist/nile-virtual-select/nile-virtual-select.esm.js +1 -1
- package/dist/src/nile-icon/icons/svg/format_clear.d.ts +5 -0
- package/dist/src/nile-icon/icons/svg/format_clear.js +5 -0
- package/dist/src/nile-icon/icons/svg/format_clear.js.map +1 -0
- package/dist/src/nile-icon/icons/svg/format_list_bulleted.d.ts +5 -0
- package/dist/src/nile-icon/icons/svg/format_list_bulleted.js +5 -0
- package/dist/src/nile-icon/icons/svg/format_list_bulleted.js.map +1 -0
- package/dist/src/nile-icon/icons/svg/format_list_numbered.d.ts +5 -0
- package/dist/src/nile-icon/icons/svg/format_list_numbered.js +5 -0
- package/dist/src/nile-icon/icons/svg/format_list_numbered.js.map +1 -0
- package/dist/src/nile-icon/icons/svg/index.d.ts +3 -0
- package/dist/src/nile-icon/icons/svg/index.js +3 -0
- package/dist/src/nile-icon/icons/svg/index.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js +3 -5
- 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 +1 -0
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js +18 -78
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rte-color.d.ts +11 -3
- package/dist/src/nile-rich-text-editor/nile-rte-color.js +171 -6
- package/dist/src/nile-rich-text-editor/nile-rte-color.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rte-link.d.ts +19 -0
- package/dist/src/nile-rich-text-editor/nile-rte-link.js +172 -0
- package/dist/src/nile-rich-text-editor/nile-rte-link.js.map +1 -0
- package/dist/src/nile-rich-text-editor/sanatize.d.ts +1 -0
- package/dist/src/nile-rich-text-editor/sanatize.js +40 -0
- package/dist/src/nile-rich-text-editor/sanatize.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/nile-icon/icons/svg/format_clear.ts +5 -0
- package/src/nile-icon/icons/svg/format_list_bulleted.ts +5 -0
- package/src/nile-icon/icons/svg/format_list_numbered.ts +5 -0
- package/src/nile-icon/icons/svg/index.ts +3 -0
- package/src/nile-rich-text-editor/nile-rich-text-editor.css.ts +3 -5
- package/src/nile-rich-text-editor/nile-rich-text-editor.ts +26 -80
- package/src/nile-rich-text-editor/nile-rte-color.ts +182 -6
- package/src/nile-rich-text-editor/nile-rte-link.ts +161 -0
- package/vscode-html-custom-data.json +33 -3
@@ -0,0 +1,172 @@
|
|
1
|
+
import { __decorate } from "tslib";
|
2
|
+
import { LitElement, html } from 'lit';
|
3
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
4
|
+
let NileRteLink = class NileRteLink extends LitElement {
|
5
|
+
constructor() {
|
6
|
+
super(...arguments);
|
7
|
+
this.placeholder = 'https://';
|
8
|
+
this.linkValue = '';
|
9
|
+
this.selectionRange = null;
|
10
|
+
}
|
11
|
+
createRenderRoot() { return this; }
|
12
|
+
connectedCallback() {
|
13
|
+
super.connectedCallback();
|
14
|
+
this.injectCss(`
|
15
|
+
nile-rte-link nile-button.rte-link-trigger::part(base) {
|
16
|
+
width: 32px;
|
17
|
+
height: 32px;
|
18
|
+
padding: 0;
|
19
|
+
border: none;
|
20
|
+
border-radius: 6px;
|
21
|
+
}
|
22
|
+
.link-popup {
|
23
|
+
display: flex;
|
24
|
+
gap: 6px;
|
25
|
+
padding: 6px 8px;
|
26
|
+
align-items: center;
|
27
|
+
background: white;
|
28
|
+
}
|
29
|
+
.link-input {
|
30
|
+
flex: 1;
|
31
|
+
padding: 6px 8px;
|
32
|
+
font-size: 14px;
|
33
|
+
border: 1px solid #ccc;
|
34
|
+
border-radius: 4px;
|
35
|
+
}
|
36
|
+
nile-popover.rte-link-popover::part(popover) {
|
37
|
+
min-width: 250px;
|
38
|
+
height: 44px;
|
39
|
+
padding: 0px;
|
40
|
+
gap: 0px;
|
41
|
+
}
|
42
|
+
`);
|
43
|
+
}
|
44
|
+
injectCss(cssText) {
|
45
|
+
if (this.querySelector('style[data-rte-link-style]'))
|
46
|
+
return;
|
47
|
+
const style = document.createElement('style');
|
48
|
+
style.setAttribute('data-rte-link-style', 'true');
|
49
|
+
style.textContent = cssText;
|
50
|
+
this.insertBefore(style, this.firstChild);
|
51
|
+
}
|
52
|
+
onOpen() {
|
53
|
+
if (!this.editorEl)
|
54
|
+
return;
|
55
|
+
const sel = document.getSelection();
|
56
|
+
if (!sel || sel.rangeCount === 0)
|
57
|
+
return;
|
58
|
+
this.selectionRange = sel.getRangeAt(0).cloneRange();
|
59
|
+
// Pre-fill with existing href if selection inside <a>
|
60
|
+
let n = sel.anchorNode;
|
61
|
+
let a = null;
|
62
|
+
while (n && n !== this.editorEl) {
|
63
|
+
if (n instanceof HTMLAnchorElement) {
|
64
|
+
a = n;
|
65
|
+
break;
|
66
|
+
}
|
67
|
+
n = n.parentNode;
|
68
|
+
}
|
69
|
+
this.linkValue = a?.href || '';
|
70
|
+
setTimeout(() => {
|
71
|
+
this.querySelector('.link-input')?.focus();
|
72
|
+
}, 0);
|
73
|
+
}
|
74
|
+
onApply() {
|
75
|
+
if (!this.editorEl || !this.selectionRange)
|
76
|
+
return;
|
77
|
+
const url = this.linkValue.trim();
|
78
|
+
if (!url)
|
79
|
+
return;
|
80
|
+
const sel = document.getSelection();
|
81
|
+
if (!sel)
|
82
|
+
return;
|
83
|
+
sel.removeAllRanges();
|
84
|
+
sel.addRange(this.selectionRange);
|
85
|
+
// Check for existing <a>
|
86
|
+
let n = this.selectionRange.startContainer;
|
87
|
+
let a = null;
|
88
|
+
while (n && n !== this.editorEl) {
|
89
|
+
if (n instanceof HTMLAnchorElement) {
|
90
|
+
a = n;
|
91
|
+
break;
|
92
|
+
}
|
93
|
+
n = n.parentNode;
|
94
|
+
}
|
95
|
+
if (a) {
|
96
|
+
a.href = url;
|
97
|
+
}
|
98
|
+
else {
|
99
|
+
const link = document.createElement('a');
|
100
|
+
link.href = url;
|
101
|
+
if (this.selectionRange.collapsed) {
|
102
|
+
link.textContent = url;
|
103
|
+
this.selectionRange.insertNode(link);
|
104
|
+
}
|
105
|
+
else {
|
106
|
+
try {
|
107
|
+
this.selectionRange.surroundContents(link);
|
108
|
+
}
|
109
|
+
catch {
|
110
|
+
const frag = this.selectionRange.extractContents();
|
111
|
+
link.appendChild(frag);
|
112
|
+
this.selectionRange.insertNode(link);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
this.emit(url);
|
117
|
+
// Close the popover by toggling `open`
|
118
|
+
const pop = this.querySelector('nile-popover');
|
119
|
+
if (pop)
|
120
|
+
pop.isShow = false;
|
121
|
+
}
|
122
|
+
emit(href) {
|
123
|
+
this.dispatchEvent(new CustomEvent('link-changed', {
|
124
|
+
detail: { href },
|
125
|
+
bubbles: true,
|
126
|
+
composed: true
|
127
|
+
}));
|
128
|
+
}
|
129
|
+
render() {
|
130
|
+
return html `
|
131
|
+
<nile-popover placement="bottom-start" class="rte-link-popover" distance="10" .arrow=${false}>
|
132
|
+
<nile-button class="rte-link-trigger" slot="anchor" variant="tertiary" size="small" @click=${() => this.onOpen()}>
|
133
|
+
<nile-icon name="link_2" aria-label="Insert/Edit Link"></nile-icon>
|
134
|
+
</nile-button>
|
135
|
+
|
136
|
+
<div class="link-popup">
|
137
|
+
<input
|
138
|
+
class="link-input"
|
139
|
+
type="text"
|
140
|
+
placeholder="Type or paste link here"
|
141
|
+
.value=${this.linkValue}
|
142
|
+
@input=${(e) => this.linkValue = e.target.value}
|
143
|
+
@keydown=${(e) => {
|
144
|
+
if (e.key === 'Enter')
|
145
|
+
this.onApply();
|
146
|
+
if (e.key === 'Escape') {
|
147
|
+
const pop = this.querySelector('nile-popover');
|
148
|
+
if (pop)
|
149
|
+
pop.isShow = false;
|
150
|
+
}
|
151
|
+
}}
|
152
|
+
/>
|
153
|
+
<nile-button @click=${() => this.onApply()}>Apply</nile-button>
|
154
|
+
</div>
|
155
|
+
</nile-popover>
|
156
|
+
`;
|
157
|
+
}
|
158
|
+
};
|
159
|
+
__decorate([
|
160
|
+
property({ attribute: false })
|
161
|
+
], NileRteLink.prototype, "editorEl", void 0);
|
162
|
+
__decorate([
|
163
|
+
property({ type: String })
|
164
|
+
], NileRteLink.prototype, "placeholder", void 0);
|
165
|
+
__decorate([
|
166
|
+
state()
|
167
|
+
], NileRteLink.prototype, "linkValue", void 0);
|
168
|
+
NileRteLink = __decorate([
|
169
|
+
customElement('nile-rte-link')
|
170
|
+
], NileRteLink);
|
171
|
+
export { NileRteLink };
|
172
|
+
//# sourceMappingURL=nile-rte-link.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"nile-rte-link.js","sourceRoot":"","sources":["../../../src/nile-rich-text-editor/nile-rte-link.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\n@customElement('nile-rte-link')\nexport class NileRteLink extends LitElement {\n protected createRenderRoot() { return this; }\n\n @property({ attribute: false }) editorEl!: HTMLElement;\n @property({ type: String }) placeholder = 'https://';\n\n @state() private linkValue = '';\n private selectionRange: Range | null = null;\n\n connectedCallback() {\n super.connectedCallback();\n this.injectCss(`\n nile-rte-link nile-button.rte-link-trigger::part(base) {\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 6px;\n }\n .link-popup {\n display: flex;\n gap: 6px;\n padding: 6px 8px;\n align-items: center;\n background: white;\n }\n .link-input {\n flex: 1;\n padding: 6px 8px;\n font-size: 14px;\n border: 1px solid #ccc;\n border-radius: 4px;\n }\n nile-popover.rte-link-popover::part(popover) {\n min-width: 250px;\n height: 44px;\n padding: 0px;\n gap: 0px;\n }\n `);\n }\n\n private injectCss(cssText: string) {\n if (this.querySelector('style[data-rte-link-style]')) return;\n const style = document.createElement('style');\n style.setAttribute('data-rte-link-style', 'true');\n style.textContent = cssText;\n this.insertBefore(style, this.firstChild);\n }\n\n private onOpen() {\n if (!this.editorEl) return;\n const sel = document.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n\n this.selectionRange = sel.getRangeAt(0).cloneRange();\n\n // Pre-fill with existing href if selection inside <a>\n let n: Node | null = sel.anchorNode;\n let a: HTMLAnchorElement | null = null;\n while (n && n !== this.editorEl) {\n if (n instanceof HTMLAnchorElement) { a = n; break; }\n n = n.parentNode;\n }\n this.linkValue = a?.href || '';\n\n setTimeout(() => {\n this.querySelector<HTMLInputElement>('.link-input')?.focus();\n }, 0);\n }\n\n private onApply() {\n if (!this.editorEl || !this.selectionRange) return;\n const url = this.linkValue.trim();\n if (!url) return;\n\n const sel = document.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(this.selectionRange);\n\n // Check for existing <a>\n let n: Node | null = this.selectionRange.startContainer;\n let a: HTMLAnchorElement | null = null;\n while (n && n !== this.editorEl) {\n if (n instanceof HTMLAnchorElement) { a = n; break; }\n n = n.parentNode;\n }\n\n if (a) {\n a.href = url;\n } else {\n const link = document.createElement('a');\n link.href = url;\n if (this.selectionRange.collapsed) {\n link.textContent = url;\n this.selectionRange.insertNode(link);\n } else {\n try {\n this.selectionRange.surroundContents(link);\n } catch {\n const frag = this.selectionRange.extractContents();\n link.appendChild(frag);\n this.selectionRange.insertNode(link);\n }\n }\n }\n\n this.emit(url);\n\n // Close the popover by toggling `open`\n const pop = this.querySelector('nile-popover');\n if (pop) (pop as any).isShow = false;\n }\n\n private emit(href: string) {\n this.dispatchEvent(new CustomEvent('link-changed', {\n detail: { href },\n bubbles: true,\n composed: true\n }));\n }\n\n render() {\n return html`\n <nile-popover placement=\"bottom-start\" class=\"rte-link-popover\" distance=\"10\" .arrow=${false}>\n <nile-button class=\"rte-link-trigger\" slot=\"anchor\" variant=\"tertiary\" size=\"small\" @click=${() => this.onOpen()}>\n <nile-icon name=\"link_2\" aria-label=\"Insert/Edit Link\"></nile-icon>\n </nile-button>\n\n <div class=\"link-popup\">\n <input\n class=\"link-input\"\n type=\"text\"\n placeholder=\"Type or paste link here\"\n .value=${this.linkValue}\n @input=${(e: any) => this.linkValue = e.target.value}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') this.onApply();\n if (e.key === 'Escape') {\n const pop = this.querySelector('nile-popover');\n if (pop) (pop as any).isShow = false;\n }\n }}\n />\n <nile-button @click=${() => this.onApply()}>Apply</nile-button>\n </div>\n </nile-popover>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-rte-link': NileRteLink;\n }\n}\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function sanitizeContent(editorEl: HTMLElement): HTMLElement;
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// sanitize.ts
|
2
|
+
export function sanitizeContent(editorEl) {
|
3
|
+
const clone = editorEl.cloneNode(true);
|
4
|
+
// Disallowed tags
|
5
|
+
clone.querySelectorAll('font, o\\:p, script, style').forEach(n => n.remove());
|
6
|
+
// Clean empty spans
|
7
|
+
clone.querySelectorAll('span').forEach(span => {
|
8
|
+
if (!span.getAttributeNames().length) {
|
9
|
+
while (span.firstChild)
|
10
|
+
span.parentNode?.insertBefore(span.firstChild, span);
|
11
|
+
span.remove();
|
12
|
+
}
|
13
|
+
});
|
14
|
+
const allowed = [
|
15
|
+
'font-weight', 'font-style', 'text-decoration', 'text-transform',
|
16
|
+
'font-size', 'line-height', 'font-family', 'color', 'background-color',
|
17
|
+
'text-align', 'margin-left', 'margin-right', 'margin-top', 'margin-bottom',
|
18
|
+
'list-style-type'
|
19
|
+
];
|
20
|
+
// Walk over elements and embed computed styles
|
21
|
+
const walker = document.createTreeWalker(editorEl, NodeFilter.SHOW_ELEMENT);
|
22
|
+
const targetWalker = document.createTreeWalker(clone, NodeFilter.SHOW_ELEMENT);
|
23
|
+
while (walker.nextNode() && targetWalker.nextNode()) {
|
24
|
+
const srcEl = walker.currentNode;
|
25
|
+
const dstEl = targetWalker.currentNode;
|
26
|
+
const comp = getComputedStyle(srcEl);
|
27
|
+
const safe = [];
|
28
|
+
allowed.forEach(prop => {
|
29
|
+
const val = comp.getPropertyValue(prop);
|
30
|
+
if (val && val !== 'normal' && val !== 'initial' && val !== 'none' && val !== '0px') {
|
31
|
+
safe.push(`${prop}:${val}`);
|
32
|
+
}
|
33
|
+
});
|
34
|
+
if (safe.length) {
|
35
|
+
dstEl.setAttribute('style', safe.join(';'));
|
36
|
+
}
|
37
|
+
}
|
38
|
+
return clone;
|
39
|
+
}
|
40
|
+
//# sourceMappingURL=sanatize.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"sanatize.js","sourceRoot":"","sources":["../../../src/nile-rich-text-editor/sanatize.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,MAAM,UAAU,eAAe,CAAC,QAAqB;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAgB,CAAC;IAEtD,kBAAkB;IAClB,KAAK,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAE9E,oBAAoB;IACpB,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC5C,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,UAAU;gBAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC7E,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG;QACd,aAAa,EAAC,YAAY,EAAC,iBAAiB,EAAC,gBAAgB;QAC7D,WAAW,EAAC,aAAa,EAAC,aAAa,EAAC,OAAO,EAAC,kBAAkB;QAClE,YAAY,EAAC,aAAa,EAAC,cAAc,EAAC,YAAY,EAAC,eAAe;QACtE,iBAAiB;KAClB,CAAC;IAEF,+CAA+C;IAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAC5E,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAE/E,OAAO,MAAM,CAAC,QAAQ,EAAE,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,WAA0B,CAAC;QAChD,MAAM,KAAK,GAAG,YAAY,CAAC,WAA0B,CAAC;QAEtD,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACrB,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,GAAG,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;gBACpF,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["// sanitize.ts\nexport function sanitizeContent(editorEl: HTMLElement): HTMLElement {\n const clone = editorEl.cloneNode(true) as HTMLElement;\n \n // Disallowed tags\n clone.querySelectorAll('font, o\\\\:p, script, style').forEach(n => n.remove());\n \n // Clean empty spans\n clone.querySelectorAll('span').forEach(span => {\n if (!span.getAttributeNames().length) {\n while (span.firstChild) span.parentNode?.insertBefore(span.firstChild, span);\n span.remove();\n }\n });\n \n const allowed = [\n 'font-weight','font-style','text-decoration','text-transform',\n 'font-size','line-height','font-family','color','background-color',\n 'text-align','margin-left','margin-right','margin-top','margin-bottom',\n 'list-style-type'\n ];\n \n // Walk over elements and embed computed styles\n const walker = document.createTreeWalker(editorEl, NodeFilter.SHOW_ELEMENT);\n const targetWalker = document.createTreeWalker(clone, NodeFilter.SHOW_ELEMENT);\n \n while (walker.nextNode() && targetWalker.nextNode()) {\n const srcEl = walker.currentNode as HTMLElement;\n const dstEl = targetWalker.currentNode as HTMLElement;\n \n const comp = getComputedStyle(srcEl);\n const safe: string[] = [];\n \n allowed.forEach(prop => {\n const val = comp.getPropertyValue(prop);\n if (val && val !== 'normal' && val !== 'initial' && val !== 'none' && val !== '0px') {\n safe.push(`${prop}:${val}`);\n }\n });\n \n if (safe.length) {\n dstEl.setAttribute('style', safe.join(';'));\n }\n }\n \n return clone;\n }\n "]}
|