nsCOMPtr<nsIDOMNode> startGrandParent; result = startParent->GetParentNode(getter_AddRefs(startGrandParent)); if (NS_FAILED(result)) return result; if (!startGrandParent) return NS_ERROR_NULL_POINTER; nsCOMPtr<nsIDOMNode> endGrandParent; result = endParent->GetParentNode(getter_AddRefs(endGrandParent)); if (NS_FAILED(result)) return result; if (!endGrandParent) return NS_ERROR_NULL_POINTER;
NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,                                             const nsString *aAttribute,                                            const nsString *aValue){  if (!aProperty) { return NS_ERROR_NULL_POINTER; }  if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }  ForceCompositionEnd();  nsAutoEditBatch batchIt(this);  nsAutoRules beginRulesSniffing(this, kOpInsertElement, nsIEditor::eNext);    if (gNoisy)   {     nsAutoString propString;    aProperty->ToString(propString);    char *propCString = propString.ToNewCString();    if (gNoisy) { printf("---------- start nsTextEditor::SetTextProperty %s ----------\n", propCString); }    nsCRT::free(propCString);  }  nsresult result=NS_ERROR_NOT_INITIALIZED;  nsCOMPtr<nsIDOMSelection>selection;  result = GetSelection(getter_AddRefs(selection));  if (NS_FAILED(result)) return result;  if (!selection) return NS_ERROR_NULL_POINTER;  PRBool cancel, handled;  nsTextRulesInfo ruleInfo(nsTextEditRules::kSetTextProperty);  result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);  if (NS_FAILED(result)) return result;  if (!cancel && !handled)  {    PRBool isCollapsed;    selection->GetIsCollapsed(&isCollapsed);    if (PR_TRUE==isCollapsed)    {      // manipulating text attributes on a collapsed selection only sets state for the next text insertion      SetTypeInStateForProperty(*mTypeInState, aProperty, aAttribute, aValue);    }    else    {      // set the text property for all selected ranges      nsCOMPtr<nsIEnumerator> enumerator;      result = selection->GetEnumerator(getter_AddRefs(enumerator));      if (NS_FAILED(result)) return result;      if (!enumerator) return NS_ERROR_NULL_POINTER;      enumerator->First();       nsCOMPtr<nsISupports> currentItem;      result = enumerator->CurrentItem(getter_AddRefs(currentItem));      if (NS_FAILED(result)) return result;      if (!currentItem) return NS_ERROR_NULL_POINTER;      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );      nsCOMPtr<nsIDOMNode>commonParent;      result = range->GetCommonParent(getter_AddRefs(commonParent));      if (NS_FAILED(result)) return result;      if (!commonParent) return NS_ERROR_NULL_POINTER;      PRInt32 startOffset, endOffset;      range->GetStartOffset(&startOffset);      range->GetEndOffset(&endOffset);      nsCOMPtr<nsIDOMNode> startParent;  nsCOMPtr<nsIDOMNode> endParent;      range->GetStartParent(getter_AddRefs(startParent));      range->GetEndParent(getter_AddRefs(endParent));      PRBool startIsText = IsTextNode(startParent);      PRBool endIsText = IsTextNode(endParent);      if ((PR_TRUE==startIsText) && (PR_TRUE==endIsText) &&          (startParent.get()==endParent.get()))       { // the range is entirely contained within a single text node        // commonParent==aStartParent, so get the "real" parent of the selection        startParent->GetParentNode(getter_AddRefs(commonParent));        result = SetTextPropertiesForNode(startParent, commonParent,                                           startOffset, endOffset,                                          aProperty, aAttribute, aValue);      }      else      {        nsCOMPtr<nsIDOMNode> startGrandParent;        result = startParent->GetParentNode(getter_AddRefs(startGrandParent));        if (NS_FAILED(result)) return result;        if (!startGrandParent) return NS_ERROR_NULL_POINTER;        nsCOMPtr<nsIDOMNode> endGrandParent;        result = endParent->GetParentNode(getter_AddRefs(endGrandParent));        if (NS_FAILED(result)) return result;        if (!endGrandParent) return NS_ERROR_NULL_POINTER;        PRBool canCollapseStyleNode = PR_FALSE;        if ((PR_TRUE==startIsText) && (PR_TRUE==endIsText) &&            endGrandParent.get()==startGrandParent.get())        {          result = IntermediateNodesAreInline(range, startParent, startOffset,                                               endParent, endOffset,                                               canCollapseStyleNode);        }        if (NS_SUCCEEDED(result))         {          if (PR_TRUE==canCollapseStyleNode)          { // the range is between 2 nodes that have a common (immediate) grandparent,            // and any intermediate nodes are just inline style nodes            result = SetTextPropertiesForNodesWithSameParent(startParent,startOffset,                                                             endParent,  endOffset,                                                             commonParent,                                                             aProperty, aAttribute, aValue);          }          else          { // the range is between 2 nodes that have no simple relationship            result = SetTextPropertiesForNodeWithDifferentParents(range,                                                                  startParent,startOffset,                                                                   endParent,  endOffset,                                                                  commonParent,                                                                  aProperty, aAttribute, aValue);          }        }      }      if (NS_SUCCEEDED(result))      { // compute a range for the selection        // don't want to actually do anything with selection, because        // we are still iterating through it.  Just want to create and remember        // an nsIDOMRange, and later add the range to the selection after clearing it.        // XXX: I'm blocked here because nsIDOMSelection doesn't provide a mechanism        //      for setting a compound selection yet.      }    }  }  if (!cancel)  {    // post-process    result = mRules->DidDoAction(selection, &ruleInfo, result);  }  if (gNoisy) {DebugDumpContent(); } // DEBUG  if (gNoisy)   {     nsAutoString propString;    aProperty->ToString(propString);    char *propCString = propString.ToNewCString();    if (gNoisy) { printf("---------- end nsTextEditor::SetTextProperty %s ----------\n", propCString); }    nsCRT::free(propCString);  }  return result;}