Bug 1338445 - Restrict whitespace match in phone number regex for AccessibleCaret.
In phoneRegex, replace '\\s ' (matching a whitespace character) with ' '
since phone number won't contain something like new line or tab.
Also, consider it done if selected text is not changed after calling
Modify().
MozReview-Commit-ID: 2lB9w2gYCOD
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -946,38 +946,48 @@ AccessibleCaretManager::ExtendPhoneNumbe
if (!anchorFocusRange) {
return;
}
// Backup the anchor focus range since both anchor node and focus node might
// be changed after calling Selection::Modify().
RefPtr<nsRange> oldAnchorFocusRange = anchorFocusRange->CloneRange();
- // Save current Focus position, and extend the selection one char.
- nsINode* focusNode = selection->GetFocusNode();
- uint32_t focusOffset = selection->FocusOffset();
+ // Save current focus node, focus offset and the selected text so that
+ // we can compare them with the modified ones later.
+ nsINode* oldFocusNode = selection->GetFocusNode();
+ uint32_t oldFocusOffset = selection->FocusOffset();
+ nsAutoString oldSelectedText;
+ selection->Stringify(oldSelectedText);
+
+ // Extend the selection by one char.
selection->Modify(NS_LITERAL_STRING("extend"),
aDirection,
NS_LITERAL_STRING("character"));
if (IsTerminated()) {
return;
}
// If the selection didn't change, (can't extend further), we're done.
- if (selection->GetFocusNode() == focusNode &&
- selection->FocusOffset() == focusOffset) {
+ if (selection->GetFocusNode() == oldFocusNode &&
+ selection->FocusOffset() == oldFocusOffset) {
return;
}
// If the changed selection isn't a valid phone number, we're done.
+ // Also, if the selection was extended to a new block node, the string
+ // returned by stringify() won't have a new line at the beginning or the
+ // end of the string. Therefore, if either focus node or offset is
+ // changed, but selected text is not changed, we're done, too.
nsAutoString selectedText;
selection->Stringify(selectedText);
- nsAutoString phoneRegex(NS_LITERAL_STRING("(^\\+)?[0-9\\s,\\-.()*#pw]{1,30}$"));
+ nsAutoString phoneRegex(NS_LITERAL_STRING("(^\\+)?[0-9 ,\\-.()*#pw]{1,30}$"));
- if (!nsContentUtils::IsPatternMatching(selectedText, phoneRegex, doc)) {
+ if (!nsContentUtils::IsPatternMatching(selectedText, phoneRegex, doc) ||
+ oldSelectedText == selectedText) {
// Backout the undesired selection extend, restore the old anchor focus
// range before exit.
selection->SetAnchorFocusToRange(oldAnchorFocusRange);
return;
}
}
}
--- a/mobile/android/tests/browser/robocop/testAccessibleCarets.html
+++ b/mobile/android/tests/browser/robocop/testAccessibleCarets.html
@@ -36,10 +36,15 @@
<input id="LTRphone" style="direction: ltr;" size="40"
value="09876543210 .-.)(wp#*1034103410341034X">
<br>
<input id="RTLphone" style="direction: rtl;" size="40"
value="התקשר +972 3 7347514 במשך זמן טוב">
<br><br><br>
<div>x<input value="DDs12">3 45<em id="bug1265750"> 678</em> 90</div>
+ <br><br><br>
+ <tr><td>cell</td><td><p id="bug1338445-1">012345p</p></td><td>cell</td></tr>
+ <br><br><br>
+ <div><p>p12</p><p id="bug1338445-2">p34</p><p>p56</p></div>
+ </tr>
</body>
</html>
--- a/mobile/android/tests/browser/robocop/testAccessibleCarets.js
+++ b/mobile/android/tests/browser/robocop/testAccessibleCarets.js
@@ -177,31 +177,35 @@ add_task(function* testAccessibleCarets(
let ce_RTL_elem = doc.getElementById("RTLcontenteditable");
let tc_RTL_elem = doc.getElementById("RTLtextContent");
let i_RTL_elem = doc.getElementById("RTLinput");
let ta_RTL_elem = doc.getElementById("RTLtextarea");
let ip_LTR_elem = doc.getElementById("LTRphone");
let ip_RTL_elem = doc.getElementById("RTLphone");
let bug1265750_elem = doc.getElementById("bug1265750");
+ let bug1338445_elem1 = doc.getElementById("bug1338445-1");
+ let bug1338445_elem2 = doc.getElementById("bug1338445-2");
// Locate longpress midpoints for test elements, ensure expactations.
let ce_LTR_midPoint = getCharPressPoint(doc, ce_LTR_elem, 0, "F");
let tc_LTR_midPoint = getCharPressPoint(doc, tc_LTR_elem, 0, "O");
let i_LTR_midPoint = getCharPressPoint(doc, i_LTR_elem, 0, "T");
let ta_LTR_midPoint = getCharPressPoint(doc, ta_LTR_elem, 0, "W");
let ce_RTL_midPoint = getCharPressPoint(doc, ce_RTL_elem, 0, "א");
let tc_RTL_midPoint = getCharPressPoint(doc, tc_RTL_elem, 0, "ת");
let i_RTL_midPoint = getCharPressPoint(doc, i_RTL_elem, 0, "ל");
let ta_RTL_midPoint = getCharPressPoint(doc, ta_RTL_elem, 0, "ה");
let ip_LTR_midPoint = getCharPressPoint(doc, ip_LTR_elem, 8, "2");
let ip_RTL_midPoint = getCharPressPoint(doc, ip_RTL_elem, 9, "2");
let bug1265750_midPoint = getCharPressPoint(doc, bug1265750_elem, 2, "7");
+ let bug1338445_midPoint1 = getCharPressPoint(doc, bug1338445_elem1, 3, "3");
+ let bug1338445_midPoint2 = getCharPressPoint(doc, bug1338445_elem2, 1, "3");
// Longpress various LTR content elements. Test focused element against
// expected, and selected text against expected.
let result = getLongPressResult(browser, ce_LTR_midPoint);
is(result.focusedElement, ce_LTR_elem, "Focused element should match expected.");
is(result.text, "Find", "Selected text should match expected text.");
result = getLongPressResult(browser, tc_LTR_midPoint);
@@ -223,16 +227,26 @@ add_task(function* testAccessibleCarets(
is(result.text.length, 30,
"Selected phone number length should match expected maximum.");
result = getLongPressResult(browser, bug1265750_midPoint);
is(result.focusedElement, null, "Focused element should match expected.");
is(result.text, "3 45 678 90",
"Selected phone number should match expected text.");
+ result = getLongPressResult(browser, bug1338445_midPoint1);
+ is(result.focusedElement, null, "Focused element should match expected.");
+ is(result.text, "012345p",
+ "Selected phone number should match expected text.");
+
+ result = getLongPressResult(browser, bug1338445_midPoint2);
+ is(result.focusedElement, null, "Focused element should match expected.");
+ is(result.text, "p34",
+ "Selected phone number should match expected text.");
+
// Longpress various RTL content elements. Test focused element against
// expected, and selected text against expected.
result = getLongPressResult(browser, ce_RTL_midPoint);
is(result.focusedElement, ce_RTL_elem, "Focused element should match expected.");
is(result.text, "איפה", "Selected text should match expected text.");
result = getLongPressResult(browser, tc_RTL_midPoint);
is(result.focusedElement, null, "No focused element is expected.");