bool nsXHTMLContentSerializer::AfterElementStart(nsIContent* aContent, nsIContent* aOriginalElement, nsAString& aStr) { nsIAtom *name = aContent->Tag(); if (aContent->GetNameSpaceID() == kNameSpaceID_XHTML && mRewriteEncodingDeclaration && name == nsGkAtoms::head) { // Check if there already are any content-type meta children. // If there are, they will be modified to use the correct charset. // If there aren't, we'll insert one here. bool hasMeta = false; for (nsIContent* child = aContent->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->IsHTML(nsGkAtoms::meta) && child->HasAttr(kNameSpaceID_None, nsGkAtoms::content)) { nsAutoString header; child->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header); if (header.LowerCaseEqualsLiteral("content-type")) { hasMeta = true; break; } } } if (!hasMeta) { NS_ENSURE_TRUE(AppendNewLineToString(aStr), false); if (mDoFormat) { NS_ENSURE_TRUE(AppendIndentation(aStr), false); } NS_ENSURE_TRUE(AppendToString(NS_LITERAL_STRING("<meta http-equiv=\"content-type\""), aStr), false); NS_ENSURE_TRUE(AppendToString(NS_LITERAL_STRING(" content=\"text/html; charset="), aStr), false); NS_ENSURE_TRUE(AppendToString(NS_ConvertASCIItoUTF16(mCharset), aStr), false); if (mIsHTMLSerializer) { NS_ENSURE_TRUE(AppendToString(NS_LITERAL_STRING("\">"), aStr), false); } else { NS_ENSURE_TRUE(AppendToString(NS_LITERAL_STRING("\" />"), aStr), false); } } } return true; }
void nsXHTMLContentSerializer::AfterElementStart(nsIContent * aContent, nsIDOMElement *aOriginalElement, nsAString& aStr) { nsIAtom *name = aContent->Tag(); if (aContent->GetNameSpaceID() == kNameSpaceID_XHTML && mRewriteEncodingDeclaration && name == nsGkAtoms::head) { // Check if there already are any content-type meta children. // If there are, they will be modified to use the correct charset. // If there aren't, we'll insert one here. PRBool hasMeta = PR_FALSE; PRUint32 i, childCount = aContent->GetChildCount(); for (i = 0; i < childCount; ++i) { nsIContent* child = aContent->GetChildAt(i); if (child->IsHTML() && child->Tag() == nsGkAtoms::meta && child->HasAttr(kNameSpaceID_None, nsGkAtoms::content)) { nsAutoString header; child->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header); if (header.LowerCaseEqualsLiteral("content-type")) { hasMeta = PR_TRUE; break; } } } if (!hasMeta) { AppendNewLineToString(aStr); if (mDoFormat) { AppendIndentation(aStr); } AppendToString(NS_LITERAL_STRING("<meta http-equiv=\"content-type\""), aStr); AppendToString(NS_LITERAL_STRING(" content=\"text/html; charset="), aStr); AppendToString(NS_ConvertASCIItoUTF16(mCharset), aStr); if (mIsHTMLSerializer) AppendToString(NS_LITERAL_STRING("\">"), aStr); else AppendToString(NS_LITERAL_STRING("\" />"), aStr); } } }
NS_IMETHODIMP nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement, nsAString& aStr) { NS_ENSURE_ARG(aElement); nsCOMPtr<nsIContent> content = do_QueryInterface(aElement); if (!content) return NS_ERROR_FAILURE; nsIAtom *name = content->Tag(); if (name == nsGkAtoms::script || name == nsGkAtoms::style || name == nsGkAtoms::noscript || name == nsGkAtoms::noframes) { --mDisableEntityEncoding; } PRBool forceFormat = content->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdirty); if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) { DecrIndentation(name); } if (name == nsGkAtoms::script) { nsCOMPtr<nsIScriptElement> script = do_QueryInterface(aElement); if (script && script->IsMalformed()) { // We're looking at a malformed script tag. This means that the end tag // was missing in the source. Imitate that here by not serializing the end // tag. --mPreLevel; return NS_OK; } } else if (mIsCopying && name == nsGkAtoms::ol) { NS_ASSERTION((!mOLStateStack.IsEmpty()), "Cannot have an empty OL Stack"); /* Though at this point we must always have an state to be deleted as all the OL opening tags are supposed to push an olState object to the stack*/ if (!mOLStateStack.IsEmpty()) { mOLStateStack.RemoveElementAt(mOLStateStack.Length() -1); } } nsIParserService* parserService = nsContentUtils::GetParserService(); if (parserService) { PRBool isContainer; parserService->IsContainer(parserService->HTMLAtomTagToId(name), isContainer); if (!isContainer) return NS_OK; } if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) { PRBool lineBreakBeforeClose = LineBreakBeforeClose(content->GetNameSpaceID(), name); if (mColPos && lineBreakBeforeClose) { AppendNewLineToString(aStr); } if (!mColPos) { AppendIndentation(aStr); } else if (mAddSpace) { AppendToString(PRUnichar(' '), aStr); mAddSpace = PR_FALSE; } } else if (mAddSpace) { AppendToString(PRUnichar(' '), aStr); mAddSpace = PR_FALSE; } nsAutoString nameStr; name->ToString(nameStr); AppendToString(kEndTag, aStr); AppendToString(nameStr.get(), -1, aStr); AppendToString(kGreaterThan, aStr); MaybeLeaveFromPreContent(content); if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw && LineBreakAfterClose(content->GetNameSpaceID(), name)) { AppendNewLineToString(aStr); } else { MaybeFlagNewlineForRootNode(aElement); } if (name == nsGkAtoms::body) { --mInBody; } return NS_OK; }
NS_IMETHODIMP nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, nsIDOMElement *aOriginalElement, nsAString& aStr) { NS_ENSURE_ARG(aElement); nsCOMPtr<nsIContent> content = do_QueryInterface(aElement); if (!content) return NS_ERROR_FAILURE; PRBool forceFormat = PR_FALSE; if (!CheckElementStart(content, forceFormat, aStr)) { return NS_OK; } nsIAtom *name = content->Tag(); PRBool lineBreakBeforeOpen = LineBreakBeforeOpen(content->GetNameSpaceID(), name); if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) { if (mColPos && lineBreakBeforeOpen) { AppendNewLineToString(aStr); } else { MaybeAddNewlineForRootNode(aStr); } if (!mColPos) { AppendIndentation(aStr); } else if (mAddSpace) { AppendToString(PRUnichar(' '), aStr); mAddSpace = PR_FALSE; } } else if (mAddSpace) { AppendToString(PRUnichar(' '), aStr); mAddSpace = PR_FALSE; } else { MaybeAddNewlineForRootNode(aStr); } // Always reset to avoid false newlines in case MaybeAddNewlineForRootNode wasn't // called mAddNewlineForRootNode = PR_FALSE; AppendToString(kLessThan, aStr); nsAutoString nameStr; name->ToString(nameStr); AppendToString(nameStr.get(), -1, aStr); MaybeEnterInPreContent(content); // for block elements, we increase the indentation if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) IncrIndentation(name); // Need to keep track of OL and LI elements in order to get ordinal number // for the LI. if (mIsCopying && name == nsGkAtoms::ol){ // We are copying and current node is an OL; // Store its start attribute value in olState->startVal. nsAutoString start; PRInt32 startAttrVal = 0; aElement->GetAttribute(NS_LITERAL_STRING("start"), start); if (!start.IsEmpty()){ PRInt32 rv = 0; startAttrVal = start.ToInteger(&rv); //If OL has "start" attribute, first LI element has to start with that value //Therefore subtracting 1 as all the LI elements are incrementing it before using it; //In failure of ToInteger(), default StartAttrValue to 0. if (NS_SUCCEEDED(rv)) startAttrVal--; else startAttrVal = 0; } mOLStateStack.AppendElement(olState(startAttrVal, PR_TRUE)); } if (mIsCopying && name == nsGkAtoms::li) { mIsFirstChildOfOL = IsFirstChildOfOL(aOriginalElement); if (mIsFirstChildOfOL){ // If OL is parent of this LI, serialize attributes in different manner. SerializeLIValueAttribute(aElement, aStr); } } // Even LI passed above have to go through this // for serializing attributes other than "value". nsAutoString dummyPrefix; SerializeAttributes(content, aOriginalElement, dummyPrefix, EmptyString(), name, aStr); AppendToString(kGreaterThan, aStr); if (name == nsGkAtoms::script || name == nsGkAtoms::style || name == nsGkAtoms::noscript || name == nsGkAtoms::noframes) { ++mDisableEntityEncoding; } if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw && LineBreakAfterOpen(content->GetNameSpaceID(), name)) { AppendNewLineToString(aStr); } AfterElementStart(content, aOriginalElement, aStr); return NS_OK; }