summaryrefslogtreecommitdiff
path: root/layout/forms/nsColorControlFrame.cpp
blob: 63aee814aae6b5e0d91ba63d84911928ba5f6953 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsContentList.h"
#include "nsContentUtils.h"
#include "nsCSSPseudoElements.h"
#include "nsFormControlFrame.h"
#include "nsGkAtoms.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMNode.h"
#include "nsIFormControl.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "nsIDocument.h"

using mozilla::dom::Element;

nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext)
  : nsHTMLButtonControlFrame(aContext)
{
}

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)
{
  nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
  nsContentUtils::DestroyAnonymousContent(&mColorContent);
  nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot);
}

nsIAtom*
nsColorControlFrame::GetType() const
{
  return nsGkAtoms::colorControlFrame;
}

#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 there is none.
  nsAutoString color;
  nsCOMPtr<nsIDOMHTMLInputElement> elt = do_QueryInterface(mContent);
  elt->GetValue(color);
  MOZ_ASSERT(!color.IsEmpty(),
             "Content node's GetValue() should return a valid color string "
             "(the default color, in case no valid color is set)");

  // Set the background-color style property of the swatch element to this color
  return mColorContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
      NS_LITERAL_STRING("background-color:") + color, true);
}

nsresult
nsColorControlFrame::AttributeChanged(int32_t  aNameSpaceID,
                                      nsIAtom* 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->GetType() == 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);
}