LCOV - code coverage report
Current view: top level - editor/libeditor - HTMLAnonymousNodeEditor.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 251 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "mozilla/HTMLEditor.h"
       6             : 
       7             : #include "mozilla/Attributes.h"
       8             : #include "mozilla/dom/Element.h"
       9             : #include "mozilla/mozalloc.h"
      10             : #include "nsAString.h"
      11             : #include "nsCOMPtr.h"
      12             : #include "nsComputedDOMStyle.h"
      13             : #include "nsDebug.h"
      14             : #include "nsError.h"
      15             : #include "nsGkAtoms.h"
      16             : #include "nsIAtom.h"
      17             : #include "nsIContent.h"
      18             : #include "nsID.h"
      19             : #include "nsIDOMCSSPrimitiveValue.h"
      20             : #include "nsIDOMCSSStyleDeclaration.h"
      21             : #include "nsIDOMCSSValue.h"
      22             : #include "nsIDOMElement.h"
      23             : #include "nsIDOMEventTarget.h"
      24             : #include "nsIDOMHTMLElement.h"
      25             : #include "nsIDOMNode.h"
      26             : #include "nsIDOMWindow.h"
      27             : #include "nsIDocument.h"
      28             : #include "nsIDocumentObserver.h"
      29             : #include "nsIHTMLAbsPosEditor.h"
      30             : #include "nsIHTMLInlineTableEditor.h"
      31             : #include "nsIHTMLObjectResizer.h"
      32             : #include "nsStubMutationObserver.h"
      33             : #include "nsINode.h"
      34             : #include "nsIPresShell.h"
      35             : #include "nsISupportsImpl.h"
      36             : #include "nsISupportsUtils.h"
      37             : #include "nsLiteralString.h"
      38             : #include "nsPresContext.h"
      39             : #include "nsReadableUtils.h"
      40             : #include "nsString.h"
      41             : #include "nsStringFwd.h"
      42             : #include "nsUnicharUtils.h"
      43             : #include "nscore.h"
      44             : #include "nsContentUtils.h" // for nsAutoScriptBlocker
      45             : 
      46             : class nsIDOMEventListener;
      47             : class nsISelection;
      48             : 
      49             : namespace mozilla {
      50             : 
      51             : using namespace dom;
      52             : 
      53             : // retrieve an integer stored into a CSS computed float value
      54           0 : static int32_t GetCSSFloatValue(nsIDOMCSSStyleDeclaration * aDecl,
      55             :                                 const nsAString & aProperty)
      56             : {
      57           0 :   MOZ_ASSERT(aDecl);
      58             : 
      59           0 :   nsCOMPtr<nsIDOMCSSValue> value;
      60             :   // get the computed CSSValue of the property
      61           0 :   nsresult rv = aDecl->GetPropertyCSSValue(aProperty, getter_AddRefs(value));
      62           0 :   if (NS_FAILED(rv) || !value) {
      63           0 :     return 0;
      64             :   }
      65             : 
      66             :   // check the type of the returned CSSValue; we handle here only
      67             :   // pixel and enum types
      68           0 :   nsCOMPtr<nsIDOMCSSPrimitiveValue> val = do_QueryInterface(value);
      69             :   uint16_t type;
      70           0 :   val->GetPrimitiveType(&type);
      71             : 
      72           0 :   float f = 0;
      73           0 :   switch (type) {
      74             :     case nsIDOMCSSPrimitiveValue::CSS_PX:
      75             :       // the value is in pixels, just get it
      76           0 :       rv = val->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_PX, &f);
      77           0 :       NS_ENSURE_SUCCESS(rv, 0);
      78           0 :       break;
      79             :     case nsIDOMCSSPrimitiveValue::CSS_IDENT: {
      80             :       // the value is keyword, we have to map these keywords into
      81             :       // numeric values
      82           0 :       nsAutoString str;
      83           0 :       val->GetStringValue(str);
      84           0 :       if (str.EqualsLiteral("thin")) {
      85           0 :         f = 1;
      86           0 :       } else if (str.EqualsLiteral("medium")) {
      87           0 :         f = 3;
      88           0 :       } else if (str.EqualsLiteral("thick")) {
      89           0 :         f = 5;
      90             :       }
      91           0 :       break;
      92             :     }
      93             :   }
      94             : 
      95           0 :   return (int32_t) f;
      96             : }
      97             : 
      98             : class ElementDeletionObserver final : public nsStubMutationObserver
      99             : {
     100             : public:
     101           0 :   ElementDeletionObserver(nsIContent* aNativeAnonNode,
     102             :                           nsIContent* aObservedNode)
     103           0 :     : mNativeAnonNode(aNativeAnonNode)
     104           0 :     , mObservedNode(aObservedNode)
     105           0 :   {}
     106             : 
     107             :   NS_DECL_ISUPPORTS
     108             :   NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
     109             :   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
     110             : 
     111             : protected:
     112           0 :   ~ElementDeletionObserver() {}
     113             :   nsIContent* mNativeAnonNode;
     114             :   nsIContent* mObservedNode;
     115             : };
     116             : 
     117           0 : NS_IMPL_ISUPPORTS(ElementDeletionObserver, nsIMutationObserver)
     118             : 
     119             : void
     120           0 : ElementDeletionObserver::ParentChainChanged(nsIContent* aContent)
     121             : {
     122             :   // If the native anonymous content has been unbound already in
     123             :   // DeleteRefToAnonymousNode, mNativeAnonNode's parentNode is null.
     124           0 :   if (aContent == mObservedNode && mNativeAnonNode &&
     125           0 :       mNativeAnonNode->GetParentNode() == aContent) {
     126             :     // If the observed node has been moved to another document, there isn't much
     127             :     // we can do easily. But at least be safe and unbind the native anonymous
     128             :     // content and stop observing changes.
     129           0 :     if (mNativeAnonNode->OwnerDoc() != mObservedNode->OwnerDoc()) {
     130           0 :       mObservedNode->RemoveMutationObserver(this);
     131           0 :       mObservedNode = nullptr;
     132           0 :       mNativeAnonNode->RemoveMutationObserver(this);
     133           0 :       mNativeAnonNode->UnbindFromTree();
     134           0 :       mNativeAnonNode = nullptr;
     135           0 :       NS_RELEASE_THIS();
     136           0 :       return;
     137             :     }
     138             : 
     139             :     // We're staying in the same document, just rebind the native anonymous
     140             :     // node so that the subtree root points to the right object etc.
     141           0 :     mNativeAnonNode->UnbindFromTree();
     142           0 :     mNativeAnonNode->BindToTree(mObservedNode->GetUncomposedDoc(), mObservedNode,
     143           0 :                                 mObservedNode, true);
     144             :   }
     145             : }
     146             : 
     147             : void
     148           0 : ElementDeletionObserver::NodeWillBeDestroyed(const nsINode* aNode)
     149             : {
     150           0 :   NS_ASSERTION(aNode == mNativeAnonNode || aNode == mObservedNode,
     151             :                "Wrong aNode!");
     152           0 :   if (aNode == mNativeAnonNode) {
     153           0 :     mObservedNode->RemoveMutationObserver(this);
     154           0 :     mObservedNode = nullptr;
     155             :   } else {
     156           0 :     mNativeAnonNode->RemoveMutationObserver(this);
     157           0 :     mNativeAnonNode->UnbindFromTree();
     158           0 :     mNativeAnonNode = nullptr;
     159             :   }
     160             : 
     161           0 :   NS_RELEASE_THIS();
     162           0 : }
     163             : 
     164             : already_AddRefed<Element>
     165           0 : HTMLEditor::CreateAnonymousElement(nsIAtom* aTag,
     166             :                                    nsIDOMNode* aParentNode,
     167             :                                    const nsAString& aAnonClass,
     168             :                                    bool aIsCreatedHidden)
     169             : {
     170           0 :   if (NS_WARN_IF(!aParentNode)) {
     171           0 :     return nullptr;
     172             :   }
     173             : 
     174           0 :   nsCOMPtr<nsIContent> parentContent = do_QueryInterface(aParentNode);
     175           0 :   if (NS_WARN_IF(!parentContent)) {
     176           0 :     return nullptr;
     177             :   }
     178             : 
     179           0 :   nsCOMPtr<nsIDocument> doc = GetDocument();
     180           0 :   if (NS_WARN_IF(!doc)) {
     181           0 :     return nullptr;
     182             :   }
     183             : 
     184             :   // Get the pres shell
     185           0 :   nsCOMPtr<nsIPresShell> ps = GetPresShell();
     186           0 :   if (NS_WARN_IF(!ps)) {
     187           0 :     return nullptr;
     188             :   }
     189             : 
     190             :   // Create a new node through the element factory
     191           0 :   RefPtr<Element> newContent = CreateHTMLContent(aTag);
     192           0 :   if (NS_WARN_IF(!newContent)) {
     193           0 :     return nullptr;
     194             :   }
     195             : 
     196             :   // add the "hidden" class if needed
     197           0 :   if (aIsCreatedHidden) {
     198             :     nsresult rv =
     199           0 :       newContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
     200           0 :                           NS_LITERAL_STRING("hidden"), true);
     201           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     202           0 :       return nullptr;
     203             :     }
     204             :   }
     205             : 
     206             :   // add an _moz_anonclass attribute if needed
     207           0 :   if (!aAnonClass.IsEmpty()) {
     208             :     nsresult rv =
     209           0 :       newContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_moz_anonclass,
     210           0 :                           aAnonClass, true);
     211           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     212           0 :       return nullptr;
     213             :     }
     214             :   }
     215             : 
     216             :   {
     217           0 :     nsAutoScriptBlocker scriptBlocker;
     218             : 
     219             :     // establish parenthood of the element
     220           0 :     newContent->SetIsNativeAnonymousRoot();
     221             :     nsresult rv =
     222           0 :       newContent->BindToTree(doc, parentContent, parentContent, true);
     223           0 :     if (NS_FAILED(rv)) {
     224           0 :       newContent->UnbindFromTree();
     225           0 :       return nullptr;
     226             :     }
     227             :   }
     228             : 
     229             :   // Record the NAC on the element, so that AllChildrenIterator can find it.
     230             :   auto nac = static_cast<ManualNAC*>(
     231           0 :       parentContent->GetProperty(nsGkAtoms::manualNACProperty));
     232           0 :   if (!nac) {
     233           0 :     nac = new ManualNAC();
     234           0 :     parentContent->SetProperty(nsGkAtoms::manualNACProperty, nac,
     235           0 :                                nsINode::DeleteProperty<ManualNAC>);
     236             :   }
     237           0 :   nac->AppendElement(newContent);
     238             : 
     239             :   ElementDeletionObserver* observer =
     240           0 :     new ElementDeletionObserver(newContent, parentContent);
     241           0 :   NS_ADDREF(observer); // NodeWillBeDestroyed releases.
     242           0 :   parentContent->AddMutationObserver(observer);
     243           0 :   newContent->AddMutationObserver(observer);
     244             : 
     245             : #ifdef DEBUG
     246             :   // Editor anonymous content gets passed to PostRecreateFramesFor... which
     247             :   // can't _really_ deal with anonymous content (because it can't get the frame
     248             :   // tree ordering right).  But for us the ordering doesn't matter so this is
     249             :   // sort of ok.
     250           0 :   newContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
     251           0 :                           reinterpret_cast<void*>(true));
     252             : #endif // DEBUG
     253             : 
     254             :   // display the element
     255           0 :   ps->PostRecreateFramesFor(newContent);
     256             : 
     257           0 :   return newContent.forget();
     258             : }
     259             : 
     260             : // Removes event listener and calls DeleteRefToAnonymousNode.
     261             : void
     262           0 : HTMLEditor::RemoveListenerAndDeleteRef(const nsAString& aEvent,
     263             :                                        nsIDOMEventListener* aListener,
     264             :                                        bool aUseCapture,
     265             :                                        Element* aElement,
     266             :                                        nsIPresShell* aShell)
     267             : {
     268           0 :   nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
     269           0 :   if (evtTarget) {
     270           0 :     evtTarget->RemoveEventListener(aEvent, aListener, aUseCapture);
     271             :   }
     272           0 :   DeleteRefToAnonymousNode(aElement, aShell);
     273           0 : }
     274             : 
     275             : // Deletes all references to an anonymous element
     276             : void
     277           0 : HTMLEditor::DeleteRefToAnonymousNode(nsIContent* aContent,
     278             :                                      nsIPresShell* aShell)
     279             : {
     280             :   // call ContentRemoved() for the anonymous content
     281             :   // node so its references get removed from the frame manager's
     282             :   // undisplay map, and its layout frames get destroyed!
     283             : 
     284           0 :   if (NS_WARN_IF(!aContent)) {
     285           0 :     return;
     286             :   }
     287             : 
     288           0 :   nsIContent* parentContent = aContent->GetParent();
     289           0 :   if (NS_WARN_IF(!parentContent)) {
     290             :     // aContent was already removed?
     291           0 :     return;
     292             :   }
     293             : 
     294           0 :   nsAutoScriptBlocker scriptBlocker;
     295             :   // Need to check whether aShell has been destroyed (but not yet deleted).
     296             :   // In that case presContext->GetPresShell() returns nullptr.
     297             :   // See bug 338129.
     298           0 :   if (aContent->IsInComposedDoc() && aShell && aShell->GetPresContext() &&
     299           0 :       aShell->GetPresContext()->GetPresShell() == aShell) {
     300           0 :     nsCOMPtr<nsIDocumentObserver> docObserver = do_QueryInterface(aShell);
     301           0 :     if (docObserver) {
     302             :       // Call BeginUpdate() so that the nsCSSFrameConstructor/PresShell
     303             :       // knows we're messing with the frame tree.
     304           0 :       nsCOMPtr<nsIDocument> document = GetDocument();
     305           0 :       if (document) {
     306           0 :         docObserver->BeginUpdate(document, UPDATE_CONTENT_MODEL);
     307             :       }
     308             : 
     309             :       // XXX This is wrong (bug 439258).  Once it's fixed, the NS_WARNING
     310             :       // in RestyleManager::RestyleForRemove should be changed back
     311             :       // to an assertion.
     312           0 :       docObserver->ContentRemoved(aContent->GetComposedDoc(),
     313             :                                   parentContent, aContent, -1,
     314           0 :                                   aContent->GetPreviousSibling());
     315           0 :       if (document) {
     316           0 :         docObserver->EndUpdate(document, UPDATE_CONTENT_MODEL);
     317             :       }
     318             :     }
     319             :   }
     320             : 
     321             :   // Remove reference from the parent element.
     322             :   auto nac = static_cast<mozilla::ManualNAC*>(
     323           0 :       parentContent->GetProperty(nsGkAtoms::manualNACProperty));
     324           0 :   MOZ_ASSERT(nac);
     325           0 :   nac->RemoveElement(aContent);
     326           0 :   if (nac->IsEmpty()) {
     327           0 :     parentContent->DeleteProperty(nsGkAtoms::manualNACProperty);
     328             :   }
     329             : 
     330           0 :   aContent->UnbindFromTree();
     331             : }
     332             : 
     333             : // The following method is mostly called by a selection listener. When a
     334             : // selection change is notified, the method is called to check if resizing
     335             : // handles, a grabber and/or inline table editing UI need to be displayed
     336             : // or refreshed
     337             : NS_IMETHODIMP
     338           0 : HTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection* aSelection)
     339             : {
     340           0 :   NS_ENSURE_ARG_POINTER(aSelection);
     341             : 
     342             :   // early way out if all contextual UI extensions are disabled
     343           0 :   NS_ENSURE_TRUE(mIsObjectResizingEnabled ||
     344             :       mIsAbsolutelyPositioningEnabled ||
     345             :       mIsInlineTableEditingEnabled, NS_OK);
     346             : 
     347             :   // Don't change selection state if we're moving.
     348           0 :   if (mIsMoving) {
     349           0 :     return NS_OK;
     350             :   }
     351             : 
     352           0 :   nsCOMPtr<nsIDOMElement> focusElement;
     353             :   // let's get the containing element of the selection
     354           0 :   nsresult rv = GetSelectionContainer(getter_AddRefs(focusElement));
     355           0 :   NS_ENSURE_TRUE(focusElement, NS_OK);
     356           0 :   NS_ENSURE_SUCCESS(rv, rv);
     357             : 
     358             :   // If we're not in a document, don't try to add resizers
     359           0 :   nsCOMPtr<dom::Element> focusElementNode = do_QueryInterface(focusElement);
     360           0 :   NS_ENSURE_STATE(focusElementNode);
     361           0 :   if (!focusElementNode->IsInUncomposedDoc()) {
     362           0 :     return NS_OK;
     363             :   }
     364             : 
     365             :   // what's its tag?
     366           0 :   nsAutoString focusTagName;
     367           0 :   rv = focusElement->GetTagName(focusTagName);
     368           0 :   NS_ENSURE_SUCCESS(rv, rv);
     369           0 :   ToLowerCase(focusTagName);
     370           0 :   nsCOMPtr<nsIAtom> focusTagAtom = NS_Atomize(focusTagName);
     371             : 
     372           0 :   nsCOMPtr<nsIDOMElement> absPosElement;
     373           0 :   if (mIsAbsolutelyPositioningEnabled) {
     374             :     // Absolute Positioning support is enabled, is the selection contained
     375             :     // in an absolutely positioned element ?
     376             :     rv =
     377           0 :       GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(absPosElement));
     378           0 :     NS_ENSURE_SUCCESS(rv, rv);
     379             :   }
     380             : 
     381           0 :   nsCOMPtr<nsIDOMElement> cellElement;
     382           0 :   if (mIsObjectResizingEnabled || mIsInlineTableEditingEnabled) {
     383             :     // Resizing or Inline Table Editing is enabled, we need to check if the
     384             :     // selection is contained in a table cell
     385           0 :     rv = GetElementOrParentByTagName(NS_LITERAL_STRING("td"),
     386             :                                      nullptr,
     387           0 :                                      getter_AddRefs(cellElement));
     388           0 :     NS_ENSURE_SUCCESS(rv, rv);
     389             :   }
     390             : 
     391           0 :   if (mIsObjectResizingEnabled && cellElement) {
     392             :     // we are here because Resizing is enabled AND selection is contained in
     393             :     // a cell
     394             : 
     395             :     // get the enclosing table
     396           0 :     if (nsGkAtoms::img != focusTagAtom) {
     397             :       // the element container of the selection is not an image, so we'll show
     398             :       // the resizers around the table
     399           0 :       nsCOMPtr<nsIDOMNode> tableNode = GetEnclosingTable(cellElement);
     400           0 :       focusElement = do_QueryInterface(tableNode);
     401           0 :       focusTagAtom = nsGkAtoms::table;
     402             :     }
     403             :   }
     404             : 
     405             :   // we allow resizers only around images, tables, and absolutely positioned
     406             :   // elements. If we don't have image/table, let's look at the latter case.
     407           0 :   if (nsGkAtoms::img != focusTagAtom && nsGkAtoms::table != focusTagAtom) {
     408           0 :     focusElement = absPosElement;
     409             :   }
     410             : 
     411             :   // at this point, focusElement  contains the element for Resizing,
     412             :   //                cellElement   contains the element for InlineTableEditing
     413             :   //                absPosElement contains the element for Positioning
     414             : 
     415             :   // Note: All the Hide/Show methods below may change attributes on real
     416             :   // content which means a DOMAttrModified handler may cause arbitrary
     417             :   // side effects while this code runs (bug 420439).
     418             : 
     419           0 :   if (mIsAbsolutelyPositioningEnabled && mAbsolutelyPositionedObject &&
     420           0 :       absPosElement != GetAsDOMNode(mAbsolutelyPositionedObject)) {
     421           0 :     rv = HideGrabber();
     422           0 :     NS_ENSURE_SUCCESS(rv, rv);
     423           0 :     NS_ASSERTION(!mAbsolutelyPositionedObject, "HideGrabber failed");
     424             :   }
     425             : 
     426           0 :   if (mIsObjectResizingEnabled && mResizedObject &&
     427           0 :       GetAsDOMNode(mResizedObject) != focusElement) {
     428           0 :     rv = HideResizers();
     429           0 :     NS_ENSURE_SUCCESS(rv, rv);
     430           0 :     NS_ASSERTION(!mResizedObject, "HideResizers failed");
     431             :   }
     432             : 
     433           0 :   if (mIsInlineTableEditingEnabled && mInlineEditedCell &&
     434           0 :       mInlineEditedCell != cellElement) {
     435           0 :     rv = HideInlineTableEditingUI();
     436           0 :     NS_ENSURE_SUCCESS(rv, rv);
     437           0 :     NS_ASSERTION(!mInlineEditedCell, "HideInlineTableEditingUI failed");
     438             :   }
     439             : 
     440             :   // now, let's display all contextual UI for good
     441           0 :   nsIContent* hostContent = GetActiveEditingHost();
     442           0 :   nsCOMPtr<nsIDOMNode> hostNode = do_QueryInterface(hostContent);
     443             : 
     444           0 :   if (mIsObjectResizingEnabled && focusElement &&
     445           0 :       IsModifiableNode(focusElement) && focusElement != hostNode) {
     446           0 :     if (nsGkAtoms::img == focusTagAtom) {
     447           0 :       mResizedObjectIsAnImage = true;
     448             :     }
     449           0 :     if (mResizedObject) {
     450           0 :       nsresult rv = RefreshResizers();
     451           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     452           0 :         return rv;
     453             :       }
     454             :     } else {
     455           0 :       nsresult rv = ShowResizers(focusElement);
     456           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     457           0 :         return rv;
     458             :       }
     459             :     }
     460             :   }
     461             : 
     462           0 :   if (mIsAbsolutelyPositioningEnabled && absPosElement &&
     463           0 :       IsModifiableNode(absPosElement) && absPosElement != hostNode) {
     464           0 :     if (mAbsolutelyPositionedObject) {
     465           0 :       nsresult rv = RefreshGrabber();
     466           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     467           0 :         return rv;
     468             :       }
     469             :     } else {
     470           0 :       nsresult rv = ShowGrabberOnElement(absPosElement);
     471           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     472           0 :         return rv;
     473             :       }
     474             :     }
     475             :   }
     476             : 
     477           0 :   if (mIsInlineTableEditingEnabled && cellElement &&
     478           0 :       IsModifiableNode(cellElement) && cellElement != hostNode) {
     479           0 :     if (mInlineEditedCell) {
     480           0 :       nsresult rv = RefreshInlineTableEditingUI();
     481           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     482           0 :         return rv;
     483             :       }
     484             :     } else {
     485           0 :       nsresult rv = ShowInlineTableEditingUI(cellElement);
     486           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     487           0 :         return rv;
     488             :       }
     489             :     }
     490             :   }
     491             : 
     492           0 :   return NS_OK;
     493             : }
     494             : 
     495             : // Resizing and Absolute Positioning need to know everything about the
     496             : // containing box of the element: position, size, margins, borders
     497             : nsresult
     498           0 : HTMLEditor::GetPositionAndDimensions(nsIDOMElement* aElement,
     499             :                                      int32_t& aX,
     500             :                                      int32_t& aY,
     501             :                                      int32_t& aW,
     502             :                                      int32_t& aH,
     503             :                                      int32_t& aBorderLeft,
     504             :                                      int32_t& aBorderTop,
     505             :                                      int32_t& aMarginLeft,
     506             :                                      int32_t& aMarginTop)
     507             : {
     508           0 :   nsCOMPtr<Element> element = do_QueryInterface(aElement);
     509           0 :   NS_ENSURE_ARG_POINTER(element);
     510             : 
     511             :   // Is the element positioned ? let's check the cheap way first...
     512           0 :   bool isPositioned = false;
     513             :   nsresult rv =
     514           0 :     aElement->HasAttribute(NS_LITERAL_STRING("_moz_abspos"), &isPositioned);
     515           0 :   NS_ENSURE_SUCCESS(rv, rv);
     516           0 :   if (!isPositioned) {
     517             :     // hmmm... the expensive way now...
     518           0 :     nsAutoString positionStr;
     519           0 :     mCSSEditUtils->GetComputedProperty(*element, *nsGkAtoms::position,
     520           0 :                                        positionStr);
     521           0 :     isPositioned = positionStr.EqualsLiteral("absolute");
     522             :   }
     523             : 
     524           0 :   if (isPositioned) {
     525             :     // Yes, it is absolutely positioned
     526           0 :     mResizedObjectIsAbsolutelyPositioned = true;
     527             : 
     528             :     // Get the all the computed css styles attached to the element node
     529             :     RefPtr<nsComputedDOMStyle> cssDecl =
     530           0 :       mCSSEditUtils->GetComputedStyle(element);
     531           0 :     NS_ENSURE_STATE(cssDecl);
     532             : 
     533           0 :     aBorderLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-left-width"));
     534           0 :     aBorderTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-top-width"));
     535           0 :     aMarginLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-left"));
     536           0 :     aMarginTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-top"));
     537             : 
     538           0 :     aX = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("left")) +
     539           0 :          aMarginLeft + aBorderLeft;
     540           0 :     aY = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("top")) +
     541           0 :          aMarginTop + aBorderTop;
     542           0 :     aW = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("width"));
     543           0 :     aH = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("height"));
     544             :   } else {
     545           0 :     mResizedObjectIsAbsolutelyPositioned = false;
     546           0 :     nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(aElement);
     547           0 :     if (!htmlElement) {
     548           0 :       return NS_ERROR_NULL_POINTER;
     549             :     }
     550           0 :     GetElementOrigin(aElement, aX, aY);
     551             : 
     552           0 :     if (NS_WARN_IF(NS_FAILED(htmlElement->GetOffsetWidth(&aW))) ||
     553           0 :         NS_WARN_IF(NS_FAILED(htmlElement->GetOffsetHeight(&aH)))) {
     554           0 :       return rv;
     555             :     }
     556             : 
     557           0 :     aBorderLeft = 0;
     558           0 :     aBorderTop  = 0;
     559           0 :     aMarginLeft = 0;
     560           0 :     aMarginTop = 0;
     561             :   }
     562           0 :   return NS_OK;
     563             : }
     564             : 
     565             : // self-explanatory
     566             : void
     567           0 : HTMLEditor::SetAnonymousElementPosition(int32_t aX,
     568             :                                         int32_t aY,
     569             :                                         Element* aElement)
     570             : {
     571           0 :   mCSSEditUtils->SetCSSPropertyPixels(*aElement, *nsGkAtoms::left, aX);
     572           0 :   mCSSEditUtils->SetCSSPropertyPixels(*aElement, *nsGkAtoms::top, aY);
     573           0 : }
     574             : 
     575             : } // namespace mozilla

Generated by: LCOV version 1.13