tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsColorControlFrame.cpp (4426B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsColorControlFrame.h"
      8 
      9 #include "mozilla/PresShell.h"
     10 #include "mozilla/dom/Document.h"
     11 #include "mozilla/dom/HTMLInputElement.h"
     12 #include "nsContentCreatorFunctions.h"
     13 #include "nsContentUtils.h"
     14 #include "nsGkAtoms.h"
     15 #include "nsIFormControl.h"
     16 
     17 using namespace mozilla;
     18 using mozilla::dom::CallerType;
     19 using mozilla::dom::HTMLInputElement;
     20 
     21 nsColorControlFrame::nsColorControlFrame(ComputedStyle* aStyle,
     22                                         nsPresContext* aPresContext)
     23    : ButtonControlFrame(aStyle, aPresContext, kClassID) {}
     24 
     25 nsIFrame* NS_NewColorControlFrame(PresShell* aPresShell,
     26                                  ComputedStyle* aStyle) {
     27  return new (aPresShell)
     28      nsColorControlFrame(aStyle, aPresShell->GetPresContext());
     29 }
     30 
     31 NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame)
     32 
     33 NS_QUERYFRAME_HEAD(nsColorControlFrame)
     34  NS_QUERYFRAME_ENTRY(nsColorControlFrame)
     35 NS_QUERYFRAME_TAIL_INHERITING(ButtonControlFrame)
     36 
     37 void nsColorControlFrame::Destroy(DestroyContext& aContext) {
     38  aContext.AddAnonymousContent(mColorContent.forget());
     39  ButtonControlFrame::Destroy(aContext);
     40 }
     41 
     42 // Create the color area for the button.
     43 // The frame will be generated by the frame constructor.
     44 nsresult nsColorControlFrame::CreateAnonymousContent(
     45    nsTArray<ContentInfo>& aElements) {
     46  mColorContent = mContent->OwnerDoc()->CreateHTMLElement(nsGkAtoms::div);
     47  mColorContent->SetPseudoElementType(PseudoStyleType::mozColorSwatch);
     48  // Mark the element to be native anonymous before setting any attributes.
     49  mColorContent->SetIsNativeAnonymousRoot();
     50  UpdateColor();
     51  aElements.AppendElement(mColorContent);
     52  return NS_OK;
     53 }
     54 
     55 void nsColorControlFrame::AppendAnonymousContentTo(
     56    nsTArray<nsIContent*>& aElements, uint32_t aFilter) {
     57  if (mColorContent) {
     58    aElements.AppendElement(mColorContent);
     59  }
     60 }
     61 
     62 void nsColorControlFrame::UpdateColor() {
     63  // Get the color from the "value" property of our content; it will return the
     64  // default color (through the sanitization algorithm) if the value is empty.
     65  nsAutoString color;
     66  auto* elt = HTMLInputElement::FromNode(mContent);
     67  elt->GetValue(color, CallerType::System);
     68 
     69  if (color.IsEmpty()) {
     70    // OK, there is one case the color string might be empty -- if our content
     71    // is still being created, i.e. if it has mDoneCreating==false.  In that
     72    // case, we simply do nothing, because we'll be called again with a complete
     73    // content node before we ever reflow or paint. Specifically: we can expect
     74    // that HTMLInputElement::DoneCreatingElement() will set mDoneCreating to
     75    // true (which enables sanitization) and then it'll call SetValueInternal(),
     76    // which produces a nonempty color (via sanitization), and then it'll call
     77    // this function here, and we'll get the nonempty default color.
     78    MOZ_ASSERT(HasAnyStateBits(NS_FRAME_FIRST_REFLOW),
     79               "Content node's GetValue() should return a valid color string "
     80               "by the time we've been reflowed (the default color, in case "
     81               "no valid color is set)");
     82    return;
     83  }
     84 
     85  // Set the background-color CSS property of the swatch element to this color.
     86  mColorContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
     87                         u"background-color:"_ns + color,
     88                         /* aNotify */ true);
     89 }
     90 
     91 nsresult nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID,
     92                                               nsAtom* aAttribute,
     93                                               AttrModType aModType) {
     94  NS_ASSERTION(mColorContent, "The color div must exist");
     95 
     96  // If the value attribute is set, update the color box, but only if we're
     97  // still a color control, which might not be the case if the type attribute
     98  // was removed/changed.
     99  if (nsIFormControl::FromNode(GetContent())->ControlType() ==
    100          FormControlType::InputColor &&
    101      aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) {
    102    UpdateColor();
    103  }
    104  return ButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute,
    105                                              aModType);
    106 }