diff --git a/mozilla/editor/libeditor/html/crashtests/420439.html b/mozilla/editor/libeditor/html/crashtests/420439.html
new file mode 100644
index 00000000000..e1303307da0
--- /dev/null
+++ b/mozilla/editor/libeditor/html/crashtests/420439.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/mozilla/editor/libeditor/html/crashtests/crashtests.list b/mozilla/editor/libeditor/html/crashtests/crashtests.list
index 252cb98981d..fd9d647636d 100644
--- a/mozilla/editor/libeditor/html/crashtests/crashtests.list
+++ b/mozilla/editor/libeditor/html/crashtests/crashtests.list
@@ -2,3 +2,4 @@ load 336081-1.xhtml # asserts (no bug?)
load 382778-1.html
load 407074-1.html
load 407277-1.html
+load 420439.html
diff --git a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp
index aa06b289a83..cf36afcd20f 100644
--- a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp
@@ -334,6 +334,11 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
{
NS_ENSURE_ARG_POINTER(aElement);
+ if (mGrabber) {
+ NS_ERROR("call HideGrabber first");
+ return NS_ERROR_UNEXPECTED;
+ }
+
nsAutoString classValue;
nsresult res = CheckPositionedElementBGandFG(aElement, classValue);
if (NS_FAILED(res)) return res;
diff --git a/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp b/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
index b76aef84352..670bd760afb 100644
--- a/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
@@ -344,30 +344,29 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection)
// cellElement contains the element for InlineTableEditing
// absPosElement contains the element for Positioning
- // first let's cancel old settings if needed
- PRBool refreshResizing = (mResizedObject != nsnull);
- PRBool refreshPositioning = (mAbsolutelyPositionedObject != nsnull);
- PRBool refreshTableEditing = (mInlineEditedCell != nsnull);
+ // Note: All the Hide/Show methods below may change attributes on real
+ // content which means a DOMAttrModified handler may cause arbitrary
+ // side effects while this code runs (bug 420439).
if (mIsAbsolutelyPositioningEnabled && mAbsolutelyPositionedObject &&
absPosElement != mAbsolutelyPositionedObject) {
res = HideGrabber();
if (NS_FAILED(res)) return res;
- refreshPositioning = PR_FALSE;
+ NS_ASSERTION(!mAbsolutelyPositionedObject, "HideGrabber failed");
}
if (mIsObjectResizingEnabled && mResizedObject &&
mResizedObject != focusElement) {
res = HideResizers();
if (NS_FAILED(res)) return res;
- refreshResizing = PR_FALSE;
+ NS_ASSERTION(!mResizedObject, "HideResizers failed");
}
if (mIsInlineTableEditingEnabled && mInlineEditedCell &&
mInlineEditedCell != cellElement) {
res = HideInlineTableEditingUI();
if (NS_FAILED(res)) return res;
- refreshTableEditing = PR_FALSE;
+ NS_ASSERTION(!mInlineEditedCell, "HideInlineTableEditingUI failed");
}
// now, let's display all contextual UI for good
@@ -376,7 +375,7 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection)
IsModifiableNode(focusElement)) {
if (nsEditProperty::img == focusTagAtom)
mResizedObjectIsAnImage = PR_TRUE;
- if (refreshResizing)
+ if (mResizedObject)
res = RefreshResizers();
else
res = ShowResizers(focusElement);
@@ -385,7 +384,7 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection)
if (mIsAbsolutelyPositioningEnabled && absPosElement &&
IsModifiableNode(absPosElement)) {
- if (refreshPositioning)
+ if (mAbsolutelyPositionedObject)
res = RefreshGrabber();
else
res = ShowGrabberOnElement(absPosElement);
@@ -394,7 +393,7 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection)
if (mIsInlineTableEditingEnabled && cellElement &&
IsModifiableNode(cellElement)) {
- if (refreshTableEditing)
+ if (mInlineEditedCell)
res = RefreshInlineTableEditingUI();
else
res = ShowInlineTableEditingUI(cellElement);
diff --git a/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp
index 452ed45b438..1d70ebaa282 100644
--- a/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp
@@ -71,6 +71,11 @@ nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell)
if (!nsHTMLEditUtils::IsTableCell(aCell))
return NS_OK;
+ if (mInlineEditedCell) {
+ NS_ERROR("call HideInlineTableEditingUI first");
+ return NS_ERROR_UNEXPECTED;
+ }
+
// the resizers and the shadow will be anonymous children of the body
nsIDOMElement *bodyElement = GetRoot();
if (!bodyElement) return NS_ERROR_NULL_POINTER;
diff --git a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp
index eb84689fd64..96d1e5ad1f7 100644
--- a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp
@@ -336,6 +336,12 @@ NS_IMETHODIMP
nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
{
NS_ENSURE_ARG_POINTER(aResizedElement);
+
+ if (mResizedObject) {
+ NS_ERROR("call HideResizers first");
+ return NS_ERROR_UNEXPECTED;
+ }
+
mResizedObject = aResizedElement;
// The resizers and the shadow will be anonymous siblings of the element.
@@ -476,6 +482,11 @@ nsHTMLEditor::HideResizers(void)
mResizingInfo, parentContent, ps);
mResizingInfo = nsnull;
+ if (mActivatedHandle) {
+ mActivatedHandle->RemoveAttribute(NS_LITERAL_STRING("_moz_activated"));
+ mActivatedHandle = nsnull;
+ }
+
// don't forget to remove the listeners !
nsCOMPtr piTarget = GetPIDOMEventTarget();