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
+