nsresult nsLoggingSink::OpenNode(const char* aKind, const nsIParserNode& aNode) { WriteTabs(mOutput,++mLevel); PR_fprintf(mOutput,"<open container="); nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType()); if ((nodeType >= eHTMLTag_unknown) && (nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) { const PRUnichar* tag = nsHTMLTags::GetStringValue(nodeType); PR_fprintf(mOutput, "\"%s\"", NS_ConvertUTF16toUTF8(tag).get()); } else { char* text = nsnull; GetNewCString(aNode.GetText(), &text); if(text) { PR_fprintf(mOutput, "\"%s\"", text); nsMemory::Free(text); } } if (WillWriteAttributes(aNode)) { PR_fprintf(mOutput, ">\n"); WriteAttributes(aNode); PR_fprintf(mOutput, "</open>\n"); } else { PR_fprintf(mOutput, ">\n"); } return NS_OK; }
nsresult nsLoggingSink::LeafNode(const nsIParserNode& aNode) { WriteTabs(mOutput,1+mLevel); nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType()); if ((nodeType >= eHTMLTag_unknown) && (nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) { const PRUnichar* tag = nsHTMLTags::GetStringValue(nodeType); if(tag) PR_fprintf(mOutput, "<leaf tag=\"%s\"", NS_ConvertUTF16toUTF8(tag).get()); else PR_fprintf(mOutput, "<leaf tag=\"???\""); if (WillWriteAttributes(aNode)) { PR_fprintf(mOutput, ">\n"); WriteAttributes(aNode); PR_fprintf(mOutput, "</leaf>\n"); } else { PR_fprintf(mOutput, "/>\n"); } } else { PRInt32 pos; nsAutoString tmp; char* str = nsnull; switch (nodeType) { case eHTMLTag_whitespace: case eHTMLTag_text: GetNewCString(aNode.GetText(), &str); if(str) { PR_fprintf(mOutput, "<text value=\"%s\"/>\n", str); nsMemory::Free(str); } break; case eHTMLTag_newline: PR_fprintf(mOutput, "<newline/>\n"); break; case eHTMLTag_entity: tmp.Append(aNode.GetText()); tmp.Cut(0, 1); pos = tmp.Length() - 1; if (pos >= 0) { tmp.Cut(pos, 1); } PR_fprintf(mOutput, "<entity value=\"%s\"/>\n", NS_LossyConvertUTF16toASCII(tmp).get()); break; default: NS_NOTREACHED("unsupported leaf node type"); }//switch } return NS_OK; }
NS_IMETHODIMP mozSanitizingHTMLSerializer::AddLeaf(const nsIParserNode& aNode) { eHTMLTags type = (eHTMLTags)aNode.GetNodeType(); const nsAString& text = aNode.GetText(); mParserNode = const_cast<nsIParserNode*>(&aNode); return DoAddLeaf(type, text); }
NS_IMETHODIMP mozSanitizingHTMLSerializer::OpenContainer(const nsIParserNode& aNode) { PRInt32 type = aNode.GetNodeType(); mParserNode = const_cast<nsIParserNode *>(&aNode); return DoOpenContainer(type); }
nsresult nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) { WriteTabs(mOutput,1+mLevel); nsAutoString tmp; PRInt32 ac = aNode.GetAttributeCount(); for (PRInt32 i = 0; i < ac; ++i) { char* key=nsnull; char* value=nsnull; const nsAString& k = aNode.GetKeyAt(i); const nsAString& v = aNode.GetValueAt(i); GetNewCString(k, &key); if(key) { PR_fprintf(mOutput, " <attr key=\"%s\" value=\"", key); nsMemory::Free(key); } tmp.Truncate(); tmp.Append(v); if(!tmp.IsEmpty()) { PRUnichar first = tmp.First(); if ((first == '"') || (first == '\'')) { if (tmp.Last() == first) { tmp.Cut(0, 1); PRInt32 pos = tmp.Length() - 1; if (pos >= 0) { tmp.Cut(pos, 1); } } else { // Mismatched quotes - leave them in } } GetNewCString(tmp, &value); if(value) { PR_fprintf(mOutput, "%s\"/>\n", value); WriteTabs(mOutput,1+mLevel); nsMemory::Free(value); } } } WriteTabs(mOutput,1+mLevel); return NS_OK; }
PRBool nsLoggingSink::WillWriteAttributes(const nsIParserNode& aNode) { PRInt32 ac = aNode.GetAttributeCount(); if (0 != ac) { return PR_TRUE; } return PR_FALSE; }
nsresult FBMLContentSink::AddComment(const nsIParserNode& aNode) { PRInt32 tagId = aNode.GetNodeType(); #ifdef VERBOSE_LOGGING printf("AddComment: %d\n", tagId); string text; nsString stext(aNode.GetText()); UTF16ToStdString(text, stext); printf("\tComment Text: [%s]\n", text.c_str()); #endif if (mPreserveComment) { OpenContainer(aNode); PRInt32 lineNo = aNode.GetSourceLineNumber(); fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo); string text; nsString stext(aNode.GetText()); UTF16ToStdString(text, stext); node->text = strdup(text.c_str()); CloseContainer((nsHTMLTag)tagId); } return NS_OK; }
/** * This gets called by the parser when you want to add * a PI node to the current container in the content * model. * * @updated gess 3/25/98 * @param * @return */ NS_IMETHODIMP nsLoggingSink::AddProcessingInstruction(const nsIParserNode& aNode){ #ifdef VERBOSE_DEBUG DebugDump("<",aNode.GetText(),(mNodeStackPos)*2); #endif nsresult theResult=NS_OK; //then proxy the call to the real sink if you have one. if(mSink) { theResult=mSink->AddProcessingInstruction(aNode); } return theResult; }
nsresult FBMLContentSink::OpenContainer(const nsIParserNode& aNode) { PRInt32 tagId = aNode.GetNodeType(); bool attrSpecial = false; contexts *back_contexts; PRInt32 attrId; #ifdef VERBOSE_LOGGING printf("OpenContainer: %d [%s]\n", tagId, GetTagName((nsHTMLTag)tagId).c_str()); #endif if (mRuleStack.empty()) { back_contexts = NULL; } else { back_contexts = mRuleStack.back(); } if (tagId == eHTMLTag_userdefined) { string text; nsString stext(aNode.GetText()); UTF16ToStdString(text, stext); PRInt32 lineNo = aNode.GetSourceLineNumber(); char errorMsg[512]; snprintf(errorMsg, sizeof(errorMsg), "FBML Error (line %d): unknown tag \"%s\"\n", (int)lineNo, text.c_str()); mError += errorMsg; } else if (!mSkipSchemaChecking && mCurrent && back_contexts) { // check illegal children vector<vector<char> > &rules = back_contexts->tag_rules; if (tagId >= 0 && tagId < rules.size()) { for (fbml_node *p = mCurrent; p; p = p->parent) { unsigned short parentTagId = p->eHTMLTag; if (parentTagId >= rules.size() || rules[tagId][parentTagId]) { PRInt32 lineNo = aNode.GetSourceLineNumber(); char errorMsg[512]; snprintf(errorMsg, sizeof(errorMsg), "FBML Error (line %d): illegal tag \"%s\" under \"%s\"\n", (int)lineNo, GetTagName((nsHTMLTag)tagId).c_str(), GetTagName((nsHTMLTag)parentTagId).c_str()); mError += errorMsg; tagId = eHTMLTag_userdefined; // nuke it } } } } PRInt32 lineNo = aNode.GetSourceLineNumber(); fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo); if (node) { int count = aNode.GetAttributeCount(); for (int i = 0; i < count; i++) { string n; nsString sn(aNode.GetKeyAt(i)); UTF16ToStdString(n, sn); string v; nsString sv(aNode.GetValueAt(i)); UTF16ToUTF8String(v, sv); attrId = nsHTMLAttrs::LookupAttr(sn); char attrFlag = GetAttrFlag(attrId); // If we are in internal page skip all these checks if (mSkipSchemaChecking) { fbml_node_add_attribute(node, (char*)n.c_str(), (char*)v.c_str(), attrFlag, 1); continue; } bool fail = false; for (char *p = (char*)n.c_str(); *p; p++) { if (*p >= 'A' && *p <= 'Z') *p |= 0x20; // make sure attrs are well formed if (*p != ':' && *p !='_' && *p != '-' && (*p<'a' || *p>'z') && (*p<'0' || *p>'9') ) { fail = true; break; } } if (fail) { PRInt32 lineNo = aNode.GetSourceLineNumber(); char errorMsg[512]; snprintf(errorMsg, sizeof(errorMsg), "FBML Error (line %d): illegal attr \"%s\" in tag \"%s\". Attribute names can only contain alphanumeric characters, underscores, and hyphens.", (int)lineNo, n.c_str(), GetTagName((nsHTMLTag)tagId).c_str() ); mError += errorMsg; } // check schema else if (back_contexts && attrId >= 0 && attrId < back_contexts->attr_rules.size() && back_contexts->attr_rules[attrId]) { PRInt32 lineNo = aNode.GetSourceLineNumber(); char errorMsg[512]; snprintf(errorMsg, sizeof(errorMsg), "FBML Error (line %d): illegal attr \"%s\" in tag \"%s\" under \"%s\"\n", (int)lineNo, n.c_str(), GetTagName((nsHTMLTag)tagId).c_str(), back_contexts->tag_name.c_str()); mError += errorMsg; } else if (mCSSSanitizer && (attrFlag & FB_FLAG_ATTR_STYLE)) { char *sanitized_css = NULL; char *error = NULL; int ret = fbml_sanitize_css((char*)v.c_str(), 1, lineNo, mCSSSanitizer, &sanitized_css, &error); if (sanitized_css) { fbml_node_add_attribute(node, (char*)n.c_str(), sanitized_css, attrFlag, 0); } if (error) { mError += error; free(error); } } else if (mJSSanitizer && (attrFlag & FB_FLAG_ATTR_SCRIPT)) { char *sanitized_js = NULL; char *error = NULL; int ret = fbml_sanitize_js((char*)v.c_str(), v.length(), 1, lineNo, mJSSanitizer, &sanitized_js, &error); if (sanitized_js) { if (mJSSanitizer->pfunc_eh_translator) { char *translated = mJSSanitizer->pfunc_eh_translator (sanitized_js, mJSSanitizer->eh_translate_data); free(sanitized_js); sanitized_js = translated; } fbml_node_add_attribute(node, (char*)n.c_str(), sanitized_js, attrFlag, 0); } if (error) { mError += error; free(error); } } else if (mRewriter && mRewriter->pfunc_rewriter && (attrFlag & FB_FLAG_ATTR_REWRITE)){ char *rewritten_attr = mRewriter->pfunc_rewriter((char *)GetTagName((nsHTMLTag)tagId).c_str(), (char *)n.c_str(), (char *)v.c_str(), mRewriter->rewrite_data); fbml_node_add_attribute(node, (char*)n.c_str(), rewritten_attr, attrFlag, 0); } else { if (attrFlag & FB_FLAG_ATTR_SPECIAL) { attrSpecial = true; } fbml_node_add_attribute(node, (char*)n.c_str(), (char*)v.c_str(), attrFlag, 1); } } if (attrSpecial) { fbml_node_add_flags(node, FB_FLAG_HAS_SPECIAL_ATTR); } mCurrent = node; if (!mSkipSchemaChecking && tagId >= 0 && tagId < m_context_rules.size()) { contexts *rule = &m_context_rules[tagId]; if (rule && (!rule->tag_rules.empty() || !rule->attr_rules.empty())) { mRuleStack.push_back(rule); } else if (mRuleStack.empty()) { mRuleStack.push_back(NULL); } else { mRuleStack.push_back(mRuleStack.back()); } } else { mRuleStack.push_back(NULL); } } return NS_OK; }
nsresult FBMLContentSink::AddLeaf(const nsIParserNode& aNode) { PRInt32 tagId = aNode.GetNodeType(); #ifdef VERBOSE_LOGGING printf("AddLeaf: %d [%s] Attribute Count: [%d]\n", tagId, GetTagName((nsHTMLTag)tagId).c_str(), aNode.GetAttributeCount()); string text; nsString stext(aNode.GetText()); UTF16ToStdString(text, stext); printf("\tLeaf Text: [%s]\n", text.c_str()); #endif if (tagId == eHTMLTag_title || tagId == eHTMLTag_script || (GetFlag(tagId) & FB_FLAG_STYLE)) { nsCOMPtr<nsIDTD> dtd; mParser->GetDTD(getter_AddRefs(dtd)); nsAutoString script; PRInt32 lineNo = 0; dtd->CollectSkippedContent(tagId, script, lineNo); string text; UTF16ToStdString(text, script); #ifdef VERBOSE_LOGGING printf("\tCollected Content:: [%s]\n", text.c_str()); #endif OpenContainer(aNode); fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo); if (mCSSSanitizer && (GetFlag(tagId) & FB_FLAG_STYLE)) { char *sanitized_css = NULL; char *error = NULL; int ret = fbml_sanitize_css((char*)text.c_str(), 0, lineNo, mCSSSanitizer, &sanitized_css, &error); if (sanitized_css) { node->text = sanitized_css; } if (error) { mError += error; free(error); } } else if (mJSSanitizer && tagId == eHTMLTag_script) { char *sanitized_js = NULL; char *error = NULL; int ret = fbml_sanitize_js((char*)text.c_str(), text.length(), 0, lineNo, mJSSanitizer, &sanitized_js, &error); if (sanitized_js) { node->text = sanitized_js; } if (error) { mError += error; free(error); } } else { node->text = strdup(text.c_str()); } CloseContainer((nsHTMLTag)tagId); return NS_OK; } switch (aNode.GetTokenType()) { case eToken_start: OpenContainer(aNode); CloseContainer((nsHTMLTag)tagId); break; case eToken_text: case eToken_whitespace: case eToken_newline: { PRInt32 lineNo = aNode.GetSourceLineNumber(); fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo); string text; nsString stext(aNode.GetText()); UTF16ToStdString(text, stext); node->text = strdup(text.c_str()); } break; } return NS_OK; }