forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			154 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
	
		
			5.2 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 "nsIDOMNode.h"
 | 
						|
#include "nsIFormControl.h"
 | 
						|
#include "mozilla/StyleSetHandle.h"
 | 
						|
#include "mozilla/StyleSetHandleInlines.h"
 | 
						|
#include "mozilla/dom/HTMLInputElement.h"
 | 
						|
#include "nsIDocument.h"
 | 
						|
 | 
						|
using mozilla::dom::Element;
 | 
						|
using mozilla::dom::HTMLInputElement;
 | 
						|
using mozilla::dom::CallerType;
 | 
						|
 | 
						|
nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext)
 | 
						|
  : nsHTMLButtonControlFrame(aContext, kClassID)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
nsIFrame*
 | 
						|
NS_NewColorControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 | 
						|
{
 | 
						|
  return new (aPresShell) nsColorControlFrame(aContext);
 | 
						|
}
 | 
						|
 | 
						|
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)
 | 
						|
{
 | 
						|
  nsCOMPtr<nsIDocument> 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::FromContent(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;
 | 
						|
}
 | 
						|
 | 
						|
Element*
 | 
						|
nsColorControlFrame::GetPseudoElement(CSSPseudoElementType aType)
 | 
						|
{
 | 
						|
  if (aType == CSSPseudoElementType::mozColorSwatch) {
 | 
						|
    return mColorContent;
 | 
						|
  }
 | 
						|
 | 
						|
  return nsContainerFrame::GetPseudoElement(aType);
 | 
						|
}
 |