diff --git a/webodf/lib/odf/OdfUtils.js b/webodf/lib/odf/OdfUtils.js index 55b0c320..5a00de8e 100644 --- a/webodf/lib/odf/OdfUtils.js +++ b/webodf/lib/odf/OdfUtils.js @@ -191,23 +191,23 @@ odf.OdfUtils = function OdfUtils() { } this.isCharacterElement = isCharacterElement; /** - * Determine if the node is a whitespace character element. + * Determine if the node is a character element. * @param {?Node} e * @return {!boolean} */ - function isWhitespaceElement(e) { + function isSpaceElement(e) { var n = e && e.localName, ns, r = false; if (n) { ns = e.namespaceURI; if (ns === textns) { - r = n === "s" || n === "tab"; + r = n === "s"; } } return r; } - this.isWhitespaceElement = isWhitespaceElement; + this.isSpaceElement = isSpaceElement; /** * @param {!Node} node * @return {!Node} @@ -255,12 +255,13 @@ odf.OdfUtils = function OdfUtils() { /** * Walk to the left along the DOM and return true if the first thing - * encountered is either a non-whitespace character or a non-whitespace - * character element. Walking goes through grouping elements. + * encountered is either a non-whitespace text character or a non-space + * character element (i.e., any character element other than ). + * Walking goes through grouping elements. * @param {?Node} node the first node to scan * @return {!boolean} */ - function scanLeftForNonWhitespace(node) { + function scanLeftForNonSpace(node) { var r = false; while (node) { if (node.nodeType === Node.TEXT_NODE) { @@ -272,7 +273,7 @@ odf.OdfUtils = function OdfUtils() { ); } } else if (isCharacterElement(node)) { - r = isWhitespaceElement(node) === false; + r = isSpaceElement(node) === false; node = null; } else { node = previousNode(node); @@ -280,7 +281,7 @@ odf.OdfUtils = function OdfUtils() { } return r; } - this.scanLeftForNonWhitespace = scanLeftForNonWhitespace; + this.scanLeftForNonSpace = scanLeftForNonSpace; /** * Walk to the left along the DOM and return the type of the first * thing encountered. @@ -299,7 +300,7 @@ odf.OdfUtils = function OdfUtils() { if (!isODFWhitespace(text.substr(text.length - 1, 1))) { r = 1; // character found } else if (text.length === 1) { - r = scanLeftForNonWhitespace(previousNode(node)) ? 2 : 0; + r = scanLeftForNonSpace(previousNode(node)) ? 2 : 0; } else { r = isODFWhitespace(text.substr(text.length - 2, 1)) ? 0 : 2; } @@ -426,7 +427,7 @@ odf.OdfUtils = function OdfUtils() { // First whitespace after a character is significant result = true; } - } else if (scanLeftForNonWhitespace(previousNode(textNode))) { + } else if (scanLeftForNonSpace(previousNode(textNode))) { // If the first character found scanning to the left is non-whitespace, this might still be significant result = true; } @@ -449,7 +450,7 @@ odf.OdfUtils = function OdfUtils() { */ this.isDowngradableSpaceElement = function(node) { if (node.namespaceURI === textns && node.localName === "s") { - return scanLeftForNonWhitespace(previousNode(node)) && scanRightForAnyCharacter(nextNode(node)); + return scanLeftForNonSpace(previousNode(node)) && scanRightForAnyCharacter(nextNode(node)); } return false; }; diff --git a/webodf/lib/ops/TextPositionFilter.js b/webodf/lib/ops/TextPositionFilter.js index 1e0dc4b0..468a49a8 100644 --- a/webodf/lib/ops/TextPositionFilter.js +++ b/webodf/lib/ops/TextPositionFilter.js @@ -150,9 +150,9 @@ ops.TextPositionFilter = function TextPositionFilter(getRootNode) { } } else { // check if there is a non-whitespace character or - // character element in a preceding node + // character element (other than text:s) in a preceding node leftNode = odfUtils.previousNode(container); - if (odfUtils.scanLeftForNonWhitespace(leftNode)) { + if (odfUtils.scanLeftForNonSpace(leftNode)) { r = FILTER_ACCEPT; } } diff --git a/webodf/tests/odf/OdfUtilsTests.js b/webodf/tests/odf/OdfUtilsTests.js index 89da48b5..e13abf8d 100644 --- a/webodf/tests/odf/OdfUtilsTests.js +++ b/webodf/tests/odf/OdfUtilsTests.js @@ -233,6 +233,12 @@ odf.OdfUtilsTests = function OdfUtilsTests(runner) { r.shouldBe(t, "t.isDowngradable", "true"); } + function isDowngradableWhitespace_DowngradesFirstSpaceAfterTab() { + t.doc = createDocument(" b"); + t.isDowngradable = t.odfUtils.isDowngradableSpaceElement(t.doc.childNodes[1]); + + r.shouldBe(t, "t.isDowngradable", "true"); + } function isDowngradableWhitespace_DoesNotDowngradeTrailingSpace() { t.doc = createDocument("a "); t.isDowngradable = t.odfUtils.isDowngradableSpaceElement(t.doc.childNodes[1]); @@ -271,6 +277,7 @@ odf.OdfUtilsTests = function OdfUtilsTests(runner) { getImageElements_ReturnTwoImages, isDowngradableWhitespace_DowngradesFirstSpaceAfterChar, + isDowngradableWhitespace_DowngradesFirstSpaceAfterTab, isDowngradableWhitespace_DoesNotDowngradeTrailingSpace, isDowngradableWhitespace_DoesNotDowngradeLeading, isDowngradableWhitespace_DoesNotDowngradeAfterSpace diff --git a/webodf/tests/ops/OdtDocumentTests.js b/webodf/tests/ops/OdtDocumentTests.js index 5f1af0c1..8f3c750b 100644 --- a/webodf/tests/ops/OdtDocumentTests.js +++ b/webodf/tests/ops/OdtDocumentTests.js @@ -500,6 +500,9 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { testCursorPositions("| |"); // TODO behaviour is different from README_cursorpositions // cursorPositionsTest(" |A| | | |B| "); + testCursorPositions("| | | |"); + testCursorPositions("| | | |"); + testCursorPositions("|a| | | "); } function testAvailablePositions_DrawElements() { testCursorPositions("|data|"); diff --git a/webodf/tests/ops/operationtests.xml b/webodf/tests/ops/operationtests.xml index 65d4a50d..6a34f81f 100644 --- a/webodf/tests/ops/operationtests.xml +++ b/webodf/tests/ops/operationtests.xml @@ -172,7 +172,6 @@ a b - a @@ -288,6 +287,17 @@ a bc + + + + + + + + + + U +