diff --git a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp
index 3f9716d6a5d..aa06b289a83 100644
--- a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp
@@ -106,7 +106,7 @@ nsHTMLEditor::GetAbsolutelyPositionedSelectionContainer(nsIDOMElement **_retval)
nsCOMPtr node = do_QueryInterface(element);
nsCOMPtr resultNode;
- do {
+ while (!resultNode && !nsEditor::NodeIsType(node, nsEditProperty::html)) {
res = mHTMLCSSUtils->GetComputedProperty(node, nsEditProperty::cssPosition,
positionStr);
if (NS_FAILED(res)) return res;
@@ -118,8 +118,7 @@ nsHTMLEditor::GetAbsolutelyPositionedSelectionContainer(nsIDOMElement **_retval)
if (NS_FAILED(res)) return res;
node.swap(parentNode);
}
- } while (!resultNode &&
- !nsEditor::NodeIsType(node, nsEditProperty::html));
+ }
element = do_QueryInterface(resultNode );
*_retval = element;
@@ -315,16 +314,16 @@ nsHTMLEditor::HideGrabber()
nsCOMPtr ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
- // get the root content node.
+ nsCOMPtr parentNode;
+ res = mGrabber->GetParentNode(getter_AddRefs(parentNode));
+ NS_ENSURE_SUCCESS(res, res);
- nsIDOMElement *rootElement = GetRoot();
+ nsCOMPtr parentContent = do_QueryInterface(parentNode);
+ if (!parentContent) return NS_ERROR_NULL_POINTER;
- nsCOMPtr rootContent = do_QueryInterface(rootElement);
- if (!rootContent) return NS_ERROR_NULL_POINTER;
-
- DeleteRefToAnonymousNode(mGrabber, rootContent, ps);
+ DeleteRefToAnonymousNode(mGrabber, parentContent, ps);
mGrabber = nsnull;
- DeleteRefToAnonymousNode(mPositioningShadow, rootContent, ps);
+ DeleteRefToAnonymousNode(mPositioningShadow, parentContent, ps);
mPositioningShadow = nsnull;
return NS_OK;
@@ -346,11 +345,13 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
// first, let's keep track of that element...
mAbsolutelyPositionedObject = aElement;
- nsIDOMElement *rootElement = GetRoot();
- if (!rootElement) return NS_ERROR_NULL_POINTER;
+ nsCOMPtr parentNode;
+ res = aElement->GetParentNode(getter_AddRefs(parentNode));
+ NS_ENSURE_SUCCESS(res, res);
+
+ res = CreateGrabber(parentNode, getter_AddRefs(mGrabber));
+ NS_ENSURE_SUCCESS(res, res);
- res = CreateGrabber(rootElement, getter_AddRefs(mGrabber));
- if (NS_FAILED(res)) return res;
// and set its position
return RefreshGrabber();
}
@@ -358,16 +359,17 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
nsresult
nsHTMLEditor::StartMoving(nsIDOMElement *aHandle)
{
- nsIDOMElement *rootElement = GetRoot();
- if (!rootElement) return NS_ERROR_NULL_POINTER;
+ nsCOMPtr parentNode;
+ nsresult res = mGrabber->GetParentNode(getter_AddRefs(parentNode));
+ NS_ENSURE_SUCCESS(res, res);
// now, let's create the resizing shadow
- nsresult result = CreateShadow(getter_AddRefs(mPositioningShadow),
- rootElement, mAbsolutelyPositionedObject);
- if (NS_FAILED(result)) return result;
- result = SetShadowPosition(mPositioningShadow, mAbsolutelyPositionedObject,
+ res = CreateShadow(getter_AddRefs(mPositioningShadow),
+ parentNode, mAbsolutelyPositionedObject);
+ NS_ENSURE_SUCCESS(res,res);
+ res = SetShadowPosition(mPositioningShadow, mAbsolutelyPositionedObject,
mPositionedObjectX, mPositionedObjectY);
- if (NS_FAILED(result)) return result;
+ NS_ENSURE_SUCCESS(res,res);
// make the shadow appear
mPositioningShadow->RemoveAttribute(NS_LITERAL_STRING("class"));
@@ -381,7 +383,7 @@ nsHTMLEditor::StartMoving(nsIDOMElement *aHandle)
mPositionedObjectHeight);
mIsMoving = PR_TRUE;
- return result;
+ return res;
}
void
@@ -421,14 +423,15 @@ nsHTMLEditor::EndMoving()
nsCOMPtr ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
- // get the root content node.
+ nsCOMPtr parentNode;
+ nsresult res = mGrabber->GetParentNode(getter_AddRefs(parentNode));
+ NS_ENSURE_SUCCESS(res, res);
- nsIDOMElement *rootElement = GetRoot();
+ nsCOMPtr parentContent( do_QueryInterface(parentNode) );
+ if (!parentContent) return NS_ERROR_FAILURE;
- nsCOMPtr rootContent( do_QueryInterface(rootElement) );
- if (!rootContent) return NS_ERROR_FAILURE;
+ DeleteRefToAnonymousNode(mPositioningShadow, parentContent, ps);
- DeleteRefToAnonymousNode(mPositioningShadow, rootContent, ps);
mPositioningShadow = nsnull;
}
nsCOMPtr piTarget = GetPIDOMEventTarget();
diff --git a/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp b/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
index d8f71067784..2dbdc6868af 100644
--- a/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
@@ -203,8 +203,18 @@ nsHTMLEditor::DeleteRefToAnonymousNode(nsIDOMElement* aElement,
aShell->GetPresContext()->GetPresShell() == aShell) {
nsCOMPtr docObserver = do_QueryInterface(aShell);
if (docObserver) {
+ // Call BeginUpdate() so that the nsCSSFrameConstructor/PresShell
+ // knows we're messing with the frame tree.
+ nsCOMPtr domDocument;
+ nsresult res = GetDocument(getter_AddRefs(domDocument));
+ nsCOMPtr document = do_QueryInterface(domDocument);
+ if (document)
+ docObserver->BeginUpdate(document, UPDATE_CONTENT_MODEL);
+
docObserver->ContentRemoved(content->GetCurrentDoc(),
aParentContent, content, -1);
+ if (document)
+ docObserver->EndUpdate(document, UPDATE_CONTENT_MODEL);
}
}
content->UnbindFromTree();
diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp
index 22f6931e4bb..694c6502b63 100644
--- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp
@@ -5800,34 +5800,21 @@ nsHTMLEditor::CopyLastEditableChildStyles(nsIDOMNode * aPreviousBlock, nsIDOMNod
nsresult
nsHTMLEditor::GetElementOrigin(nsIDOMElement * aElement, PRInt32 & aX, PRInt32 & aY)
{
- // we are going to need the PresShell
+ aX = 0;
+ aY = 0;
+
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr content = do_QueryInterface(aElement);
- nsIFrame *frame = ps->GetPrimaryFrameFor(content); // not ref-counted
+ nsIFrame *frame = ps->GetPrimaryFrameFor(content);
- if (nsHTMLEditUtils::IsHR(aElement) && frame) {
- frame = frame->GetNextSibling();
- }
- PRInt32 offsetX = 0, offsetY = 0;
- while (frame) {
- // Look for a widget so we can get screen coordinates
- nsIView* view = frame->GetViewExternal();
- if (view && view->HasWidget())
- break;
-
- // No widget yet, so count up the coordinates of the frame
- nsPoint origin = frame->GetPosition();
- offsetX += origin.x;
- offsetY += origin.y;
-
- frame = frame->GetParent();
- }
-
- aX = nsPresContext::AppUnitsToIntCSSPixels(offsetX);
- aY = nsPresContext::AppUnitsToIntCSSPixels(offsetY);
+ nsIFrame *container = ps->GetAbsoluteContainingBlock(frame);
+ if (!frame) return NS_OK;
+ nsPoint off = frame->GetOffsetTo(container);
+ aX = nsPresContext::AppUnitsToIntCSSPixels(off.x);
+ aY = nsPresContext::AppUnitsToIntCSSPixels(off.y);
return NS_OK;
}
diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h
index 1ab4d1a62f3..2a1e91453b7 100644
--- a/mozilla/editor/libeditor/html/nsHTMLEditor.h
+++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h
@@ -815,6 +815,8 @@ protected:
void DeleteRefToAnonymousNode(nsIDOMElement* aElement,
nsIContent * aParentContent,
nsIPresShell* aShell);
+
+ // Returns the offset of an element's frame to its absolute containing block.
nsresult GetElementOrigin(nsIDOMElement * aElement, PRInt32 & aX, PRInt32 & aY);
nsresult GetPositionAndDimensions(nsIDOMElement * aElement,
PRInt32 & aX, PRInt32 & aY,
diff --git a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp
index f430752dfe6..eb84689fd64 100644
--- a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp
@@ -338,37 +338,37 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
NS_ENSURE_ARG_POINTER(aResizedElement);
mResizedObject = aResizedElement;
- // the resizers and the shadow will be anonymous children of the body
- nsIDOMElement *bodyElement = GetRoot();
- if (!bodyElement) return NS_ERROR_NULL_POINTER;
-
- // let's create the resizers
+ // The resizers and the shadow will be anonymous siblings of the element.
nsresult res;
+ nsCOMPtr parentNode;
+ res = aResizedElement->GetParentNode(getter_AddRefs(parentNode));
+ NS_ENSURE_SUCCESS(res, res);
+
res = CreateResizer(getter_AddRefs(mTopLeftHandle),
- nsIHTMLObjectResizer::eTopLeft, bodyElement);
+ nsIHTMLObjectResizer::eTopLeft, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mTopHandle),
- nsIHTMLObjectResizer::eTop, bodyElement);
+ nsIHTMLObjectResizer::eTop, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mTopRightHandle),
- nsIHTMLObjectResizer::eTopRight, bodyElement);
+ nsIHTMLObjectResizer::eTopRight, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mLeftHandle),
- nsIHTMLObjectResizer::eLeft, bodyElement);
+ nsIHTMLObjectResizer::eLeft, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mRightHandle),
- nsIHTMLObjectResizer::eRight, bodyElement);
+ nsIHTMLObjectResizer::eRight, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mBottomLeftHandle),
- nsIHTMLObjectResizer::eBottomLeft, bodyElement);
+ nsIHTMLObjectResizer::eBottomLeft, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mBottomHandle),
- nsIHTMLObjectResizer::eBottom, bodyElement);
+ nsIHTMLObjectResizer::eBottom, parentNode);
if (NS_FAILED(res)) return res;
res = CreateResizer(getter_AddRefs(mBottomRightHandle),
- nsIHTMLObjectResizer::eBottomRight, bodyElement);
+ nsIHTMLObjectResizer::eBottomRight, parentNode);
if (NS_FAILED(res)) return res;
res = GetPositionAndDimensions(aResizedElement,
@@ -387,7 +387,7 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
if (NS_FAILED(res)) return res;
// now, let's create the resizing shadow
- res = CreateShadow(getter_AddRefs(mResizingShadow), bodyElement,
+ res = CreateShadow(getter_AddRefs(mResizingShadow), parentNode,
aResizedElement);
if (NS_FAILED(res)) return res;
// and set its position
@@ -396,7 +396,7 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
if (NS_FAILED(res)) return res;
// and then the resizing info tooltip
- res = CreateResizingInfo(getter_AddRefs(mResizingInfo), bodyElement);
+ res = CreateResizingInfo(getter_AddRefs(mResizingInfo), parentNode);
if (NS_FAILED(res)) return res;
@@ -428,60 +428,58 @@ nsHTMLEditor::HideResizers(void)
nsCOMPtr ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
- // get the root content node.
-
- nsIDOMElement *bodyElement = GetRoot();
-
- nsCOMPtr bodyContent( do_QueryInterface(bodyElement) );
- if (!bodyContent) return NS_ERROR_FAILURE;
+ nsresult res;
+ nsCOMPtr parentNode;
+ res = mTopLeftHandle->GetParentNode(getter_AddRefs(parentNode));
+ NS_ENSURE_SUCCESS(res, res);
+ nsCOMPtr parentContent = do_QueryInterface(parentNode);
NS_NAMED_LITERAL_STRING(mousedown, "mousedown");
-
+
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mTopLeftHandle, bodyContent, ps);
+ mTopLeftHandle, parentContent, ps);
mTopLeftHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mTopHandle, bodyContent, ps);
+ mTopHandle, parentContent, ps);
mTopHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mTopRightHandle, bodyContent, ps);
+ mTopRightHandle, parentContent, ps);
mTopRightHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mLeftHandle, bodyContent, ps);
+ mLeftHandle, parentContent, ps);
mLeftHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mRightHandle, bodyContent, ps);
+ mRightHandle, parentContent, ps);
mRightHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mBottomLeftHandle, bodyContent, ps);
+ mBottomLeftHandle, parentContent, ps);
mBottomLeftHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mBottomHandle, bodyContent, ps);
+ mBottomHandle, parentContent, ps);
mBottomHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mBottomRightHandle, bodyContent, ps);
+ mBottomRightHandle, parentContent, ps);
mBottomRightHandle = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mResizingShadow, bodyContent, ps);
+ mResizingShadow, parentContent, ps);
mResizingShadow = nsnull;
RemoveListenerAndDeleteRef(mousedown, mMouseListenerP, PR_TRUE,
- mResizingInfo, bodyContent, ps);
+ mResizingInfo, parentContent, ps);
mResizingInfo = nsnull;
// don't forget to remove the listeners !
nsCOMPtr piTarget = GetPIDOMEventTarget();
nsCOMPtr target = do_QueryInterface(piTarget);
- nsresult res;
if (target && mMouseMotionListenerP)
{
@@ -683,10 +681,45 @@ nsHTMLEditor::SetResizingInfoPosition(PRInt32 aX, PRInt32 aY, PRInt32 aW, PRInt3
NS_NAMED_LITERAL_STRING(leftStr, "left");
NS_NAMED_LITERAL_STRING(topStr, "top");
+
+ // Determine the position of the resizing info box based upon the new
+ // position and size of the element (aX, aY, aW, aH), and which
+ // resizer is the "activated handle". For example, place the resizing
+ // info box at the bottom-right corner of the new element, if the element
+ // is being resized by the bottom-right resizer.
+ PRInt32 infoXPosition;
+ PRInt32 infoYPosition;
+
+ if (mActivatedHandle == mTopLeftHandle ||
+ mActivatedHandle == mLeftHandle ||
+ mActivatedHandle == mBottomLeftHandle)
+ infoXPosition = aX;
+ else if (mActivatedHandle == mTopHandle ||
+ mActivatedHandle == mBottomHandle)
+ infoXPosition = aX + (aW / 2);
+ else
+ // should only occur when mActivatedHandle is one of the 3 right-side
+ // handles, but this is a reasonable default if it isn't any of them (?)
+ infoXPosition = aX + aW;
+
+ if (mActivatedHandle == mTopLeftHandle ||
+ mActivatedHandle == mTopHandle ||
+ mActivatedHandle == mTopRightHandle)
+ infoYPosition = aY;
+ else if (mActivatedHandle == mLeftHandle ||
+ mActivatedHandle == mRightHandle)
+ infoYPosition = aY + (aH / 2);
+ else
+ // should only occur when mActivatedHandle is one of the 3 bottom-side
+ // handles, but this is a reasonable default if it isn't any of them (?)
+ infoYPosition = aY + aH;
+
+ // Offset info box by 20 so it's not directly under the mouse cursor.
+ const int mouseCursorOffset = 20;
mHTMLCSSUtils->SetCSSPropertyPixels(mResizingInfo, leftStr,
- aX + mInfoXIncrement);
+ infoXPosition + mouseCursorOffset);
mHTMLCSSUtils->SetCSSPropertyPixels(mResizingInfo, topStr,
- aY + mInfoYIncrement);
+ infoYPosition + mouseCursorOffset);
nsCOMPtr textInfo;
nsresult res = mResizingInfo->GetFirstChild(getter_AddRefs(textInfo));
@@ -840,15 +873,17 @@ nsHTMLEditor::MouseMove(nsIDOMEvent* aMouseEvent)
mouseEvent->GetClientX(&clientX);
mouseEvent->GetClientY(&clientY);
+ PRInt32 newX = GetNewResizingX(clientX, clientY);
+ PRInt32 newY = GetNewResizingY(clientX, clientY);
PRInt32 newWidth = GetNewResizingWidth(clientX, clientY);
PRInt32 newHeight = GetNewResizingHeight(clientX, clientY);
mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
leftStr,
- GetNewResizingX(clientX, clientY));
+ newX);
mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
topStr,
- GetNewResizingY(clientX, clientY));
+ newY);
mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
NS_LITERAL_STRING("width"),
newWidth);
@@ -856,7 +891,7 @@ nsHTMLEditor::MouseMove(nsIDOMEvent* aMouseEvent)
NS_LITERAL_STRING("height"),
newHeight);
- return SetResizingInfoPosition(clientX, clientY, newWidth, newHeight);
+ return SetResizingInfoPosition(newX, newY, newWidth, newHeight);
}
if (mGrabberClicked) {
diff --git a/mozilla/layout/base/nsCSSFrameConstructor.h b/mozilla/layout/base/nsCSSFrameConstructor.h
index f26fed5c9db..671537e1c16 100644
--- a/mozilla/layout/base/nsCSSFrameConstructor.h
+++ b/mozilla/layout/base/nsCSSFrameConstructor.h
@@ -723,14 +723,16 @@ private:
nsIFrame* GetFrameFor(nsIContent* aContent);
/**
- * These functions are used when we start frame creation from a non-root
+ * These two functions are used when we start frame creation from a non-root
* element. They should recreate the same state that we would have
* arrived at if we had built frames from the root frame to aFrame.
* Therefore, any calls to PushFloatContainingBlock and
* PushAbsoluteContainingBlock during frame construction should get
* corresponding logic in these functions.
*/
+public:
nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);
+private:
nsIFrame* GetFloatContainingBlock(nsIFrame* aFrame);
nsIContent* PropagateScrollToViewport();
diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h
index 1771672e508..812292ce97c 100644
--- a/mozilla/layout/base/nsIPresShell.h
+++ b/mozilla/layout/base/nsIPresShell.h
@@ -645,6 +645,8 @@ public:
*/
static PRInt32 GetVerifyReflowFlags();
+ virtual nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);
+
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD DumpReflows() = 0;
NS_IMETHOD CountReflows(const char * aName, nsIFrame * aFrame) = 0;
diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp
index 1cccac8ce94..4b65baabccc 100644
--- a/mozilla/layout/base/nsPresShell.cpp
+++ b/mozilla/layout/base/nsPresShell.cpp
@@ -7662,3 +7662,8 @@ void ColorToString(nscolor aColor, nsAutoString &aString)
NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor));
CopyASCIItoUTF16(buf, aString);
}
+
+nsIFrame* nsIPresShell::GetAbsoluteContainingBlock(nsIFrame *aFrame)
+{
+ return FrameConstructor()->GetAbsoluteContainingBlock(aFrame);
+}