diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 554cfbc1251..d2e32d009a9 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -938,6 +938,14 @@ public: static void AppendNodeTextContent(nsINode* aNode, PRBool aDeep, nsAString& aResult); + /** + * Utility method that checks if a given node has any non-empty + * children. + * NOTE! This method does not descend recursivly into elements. + * Though it would be easy to make it so if needed + */ + static PRBool HasNonEmptyTextContent(nsINode* aNode); + private: static nsresult doReparentContentWrapper(nsIContent *aChild, JSContext *cx, diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index d05d5437134..a7a02e74491 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -3410,3 +3410,18 @@ nsContentUtils::AppendNodeTextContent(nsINode* aNode, PRBool aDeep, } } } + +PRBool +nsContentUtils::HasNonEmptyTextContent(nsINode* aNode) +{ + nsIContent* child; + PRUint32 i; + for (i = 0; (child = aNode->GetChildAt(i)); ++i) { + if (child->IsNodeOfType(nsINode::eTEXT) && + child->TextLength() > 0) { + return PR_TRUE; + } + } + + return PR_FALSE; +} diff --git a/mozilla/content/base/src/nsScriptElement.cpp b/mozilla/content/base/src/nsScriptElement.cpp index 7a01580f095..94779b1d621 100755 --- a/mozilla/content/base/src/nsScriptElement.cpp +++ b/mozilla/content/base/src/nsScriptElement.cpp @@ -138,9 +138,7 @@ nsScriptElement::AttributeChanged(nsIDocument* aDocument, nsIAtom* aAttribute, PRInt32 aModType) { - if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::src) { - MaybeProcessScript(); - } + MaybeProcessScript(); } void @@ -194,8 +192,7 @@ nsScriptElement::MaybeProcessScript() if (mIsEvaluated || !mDoneAddingChildren || !cont->IsInDoc() || mMalformed || InNonScriptingContainer(cont) || - !(cont->HasAttr(kNameSpaceID_None, nsGkAtoms::src) || - cont->GetChildCount())) { + !HasScriptContent()) { return NS_OK; } diff --git a/mozilla/content/base/src/nsScriptElement.h b/mozilla/content/base/src/nsScriptElement.h index b4f21417bc3..14630aa79f9 100755 --- a/mozilla/content/base/src/nsScriptElement.h +++ b/mozilla/content/base/src/nsScriptElement.h @@ -73,6 +73,11 @@ public: protected: // Internal methods + /** + * Check if this element contains any script, linked or inline + */ + virtual PRBool HasScriptContent() = 0; + /** * Processes the script if it's in the document-tree and links to or * contains a script. Once it has been evaluated there is no way to make it diff --git a/mozilla/content/html/content/src/nsHTMLScriptElement.cpp b/mozilla/content/html/content/src/nsHTMLScriptElement.cpp index 2b07757a914..044dfec4671 100644 --- a/mozilla/content/html/content/src/nsHTMLScriptElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLScriptElement.cpp @@ -357,19 +357,8 @@ protected: // Pointer to the script handler helper object (OWNING reference) nsCOMPtr mScriptEventHandler; - /** - * Processes the script if it's in the document-tree and links to or - * contains a script. Once it has been evaluated there is no way to make it - * reevaluate the script, you'll have to create a new element. This also means - * that when adding a src attribute to an element that already contains an - * inline script, the script referenced by the src attribute will not be - * loaded. - * - * In order to be able to use multiple childNodes, or to use the - * fallback-mechanism of using both inline script and linked script you have - * to add all attributes and childNodes before adding the element to the - * document-tree. - */ + // nsScriptElement + virtual PRBool HasScriptContent(); virtual nsresult MaybeProcessScript(); }; @@ -532,6 +521,13 @@ nsHTMLScriptElement::GetScriptCharset(nsAString& charset) GetCharset(charset); } +PRBool +nsHTMLScriptElement::HasScriptContent() +{ + return HasAttr(kNameSpaceID_None, nsGkAtoms::src) || + nsContentUtils::HasNonEmptyTextContent(this); +} + nsresult nsHTMLScriptElement::MaybeProcessScript() { diff --git a/mozilla/content/svg/content/src/nsSVGScriptElement.cpp b/mozilla/content/svg/content/src/nsSVGScriptElement.cpp index 759ec7fd15f..cfadfcd7c05 100644 --- a/mozilla/content/svg/content/src/nsSVGScriptElement.cpp +++ b/mozilla/content/svg/content/src/nsSVGScriptElement.cpp @@ -81,11 +81,15 @@ public: virtual void GetScriptText(nsAString& text); virtual void GetScriptCharset(nsAString& charset); + // nsScriptElement + virtual PRBool HasScriptContent(); + // nsISVGValueObserver specializations: NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable, nsISVGValue::modificationType aModType); // nsIContent specializations: + virtual nsresult DoneAddingChildren(PRBool aHaveNotified); virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, PRBool aCompileEventHandlers); @@ -222,6 +226,17 @@ nsSVGScriptElement::GetScriptCharset(nsAString& charset) charset.Truncate(); } +//---------------------------------------------------------------------- +// nsScriptElement methods + +PRBool +nsSVGScriptElement::HasScriptContent() +{ + nsAutoString src; + mHref->GetAnimVal(src); + return !src.IsEmpty() || nsContentUtils::HasNonEmptyTextContent(this); +} + //---------------------------------------------------------------------- // nsISVGValueObserver methods @@ -241,6 +256,13 @@ nsSVGScriptElement::DidModifySVGObservable(nsISVGValue* aObservable, //---------------------------------------------------------------------- // nsIContent methods +nsresult +nsSVGScriptElement::DoneAddingChildren(PRBool aHaveNotified) +{ + mDoneAddingChildren = PR_TRUE; + return MaybeProcessScript(); +} + nsresult nsSVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent,