editor/libeditor/html/nsHTMLAbsPosition.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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/. */
     5 #include <math.h>
     7 #include "mozilla/Preferences.h"
     8 #include "mozilla/dom/Selection.h"
     9 #include "mozilla/dom/Element.h"
    10 #include "mozilla/mozalloc.h"
    11 #include "nsAString.h"
    12 #include "nsAlgorithm.h"
    13 #include "nsAutoPtr.h"
    14 #include "nsCOMPtr.h"
    15 #include "nsComputedDOMStyle.h"
    16 #include "nsDebug.h"
    17 #include "nsEditProperty.h"
    18 #include "nsEditRules.h"
    19 #include "nsEditor.h"
    20 #include "nsEditorUtils.h"
    21 #include "nsError.h"
    22 #include "nsGkAtoms.h"
    23 #include "nsHTMLCSSUtils.h"
    24 #include "nsHTMLEditRules.h"
    25 #include "nsHTMLEditUtils.h"
    26 #include "nsHTMLEditor.h"
    27 #include "nsHTMLObjectResizer.h"
    28 #include "nsIContent.h"
    29 #include "nsROCSSPrimitiveValue.h"
    30 #include "nsIDOMCSSStyleDeclaration.h"
    31 #include "nsIDOMElement.h"
    32 #include "nsIDOMEventListener.h"
    33 #include "nsIDOMEventTarget.h"
    34 #include "nsIDOMNode.h"
    35 #include "nsDOMCSSRGBColor.h"
    36 #include "nsIDOMWindow.h"
    37 #include "nsIEditor.h"
    38 #include "nsIHTMLEditor.h"
    39 #include "nsIHTMLObjectResizer.h"
    40 #include "nsINode.h"
    41 #include "nsIPresShell.h"
    42 #include "nsISelection.h"
    43 #include "nsISupportsImpl.h"
    44 #include "nsISupportsUtils.h"
    45 #include "nsLiteralString.h"
    46 #include "nsReadableUtils.h"
    47 #include "nsString.h"
    48 #include "nsStringFwd.h"
    49 #include "nsTextEditRules.h"
    50 #include "nsTextEditUtils.h"
    51 #include "nscore.h"
    52 #include <algorithm>
    54 using namespace mozilla;
    55 using namespace mozilla::dom;
    57 #define  BLACK_BG_RGB_TRIGGER 0xd0
    59 NS_IMETHODIMP
    60 nsHTMLEditor::AbsolutePositionSelection(bool aEnabled)
    61 {
    62   nsAutoEditBatch beginBatching(this);
    63   nsAutoRules beginRulesSniffing(this,
    64                                  aEnabled ? EditAction::setAbsolutePosition :
    65                                             EditAction::removeAbsolutePosition,
    66                                  nsIEditor::eNext);
    68   // the line below does not match the code; should it be removed?
    69   // Find out if the selection is collapsed:
    70   nsRefPtr<Selection> selection = GetSelection();
    71   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
    73   nsTextRulesInfo ruleInfo(aEnabled ? EditAction::setAbsolutePosition :
    74                                       EditAction::removeAbsolutePosition);
    75   bool cancel, handled;
    76   // Protect the edit rules object from dying
    77   nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
    78   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
    79   if (NS_FAILED(res) || cancel)
    80     return res;
    82   return mRules->DidDoAction(selection, &ruleInfo, res);
    83 }
    85 NS_IMETHODIMP
    86 nsHTMLEditor::GetAbsolutelyPositionedSelectionContainer(nsIDOMElement **_retval)
    87 {
    88   nsCOMPtr<nsIDOMElement> element;
    89   nsresult res = GetSelectionContainer(getter_AddRefs(element));
    90   NS_ENSURE_SUCCESS(res, res);
    92   nsAutoString positionStr;
    93   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(element);
    94   nsCOMPtr<nsIDOMNode> resultNode;
    96   while (!resultNode && node && !nsEditor::NodeIsType(node, nsEditProperty::html)) {
    97     res = mHTMLCSSUtils->GetComputedProperty(node, nsEditProperty::cssPosition,
    98                                              positionStr);
    99     NS_ENSURE_SUCCESS(res, res);
   100     if (positionStr.EqualsLiteral("absolute"))
   101       resultNode = node;
   102     else {
   103       nsCOMPtr<nsIDOMNode> parentNode;
   104       res = node->GetParentNode(getter_AddRefs(parentNode));
   105       NS_ENSURE_SUCCESS(res, res);
   106       node.swap(parentNode);
   107     }
   108   }
   110   element = do_QueryInterface(resultNode ); 
   111   *_retval = element;
   112   NS_IF_ADDREF(*_retval);
   113   return NS_OK;
   114 }
   116 NS_IMETHODIMP
   117 nsHTMLEditor::GetSelectionContainerAbsolutelyPositioned(bool *aIsSelectionContainerAbsolutelyPositioned)
   118 {
   119   *aIsSelectionContainerAbsolutelyPositioned = (mAbsolutelyPositionedObject != nullptr);
   120   return NS_OK;
   121 }
   123 NS_IMETHODIMP
   124 nsHTMLEditor::GetAbsolutePositioningEnabled(bool * aIsEnabled)
   125 {
   126   *aIsEnabled = mIsAbsolutelyPositioningEnabled;
   127   return NS_OK;
   128 }
   130 NS_IMETHODIMP
   131 nsHTMLEditor::SetAbsolutePositioningEnabled(bool aIsEnabled)
   132 {
   133   mIsAbsolutelyPositioningEnabled = aIsEnabled;
   134   return NS_OK;
   135 }
   137 NS_IMETHODIMP
   138 nsHTMLEditor::RelativeChangeElementZIndex(nsIDOMElement * aElement,
   139                                           int32_t aChange,
   140                                           int32_t * aReturn)
   141 {
   142   NS_ENSURE_ARG_POINTER(aElement);
   143   NS_ENSURE_ARG_POINTER(aReturn);
   144   if (!aChange) // early way out, no change
   145     return NS_OK;
   147   int32_t zIndex;
   148   nsresult res = GetElementZIndex(aElement, &zIndex);
   149   NS_ENSURE_SUCCESS(res, res);
   151   zIndex = std::max(zIndex + aChange, 0);
   152   SetElementZIndex(aElement, zIndex);
   153   *aReturn = zIndex;
   155   return NS_OK;
   156 }
   158 NS_IMETHODIMP
   159 nsHTMLEditor::SetElementZIndex(nsIDOMElement * aElement,
   160                                int32_t aZindex)
   161 {
   162   NS_ENSURE_ARG_POINTER(aElement);
   164   nsAutoString zIndexStr;
   165   zIndexStr.AppendInt(aZindex);
   167   mHTMLCSSUtils->SetCSSProperty(aElement,
   168                                 nsEditProperty::cssZIndex,
   169                                 zIndexStr,
   170                                 false);
   171   return NS_OK;
   172 }
   174 NS_IMETHODIMP
   175 nsHTMLEditor::RelativeChangeZIndex(int32_t aChange)
   176 {
   177   nsAutoEditBatch beginBatching(this);
   178   nsAutoRules beginRulesSniffing(this,
   179                                  (aChange < 0) ? EditAction::decreaseZIndex :
   180                                                  EditAction::increaseZIndex,
   181                                  nsIEditor::eNext);
   183   // brade: can we get rid of this comment?
   184   // Find out if the selection is collapsed:
   185   nsRefPtr<Selection> selection = GetSelection();
   186   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
   187   nsTextRulesInfo ruleInfo(aChange < 0 ? EditAction::decreaseZIndex :
   188                                          EditAction::increaseZIndex);
   189   bool cancel, handled;
   190   // Protect the edit rules object from dying
   191   nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
   192   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   193   if (cancel || NS_FAILED(res))
   194     return res;
   196   return mRules->DidDoAction(selection, &ruleInfo, res);
   197 }
   199 NS_IMETHODIMP
   200 nsHTMLEditor::GetElementZIndex(nsIDOMElement * aElement,
   201                                int32_t * aZindex)
   202 {
   203   nsAutoString zIndexStr;
   204   *aZindex = 0;
   206   nsresult res = mHTMLCSSUtils->GetSpecifiedProperty(aElement,
   207                                                      nsEditProperty::cssZIndex,
   208                                                      zIndexStr);
   209   NS_ENSURE_SUCCESS(res, res);
   210   if (zIndexStr.EqualsLiteral("auto")) {
   211     // we have to look at the positioned ancestors
   212     // cf. CSS 2 spec section 9.9.1
   213     nsCOMPtr<nsIDOMNode> parentNode;
   214     res = aElement->GetParentNode(getter_AddRefs(parentNode));
   215     NS_ENSURE_SUCCESS(res, res);
   216     nsCOMPtr<nsIDOMNode> node = parentNode;
   217     nsAutoString positionStr;
   218     while (node && 
   219            zIndexStr.EqualsLiteral("auto") &&
   220            !nsTextEditUtils::IsBody(node)) {
   221       res = mHTMLCSSUtils->GetComputedProperty(node,
   222                                                nsEditProperty::cssPosition,
   223                                                positionStr);
   224       NS_ENSURE_SUCCESS(res, res);
   225       if (positionStr.EqualsLiteral("absolute")) {
   226         // ah, we found one, what's its z-index ? If its z-index is auto,
   227         // we have to continue climbing the document's tree
   228         res = mHTMLCSSUtils->GetComputedProperty(node,
   229                                                  nsEditProperty::cssZIndex,
   230                                                  zIndexStr);
   231         NS_ENSURE_SUCCESS(res, res);
   232       }
   233       res = node->GetParentNode(getter_AddRefs(parentNode));
   234       NS_ENSURE_SUCCESS(res, res);
   235       node = parentNode;
   236     }
   237   }
   239   if (!zIndexStr.EqualsLiteral("auto")) {
   240     nsresult errorCode;
   241     *aZindex = zIndexStr.ToInteger(&errorCode);
   242   }
   244   return NS_OK;
   245 }
   247 nsresult
   248 nsHTMLEditor::CreateGrabber(nsIDOMNode * aParentNode, nsIDOMElement ** aReturn)
   249 {
   250   // let's create a grabber through the element factory
   251   nsresult res = CreateAnonymousElement(NS_LITERAL_STRING("span"),
   252                                         aParentNode,
   253                                         NS_LITERAL_STRING("mozGrabber"),
   254                                         false,
   255                                         aReturn);
   257   NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE);
   259   // add the mouse listener so we can detect a click on a resizer
   260   nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(*aReturn));
   261   evtTarget->AddEventListener(NS_LITERAL_STRING("mousedown"),
   262                               mEventListener, false);
   264   return res;
   265 }
   267 NS_IMETHODIMP
   268 nsHTMLEditor::RefreshGrabber()
   269 {
   270   NS_ENSURE_TRUE(mAbsolutelyPositionedObject, NS_ERROR_NULL_POINTER);
   272   nsresult res = GetPositionAndDimensions(mAbsolutelyPositionedObject,
   273                                          mPositionedObjectX,
   274                                          mPositionedObjectY,
   275                                          mPositionedObjectWidth,
   276                                          mPositionedObjectHeight,
   277                                          mPositionedObjectBorderLeft,
   278                                          mPositionedObjectBorderTop,
   279                                          mPositionedObjectMarginLeft,
   280                                          mPositionedObjectMarginTop);
   282   NS_ENSURE_SUCCESS(res, res);
   284   SetAnonymousElementPosition(mPositionedObjectX+12,
   285                               mPositionedObjectY-14,
   286                               mGrabber);
   287   return NS_OK;
   288 }
   290 NS_IMETHODIMP
   291 nsHTMLEditor::HideGrabber()
   292 {
   293   nsresult res =
   294     mAbsolutelyPositionedObject->RemoveAttribute(NS_LITERAL_STRING("_moz_abspos"));
   295   NS_ENSURE_SUCCESS(res, res);
   297   mAbsolutelyPositionedObject = nullptr;
   298   NS_ENSURE_TRUE(mGrabber, NS_ERROR_NULL_POINTER);
   300   // get the presshell's document observer interface.
   301   nsCOMPtr<nsIPresShell> ps = GetPresShell();
   302   // We allow the pres shell to be null; when it is, we presume there
   303   // are no document observers to notify, but we still want to
   304   // UnbindFromTree.
   306   nsCOMPtr<nsIDOMNode> parentNode;
   307   res = mGrabber->GetParentNode(getter_AddRefs(parentNode));
   308   NS_ENSURE_SUCCESS(res, res);
   310   nsCOMPtr<nsIContent> parentContent = do_QueryInterface(parentNode);
   311   NS_ENSURE_TRUE(parentContent, NS_ERROR_NULL_POINTER);
   313   DeleteRefToAnonymousNode(mGrabber, parentContent, ps);
   314   mGrabber = nullptr;
   315   DeleteRefToAnonymousNode(mPositioningShadow, parentContent, ps);
   316   mPositioningShadow = nullptr;
   318   return NS_OK;
   319 }
   321 NS_IMETHODIMP
   322 nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
   323 {
   324   NS_ENSURE_ARG_POINTER(aElement);
   326   if (mGrabber) {
   327     NS_ERROR("call HideGrabber first");
   328     return NS_ERROR_UNEXPECTED;
   329   }
   331   nsAutoString classValue;
   332   nsresult res = CheckPositionedElementBGandFG(aElement, classValue);
   333   NS_ENSURE_SUCCESS(res, res);
   335   res = aElement->SetAttribute(NS_LITERAL_STRING("_moz_abspos"),
   336                                classValue);
   337   NS_ENSURE_SUCCESS(res, res);
   339   // first, let's keep track of that element...
   340   mAbsolutelyPositionedObject = aElement;
   342   nsCOMPtr<nsIDOMNode> parentNode;
   343   res = aElement->GetParentNode(getter_AddRefs(parentNode));
   344   NS_ENSURE_SUCCESS(res, res);
   346   res = CreateGrabber(parentNode, getter_AddRefs(mGrabber));
   347   NS_ENSURE_SUCCESS(res, res);
   349   // and set its position
   350   return RefreshGrabber();
   351 }
   353 nsresult
   354 nsHTMLEditor::StartMoving(nsIDOMElement *aHandle)
   355 {
   356   nsCOMPtr<nsIDOMNode> parentNode;
   357   nsresult res = mGrabber->GetParentNode(getter_AddRefs(parentNode));
   358   NS_ENSURE_SUCCESS(res, res);
   360   // now, let's create the resizing shadow
   361   res = CreateShadow(getter_AddRefs(mPositioningShadow),
   362                                  parentNode, mAbsolutelyPositionedObject);
   363   NS_ENSURE_SUCCESS(res,res);
   364   res = SetShadowPosition(mPositioningShadow, mAbsolutelyPositionedObject,
   365                              mPositionedObjectX, mPositionedObjectY);
   366   NS_ENSURE_SUCCESS(res,res);
   368   // make the shadow appear
   369   mPositioningShadow->RemoveAttribute(NS_LITERAL_STRING("class"));
   371   // position it
   372   mHTMLCSSUtils->SetCSSPropertyPixels(mPositioningShadow,
   373                                       NS_LITERAL_STRING("width"),
   374                                       mPositionedObjectWidth);
   375   mHTMLCSSUtils->SetCSSPropertyPixels(mPositioningShadow,
   376                                       NS_LITERAL_STRING("height"),
   377                                       mPositionedObjectHeight);
   379   mIsMoving = true;
   380   return res;
   381 }
   383 void
   384 nsHTMLEditor::SnapToGrid(int32_t & newX, int32_t & newY)
   385 {
   386   if (mSnapToGridEnabled && mGridSize) {
   387     newX = (int32_t) floor( ((float)newX / (float)mGridSize) + 0.5f ) * mGridSize;
   388     newY = (int32_t) floor( ((float)newY / (float)mGridSize) + 0.5f ) * mGridSize;
   389   }
   390 }
   392 nsresult
   393 nsHTMLEditor::GrabberClicked()
   394 {
   395   // add a mouse move listener to the editor
   396   nsresult res = NS_OK;
   397   if (!mMouseMotionListenerP) {
   398     mMouseMotionListenerP = new ResizerMouseMotionListener(this);
   399     if (!mMouseMotionListenerP) {return NS_ERROR_NULL_POINTER;}
   401     nsCOMPtr<nsIDOMEventTarget> piTarget = GetDOMEventTarget();
   402     NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE);
   404     res = piTarget->AddEventListener(NS_LITERAL_STRING("mousemove"),
   405                                      mMouseMotionListenerP,
   406                                      false, false);
   407     NS_ASSERTION(NS_SUCCEEDED(res),
   408                  "failed to register mouse motion listener");
   409   }
   410   mGrabberClicked = true;
   411   return res;
   412 }
   414 nsresult
   415 nsHTMLEditor::EndMoving()
   416 {
   417   if (mPositioningShadow) {
   418     nsCOMPtr<nsIPresShell> ps = GetPresShell();
   419     NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
   421     nsCOMPtr<nsIDOMNode> parentNode;
   422     nsresult res = mGrabber->GetParentNode(getter_AddRefs(parentNode));
   423     NS_ENSURE_SUCCESS(res, res);
   425     nsCOMPtr<nsIContent> parentContent( do_QueryInterface(parentNode) );
   426     NS_ENSURE_TRUE(parentContent, NS_ERROR_FAILURE);
   428     DeleteRefToAnonymousNode(mPositioningShadow, parentContent, ps);
   430     mPositioningShadow = nullptr;
   431   }
   432   nsCOMPtr<nsIDOMEventTarget> piTarget = GetDOMEventTarget();
   434   if (piTarget && mMouseMotionListenerP) {
   435 #ifdef DEBUG
   436     nsresult res =
   437 #endif
   438     piTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
   439                                   mMouseMotionListenerP,
   440                                   false);
   441     NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener");
   442   }
   443   mMouseMotionListenerP = nullptr;
   445   mGrabberClicked = false;
   446   mIsMoving = false;
   447   nsCOMPtr<nsISelection> selection;
   448   GetSelection(getter_AddRefs(selection));
   449   if (!selection) {
   450     return NS_ERROR_NOT_INITIALIZED;
   451   }
   452   return CheckSelectionStateForAnonymousButtons(selection);
   453 }
   454 nsresult
   455 nsHTMLEditor::SetFinalPosition(int32_t aX, int32_t aY)
   456 {
   457   nsresult res = EndMoving();
   458   NS_ENSURE_SUCCESS(res, res);
   460   // we have now to set the new width and height of the resized object
   461   // we don't set the x and y position because we don't control that in
   462   // a normal HTML layout
   463   int32_t newX = mPositionedObjectX + aX - mOriginalX - (mPositionedObjectBorderLeft+mPositionedObjectMarginLeft);
   464   int32_t newY = mPositionedObjectY + aY - mOriginalY - (mPositionedObjectBorderTop+mPositionedObjectMarginTop);
   466   SnapToGrid(newX, newY);
   468   nsAutoString x, y;
   469   x.AppendInt(newX);
   470   y.AppendInt(newY);
   472   // we want one transaction only from a user's point of view
   473   nsAutoEditBatch batchIt(this);
   475   mHTMLCSSUtils->SetCSSPropertyPixels(mAbsolutelyPositionedObject,
   476                                       nsEditProperty::cssTop,
   477                                       newY,
   478                                       false);
   479   mHTMLCSSUtils->SetCSSPropertyPixels(mAbsolutelyPositionedObject,
   480                                       nsEditProperty::cssLeft,
   481                                       newX,
   482                                       false);
   483   // keep track of that size
   484   mPositionedObjectX  = newX;
   485   mPositionedObjectY  = newY;
   487   return RefreshResizers();
   488 }
   490 void
   491 nsHTMLEditor::AddPositioningOffset(int32_t & aX, int32_t & aY)
   492 {
   493   // Get the positioning offset
   494   int32_t positioningOffset =
   495     Preferences::GetInt("editor.positioning.offset", 0);
   497   aX += positioningOffset;
   498   aY += positioningOffset;
   499 }
   501 NS_IMETHODIMP
   502 nsHTMLEditor::AbsolutelyPositionElement(nsIDOMElement * aElement,
   503                                         bool aEnabled)
   504 {
   505   NS_ENSURE_ARG_POINTER(aElement);
   507   nsAutoString positionStr;
   508   mHTMLCSSUtils->GetComputedProperty(aElement, nsEditProperty::cssPosition,
   509                                      positionStr);
   510   bool isPositioned = (positionStr.EqualsLiteral("absolute"));
   512   // nothing to do if the element is already in the state we want
   513   if (isPositioned == aEnabled)
   514     return NS_OK;
   516   nsAutoEditBatch batchIt(this);
   518   if (aEnabled) {
   519     int32_t x, y;
   520     GetElementOrigin(aElement, x, y);
   522     mHTMLCSSUtils->SetCSSProperty(aElement,
   523                                   nsEditProperty::cssPosition,
   524                                   NS_LITERAL_STRING("absolute"),
   525                                   false);
   527     AddPositioningOffset(x, y);
   528     SnapToGrid(x, y);
   529     SetElementPosition(aElement, x, y);
   531     // we may need to create a br if the positioned element is alone in its
   532     // container
   533     nsCOMPtr<nsINode> element = do_QueryInterface(aElement);
   534     NS_ENSURE_STATE(element);
   536     nsINode* parentNode = element->GetParentNode();
   537     if (parentNode->GetChildCount() == 1) {
   538       nsCOMPtr<nsIDOMNode> brNode;
   539       nsresult res = CreateBR(parentNode->AsDOMNode(), 0, address_of(brNode));
   540       NS_ENSURE_SUCCESS(res, res);
   541     }
   542   }
   543   else {
   544     mHTMLCSSUtils->RemoveCSSProperty(aElement,
   545                                      nsEditProperty::cssPosition,
   546                                      EmptyString(), false);
   547     mHTMLCSSUtils->RemoveCSSProperty(aElement,
   548                                      nsEditProperty::cssTop,
   549                                      EmptyString(), false);
   550     mHTMLCSSUtils->RemoveCSSProperty(aElement,
   551                                      nsEditProperty::cssLeft,
   552                                      EmptyString(), false);
   553     mHTMLCSSUtils->RemoveCSSProperty(aElement,
   554                                      nsEditProperty::cssZIndex,
   555                                      EmptyString(), false);
   557     if (!nsHTMLEditUtils::IsImage(aElement)) {
   558       mHTMLCSSUtils->RemoveCSSProperty(aElement,
   559                                        nsEditProperty::cssWidth,
   560                                        EmptyString(), false);
   561       mHTMLCSSUtils->RemoveCSSProperty(aElement,
   562                                        nsEditProperty::cssHeight,
   563                                        EmptyString(), false);
   564     }
   566     nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
   567     if (element && element->IsHTML(nsGkAtoms::div) && !HasStyleOrIdOrClass(element)) {
   568       nsRefPtr<nsHTMLEditRules> htmlRules = static_cast<nsHTMLEditRules*>(mRules.get());
   569       NS_ENSURE_TRUE(htmlRules, NS_ERROR_FAILURE);
   570       nsresult res = htmlRules->MakeSureElemStartsOrEndsOnCR(aElement);
   571       NS_ENSURE_SUCCESS(res, res);
   572       res = RemoveContainer(aElement);
   573       NS_ENSURE_SUCCESS(res, res);
   574     }
   575   }
   576   return NS_OK;
   577 }
   579 NS_IMETHODIMP
   580 nsHTMLEditor::SetSnapToGridEnabled(bool aEnabled)
   581 {
   582   mSnapToGridEnabled = aEnabled;
   583   return NS_OK;
   584 }
   586 NS_IMETHODIMP
   587 nsHTMLEditor::GetSnapToGridEnabled(bool * aIsEnabled)
   588 {
   589   *aIsEnabled = mSnapToGridEnabled;
   590   return NS_OK;
   591 }
   593 NS_IMETHODIMP
   594 nsHTMLEditor::SetGridSize(uint32_t aSize)
   595 {
   596   mGridSize = aSize;
   597   return NS_OK;
   598 }
   600 NS_IMETHODIMP
   601 nsHTMLEditor::GetGridSize(uint32_t * aSize)
   602 {
   603   *aSize = mGridSize;
   604   return NS_OK;
   605 }
   607 // self-explanatory
   608 NS_IMETHODIMP
   609 nsHTMLEditor::SetElementPosition(nsIDOMElement *aElement, int32_t aX, int32_t aY)
   610 {
   611   nsAutoEditBatch batchIt(this);
   613   mHTMLCSSUtils->SetCSSPropertyPixels(aElement,
   614                                       nsEditProperty::cssLeft,
   615                                       aX,
   616                                       false);
   617   mHTMLCSSUtils->SetCSSPropertyPixels(aElement,
   618                                       nsEditProperty::cssTop,
   619                                       aY,
   620                                       false);
   621   return NS_OK;
   622 }
   624 // self-explanatory
   625 NS_IMETHODIMP
   626 nsHTMLEditor::GetPositionedElement(nsIDOMElement ** aReturn)
   627 {
   628   *aReturn = mAbsolutelyPositionedObject;
   629   NS_IF_ADDREF(*aReturn);
   630   return NS_OK;
   631 }
   633 nsresult
   634 nsHTMLEditor::CheckPositionedElementBGandFG(nsIDOMElement * aElement,
   635                                             nsAString & aReturn)
   636 {
   637   // we are going to outline the positioned element and bring it to the
   638   // front to overlap any other element intersecting with it. But
   639   // first, let's see what's the background and foreground colors of the
   640   // positioned element.
   641   // if background-image computed value is 'none,
   642   //   If the background color is 'auto' and R G B values of the foreground are
   643   //       each above #d0, use a black background
   644   //   If the background color is 'auto' and at least one of R G B values of
   645   //       the foreground is below #d0, use a white background
   646   // Otherwise don't change background/foreground
   648   aReturn.Truncate();
   650   nsAutoString bgImageStr;
   651   nsresult res =
   652     mHTMLCSSUtils->GetComputedProperty(aElement,
   653                                        nsEditProperty::cssBackgroundImage,
   654                                        bgImageStr);
   655   NS_ENSURE_SUCCESS(res, res);
   656   if (bgImageStr.EqualsLiteral("none")) {
   657     nsAutoString bgColorStr;
   658     res =
   659       mHTMLCSSUtils->GetComputedProperty(aElement,
   660                                          nsEditProperty::cssBackgroundColor,
   661                                          bgColorStr);
   662     NS_ENSURE_SUCCESS(res, res);
   663     if (bgColorStr.EqualsLiteral("transparent")) {
   664       nsRefPtr<nsComputedDOMStyle> cssDecl =
   665         mHTMLCSSUtils->GetComputedStyle(aElement);
   666       NS_ENSURE_STATE(cssDecl);
   668       // from these declarations, get the one we want and that one only
   669       ErrorResult error;
   670       nsRefPtr<dom::CSSValue> cssVal = cssDecl->GetPropertyCSSValue(NS_LITERAL_STRING("color"), error);
   671       NS_ENSURE_SUCCESS(error.ErrorCode(), error.ErrorCode());
   673       nsROCSSPrimitiveValue* val = cssVal->AsPrimitiveValue();
   674       NS_ENSURE_TRUE(val, NS_ERROR_FAILURE);
   676       if (nsIDOMCSSPrimitiveValue::CSS_RGBCOLOR == val->PrimitiveType()) {
   677         nsDOMCSSRGBColor* rgbVal = val->GetRGBColorValue(error);
   678         NS_ENSURE_SUCCESS(error.ErrorCode(), error.ErrorCode());
   679         float r = rgbVal->Red()->
   680           GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, error);
   681         NS_ENSURE_SUCCESS(error.ErrorCode(), error.ErrorCode());
   682         float g = rgbVal->Green()->
   683           GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, error);
   684         NS_ENSURE_SUCCESS(error.ErrorCode(), error.ErrorCode());
   685         float b = rgbVal->Blue()->
   686           GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, error);
   687         NS_ENSURE_SUCCESS(error.ErrorCode(), error.ErrorCode());
   688         if (r >= BLACK_BG_RGB_TRIGGER &&
   689             g >= BLACK_BG_RGB_TRIGGER &&
   690             b >= BLACK_BG_RGB_TRIGGER)
   691           aReturn.AssignLiteral("black");
   692         else
   693           aReturn.AssignLiteral("white");
   694         return NS_OK;
   695       }
   696     }
   697   }
   699   return NS_OK;
   700 }

mercurial