Bug 312592: Reduce amount of duplicated code in html contentsink.
r=mrbkap sr=peterv
This commit is contained in:
@@ -71,6 +71,8 @@ class nsContentSink : public nsICSSLoaderObserver,
|
||||
NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate,
|
||||
nsresult aStatus);
|
||||
|
||||
nsresult ProcessMETATag(nsIContent* aContent);
|
||||
|
||||
protected:
|
||||
nsContentSink();
|
||||
virtual ~nsContentSink();
|
||||
@@ -94,8 +96,6 @@ protected:
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia);
|
||||
|
||||
nsresult ProcessMETATag(nsIContent* aContent);
|
||||
|
||||
void PrefetchHref(const nsAString &aHref, PRBool aExplicit);
|
||||
|
||||
PRBool ScrollToRef(PRBool aReallyScroll);
|
||||
|
||||
@@ -335,7 +335,6 @@ protected:
|
||||
nsString mTitleString;
|
||||
PRInt32 mInNotification;
|
||||
nsRefPtr<nsGenericHTMLElement> mCurrentForm;
|
||||
nsCOMPtr<nsIContent> mCurrentMap;
|
||||
|
||||
nsAutoVoidArray mContextStack;
|
||||
SinkContext* mCurrentContext;
|
||||
@@ -386,9 +385,6 @@ protected:
|
||||
*/
|
||||
void AddBaseTagInfo(nsIContent* aContent);
|
||||
|
||||
void ProcessBaseHref(const nsAString& aBaseHref);
|
||||
void ProcessBaseTarget(const nsAString& aBaseTarget);
|
||||
|
||||
// Routines for tags that require special handling
|
||||
nsresult CloseHTML();
|
||||
nsresult OpenFrameset(const nsIParserNode& aNode);
|
||||
@@ -397,10 +393,8 @@ protected:
|
||||
nsresult CloseBody();
|
||||
nsresult OpenForm(const nsIParserNode& aNode);
|
||||
nsresult CloseForm();
|
||||
nsresult ProcessAREATag(const nsIParserNode& aNode);
|
||||
nsresult ProcessBASETag(const nsIParserNode& aNode);
|
||||
void ProcessBASEElement(nsGenericHTMLElement* aElement);
|
||||
nsresult ProcessLINKTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessMETATag(const nsIParserNode& aNode);
|
||||
|
||||
// Routines for tags that require special handling when we reach their end
|
||||
// tag.
|
||||
@@ -1246,13 +1240,6 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
||||
mSink->mInsideNoXXXTag++;
|
||||
break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
// We used to strip whitespace from the NAME attribute, to match
|
||||
// a 4.x quirk, but it proved too quirky for us, and IE never
|
||||
// did that. See bug 79738 for details.
|
||||
mSink->mCurrentMap = content;
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
mSink->mNumOpenIFRAMES++;
|
||||
break;
|
||||
@@ -1381,11 +1368,6 @@ SinkContext::CloseContainer(const nsHTMLTag aTag)
|
||||
|
||||
break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
mSink->mCurrentMap = nsnull;
|
||||
|
||||
break;
|
||||
|
||||
case eHTMLTag_select:
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_object:
|
||||
@@ -1451,7 +1433,8 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
||||
// this for elements that have useful URI attributes.
|
||||
// See bug 18478 and bug 30617 for why we need to do this.
|
||||
switch (nodeType) {
|
||||
// leaves with 'SRC='
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_meta:
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_input:
|
||||
@@ -1476,8 +1459,23 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
||||
// Add new leaf to its parent
|
||||
AddLeaf(content);
|
||||
|
||||
// Notify input and button that they are now fully created
|
||||
// Additional processing needed once the element is in the tree
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_base:
|
||||
if (!mSink->mInsideNoXXXTag) {
|
||||
mSink->ProcessBASEElement(content);
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_meta:
|
||||
// XXX It's just not sufficient to check if the parent is head. Also
|
||||
// check for the preference.
|
||||
// Bug 40072: Don't evaluate METAs after FRAMESET.
|
||||
if (!mSink->mInsideNoXXXTag && !mSink->mFrameset) {
|
||||
rv = mSink->ProcessMETATag(content);
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_button:
|
||||
content->DoneCreatingElement();
|
||||
@@ -2941,24 +2939,10 @@ HTMLContentSink::AddLeaf(const nsIParserNode& aNode)
|
||||
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_area:
|
||||
rv = ProcessAREATag(aNode);
|
||||
|
||||
break;
|
||||
case eHTMLTag_base:
|
||||
mCurrentContext->FlushTextAndRelease();
|
||||
rv = ProcessBASETag(aNode);
|
||||
|
||||
break;
|
||||
case eHTMLTag_link:
|
||||
mCurrentContext->FlushTextAndRelease();
|
||||
rv = ProcessLINKTag(aNode);
|
||||
|
||||
break;
|
||||
case eHTMLTag_meta:
|
||||
mCurrentContext->FlushTextAndRelease();
|
||||
rv = ProcessMETATag(aNode);
|
||||
|
||||
break;
|
||||
default:
|
||||
rv = mCurrentContext->AddLeaf(aNode);
|
||||
@@ -3496,71 +3480,6 @@ HTMLContentSink::AddBaseTagInfo(nsIContent* aContent)
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode)
|
||||
{
|
||||
if (!mCurrentMap) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
|
||||
nsRefPtr<nsGenericHTMLElement> area =
|
||||
CreateContentObject(aNode, nodeType, nsnull, nsnull);
|
||||
if (!area) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do this
|
||||
// for elements that have useful URI attributes.
|
||||
// See bug 18478 and bug 30617 for why we need to do this.
|
||||
AddBaseTagInfo(area);
|
||||
|
||||
// Set the content's attributes
|
||||
nsresult rv = AddAttributes(aNode, area);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Add AREA object to the current map
|
||||
mCurrentMap->AppendChildTo(area, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLContentSink::ProcessBaseHref(const nsAString& aBaseHref)
|
||||
{
|
||||
//-- Make sure this page is allowed to load this URI
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> baseHrefURI;
|
||||
rv = NS_NewURI(getter_AddRefs(baseHrefURI), aBaseHref, nsnull);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
// Setting "BASE URI" from the last BASE tag appearing in HEAD.
|
||||
if (!mBody) {
|
||||
// The document checks if it is legal to set this base
|
||||
rv = mDocument->SetBaseURI(baseHrefURI);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDocumentBaseURI = mDocument->GetBaseURI();
|
||||
}
|
||||
} else {
|
||||
// NAV compatibility quirk
|
||||
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
rv = securityManager->
|
||||
CheckLoadURIWithPrincipal(mDocument->GetPrincipal(), baseHrefURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBaseHREF = aBaseHref;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::OpenHeadContext()
|
||||
{
|
||||
@@ -3605,59 +3524,51 @@ HTMLContentSink::CloseHeadContext()
|
||||
}
|
||||
|
||||
void
|
||||
HTMLContentSink::ProcessBaseTarget(const nsAString& aBaseTarget)
|
||||
HTMLContentSink::ProcessBASEElement(nsGenericHTMLElement* aElement)
|
||||
{
|
||||
if (!mBody) {
|
||||
// still in real HEAD
|
||||
mDocument->SetBaseTarget(aBaseTarget);
|
||||
} else {
|
||||
// NAV compatibility quirk
|
||||
mBaseTarget = aBaseTarget;
|
||||
}
|
||||
}
|
||||
// href attribute
|
||||
nsAutoString attrValue;
|
||||
if (aElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, attrValue)) {
|
||||
//-- Make sure this page is allowed to load this URI
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> baseHrefURI;
|
||||
rv = NS_NewURI(getter_AddRefs(baseHrefURI), attrValue, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessBASETag(const nsIParserNode& aNode)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
nsGenericHTMLElement* parent = nsnull;
|
||||
|
||||
if (mCurrentContext) {
|
||||
parent = mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent;
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
// Create content object
|
||||
nsCOMPtr<nsIContent> element;
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::base, nsnull,
|
||||
kNameSpaceID_None,
|
||||
getter_AddRefs(nodeInfo));
|
||||
|
||||
result = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
element->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
|
||||
// Add in the attributes and add the base content object to the
|
||||
// head container.
|
||||
result = AddAttributes(aNode, element);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
parent->AppendChildTo(element, PR_FALSE);
|
||||
if (!mInsideNoXXXTag) {
|
||||
nsAutoString value;
|
||||
if (element->GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, value)) {
|
||||
ProcessBaseHref(value);
|
||||
// Setting "BASE URI" from the last BASE tag appearing in HEAD.
|
||||
if (!mBody) {
|
||||
// The document checks if it is legal to set this base. Failing here is
|
||||
// ok, we just won't set a new base.
|
||||
rv = mDocument->SetBaseURI(baseHrefURI);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDocumentBaseURI = mDocument->GetBaseURI();
|
||||
}
|
||||
} else {
|
||||
// NAV compatibility quirk
|
||||
|
||||
if (element->GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, value)) {
|
||||
ProcessBaseTarget(value);
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
rv = securityManager->
|
||||
CheckLoadURIWithPrincipal(mDocument->GetPrincipal(), baseHrefURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mBaseHREF = attrValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
// target attribute
|
||||
if (aElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, attrValue)) {
|
||||
if (!mBody) {
|
||||
// still in real HEAD
|
||||
mDocument->SetBaseTarget(attrValue);
|
||||
} else {
|
||||
// NAV compatibility quirk
|
||||
mBaseTarget = attrValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -3729,55 +3640,6 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
|
||||
{
|
||||
nsGenericHTMLElement* parent = nsnull;
|
||||
|
||||
if (mCurrentContext) {
|
||||
parent = mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Create content object
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::meta, nsnull,
|
||||
kNameSpaceID_None,
|
||||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsGenericHTMLElement> it = NS_NewHTMLMetaElement(nodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
it->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
|
||||
// Add in the attributes and add the meta content object to the head
|
||||
// container.
|
||||
AddBaseTagInfo(it);
|
||||
rv = AddAttributes(aNode, it);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
parent->AppendChildTo(it, PR_FALSE);
|
||||
|
||||
// XXX It's just not sufficient to check if the parent is head. Also
|
||||
// check for the preference.
|
||||
// Bug 40072: Don't evaluate METAs after FRAMESET.
|
||||
if (!mInsideNoXXXTag && !mFrameset) {
|
||||
rv = nsContentSink::ProcessMETATag(it);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
HTMLContentSink::ForceReflow()
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
||||
static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
|
||||
@@ -802,25 +803,47 @@ nsImageMap::Init(nsIPresShell* aPresShell, nsIFrame* aImageFrame, nsIDOMHTMLMapE
|
||||
|
||||
|
||||
nsresult
|
||||
nsImageMap::UpdateAreasForBlock(nsIContent* aParent, PRBool* aFoundAnchor)
|
||||
nsImageMap::SearchForAreas(nsIContent* aParent, PRBool& aFoundArea,
|
||||
PRBool& aFoundAnchor)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRUint32 i, n = aParent->GetChildCount();
|
||||
|
||||
for (i = 0; (i < n) && NS_SUCCEEDED(rv); i++) {
|
||||
// Look for <area> or <a> elements. We'll use whichever type we find first.
|
||||
for (i = 0; i < n; i++) {
|
||||
nsIContent *child = aParent->GetChildAt(i);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> area = do_QueryInterface(child);
|
||||
if (area) {
|
||||
*aFoundAnchor = PR_TRUE;
|
||||
rv = AddArea(child);
|
||||
if (child->IsContentOfType(nsIContent::eHTML)) {
|
||||
// If we haven't determined that the map element contains an
|
||||
// <a> element yet, then look for <area>.
|
||||
if (!aFoundAnchor && child->Tag() == nsHTMLAtoms::area) {
|
||||
aFoundArea = PR_TRUE;
|
||||
rv = AddArea(child);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Continue to next child. This stops mContainsBlockContents from
|
||||
// getting set. It also makes us ignore children of <area>s which
|
||||
// is consistent with how we react to dynamic insertion of such
|
||||
// children.
|
||||
continue;
|
||||
}
|
||||
// If we haven't determined that the map element contains an
|
||||
// <area> element yet, then look for <a>.
|
||||
if (!aFoundArea && child->Tag() == nsHTMLAtoms::a) {
|
||||
aFoundAnchor = PR_TRUE;
|
||||
rv = AddArea(child);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = UpdateAreasForBlock(child, aFoundAnchor);
|
||||
|
||||
if (child->IsContentOfType(nsIContent::eELEMENT)) {
|
||||
mContainsBlockContents = PR_TRUE;
|
||||
rv = SearchForAreas(child, aFoundArea, aFoundAnchor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -829,38 +852,11 @@ nsImageMap::UpdateAreas()
|
||||
// Get rid of old area data
|
||||
FreeAreas();
|
||||
|
||||
PRUint32 i, n = mMap->GetChildCount();
|
||||
PRBool containsBlock = PR_FALSE, containsArea = PR_FALSE;
|
||||
PRBool foundArea = PR_FALSE;
|
||||
PRBool foundAnchor = PR_FALSE;
|
||||
mContainsBlockContents = PR_FALSE;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
nsIContent *child = mMap->GetChildAt(i);
|
||||
|
||||
// Only look at elements and not text, comments, etc.
|
||||
if (!child->IsContentOfType(nsIContent::eHTML))
|
||||
continue;
|
||||
|
||||
// First check if this map element contains an AREA element.
|
||||
// If so, we only look for AREA elements
|
||||
if (!containsBlock) {
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area = do_QueryInterface(child);
|
||||
if (area) {
|
||||
containsArea = PR_TRUE;
|
||||
AddArea(child);
|
||||
}
|
||||
}
|
||||
|
||||
// If we haven't determined that the map element contains an
|
||||
// AREA element yet, the look for a block element with children
|
||||
// that are anchors.
|
||||
if (!containsArea) {
|
||||
UpdateAreasForBlock(child, &containsBlock);
|
||||
|
||||
if (containsBlock)
|
||||
mContainsBlockContents = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return SearchForAreas(mMap, foundArea, foundAnchor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -979,9 +975,9 @@ nsImageMap::AttributeChanged(nsIDocument* aDocument,
|
||||
// the map. But only do this if the node is an HTML <area> or <a>
|
||||
// and the attribute that's changing is "shape" or "coords" -- those
|
||||
// are the only cases we care about.
|
||||
if (aContent->IsContentOfType(nsIContent::eHTML) &&
|
||||
(aContent->NodeInfo()->Equals(nsHTMLAtoms::area) ||
|
||||
if ((aContent->NodeInfo()->Equals(nsHTMLAtoms::area) ||
|
||||
aContent->NodeInfo()->Equals(nsHTMLAtoms::a)) &&
|
||||
aContent->IsContentOfType(nsIContent::eHTML) &&
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsHTMLAtoms::shape ||
|
||||
aAttribute == nsHTMLAtoms::coords)) {
|
||||
|
||||
@@ -114,7 +114,8 @@ protected:
|
||||
void FreeAreas();
|
||||
|
||||
nsresult UpdateAreas();
|
||||
nsresult UpdateAreasForBlock(nsIContent* aParent, PRBool* aFoundAnchor);
|
||||
nsresult SearchForAreas(nsIContent* aParent, PRBool& aFoundArea,
|
||||
PRBool& aFoundAnchor);
|
||||
|
||||
nsresult AddArea(nsIContent* aArea);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user