Bug 429175: Make sure to only set aNotify to true when we should. r=peterv

This commit is contained in:
Jonas Sicking 2010-05-03 06:23:36 -07:00
Родитель 9b1b0e240d
Коммит 3a279be650
15 изменённых файлов: 48 добавлений и 106 удалений

Просмотреть файл

@ -3530,6 +3530,12 @@ nsContentUtils::HasMutationListeners(nsINode* aNode,
return PR_FALSE;
}
NS_ASSERTION((aNode->IsNodeOfType(nsINode::eCONTENT) &&
static_cast<nsIContent*>(aNode)->
IsInNativeAnonymousSubtree()) ||
sScriptBlockerCount == sRemovableScriptBlockerCount,
"Want to fire mutation events, but it's not safe");
// global object will be null for documents that don't have windows.
nsPIDOMWindow* window = doc->GetInnerWindow();
// This relies on nsEventListenerManager::AddEventListener, which sets

Просмотреть файл

@ -842,7 +842,10 @@ nsDOMAttribute::EnsureChildState(PRBool aSetText, PRBool &aHasChild) const
aHasChild = !value.IsEmpty();
if (aSetText && aHasChild) {
mChild->SetText(value, PR_TRUE);
// aNotify should probably be PR_TRUE sometimes, but it's unlikely that
// anyone cares. And we aren't updating the node when the attribute changes
// anyway so any notifications are way late.
mChild->SetText(value, PR_FALSE);
}
return NS_OK;

Просмотреть файл

@ -468,58 +468,6 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNode, PRBool aDeep, nsIDOMNode **aResult)
return NS_OK;
}
class AdoptFuncData {
public:
AdoptFuncData(nsGenericElement *aElement,
nsNodeInfoManager *aNewNodeInfoManager, JSContext *aCx,
JSObject *aOldScope, JSObject *aNewScope,
nsCOMArray<nsINode> &aNodesWithProperties)
: mElement(aElement),
mNewNodeInfoManager(aNewNodeInfoManager),
mCx(aCx),
mOldScope(aOldScope),
mNewScope(aNewScope),
mNodesWithProperties(aNodesWithProperties)
{
}
nsGenericElement *mElement;
nsNodeInfoManager *mNewNodeInfoManager;
JSContext *mCx;
JSObject *mOldScope;
JSObject *mNewScope;
nsCOMArray<nsINode> &mNodesWithProperties;
};
PLDHashOperator
AdoptFunc(nsAttrHashKey::KeyType aKey, nsIDOMNode *aData, void* aUserArg)
{
nsCOMPtr<nsIAttribute> attr = do_QueryInterface(aData);
NS_ASSERTION(attr, "non-nsIAttribute somehow made it into the hashmap?!");
AdoptFuncData *data = static_cast<AdoptFuncData*>(aUserArg);
// If we were passed an element we need to clone the attribute nodes and
// insert them into the element.
PRBool clone = data->mElement != nsnull;
nsCOMPtr<nsINode> node;
nsresult rv = nsNodeUtils::CloneAndAdopt(attr, clone, PR_TRUE,
data->mNewNodeInfoManager,
data->mCx, data->mOldScope,
data->mNewScope,
data->mNodesWithProperties,
nsnull, getter_AddRefs(node));
if (NS_SUCCEEDED(rv) && clone) {
nsCOMPtr<nsIDOMAttr> dummy, attribute = do_QueryInterface(node, &rv);
if (NS_SUCCEEDED(rv)) {
rv = data->mElement->SetAttributeNode(attribute, getter_AddRefs(dummy));
}
}
return NS_SUCCEEDED(rv) ? PL_DHASH_NEXT : PL_DHASH_STOP;
}
/* static */
nsresult
nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
@ -657,22 +605,10 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
}
}
if (elem) {
// aNode's attributes.
const nsDOMAttributeMap *map = elem->GetAttributeMap();
if (map) {
// If we're cloning we need to insert the cloned attribute nodes into the
// cloned element. We assume that the clone of an nsGenericElement is also
// an nsGenericElement.
nsGenericElement* elemClone =
aClone ? static_cast<nsGenericElement*>(clone.get()) : nsnull;
AdoptFuncData data(elemClone, nodeInfoManager, aCx, aOldScope, aNewScope,
aNodesWithProperties);
PRUint32 count = map->Enumerate(AdoptFunc, &data);
NS_ENSURE_TRUE(count == map->Count(), NS_ERROR_FAILURE);
}
}
// XXX If there are any attribute nodes on this element with UserDataHandlers
// we should technically adopt/clone/import such attribute nodes and notify
// those handlers. However we currently don't have code to do so without
// also notifying when it's not safe so we're not doing that at this time.
// The DOM spec says to always adopt/clone/import the children of attribute
// nodes.

Просмотреть файл

@ -118,7 +118,9 @@ protected:
PRInt32 aNameSpaceID,
nsIAtom* aTagName,
PRUint32 aLineNumber);
PRBool NotifyForDocElement() { return PR_FALSE; }
nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
nsIContent** aResult, PRBool* aAppendContent,

Просмотреть файл

@ -963,7 +963,7 @@ nsXMLContentSink::SetDocElement(PRInt32 aNameSpaceID,
mDocElement = aContent;
NS_ADDREF(mDocElement);
nsresult rv = mDocument->AppendChildTo(mDocElement, PR_TRUE);
nsresult rv = mDocument->AppendChildTo(mDocElement, NotifyForDocElement());
if (NS_FAILED(rv)) {
// If we return PR_FALSE here, the caller will bail out because it won't
// find a parent content node to append to, which is fine.

Просмотреть файл

@ -133,6 +133,7 @@ protected:
virtual PRBool SetDocElement(PRInt32 aNameSpaceID,
nsIAtom *aTagName,
nsIContent *aContent);
virtual PRBool NotifyForDocElement() { return PR_TRUE; }
virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
nsIContent** aResult, PRBool* aAppendContent,

Просмотреть файл

@ -170,6 +170,7 @@ EDITOR_ATOM(cssZIndex, "z-index")
EDITOR_ATOM(cssMozUserModify, "-moz-user-modify")
EDITOR_ATOM(cssMozUserSelect, "-moz-user-select")
EDITOR_ATOM(mozdirty, "_moz_dirty")
EDITOR_ATOM(mozEditorBogusNode, "_moz_editor_bogus_node")
EDITOR_ATOM(cssPxUnit, "px")
EDITOR_ATOM(cssEmUnit, "em")

Просмотреть файл

@ -68,6 +68,7 @@
#include "nsISelectionPrivate.h"
#include "nsISelectionController.h"
#include "nsIEnumerator.h"
#include "nsEditProperty.h"
#include "nsIAtom.h"
#include "nsCaret.h"
#include "nsIWidget.h"
@ -1206,9 +1207,10 @@ NS_IMETHODIMP
nsEditor::MarkNodeDirty(nsIDOMNode* aNode)
{
// mark the node dirty.
nsCOMPtr<nsIDOMElement> element (do_QueryInterface(aNode));
nsCOMPtr<nsIContent> element (do_QueryInterface(aNode));
if (element)
element->SetAttribute(NS_LITERAL_STRING("_moz_dirty"), EmptyString());
element->SetAttr(kNameSpaceID_None, nsEditProperty::mozdirty,
EmptyString(), PR_FALSE);
return NS_OK;
}
@ -3633,20 +3635,10 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
PRBool
nsEditor::IsMozEditorBogusNode(nsIDOMNode *aNode)
{
if (!aNode)
return PR_FALSE;
nsCOMPtr<nsIDOMElement>element = do_QueryInterface(aNode);
if (element)
{
nsAutoString val;
(void)element->GetAttribute(kMOZEditorBogusNodeAttr, val);
if (val.Equals(kMOZEditorBogusNodeValue)) {
return PR_TRUE;
}
}
return PR_FALSE;
nsCOMPtr<nsIContent> element = do_QueryInterface(aNode);
return element &&
element->AttrValueIs(kNameSpaceID_None, kMOZEditorBogusNodeAttrAtom,
kMOZEditorBogusNodeValue, eCaseMatters);
}
nsresult

Просмотреть файл

@ -87,7 +87,7 @@ class nsIFile;
class nsISelectionController;
class nsIDOMEventTarget;
#define kMOZEditorBogusNodeAttr NS_LITERAL_STRING("_moz_editor_bogus_node")
#define kMOZEditorBogusNodeAttrAtom nsEditProperty::mozEditorBogusNode
#define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
/** implementation of an editor object. it will be the controller/focal point

Просмотреть файл

@ -57,6 +57,7 @@
#include "nsIContentIterator.h"
#include "nsEditorUtils.h"
#include "EditTxn.h"
#include "nsEditProperty.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsUnicharUtils.h"
@ -1347,8 +1348,8 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
if (!mBogusNode) return NS_ERROR_NULL_POINTER;
// give it a special attribute
brElement->SetAttribute( kMOZEditorBogusNodeAttr,
kMOZEditorBogusNodeValue );
newContent->SetAttr(kNameSpaceID_None, kMOZEditorBogusNodeAttrAtom,
kMOZEditorBogusNodeValue, PR_FALSE);
// put the node in the document
res = mEditor->InsertNode(mBogusNode, body, 0);

Просмотреть файл

@ -3598,6 +3598,15 @@ nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
NS_ASSERTION(aContent && aAttrName, "Missing stuff, prepare to crash");
}
nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
PRInt32 aValue)
: mContent(aContent),
mAttrName(aAttrName)
{
NS_ASSERTION(aContent && aAttrName, "Missing stuff, prepare to crash");
mValue.AppendInt(aValue);
}
NS_IMETHODIMP
nsSetAttrRunnable::Run()
{

Просмотреть файл

@ -1188,6 +1188,8 @@ class nsSetAttrRunnable : public nsRunnable
public:
nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
const nsAString& aValue);
nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
PRInt32 aValue);
NS_DECL_NSIRUNNABLE

Просмотреть файл

@ -59,6 +59,7 @@
#include "nsIEditorIMESupport.h"
#include "nsIPhonetic.h"
#include "nsIEditorObserver.h"
#include "nsEditProperty.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
@ -2975,11 +2976,7 @@ nsTextControlFrame::UpdateValueDisplay(PRBool aNotify,
if (!aBeforeEditorInit)
{
nsWeakFrame weakFrame(this);
if (value.IsEmpty()) {
ShowPlaceholder();
} else {
HidePlaceholder();
}
SetPlaceholderClass(value.IsEmpty(), aNotify);
NS_ENSURE_STATE(weakFrame.IsAlive());
}

Просмотреть файл

@ -155,16 +155,10 @@ nsProgressMeterFrame::AttributeChanged(PRInt32 aNameSpaceID,
flex = maxFlex;
}
PRInt32 remainder = maxFlex - flex;
nsAutoString leftFlex, rightFlex;
leftFlex.AppendInt(flex);
rightFlex.AppendInt(remainder);
nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
barChild->GetContent(), nsGkAtoms::flex, leftFlex));
barChild->GetContent(), nsGkAtoms::flex, flex));
nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
remainderContent, nsGkAtoms::flex, rightFlex));
remainderContent, nsGkAtoms::flex, maxFlex - flex));
nsContentUtils::AddScriptRunner(new nsReflowFrameRunnable(
this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY));
}

Просмотреть файл

@ -302,10 +302,8 @@ nsSliderFrame::AttributeChanged(PRInt32 aNameSpaceID,
}
}
nsAutoString currentStr;
currentStr.AppendInt(current);
nsContentUtils::AddScriptRunner(
new nsSetAttrRunnable(scrollbar, nsGkAtoms::curpos, currentStr));
new nsSetAttrRunnable(scrollbar, nsGkAtoms::curpos, current));
}
}