nsresult mozInlineSpellWordUtil::SetEnd(nsIDOMNode* aEndNode, PRInt32 aEndOffset) { NS_PRECONDITION(aEndNode, "Null end node?"); NS_ASSERTION(mRootNode, "Not initialized"); InvalidateWords(); if (!IsTextNode(aEndNode)) { // End at the start of the first text node after aEndNode/aEndOffset. aEndNode = FindNextTextNode(aEndNode, aEndOffset, mRootNode); aEndOffset = 0; } mSoftEnd = NodeOffset(aEndNode, aEndOffset); return NS_OK; }
/*GetIndex return the index of element (ie. number of elements previous to this one with same tag) */ int CXMLElement::GetIndex() { CXMLElement telement; telement.CopyElement(this); int occur = 1; if (!IsTextNode()) { while (telement.GoPrev((char *)element->name)) occur++; } else { while(telement.GoPrev(NULL, true)) if (telement.IsTextNode()) occur++; } return occur; }
nsresult mozInlineSpellWordUtil::SetPosition(nsIDOMNode* aNode, PRInt32 aOffset) { InvalidateWords(); if (!IsTextNode(aNode)) { // Start at the start of the first text node after aNode/aOffset. aNode = FindNextTextNode(aNode, aOffset, mRootNode); aOffset = 0; } mSoftBegin = NodeOffset(aNode, aOffset); EnsureWords(); PRInt32 textOffset = MapDOMPositionToSoftTextOffset(mSoftBegin); if (textOffset < 0) return NS_OK; mNextWordIndex = FindRealWordContaining(textOffset, HINT_END, PR_TRUE); return NS_OK; }
/** * Check if there's a DOM word separator before aBeforeOffset in this node. * Always returns PR_TRUE if it's a BR element. * aSeparatorOffset is set to the index of the last separator if any is found * (0 for BR elements). */ static PRBool ContainsDOMWordSeparator(nsIDOMNode* aNode, PRInt32 aBeforeOffset, PRInt32* aSeparatorOffset) { if (IsBRElement(aNode)) { *aSeparatorOffset = 0; return PR_TRUE; } if (!IsTextNode(aNode)) return PR_FALSE; nsAutoString str; GetNodeText(aNode, str); for (PRInt32 i = PR_MIN(aBeforeOffset, PRInt32(str.Length())) - 1; i >= 0; --i) { if (IsDOMWordSeparator(str.CharAt(i))) { *aSeparatorOffset = i; return PR_TRUE; } } return PR_FALSE; }
void mozInlineSpellWordUtil::BuildSoftText() { // First we have to work backwards from mSoftStart to find a text node // containing a DOM word separator, a non-inline-element // boundary, or the hard start node. That's where we'll start building the // soft string from. nsIDOMNode* node = mSoftBegin.mNode; PRInt32 firstOffsetInNode = 0; PRInt32 checkBeforeOffset = mSoftBegin.mOffset; while (node) { if (ContainsDOMWordSeparator(node, checkBeforeOffset, &firstOffsetInNode)) break; checkBeforeOffset = PR_INT32_MAX; if (IsBreakElement(mCSSView, node)) { // Since FindPrevNode follows tree *preorder*, we're about to traverse // up out of 'node'. Since node induces breaks (e.g., it's a block), // don't bother trying to look outside it, just stop now. break; } node = FindPrevNode(node, mRootNode); } // Now build up the string moving forward through the DOM until we reach // the soft end and *then* see a DOM word separator, a non-inline-element // boundary, or the hard end node. mSoftText.Truncate(); mSoftTextDOMMapping.Clear(); PRBool seenSoftEnd = PR_FALSE; // Leave this outside the loop so large heap string allocations can be reused // across iterations nsAutoString str; while (node) { if (node == mSoftEnd.mNode) { seenSoftEnd = PR_TRUE; } PRBool exit = PR_FALSE; if (IsTextNode(node)) { GetNodeText(node, str); PRInt32 lastOffsetInNode = str.Length(); if (seenSoftEnd) { // check whether we can stop after this for (PRInt32 i = node == mSoftEnd.mNode ? mSoftEnd.mOffset : 0; i < PRInt32(str.Length()); ++i) { if (IsDOMWordSeparator(str.CharAt(i))) { exit = PR_TRUE; // stop at the first separator after the soft end point lastOffsetInNode = i; break; } } } if (firstOffsetInNode < lastOffsetInNode) { PRInt32 len = lastOffsetInNode - firstOffsetInNode; mSoftTextDOMMapping.AppendElement( DOMTextMapping(NodeOffset(node, firstOffsetInNode), mSoftText.Length(), len)); mSoftText.Append(Substring(str, firstOffsetInNode, len)); } firstOffsetInNode = 0; } if (exit) break; CheckLeavingBreakElementClosure closure = { mCSSView, PR_FALSE }; node = FindNextNode(node, mRootNode, CheckLeavingBreakElement, &closure); if (closure.mLeftBreakElement || (node && IsBreakElement(mCSSView, node))) { // We left, or are entering, a break element (e.g., block). Maybe we can // stop now. if (seenSoftEnd) break; // Record the break mSoftText.Append(' '); } } #ifdef DEBUG_SPELLCHECK printf("Got DOM string: %s\n", NS_ConvertUTF16toUTF8(mSoftText).get()); #endif }