Blame dom/events/ContentEventHandler.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef mozilla_ContentEventHandler_h_
Packit f0b94e
#define mozilla_ContentEventHandler_h_
Packit f0b94e
Packit f0b94e
#include "mozilla/EventForwards.h"
Packit f0b94e
#include "mozilla/dom/Selection.h"
Packit f0b94e
#include "nsCOMPtr.h"
Packit f0b94e
#include "nsIFrame.h"
Packit f0b94e
#include "nsINode.h"
Packit f0b94e
#include "nsISelectionController.h"
Packit f0b94e
Packit f0b94e
class nsPresContext;
Packit f0b94e
class nsRange;
Packit f0b94e
Packit f0b94e
struct nsRect;
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
enum LineBreakType { LINE_BREAK_TYPE_NATIVE, LINE_BREAK_TYPE_XP };
Packit f0b94e
Packit f0b94e
/*
Packit f0b94e
 * Query Content Event Handler
Packit f0b94e
 *   ContentEventHandler is a helper class for EventStateManager.
Packit f0b94e
 *   The platforms request some content informations, e.g., the selected text,
Packit f0b94e
 *   the offset of the selected text and the text for specified range.
Packit f0b94e
 *   This class answers to NS_QUERY_* events from actual contents.
Packit f0b94e
 */
Packit f0b94e
Packit f0b94e
class MOZ_STACK_CLASS ContentEventHandler {
Packit f0b94e
 private:
Packit f0b94e
  /**
Packit f0b94e
   * RawRange is a helper class of ContentEventHandler class.  The caller is
Packit f0b94e
   * responsible for making sure the start/end nodes are in document order.
Packit f0b94e
   * This is enforced by assertions in DEBUG builds.
Packit f0b94e
   */
Packit f0b94e
  class MOZ_STACK_CLASS RawRange final {
Packit f0b94e
   public:
Packit f0b94e
    RawRange() {}
Packit f0b94e
Packit f0b94e
    void Clear() {
Packit f0b94e
      mRoot = nullptr;
Packit f0b94e
      mStart = RangeBoundary();
Packit f0b94e
      mEnd = RangeBoundary();
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    bool IsPositioned() const { return mStart.IsSet() && mEnd.IsSet(); }
Packit f0b94e
    bool Collapsed() const { return mStart == mEnd && IsPositioned(); }
Packit f0b94e
    nsINode* GetStartContainer() const { return mStart.Container(); }
Packit f0b94e
    nsINode* GetEndContainer() const { return mEnd.Container(); }
Packit f0b94e
    uint32_t StartOffset() const { return mStart.Offset(); }
Packit f0b94e
    uint32_t EndOffset() const { return mEnd.Offset(); }
Packit f0b94e
    nsIContent* StartRef() const { return mStart.Ref(); }
Packit f0b94e
    nsIContent* EndRef() const { return mEnd.Ref(); }
Packit f0b94e
Packit f0b94e
    const RangeBoundary& Start() const { return mStart; }
Packit f0b94e
    const RangeBoundary& End() const { return mEnd; }
Packit f0b94e
Packit f0b94e
    // XXX: Make these use RangeBoundaries...
Packit f0b94e
    nsresult CollapseTo(const RawRangeBoundary& aBoundary) {
Packit f0b94e
      return SetStartAndEnd(aBoundary, aBoundary);
Packit f0b94e
    }
Packit f0b94e
    nsresult SetStart(const RawRangeBoundary& aStart);
Packit f0b94e
    nsresult SetEnd(const RawRangeBoundary& aEnd);
Packit f0b94e
Packit f0b94e
    // NOTE: These helpers can hide performance problems, as they perform a
Packit f0b94e
    // search to find aStartOffset in aStartContainer.
Packit f0b94e
    nsresult SetStart(nsINode* aStartContainer, uint32_t aStartOffset) {
Packit f0b94e
      return SetStart(RawRangeBoundary(aStartContainer, aStartOffset));
Packit f0b94e
    }
Packit f0b94e
    nsresult SetEnd(nsINode* aEndContainer, uint32_t aEndOffset) {
Packit f0b94e
      return SetEnd(RawRangeBoundary(aEndContainer, aEndOffset));
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    nsresult SetEndAfter(nsINode* aEndContainer);
Packit f0b94e
    void SetStartAndEnd(const nsRange* aRange);
Packit f0b94e
    nsresult SetStartAndEnd(const RawRangeBoundary& aStart,
Packit f0b94e
                            const RawRangeBoundary& aEnd);
Packit f0b94e
Packit f0b94e
    nsresult SelectNodeContents(nsINode* aNodeToSelectContents);
Packit f0b94e
Packit f0b94e
   private:
Packit f0b94e
    nsINode* IsValidBoundary(nsINode* aNode) const;
Packit f0b94e
    inline void AssertStartIsBeforeOrEqualToEnd();
Packit f0b94e
Packit f0b94e
    nsCOMPtr<nsINode> mRoot;
Packit f0b94e
Packit f0b94e
    RangeBoundary mStart;
Packit f0b94e
    RangeBoundary mEnd;
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  typedef dom::Selection Selection;
Packit f0b94e
Packit f0b94e
  explicit ContentEventHandler(nsPresContext* aPresContext);
Packit f0b94e
Packit f0b94e
  // Handle aEvent in the current process.
Packit f0b94e
  nsresult HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
Packit f0b94e
Packit f0b94e
  // eQuerySelectedText event handler
Packit f0b94e
  nsresult OnQuerySelectedText(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryTextContent event handler
Packit f0b94e
  nsresult OnQueryTextContent(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryCaretRect event handler
Packit f0b94e
  nsresult OnQueryCaretRect(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryTextRect event handler
Packit f0b94e
  nsresult OnQueryTextRect(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryTextRectArray event handler
Packit f0b94e
  nsresult OnQueryTextRectArray(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryEditorRect event handler
Packit f0b94e
  nsresult OnQueryEditorRect(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryContentState event handler
Packit f0b94e
  nsresult OnQueryContentState(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQuerySelectionAsTransferable event handler
Packit f0b94e
  nsresult OnQuerySelectionAsTransferable(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryCharacterAtPoint event handler
Packit f0b94e
  nsresult OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // eQueryDOMWidgetHittest event handler
Packit f0b94e
  nsresult OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent);
Packit f0b94e
Packit f0b94e
  // NS_SELECTION_* event
Packit f0b94e
  nsresult OnSelectionEvent(WidgetSelectionEvent* aEvent);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  nsCOMPtr<nsIDocument> mDocument;
Packit f0b94e
  // mSelection is typically normal selection but if OnQuerySelectedText()
Packit f0b94e
  // is called, i.e., handling eQuerySelectedText, it's the specified selection
Packit f0b94e
  // by WidgetQueryContentEvent::mInput::mSelectionType.
Packit f0b94e
  RefPtr<Selection> mSelection;
Packit f0b94e
  // mFirstSelectedRawRange is initialized from the first range of mSelection,
Packit f0b94e
  // if it exists.  Otherwise, it is reset by Clear().
Packit f0b94e
  RawRange mFirstSelectedRawRange;
Packit f0b94e
  nsCOMPtr<nsIContent> mRootContent;
Packit f0b94e
Packit f0b94e
  nsresult Init(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  nsresult Init(WidgetSelectionEvent* aEvent);
Packit f0b94e
Packit f0b94e
  nsresult InitBasic();
Packit f0b94e
  nsresult InitCommon(SelectionType aSelectionType = SelectionType::eNormal);
Packit f0b94e
  /**
Packit f0b94e
   * InitRootContent() computes the root content of current focused editor.
Packit f0b94e
   *
Packit f0b94e
   * @param aNormalSelection    This must be a Selection instance whose type is
Packit f0b94e
   *                            SelectionType::eNormal.
Packit f0b94e
   */
Packit f0b94e
  nsresult InitRootContent(Selection* aNormalSelection);
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  // FlatText means the text that is generated from DOM tree. The BR elements
Packit f0b94e
  // are replaced to native linefeeds. Other elements are ignored.
Packit f0b94e
Packit f0b94e
  // NodePosition stores a pair of node and offset in the node.
Packit f0b94e
  // When mNode is an element and mOffset is 0, the start position means after
Packit f0b94e
  // the open tag of mNode.
Packit f0b94e
  // This is useful to receive one or more sets of them instead of nsRange.
Packit f0b94e
  // This type is intended to be used for short-lived operations, and is thus
Packit f0b94e
  // marked MOZ_STACK_CLASS.
Packit f0b94e
  struct MOZ_STACK_CLASS NodePosition : public RangeBoundary {
Packit f0b94e
    // Only when mNode is an element node and mOffset is 0, mAfterOpenTag is
Packit f0b94e
    // referred.
Packit f0b94e
    bool mAfterOpenTag = true;
Packit f0b94e
Packit f0b94e
    NodePosition() : RangeBoundary() {}
Packit f0b94e
Packit f0b94e
    NodePosition(nsINode* aContainer, int32_t aOffset)
Packit f0b94e
        : RangeBoundary(aContainer, aOffset) {}
Packit f0b94e
Packit f0b94e
    NodePosition(nsINode* aContainer, nsIContent* aRef)
Packit f0b94e
        : RangeBoundary(aContainer, aRef) {}
Packit f0b94e
Packit f0b94e
    explicit NodePosition(const nsIFrame::ContentOffsets& aContentOffsets)
Packit f0b94e
        : RangeBoundary(aContentOffsets.content, aContentOffsets.offset) {}
Packit f0b94e
Packit f0b94e
   public:
Packit f0b94e
    bool operator==(const NodePosition& aOther) const {
Packit f0b94e
      return RangeBoundary::operator==(aOther) &&
Packit f0b94e
             mAfterOpenTag == aOther.mAfterOpenTag;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    bool IsBeforeOpenTag() const {
Packit f0b94e
      return IsSet() && Container()->IsElement() && !Ref() && !mAfterOpenTag;
Packit f0b94e
    }
Packit f0b94e
    bool IsImmediatelyAfterOpenTag() const {
Packit f0b94e
      return IsSet() && Container()->IsElement() && !Ref() && mAfterOpenTag;
Packit f0b94e
    }
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  // NodePositionBefore isn't good name if Container() isn't an element node nor
Packit f0b94e
  // Offset() is not 0, though, when Container() is an element node and mOffset
Packit f0b94e
  // is 0, this is treated as before the open tag of Container().
Packit f0b94e
  struct NodePositionBefore final : public NodePosition {
Packit f0b94e
    NodePositionBefore(nsINode* aContainer, int32_t aOffset)
Packit f0b94e
        : NodePosition(aContainer, aOffset) {
Packit f0b94e
      mAfterOpenTag = false;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    NodePositionBefore(nsINode* aContainer, nsIContent* aRef)
Packit f0b94e
        : NodePosition(aContainer, aRef) {
Packit f0b94e
      mAfterOpenTag = false;
Packit f0b94e
    }
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  // Get the flatten text length in the range.
Packit f0b94e
  // @param aStartPosition      Start node and offset in the node of the range.
Packit f0b94e
  // @param aEndPosition        End node and offset in the node of the range.
Packit f0b94e
  // @param aRootContent        The root content of the editor or document.
Packit f0b94e
  //                            aRootContent won't cause any text including
Packit f0b94e
  //                            line breaks.
Packit f0b94e
  // @param aLength             The result of the flatten text length of the
Packit f0b94e
  //                            range.
Packit f0b94e
  // @param aLineBreakType      Whether this computes flatten text length with
Packit f0b94e
  //                            native line breakers on the platform or
Packit f0b94e
  //                            with XP line breaker (\n).
Packit f0b94e
  // @param aIsRemovingNode     Should be true only when this is called from
Packit f0b94e
  //                            nsIMutationObserver::ContentRemoved().
Packit f0b94e
  //                            When this is true, aStartPosition.mNode should
Packit f0b94e
  //                            be the root node of removing nodes and mOffset
Packit f0b94e
  //                            should be 0 and aEndPosition.mNode should be
Packit f0b94e
  //                            same as aStartPosition.mNode and mOffset should
Packit f0b94e
  //                            be number of the children of mNode.
Packit f0b94e
  static nsresult GetFlatTextLengthInRange(const NodePosition& aStartPosition,
Packit f0b94e
                                           const NodePosition& aEndPosition,
Packit f0b94e
                                           nsIContent* aRootContent,
Packit f0b94e
                                           uint32_t* aLength,
Packit f0b94e
                                           LineBreakType aLineBreakType,
Packit f0b94e
                                           bool aIsRemovingNode = false);
Packit f0b94e
  // Computes the native text length between aStartOffset and aEndOffset of
Packit f0b94e
  // aContent.  aContent must be a text node.
Packit f0b94e
  static uint32_t GetNativeTextLength(nsIContent* aContent,
Packit f0b94e
                                      uint32_t aStartOffset,
Packit f0b94e
                                      uint32_t aEndOffset);
Packit f0b94e
  // Get the native text length of aContent.  aContent must be a text node.
Packit f0b94e
  static uint32_t GetNativeTextLength(nsIContent* aContent,
Packit f0b94e
                                      uint32_t aMaxLength = UINT32_MAX);
Packit f0b94e
  // Get the native text length which is inserted before aContent.
Packit f0b94e
  // aContent should be an element.
Packit f0b94e
  static uint32_t GetNativeTextLengthBefore(nsIContent* aContent,
Packit f0b94e
                                            nsINode* aRootNode);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  // Get the text length of aContent.  aContent must be a text node.
Packit f0b94e
  static uint32_t GetTextLength(nsIContent* aContent,
Packit f0b94e
                                LineBreakType aLineBreakType,
Packit f0b94e
                                uint32_t aMaxLength = UINT32_MAX);
Packit f0b94e
  // Get the text length of a given range of a content node in
Packit f0b94e
  // the given line break type.
Packit f0b94e
  static uint32_t GetTextLengthInRange(nsIContent* aContent,
Packit f0b94e
                                       uint32_t aXPStartOffset,
Packit f0b94e
                                       uint32_t aXPEndOffset,
Packit f0b94e
                                       LineBreakType aLineBreakType);
Packit f0b94e
  // Get the contents in aContent (meaning all children of aContent) as plain
Packit f0b94e
  // text.  E.g., specifying mRootContent gets whole text in it.
Packit f0b94e
  // Note that the result is not same as .textContent.  The result is
Packit f0b94e
  // optimized for native IMEs.  For example, 
element and some block
Packit f0b94e
  // elements causes "\n" (or "\r\n"), see also ShouldBreakLineBefore().
Packit f0b94e
  nsresult GenerateFlatTextContent(nsIContent* aContent, nsString& aString,
Packit f0b94e
                                   LineBreakType aLineBreakType);
Packit f0b94e
  // Get the contents of aRange as plain text.
Packit f0b94e
  nsresult GenerateFlatTextContent(const RawRange& aRawRange, nsString& aString,
Packit f0b94e
                                   LineBreakType aLineBreakType);
Packit f0b94e
  // Get offset of start of aRange.  Note that the result includes the length
Packit f0b94e
  // of line breaker caused by the start of aContent because aRange never
Packit f0b94e
  // includes the line breaker caused by its start node.
Packit f0b94e
  nsresult GetStartOffset(const RawRange& aRawRange, uint32_t* aOffset,
Packit f0b94e
                          LineBreakType aLineBreakType);
Packit f0b94e
  // Check if we should insert a line break before aContent.
Packit f0b94e
  // This should return false only when aContent is an html element which
Packit f0b94e
  // is typically used in a paragraph like .
Packit f0b94e
  static bool ShouldBreakLineBefore(nsIContent* aContent, nsINode* aRootNode);
Packit f0b94e
  // Get the line breaker length.
Packit f0b94e
  static inline uint32_t GetBRLength(LineBreakType aLineBreakType);
Packit f0b94e
  static LineBreakType GetLineBreakType(WidgetQueryContentEvent* aEvent);
Packit f0b94e
  static LineBreakType GetLineBreakType(WidgetSelectionEvent* aEvent);
Packit f0b94e
  static LineBreakType GetLineBreakType(bool aUseNativeLineBreak);
Packit f0b94e
  // Returns focused content (including its descendant documents).
Packit f0b94e
  nsIContent* GetFocusedContent();
Packit f0b94e
  // Returns true if the content is a plugin host.
Packit f0b94e
  bool IsPlugin(nsIContent* aContent);
Packit f0b94e
  // QueryContentRect() sets the rect of aContent's frame(s) to aEvent.
Packit f0b94e
  nsresult QueryContentRect(nsIContent* aContent,
Packit f0b94e
                            WidgetQueryContentEvent* aEvent);
Packit f0b94e
  // Initialize aRawRange from the offset of FlatText and the text length.
Packit f0b94e
  // If aExpandToClusterBoundaries is true, the start offset and the end one are
Packit f0b94e
  // expanded to nearest cluster boundaries.
Packit f0b94e
  nsresult SetRawRangeFromFlatTextOffset(RawRange* aRawRange, uint32_t aOffset,
Packit f0b94e
                                         uint32_t aLength,
Packit f0b94e
                                         LineBreakType aLineBreakType,
Packit f0b94e
                                         bool aExpandToClusterBoundaries,
Packit f0b94e
                                         uint32_t* aNewOffset = nullptr,
Packit f0b94e
                                         nsIContent** aLastTextNode = nullptr);
Packit f0b94e
  // If the aCollapsedRawRange isn't in text node but next to a text node,
Packit f0b94e
  // this method modifies it in the text node.  Otherwise, not modified.
Packit f0b94e
  nsresult AdjustCollapsedRangeMaybeIntoTextNode(RawRange& aCollapsedRawRange);
Packit f0b94e
  // Convert the frame relative offset to be relative to the root frame of the
Packit f0b94e
  // root presContext (but still measured in appUnits of aFrame's presContext).
Packit f0b94e
  nsresult ConvertToRootRelativeOffset(nsIFrame* aFrame, nsRect& aRect);
Packit f0b94e
  // Expand aXPOffset to the nearest offset in cluster boundary. aForward is
Packit f0b94e
  // true, it is expanded to forward.
Packit f0b94e
  nsresult ExpandToClusterBoundary(nsIContent* aContent, bool aForward,
Packit f0b94e
                                   uint32_t* aXPOffset);
Packit f0b94e
Packit f0b94e
  typedef nsTArray<mozilla::FontRange> FontRangeArray;
Packit f0b94e
  static void AppendFontRanges(FontRangeArray& aFontRanges,
Packit f0b94e
                               nsIContent* aContent, uint32_t aBaseOffset,
Packit f0b94e
                               uint32_t aXPStartOffset, uint32_t aXPEndOffset,
Packit f0b94e
                               LineBreakType aLineBreakType);
Packit f0b94e
  nsresult GenerateFlatFontRanges(const RawRange& aRawRange,
Packit f0b94e
                                  FontRangeArray& aFontRanges,
Packit f0b94e
                                  uint32_t& aLength,
Packit f0b94e
                                  LineBreakType aLineBreakType);
Packit f0b94e
  nsresult QueryTextRectByRange(const RawRange& aRawRange,
Packit f0b94e
                                LayoutDeviceIntRect& aRect,
Packit f0b94e
                                WritingMode& aWritingMode);
Packit f0b94e
Packit f0b94e
  // Returns a node and position in the node for computing text rect.
Packit f0b94e
  NodePosition GetNodePositionHavingFlatText(const NodePosition& aNodePosition);
Packit f0b94e
  NodePosition GetNodePositionHavingFlatText(nsINode* aNode,
Packit f0b94e
                                             int32_t aNodeOffset);
Packit f0b94e
Packit f0b94e
  struct MOZ_STACK_CLASS FrameAndNodeOffset final {
Packit f0b94e
    // mFrame is safe since this can live in only stack class and
Packit f0b94e
    // ContentEventHandler doesn't modify layout after
Packit f0b94e
    // ContentEventHandler::Init() flushes pending layout.  In other words,
Packit f0b94e
    // this struct shouldn't be used before calling
Packit f0b94e
    // ContentEventHandler::Init().
Packit f0b94e
    nsIFrame* mFrame;
Packit f0b94e
    // offset in the node of mFrame
Packit f0b94e
    int32_t mOffsetInNode;
Packit f0b94e
Packit f0b94e
    FrameAndNodeOffset() : mFrame(nullptr), mOffsetInNode(-1) {}
Packit f0b94e
Packit f0b94e
    FrameAndNodeOffset(nsIFrame* aFrame, int32_t aStartOffsetInNode)
Packit f0b94e
        : mFrame(aFrame), mOffsetInNode(aStartOffsetInNode) {}
Packit f0b94e
Packit f0b94e
    nsIFrame* operator->() { return mFrame; }
Packit f0b94e
    const nsIFrame* operator->() const { return mFrame; }
Packit f0b94e
    operator nsIFrame*() { return mFrame; }
Packit f0b94e
    operator const nsIFrame*() const { return mFrame; }
Packit f0b94e
    bool IsValid() const { return mFrame && mOffsetInNode >= 0; }
Packit f0b94e
  };
Packit f0b94e
  // Get first frame after the start of the given range for computing text rect.
Packit f0b94e
  // This returns invalid FrameAndNodeOffset if there is no content which
Packit f0b94e
  // should affect to computing text rect in the range.  mOffsetInNode is start
Packit f0b94e
  // offset in the frame.
Packit f0b94e
  FrameAndNodeOffset GetFirstFrameInRangeForTextRect(const RawRange& aRawRange);
Packit f0b94e
Packit f0b94e
  // Get last frame before the end of the given range for computing text rect.
Packit f0b94e
  // This returns invalid FrameAndNodeOffset if there is no content which
Packit f0b94e
  // should affect to computing text rect in the range.  mOffsetInNode is end
Packit f0b94e
  // offset in the frame.
Packit f0b94e
  FrameAndNodeOffset GetLastFrameInRangeForTextRect(const RawRange& aRawRange);
Packit f0b94e
Packit f0b94e
  struct MOZ_STACK_CLASS FrameRelativeRect final {
Packit f0b94e
    // mRect is relative to the mBaseFrame's position.
Packit f0b94e
    nsRect mRect;
Packit f0b94e
    nsIFrame* mBaseFrame;
Packit f0b94e
Packit f0b94e
    FrameRelativeRect() : mBaseFrame(nullptr) {}
Packit f0b94e
Packit f0b94e
    explicit FrameRelativeRect(nsIFrame* aBaseFrame) : mBaseFrame(aBaseFrame) {}
Packit f0b94e
Packit f0b94e
    FrameRelativeRect(const nsRect& aRect, nsIFrame* aBaseFrame)
Packit f0b94e
        : mRect(aRect), mBaseFrame(aBaseFrame) {}
Packit f0b94e
Packit f0b94e
    bool IsValid() const { return mBaseFrame != nullptr; }
Packit f0b94e
Packit f0b94e
    // Returns an nsRect relative to aBaseFrame instead of mBaseFrame.
Packit f0b94e
    nsRect RectRelativeTo(nsIFrame* aBaseFrame) const;
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  // Returns a rect for line breaker before the node of aFrame (If aFrame is
Packit f0b94e
  // a 
frame or a block level frame, it causes a line break at its
Packit f0b94e
  // element's open tag, see also ShouldBreakLineBefore()).  Note that this
Packit f0b94e
  // doesn't check if aFrame should cause line break in non-debug build.
Packit f0b94e
  FrameRelativeRect GetLineBreakerRectBefore(nsIFrame* aFrame);
Packit f0b94e
Packit f0b94e
  // Returns a line breaker rect after aTextContent as there is a line breaker
Packit f0b94e
  // immediately after aTextContent.  This is useful when following block
Packit f0b94e
  // element causes a line break before it and it needs to compute the line
Packit f0b94e
  // breaker's rect.  For example, if there is |

abc

def

|, the
Packit f0b94e
  // rect of 2nd 

's line breaker should be at right of "c" in the first

Packit f0b94e
  // 

, not the start of 2nd

. The result is relative to the last text

Packit f0b94e
  // frame which represents the last character of aTextContent.
Packit f0b94e
  FrameRelativeRect GuessLineBreakerRectAfter(nsIContent* aTextContent);
Packit f0b94e
Packit f0b94e
  // Returns a guessed first rect.  I.e., it may be different from actual
Packit f0b94e
  // caret when selection is collapsed at start of aFrame.  For example, this
Packit f0b94e
  // guess the caret rect only with the content box of aFrame and its font
Packit f0b94e
  // height like:
Packit f0b94e
  // +-aFrame----------------- (border box)
Packit f0b94e
  // |
Packit f0b94e
  // |  +--------------------- (content box)
Packit f0b94e
  // |  | I
Packit f0b94e
  //      ^ guessed caret rect
Packit f0b94e
  // However, actual caret is computed with more information like line-height,
Packit f0b94e
  // child frames of aFrame etc.  But this does not emulate actual caret
Packit f0b94e
  // behavior exactly for simpler and faster code because it's difficult and
Packit f0b94e
  // we're not sure it's worthwhile to do it with complicated implementation.
Packit f0b94e
  FrameRelativeRect GuessFirstCaretRectIn(nsIFrame* aFrame);
Packit f0b94e
Packit f0b94e
  // Make aRect non-empty.  If width and/or height is 0, these methods set them
Packit f0b94e
  // to 1.  Note that it doesn't set nsRect's width nor height to one device
Packit f0b94e
  // pixel because using nsRect::ToOutsidePixels() makes actual width or height
Packit f0b94e
  // to 2 pixels because x and y may not be aligned to device pixels.
Packit f0b94e
  void EnsureNonEmptyRect(nsRect& aRect) const;
Packit f0b94e
  void EnsureNonEmptyRect(LayoutDeviceIntRect& aRect) const;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif  // mozilla_ContentEventHandler_h_