etherpad-webcomponents 0.0.5 → 0.0.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.
Files changed (145) hide show
  1. package/dist/EpDropdown.d.ts +3 -0
  2. package/dist/EpDropdown.d.ts.map +1 -1
  3. package/dist/EpDropdown.js +30 -4
  4. package/dist/EpDropdown.js.map +1 -1
  5. package/dist/EpEditor.d.ts +108 -0
  6. package/dist/EpEditor.d.ts.map +1 -0
  7. package/dist/EpEditor.js +288 -0
  8. package/dist/EpEditor.js.map +1 -0
  9. package/dist/editor/AceEditor.d.ts +204 -0
  10. package/dist/editor/AceEditor.d.ts.map +1 -0
  11. package/dist/editor/AceEditor.js +2847 -0
  12. package/dist/editor/AceEditor.js.map +1 -0
  13. package/dist/editor/AttributeManager.d.ts +25 -0
  14. package/dist/editor/AttributeManager.d.ts.map +1 -0
  15. package/dist/editor/AttributeManager.js +236 -0
  16. package/dist/editor/AttributeManager.js.map +1 -0
  17. package/dist/editor/AttributeMap.d.ts +13 -0
  18. package/dist/editor/AttributeMap.d.ts.map +1 -0
  19. package/dist/editor/AttributeMap.js +37 -0
  20. package/dist/editor/AttributeMap.js.map +1 -0
  21. package/dist/editor/AttributePool.d.ts +22 -0
  22. package/dist/editor/AttributePool.d.ts.map +1 -0
  23. package/dist/editor/AttributePool.js +101 -0
  24. package/dist/editor/AttributePool.js.map +1 -0
  25. package/dist/editor/Builder.d.ts +15 -0
  26. package/dist/editor/Builder.d.ts.map +1 -0
  27. package/dist/editor/Builder.js +47 -0
  28. package/dist/editor/Builder.js.map +1 -0
  29. package/dist/editor/Changeset.d.ts +61 -0
  30. package/dist/editor/Changeset.d.ts.map +1 -0
  31. package/dist/editor/Changeset.js +942 -0
  32. package/dist/editor/Changeset.js.map +1 -0
  33. package/dist/editor/ChangesetUtils.d.ts +11 -0
  34. package/dist/editor/ChangesetUtils.d.ts.map +1 -0
  35. package/dist/editor/ChangesetUtils.js +30 -0
  36. package/dist/editor/ChangesetUtils.js.map +1 -0
  37. package/dist/editor/MergingOpAssembler.d.ts +13 -0
  38. package/dist/editor/MergingOpAssembler.d.ts.map +1 -0
  39. package/dist/editor/MergingOpAssembler.js +60 -0
  40. package/dist/editor/MergingOpAssembler.js.map +1 -0
  41. package/dist/editor/Op.d.ts +10 -0
  42. package/dist/editor/Op.d.ts.map +1 -0
  43. package/dist/editor/Op.js +18 -0
  44. package/dist/editor/Op.js.map +1 -0
  45. package/dist/editor/OpAssembler.d.ts +9 -0
  46. package/dist/editor/OpAssembler.d.ts.map +1 -0
  47. package/dist/editor/OpAssembler.js +16 -0
  48. package/dist/editor/OpAssembler.js.map +1 -0
  49. package/dist/editor/OpIter.d.ts +9 -0
  50. package/dist/editor/OpIter.d.ts.map +1 -0
  51. package/dist/editor/OpIter.js +22 -0
  52. package/dist/editor/OpIter.js.map +1 -0
  53. package/dist/editor/SmartOpAssembler.d.ts +21 -0
  54. package/dist/editor/SmartOpAssembler.d.ts.map +1 -0
  55. package/dist/editor/SmartOpAssembler.js +71 -0
  56. package/dist/editor/SmartOpAssembler.js.map +1 -0
  57. package/dist/editor/StringAssembler.d.ts +7 -0
  58. package/dist/editor/StringAssembler.d.ts.map +1 -0
  59. package/dist/editor/StringAssembler.js +15 -0
  60. package/dist/editor/StringAssembler.js.map +1 -0
  61. package/dist/editor/StringIterator.d.ts +13 -0
  62. package/dist/editor/StringIterator.d.ts.map +1 -0
  63. package/dist/editor/StringIterator.js +29 -0
  64. package/dist/editor/StringIterator.js.map +1 -0
  65. package/dist/editor/TextLinesMutator.d.ts +31 -0
  66. package/dist/editor/TextLinesMutator.d.ts.map +1 -0
  67. package/dist/editor/TextLinesMutator.js +198 -0
  68. package/dist/editor/TextLinesMutator.js.map +1 -0
  69. package/dist/editor/ace2_common.d.ts +9 -0
  70. package/dist/editor/ace2_common.d.ts.map +1 -0
  71. package/dist/editor/ace2_common.js +31 -0
  72. package/dist/editor/ace2_common.js.map +1 -0
  73. package/dist/editor/attributes.d.ts +20 -0
  74. package/dist/editor/attributes.d.ts.map +1 -0
  75. package/dist/editor/attributes.js +54 -0
  76. package/dist/editor/attributes.js.map +1 -0
  77. package/dist/editor/browser_flags.d.ts +7 -0
  78. package/dist/editor/browser_flags.d.ts.map +1 -0
  79. package/dist/editor/browser_flags.js +8 -0
  80. package/dist/editor/browser_flags.js.map +1 -0
  81. package/dist/editor/changesettracker.d.ts +54 -0
  82. package/dist/editor/changesettracker.d.ts.map +1 -0
  83. package/dist/editor/changesettracker.js +193 -0
  84. package/dist/editor/changesettracker.js.map +1 -0
  85. package/dist/editor/colorutils.d.ts +22 -0
  86. package/dist/editor/colorutils.d.ts.map +1 -0
  87. package/dist/editor/colorutils.js +81 -0
  88. package/dist/editor/colorutils.js.map +1 -0
  89. package/dist/editor/contentcollector.d.ts +52 -0
  90. package/dist/editor/contentcollector.d.ts.map +1 -0
  91. package/dist/editor/contentcollector.js +692 -0
  92. package/dist/editor/contentcollector.js.map +1 -0
  93. package/dist/editor/core/EventBus.d.ts +187 -0
  94. package/dist/editor/core/EventBus.d.ts.map +1 -0
  95. package/dist/editor/core/EventBus.js +169 -0
  96. package/dist/editor/core/EventBus.js.map +1 -0
  97. package/dist/editor/cssmanager.d.ts +6 -0
  98. package/dist/editor/cssmanager.d.ts.map +1 -0
  99. package/dist/editor/cssmanager.js +35 -0
  100. package/dist/editor/cssmanager.js.map +1 -0
  101. package/dist/editor/domline.d.ts +35 -0
  102. package/dist/editor/domline.d.ts.map +1 -0
  103. package/dist/editor/domline.js +267 -0
  104. package/dist/editor/domline.js.map +1 -0
  105. package/dist/editor/html_escape.d.ts +3 -0
  106. package/dist/editor/html_escape.d.ts.map +1 -0
  107. package/dist/editor/html_escape.js +8 -0
  108. package/dist/editor/html_escape.js.map +1 -0
  109. package/dist/editor/linestylefilter.d.ts +22 -0
  110. package/dist/editor/linestylefilter.d.ts.map +1 -0
  111. package/dist/editor/linestylefilter.js +298 -0
  112. package/dist/editor/linestylefilter.js.map +1 -0
  113. package/dist/editor/skiplist.d.ts +51 -0
  114. package/dist/editor/skiplist.d.ts.map +1 -0
  115. package/dist/editor/skiplist.js +327 -0
  116. package/dist/editor/skiplist.js.map +1 -0
  117. package/dist/editor/types/AText.d.ts +5 -0
  118. package/dist/editor/types/AText.d.ts.map +1 -0
  119. package/dist/editor/types/AText.js +2 -0
  120. package/dist/editor/types/AText.js.map +1 -0
  121. package/dist/editor/types/Attribute.d.ts +2 -0
  122. package/dist/editor/types/Attribute.d.ts.map +1 -0
  123. package/dist/editor/types/Attribute.js +2 -0
  124. package/dist/editor/types/Attribute.js.map +1 -0
  125. package/dist/editor/types/ChangeSet.d.ts +7 -0
  126. package/dist/editor/types/ChangeSet.d.ts.map +1 -0
  127. package/dist/editor/types/ChangeSet.js +2 -0
  128. package/dist/editor/types/ChangeSet.js.map +1 -0
  129. package/dist/editor/types/ChangeSetBuilder.d.ts +7 -0
  130. package/dist/editor/types/ChangeSetBuilder.d.ts.map +1 -0
  131. package/dist/editor/types/ChangeSetBuilder.js +2 -0
  132. package/dist/editor/types/ChangeSetBuilder.js.map +1 -0
  133. package/dist/editor/types/RepModel.d.ts +25 -0
  134. package/dist/editor/types/RepModel.d.ts.map +1 -0
  135. package/dist/editor/types/RepModel.js +2 -0
  136. package/dist/editor/types/RepModel.js.map +1 -0
  137. package/dist/editor/undomodule.d.ts +30 -0
  138. package/dist/editor/undomodule.d.ts.map +1 -0
  139. package/dist/editor/undomodule.js +266 -0
  140. package/dist/editor/undomodule.js.map +1 -0
  141. package/dist/index.d.ts +7 -0
  142. package/dist/index.d.ts.map +1 -1
  143. package/dist/index.js +4 -0
  144. package/dist/index.js.map +1 -1
  145. package/package.json +7 -5
@@ -0,0 +1,692 @@
1
+ /**
2
+ * This code is mostly from the old Etherpad. Please help us to comment this code.
3
+ * This helps other people to understand this code better and helps them to improve it.
4
+ * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
5
+ */
6
+ // THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.contentcollector
7
+ // %APPJET%: import("etherpad.collab.ace.easysync2.Changeset");
8
+ // %APPJET%: import("etherpad.admin.plugins");
9
+ import Op from "./Op.js";
10
+ /**
11
+ * Copyright 2009 Google Inc.
12
+ *
13
+ * Licensed under the Apache License, Version 2.0 (the "License");
14
+ * you may not use this file except in compliance with the License.
15
+ * You may obtain a copy of the License at
16
+ *
17
+ * http://www.apache.org/licenses/LICENSE-2.0
18
+ *
19
+ * Unless required by applicable law or agreed to in writing, software
20
+ * distributed under the License is distributed on an "AS-IS" BASIS,
21
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ * See the License for the specific language governing permissions and
23
+ * limitations under the License.
24
+ */
25
+ const _MAX_LIST_LEVEL = 16;
26
+ import AttributeMap from './AttributeMap.js';
27
+ import { subattribution } from './Changeset.js';
28
+ import { SmartOpAssembler } from "./SmartOpAssembler.js";
29
+ import { editorBus } from './core/EventBus.js';
30
+ export const sanitizeUnicode = (s) => s.normalize('NFC');
31
+ const tagName = (n) => n.tagName && n.tagName.toLowerCase();
32
+ // supportedElems are Supported natively within Etherpad and don't require a plugin
33
+ export const supportedElems = new Set([
34
+ 'author',
35
+ 'b',
36
+ 'bold',
37
+ 'br',
38
+ 'div',
39
+ 'font',
40
+ 'i',
41
+ 'insertorder',
42
+ 'italic',
43
+ 'li',
44
+ 'lmkr',
45
+ 'ol',
46
+ 'p',
47
+ 'pre',
48
+ 'strong',
49
+ 's',
50
+ 'span',
51
+ 'u',
52
+ 'ul',
53
+ ]);
54
+ export const makeContentCollector = (collectStyles, abrowser, apool, className2Author) => {
55
+ const _blockElems = {
56
+ div: 1,
57
+ p: 1,
58
+ pre: 1,
59
+ li: 1,
60
+ };
61
+ // Let plugins register additional block elements (e.g. h1-h4 from ep_heading).
62
+ // Plugins push tag names into the result array; we then add them to _blockElems.
63
+ const pluginBlockElems = [];
64
+ editorBus.emit('editor:register:block:elements', { result: pluginBlockElems });
65
+ for (const tag of pluginBlockElems) {
66
+ _blockElems[tag] = 1;
67
+ }
68
+ const isBlockElement = (n) => !!_blockElems[tagName(n) || ''];
69
+ const textify = (str) => sanitizeUnicode(str.replace(/(\n | \n)/g, ' ')
70
+ .replace(/[\n\r ]/g, ' ')
71
+ .replace(/\xa0/g, ' ')
72
+ .replace(/\t/g, ' '));
73
+ const getAssoc = (node, name) => node[`_magicdom_${name}`];
74
+ const lines = (() => {
75
+ const textArray = [];
76
+ const attribsArray = [];
77
+ let attribsBuilder = null;
78
+ const op = new Op('+');
79
+ const self = {
80
+ length: () => textArray.length,
81
+ atColumnZero: () => textArray[textArray.length - 1] === '',
82
+ startNew: () => {
83
+ textArray.push('');
84
+ self.flush();
85
+ attribsBuilder = new SmartOpAssembler();
86
+ },
87
+ textOfLine: (i) => textArray[i],
88
+ appendText: (txt, attrString = '') => {
89
+ textArray[textArray.length - 1] += txt;
90
+ op.attribs = attrString;
91
+ op.chars = txt.length;
92
+ attribsBuilder.append(op);
93
+ },
94
+ textLines: () => textArray.slice(),
95
+ attribLines: () => attribsArray,
96
+ // call flush only when you're done
97
+ flush: () => {
98
+ if (attribsBuilder) {
99
+ attribsArray.push(attribsBuilder.toString());
100
+ attribsBuilder = null;
101
+ }
102
+ },
103
+ };
104
+ self.startNew();
105
+ return self;
106
+ })();
107
+ const cc = {};
108
+ const _ensureColumnZero = (state) => {
109
+ if (!lines.atColumnZero()) {
110
+ cc.startNewLine(state);
111
+ }
112
+ };
113
+ let selection;
114
+ let startPoint;
115
+ let endPoint;
116
+ let selStart = [-1, -1];
117
+ let selEnd = [-1, -1];
118
+ const _isEmpty = (node, state) => {
119
+ // consider clean blank lines pasted in IE to be empty
120
+ if (node.childNodes.length === 0)
121
+ return true;
122
+ if (node.childNodes.length === 1 &&
123
+ getAssoc(node, 'shouldBeEmpty') &&
124
+ node.innerHTML === ' ' &&
125
+ !getAssoc(node, 'unpasted')) {
126
+ if (state) {
127
+ const child = node.childNodes[0];
128
+ _reachPoint(child, 0, state);
129
+ _reachPoint(child, 1, state);
130
+ }
131
+ return true;
132
+ }
133
+ return false;
134
+ };
135
+ const _pointHere = (charsAfter, state) => {
136
+ const ln = lines.length() - 1;
137
+ let chr = lines.textOfLine(ln).length;
138
+ if (chr === 0 && Object.keys(state.lineAttributes).length !== 0) {
139
+ chr += 1; // listMarker
140
+ }
141
+ chr += charsAfter;
142
+ return [ln, chr];
143
+ };
144
+ const _reachBlockPoint = (nd, idx, state) => {
145
+ if (nd.nodeType !== nd.TEXT_NODE)
146
+ _reachPoint(nd, idx, state);
147
+ };
148
+ const _reachPoint = (nd, idx, state) => {
149
+ if (startPoint && nd === startPoint.node && startPoint.index === idx) {
150
+ selStart = _pointHere(0, state);
151
+ }
152
+ if (endPoint && nd === endPoint.node && endPoint.index === idx) {
153
+ selEnd = _pointHere(0, state);
154
+ }
155
+ };
156
+ cc.incrementFlag = (state, flagName) => {
157
+ state.flags[flagName] = (state.flags[flagName] || 0) + 1;
158
+ };
159
+ cc.decrementFlag = (state, flagName) => {
160
+ state.flags[flagName]--;
161
+ };
162
+ cc.incrementAttrib = (state, attribName) => {
163
+ if (!state.attribs[attribName]) {
164
+ state.attribs[attribName] = 1;
165
+ }
166
+ else {
167
+ state.attribs[attribName]++;
168
+ }
169
+ _recalcAttribString(state);
170
+ };
171
+ cc.decrementAttrib = (state, attribName) => {
172
+ state.attribs[attribName]--;
173
+ _recalcAttribString(state);
174
+ };
175
+ const _enterList = (state, listType) => {
176
+ if (!listType)
177
+ return;
178
+ const oldListType = state.lineAttributes.list;
179
+ if (listType !== 'none') {
180
+ state.listNesting = (state.listNesting || 0) + 1;
181
+ // reminder that listType can be "number2", "number3" etc.
182
+ if (listType.indexOf('number') !== -1) {
183
+ state.start = (state.start || 0) + 1;
184
+ }
185
+ }
186
+ if (listType === 'none') {
187
+ delete state.lineAttributes.list;
188
+ }
189
+ else {
190
+ state.lineAttributes.list = listType;
191
+ }
192
+ _recalcAttribString(state);
193
+ return oldListType;
194
+ };
195
+ const _exitList = (state, oldListType) => {
196
+ if (state.lineAttributes.list) {
197
+ state.listNesting = (state.listNesting || 0) - 1;
198
+ }
199
+ if (oldListType && oldListType !== 'none') {
200
+ state.lineAttributes.list = oldListType;
201
+ }
202
+ else {
203
+ delete state.lineAttributes.list;
204
+ delete state.lineAttributes.start;
205
+ }
206
+ _recalcAttribString(state);
207
+ };
208
+ const _enterAuthor = (state, author) => {
209
+ const oldAuthor = state.author;
210
+ state.authorLevel = (state.authorLevel || 0) + 1;
211
+ state.author = author;
212
+ _recalcAttribString(state);
213
+ return oldAuthor;
214
+ };
215
+ const _exitAuthor = (state, oldAuthor) => {
216
+ state.authorLevel = (state.authorLevel || 0) - 1;
217
+ state.author = oldAuthor;
218
+ _recalcAttribString(state);
219
+ };
220
+ const _recalcAttribString = (state) => {
221
+ const attribs = new AttributeMap(apool);
222
+ for (const [a, count] of Object.entries(state.attribs)) {
223
+ if (!count)
224
+ continue;
225
+ // The following splitting of the attribute name is a workaround
226
+ // to enable the content collector to store key-value attributes
227
+ // see https://github.com/ether/etherpad-lite/issues/2567 for more information
228
+ // in long term the contentcollector should be refactored to get rid of this workaround
229
+ //
230
+ // TODO: This approach doesn't support changing existing values: if both 'foo::bar' and
231
+ // 'foo::baz' are in state.attribs then the last one encountered while iterating will win.
232
+ const ATTRIBUTE_SPLIT_STRING = '::';
233
+ // see if attributeString is splittable
234
+ const attributeSplits = a.split(ATTRIBUTE_SPLIT_STRING);
235
+ if (attributeSplits.length > 1) {
236
+ // the attribute name follows the convention key::value
237
+ // so save it as a key value attribute
238
+ const [k, v] = attributeSplits;
239
+ if (v)
240
+ attribs.set(k, v);
241
+ }
242
+ else {
243
+ // the "normal" case, the attribute is just a switch
244
+ // so set it true
245
+ attribs.set(a, 'true');
246
+ }
247
+ }
248
+ if ((state.authorLevel || 0) > 0) {
249
+ if (apool.putAttrib(['author', state.author || ''], true) >= 0) {
250
+ // require that author already be in pool
251
+ // (don't add authors from other documents, etc.)
252
+ if (state.author)
253
+ attribs.set('author', state.author);
254
+ }
255
+ }
256
+ state.attribString = attribs.toString();
257
+ };
258
+ const _produceLineAttributesMarker = (state) => {
259
+ // TODO: This has to go to AttributeManager.
260
+ const attribs = new AttributeMap(apool)
261
+ .set('lmkr', '1')
262
+ .set('insertorder', 'first')
263
+ // TODO: Converting all falsy values in state.lineAttributes into removals is awkward.
264
+ // Better would be to never add 0, false, null, or undefined to state.lineAttributes in the
265
+ // first place (I'm looking at you, state.lineAttributes.start).
266
+ .update(Object.entries(state.lineAttributes).map(([k, v]) => [k, v || '']), true);
267
+ lines.appendText('*', attribs.toString());
268
+ };
269
+ cc.startNewLine = (state) => {
270
+ if (state) {
271
+ const atBeginningOfLine = lines.textOfLine(lines.length() - 1).length === 0;
272
+ if (atBeginningOfLine && Object.keys(state.lineAttributes).length !== 0) {
273
+ _produceLineAttributesMarker(state);
274
+ }
275
+ }
276
+ lines.startNew();
277
+ };
278
+ cc.notifySelection = (sel) => {
279
+ if (sel) {
280
+ selection = sel;
281
+ startPoint = selection.startPoint;
282
+ endPoint = selection.endPoint;
283
+ }
284
+ };
285
+ cc.doAttrib = (state, na) => {
286
+ state.localAttribs = (state.localAttribs || []);
287
+ state.localAttribs.push(na);
288
+ cc.incrementAttrib(state, na);
289
+ };
290
+ cc.collectContent = function (node, state) {
291
+ let unsupportedElements = null;
292
+ if (!state) {
293
+ state = {
294
+ flags: { /* name -> nesting counter*/},
295
+ localAttribs: null,
296
+ attribs: { /* name -> nesting counter*/},
297
+ attribString: '',
298
+ // lineAttributes maintain a map from attributes to attribute values set on a line
299
+ lineAttributes: {
300
+ /*
301
+ example:
302
+ 'list': 'bullet1',
303
+ */
304
+ },
305
+ unsupportedElements: new Set(),
306
+ };
307
+ unsupportedElements = state.unsupportedElements;
308
+ }
309
+ const localAttribs = state.localAttribs;
310
+ state.localAttribs = null;
311
+ const isBlock = isBlockElement(node);
312
+ if (!isBlock && node.name && (node.name !== 'body')) {
313
+ if (!supportedElems.has(node.name))
314
+ state.unsupportedElements.add(node.name);
315
+ }
316
+ const isEmpty = _isEmpty(node, state);
317
+ if (isBlock)
318
+ _ensureColumnZero(state);
319
+ const startLine = lines.length() - 1;
320
+ _reachBlockPoint(node, 0, state);
321
+ if (node.nodeType === node.TEXT_NODE) {
322
+ const tname = node.parentNode.getAttribute('name');
323
+ const context = { cc: this, state, tname, node, text: node.nodeValue || '' };
324
+ // Hook functions may either return a string (deprecated) or modify context.text. If any hook
325
+ // function modifies context.text then all returned strings are ignored. If no hook functions
326
+ // modify context.text, the first hook function to return a string wins.
327
+ editorBus.emit('custom:collect:content:line:text', context);
328
+ let txt = context.text;
329
+ let rest = '';
330
+ let x = 0; // offset into original text
331
+ if (txt.length === 0) {
332
+ if (startPoint && node === startPoint.node) {
333
+ selStart = _pointHere(0, state);
334
+ }
335
+ if (endPoint && node === endPoint.node) {
336
+ selEnd = _pointHere(0, state);
337
+ }
338
+ }
339
+ while (txt.length > 0) {
340
+ let consumed = 0;
341
+ if (state.flags.preMode) {
342
+ const firstLine = txt.split('\n', 1)[0];
343
+ consumed = firstLine.length + 1;
344
+ rest = txt.substring(consumed);
345
+ txt = firstLine;
346
+ }
347
+ else { /* will only run this loop body once */
348
+ }
349
+ if (startPoint && node === startPoint.node && startPoint.index - x <= txt.length) {
350
+ selStart = _pointHere(startPoint.index - x, state);
351
+ }
352
+ if (endPoint && node === endPoint.node && endPoint.index - x <= txt.length) {
353
+ selEnd = _pointHere(endPoint.index - x, state);
354
+ }
355
+ let txt2 = txt;
356
+ if ((!state.flags.preMode) && /^[\r\n]*$/.exec(txt)) {
357
+ // prevents textnodes containing just "\n" from being significant
358
+ // in safari when pasting text, now that we convert them to
359
+ // spaces instead of removing them, because in other cases
360
+ // removing "\n" from pasted HTML will collapse words together.
361
+ txt2 = '';
362
+ }
363
+ const atBeginningOfLine = lines.textOfLine(lines.length() - 1).length === 0;
364
+ if (atBeginningOfLine) {
365
+ // newlines in the source mustn't become spaces at beginning of line box
366
+ txt2 = txt2.replace(/^\n*/, '');
367
+ }
368
+ if (atBeginningOfLine && Object.keys(state.lineAttributes).length !== 0) {
369
+ _produceLineAttributesMarker(state);
370
+ }
371
+ lines.appendText(textify(txt2), state.attribString);
372
+ x += consumed;
373
+ txt = rest;
374
+ if (txt.length > 0) {
375
+ cc.startNewLine(state);
376
+ }
377
+ }
378
+ }
379
+ else if (node.nodeType === node.ELEMENT_NODE) {
380
+ const tname = tagName(node) || '';
381
+ const el = node;
382
+ if (tname === 'img') {
383
+ const imageContext = {
384
+ cc,
385
+ state,
386
+ tname,
387
+ styl: null,
388
+ cls: null,
389
+ node,
390
+ };
391
+ editorBus.emit('custom:collect:content:image', imageContext);
392
+ }
393
+ else {
394
+ // THIS SEEMS VERY HACKY! -- Please submit a better fix!
395
+ delete state.lineAttributes.img;
396
+ }
397
+ if (tname === 'br') {
398
+ this.breakLine = true;
399
+ const tvalue = el.getAttribute('value');
400
+ const lineBreakContext = {
401
+ cc: this,
402
+ state,
403
+ tname,
404
+ tvalue,
405
+ styl: null,
406
+ cls: null,
407
+ };
408
+ editorBus.emit('custom:collect:content:line:break', lineBreakContext);
409
+ cc.startNewLine(state);
410
+ }
411
+ else if (tname === 'script' || tname === 'style') {
412
+ // ignore
413
+ }
414
+ else if (!isEmpty) {
415
+ let styl = el.getAttribute('style');
416
+ let cls = el.getAttribute('class');
417
+ let isPre = (tname === 'pre');
418
+ if ((!isPre) && abrowser && abrowser.safari) {
419
+ isPre = styl ? /\bwhite-space:\s*pre\b/i.exec(styl) : null;
420
+ }
421
+ if (isPre)
422
+ cc.incrementFlag(state, 'preMode');
423
+ let oldListTypeOrNull = null;
424
+ let oldAuthorOrNull = null;
425
+ // LibreOffice Writer puts in weird items during import or copy/paste, we should drop them.
426
+ if (cls === 'Numbering_20_Symbols' || cls === 'Bullet_20_Symbols') {
427
+ styl = null;
428
+ cls = null;
429
+ // We have to return here but this could break things in the future,
430
+ // for now it shows how to fix the problem
431
+ return;
432
+ }
433
+ if (collectStyles) {
434
+ const preContext = { cc: cc, state: state, tname, styl, cls: cls || '' };
435
+ editorBus.emit('editor:collect:content:pre', preContext);
436
+ if (tname === 'b' ||
437
+ (styl && /\bfont-weight:\s*bold\b/i.exec(styl)) ||
438
+ tname === 'strong') {
439
+ cc.doAttrib(state, 'bold');
440
+ }
441
+ if (tname === 'i' ||
442
+ (styl && /\bfont-style:\s*italic\b/i.exec(styl)) ||
443
+ tname === 'em') {
444
+ cc.doAttrib(state, 'italic');
445
+ }
446
+ if (tname === 'u' ||
447
+ (styl && /\btext-decoration:\s*underline\b/i.exec(styl)) ||
448
+ tname === 'ins') {
449
+ cc.doAttrib(state, 'underline');
450
+ }
451
+ if (tname === 's' ||
452
+ (styl && /\btext-decoration:\s*line-through\b/i.exec(styl)) ||
453
+ tname === 'del') {
454
+ cc.doAttrib(state, 'strikethrough');
455
+ }
456
+ if (tname === 'ul' || tname === 'ol') {
457
+ let type = el.getAttribute('class');
458
+ const rr = cls && /(?:^| )list-([a-z]+[0-9]+)\b/.exec(cls);
459
+ // lists do not need to have a type, so before we make a wrong guess
460
+ // check if we find a better hint within the node's children
461
+ if (!rr && !type) {
462
+ for (let ci = 0; ci < node.childNodes.length; ci++) {
463
+ const child = node.childNodes[ci];
464
+ if (tagName(child) !== 'ul')
465
+ continue;
466
+ type = child.getAttribute('class');
467
+ if (type)
468
+ break;
469
+ }
470
+ }
471
+ if (rr && rr[1]) {
472
+ type = rr[1];
473
+ }
474
+ else {
475
+ if (tname === 'ul') {
476
+ const ulCls = el.getAttribute('class');
477
+ if ((type && type.match('indent')) || (ulCls && ulCls.match('indent'))) {
478
+ type = 'indent';
479
+ }
480
+ else {
481
+ type = 'bullet';
482
+ }
483
+ }
484
+ else {
485
+ type = 'number';
486
+ }
487
+ type += String(Math.min(_MAX_LIST_LEVEL, (state.listNesting || 0) + 1));
488
+ }
489
+ oldListTypeOrNull = (_enterList(state, type) || 'none');
490
+ }
491
+ else if ((tname === 'div' || tname === 'p') && cls && cls.match(/(?:^| )ace-line\b/)) {
492
+ // This has undesirable behavior in Chrome but is right in other browsers.
493
+ // See https://github.com/ether/etherpad-lite/issues/2412 for reasoning
494
+ if (!abrowser.chrome)
495
+ oldListTypeOrNull = (_enterList(state, undefined) || 'none');
496
+ }
497
+ else if (tname === 'li') {
498
+ state.lineAttributes.start = state.start || 0;
499
+ _recalcAttribString(state);
500
+ if (state.lineAttributes.list && String(state.lineAttributes.list).indexOf('number') !== -1) {
501
+ /*
502
+ Nested OLs are not --> <ol><li>1</li><ol>nested</ol></ol>
503
+ They are --> <ol><li>1</li><li><ol><li>nested</li></ol></li></ol>
504
+ Note how the <ol> item has to be inside a <li>
505
+ Because of this we don't increment the start number
506
+ */
507
+ if (node.parentNode && tagName(node.parentNode) !== 'ol') {
508
+ /*
509
+ TODO: start number has to increment based on indentLevel(numberX)
510
+ This means we have to build an object IE
511
+ {
512
+ 1: 4
513
+ 2: 3
514
+ 3: 5
515
+ }
516
+ But the browser seems to handle it fine using CSS.. Why can't we do the same
517
+ with exports? We can.. But let's leave this comment in because it might be useful
518
+ in the future..
519
+ */
520
+ state.start = (state.start || 0) + 1; // not if it's parent is an OL or UL.
521
+ }
522
+ }
523
+ // UL list items never modify the start value.
524
+ if (node.parentNode && tagName(node.parentNode) === 'ul') {
525
+ state.start = (state.start || 0) + 1;
526
+ // TODO, this is hacky.
527
+ // Because if the first item is an UL it will increment a list no?
528
+ // A much more graceful way would be to say, ul increases if it's within an OL
529
+ // But I don't know a way to do that because we're only aware of the previous Line
530
+ // As the concept of parent's doesn't exist when processing each domline...
531
+ }
532
+ }
533
+ else {
534
+ // Below needs more testin if it's necessary as _exitList should take care of this.
535
+ // delete state.start;
536
+ // delete state.listNesting;
537
+ // _recalcAttribString(state);
538
+ }
539
+ if (className2Author && cls) {
540
+ const classes = cls.match(/\S+/g);
541
+ if (classes && classes.length > 0) {
542
+ for (let i = 0; i < classes.length; i++) {
543
+ const c = classes[i];
544
+ const a = className2Author(c);
545
+ if (a) {
546
+ oldAuthorOrNull = (_enterAuthor(state, a) || 'none');
547
+ break;
548
+ }
549
+ }
550
+ }
551
+ }
552
+ }
553
+ for (let ci = 0; ci < node.childNodes.length; ci++) {
554
+ cc.collectContent.call(cc, node.childNodes[ci], state);
555
+ }
556
+ if (collectStyles) {
557
+ const postContext = { cc: cc, state: state, tname, styl, cls };
558
+ editorBus.emit('custom:collect:content:post', postContext);
559
+ }
560
+ if (isPre)
561
+ cc.decrementFlag(state, 'preMode');
562
+ if (state.localAttribs) {
563
+ for (let i = 0; i < state.localAttribs.length; i++) {
564
+ cc.decrementAttrib(state, state.localAttribs[i]);
565
+ }
566
+ }
567
+ if (oldListTypeOrNull) {
568
+ _exitList(state, oldListTypeOrNull);
569
+ }
570
+ if (oldAuthorOrNull) {
571
+ _exitAuthor(state, oldAuthorOrNull);
572
+ }
573
+ }
574
+ }
575
+ _reachBlockPoint(node, 1, state);
576
+ if (isBlock) {
577
+ if (lines.length() - 1 === startLine) {
578
+ // added additional check to resolve https://github.com/JohnMcLear/ep_copy_paste_images/issues/20
579
+ // this does mean that images etc can't be pasted on lists but imho that's fine
580
+ // If we're doing an export event we need to start a new lines
581
+ // Export events don't have window available.
582
+ // commented out to solve #2412 - https://github.com/ether/etherpad-lite/issues/2412
583
+ if ((state.lineAttributes && !state.lineAttributes.list) || typeof window === 'undefined') {
584
+ cc.startNewLine(state);
585
+ }
586
+ }
587
+ else {
588
+ _ensureColumnZero(state);
589
+ }
590
+ }
591
+ state.localAttribs = localAttribs;
592
+ if (unsupportedElements && unsupportedElements.size) {
593
+ console.warn('Ignoring unsupported elements (you might want to install a plugin): ' +
594
+ `${[...unsupportedElements].join(', ')}`);
595
+ }
596
+ };
597
+ // can pass a falsy value for end of doc
598
+ cc.notifyNextNode = (node) => {
599
+ // an "empty block" won't end a line; this addresses an issue in IE with
600
+ // typing into a blank line at the end of the document. typed text
601
+ // goes into the body, and the empty line div still looks clean.
602
+ // it is incorporated as dirty by the rule that a dirty region has
603
+ // to end a line.
604
+ if ((!node) || (isBlockElement(node) && !_isEmpty(node))) {
605
+ _ensureColumnZero(null);
606
+ }
607
+ };
608
+ // each returns [line, char] or [-1,-1]
609
+ const getSelectionStart = () => selStart;
610
+ const getSelectionEnd = () => selEnd;
611
+ // returns array of strings for lines found, last entry will be "" if
612
+ // last line is complete (i.e. if a following span should be on a new line).
613
+ // can be called at any point
614
+ cc.getLines = () => lines.textLines();
615
+ cc.finish = () => {
616
+ lines.flush();
617
+ const lineAttribs = lines.attribLines();
618
+ const lineStrings = cc.getLines();
619
+ lineStrings.length--;
620
+ lineAttribs.length--;
621
+ const ss = getSelectionStart();
622
+ const se = getSelectionEnd();
623
+ const fixLongLines = () => {
624
+ // design mode does not deal with with really long lines!
625
+ const lineLimit = 2000; // chars
626
+ const buffer = 10; // chars allowed over before wrapping
627
+ let linesWrapped = 0;
628
+ let numLinesAfter = 0;
629
+ for (let i = lineStrings.length - 1; i >= 0; i--) {
630
+ let oldString = lineStrings[i];
631
+ let oldAttribString = lineAttribs[i];
632
+ if (oldString.length > lineLimit + buffer) {
633
+ const newStrings = [];
634
+ const newAttribStrings = [];
635
+ while (oldString.length > lineLimit) {
636
+ // var semiloc = oldString.lastIndexOf(';', lineLimit-1);
637
+ // var lengthToTake = (semiloc >= 0 ? (semiloc+1) : lineLimit);
638
+ const lengthToTake = lineLimit;
639
+ newStrings.push(oldString.substring(0, lengthToTake));
640
+ oldString = oldString.substring(lengthToTake);
641
+ newAttribStrings.push(subattribution(oldAttribString, 0, lengthToTake));
642
+ oldAttribString = subattribution(oldAttribString, lengthToTake);
643
+ }
644
+ if (oldString.length > 0) {
645
+ newStrings.push(oldString);
646
+ newAttribStrings.push(oldAttribString);
647
+ }
648
+ const fixLineNumber = (lineChar) => {
649
+ if (lineChar[0] < 0)
650
+ return;
651
+ let n = lineChar[0];
652
+ let c = lineChar[1];
653
+ if (n > i) {
654
+ n += (newStrings.length - 1);
655
+ }
656
+ else if (n === i) {
657
+ let a = 0;
658
+ while (c > newStrings[a].length) {
659
+ c -= newStrings[a].length;
660
+ a++;
661
+ }
662
+ n += a;
663
+ }
664
+ lineChar[0] = n;
665
+ lineChar[1] = c;
666
+ };
667
+ fixLineNumber(ss);
668
+ fixLineNumber(se);
669
+ linesWrapped++;
670
+ numLinesAfter += newStrings.length;
671
+ lineStrings.splice(i, 1, ...newStrings);
672
+ lineAttribs.splice(i, 1, ...newAttribStrings);
673
+ }
674
+ }
675
+ return {
676
+ linesWrapped,
677
+ numLinesAfter,
678
+ };
679
+ };
680
+ const wrapData = fixLongLines();
681
+ return {
682
+ selStart: ss,
683
+ selEnd: se,
684
+ linesWrapped: wrapData.linesWrapped,
685
+ numLinesAfter: wrapData.numLinesAfter,
686
+ lines: lineStrings,
687
+ lineAttribs,
688
+ };
689
+ };
690
+ return cc;
691
+ };
692
+ //# sourceMappingURL=contentcollector.js.map