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/. */
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"
15 #include "nsComputedDOMStyle.h"
17 #include "nsEditRules.h"
19 #include "nsEditorUtils.h"
21 #include "nsGkAtoms.h"
22 #include "nsHTMLCSSUtils.h"
23 #include "nsHTMLEditRules.h"
24 #include "nsHTMLEditUtils.h"
25 #include "nsHTMLEditor.h"
26 #include "nsHTMLObjectResizer.h"
27 #include "nsIContent.h"
28 #include "nsROCSSPrimitiveValue.h"
29 #include "nsIDOMCSSStyleDeclaration.h"
30 #include "nsIDOMElement.h"
31 #include "nsIDOMEventListener.h"
32 #include "nsIDOMEventTarget.h"
33 #include "nsIDOMNode.h"
34 #include "nsDOMCSSRGBColor.h"
35 #include "nsIDOMWindow.h"
36 #include "nsIEditor.h"
37 #include "nsIHTMLEditor.h"
38 #include "nsIHTMLObjectResizer.h"
40 #include "nsIPresShell.h"
41 #include "nsISelection.h"
42 #include "nsISupportsImpl.h"
43 #include "nsISupportsUtils.h"
44 #include "nsLiteralString.h"
45 #include "nsReadableUtils.h"
47 #include "nsStringFwd.h"
48 #include "nsTextEditRules.h"
49 #include "nsTextEditUtils.h"
53 using namespace mozilla
;
54 using namespace mozilla::dom
;
56 #define BLACK_BG_RGB_TRIGGER 0xd0
59 nsHTMLEditor::AbsolutePositionSelection(bool aEnabled
)
61 nsAutoEditBatch
beginBatching(this);
62 nsAutoRules
beginRulesSniffing(this,
63 aEnabled
? EditAction::setAbsolutePosition
:
64 EditAction::removeAbsolutePosition
,
67 // the line below does not match the code; should it be removed?
68 // Find out if the selection is collapsed:
69 nsRefPtr
<Selection
> selection
= GetSelection();
70 NS_ENSURE_TRUE(selection
, NS_ERROR_NULL_POINTER
);
72 nsTextRulesInfo
ruleInfo(aEnabled
? EditAction::setAbsolutePosition
:
73 EditAction::removeAbsolutePosition
);
75 // Protect the edit rules object from dying
76 nsCOMPtr
<nsIEditRules
> kungFuDeathGrip(mRules
);
77 nsresult res
= mRules
->WillDoAction(selection
, &ruleInfo
, &cancel
, &handled
);
78 if (NS_FAILED(res
) || cancel
)
81 return mRules
->DidDoAction(selection
, &ruleInfo
, res
);
85 nsHTMLEditor::GetAbsolutelyPositionedSelectionContainer(nsIDOMElement
**_retval
)
87 nsCOMPtr
<nsIDOMElement
> element
;
88 nsresult res
= GetSelectionContainer(getter_AddRefs(element
));
89 NS_ENSURE_SUCCESS(res
, res
);
91 nsAutoString positionStr
;
92 nsCOMPtr
<nsIDOMNode
> node
= do_QueryInterface(element
);
93 nsCOMPtr
<nsIDOMNode
> resultNode
;
95 while (!resultNode
&& node
&& !nsEditor::NodeIsType(node
, nsGkAtoms::html
)) {
96 res
= mHTMLCSSUtils
->GetComputedProperty(node
, nsGkAtoms::position
,
98 NS_ENSURE_SUCCESS(res
, res
);
99 if (positionStr
.EqualsLiteral("absolute"))
102 nsCOMPtr
<nsIDOMNode
> parentNode
;
103 res
= node
->GetParentNode(getter_AddRefs(parentNode
));
104 NS_ENSURE_SUCCESS(res
, res
);
105 node
.swap(parentNode
);
109 element
= do_QueryInterface(resultNode
);
111 NS_IF_ADDREF(*_retval
);
116 nsHTMLEditor::GetSelectionContainerAbsolutelyPositioned(bool *aIsSelectionContainerAbsolutelyPositioned
)
118 *aIsSelectionContainerAbsolutelyPositioned
= (mAbsolutelyPositionedObject
!= nullptr);
123 nsHTMLEditor::GetAbsolutePositioningEnabled(bool * aIsEnabled
)
125 *aIsEnabled
= mIsAbsolutelyPositioningEnabled
;
130 nsHTMLEditor::SetAbsolutePositioningEnabled(bool aIsEnabled
)
132 mIsAbsolutelyPositioningEnabled
= aIsEnabled
;
137 nsHTMLEditor::RelativeChangeElementZIndex(nsIDOMElement
* aElement
,
141 NS_ENSURE_ARG_POINTER(aElement
);
142 NS_ENSURE_ARG_POINTER(aReturn
);
143 if (!aChange
) // early way out, no change
147 nsresult res
= GetElementZIndex(aElement
, &zIndex
);
148 NS_ENSURE_SUCCESS(res
, res
);
150 zIndex
= std::max(zIndex
+ aChange
, 0);
151 SetElementZIndex(aElement
, zIndex
);
158 nsHTMLEditor::SetElementZIndex(nsIDOMElement
* aElement
, int32_t aZindex
)
160 nsCOMPtr
<Element
> element
= do_QueryInterface(aElement
);
161 NS_ENSURE_ARG_POINTER(element
);
163 nsAutoString zIndexStr
;
164 zIndexStr
.AppendInt(aZindex
);
166 mHTMLCSSUtils
->SetCSSProperty(*element
, *nsGkAtoms::z_index
, zIndexStr
);
171 nsHTMLEditor::RelativeChangeZIndex(int32_t aChange
)
173 nsAutoEditBatch
beginBatching(this);
174 nsAutoRules
beginRulesSniffing(this,
175 (aChange
< 0) ? EditAction::decreaseZIndex
:
176 EditAction::increaseZIndex
,
179 // brade: can we get rid of this comment?
180 // Find out if the selection is collapsed:
181 nsRefPtr
<Selection
> selection
= GetSelection();
182 NS_ENSURE_TRUE(selection
, NS_ERROR_NULL_POINTER
);
183 nsTextRulesInfo
ruleInfo(aChange
< 0 ? EditAction::decreaseZIndex
:
184 EditAction::increaseZIndex
);
185 bool cancel
, handled
;
186 // Protect the edit rules object from dying
187 nsCOMPtr
<nsIEditRules
> kungFuDeathGrip(mRules
);
188 nsresult res
= mRules
->WillDoAction(selection
, &ruleInfo
, &cancel
, &handled
);
189 if (cancel
|| NS_FAILED(res
))
192 return mRules
->DidDoAction(selection
, &ruleInfo
, res
);
196 nsHTMLEditor::GetElementZIndex(nsIDOMElement
* aElement
,
199 nsAutoString zIndexStr
;
202 nsresult res
= mHTMLCSSUtils
->GetSpecifiedProperty(aElement
,
205 NS_ENSURE_SUCCESS(res
, res
);
206 if (zIndexStr
.EqualsLiteral("auto")) {
207 // we have to look at the positioned ancestors
208 // cf. CSS 2 spec section 9.9.1
209 nsCOMPtr
<nsIDOMNode
> parentNode
;
210 res
= aElement
->GetParentNode(getter_AddRefs(parentNode
));
211 NS_ENSURE_SUCCESS(res
, res
);
212 nsCOMPtr
<nsIDOMNode
> node
= parentNode
;
213 nsAutoString positionStr
;
215 zIndexStr
.EqualsLiteral("auto") &&
216 !nsTextEditUtils::IsBody(node
)) {
217 res
= mHTMLCSSUtils
->GetComputedProperty(node
, nsGkAtoms::position
,
219 NS_ENSURE_SUCCESS(res
, res
);
220 if (positionStr
.EqualsLiteral("absolute")) {
221 // ah, we found one, what's its z-index ? If its z-index is auto,
222 // we have to continue climbing the document's tree
223 res
= mHTMLCSSUtils
->GetComputedProperty(node
, nsGkAtoms::z_index
,
225 NS_ENSURE_SUCCESS(res
, res
);
227 res
= node
->GetParentNode(getter_AddRefs(parentNode
));
228 NS_ENSURE_SUCCESS(res
, res
);
233 if (!zIndexStr
.EqualsLiteral("auto")) {
235 *aZindex
= zIndexStr
.ToInteger(&errorCode
);
242 nsHTMLEditor::CreateGrabber(nsIDOMNode
* aParentNode
, nsIDOMElement
** aReturn
)
244 // let's create a grabber through the element factory
245 nsresult res
= CreateAnonymousElement(NS_LITERAL_STRING("span"),
247 NS_LITERAL_STRING("mozGrabber"),
251 NS_ENSURE_TRUE(*aReturn
, NS_ERROR_FAILURE
);
253 // add the mouse listener so we can detect a click on a resizer
254 nsCOMPtr
<nsIDOMEventTarget
> evtTarget(do_QueryInterface(*aReturn
));
255 evtTarget
->AddEventListener(NS_LITERAL_STRING("mousedown"),
256 mEventListener
, false);
262 nsHTMLEditor::RefreshGrabber()
264 NS_ENSURE_TRUE(mAbsolutelyPositionedObject
, NS_ERROR_NULL_POINTER
);
266 nsresult res
= GetPositionAndDimensions(mAbsolutelyPositionedObject
,
269 mPositionedObjectWidth
,
270 mPositionedObjectHeight
,
271 mPositionedObjectBorderLeft
,
272 mPositionedObjectBorderTop
,
273 mPositionedObjectMarginLeft
,
274 mPositionedObjectMarginTop
);
276 NS_ENSURE_SUCCESS(res
, res
);
278 SetAnonymousElementPosition(mPositionedObjectX
+12,
279 mPositionedObjectY
-14,
285 nsHTMLEditor::HideGrabber()
288 mAbsolutelyPositionedObject
->RemoveAttribute(NS_LITERAL_STRING("_moz_abspos"));
289 NS_ENSURE_SUCCESS(res
, res
);
291 mAbsolutelyPositionedObject
= nullptr;
292 NS_ENSURE_TRUE(mGrabber
, NS_ERROR_NULL_POINTER
);
294 // get the presshell's document observer interface.
295 nsCOMPtr
<nsIPresShell
> ps
= GetPresShell();
296 // We allow the pres shell to be null; when it is, we presume there
297 // are no document observers to notify, but we still want to
300 nsCOMPtr
<nsIDOMNode
> parentNode
;
301 res
= mGrabber
->GetParentNode(getter_AddRefs(parentNode
));
302 NS_ENSURE_SUCCESS(res
, res
);
304 nsCOMPtr
<nsIContent
> parentContent
= do_QueryInterface(parentNode
);
305 NS_ENSURE_TRUE(parentContent
, NS_ERROR_NULL_POINTER
);
307 DeleteRefToAnonymousNode(mGrabber
, parentContent
, ps
);
309 DeleteRefToAnonymousNode(mPositioningShadow
, parentContent
, ps
);
310 mPositioningShadow
= nullptr;
316 nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement
* aElement
)
318 NS_ENSURE_ARG_POINTER(aElement
);
321 NS_ERROR("call HideGrabber first");
322 return NS_ERROR_UNEXPECTED
;
325 nsAutoString classValue
;
326 nsresult res
= CheckPositionedElementBGandFG(aElement
, classValue
);
327 NS_ENSURE_SUCCESS(res
, res
);
329 res
= aElement
->SetAttribute(NS_LITERAL_STRING("_moz_abspos"),
331 NS_ENSURE_SUCCESS(res
, res
);
333 // first, let's keep track of that element...
334 mAbsolutelyPositionedObject
= aElement
;
336 nsCOMPtr
<nsIDOMNode
> parentNode
;
337 res
= aElement
->GetParentNode(getter_AddRefs(parentNode
));
338 NS_ENSURE_SUCCESS(res
, res
);
340 res
= CreateGrabber(parentNode
, getter_AddRefs(mGrabber
));
341 NS_ENSURE_SUCCESS(res
, res
);
343 // and set its position
344 return RefreshGrabber();
348 nsHTMLEditor::StartMoving(nsIDOMElement
*aHandle
)
350 nsCOMPtr
<nsIDOMNode
> parentNode
;
351 nsresult res
= mGrabber
->GetParentNode(getter_AddRefs(parentNode
));
352 NS_ENSURE_SUCCESS(res
, res
);
354 // now, let's create the resizing shadow
355 res
= CreateShadow(getter_AddRefs(mPositioningShadow
),
356 parentNode
, mAbsolutelyPositionedObject
);
357 NS_ENSURE_SUCCESS(res
,res
);
358 res
= SetShadowPosition(mPositioningShadow
, mAbsolutelyPositionedObject
,
359 mPositionedObjectX
, mPositionedObjectY
);
360 NS_ENSURE_SUCCESS(res
,res
);
362 // make the shadow appear
363 mPositioningShadow
->RemoveAttribute(NS_LITERAL_STRING("class"));
366 mHTMLCSSUtils
->SetCSSPropertyPixels(mPositioningShadow
,
367 NS_LITERAL_STRING("width"),
368 mPositionedObjectWidth
);
369 mHTMLCSSUtils
->SetCSSPropertyPixels(mPositioningShadow
,
370 NS_LITERAL_STRING("height"),
371 mPositionedObjectHeight
);
378 nsHTMLEditor::SnapToGrid(int32_t & newX
, int32_t & newY
)
380 if (mSnapToGridEnabled
&& mGridSize
) {
381 newX
= (int32_t) floor( ((float)newX
/ (float)mGridSize
) + 0.5f
) * mGridSize
;
382 newY
= (int32_t) floor( ((float)newY
/ (float)mGridSize
) + 0.5f
) * mGridSize
;
387 nsHTMLEditor::GrabberClicked()
389 // add a mouse move listener to the editor
390 nsresult res
= NS_OK
;
391 if (!mMouseMotionListenerP
) {
392 mMouseMotionListenerP
= new ResizerMouseMotionListener(this);
393 if (!mMouseMotionListenerP
) {return NS_ERROR_NULL_POINTER
;}
395 nsCOMPtr
<nsIDOMEventTarget
> piTarget
= GetDOMEventTarget();
396 NS_ENSURE_TRUE(piTarget
, NS_ERROR_FAILURE
);
398 res
= piTarget
->AddEventListener(NS_LITERAL_STRING("mousemove"),
399 mMouseMotionListenerP
,
401 NS_ASSERTION(NS_SUCCEEDED(res
),
402 "failed to register mouse motion listener");
404 mGrabberClicked
= true;
409 nsHTMLEditor::EndMoving()
411 if (mPositioningShadow
) {
412 nsCOMPtr
<nsIPresShell
> ps
= GetPresShell();
413 NS_ENSURE_TRUE(ps
, NS_ERROR_NOT_INITIALIZED
);
415 nsCOMPtr
<nsIDOMNode
> parentNode
;
416 nsresult res
= mGrabber
->GetParentNode(getter_AddRefs(parentNode
));
417 NS_ENSURE_SUCCESS(res
, res
);
419 nsCOMPtr
<nsIContent
> parentContent( do_QueryInterface(parentNode
) );
420 NS_ENSURE_TRUE(parentContent
, NS_ERROR_FAILURE
);
422 DeleteRefToAnonymousNode(mPositioningShadow
, parentContent
, ps
);
424 mPositioningShadow
= nullptr;
426 nsCOMPtr
<nsIDOMEventTarget
> piTarget
= GetDOMEventTarget();
428 if (piTarget
&& mMouseMotionListenerP
) {
432 piTarget
->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
433 mMouseMotionListenerP
,
435 NS_ASSERTION(NS_SUCCEEDED(res
), "failed to remove mouse motion listener");
437 mMouseMotionListenerP
= nullptr;
439 mGrabberClicked
= false;
441 nsCOMPtr
<nsISelection
> selection
;
442 GetSelection(getter_AddRefs(selection
));
444 return NS_ERROR_NOT_INITIALIZED
;
446 return CheckSelectionStateForAnonymousButtons(selection
);
449 nsHTMLEditor::SetFinalPosition(int32_t aX
, int32_t aY
)
451 nsresult res
= EndMoving();
452 NS_ENSURE_SUCCESS(res
, res
);
454 // we have now to set the new width and height of the resized object
455 // we don't set the x and y position because we don't control that in
456 // a normal HTML layout
457 int32_t newX
= mPositionedObjectX
+ aX
- mOriginalX
- (mPositionedObjectBorderLeft
+mPositionedObjectMarginLeft
);
458 int32_t newY
= mPositionedObjectY
+ aY
- mOriginalY
- (mPositionedObjectBorderTop
+mPositionedObjectMarginTop
);
460 SnapToGrid(newX
, newY
);
466 // we want one transaction only from a user's point of view
467 nsAutoEditBatch
batchIt(this);
469 nsCOMPtr
<Element
> absolutelyPositionedObject
=
470 do_QueryInterface(mAbsolutelyPositionedObject
);
471 NS_ENSURE_STATE(absolutelyPositionedObject
);
472 mHTMLCSSUtils
->SetCSSPropertyPixels(*absolutelyPositionedObject
,
473 *nsGkAtoms::top
, newY
);
474 mHTMLCSSUtils
->SetCSSPropertyPixels(*absolutelyPositionedObject
,
475 *nsGkAtoms::left
, newX
);
476 // keep track of that size
477 mPositionedObjectX
= newX
;
478 mPositionedObjectY
= newY
;
480 return RefreshResizers();
484 nsHTMLEditor::AddPositioningOffset(int32_t & aX
, int32_t & aY
)
486 // Get the positioning offset
487 int32_t positioningOffset
=
488 Preferences::GetInt("editor.positioning.offset", 0);
490 aX
+= positioningOffset
;
491 aY
+= positioningOffset
;
495 nsHTMLEditor::AbsolutelyPositionElement(nsIDOMElement
* aElement
,
498 nsCOMPtr
<Element
> element
= do_QueryInterface(aElement
);
499 NS_ENSURE_ARG_POINTER(element
);
501 nsAutoString positionStr
;
502 mHTMLCSSUtils
->GetComputedProperty(aElement
, nsGkAtoms::position
,
504 bool isPositioned
= (positionStr
.EqualsLiteral("absolute"));
506 // nothing to do if the element is already in the state we want
507 if (isPositioned
== aEnabled
)
510 nsAutoEditBatch
batchIt(this);
514 GetElementOrigin(aElement
, x
, y
);
516 mHTMLCSSUtils
->SetCSSProperty(*element
, *nsGkAtoms::position
,
517 NS_LITERAL_STRING("absolute"));
519 AddPositioningOffset(x
, y
);
521 SetElementPosition(aElement
, x
, y
);
523 // we may need to create a br if the positioned element is alone in its
525 nsCOMPtr
<nsINode
> element
= do_QueryInterface(aElement
);
526 NS_ENSURE_STATE(element
);
528 nsINode
* parentNode
= element
->GetParentNode();
529 if (parentNode
->GetChildCount() == 1) {
530 nsCOMPtr
<nsIDOMNode
> brNode
;
531 nsresult res
= CreateBR(parentNode
->AsDOMNode(), 0, address_of(brNode
));
532 NS_ENSURE_SUCCESS(res
, res
);
536 mHTMLCSSUtils
->RemoveCSSProperty(*element
, *nsGkAtoms::position
,
538 mHTMLCSSUtils
->RemoveCSSProperty(*element
, *nsGkAtoms::top
,
540 mHTMLCSSUtils
->RemoveCSSProperty(*element
, *nsGkAtoms::left
,
542 mHTMLCSSUtils
->RemoveCSSProperty(*element
, *nsGkAtoms::z_index
,
545 if (!nsHTMLEditUtils::IsImage(aElement
)) {
546 mHTMLCSSUtils
->RemoveCSSProperty(*element
, *nsGkAtoms::width
,
548 mHTMLCSSUtils
->RemoveCSSProperty(*element
, *nsGkAtoms::height
,
552 nsCOMPtr
<dom::Element
> element
= do_QueryInterface(aElement
);
553 if (element
&& element
->IsHTML(nsGkAtoms::div
) && !HasStyleOrIdOrClass(element
)) {
554 nsRefPtr
<nsHTMLEditRules
> htmlRules
= static_cast<nsHTMLEditRules
*>(mRules
.get());
555 NS_ENSURE_TRUE(htmlRules
, NS_ERROR_FAILURE
);
556 nsresult res
= htmlRules
->MakeSureElemStartsOrEndsOnCR(aElement
);
557 NS_ENSURE_SUCCESS(res
, res
);
558 res
= RemoveContainer(element
);
559 NS_ENSURE_SUCCESS(res
, res
);
566 nsHTMLEditor::SetSnapToGridEnabled(bool aEnabled
)
568 mSnapToGridEnabled
= aEnabled
;
573 nsHTMLEditor::GetSnapToGridEnabled(bool * aIsEnabled
)
575 *aIsEnabled
= mSnapToGridEnabled
;
580 nsHTMLEditor::SetGridSize(uint32_t aSize
)
587 nsHTMLEditor::GetGridSize(uint32_t * aSize
)
595 nsHTMLEditor::SetElementPosition(nsIDOMElement
*aElement
, int32_t aX
, int32_t aY
)
597 nsCOMPtr
<Element
> element
= do_QueryInterface(aElement
);
598 NS_ENSURE_STATE(element
);
599 nsAutoEditBatch
batchIt(this);
601 mHTMLCSSUtils
->SetCSSPropertyPixels(*element
, *nsGkAtoms::left
, aX
);
602 mHTMLCSSUtils
->SetCSSPropertyPixels(*element
, *nsGkAtoms::top
, aY
);
608 nsHTMLEditor::GetPositionedElement(nsIDOMElement
** aReturn
)
610 *aReturn
= mAbsolutelyPositionedObject
;
611 NS_IF_ADDREF(*aReturn
);
616 nsHTMLEditor::CheckPositionedElementBGandFG(nsIDOMElement
* aElement
,
619 // we are going to outline the positioned element and bring it to the
620 // front to overlap any other element intersecting with it. But
621 // first, let's see what's the background and foreground colors of the
622 // positioned element.
623 // if background-image computed value is 'none,
624 // If the background color is 'auto' and R G B values of the foreground are
625 // each above #d0, use a black background
626 // If the background color is 'auto' and at least one of R G B values of
627 // the foreground is below #d0, use a white background
628 // Otherwise don't change background/foreground
632 nsAutoString bgImageStr
;
634 mHTMLCSSUtils
->GetComputedProperty(aElement
, nsGkAtoms::background_image
,
636 NS_ENSURE_SUCCESS(res
, res
);
637 if (bgImageStr
.EqualsLiteral("none")) {
638 nsAutoString bgColorStr
;
640 mHTMLCSSUtils
->GetComputedProperty(aElement
, nsGkAtoms::backgroundColor
,
642 NS_ENSURE_SUCCESS(res
, res
);
643 if (bgColorStr
.EqualsLiteral("transparent")) {
644 nsRefPtr
<nsComputedDOMStyle
> cssDecl
=
645 mHTMLCSSUtils
->GetComputedStyle(aElement
);
646 NS_ENSURE_STATE(cssDecl
);
648 // from these declarations, get the one we want and that one only
650 nsRefPtr
<dom::CSSValue
> cssVal
= cssDecl
->GetPropertyCSSValue(NS_LITERAL_STRING("color"), error
);
651 NS_ENSURE_SUCCESS(error
.ErrorCode(), error
.ErrorCode());
653 nsROCSSPrimitiveValue
* val
= cssVal
->AsPrimitiveValue();
654 NS_ENSURE_TRUE(val
, NS_ERROR_FAILURE
);
656 if (nsIDOMCSSPrimitiveValue::CSS_RGBCOLOR
== val
->PrimitiveType()) {
657 nsDOMCSSRGBColor
* rgbVal
= val
->GetRGBColorValue(error
);
658 NS_ENSURE_SUCCESS(error
.ErrorCode(), error
.ErrorCode());
659 float r
= rgbVal
->Red()->
660 GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER
, error
);
661 NS_ENSURE_SUCCESS(error
.ErrorCode(), error
.ErrorCode());
662 float g
= rgbVal
->Green()->
663 GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER
, error
);
664 NS_ENSURE_SUCCESS(error
.ErrorCode(), error
.ErrorCode());
665 float b
= rgbVal
->Blue()->
666 GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER
, error
);
667 NS_ENSURE_SUCCESS(error
.ErrorCode(), error
.ErrorCode());
668 if (r
>= BLACK_BG_RGB_TRIGGER
&&
669 g
>= BLACK_BG_RGB_TRIGGER
&&
670 b
>= BLACK_BG_RGB_TRIGGER
)
671 aReturn
.AssignLiteral("black");
673 aReturn
.AssignLiteral("white");