@plannotator/web-highlighter 0.8.0

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 (88) hide show
  1. package/.cursor/environment.json +6 -0
  2. package/.eslintrc.js +250 -0
  3. package/.prettierrc +9 -0
  4. package/.travis.yml +17 -0
  5. package/CHANGELOG.md +220 -0
  6. package/LICENSE +21 -0
  7. package/README.md +371 -0
  8. package/README.zh_CN.md +367 -0
  9. package/config/base.config.js +25 -0
  10. package/config/base.example.config.js +38 -0
  11. package/config/paths.js +22 -0
  12. package/config/server.config.js +17 -0
  13. package/config/webpack.config.dev.js +18 -0
  14. package/config/webpack.config.example.js +20 -0
  15. package/config/webpack.config.prod.js +28 -0
  16. package/dist/data/cache.d.ts +13 -0
  17. package/dist/index.d.ts +58 -0
  18. package/dist/model/range/dom.d.ts +6 -0
  19. package/dist/model/range/index.d.ts +20 -0
  20. package/dist/model/range/selection.d.ts +14 -0
  21. package/dist/model/source/dom.d.ts +23 -0
  22. package/dist/model/source/index.d.ts +18 -0
  23. package/dist/painter/dom.d.ts +22 -0
  24. package/dist/painter/index.d.ts +19 -0
  25. package/dist/painter/style.d.ts +1 -0
  26. package/dist/types/index.d.ts +102 -0
  27. package/dist/util/camel.d.ts +5 -0
  28. package/dist/util/const.d.ts +41 -0
  29. package/dist/util/deferred.d.ts +9 -0
  30. package/dist/util/dom.d.ts +32 -0
  31. package/dist/util/event.emitter.d.ts +13 -0
  32. package/dist/util/hook.d.ts +15 -0
  33. package/dist/util/interaction.d.ts +6 -0
  34. package/dist/util/is.mobile.d.ts +5 -0
  35. package/dist/util/tool.d.ts +4 -0
  36. package/dist/util/uuid.d.ts +4 -0
  37. package/dist/web-highlighter.min.js +3 -0
  38. package/dist/web-highlighter.min.js.map +1 -0
  39. package/docs/ADVANCE.md +113 -0
  40. package/docs/ADVANCE.zh_CN.md +111 -0
  41. package/docs/img/create-flow.jpg +0 -0
  42. package/docs/img/create-flow.zh_CN.jpg +0 -0
  43. package/docs/img/logo.png +0 -0
  44. package/docs/img/remove-flow.jpg +0 -0
  45. package/docs/img/remove-flow.zh_CN.jpg +0 -0
  46. package/docs/img/sample.gif +0 -0
  47. package/example/index.css +2 -0
  48. package/example/index.js +214 -0
  49. package/example/local.store.js +72 -0
  50. package/example/my.css +119 -0
  51. package/example/tpl.html +59 -0
  52. package/package.json +103 -0
  53. package/script/build.js +17 -0
  54. package/script/convet-md.js +25 -0
  55. package/script/dev.js +22 -0
  56. package/src/data/cache.ts +57 -0
  57. package/src/index.ts +285 -0
  58. package/src/model/range/dom.ts +94 -0
  59. package/src/model/range/index.ts +88 -0
  60. package/src/model/range/selection.ts +55 -0
  61. package/src/model/source/dom.ts +66 -0
  62. package/src/model/source/index.ts +54 -0
  63. package/src/painter/dom.ts +345 -0
  64. package/src/painter/index.ts +199 -0
  65. package/src/painter/style.ts +21 -0
  66. package/src/types/index.ts +118 -0
  67. package/src/util/camel.ts +6 -0
  68. package/src/util/const.ts +54 -0
  69. package/src/util/deferred.ts +37 -0
  70. package/src/util/dom.ts +155 -0
  71. package/src/util/event.emitter.ts +45 -0
  72. package/src/util/hook.ts +52 -0
  73. package/src/util/interaction.ts +20 -0
  74. package/src/util/is.mobile.ts +7 -0
  75. package/src/util/tool.ts +14 -0
  76. package/src/util/uuid.ts +10 -0
  77. package/test/api.spec.ts +555 -0
  78. package/test/event.spec.ts +284 -0
  79. package/test/fixtures/broken.json +32 -0
  80. package/test/fixtures/index.html +11 -0
  81. package/test/fixtures/source.json +47 -0
  82. package/test/hook.spec.ts +244 -0
  83. package/test/integrate.spec.ts +48 -0
  84. package/test/mobile.spec.ts +87 -0
  85. package/test/option.spec.ts +212 -0
  86. package/test/util.spec.ts +244 -0
  87. package/test-newlines.html +226 -0
  88. package/tsconfig.json +23 -0
@@ -0,0 +1,226 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>web-highlighter Newlines Test</title>
5
+ <style>
6
+ body {
7
+ font-family: system-ui, sans-serif;
8
+ max-width: 800px;
9
+ margin: 40px auto;
10
+ padding: 20px;
11
+ }
12
+ .test-content {
13
+ background: #f5f5f5;
14
+ padding: 20px;
15
+ border-radius: 8px;
16
+ margin-bottom: 20px;
17
+ }
18
+ .test-content p {
19
+ margin: 10px 0;
20
+ }
21
+ button {
22
+ padding: 10px 20px;
23
+ font-size: 16px;
24
+ cursor: pointer;
25
+ margin-right: 10px;
26
+ margin-bottom: 10px;
27
+ }
28
+ .results {
29
+ margin-top: 20px;
30
+ padding: 20px;
31
+ background: #e8f4e8;
32
+ border-radius: 8px;
33
+ }
34
+ .result-block {
35
+ margin: 15px 0;
36
+ padding: 10px;
37
+ background: white;
38
+ border-radius: 4px;
39
+ }
40
+ .result-block h4 {
41
+ margin: 0 0 10px 0;
42
+ color: #333;
43
+ }
44
+ pre {
45
+ background: #f0f0f0;
46
+ padding: 10px;
47
+ border-radius: 4px;
48
+ white-space: pre-wrap;
49
+ word-wrap: break-word;
50
+ }
51
+ .match { color: green; }
52
+ .no-match { color: red; }
53
+ .highlight-mengshou-wrap {
54
+ background-color: #ffeb3b;
55
+ }
56
+ </style>
57
+ </head>
58
+ <body>
59
+ <h1>web-highlighter Newlines Fix Test</h1>
60
+
61
+ <h2>Test 1: Compare APIs</h2>
62
+ <p><strong>Instructions:</strong> Select text across multiple paragraphs below, then click "Compare APIs".</p>
63
+
64
+ <div class="test-content" id="test-content">
65
+ <p>This is the first paragraph with some text.</p>
66
+ <p>This is the second paragraph with different text.</p>
67
+ <p>This is the third paragraph for good measure.</p>
68
+ </div>
69
+
70
+ <button onclick="compareApis()">Compare APIs</button>
71
+ <button onclick="clearResults()">Clear Results</button>
72
+
73
+ <h2>Test 2: web-highlighter Integration</h2>
74
+ <p><strong>Instructions:</strong> Select text across paragraphs below, then click "Highlight Selection". Check that source.text has newlines.</p>
75
+
76
+ <div class="test-content" id="highlighter-root">
77
+ <p>First paragraph for highlighting test.</p>
78
+ <p>Second paragraph for highlighting test.</p>
79
+ <p>Third paragraph for highlighting test.</p>
80
+ </div>
81
+
82
+ <button onclick="initHighlighter()">Initialize Highlighter</button>
83
+ <button onclick="highlightSelection()">Highlight Selection</button>
84
+ <button onclick="clearHighlights()">Clear All</button>
85
+
86
+ <div class="results" id="results" style="display: none;"></div>
87
+
88
+ <script src="./dist/web-highlighter.min.js"></script>
89
+ <script>
90
+ let highlighter = null;
91
+ let lastSource = null;
92
+
93
+ function compareApis() {
94
+ const selection = window.getSelection();
95
+
96
+ if (selection.isCollapsed || selection.rangeCount === 0) {
97
+ alert('Please select some text first (try selecting across multiple paragraphs)');
98
+ return;
99
+ }
100
+
101
+ const range = selection.getRangeAt(0);
102
+
103
+ const selectionText = selection.toString();
104
+ const rangeText = range.toString();
105
+
106
+ // Also test innerText approach
107
+ const fragment = range.cloneContents();
108
+ const temp = document.createElement('div');
109
+ temp.appendChild(fragment);
110
+ document.body.appendChild(temp);
111
+ const innerTextResult = temp.innerText;
112
+ temp.remove();
113
+
114
+ showResults(`
115
+ <h3>API Comparison Results</h3>
116
+
117
+ <div class="result-block">
118
+ <h4>Selection.toString() ${selectionText.includes('\\n') ? '(has newlines)' : '(NO newlines)'}</h4>
119
+ <pre>${escapeHtml(selectionText)}</pre>
120
+ <p>JSON: <code>${JSON.stringify(selectionText)}</code></p>
121
+ </div>
122
+
123
+ <div class="result-block">
124
+ <h4>Range.toString() ${rangeText.includes('\\n') ? '(has newlines)' : '(NO newlines)'}</h4>
125
+ <pre>${escapeHtml(rangeText)}</pre>
126
+ <p>JSON: <code>${JSON.stringify(rangeText)}</code></p>
127
+ </div>
128
+
129
+ <div class="result-block">
130
+ <h4>innerText (cloned) ${innerTextResult.includes('\\n') ? '(has newlines)' : '(NO newlines)'}</h4>
131
+ <pre>${escapeHtml(innerTextResult)}</pre>
132
+ <p>JSON: <code>${JSON.stringify(innerTextResult)}</code></p>
133
+ </div>
134
+
135
+ <div class="result-block">
136
+ <h4>Comparison</h4>
137
+ <p class="${selectionText === rangeText ? 'match' : 'no-match'}">
138
+ Selection === Range: <strong>${selectionText === rangeText ? 'YES' : 'NO (different!)'}</strong>
139
+ </p>
140
+ </div>
141
+ `);
142
+ }
143
+
144
+ function initHighlighter() {
145
+ if (highlighter) {
146
+ highlighter.dispose();
147
+ }
148
+
149
+ highlighter = new Highlighter({
150
+ $root: document.getElementById('highlighter-root'),
151
+ style: {
152
+ className: 'highlight-mengshou-wrap'
153
+ }
154
+ });
155
+
156
+ highlighter.on(Highlighter.event.CREATE, function(data) {
157
+ lastSource = data.sources[0];
158
+ const text = lastSource.text;
159
+ const hasNewlines = text.includes('\\n');
160
+
161
+ showResults(`
162
+ <h3>Highlight Created!</h3>
163
+
164
+ <div class="result-block">
165
+ <h4>source.text ${hasNewlines ? '(HAS NEWLINES - FIX WORKS!)' : '(no newlines)'}</h4>
166
+ <pre>${escapeHtml(text)}</pre>
167
+ <p>JSON: <code>${JSON.stringify(text)}</code></p>
168
+ <p>Length: ${text.length}</p>
169
+ </div>
170
+
171
+ <div class="result-block">
172
+ <h4>Full Source Object</h4>
173
+ <pre>${JSON.stringify(lastSource, null, 2)}</pre>
174
+ </div>
175
+
176
+ <div class="result-block ${hasNewlines ? 'match' : 'no-match'}">
177
+ <h4>Result</h4>
178
+ <p><strong>${hasNewlines ? 'SUCCESS: Newlines are preserved!' : 'ISSUE: No newlines found'}</strong></p>
179
+ </div>
180
+ `);
181
+ });
182
+
183
+ alert('Highlighter initialized! Now select text across paragraphs and click "Highlight Selection"');
184
+ }
185
+
186
+ function highlightSelection() {
187
+ if (!highlighter) {
188
+ alert('Please initialize the highlighter first');
189
+ return;
190
+ }
191
+
192
+ const selection = window.getSelection();
193
+ if (selection.isCollapsed) {
194
+ alert('Please select some text first');
195
+ return;
196
+ }
197
+
198
+ const range = selection.getRangeAt(0);
199
+ highlighter.fromRange(range);
200
+ }
201
+
202
+ function clearHighlights() {
203
+ if (highlighter) {
204
+ highlighter.removeAll();
205
+ }
206
+ document.getElementById('results').style.display = 'none';
207
+ }
208
+
209
+ function showResults(html) {
210
+ const resultsDiv = document.getElementById('results');
211
+ resultsDiv.style.display = 'block';
212
+ resultsDiv.innerHTML = html;
213
+ }
214
+
215
+ function escapeHtml(text) {
216
+ const div = document.createElement('div');
217
+ div.textContent = text;
218
+ return div.innerHTML;
219
+ }
220
+
221
+ function clearResults() {
222
+ document.getElementById('results').style.display = 'none';
223
+ }
224
+ </script>
225
+ </body>
226
+ </html>
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "esModuleInterop": true,
4
+ "declaration": true,
5
+ "sourceMap": true,
6
+ "outDir": "./dist",
7
+ "lib": [
8
+ "dom",
9
+ "dom.iterable",
10
+ "es2015"
11
+ ],
12
+ "target": "es5",
13
+ "downlevelIteration": true,
14
+ "resolveJsonModule": true,
15
+ "baseUrl": ".",
16
+ "paths": {
17
+ "@src/*": ["./src/*"]
18
+ }
19
+ },
20
+ "include": [
21
+ "src/**/*"
22
+ ]
23
+ }