editable.ts 0.0.1
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/LICENSE +21 -0
- package/README.md +571 -0
- package/dist/editable.umd.cjs +2 -0
- package/dist/editable.umd.cjs.map +1 -0
- package/lib/block.d.ts +13 -0
- package/lib/block.d.ts.map +1 -0
- package/lib/block.js +58 -0
- package/lib/block.js.map +1 -0
- package/lib/clipboard.d.ts +22 -0
- package/lib/clipboard.d.ts.map +1 -0
- package/lib/clipboard.js +154 -0
- package/lib/clipboard.js.map +1 -0
- package/lib/config.d.ts +37 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +64 -0
- package/lib/config.js.map +1 -0
- package/lib/content.d.ts +37 -0
- package/lib/content.d.ts.map +1 -0
- package/lib/content.js +526 -0
- package/lib/content.js.map +1 -0
- package/lib/core.d.ts +97 -0
- package/lib/core.d.ts.map +1 -0
- package/lib/core.js +261 -0
- package/lib/core.js.map +1 -0
- package/lib/create-default-behavior.d.ts +31 -0
- package/lib/create-default-behavior.d.ts.map +1 -0
- package/lib/create-default-behavior.js +178 -0
- package/lib/create-default-behavior.js.map +1 -0
- package/lib/create-default-events.d.ts +152 -0
- package/lib/create-default-events.d.ts.map +1 -0
- package/lib/create-default-events.js +183 -0
- package/lib/create-default-events.js.map +1 -0
- package/lib/cursor.d.ts +68 -0
- package/lib/cursor.d.ts.map +1 -0
- package/lib/cursor.js +354 -0
- package/lib/cursor.js.map +1 -0
- package/lib/dispatcher.d.ts +78 -0
- package/lib/dispatcher.d.ts.map +1 -0
- package/lib/dispatcher.js +416 -0
- package/lib/dispatcher.js.map +1 -0
- package/lib/eventable.d.ts +2 -0
- package/lib/eventable.d.ts.map +1 -0
- package/lib/eventable.js +104 -0
- package/lib/eventable.js.map +1 -0
- package/lib/feature-detection.d.ts +12 -0
- package/lib/feature-detection.d.ts.map +1 -0
- package/lib/feature-detection.js +42 -0
- package/lib/feature-detection.js.map +1 -0
- package/lib/highlight-support.d.ts +24 -0
- package/lib/highlight-support.d.ts.map +1 -0
- package/lib/highlight-support.js +172 -0
- package/lib/highlight-support.js.map +1 -0
- package/lib/highlight-text.d.ts +21 -0
- package/lib/highlight-text.d.ts.map +1 -0
- package/lib/highlight-text.js +147 -0
- package/lib/highlight-text.js.map +1 -0
- package/lib/keyboard.d.ts +33 -0
- package/lib/keyboard.d.ts.map +1 -0
- package/lib/keyboard.js +189 -0
- package/lib/keyboard.js.map +1 -0
- package/lib/monitored-highlighting.d.ts +28 -0
- package/lib/monitored-highlighting.d.ts.map +1 -0
- package/lib/monitored-highlighting.js +194 -0
- package/lib/monitored-highlighting.js.map +1 -0
- package/lib/node-iterator.d.ts +16 -0
- package/lib/node-iterator.d.ts.map +1 -0
- package/lib/node-iterator.js +97 -0
- package/lib/node-iterator.js.map +1 -0
- package/lib/node-type.d.ts +13 -0
- package/lib/node-type.d.ts.map +1 -0
- package/lib/node-type.js +15 -0
- package/lib/node-type.js.map +1 -0
- package/lib/parser.d.ts +89 -0
- package/lib/parser.d.ts.map +1 -0
- package/lib/parser.js +251 -0
- package/lib/parser.js.map +1 -0
- package/lib/plugins/highlighting/match-collection.d.ts +7 -0
- package/lib/plugins/highlighting/match-collection.d.ts.map +1 -0
- package/lib/plugins/highlighting/match-collection.js +62 -0
- package/lib/plugins/highlighting/match-collection.js.map +1 -0
- package/lib/plugins/highlighting/spellcheck-service.d.ts +12 -0
- package/lib/plugins/highlighting/spellcheck-service.d.ts.map +1 -0
- package/lib/plugins/highlighting/spellcheck-service.js +24 -0
- package/lib/plugins/highlighting/spellcheck-service.js.map +1 -0
- package/lib/plugins/highlighting/text-search.d.ts +10 -0
- package/lib/plugins/highlighting/text-search.d.ts.map +1 -0
- package/lib/plugins/highlighting/text-search.js +92 -0
- package/lib/plugins/highlighting/text-search.js.map +1 -0
- package/lib/plugins/highlighting/whitespace-highlighting.d.ts +14 -0
- package/lib/plugins/highlighting/whitespace-highlighting.d.ts.map +1 -0
- package/lib/plugins/highlighting/whitespace-highlighting.js +52 -0
- package/lib/plugins/highlighting/whitespace-highlighting.js.map +1 -0
- package/lib/quotes.d.ts +8 -0
- package/lib/quotes.d.ts.map +1 -0
- package/lib/quotes.js +170 -0
- package/lib/quotes.js.map +1 -0
- package/lib/range-container.d.ts +22 -0
- package/lib/range-container.d.ts.map +1 -0
- package/lib/range-container.js +52 -0
- package/lib/range-container.js.map +1 -0
- package/lib/range-save-restore.d.ts +13 -0
- package/lib/range-save-restore.d.ts.map +1 -0
- package/lib/range-save-restore.js +153 -0
- package/lib/range-save-restore.js.map +1 -0
- package/lib/selection-watcher.d.ts +55 -0
- package/lib/selection-watcher.d.ts.map +1 -0
- package/lib/selection-watcher.js +126 -0
- package/lib/selection-watcher.js.map +1 -0
- package/lib/selection.d.ts +74 -0
- package/lib/selection.d.ts.map +1 -0
- package/lib/selection.js +341 -0
- package/lib/selection.js.map +1 -0
- package/lib/smartQuotes.d.ts +16 -0
- package/lib/smartQuotes.d.ts.map +1 -0
- package/lib/smartQuotes.js +92 -0
- package/lib/smartQuotes.js.map +1 -0
- package/lib/util/binary_search.d.ts +23 -0
- package/lib/util/binary_search.d.ts.map +1 -0
- package/lib/util/binary_search.js +137 -0
- package/lib/util/binary_search.js.map +1 -0
- package/lib/util/clone-deep.d.ts +8 -0
- package/lib/util/clone-deep.d.ts.map +1 -0
- package/lib/util/clone-deep.js +10 -0
- package/lib/util/clone-deep.js.map +1 -0
- package/lib/util/dom.d.ts +43 -0
- package/lib/util/dom.d.ts.map +1 -0
- package/lib/util/dom.js +272 -0
- package/lib/util/dom.js.map +1 -0
- package/lib/util/element.d.ts +10 -0
- package/lib/util/element.d.ts.map +1 -0
- package/lib/util/element.js +29 -0
- package/lib/util/element.js.map +1 -0
- package/lib/util/error.d.ts +2 -0
- package/lib/util/error.d.ts.map +1 -0
- package/lib/util/error.js +16 -0
- package/lib/util/error.js.map +1 -0
- package/lib/util/log.d.ts +2 -0
- package/lib/util/log.d.ts.map +1 -0
- package/lib/util/log.js +18 -0
- package/lib/util/log.js.map +1 -0
- package/lib/util/merge.d.ts +6 -0
- package/lib/util/merge.d.ts.map +1 -0
- package/lib/util/merge.js +31 -0
- package/lib/util/merge.js.map +1 -0
- package/lib/util/string.d.ts +25 -0
- package/lib/util/string.d.ts.map +1 -0
- package/lib/util/string.js +68 -0
- package/lib/util/string.js.map +1 -0
- package/lib/util/viewport.d.ts +6 -0
- package/lib/util/viewport.d.ts.map +1 -0
- package/lib/util/viewport.js +8 -0
- package/lib/util/viewport.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for contenteditable support
|
|
3
|
+
*
|
|
4
|
+
* (from Modernizr)
|
|
5
|
+
* this is known to false positive in some mobile browsers
|
|
6
|
+
* here is a whitelist of verified working browsers:
|
|
7
|
+
* https://github.com/NielsLeenheer/html5test/blob/549f6eac866aa861d9649a0707ff2c0157895706/scripts/engine.js#L2083
|
|
8
|
+
*/
|
|
9
|
+
export const contenteditable = typeof document.documentElement.contentEditable !== 'undefined';
|
|
10
|
+
// Detect webkit browser engine
|
|
11
|
+
// That way we can detect the contenteditable span bug on safari, but exclude chrome
|
|
12
|
+
// Regex taken from: https://github.com/lancedikson/bowser/blob/f09411489ced05811c91cc6670a8e4ca9cbe39a7/src/parser-engines.js#L93-L106
|
|
13
|
+
// Attention, this might be error prone as any engine version change breaks this.
|
|
14
|
+
const isBlink = /(apple)?webkit\/537\.36/i.test(window.navigator.userAgent);
|
|
15
|
+
const isWebkit = /(apple)?webkit/i.test(window.navigator.userAgent);
|
|
16
|
+
const webKit = !isBlink && isWebkit;
|
|
17
|
+
/**
|
|
18
|
+
* Check selectionchange event (supported in IE, Chrome, Firefox and Safari)
|
|
19
|
+
* Firefox supports it since version 52 (2017).
|
|
20
|
+
* Opera has no support as of 2021.
|
|
21
|
+
*/
|
|
22
|
+
const hasNativeSelectionchangeSupport = (document) => {
|
|
23
|
+
const doc = document;
|
|
24
|
+
const osc = doc.onselectionchange;
|
|
25
|
+
if (osc !== undefined) {
|
|
26
|
+
try {
|
|
27
|
+
doc.onselectionchange = 0;
|
|
28
|
+
return doc.onselectionchange === null;
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
// ignore
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
doc.onselectionchange = osc;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
};
|
|
39
|
+
export const selectionchange = hasNativeSelectionchangeSupport(document);
|
|
40
|
+
// See Keyboard.prototype.preventContenteditableBug for more information.
|
|
41
|
+
export const contenteditableSpanBug = !!webKit;
|
|
42
|
+
//# sourceMappingURL=feature-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-detection.js","sourceRoot":"","sources":["../src/feature-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;EAOE;AACF,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,QAAQ,CAAC,eAAe,CAAC,eAAe,KAAK,WAAW,CAAA;AAE9F,+BAA+B;AAC/B,oFAAoF;AACpF,uIAAuI;AACvI,iFAAiF;AACjF,MAAM,OAAO,GAAG,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;AAC3E,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;AACnE,MAAM,MAAM,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAA;AAEnC;;;;GAIG;AACH,MAAM,+BAA+B,GAAG,CAAC,QAAkB,EAAW,EAAE;IACtE,MAAM,GAAG,GAAG,QAAQ,CAAA;IACpB,MAAM,GAAG,GAAI,GAAW,CAAC,iBAAiB,CAAA;IAC1C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC;YACF,GAAW,CAAC,iBAAiB,GAAG,CAAC,CAAA;YAClC,OAAQ,GAAW,CAAC,iBAAiB,KAAK,IAAI,CAAA;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS;QACX,CAAC;gBAAS,CAAC;YACR,GAAW,CAAC,iBAAiB,GAAG,GAAG,CAAA;QACtC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAC,QAAQ,CAAC,CAAA;AAExE,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type Dispatcher from './dispatcher.js';
|
|
2
|
+
declare const highlightSupport: {
|
|
3
|
+
highlightText(editableHost: HTMLElement, text: string, highlightId: string, type: string, dispatcher: Dispatcher | undefined, win?: Window): number | undefined;
|
|
4
|
+
highlightRange(editableHost: HTMLElement, text: string, highlightId: string, startIndex: number, endIndex: number, dispatcher: Dispatcher | undefined, win?: Window, type?: string): number;
|
|
5
|
+
updateHighlight(editableHost: HTMLElement, highlightId: string, addCssClass?: string, removeCssClass?: string): void;
|
|
6
|
+
removeHighlight(editableHost: HTMLElement, highlightId: string, dispatcher?: Dispatcher): void;
|
|
7
|
+
hasHighlight(editableHost: HTMLElement, highlightId: string): boolean;
|
|
8
|
+
extractHighlightedRanges(editableHost: HTMLElement, type?: string): Record<string, {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
text: string;
|
|
12
|
+
nativeRange: Range;
|
|
13
|
+
}> | undefined;
|
|
14
|
+
extractMarkerNodePosition(editableHost: HTMLElement, markers: NodeListOf<Element>): {
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
text: string;
|
|
18
|
+
nativeRange: Range;
|
|
19
|
+
} | undefined;
|
|
20
|
+
cleanupStaleMarkerNodes(editableHost: HTMLElement, highlightType: string): void;
|
|
21
|
+
createMarkerNode(markerMarkup: string, highlightType: string, win?: Window): HTMLElement | null;
|
|
22
|
+
};
|
|
23
|
+
export default highlightSupport;
|
|
24
|
+
//# sourceMappingURL=highlight-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight-support.d.ts","sourceRoot":"","sources":["../src/highlight-support.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAM7C,QAAA,MAAM,gBAAgB;gCAIS,WAAW,QAAQ,MAAM,eAAe,MAAM,QAAQ,MAAM,cAAc,UAAU,GAAG,SAAS,QAAQ,MAAM,GAAG,MAAM,GAAG,SAAS;iCAuClI,WAAW,QAAQ,MAAM,eAAe,MAAM,cAAc,MAAM,YAAY,MAAM,cAAc,UAAU,GAAG,SAAS,QAAQ,MAAM,SAAQ,MAAM,GAAe,MAAM;kCA2CxK,WAAW,eAAe,MAAM,gBAAgB,MAAM,mBAAmB,MAAM,GAAG,IAAI;kCAUtF,WAAW,eAAe,MAAM,eAAe,UAAU,GAAG,IAAI;+BAYnE,WAAW,eAAe,MAAM,GAAG,OAAO;2CAK9B,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAC,CAAC,GAAG,SAAS;4CAuBtH,WAAW,WAAW,UAAU,CAAC,OAAO,CAAC,GAAG;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAC,GAAG,SAAS;0CAoBxH,WAAW,iBAAiB,MAAM,GAAG,IAAI;mCAShD,MAAM,iBAAiB,MAAM,QAAQ,MAAM,GAAG,WAAW,GAAG,IAAI;CAejG,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as content from './content.js';
|
|
2
|
+
import highlightText from './highlight-text.js';
|
|
3
|
+
import { searchText } from './plugins/highlighting/text-search.js';
|
|
4
|
+
import { createElement, createRange, toCharacterRange } from './util/dom.js';
|
|
5
|
+
const highlightSupport = {
|
|
6
|
+
// Used to highlight arbitrary text in an editable. All occurrences
|
|
7
|
+
// will be highlighted.
|
|
8
|
+
highlightText(editableHost, text, highlightId, type, dispatcher, win) {
|
|
9
|
+
if (this.hasHighlight(editableHost, highlightId))
|
|
10
|
+
return;
|
|
11
|
+
const blockText = highlightText.extractText(editableHost);
|
|
12
|
+
const marker = `<span class="highlight-${type}"></span>`;
|
|
13
|
+
let winWindow = win;
|
|
14
|
+
if (!winWindow) {
|
|
15
|
+
const doc = editableHost.ownerDocument || (typeof document !== 'undefined' ? document : null);
|
|
16
|
+
winWindow = doc?.defaultView || undefined;
|
|
17
|
+
}
|
|
18
|
+
if (!winWindow) {
|
|
19
|
+
winWindow = (typeof window !== 'undefined' && window.document ? window : undefined);
|
|
20
|
+
}
|
|
21
|
+
if (!winWindow) {
|
|
22
|
+
throw new Error('Could not determine window object for highlightText');
|
|
23
|
+
}
|
|
24
|
+
const markerNode = highlightSupport.createMarkerNode(marker, type, winWindow);
|
|
25
|
+
if (!markerNode)
|
|
26
|
+
return undefined;
|
|
27
|
+
const matches = searchText(blockText, text, markerNode);
|
|
28
|
+
if (matches && matches.length) {
|
|
29
|
+
const match = matches[0];
|
|
30
|
+
if (highlightId)
|
|
31
|
+
match.id = highlightId;
|
|
32
|
+
highlightText.highlightMatches(editableHost, matches);
|
|
33
|
+
if (dispatcher)
|
|
34
|
+
dispatcher.notify('change', editableHost);
|
|
35
|
+
return match.startIndex;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
},
|
|
39
|
+
// Used to highlight comments.
|
|
40
|
+
// This function was changed to track matches when text is added to the start
|
|
41
|
+
// of a component, but multiple white spaces break it in a strict sense
|
|
42
|
+
// The function works in the editor and in browsers, but tests with
|
|
43
|
+
// multiple white spaces will fail.
|
|
44
|
+
// Browsers change the white spaces to   and the function works,
|
|
45
|
+
// and the tests in highlight.spec.js have been updated to represent this.
|
|
46
|
+
highlightRange(editableHost, text, highlightId, startIndex, endIndex, dispatcher, win, type = 'comment') {
|
|
47
|
+
if (this.hasHighlight(editableHost, highlightId)) {
|
|
48
|
+
this.removeHighlight(editableHost, highlightId, dispatcher);
|
|
49
|
+
}
|
|
50
|
+
const blockText = highlightText.extractText(editableHost, false);
|
|
51
|
+
if (blockText === '')
|
|
52
|
+
return -1; // the text was deleted so we can't highlight anything
|
|
53
|
+
let winWindow = win;
|
|
54
|
+
if (!winWindow) {
|
|
55
|
+
const doc = editableHost.ownerDocument || (typeof document !== 'undefined' ? document : null);
|
|
56
|
+
winWindow = doc?.defaultView || undefined;
|
|
57
|
+
}
|
|
58
|
+
if (!winWindow) {
|
|
59
|
+
winWindow = (typeof window !== 'undefined' && window.document ? window : undefined);
|
|
60
|
+
}
|
|
61
|
+
if (!winWindow) {
|
|
62
|
+
throw new Error('Could not determine window object for highlightRange');
|
|
63
|
+
}
|
|
64
|
+
const marker = this.createMarkerNode(`<span class="highlight-${type}"></span>`, type, winWindow);
|
|
65
|
+
if (!marker)
|
|
66
|
+
return -1;
|
|
67
|
+
const actualStartIndex = startIndex;
|
|
68
|
+
const actualEndIndex = endIndex;
|
|
69
|
+
highlightText.highlightMatches(editableHost, [{
|
|
70
|
+
startIndex: actualStartIndex,
|
|
71
|
+
endIndex: actualEndIndex,
|
|
72
|
+
match: text.substring(actualStartIndex, actualEndIndex),
|
|
73
|
+
id: highlightId,
|
|
74
|
+
marker
|
|
75
|
+
}], false);
|
|
76
|
+
if (dispatcher)
|
|
77
|
+
dispatcher.notify('change', editableHost);
|
|
78
|
+
return actualStartIndex;
|
|
79
|
+
},
|
|
80
|
+
updateHighlight(editableHost, highlightId, addCssClass, removeCssClass) {
|
|
81
|
+
if (!document.documentElement.classList)
|
|
82
|
+
return;
|
|
83
|
+
const elems = editableHost.querySelectorAll(`[data-word-id="${highlightId}"]`);
|
|
84
|
+
for (const elem of Array.from(elems)) {
|
|
85
|
+
if (removeCssClass)
|
|
86
|
+
elem.classList.remove(removeCssClass);
|
|
87
|
+
if (addCssClass)
|
|
88
|
+
elem.classList.add(addCssClass);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
removeHighlight(editableHost, highlightId, dispatcher) {
|
|
92
|
+
const elems = editableHost.querySelectorAll(`[data-word-id="${highlightId}"]`);
|
|
93
|
+
for (const elem of Array.from(elems)) {
|
|
94
|
+
content.unwrap(elem);
|
|
95
|
+
}
|
|
96
|
+
// remove empty text nodes, combine adjacent text nodes
|
|
97
|
+
editableHost.normalize();
|
|
98
|
+
if (dispatcher)
|
|
99
|
+
dispatcher.notify('change', editableHost);
|
|
100
|
+
},
|
|
101
|
+
hasHighlight(editableHost, highlightId) {
|
|
102
|
+
const matches = editableHost.querySelectorAll(`[data-word-id="${highlightId}"]`);
|
|
103
|
+
return !!matches.length;
|
|
104
|
+
},
|
|
105
|
+
extractHighlightedRanges(editableHost, type) {
|
|
106
|
+
let findMarkersQuery = '[data-word-id]';
|
|
107
|
+
if (type)
|
|
108
|
+
findMarkersQuery += `[data-highlight="${type}"]`;
|
|
109
|
+
const markers = editableHost.querySelectorAll(findMarkersQuery);
|
|
110
|
+
if (!markers.length)
|
|
111
|
+
return undefined;
|
|
112
|
+
const groups = {};
|
|
113
|
+
for (const marker of Array.from(markers)) {
|
|
114
|
+
const highlightId = marker.getAttribute('data-word-id');
|
|
115
|
+
if (highlightId && !groups[highlightId]) {
|
|
116
|
+
groups[highlightId] = editableHost.querySelectorAll(`[data-word-id="${highlightId}"]`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const res = {};
|
|
120
|
+
for (const highlightId in groups) {
|
|
121
|
+
const position = this.extractMarkerNodePosition(editableHost, groups[highlightId]);
|
|
122
|
+
if (position)
|
|
123
|
+
res[highlightId] = position;
|
|
124
|
+
}
|
|
125
|
+
return res;
|
|
126
|
+
},
|
|
127
|
+
extractMarkerNodePosition(editableHost, markers) {
|
|
128
|
+
if (markers.length === 0)
|
|
129
|
+
return undefined;
|
|
130
|
+
const range = createRange();
|
|
131
|
+
if (markers.length > 1) {
|
|
132
|
+
range.setStartBefore(markers[0]);
|
|
133
|
+
range.setEndAfter(markers[markers.length - 1]);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
range.selectNode(markers[0]);
|
|
137
|
+
}
|
|
138
|
+
const textRange = toCharacterRange(range, editableHost);
|
|
139
|
+
return {
|
|
140
|
+
start: textRange.start,
|
|
141
|
+
end: textRange.end,
|
|
142
|
+
text: textRange.text, // browser range result (does whitespace normalization)
|
|
143
|
+
nativeRange: range
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
cleanupStaleMarkerNodes(editableHost, highlightType) {
|
|
147
|
+
const nodes = editableHost.querySelectorAll(`span[data-highlight="${highlightType}"]`);
|
|
148
|
+
for (const node of Array.from(nodes)) {
|
|
149
|
+
if (!node.textContent || !node.textContent.length) {
|
|
150
|
+
node.remove();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
createMarkerNode(markerMarkup, highlightType, win) {
|
|
155
|
+
let winWindow = win || null;
|
|
156
|
+
if (!winWindow) {
|
|
157
|
+
// Try to get window from global scope
|
|
158
|
+
winWindow = (typeof window !== 'undefined' && window.document ? window : null);
|
|
159
|
+
}
|
|
160
|
+
if (!winWindow || !winWindow.document) {
|
|
161
|
+
throw new Error(`Window object with document is required. win: ${typeof win}, window: ${typeof window}`);
|
|
162
|
+
}
|
|
163
|
+
const marker = createElement(markerMarkup, winWindow);
|
|
164
|
+
if (!marker)
|
|
165
|
+
return null;
|
|
166
|
+
marker.setAttribute('data-editable', 'ui-unwrap');
|
|
167
|
+
marker.setAttribute('data-highlight', highlightType);
|
|
168
|
+
return marker;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
export default highlightSupport;
|
|
172
|
+
//# sourceMappingURL=highlight-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight-support.js","sourceRoot":"","sources":["../src/highlight-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Match } from './plugins/highlighting/text-search.js';
|
|
2
|
+
interface ExtendedMatch extends Match {
|
|
3
|
+
id?: string | number;
|
|
4
|
+
title?: string;
|
|
5
|
+
}
|
|
6
|
+
interface Portion {
|
|
7
|
+
element: Text;
|
|
8
|
+
text: string;
|
|
9
|
+
offset: number;
|
|
10
|
+
length: number;
|
|
11
|
+
isLastPortion: boolean;
|
|
12
|
+
wordId: string | number;
|
|
13
|
+
}
|
|
14
|
+
declare const _default: {
|
|
15
|
+
extractText(element: HTMLElement, convertBRs?: boolean): string;
|
|
16
|
+
highlightMatches(element: HTMLElement, matches: ExtendedMatch[], countBRs?: boolean): void;
|
|
17
|
+
wrapMatch(portions: Portion[], stencilElement: HTMLElement, title?: string): HTMLElement | undefined;
|
|
18
|
+
wrapPortion(portion: Portion, stencilElement: HTMLElement, title?: string): HTMLElement;
|
|
19
|
+
};
|
|
20
|
+
export default _default;
|
|
21
|
+
//# sourceMappingURL=highlight-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight-text.d.ts","sourceRoot":"","sources":["../src/highlight-text.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,uCAAuC,CAAA;AAEhE,UAAU,aAAc,SAAQ,KAAK;IACnC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,UAAU,OAAO;IACf,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CACxB;;yBAOuB,WAAW,eAAc,OAAO,GAAU,MAAM;8BAqB3C,WAAW,WAAW,aAAa,EAAE,aAAY,OAAO,GAAU,IAAI;wBAwF5E,OAAO,EAAE,kBAAkB,WAAW,UAAU,MAAM,GAAG,WAAW,GAAG,SAAS;yBAI/E,OAAO,kBAAkB,WAAW,UAAU,MAAM,GAAG,WAAW;;AAtH1F,wBA0IC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import NodeIterator from './node-iterator.js';
|
|
2
|
+
import * as nodeType from './node-type.js';
|
|
3
|
+
import { createRange } from './util/dom.js';
|
|
4
|
+
export default {
|
|
5
|
+
// Get the text from an editable block with a NodeIterator.
|
|
6
|
+
// This must work the same as when later iterating over the text
|
|
7
|
+
// in highlightMatches().
|
|
8
|
+
extractText(element, convertBRs = true) {
|
|
9
|
+
let text = '';
|
|
10
|
+
getText(element, convertBRs, (part) => { text += part; });
|
|
11
|
+
return text;
|
|
12
|
+
},
|
|
13
|
+
// Go through the element to highlight the matches while keeping the
|
|
14
|
+
// existing html valid (highlighting a match may require inserting multiple
|
|
15
|
+
// elements).
|
|
16
|
+
//
|
|
17
|
+
// @params
|
|
18
|
+
// - matches
|
|
19
|
+
// Array of positions in the string to highlight:
|
|
20
|
+
// e.g [{
|
|
21
|
+
// startIndex: 0,
|
|
22
|
+
// endIndex: 1,
|
|
23
|
+
// match: 'The', // not used, only the indexes are used for highlighting)
|
|
24
|
+
// marker: DOMNode, // A clone of this element will be inserted
|
|
25
|
+
// id: 'a7382', // used in word-id attribute
|
|
26
|
+
// title: 'The World' // used in title attribute (optional)
|
|
27
|
+
// }]
|
|
28
|
+
highlightMatches(element, matches, countBRs = true) {
|
|
29
|
+
if (!matches || matches.length === 0) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
element.normalize(); // mend text nodes
|
|
33
|
+
const iterator = new NodeIterator(element);
|
|
34
|
+
let currentMatchIndex = 0;
|
|
35
|
+
let totalOffset = 0;
|
|
36
|
+
let currentMatch = matches[currentMatchIndex];
|
|
37
|
+
let portions = [];
|
|
38
|
+
let next;
|
|
39
|
+
let wordId = currentMatch.id || currentMatch.startIndex;
|
|
40
|
+
let textNode;
|
|
41
|
+
while ((next = iterator.getNext())) {
|
|
42
|
+
// Account for <br> elements
|
|
43
|
+
if (next.nodeType === nodeType.textNode && next.data !== '') {
|
|
44
|
+
textNode = next;
|
|
45
|
+
}
|
|
46
|
+
else if (countBRs && next.nodeType === nodeType.elementNode && next.nodeName === 'BR') {
|
|
47
|
+
totalOffset += 1;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (!textNode)
|
|
54
|
+
continue;
|
|
55
|
+
const nodeText = textNode.data;
|
|
56
|
+
let nodeEndOffset = totalOffset + nodeText.length;
|
|
57
|
+
if (currentMatch.startIndex < nodeEndOffset && totalOffset < currentMatch.endIndex) {
|
|
58
|
+
// get portion position (fist, last or in the middle)
|
|
59
|
+
const isFirstPortion = totalOffset <= currentMatch.startIndex;
|
|
60
|
+
const isLastPortion = nodeEndOffset >= currentMatch.endIndex;
|
|
61
|
+
if (isFirstPortion) {
|
|
62
|
+
wordId = currentMatch.id || currentMatch.startIndex;
|
|
63
|
+
}
|
|
64
|
+
// calculate offset and length
|
|
65
|
+
let offset;
|
|
66
|
+
if (isFirstPortion) {
|
|
67
|
+
offset = currentMatch.startIndex - totalOffset;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
offset = 0;
|
|
71
|
+
}
|
|
72
|
+
let length;
|
|
73
|
+
if (isLastPortion) {
|
|
74
|
+
length = (currentMatch.endIndex - totalOffset) - offset;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
length = nodeText.length - offset;
|
|
78
|
+
}
|
|
79
|
+
// create portion object
|
|
80
|
+
const portion = {
|
|
81
|
+
element: textNode,
|
|
82
|
+
text: nodeText.substring(offset, offset + length),
|
|
83
|
+
offset,
|
|
84
|
+
length,
|
|
85
|
+
isLastPortion,
|
|
86
|
+
wordId
|
|
87
|
+
};
|
|
88
|
+
portions.push(portion);
|
|
89
|
+
if (isLastPortion) {
|
|
90
|
+
const lastNode = this.wrapMatch(portions, currentMatch.marker, currentMatch.title);
|
|
91
|
+
if (lastNode) {
|
|
92
|
+
iterator.replaceCurrent(lastNode);
|
|
93
|
+
// recalculate nodeEndOffset if we have to replace the current node.
|
|
94
|
+
nodeEndOffset = totalOffset + portion.length + portion.offset;
|
|
95
|
+
portions = [];
|
|
96
|
+
currentMatchIndex += 1;
|
|
97
|
+
if (currentMatchIndex < matches.length) {
|
|
98
|
+
currentMatch = matches[currentMatchIndex];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
totalOffset = nodeEndOffset;
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
// @return the last wrapped element
|
|
107
|
+
wrapMatch(portions, stencilElement, title) {
|
|
108
|
+
return portions.map((portion) => this.wrapPortion(portion, stencilElement, title)).pop();
|
|
109
|
+
},
|
|
110
|
+
wrapPortion(portion, stencilElement, title) {
|
|
111
|
+
const range = createRange();
|
|
112
|
+
range.setStart(portion.element, portion.offset);
|
|
113
|
+
range.setEnd(portion.element, portion.offset + portion.length);
|
|
114
|
+
const node = stencilElement.cloneNode(true);
|
|
115
|
+
node.setAttribute('data-word-id', String(portion.wordId));
|
|
116
|
+
if (title)
|
|
117
|
+
node.setAttribute('title', title);
|
|
118
|
+
range.surroundContents(node);
|
|
119
|
+
// Fix a weird behaviour where an empty text node is inserted after the range
|
|
120
|
+
if (node.nextSibling) {
|
|
121
|
+
const next = node.nextSibling;
|
|
122
|
+
if (next.nodeType === nodeType.textNode && next.data === '') {
|
|
123
|
+
next.remove();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return node;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
// Extract the text of an element.
|
|
130
|
+
// This has two notable behaviours:
|
|
131
|
+
// - It uses a NodeIterator which will skip elements
|
|
132
|
+
// with data-editable="remove"
|
|
133
|
+
// - It returns a \n for <br> elements
|
|
134
|
+
// (The only block level element allowed inside of editables)
|
|
135
|
+
function getText(element, convertBRs, func) {
|
|
136
|
+
const iterator = new NodeIterator(element);
|
|
137
|
+
let next;
|
|
138
|
+
while ((next = iterator.getNext())) {
|
|
139
|
+
if (next.nodeType === nodeType.textNode && next.data !== '') {
|
|
140
|
+
func(next.data);
|
|
141
|
+
}
|
|
142
|
+
else if (convertBRs && next.nodeType === nodeType.elementNode && next.nodeName === 'BR') {
|
|
143
|
+
func('\n');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=highlight-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight-text.js","sourceRoot":"","sources":["../src/highlight-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type SelectionWatcher from './selection-watcher.js';
|
|
2
|
+
interface KeyCodes {
|
|
3
|
+
left: number;
|
|
4
|
+
up: number;
|
|
5
|
+
right: number;
|
|
6
|
+
down: number;
|
|
7
|
+
tab: number;
|
|
8
|
+
esc: number;
|
|
9
|
+
backspace: number;
|
|
10
|
+
delete: number;
|
|
11
|
+
enter: number;
|
|
12
|
+
shift: number;
|
|
13
|
+
ctrl: number;
|
|
14
|
+
alt: number;
|
|
15
|
+
b: number;
|
|
16
|
+
i: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The Keyboard module defines an event API for key events.
|
|
20
|
+
*/
|
|
21
|
+
export default class Keyboard {
|
|
22
|
+
key: KeyCodes;
|
|
23
|
+
notify: (event: string, ...args: any[]) => void;
|
|
24
|
+
on: ((event: string, handler: (...args: any[]) => any) => this) & ((events: Record<string, (...args: any[]) => any>) => this);
|
|
25
|
+
off: (...args: any[]) => void;
|
|
26
|
+
selectionWatcher: SelectionWatcher;
|
|
27
|
+
constructor(selectionWatcher: SelectionWatcher);
|
|
28
|
+
dispatchKeyEvent(event: KeyboardEvent, target: any, notifyCharacterEvent?: boolean): void;
|
|
29
|
+
preventContenteditableBug(target: HTMLElement, event: KeyboardEvent): void;
|
|
30
|
+
static getNodeToRemove(selectionRange: Range, target: HTMLElement): Element | undefined;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../src/keyboard.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAA;AAE1D,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED;;GAEG;AAEH,MAAM,CAAC,OAAO,OAAO,QAAQ;IACpB,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,EAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAChD,EAAE,EAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAA;IAC9H,GAAG,EAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC9B,gBAAgB,EAAE,gBAAgB,CAAA;gBAE5B,gBAAgB,EAAE,gBAAgB;IAM/C,gBAAgB,CAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI;IAgE1F,yBAAyB,CAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IA+C3E,MAAM,CAAC,eAAe,CAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,GAAG,SAAS;CA8DzF"}
|