DXR will be turned off on Tuesday, December 29th. It will redirect to Searchfox.
See the announcement on Discourse.

DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
/* -*- 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/. */

#ifndef nsFileControlFrame_h___
#define nsFileControlFrame_h___

#include "mozilla/Attributes.h"
#include "nsBlockFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIDOMEventListener.h"
#include "nsIAnonymousContentCreator.h"
#include "nsCOMPtr.h"

namespace mozilla {
namespace dom {
class FileList;
class BlobImpl;
class DataTransfer;
}  // namespace dom
}  // namespace mozilla

class nsFileControlFrame final : public nsBlockFrame,
                                 public nsIFormControlFrame,
                                 public nsIAnonymousContentCreator {
  using Element = mozilla::dom::Element;

 public:
  NS_DECL_QUERYFRAME
  NS_DECL_FRAMEARENA_HELPERS(nsFileControlFrame)

  explicit nsFileControlFrame(ComputedStyle* aStyle,
                              nsPresContext* aPresContext);

  virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
                    nsIFrame* aPrevInFlow) override;

  void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
              const ReflowInput& aReflowInput,
              nsReflowStatus& aStatus) override;

  virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
                                const nsDisplayListSet& aLists) override;

  // nsIFormControlFrame
  virtual nsresult SetFormProperty(nsAtom* aName,
                                   const nsAString& aValue) override;
  virtual void SetFocus(bool aOn, bool aRepaint) override;

  nscoord GetMinISize(gfxContext* aRenderingContext) override;
  nscoord GetPrefISize(gfxContext* aRenderingContext) override;

  virtual void DestroyFrom(nsIFrame* aDestructRoot,
                           PostDestroyData& aPostDestroyData) override;

#ifdef DEBUG_FRAME_DUMP
  virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif

  virtual void ContentStatesChanged(mozilla::EventStates aStates) override;

  // nsIAnonymousContentCreator
  virtual nsresult CreateAnonymousContent(
      nsTArray<ContentInfo>& aElements) override;
  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                        uint32_t aFilter) override;

#ifdef ACCESSIBILITY
  virtual mozilla::a11y::AccType AccessibleType() override;
#endif

  typedef bool (*AcceptAttrCallback)(const nsAString&, void*);

 protected:
  class MouseListener;
  friend class MouseListener;
  class MouseListener : public nsIDOMEventListener {
   public:
    NS_DECL_ISUPPORTS

    explicit MouseListener(nsFileControlFrame* aFrame) : mFrame(aFrame) {}

    void ForgetFrame() { mFrame = nullptr; }

   protected:
    virtual ~MouseListener() = default;

    nsFileControlFrame* mFrame;
  };

  class SyncDisabledStateEvent;
  friend class SyncDisabledStateEvent;
  class SyncDisabledStateEvent : public mozilla::Runnable {
   public:
    explicit SyncDisabledStateEvent(nsFileControlFrame* aFrame)
        : mozilla::Runnable("nsFileControlFrame::SyncDisabledStateEvent"),
          mFrame(aFrame) {}

    NS_IMETHOD Run() override {
      nsFileControlFrame* frame =
          static_cast<nsFileControlFrame*>(mFrame.GetFrame());
      NS_ENSURE_STATE(frame);

      frame->SyncDisabledState();
      return NS_OK;
    }

   private:
    WeakFrame mFrame;
  };

  class DnDListener : public MouseListener {
   public:
    explicit DnDListener(nsFileControlFrame* aFrame) : MouseListener(aFrame) {}

    // nsIDOMEventListener
    MOZ_CAN_RUN_SCRIPT_BOUNDARY
    NS_IMETHOD HandleEvent(mozilla::dom::Event* aEvent) override;

    nsresult GetBlobImplForWebkitDirectory(mozilla::dom::FileList* aFileList,
                                           mozilla::dom::BlobImpl** aBlobImpl);

    bool IsValidDropData(mozilla::dom::DataTransfer* aDataTransfer);
    bool CanDropTheseFiles(mozilla::dom::DataTransfer* aDataTransfer,
                           bool aSupportsMultiple);
  };

  virtual bool IsFrameOfType(uint32_t aFlags) const override {
    return nsBlockFrame::IsFrameOfType(
        aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
  }

  /**
   * The text box input.
   * @see nsFileControlFrame::CreateAnonymousContent
   */
  RefPtr<Element> mTextContent;
  /**
   * The button to open a file or directory picker.
   * @see nsFileControlFrame::CreateAnonymousContent
   */
  RefPtr<Element> mBrowseFilesOrDirs;

  /**
   * Drag and drop mouse listener.
   * This makes sure we don't get used after destruction.
   */
  RefPtr<DnDListener> mMouseListener;

 protected:
  /**
   * Crop aText to fit inside aWidth using the styles of aFrame.
   * @return true if aText was modified
   */
  static bool CropTextToWidth(gfxContext& aRenderingContext,
                              const nsIFrame* aFrame, nscoord aWidth,
                              nsString& aText);

  /**
   * Sync the disabled state of the content with anonymous children.
   */
  void SyncDisabledState();

  /**
   * Updates the displayed value by using aValue.
   */
  void UpdateDisplayedValue(const nsAString& aValue, bool aNotify);
};

#endif  // nsFileControlFrame_h___