u2ui 1.5.3 → 1.5.4
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/el/ico/ico.js +5 -5
- package/el/rte/README.md +53 -13
- package/el/rte/manifest.json +19 -4
- package/el/rte/rte.css +31 -6
- package/el/rte/rte.js +174 -44
- package/el/rte0/README.md +37 -0
- package/el/rte0/manifest.json +33 -0
- package/el/rte0/rte0.css +9 -0
- package/el/rte0/rte0.js +56 -0
- package/el/system/styler.js +2 -0
- package/el/tooltip/tooltip.css +2 -2
- package/js/Placer/Placer.js +2 -1
- package/js/rte/AGENTS.md +142 -0
- package/js/rte/PLAN.md +488 -0
- package/js/rte/README.md +319 -25
- package/js/rte/blocks.js +7 -0
- package/js/rte/breaks.js +6 -0
- package/js/rte/classes.js +7 -0
- package/js/rte/docs/usage.md +845 -0
- package/js/rte/images.js +7 -0
- package/js/rte/link.js +8 -0
- package/js/rte/playground/README.md +95 -0
- package/js/rte/playground/hosts.html +518 -0
- package/js/rte/playground/index.html +824 -0
- package/js/rte/rte.js +56 -5
- package/js/rte/source.js +12 -0
- package/js/rte/src/browser/README.md +40 -0
- package/js/rte/src/browser/range-rect.js +82 -0
- package/js/rte/src/client/README.md +378 -0
- package/js/rte/src/client/blocks.js +38 -0
- package/js/rte/src/client/breaks.js +212 -0
- package/js/rte/src/client/classes.js +48 -0
- package/js/rte/src/client/editor.js +461 -0
- package/js/rte/src/client/external-input.js +47 -0
- package/js/rte/src/client/history.js +13 -0
- package/js/rte/src/client/images.js +275 -0
- package/js/rte/src/client/link.js +572 -0
- package/js/rte/src/client/marks.js +25 -0
- package/js/rte/src/client/source.js +182 -0
- package/js/rte/src/client/structure.js +27 -0
- package/js/rte/src/client/tables.js +162 -0
- package/js/rte/src/client/unstyle.js +32 -0
- package/js/rte/src/command/README.md +517 -0
- package/js/rte/src/command/block-boundary.js +43 -0
- package/js/rte/src/command/block-style.js +120 -0
- package/js/rte/src/command/commands.js +158 -0
- package/js/rte/src/command/delete.js +112 -0
- package/js/rte/src/command/edit.js +72 -0
- package/js/rte/src/command/element.js +45 -0
- package/js/rte/src/command/enter.js +175 -0
- package/js/rte/src/command/fragment.js +76 -0
- package/js/rte/src/command/insert.js +52 -0
- package/js/rte/src/command/list.js +284 -0
- package/js/rte/src/command/mark.js +583 -0
- package/js/rte/src/command/pending-marks.js +216 -0
- package/js/rte/src/command/table.js +207 -0
- package/js/rte/src/command/unstyle.js +248 -0
- package/js/rte/src/config/README.md +96 -0
- package/js/rte/src/config/config.js +127 -0
- package/js/rte/src/core/README.md +41 -0
- package/js/rte/src/core/core.js +156 -0
- package/js/rte/src/history/README.md +83 -0
- package/js/rte/src/history/history.js +283 -0
- package/js/rte/src/input/README.md +155 -0
- package/js/rte/src/input/external-input.js +130 -0
- package/js/rte/src/input/input-pipeline.js +414 -0
- package/js/rte/src/mark/README.md +219 -0
- package/js/rte/src/mark/dom-adapter.js +100 -0
- package/js/rte/src/mark/mark.js +133 -0
- package/js/rte/src/mark/standard.js +76 -0
- package/js/rte/src/model/README.md +71 -0
- package/js/rte/src/model/content-model.js +213 -0
- package/js/rte/src/model/html/README.md +51 -0
- package/js/rte/src/model/html/html-model.js +90 -0
- package/js/rte/src/normalize/execute/README.md +33 -0
- package/js/rte/src/normalize/execute/repair-executor.js +129 -0
- package/js/rte/src/normalize/normalizer/README.md +48 -0
- package/js/rte/src/normalize/normalizer/normalizer.js +141 -0
- package/js/rte/src/normalize/repair/README.md +70 -0
- package/js/rte/src/normalize/repair/repair-planner.js +208 -0
- package/js/rte/src/sanitize/README.md +105 -0
- package/js/rte/src/sanitize/native.js +43 -0
- package/js/rte/src/sanitize/policy.js +202 -0
- package/js/rte/src/selection/README.md +39 -0
- package/js/rte/src/selection/map/README.md +53 -0
- package/js/rte/src/selection/map/point-map.js +307 -0
- package/js/rte/src/selection/ownership/README.md +32 -0
- package/js/rte/src/selection/ownership/ownership.js +42 -0
- package/js/rte/src/selection/point/README.md +34 -0
- package/js/rte/src/selection/point/point.js +83 -0
- package/js/rte/src/selection/range/README.md +38 -0
- package/js/rte/src/selection/range/edit-range.js +223 -0
- package/js/rte/src/selection/snapshot.js +64 -0
- package/js/rte/src/source/README.md +64 -0
- package/js/rte/src/source/source.js +193 -0
- package/js/rte/src/surface/README.md +36 -0
- package/js/rte/src/surface/content.js +16 -0
- package/js/rte/src/surface/surface.js +87 -0
- package/js/rte/src/transaction/README.md +35 -0
- package/js/rte/src/transaction/transaction.js +56 -0
- package/js/rte/src/ui/README.md +255 -0
- package/js/rte/src/ui/chrome.js +214 -0
- package/js/rte/src/ui/handles.js +179 -0
- package/js/rte/src/ui/place.js +25 -0
- package/js/rte/src/ui/toolbar.js +283 -0
- package/js/rte/src/unstyle/README.md +103 -0
- package/js/rte/src/unstyle/unstyle.js +140 -0
- package/js/rte/tables.js +7 -0
- package/js/rte/unstyle.js +8 -0
- package/js/rte0/README.md +37 -0
- package/js/rte0/rte.js +7 -0
- package/js/{rte → rte0}/src/behavior.js +0 -1
- package/js/{rte → rte0}/src/events.js +0 -1
- package/js/{rte → rte0}/src/range.js +0 -2
- package/js/{rte → rte0}/src/ui.items.js +0 -2
- package/js/{rte → rte0}/src/ui.js +0 -1
- package/package.json +1 -1
- package/u2/Element.js +2 -2
- package/u2/plan-scoped-refactoring.md +133 -303
- package/u2/projects.json +18 -2
- package/u2/tools/update.repos.json.js +1 -1
- package/el/qrcode/package.json +0 -22
- /package/js/{rte → rte0}/old/NodeCleaner.js +0 -0
- /package/js/{rte → rte0}/old/Rte/Rte.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/Rte.ui.items.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/Rte.ui.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/crossbrowser.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/font/tinymce.svg +0 -0
- /package/js/{rte → rte0}/old/Rte/font/tinymce.woff +0 -0
- /package/js/{rte → rte0}/old/Rte/helpers.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/htmlparser.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/index.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/main.css +0 -0
- /package/js/{rte → rte0}/old/old.rte.js +0 -0
- /package/js/{rte → rte0}/old/range-selection.old.js +0 -0
- /package/js/{rte → rte0}/src/fixes.js +0 -0
- /package/js/{rte → rte0}/src/rte.js +0 -0
- /package/js/{rte → rte0}/src/ui/items/ai.js +0 -0
- /package/js/{rte → rte0}/src/ui/items/code.js +0 -0
- /package/js/{rte → rte0}/src/ui/items/undo.js +0 -0
- /package/js/{rte → rte0}/src/util/htmlparser.js +0 -0
- /package/js/{rte → rte0}/src/util/indentHtml.js +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const NAME = /^[a-z][a-z\d-]*$/;
|
|
2
|
+
const ATTRIBUTE = /^[a-z][a-z\d_.:-]*$/;
|
|
3
|
+
|
|
4
|
+
const SCOPES = new Set(['foreign', 'all']);
|
|
5
|
+
|
|
6
|
+
// The ladder is ordered from least to most destructive, and it does not stop at
|
|
7
|
+
// the application's own presentation: someone who keeps pressing wants more
|
|
8
|
+
// removed, so the last rungs take the declared content classes and finally the
|
|
9
|
+
// semantic inline elements as well.
|
|
10
|
+
//
|
|
11
|
+
// The first four rungs are scoped to `foreign`: they spare the classes the host
|
|
12
|
+
// declared as content, and the wrappers carrying them.
|
|
13
|
+
export const defaultUnstyleLevels = Object.freeze([
|
|
14
|
+
level('styles', {attributes: ['style'], scope: 'foreign'}),
|
|
15
|
+
level('attributes', {scope: 'foreign', attributes: [
|
|
16
|
+
'align', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'color',
|
|
17
|
+
'face', 'height', 'size', 'valign', 'width',
|
|
18
|
+
]}),
|
|
19
|
+
level('classes', {attributes: ['class'], scope: 'foreign'}),
|
|
20
|
+
level('formatting', {scope: 'foreign',
|
|
21
|
+
elements: ['b', 'font', 'i', 's', 'span', 'strike', 'u']}),
|
|
22
|
+
level('contentClasses', {attributes: ['class']}),
|
|
23
|
+
level('inline', {elements: [
|
|
24
|
+
'a', 'abbr', 'bdi', 'bdo', 'cite', 'code', 'data', 'del', 'dfn', 'em',
|
|
25
|
+
'ins', 'kbd', 'mark', 'q', 'ruby', 'samp', 'small', 'strong', 'sub',
|
|
26
|
+
'sup', 'time', 'var',
|
|
27
|
+
]}),
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
export class Unstyle {
|
|
31
|
+
constructor(levels = defaultUnstyleLevels) {
|
|
32
|
+
if (!Array.isArray(levels) || !levels.length) throw new TypeError('Unstyle levels must be a non-empty array');
|
|
33
|
+
this.levels = Object.freeze(levels.map(item => level(item?.name, item)));
|
|
34
|
+
if (new Set(this.levels.map(item => item.name)).size !== this.levels.length) {
|
|
35
|
+
throw new RangeError('Unstyle level names must be unique');
|
|
36
|
+
}
|
|
37
|
+
Object.freeze(this);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
clean(root, {through, map = null, transaction = null, preserve = null, keep = null} = {}) {
|
|
41
|
+
if (!root?.querySelectorAll) throw new TypeError('Unstyle cleanup requires a DOM root');
|
|
42
|
+
if (map !== null && typeof map?.unwrap !== 'function') throw new TypeError('Unstyle cleanup requires a point map');
|
|
43
|
+
if (transaction !== null && typeof transaction?.touch !== 'function') {
|
|
44
|
+
throw new TypeError('Unstyle cleanup requires a transaction');
|
|
45
|
+
}
|
|
46
|
+
if (preserve !== null && typeof preserve?.has !== 'function') {
|
|
47
|
+
throw new TypeError('Unstyle cleanup requires a preserved element set');
|
|
48
|
+
}
|
|
49
|
+
const declaredClasses = keep === null ? null : new Set(keep);
|
|
50
|
+
const end = this.levels.findIndex(level => level.name === through);
|
|
51
|
+
if (end < 0) throw new RangeError(`Unknown unstyle level: ${through}`);
|
|
52
|
+
const changed = [];
|
|
53
|
+
const elements = descendants(root).filter(element => !preserve?.has(element));
|
|
54
|
+
for (const level of this.levels.slice(0, end + 1)) {
|
|
55
|
+
const kept = keepFor(level, declaredClasses);
|
|
56
|
+
for (const element of elements.filter(element => matches(level, element, kept)).reverse()) {
|
|
57
|
+
clear(level, element, map, transaction, kept);
|
|
58
|
+
if (!changed.includes(element)) changed.push(element);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return changed;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const defaultUnstyle = new Unstyle();
|
|
66
|
+
|
|
67
|
+
// Only a level scoped to foreign presentation spares the declared classes; the
|
|
68
|
+
// rungs below that scope are where the application's own presentation goes.
|
|
69
|
+
export function keepFor(level, declaredClasses) {
|
|
70
|
+
return level.scope === 'foreign' ? declaredClasses : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// `kept` names classes the host treats as content, so removing presentation does
|
|
74
|
+
// not remove meaning the application declared.
|
|
75
|
+
export function matches(level, element, kept = null) {
|
|
76
|
+
return level.elements.includes(element.localName) && !declared(element, kept)
|
|
77
|
+
|| level.attributes.some(name => removable(name, element, kept));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// An element carrying a declared content class is content itself: the class
|
|
81
|
+
// applies to that wrapper, so removing presentation must not unwrap it.
|
|
82
|
+
export function declared(element, kept = null) {
|
|
83
|
+
return !!kept?.size && [...element.classList].some(name => kept.has(name));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Whether a level would actually take something off this element.
|
|
87
|
+
export function removable(name, element, kept = null) {
|
|
88
|
+
if (!element.hasAttribute(name)) return false;
|
|
89
|
+
if (name !== 'class' || !kept?.size) return true;
|
|
90
|
+
return [...element.classList].some(value => !kept.has(value));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Takes a level's attributes off one element, narrowing `class` to the names
|
|
94
|
+
// the host declared as content instead of dropping it whole.
|
|
95
|
+
export function strip(level, element, kept = null) {
|
|
96
|
+
for (const name of level.attributes) {
|
|
97
|
+
if (name === 'class' && kept?.size) {
|
|
98
|
+
const rest = [...element.classList].filter(value => kept.has(value));
|
|
99
|
+
if (rest.length) element.setAttribute('class', rest.join(' '));
|
|
100
|
+
else element.removeAttribute('class');
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
element.removeAttribute(name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function clear(level, element, map, transaction, kept = null) {
|
|
108
|
+
const parent = element.parentNode;
|
|
109
|
+
strip(level, element, kept);
|
|
110
|
+
const unwrap = !!parent && (level.elements.includes(element.localName)
|
|
111
|
+
|| element.localName === 'span' && !element.attributes.length);
|
|
112
|
+
if (unwrap) map ? map.unwrap(element) : element.replaceWith(...element.childNodes);
|
|
113
|
+
if (transaction && parent) transaction.touch(unwrap ? parent : element).touch(parent);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function descendants(root) {
|
|
117
|
+
const result = root.nodeType === Node.ELEMENT_NODE ? [root] : [];
|
|
118
|
+
return result.concat([...root.querySelectorAll('*')]);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function level(name, options = {}) {
|
|
122
|
+
if (typeof name !== 'string' || !name.trim()) throw new TypeError('An unstyle level requires a name');
|
|
123
|
+
const attributes = names(options.attributes || [], ATTRIBUTE, 'attribute');
|
|
124
|
+
const elements = names(options.elements || [], NAME, 'element');
|
|
125
|
+
if (!attributes.length && !elements.length) throw new TypeError('An unstyle level requires attributes or elements');
|
|
126
|
+
const scope = options.scope ?? 'all';
|
|
127
|
+
if (!SCOPES.has(scope)) throw new TypeError(`Unknown unstyle scope: ${scope}`);
|
|
128
|
+
return Object.freeze({name: name.trim(), attributes, elements, scope});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function names(values, pattern, label) {
|
|
132
|
+
if (!Array.isArray(values)) throw new TypeError(`Unstyle ${label}s must be an array`);
|
|
133
|
+
const result = [];
|
|
134
|
+
for (const value of values) {
|
|
135
|
+
const name = String(value).toLowerCase();
|
|
136
|
+
if (!pattern.test(name)) throw new TypeError(`Invalid unstyle ${label}: ${value}`);
|
|
137
|
+
if (!result.includes(name)) result.push(name);
|
|
138
|
+
}
|
|
139
|
+
return Object.freeze(result);
|
|
140
|
+
}
|
package/js/rte/tables.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import {editor} from './rte.js';
|
|
2
|
+
import {unstyle} from './src/client/unstyle.js';
|
|
3
|
+
|
|
4
|
+
export {unstyle, unstyles} from './src/client/unstyle.js';
|
|
5
|
+
export {unstyleCommand} from './src/command/unstyle.js';
|
|
6
|
+
export {Unstyle, defaultUnstyle, defaultUnstyleLevels} from './src/unstyle/unstyle.js';
|
|
7
|
+
|
|
8
|
+
editor.add(unstyle);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# SelectorObserver.js
|
|
2
|
+
Easily Make Elements Editable with Intuitive Controls
|
|
3
|
+
|
|
4
|
+
## Usage
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<div contenteditable style="--u2-rte:true" id="myEditor">
|
|
8
|
+
Start <strong>typing</strong> here...
|
|
9
|
+
</div>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```css
|
|
13
|
+
#myEditor {
|
|
14
|
+
--u2-rte-toolbar:Bold Italic Code;
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Demos
|
|
19
|
+
|
|
20
|
+
[behavior.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/behavior.html)
|
|
21
|
+
[test.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/test.html)
|
|
22
|
+
[selection-explorer.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/selection-explorer.html)
|
|
23
|
+
[events.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/events.html)
|
|
24
|
+
[minimal.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/minimal.html)
|
|
25
|
+
[fixes.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/fixes.html)
|
|
26
|
+
[range.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/range.html)
|
|
27
|
+
[ai.html](http://gcdn.li/u2ui/u2@main/js/rte0/tests/ai.html)
|
|
28
|
+
|
|
29
|
+
## Files
|
|
30
|
+
|
|
31
|
+
- /src/fixes.js: Tries to fix as many wrong browser behaviors as possible for a seamless experience.
|
|
32
|
+
|
|
33
|
+
## About
|
|
34
|
+
|
|
35
|
+
- MIT License, Copyright (c) 2022 <u2> (like all repositories in this organization) <br>
|
|
36
|
+
- Suggestions, ideas, finding bugs and making pull requests make us very happy. ♥
|
|
37
|
+
|
package/js/rte0/rte.js
ADDED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {$range} from './range.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
export let active = null; // the active contenteditable (even if the toolbar has focus)
|
|
5
4
|
export let focused = null; // the focused contenteditable (not if the toolbar has focus)
|
|
6
5
|
export let range = null; // the current selection range
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u2ui",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "HTML Advanced: More Capabilities, Same Feel, Same Simplicity",
|
|
5
5
|
"keywords": ["web-components","pattern-library","component-library","ui-toolkit","design-system"],
|
|
6
6
|
"author": "Tobias Buschor",
|
package/u2/Element.js
CHANGED
|
@@ -17,8 +17,8 @@ export default class U2Element extends HTMLElement {
|
|
|
17
17
|
|
|
18
18
|
/** Bring what a child needs into this element's shadow. Both start at once — the css is the
|
|
19
19
|
part that shows, it must not wait for a module. Defaults follow the category: an el has
|
|
20
|
-
both, a class is css only, an attr is js only — `u2-skin` is
|
|
21
|
-
stays an attr because it carries a value: useAttr('skin', {css:true}). */
|
|
20
|
+
both, a class is css only, an attr is js only — `u2-skin` is css and nothing else, and it
|
|
21
|
+
stays an attr because it carries a value: useAttr('skin', {css:true, js:false}). */
|
|
22
22
|
function use(el, category, name, {css = category !== 'attr', js = category !== 'class'} = {}) {
|
|
23
23
|
const path = `${base}${category}/${name}/${name}`;
|
|
24
24
|
const warn = err => console.warn('u2: could not load', category + '/' + name, err);
|