michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsColorControlFrame.h" michael@0: michael@0: #include "nsContentCreatorFunctions.h" michael@0: #include "nsContentList.h" michael@0: #include "nsContentUtils.h" michael@0: #include "nsFormControlFrame.h" michael@0: #include "nsGkAtoms.h" michael@0: #include "nsIDOMHTMLInputElement.h" michael@0: #include "nsIDOMNode.h" michael@0: #include "nsIFormControl.h" michael@0: #include "nsStyleSet.h" michael@0: michael@0: using mozilla::dom::Element; michael@0: michael@0: nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext): michael@0: nsColorControlFrameSuper(aContext) michael@0: { michael@0: } michael@0: michael@0: nsIFrame* michael@0: NS_NewColorControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) michael@0: { michael@0: return new (aPresShell) nsColorControlFrame(aContext); michael@0: } michael@0: michael@0: NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame) michael@0: michael@0: NS_QUERYFRAME_HEAD(nsColorControlFrame) michael@0: NS_QUERYFRAME_ENTRY(nsColorControlFrame) michael@0: NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) michael@0: NS_QUERYFRAME_TAIL_INHERITING(nsColorControlFrameSuper) michael@0: michael@0: michael@0: void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot) michael@0: { michael@0: nsFormControlFrame::RegUnRegAccessKey(static_cast(this), false); michael@0: nsContentUtils::DestroyAnonymousContent(&mColorContent); michael@0: nsColorControlFrameSuper::DestroyFrom(aDestructRoot); michael@0: } michael@0: michael@0: nsIAtom* michael@0: nsColorControlFrame::GetType() const michael@0: { michael@0: return nsGkAtoms::colorControlFrame; michael@0: } michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: nsresult michael@0: nsColorControlFrame::GetFrameName(nsAString& aResult) const michael@0: { michael@0: return MakeFrameName(NS_LITERAL_STRING("ColorControl"), aResult); michael@0: } michael@0: #endif michael@0: michael@0: // Create the color area for the button. michael@0: // The frame will be generated by the frame constructor. michael@0: nsresult michael@0: nsColorControlFrame::CreateAnonymousContent(nsTArray& aElements) michael@0: { michael@0: nsCOMPtr doc = mContent->GetCurrentDoc(); michael@0: mColorContent = doc->CreateHTMLElement(nsGkAtoms::div); michael@0: michael@0: // Mark the element to be native anonymous before setting any attributes. michael@0: mColorContent->SetIsNativeAnonymousRoot(); michael@0: michael@0: nsresult rv = UpdateColor(); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozColorSwatch; michael@0: nsRefPtr newStyleContext = PresContext()->StyleSet()-> michael@0: ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, michael@0: StyleContext(), mColorContent->AsElement()); michael@0: if (!aElements.AppendElement(ContentInfo(mColorContent, newStyleContext))) { michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: nsColorControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, michael@0: uint32_t aFilter) michael@0: { michael@0: aElements.MaybeAppendElement(mColorContent); michael@0: } michael@0: michael@0: nsresult michael@0: nsColorControlFrame::UpdateColor() michael@0: { michael@0: // Get the color from the "value" property of our content; it will return the michael@0: // default color (through the sanitization algorithm) if there is none. michael@0: nsAutoString color; michael@0: nsCOMPtr elt = do_QueryInterface(mContent); michael@0: elt->GetValue(color); michael@0: MOZ_ASSERT(!color.IsEmpty(), michael@0: "Content node's GetValue() should return a valid color string " michael@0: "(the default color, in case no valid color is set)"); michael@0: michael@0: // Set the background-color style property of the swatch element to this color michael@0: return mColorContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style, michael@0: NS_LITERAL_STRING("background-color:") + color, true); michael@0: } michael@0: michael@0: nsresult michael@0: nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID, michael@0: nsIAtom* aAttribute, michael@0: int32_t aModType) michael@0: { michael@0: NS_ASSERTION(mColorContent, "The color div must exist"); michael@0: michael@0: // If the value attribute is set, update the color box, but only if we're michael@0: // still a color control, which might not be the case if the type attribute michael@0: // was removed/changed. michael@0: nsCOMPtr fctrl = do_QueryInterface(GetContent()); michael@0: if (fctrl->GetType() == NS_FORM_INPUT_COLOR && michael@0: aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) { michael@0: UpdateColor(); michael@0: } michael@0: return nsColorControlFrameSuper::AttributeChanged(aNameSpaceID, aAttribute, michael@0: aModType); michael@0: } michael@0: michael@0: nsIFrame* michael@0: nsColorControlFrame::GetContentInsertionFrame() michael@0: { michael@0: return this; michael@0: } michael@0: michael@0: Element* michael@0: nsColorControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) michael@0: { michael@0: if (aType == nsCSSPseudoElements::ePseudo_mozColorSwatch) { michael@0: return mColorContent; michael@0: } michael@0: michael@0: return nsContainerFrame::GetPseudoElement(aType); michael@0: }