forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			130 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "nsColorControlFrame.h"
 | |
| 
 | |
| #include "nsContentCreatorFunctions.h"
 | |
| #include "nsContentUtils.h"
 | |
| #include "nsCSSPseudoElements.h"
 | |
| #include "nsCheckboxRadioFrame.h"
 | |
| #include "nsGkAtoms.h"
 | |
| #include "nsIFormControl.h"
 | |
| #include "mozilla/dom/HTMLInputElement.h"
 | |
| #include "mozilla/dom/Document.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| using mozilla::dom::CallerType;
 | |
| using mozilla::dom::Document;
 | |
| using mozilla::dom::Element;
 | |
| using mozilla::dom::HTMLInputElement;
 | |
| 
 | |
| nsColorControlFrame::nsColorControlFrame(ComputedStyle* aStyle,
 | |
|                                          nsPresContext* aPresContext)
 | |
|     : nsHTMLButtonControlFrame(aStyle, aPresContext, kClassID) {}
 | |
| 
 | |
| nsIFrame* NS_NewColorControlFrame(nsIPresShell* aPresShell,
 | |
|                                   ComputedStyle* aStyle) {
 | |
|   return new (aPresShell)
 | |
|       nsColorControlFrame(aStyle, aPresShell->GetPresContext());
 | |
| }
 | |
| 
 | |
| NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame)
 | |
| 
 | |
| NS_QUERYFRAME_HEAD(nsColorControlFrame)
 | |
|   NS_QUERYFRAME_ENTRY(nsColorControlFrame)
 | |
|   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 | |
| NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButtonControlFrame)
 | |
| 
 | |
| void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
 | |
|                                       PostDestroyData& aPostDestroyData) {
 | |
|   nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
 | |
|   aPostDestroyData.AddAnonymousContent(mColorContent.forget());
 | |
|   nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
 | |
| }
 | |
| 
 | |
| #ifdef DEBUG_FRAME_DUMP
 | |
| nsresult nsColorControlFrame::GetFrameName(nsAString& aResult) const {
 | |
|   return MakeFrameName(NS_LITERAL_STRING("ColorControl"), aResult);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| // Create the color area for the button.
 | |
| // The frame will be generated by the frame constructor.
 | |
| nsresult nsColorControlFrame::CreateAnonymousContent(
 | |
|     nsTArray<ContentInfo>& aElements) {
 | |
|   RefPtr<Document> doc = mContent->GetComposedDoc();
 | |
|   mColorContent = doc->CreateHTMLElement(nsGkAtoms::div);
 | |
|   mColorContent->SetPseudoElementType(CSSPseudoElementType::mozColorSwatch);
 | |
| 
 | |
|   // Mark the element to be native anonymous before setting any attributes.
 | |
|   mColorContent->SetIsNativeAnonymousRoot();
 | |
| 
 | |
|   nsresult rv = UpdateColor();
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   if (!aElements.AppendElement(mColorContent)) {
 | |
|     return NS_ERROR_OUT_OF_MEMORY;
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| void nsColorControlFrame::AppendAnonymousContentTo(
 | |
|     nsTArray<nsIContent*>& aElements, uint32_t aFilter) {
 | |
|   if (mColorContent) {
 | |
|     aElements.AppendElement(mColorContent);
 | |
|   }
 | |
| }
 | |
| 
 | |
| nsresult nsColorControlFrame::UpdateColor() {
 | |
|   // Get the color from the "value" property of our content; it will return the
 | |
|   // default color (through the sanitization algorithm) if the value is empty.
 | |
|   nsAutoString color;
 | |
|   HTMLInputElement* elt = HTMLInputElement::FromNode(mContent);
 | |
|   elt->GetValue(color, CallerType::System);
 | |
| 
 | |
|   if (color.IsEmpty()) {
 | |
|     // OK, there is one case the color string might be empty -- if our content
 | |
|     // is still being created, i.e. if it has mDoneCreating==false.  In that
 | |
|     // case, we simply do nothing, because we'll be called again with a complete
 | |
|     // content node before we ever reflow or paint. Specifically: we can expect
 | |
|     // that HTMLInputElement::DoneCreatingElement() will set mDoneCreating to
 | |
|     // true (which enables sanitization) and then it'll call SetValueInternal(),
 | |
|     // which produces a nonempty color (via sanitization), and then it'll call
 | |
|     // this function here, and we'll get the nonempty default color.
 | |
|     MOZ_ASSERT(HasAnyStateBits(NS_FRAME_FIRST_REFLOW),
 | |
|                "Content node's GetValue() should return a valid color string "
 | |
|                "by the time we've been reflowed (the default color, in case "
 | |
|                "no valid color is set)");
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   // Set the background-color CSS property of the swatch element to this color.
 | |
|   return mColorContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
 | |
|                                 NS_LITERAL_STRING("background-color:") + color,
 | |
|                                 /* aNotify */ true);
 | |
| }
 | |
| 
 | |
| nsresult nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID,
 | |
|                                                nsAtom* aAttribute,
 | |
|                                                int32_t aModType) {
 | |
|   NS_ASSERTION(mColorContent, "The color div must exist");
 | |
| 
 | |
|   // If the value attribute is set, update the color box, but only if we're
 | |
|   // still a color control, which might not be the case if the type attribute
 | |
|   // was removed/changed.
 | |
|   nsCOMPtr<nsIFormControl> fctrl = do_QueryInterface(GetContent());
 | |
|   if (fctrl->ControlType() == NS_FORM_INPUT_COLOR &&
 | |
|       aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) {
 | |
|     UpdateColor();
 | |
|   }
 | |
|   return nsHTMLButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute,
 | |
|                                                     aModType);
 | |
| }
 | |
| 
 | |
| nsContainerFrame* nsColorControlFrame::GetContentInsertionFrame() {
 | |
|   return this;
 | |
| }
 | 
