diff --git a/HISTORY.md b/HISTORY.md index 78510b3..3d9c83d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,12 @@ https://github.com/josdejong/jsoneditor +## not yet published, version 8.6.8 + +- Fix #936: too many return characters inserted when pasting formatted text + from OpenOffice. + + ## 2020-05-10, version 8.6.7 - Fix #858: the `dist/jsoneditor.js` bundle containing a link to a diff --git a/src/js/JSONEditor.js b/src/js/JSONEditor.js index 7eb774a..a5b026e 100644 --- a/src/js/JSONEditor.js +++ b/src/js/JSONEditor.js @@ -5,7 +5,7 @@ const VanillaPicker = require('./vanilla-picker') // may be undefined in case of const { treeModeMixins } = require('./treemode') const { textModeMixins } = require('./textmode') const { previewModeMixins } = require('./previewmode') -const { clear, extend, getInternetExplorerVersion, parse } = require('./util') +const { clear, extend, getInnerText, getInternetExplorerVersion, parse } = require('./util') const { tryRequireAjv } = require('./tryRequireAjv') const { showTransformModal } = require('./showTransformModal') const { showSortModal } = require('./showSortModal') @@ -484,6 +484,7 @@ JSONEditor.VanillaPicker = VanillaPicker // expose some utils (this is undocumented, unofficial) JSONEditor.showTransformModal = showTransformModal JSONEditor.showSortModal = showSortModal +JSONEditor.getInnerText = getInnerText // default export for TypeScript ES6 projects JSONEditor.default = JSONEditor diff --git a/src/js/util.js b/src/js/util.js index 53b5f46..65dbdf5 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -663,7 +663,6 @@ export function setSelectionOffset (params) { } } } - /** * Get the inner text of an HTML element (for example a div element) * @param {Element} element @@ -674,21 +673,28 @@ export function getInnerText (element, buffer) { const first = (buffer === undefined) if (first) { buffer = { - text: '', + _text: '', flush: function () { - const text = this.text - this.text = '' + const text = this._text + this._text = '' return text }, set: function (text) { - this.text = text + this._text = text } } } // text node if (element.nodeValue) { - return buffer.flush() + element.nodeValue + // remove return characters and the whitespace surrounding return characters + const trimmedValue = element.nodeValue.replace(/\s*\n\s*/g, '') + if (trimmedValue !== '') { + return buffer.flush() + trimmedValue + } else { + // ignore empty text + return '' + } } // divs or other HTML elements @@ -703,7 +709,9 @@ export function getInnerText (element, buffer) { const prevChild = childNodes[i - 1] const prevName = prevChild ? prevChild.nodeName : undefined if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') { - innerText += '\n' + if (innerText !== '') { + innerText += '\n' + } buffer.flush() } innerText += getInnerText(child, buffer) @@ -717,15 +725,6 @@ export function getInnerText (element, buffer) { } return innerText - } else { - if (element.nodeName === 'P' && getInternetExplorerVersion() !== -1) { - // On Internet Explorer, a

with hasChildNodes()==false is - // rendered with a new line. Note that a

with - // hasChildNodes()==true is rendered without a new line - // Other browsers always ensure there is a
inside the

, - // and if not, the

does not render a new line - return buffer.flush() - } } // br or unknown diff --git a/test/test_get_inner_text.html b/test/test_get_inner_text.html new file mode 100644 index 0000000..17d0bf6 --- /dev/null +++ b/test/test_get_inner_text.html @@ -0,0 +1,111 @@ + + + + + JSONEditor test getInnerHtml + + + + + + + +contenteditable div: +

+

Hello world

+

test paste from OpenOffice

+ a +

+
+

+

test

+
+ +

+ innerText:
+ +

+

+ getInnerText:
+ +

+

+

+ inner text (stringified):
+ +

+

+ text content (stringified):
+ +

+ + + + \ No newline at end of file