Bug 445677 - optimization for text attributes offset (do not look into embedded characters, r=marcoz

This commit is contained in:
Alexander Surkov 2010-05-25 17:40:26 +09:00
parent 4dac627a91
commit 3b24543774
5 changed files with 222 additions and 305 deletions

View File

@ -81,11 +81,11 @@ static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
// nsTextAttrs
nsTextAttrsMgr::nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
nsIDOMNode *aHyperTextNode,
PRBool aIncludeDefAttrs,
nsIDOMNode *aOffsetNode) :
mHyperTextAcc(aHyperTextAcc), mHyperTextNode(aHyperTextNode),
mIncludeDefAttrs(aIncludeDefAttrs), mOffsetNode(aOffsetNode)
nsAccessible *aOffsetAcc,
PRInt32 aOffsetAccIdx) :
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx)
{
}
@ -94,33 +94,61 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
PRInt32 *aStartHTOffset,
PRInt32 *aEndHTOffset)
{
// 1. Hyper text accessible and its DOM node must be specified always.
// 2. Offset DOM node and result hyper text offsets must be specifed in
// 1. Hyper text accessible must be specified always.
// 2. Offset accessible and result hyper text offsets must be specified in
// the case of text attributes.
// 3. Offset DOM node and result hyper text offsets must not be specifed but
// include default text attributes flag and attributes list must be specified
// in the case of default text attributes.
NS_PRECONDITION(mHyperTextAcc && mHyperTextNode &&
((mOffsetNode && aStartHTOffset && aEndHTOffset) ||
(!mOffsetNode && !aStartHTOffset && !aEndHTOffset &&
// 3. Offset accessible and result hyper text offsets must not be specified
// but include default text attributes flag and attributes list must be
// specified in the case of default text attributes.
NS_PRECONDITION(mHyperTextAcc &&
((mOffsetAcc && mOffsetAccIdx != -1 &&
aStartHTOffset && aEndHTOffset) ||
(!mOffsetAcc && mOffsetAccIdx == -1 &&
!aStartHTOffset && !aEndHTOffset &&
mIncludeDefAttrs && aAttributes)),
"Wrong usage of nsTextAttrsMgr!");
nsCOMPtr<nsIDOMElement> hyperTextElm =
nsCoreUtils::GetDOMElementFor(mHyperTextNode);
nsCOMPtr<nsIDOMElement> offsetElm;
if (mOffsetNode)
offsetElm = nsCoreUtils::GetDOMElementFor(mOffsetNode);
// Embedded objects are combined into own range with empty attributes set.
if (mOffsetAcc && nsAccUtils::IsEmbeddedObject(mOffsetAcc)) {
for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
if (!nsAccUtils::IsEmbeddedObject(currAcc))
break;
(*aStartHTOffset)--;
}
PRInt32 childCount = mHyperTextAcc->GetChildCount();
for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childCount;
childIdx++) {
nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
if (!nsAccUtils::IsEmbeddedObject(currAcc))
break;
(*aEndHTOffset)++;
}
return NS_OK;
}
nsIDOMNode *hyperTextNode = mHyperTextAcc->GetDOMNode();
nsCOMPtr<nsIDOMElement> hyperTextElm =
nsCoreUtils::GetDOMElementFor(mHyperTextAcc->GetDOMNode());
nsIFrame *rootFrame = nsCoreUtils::GetFrameFor(hyperTextElm);
nsIDOMNode *offsetNode = nsnull;
nsCOMPtr<nsIDOMElement> offsetElm;
nsIFrame *frame = nsnull;
if (offsetElm)
if (mOffsetAcc) {
offsetNode = mOffsetAcc->GetDOMNode();
offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
frame = nsCoreUtils::GetFrameFor(offsetElm);
}
nsTPtrArray<nsITextAttr> textAttrArray(10);
// "language" text attribute
nsLangTextAttr langTextAttr(mHyperTextAcc, mHyperTextNode, mOffsetNode);
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextNode, offsetNode);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr));
// "color" text attribute
@ -174,7 +202,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsresult rv = NS_OK;
// Expose text attributes range where they are applied if applicable.
if (mOffsetNode)
if (mOffsetAcc)
rv = GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
textAttrArray.Clear();
@ -185,211 +213,68 @@ nsresult
nsTextAttrsMgr::GetRange(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset)
{
nsCOMPtr<nsIDOMElement> rootElm =
nsCoreUtils::GetDOMElementFor(mHyperTextNode);
NS_ENSURE_STATE(rootElm);
PRUint32 attrLen = aTextAttrArray.Length();
nsCOMPtr<nsIDOMNode> tmpNode(mOffsetNode);
nsCOMPtr<nsIDOMNode> currNode(mOffsetNode);
// Navigate backward from anchor accessible to find start offset.
for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
PRUint32 len = aTextAttrArray.Length();
// Navigate backwards and forwards from current node to the root node to
// calculate range bounds for the text attribute. Navigation sequence is the
// following:
// 1. Navigate through the siblings.
// 2. If the traversed sibling has children then navigate from its leaf child
// to it through whole tree of the traversed sibling.
// 3. Get the parent and cycle algorithm until the root node.
// Navigate backwards (find the start offset).
while (currNode && currNode != rootElm) {
nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(currNode));
NS_ENSURE_STATE(currElm);
if (currNode != mOffsetNode) {
PRBool stop = PR_FALSE;
for (PRUint32 idx = 0; idx < len; idx++) {
nsITextAttr *textAttr = aTextAttrArray[idx];
if (!textAttr->Equal(currElm)) {
PRInt32 startHTOffset = 0;
nsAccessible *startAcc = mHyperTextAcc->
DOMPointToHypertextOffset(tmpNode, -1, &startHTOffset);
if (!startAcc)
startHTOffset = 0;
if (startHTOffset > *aStartHTOffset)
*aStartHTOffset = startHTOffset;
stop = PR_TRUE;
break;
}
}
if (stop)
break;
}
currNode->GetPreviousSibling(getter_AddRefs(tmpNode));
if (tmpNode) {
// Navigate through the subtree of traversed children to calculate
// left bound of the range.
FindStartOffsetInSubtree(aTextAttrArray, tmpNode, currNode,
aStartHTOffset);
}
currNode->GetParentNode(getter_AddRefs(tmpNode));
currNode.swap(tmpNode);
}
// Navigate forwards (find the end offset).
PRBool moveIntoSubtree = PR_TRUE;
currNode = mOffsetNode;
while (currNode && currNode != rootElm) {
nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(currNode));
NS_ENSURE_STATE(currElm);
// Stop new end offset searching if the given text attribute changes its
// value.
PRBool stop = PR_FALSE;
for (PRUint32 idx = 0; idx < len; idx++) {
nsITextAttr *textAttr = aTextAttrArray[idx];
if (!textAttr->Equal(currElm)) {
PRInt32 endHTOffset = 0;
mHyperTextAcc->DOMPointToHypertextOffset(currNode, -1, &endHTOffset);
if (endHTOffset < *aEndHTOffset)
*aEndHTOffset = endHTOffset;
stop = PR_TRUE;
break;
}
}
if (stop)
// Stop on embedded accessible since embedded accessibles are combined into
// own range.
if (nsAccUtils::IsEmbeddedObject(currAcc))
break;
if (moveIntoSubtree) {
// Navigate through subtree of traversed node. We use 'moveIntoSubtree'
// flag to avoid traversing the same subtree twice.
currNode->GetFirstChild(getter_AddRefs(tmpNode));
if (tmpNode)
FindEndOffsetInSubtree(aTextAttrArray, tmpNode, aEndHTOffset);
nsCOMPtr<nsIDOMElement> currElm =
nsCoreUtils::GetDOMElementFor(currAcc->GetDOMNode());
NS_ENSURE_STATE(currElm);
PRBool offsetFound = PR_FALSE;
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
nsITextAttr *textAttr = aTextAttrArray[attrIdx];
if (!textAttr->Equal(currElm)) {
offsetFound = PR_TRUE;
break;
}
}
currNode->GetNextSibling(getter_AddRefs(tmpNode));
moveIntoSubtree = PR_TRUE;
if (!tmpNode) {
currNode->GetParentNode(getter_AddRefs(tmpNode));
moveIntoSubtree = PR_FALSE;
if (offsetFound)
break;
*(aStartHTOffset) -= nsAccUtils::TextLength(currAcc);
}
// Navigate forward from anchor accessible to find end offset.
PRInt32 childLen = mHyperTextAcc->GetChildCount();
for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
if (nsAccUtils::IsEmbeddedObject(currAcc))
break;
nsCOMPtr<nsIDOMElement> currElm =
nsCoreUtils::GetDOMElementFor(currAcc->GetDOMNode());
NS_ENSURE_STATE(currElm);
PRBool offsetFound = PR_FALSE;
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
nsITextAttr *textAttr = aTextAttrArray[attrIdx];
// Alter the end offset when text attribute changes its value and stop
// the search.
if (!textAttr->Equal(currElm)) {
offsetFound = PR_TRUE;
break;
}
}
currNode.swap(tmpNode);
if (offsetFound)
break;
(*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
}
return NS_OK;
}
PRBool
nsTextAttrsMgr::FindEndOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
nsIDOMNode *aCurrNode,
PRInt32 *aHTOffset)
{
if (!aCurrNode)
return PR_FALSE;
nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(aCurrNode));
if (!currElm)
return PR_FALSE;
// If the given text attribute (pointed by nsTextAttr object) changes its
// value on the traversed element then fit the end of range.
PRUint32 len = aTextAttrArray.Length();
for (PRUint32 idx = 0; idx < len; idx++) {
nsITextAttr *textAttr = aTextAttrArray[idx];
if (!textAttr->Equal(currElm)) {
PRInt32 endHTOffset = 0;
mHyperTextAcc->DOMPointToHypertextOffset(aCurrNode, -1, &endHTOffset);
if (endHTOffset < *aHTOffset)
*aHTOffset = endHTOffset;
return PR_TRUE;
}
}
// Deeply traverse into the tree to fit the end of range.
nsCOMPtr<nsIDOMNode> nextNode;
aCurrNode->GetFirstChild(getter_AddRefs(nextNode));
if (nextNode) {
PRBool res = FindEndOffsetInSubtree(aTextAttrArray, nextNode, aHTOffset);
if (res)
return res;
}
aCurrNode->GetNextSibling(getter_AddRefs(nextNode));
if (nextNode) {
if (FindEndOffsetInSubtree(aTextAttrArray, nextNode, aHTOffset))
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsTextAttrsMgr::FindStartOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
nsIDOMNode *aCurrNode,
nsIDOMNode *aPrevNode,
PRInt32 *aHTOffset)
{
if (!aCurrNode)
return PR_FALSE;
// Find the closest element back to the traversed element.
nsCOMPtr<nsIDOMNode> nextNode;
aCurrNode->GetLastChild(getter_AddRefs(nextNode));
if (nextNode) {
if (FindStartOffsetInSubtree(aTextAttrArray, nextNode, aPrevNode, aHTOffset))
return PR_TRUE;
}
nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(aCurrNode));
if (!currElm)
return PR_FALSE;
// If the given text attribute (pointed by nsTextAttr object) changes its
// value on the traversed element then fit the start of range.
PRUint32 len = aTextAttrArray.Length();
for (PRUint32 idx = 0; idx < len; idx++) {
nsITextAttr *textAttr = aTextAttrArray[idx];
if (!textAttr->Equal(currElm)) {
PRInt32 startHTOffset = 0;
nsAccessible *startAcc = mHyperTextAcc->
DOMPointToHypertextOffset(aPrevNode, -1, &startHTOffset);
if (!startAcc)
startHTOffset = 0;
if (startHTOffset > *aHTOffset)
*aHTOffset = startHTOffset;
return PR_TRUE;
}
}
// Moving backwards to find the start of range.
aCurrNode->GetPreviousSibling(getter_AddRefs(nextNode));
if (nextNode) {
if (FindStartOffsetInSubtree(aTextAttrArray, nextNode, aCurrNode, aHTOffset))
return PR_TRUE;
}
return PR_FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// nsLangTextAttr

View File

@ -69,7 +69,7 @@ class nsTextAttrsMgr
public:
/**
* Constructor. If instance of the class is intended to expose default text
* attributes then 'aIncludeDefAttrs' and 'oOffsetNode' argument must be
* attributes then 'aIncludeDefAttrs' and 'aOffsetNode' argument must be
* skiped.
*
* @param aHyperTextAcc hyper text accessible text attributes are
@ -82,9 +82,9 @@ public:
* inside hyper text accessible
*/
nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
nsIDOMNode *aHyperTextNode,
PRBool aIncludeDefAttrs = PR_TRUE,
nsIDOMNode *oOffsetNode = nsnull);
nsAccessible *aOffsetAcc = nsnull,
PRInt32 aOffsetAccIdx = -1);
/*
* Return text attributes and hyper text offsets where these attributes are
@ -115,41 +115,13 @@ protected:
nsresult GetRange(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset);
/*
* Find new end offset for text attributes navigating through the tree. New
* end offset may be smaller if one of text attributes changes its value
* before the given end offset.
*
* @param aTextAttrArray [in] text attributes array
* @param aCurrNode [in] the first node of the tree
* @param aHTOffset [in, out] the end offset
* @return true if the end offset has been changed
*/
PRBool FindEndOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
nsIDOMNode *aCurrNode, PRInt32 *aHTOffset);
/*
* Find the start offset for text attributes navigating through the tree. New
* start offset may be bigger if one of text attributes changes its value
* after the given start offset.
*
* @param aTextAttrArray [in] text attributes array
* @param aCurrNode [in] the node navigating through thee thee is
* started from
* @param aPrevNode [in] the previous node placed before the start node
* @param aHTOffset [in, out] the start offset
* @return true if the start offset has been changed
*/
PRBool FindStartOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
nsIDOMNode *aCurrNode, nsIDOMNode *aPrevNode,
PRInt32 *aHTOffset);
private:
nsRefPtr<nsHyperTextAccessible> mHyperTextAcc;
nsCOMPtr<nsIDOMNode> mHyperTextNode;
PRBool mIncludeDefAttrs;
nsCOMPtr<nsIDOMNode> mOffsetNode;
nsRefPtr<nsAccessible> mOffsetAcc;
PRInt32 mOffsetAccIdx;
};

View File

@ -1084,23 +1084,16 @@ nsHyperTextAccessible::GetTextAttributes(PRBool aIncludeDefAttrs,
PRInt32 *aEndOffset,
nsIPersistentProperties **aAttributes)
{
// 1. First we get spell check, then language, then the set of CSS-based
// attributes.
// 1. Get each attribute and its ranges one after another.
// 2. As we get each new attribute, we pass the current start and end offsets
// as in/out parameters. In other words, as attributes are collected,
// the attribute range itself can only stay the same or get smaller.
//
// Example:
// Current: range 5-10
// Adding: range 7-12
// Result: range 7-10
NS_ENSURE_ARG_POINTER(aStartOffset);
*aStartOffset = 0;
NS_ENSURE_ARG_POINTER(aEndOffset);
nsresult rv = GetCharacterCount(aEndOffset);
NS_ENSURE_SUCCESS(rv, rv);
*aEndOffset = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
@ -1115,62 +1108,49 @@ nsHyperTextAccessible::GetTextAttributes(PRBool aIncludeDefAttrs,
NS_ADDREF(*aAttributes = attributes);
}
// Offset 0 is correct offset when accessible has empty text. Include
// default attributes if they were requested, otherwise return empty set.
if (aOffset == 0) {
// XXX: bug 567321. We handle here the cases when there are no children
// or when existing children have zero length.
PRBool isEmpty = PR_TRUE;
PRInt32 childCount = GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible *child = mChildren[childIdx];
if (!nsAccUtils::IsText(child) || nsAccUtils::TextLength(child) > 0) {
isEmpty = PR_FALSE;
break;
}
}
if (isEmpty) {
PRInt32 offsetAccIdx = -1;
PRInt32 startOffset = 0, endOffset = 0;
nsAccessible *offsetAcc = GetAccessibleAtOffset(aOffset, &offsetAccIdx,
&startOffset, &endOffset);
if (!offsetAcc) {
// Offset 0 is correct offset when accessible has empty text. Include
// default attributes if they were requested, otherwise return empty set.
if (aOffset == 0) {
if (aIncludeDefAttrs) {
nsTextAttrsMgr textAttrsMgr(this, mDOMNode, PR_TRUE, nsnull);
nsTextAttrsMgr textAttrsMgr(this, PR_TRUE, nsnull, -1);
return textAttrsMgr.GetAttributes(*aAttributes);
}
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
// Get the frame and accessible at the given offset.
PRInt32 startOffset = aOffset, endOffset = aOffset;
nsRefPtr<nsAccessible> startAcc;
nsIFrame *startFrame = GetPosAndText(startOffset, endOffset,
nsnull, nsnull, nsnull,
getter_AddRefs(startAcc), nsnull);
PRInt32 offsetInAcc = aOffset - startOffset;
// No start frame or accessible means wrong given offset.
if (!startFrame || !startAcc)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIDOMNode> node;
PRInt32 nodeOffset = 0;
rv = GetDOMPointByFrameOffset(startFrame, startOffset, startAcc,
getter_AddRefs(node), &nodeOffset);
nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, offsetAcc, offsetAccIdx);
nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// Set 'misspelled' text attribute.
rv = GetSpellTextAttribute(node, nodeOffset, aStartOffset, aEndOffset,
aAttributes ? *aAttributes : nsnull);
NS_ENSURE_SUCCESS(rv, rv);
// Compute spelling attributes on text accessible only.
nsIFrame *offsetFrame = offsetAcc->GetFrame();
if (offsetFrame && offsetFrame->GetType() == nsAccessibilityAtoms::textFrame) {
nsCOMPtr<nsIDOMNode> node = offsetAcc->GetDOMNode();
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
if (content && content->IsElement())
node = do_QueryInterface(content->GetChildAt(nodeOffset));
PRInt32 nodeOffset = 0;
nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
&nodeOffset);
NS_ENSURE_SUCCESS(rv, rv);
if (!node)
return NS_OK;
// Set 'misspelled' text attribute.
rv = GetSpellTextAttribute(node, nodeOffset, &startOffset, &endOffset,
aAttributes ? *aAttributes : nsnull);
NS_ENSURE_SUCCESS(rv, rv);
}
nsTextAttrsMgr textAttrsMgr(this, mDOMNode, aIncludeDefAttrs, node);
return textAttrsMgr.GetAttributes(*aAttributes, aStartOffset, aEndOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
return NS_OK;
}
// nsIPersistentProperties
@ -1181,16 +1161,16 @@ nsHyperTextAccessible::GetDefaultTextAttributes(nsIPersistentProperties **aAttri
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPersistentProperties> attributes =
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aAttributes = attributes);
if (!mDOMNode)
return NS_ERROR_FAILURE;
nsTextAttrsMgr textAttrsMgr(this, mDOMNode, PR_TRUE, nsnull);
nsTextAttrsMgr textAttrsMgr(this, PR_TRUE);
return textAttrsMgr.GetAttributes(*aAttributes);
}
@ -2130,6 +2110,32 @@ nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHyperTextAccessible protected
nsAccessible *
nsHyperTextAccessible::GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
PRInt32 *aStartOffset,
PRInt32 *aEndOffset)
{
PRInt32 startOffset = 0, endOffset = 0;
PRInt32 childCount = GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible *child = mChildren[childIdx];
endOffset += nsAccUtils::TextLength(child);
if (endOffset > aOffset) {
*aStartOffset = startOffset;
*aEndOffset = endOffset;
*aAccIdx = childIdx;
return child;
}
startOffset = endOffset;
}
return nsnull;
}
nsresult
nsHyperTextAccessible::GetDOMPointByFrameOffset(nsIFrame *aFrame,
PRInt32 aOffset,

View File

@ -252,6 +252,18 @@ protected:
*/
PRInt32 GetCaretLineNumber();
/**
* Return an accessible at the given hypertext offset.
*
* @param aOffset [out] the given hypertext offset
* @param aAccIdx [out] child index of returned accessible
* @param aStartOffset [out] start hypertext offset of returned accessible
* @param aEndOffset [out] end hypertext offset of returned accessible
*/
nsAccessible *GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
PRInt32 *aStartOffset,
PRInt32 *aEndOffset);
// Helpers
nsresult GetDOMPointByFrameOffset(nsIFrame *aFrame, PRInt32 aOffset,
nsIAccessible *aAccessible,

View File

@ -162,24 +162,36 @@
testTextAttrs(ID, 34, attrs, defAttrs, 33, 46);
//////////////////////////////////////////////////////////////////////////
// area5
// area5: "Green!*!RedNormal"
ID = "area5";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
testDefaultTextAttrs(ID, defAttrs);
// Green
tempElem = getNode(ID).firstChild.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"color": gComputedStyle.color};
testTextAttrs(ID, 0, attrs, defAttrs, 0, 5);
// br
attrs = {};
testTextAttrs(ID, 7, attrs, defAttrs, 5, 8);
testTextAttrs(ID, 5, attrs, defAttrs, 5, 6);
// img, embedded accessible, no attributes
attrs = {};
testTextAttrs(ID, 6, attrs, {}, 6, 7);
// br
attrs = {};
testTextAttrs(ID, 7, attrs, defAttrs, 7, 8);
// Red
tempElem = tempElem.nextSibling.nextSibling.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"color": gComputedStyle.color};
testTextAttrs(ID, 9, attrs, defAttrs, 8, 11);
// Normal
attrs = {};
testTextAttrs(ID, 11, attrs, defAttrs, 11, 18);
@ -419,6 +431,32 @@
attrs = { };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
//////////////////////////////////////////////////////////////////////////
// area15, embed char tests, "*plain*plain**bold*bold*"
ID = "area15";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
// p
testTextAttrs(ID, 0, { }, { }, 0, 1);
// plain
testTextAttrs(ID, 1, { }, defAttrs, 1, 6);
// p
testTextAttrs(ID, 6, { }, { }, 6, 7);
// plain
testTextAttrs(ID, 7, { }, defAttrs, 7, 12);
// p and img
testTextAttrs(ID, 12, { }, { }, 12, 14);
// bold
attrs = { "font-weight": kBoldFontWeight };
testTextAttrs(ID, 14, attrs, defAttrs, 14, 18);
// p
testTextAttrs(ID, 18, { }, { }, 18, 19);
// bold
attrs = { "font-weight": kBoldFontWeight };
testTextAttrs(ID, 19, attrs, defAttrs, 19, 23);
// p
testTextAttrs(ID, 23, { }, { }, 23, 24);
//////////////////////////////////////////////////////////////////////////
// test spelling text attributes
testSpellTextAttrs(); // Will call SimpleTest.finish();
@ -459,9 +497,10 @@
Green again
</span>
</p>
<!-- Green!*!RedNormal-->
<p id="area5">
<span style="color: green">Green</span>
<img src="moz.png" alt="image"/>
<img src="../moz.png" alt="image"/>
<span style="color: red">Red</span>Normal
</p>
<p id="area6">
@ -515,5 +554,8 @@
<p id="area12">hello</p>
<p id="area13"></p>
<input id="area14">
<!-- *plain*plain**bold*bold*-->
<div id="area15"><p>embed</p>plain<p>embed</p>plain<p>embed</p><img src="../moz.png" alt="image"/><b>bold</b><p>embed</p><b>bold</b><p>embed</p></div>
</body>
</html>