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.
Files changed (142) hide show
  1. package/el/ico/ico.js +5 -5
  2. package/el/rte/README.md +53 -13
  3. package/el/rte/manifest.json +19 -4
  4. package/el/rte/rte.css +31 -6
  5. package/el/rte/rte.js +174 -44
  6. package/el/rte0/README.md +37 -0
  7. package/el/rte0/manifest.json +33 -0
  8. package/el/rte0/rte0.css +9 -0
  9. package/el/rte0/rte0.js +56 -0
  10. package/el/system/styler.js +2 -0
  11. package/el/tooltip/tooltip.css +2 -2
  12. package/js/Placer/Placer.js +2 -1
  13. package/js/rte/AGENTS.md +142 -0
  14. package/js/rte/PLAN.md +488 -0
  15. package/js/rte/README.md +319 -25
  16. package/js/rte/blocks.js +7 -0
  17. package/js/rte/breaks.js +6 -0
  18. package/js/rte/classes.js +7 -0
  19. package/js/rte/docs/usage.md +845 -0
  20. package/js/rte/images.js +7 -0
  21. package/js/rte/link.js +8 -0
  22. package/js/rte/playground/README.md +95 -0
  23. package/js/rte/playground/hosts.html +518 -0
  24. package/js/rte/playground/index.html +824 -0
  25. package/js/rte/rte.js +56 -5
  26. package/js/rte/source.js +12 -0
  27. package/js/rte/src/browser/README.md +40 -0
  28. package/js/rte/src/browser/range-rect.js +82 -0
  29. package/js/rte/src/client/README.md +378 -0
  30. package/js/rte/src/client/blocks.js +38 -0
  31. package/js/rte/src/client/breaks.js +212 -0
  32. package/js/rte/src/client/classes.js +48 -0
  33. package/js/rte/src/client/editor.js +461 -0
  34. package/js/rte/src/client/external-input.js +47 -0
  35. package/js/rte/src/client/history.js +13 -0
  36. package/js/rte/src/client/images.js +275 -0
  37. package/js/rte/src/client/link.js +572 -0
  38. package/js/rte/src/client/marks.js +25 -0
  39. package/js/rte/src/client/source.js +182 -0
  40. package/js/rte/src/client/structure.js +27 -0
  41. package/js/rte/src/client/tables.js +162 -0
  42. package/js/rte/src/client/unstyle.js +32 -0
  43. package/js/rte/src/command/README.md +517 -0
  44. package/js/rte/src/command/block-boundary.js +43 -0
  45. package/js/rte/src/command/block-style.js +120 -0
  46. package/js/rte/src/command/commands.js +158 -0
  47. package/js/rte/src/command/delete.js +112 -0
  48. package/js/rte/src/command/edit.js +72 -0
  49. package/js/rte/src/command/element.js +45 -0
  50. package/js/rte/src/command/enter.js +175 -0
  51. package/js/rte/src/command/fragment.js +76 -0
  52. package/js/rte/src/command/insert.js +52 -0
  53. package/js/rte/src/command/list.js +284 -0
  54. package/js/rte/src/command/mark.js +583 -0
  55. package/js/rte/src/command/pending-marks.js +216 -0
  56. package/js/rte/src/command/table.js +207 -0
  57. package/js/rte/src/command/unstyle.js +248 -0
  58. package/js/rte/src/config/README.md +96 -0
  59. package/js/rte/src/config/config.js +127 -0
  60. package/js/rte/src/core/README.md +41 -0
  61. package/js/rte/src/core/core.js +156 -0
  62. package/js/rte/src/history/README.md +83 -0
  63. package/js/rte/src/history/history.js +283 -0
  64. package/js/rte/src/input/README.md +155 -0
  65. package/js/rte/src/input/external-input.js +130 -0
  66. package/js/rte/src/input/input-pipeline.js +414 -0
  67. package/js/rte/src/mark/README.md +219 -0
  68. package/js/rte/src/mark/dom-adapter.js +100 -0
  69. package/js/rte/src/mark/mark.js +133 -0
  70. package/js/rte/src/mark/standard.js +76 -0
  71. package/js/rte/src/model/README.md +71 -0
  72. package/js/rte/src/model/content-model.js +213 -0
  73. package/js/rte/src/model/html/README.md +51 -0
  74. package/js/rte/src/model/html/html-model.js +90 -0
  75. package/js/rte/src/normalize/execute/README.md +33 -0
  76. package/js/rte/src/normalize/execute/repair-executor.js +129 -0
  77. package/js/rte/src/normalize/normalizer/README.md +48 -0
  78. package/js/rte/src/normalize/normalizer/normalizer.js +141 -0
  79. package/js/rte/src/normalize/repair/README.md +70 -0
  80. package/js/rte/src/normalize/repair/repair-planner.js +208 -0
  81. package/js/rte/src/sanitize/README.md +105 -0
  82. package/js/rte/src/sanitize/native.js +43 -0
  83. package/js/rte/src/sanitize/policy.js +202 -0
  84. package/js/rte/src/selection/README.md +39 -0
  85. package/js/rte/src/selection/map/README.md +53 -0
  86. package/js/rte/src/selection/map/point-map.js +307 -0
  87. package/js/rte/src/selection/ownership/README.md +32 -0
  88. package/js/rte/src/selection/ownership/ownership.js +42 -0
  89. package/js/rte/src/selection/point/README.md +34 -0
  90. package/js/rte/src/selection/point/point.js +83 -0
  91. package/js/rte/src/selection/range/README.md +38 -0
  92. package/js/rte/src/selection/range/edit-range.js +223 -0
  93. package/js/rte/src/selection/snapshot.js +64 -0
  94. package/js/rte/src/source/README.md +64 -0
  95. package/js/rte/src/source/source.js +193 -0
  96. package/js/rte/src/surface/README.md +36 -0
  97. package/js/rte/src/surface/content.js +16 -0
  98. package/js/rte/src/surface/surface.js +87 -0
  99. package/js/rte/src/transaction/README.md +35 -0
  100. package/js/rte/src/transaction/transaction.js +56 -0
  101. package/js/rte/src/ui/README.md +255 -0
  102. package/js/rte/src/ui/chrome.js +214 -0
  103. package/js/rte/src/ui/handles.js +179 -0
  104. package/js/rte/src/ui/place.js +25 -0
  105. package/js/rte/src/ui/toolbar.js +283 -0
  106. package/js/rte/src/unstyle/README.md +103 -0
  107. package/js/rte/src/unstyle/unstyle.js +140 -0
  108. package/js/rte/tables.js +7 -0
  109. package/js/rte/unstyle.js +8 -0
  110. package/js/rte0/README.md +37 -0
  111. package/js/rte0/rte.js +7 -0
  112. package/js/{rte → rte0}/src/behavior.js +0 -1
  113. package/js/{rte → rte0}/src/events.js +0 -1
  114. package/js/{rte → rte0}/src/range.js +0 -2
  115. package/js/{rte → rte0}/src/ui.items.js +0 -2
  116. package/js/{rte → rte0}/src/ui.js +0 -1
  117. package/package.json +1 -1
  118. package/u2/Element.js +2 -2
  119. package/u2/plan-scoped-refactoring.md +133 -303
  120. package/u2/projects.json +18 -2
  121. package/u2/tools/update.repos.json.js +1 -1
  122. package/el/qrcode/package.json +0 -22
  123. /package/js/{rte → rte0}/old/NodeCleaner.js +0 -0
  124. /package/js/{rte → rte0}/old/Rte/Rte.mjs +0 -0
  125. /package/js/{rte → rte0}/old/Rte/Rte.ui.items.mjs +0 -0
  126. /package/js/{rte → rte0}/old/Rte/Rte.ui.mjs +0 -0
  127. /package/js/{rte → rte0}/old/Rte/crossbrowser.mjs +0 -0
  128. /package/js/{rte → rte0}/old/Rte/font/tinymce.svg +0 -0
  129. /package/js/{rte → rte0}/old/Rte/font/tinymce.woff +0 -0
  130. /package/js/{rte → rte0}/old/Rte/helpers.mjs +0 -0
  131. /package/js/{rte → rte0}/old/Rte/htmlparser.mjs +0 -0
  132. /package/js/{rte → rte0}/old/Rte/index.mjs +0 -0
  133. /package/js/{rte → rte0}/old/Rte/main.css +0 -0
  134. /package/js/{rte → rte0}/old/old.rte.js +0 -0
  135. /package/js/{rte → rte0}/old/range-selection.old.js +0 -0
  136. /package/js/{rte → rte0}/src/fixes.js +0 -0
  137. /package/js/{rte → rte0}/src/rte.js +0 -0
  138. /package/js/{rte → rte0}/src/ui/items/ai.js +0 -0
  139. /package/js/{rte → rte0}/src/ui/items/code.js +0 -0
  140. /package/js/{rte → rte0}/src/ui/items/undo.js +0 -0
  141. /package/js/{rte → rte0}/src/util/htmlparser.js +0 -0
  142. /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
+ }
@@ -0,0 +1,7 @@
1
+ import {editor} from './rte.js';
2
+ import {tables} from './src/client/tables.js';
3
+
4
+ export {tables, tableTools} from './src/client/tables.js';
5
+ export {Tables} from './src/command/table.js';
6
+
7
+ editor.add(tables);
@@ -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
@@ -0,0 +1,7 @@
1
+
2
+ import './src/fixes.js';
3
+ import './src/behavior.js';
4
+ import './src/rte.js';
5
+ import './src/ui.js';
6
+ import './src/ui.items.js';
7
+
@@ -1,4 +1,3 @@
1
-
2
1
  import './events.js';
3
2
  import {$range} from './range.js';
4
3
 
@@ -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
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  const selection = getSelection();
4
2
  const chainedFns = {setStart:1,setStartBefore:1,setStartAfter:1,setEnd:1,setEndAfter:1,selectNode:1,selectNodeContents:1,insertNode:1,collapse:1,deleteContents:1};
5
3
 
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  import {$range} from './range.js';
4
2
  import * as state from './events.js';
5
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  import {$range} from './range.js';
3
2
  import * as state from './events.js';
4
3
  import {Rte} from './rte.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u2ui",
3
- "version": "1.5.3",
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 the attr that styles, and it
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);