Loading accessible/src/base/TextUpdater.cpp +36 −58 Original line number Diff line number Diff line Loading @@ -87,21 +87,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText, PRUint32 oldLen = aOldText.Length(), newLen = aNewText.Length(); PRUint32 minLen = NS_MIN(oldLen, newLen); // Text was appended or removed to/from the end. if (aSkipStart == minLen) { // If text has been appended to the end, fire text inserted event. if (oldLen < newLen) { UpdateTextNFireEvent(aNewText, Substring(aNewText, oldLen), oldLen, PR_TRUE); return; } // Text has been removed from the end, fire text removed event. UpdateTextNFireEvent(aNewText, Substring(aOldText, newLen), newLen, PR_FALSE); return; } // Trim coinciding substrings from the end. PRUint32 skipEnd = 0; while (minLen - skipEnd > aSkipStart && Loading @@ -109,25 +94,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText, skipEnd++; } // Text was appended or removed to/from the start. if (skipEnd == minLen) { // If text has been appended to the start, fire text inserted event. if (oldLen < newLen) { UpdateTextNFireEvent(aNewText, Substring(aNewText, 0, newLen - skipEnd), 0, PR_TRUE); return; } // Text has been removed from the start, fire text removed event. UpdateTextNFireEvent(aNewText, Substring(aOldText, 0, oldLen - skipEnd), 0, PR_FALSE); return; } // Find the difference between strings and fire events. // Note: we can skip initial and final coinciding characters since they don't // affect the Levenshtein distance. PRInt32 strLen1 = oldLen - aSkipStart - skipEnd; PRInt32 strLen2 = newLen - aSkipStart - skipEnd; Loading @@ -137,6 +103,42 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText, // Increase offset of the text leaf on skipped characters amount. mTextOffset += aSkipStart; // It could be single insertion or removal or the case of long strings. Do not // calculate the difference between long strings and prefer to fire pair of // insert/remove events as the old string was replaced on the new one. if (strLen1 == 0 || strLen2 == 0 || strLen1 > kMaxStrLen || strLen2 > kMaxStrLen) { if (strLen1 > 0) { // Fire text change event for removal. nsRefPtr<AccEvent> textRemoveEvent = new AccTextChangeEvent(mHyperText, mTextOffset, str1, PR_FALSE); mDocument->FireDelayedAccessibleEvent(textRemoveEvent); } if (strLen2 > 0) { // Fire text change event for insertion. nsRefPtr<AccEvent> textInsertEvent = new AccTextChangeEvent(mHyperText, mTextOffset, str2, PR_TRUE); mDocument->FireDelayedAccessibleEvent(textInsertEvent); } // Fire value change event. if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) { nsRefPtr<AccEvent> valueChangeEvent = new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText, eAutoDetect, AccEvent::eRemoveDupes); mDocument->FireDelayedAccessibleEvent(valueChangeEvent); } // Update the text. mTextLeaf->SetText(aNewText); return; } // Otherwise find the difference between strings and fire events. // Note: we can skip initial and final coinciding characters since they don't // affect the Levenshtein distance. // Compute the flat structured matrix need to compute the difference. PRUint32 len1 = strLen1 + 1, len2 = strLen2 + 1; PRUint32* entries = new PRUint32[len1 * len2]; Loading Loading @@ -238,27 +240,3 @@ TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1, if (colEnd) FireDeleteEvent(Substring(aStr1, 0, colEnd), 0, aEvents); } void TextUpdater::UpdateTextNFireEvent(const nsAString& aNewText, const nsAString& aChangeText, PRUint32 aAddlOffset, PRBool aIsInserted) { // Fire text change event. nsRefPtr<AccEvent> textChangeEvent = new AccTextChangeEvent(mHyperText, mTextOffset + aAddlOffset, aChangeText, aIsInserted); mDocument->FireDelayedAccessibleEvent(textChangeEvent); // Fire value change event. if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) { nsRefPtr<AccEvent> valueChangeEvent = new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText, eAutoDetect, AccEvent::eRemoveDupes); mDocument->FireDelayedAccessibleEvent(valueChangeEvent); } // Update the text. mTextLeaf->SetText(aNewText); } accessible/src/base/TextUpdater.h +3 −4 Original line number Diff line number Diff line Loading @@ -108,11 +108,10 @@ private: } /** * Update the text and fire text change/value change events. * The constant used to skip string difference calculation in case of long * strings. */ void UpdateTextNFireEvent(const nsAString& aNewText, const nsAString& aChangeText, PRUint32 aAddlOffset, PRBool aIsInserted); const static PRUint32 kMaxStrLen = 1 << 6; private: nsDocAccessible* mDocument; Loading accessible/src/msaa/nsAccessibleWrap.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -234,9 +234,16 @@ __try { STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren) { __try { if (!pcountChildren) return E_INVALIDARG; *pcountChildren = 0; if (IsDefunct()) return E_FAIL; if (nsAccUtils::MustPrune(this)) return NS_OK; return S_OK; *pcountChildren = GetChildCount(); } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { } Loading accessible/src/xul/nsXULFormControlAccessible.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -682,6 +682,9 @@ NS_IMPL_ISUPPORTS_INHERITED3(nsXULTextFieldAccessible, nsAccessible, nsHyperText NS_IMETHODIMP nsXULTextFieldAccessible::GetValue(nsAString& aValue) { if (IsDefunct()) return NS_ERROR_FAILURE; PRUint64 state = NativeState(); if (state & states::PROTECTED) // Don't return password text! Loading accessible/tests/mochitest/events/test_text_alg.html +49 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ const kRemoval = 0; const kInsertion = 1; const kUnexpected = true; function changeText(aContainerID, aValue, aEventList) { Loading @@ -32,13 +33,21 @@ this.textData = this.textNode.data; this.eventSeq = [ ]; this.unexpectedEventSeq = [ ]; for (var i = 0; i < aEventList.length; i++) { var isInserted = aEventList[i][0]; var str = aEventList[i][1]; var offset = aEventList[i][2]; var event = aEventList[i]; var isInserted = event[0]; var str = event[1]; var offset = event[2]; var checker = new textChangeChecker(this.containerNode, offset, offset + str.length, str, isInserted); if (eventItem[3] == kUnexpected) this.unexpectedEventSeq.push(checker); else this.eventSeq.push(checker); } Loading @@ -54,6 +63,13 @@ } } function expStr(x, doublings) { for (var i = 0; i < doublings; ++i) x = x + x; return x; } //////////////////////////////////////////////////////////////////////////// // Do tests Loading Loading @@ -167,6 +183,34 @@ ]; gQueue.push(new changeText("p11", "levenshtein", events)); ////////////////////////////////////////////////////////////////////////// // long strings, remove/insert pair as the old string was replaced on // new one var longStr1 = expStr("x", 16); var longStr2 = expStr("X", 16); var newStr = "a" + longStr1 + "b", insStr = longStr1, rmStr = ""; events = [ [ kRemoval, rmStr, 1, kUnexpected ], [ kInsertion, insStr, 1 ] ]; gQueue.push(new changeText("p12", newStr, events)); newStr = "a" + longStr2 + "b", insStr = longStr2, rmStr = longStr1; events = [ [ kRemoval, rmStr, 1 ], [ kInsertion, insStr, 1] ]; gQueue.push(new changeText("p12", newStr, events)); newStr = "ab", insStr = "", rmStr = longStr2; events = [ [ kRemoval, rmStr, 1 ], [ kInsertion, insStr, 1, kUnexpected ] ]; gQueue.push(new changeText("p12", newStr, events)); gQueue.invoke(); // Will call SimpleTest.finish(); } Loading Loading @@ -201,5 +245,6 @@ <p id="p9">abcDEFabc</p> <p id="p10">!abcdef@</p> <p id="p11">meilenstein</p> <p id="p12">ab</p> </body> </html> Loading
accessible/src/base/TextUpdater.cpp +36 −58 Original line number Diff line number Diff line Loading @@ -87,21 +87,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText, PRUint32 oldLen = aOldText.Length(), newLen = aNewText.Length(); PRUint32 minLen = NS_MIN(oldLen, newLen); // Text was appended or removed to/from the end. if (aSkipStart == minLen) { // If text has been appended to the end, fire text inserted event. if (oldLen < newLen) { UpdateTextNFireEvent(aNewText, Substring(aNewText, oldLen), oldLen, PR_TRUE); return; } // Text has been removed from the end, fire text removed event. UpdateTextNFireEvent(aNewText, Substring(aOldText, newLen), newLen, PR_FALSE); return; } // Trim coinciding substrings from the end. PRUint32 skipEnd = 0; while (minLen - skipEnd > aSkipStart && Loading @@ -109,25 +94,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText, skipEnd++; } // Text was appended or removed to/from the start. if (skipEnd == minLen) { // If text has been appended to the start, fire text inserted event. if (oldLen < newLen) { UpdateTextNFireEvent(aNewText, Substring(aNewText, 0, newLen - skipEnd), 0, PR_TRUE); return; } // Text has been removed from the start, fire text removed event. UpdateTextNFireEvent(aNewText, Substring(aOldText, 0, oldLen - skipEnd), 0, PR_FALSE); return; } // Find the difference between strings and fire events. // Note: we can skip initial and final coinciding characters since they don't // affect the Levenshtein distance. PRInt32 strLen1 = oldLen - aSkipStart - skipEnd; PRInt32 strLen2 = newLen - aSkipStart - skipEnd; Loading @@ -137,6 +103,42 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText, // Increase offset of the text leaf on skipped characters amount. mTextOffset += aSkipStart; // It could be single insertion or removal or the case of long strings. Do not // calculate the difference between long strings and prefer to fire pair of // insert/remove events as the old string was replaced on the new one. if (strLen1 == 0 || strLen2 == 0 || strLen1 > kMaxStrLen || strLen2 > kMaxStrLen) { if (strLen1 > 0) { // Fire text change event for removal. nsRefPtr<AccEvent> textRemoveEvent = new AccTextChangeEvent(mHyperText, mTextOffset, str1, PR_FALSE); mDocument->FireDelayedAccessibleEvent(textRemoveEvent); } if (strLen2 > 0) { // Fire text change event for insertion. nsRefPtr<AccEvent> textInsertEvent = new AccTextChangeEvent(mHyperText, mTextOffset, str2, PR_TRUE); mDocument->FireDelayedAccessibleEvent(textInsertEvent); } // Fire value change event. if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) { nsRefPtr<AccEvent> valueChangeEvent = new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText, eAutoDetect, AccEvent::eRemoveDupes); mDocument->FireDelayedAccessibleEvent(valueChangeEvent); } // Update the text. mTextLeaf->SetText(aNewText); return; } // Otherwise find the difference between strings and fire events. // Note: we can skip initial and final coinciding characters since they don't // affect the Levenshtein distance. // Compute the flat structured matrix need to compute the difference. PRUint32 len1 = strLen1 + 1, len2 = strLen2 + 1; PRUint32* entries = new PRUint32[len1 * len2]; Loading Loading @@ -238,27 +240,3 @@ TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1, if (colEnd) FireDeleteEvent(Substring(aStr1, 0, colEnd), 0, aEvents); } void TextUpdater::UpdateTextNFireEvent(const nsAString& aNewText, const nsAString& aChangeText, PRUint32 aAddlOffset, PRBool aIsInserted) { // Fire text change event. nsRefPtr<AccEvent> textChangeEvent = new AccTextChangeEvent(mHyperText, mTextOffset + aAddlOffset, aChangeText, aIsInserted); mDocument->FireDelayedAccessibleEvent(textChangeEvent); // Fire value change event. if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) { nsRefPtr<AccEvent> valueChangeEvent = new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText, eAutoDetect, AccEvent::eRemoveDupes); mDocument->FireDelayedAccessibleEvent(valueChangeEvent); } // Update the text. mTextLeaf->SetText(aNewText); }
accessible/src/base/TextUpdater.h +3 −4 Original line number Diff line number Diff line Loading @@ -108,11 +108,10 @@ private: } /** * Update the text and fire text change/value change events. * The constant used to skip string difference calculation in case of long * strings. */ void UpdateTextNFireEvent(const nsAString& aNewText, const nsAString& aChangeText, PRUint32 aAddlOffset, PRBool aIsInserted); const static PRUint32 kMaxStrLen = 1 << 6; private: nsDocAccessible* mDocument; Loading
accessible/src/msaa/nsAccessibleWrap.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -234,9 +234,16 @@ __try { STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren) { __try { if (!pcountChildren) return E_INVALIDARG; *pcountChildren = 0; if (IsDefunct()) return E_FAIL; if (nsAccUtils::MustPrune(this)) return NS_OK; return S_OK; *pcountChildren = GetChildCount(); } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { } Loading
accessible/src/xul/nsXULFormControlAccessible.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -682,6 +682,9 @@ NS_IMPL_ISUPPORTS_INHERITED3(nsXULTextFieldAccessible, nsAccessible, nsHyperText NS_IMETHODIMP nsXULTextFieldAccessible::GetValue(nsAString& aValue) { if (IsDefunct()) return NS_ERROR_FAILURE; PRUint64 state = NativeState(); if (state & states::PROTECTED) // Don't return password text! Loading
accessible/tests/mochitest/events/test_text_alg.html +49 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ const kRemoval = 0; const kInsertion = 1; const kUnexpected = true; function changeText(aContainerID, aValue, aEventList) { Loading @@ -32,13 +33,21 @@ this.textData = this.textNode.data; this.eventSeq = [ ]; this.unexpectedEventSeq = [ ]; for (var i = 0; i < aEventList.length; i++) { var isInserted = aEventList[i][0]; var str = aEventList[i][1]; var offset = aEventList[i][2]; var event = aEventList[i]; var isInserted = event[0]; var str = event[1]; var offset = event[2]; var checker = new textChangeChecker(this.containerNode, offset, offset + str.length, str, isInserted); if (eventItem[3] == kUnexpected) this.unexpectedEventSeq.push(checker); else this.eventSeq.push(checker); } Loading @@ -54,6 +63,13 @@ } } function expStr(x, doublings) { for (var i = 0; i < doublings; ++i) x = x + x; return x; } //////////////////////////////////////////////////////////////////////////// // Do tests Loading Loading @@ -167,6 +183,34 @@ ]; gQueue.push(new changeText("p11", "levenshtein", events)); ////////////////////////////////////////////////////////////////////////// // long strings, remove/insert pair as the old string was replaced on // new one var longStr1 = expStr("x", 16); var longStr2 = expStr("X", 16); var newStr = "a" + longStr1 + "b", insStr = longStr1, rmStr = ""; events = [ [ kRemoval, rmStr, 1, kUnexpected ], [ kInsertion, insStr, 1 ] ]; gQueue.push(new changeText("p12", newStr, events)); newStr = "a" + longStr2 + "b", insStr = longStr2, rmStr = longStr1; events = [ [ kRemoval, rmStr, 1 ], [ kInsertion, insStr, 1] ]; gQueue.push(new changeText("p12", newStr, events)); newStr = "ab", insStr = "", rmStr = longStr2; events = [ [ kRemoval, rmStr, 1 ], [ kInsertion, insStr, 1, kUnexpected ] ]; gQueue.push(new changeText("p12", newStr, events)); gQueue.invoke(); // Will call SimpleTest.finish(); } Loading Loading @@ -201,5 +245,6 @@ <p id="p9">abcDEFabc</p> <p id="p10">!abcdef@</p> <p id="p11">meilenstein</p> <p id="p12">ab</p> </body> </html>