Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  WhiteSpaceVisibilityKeeper.h   Sprache: C

 
/* -*- 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/. */


#ifndef WhiteSpaceVisibilityKeeper_h
#define WhiteSpaceVisibilityKeeper_h

#include "EditAction.h"
#include "EditorBase.h"
#include "EditorForwards.h"
#include "EditorDOMPoint.h"  // for EditorDOMPoint
#include "EditorUtils.h"     // for CaretPoint
#include "HTMLEditHelpers.h"
#include "HTMLEditor.h"
#include "HTMLEditUtils.h"
#include "WSRunScanner.h"

#include "mozilla/Assertions.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLBRElement.h"
#include "mozilla/dom/Text.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"

namespace mozilla {

/**
 * WhiteSpaceVisibilityKeeper class helps `HTMLEditor` modifying the DOM tree
 * with keeps white-space sequence visibility automatically.  E.g., invisible
 * leading/trailing white-spaces becomes visible, this class members delete
 * them.  E.g., when splitting visible-white-space sequence, this class may
 * replace ASCII white-spaces at split edges with NBSPs.
 */

class WhiteSpaceVisibilityKeeper final {
 private:
  using AutoTransactionsConserveSelection =
      EditorBase::AutoTransactionsConserveSelection;
  using EditorType = EditorBase::EditorType;
  using Element = dom::Element;
  using HTMLBRElement = dom::HTMLBRElement;
  using IgnoreNonEditableNodes = WSRunScanner::IgnoreNonEditableNodes;
  using InsertTextTo = EditorBase::InsertTextTo;
  using LineBreakType = HTMLEditor::LineBreakType;
  using PointPosition = WSRunScanner::PointPosition;
  using Scan = WSRunScanner::Scan;
  using TextFragmentData = WSRunScanner::TextFragmentData;
  using VisibleWhiteSpacesData = WSRunScanner::VisibleWhiteSpacesData;

 public:
  WhiteSpaceVisibilityKeeper() = delete;
  explicit WhiteSpaceVisibilityKeeper(
      const WhiteSpaceVisibilityKeeper& aOther) = delete;
  WhiteSpaceVisibilityKeeper(WhiteSpaceVisibilityKeeper&& aOther) = delete;

  /**
   * Remove invisible leading white-spaces and trailing white-spaces if there
   * are around aPoint.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  DeleteInvisibleASCIIWhiteSpaces(HTMLEditor& aHTMLEditor,
                                  const EditorDOMPoint& aPoint);

  /**
   * Fix up white-spaces before aStartPoint and after aEndPoint in preparation
   * for content to keep the white-spaces visibility after the range is deleted.
   * Note that the nodes and offsets are adjusted in response to any dom changes
   * we make while adjusting white-spaces.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  PrepareToDeleteRangeAndTrackPoints(HTMLEditor& aHTMLEditor,
                                     EditorDOMPoint* aStartPoint,
                                     EditorDOMPoint* aEndPoint,
                                     const Element& aEditingHost) {
    MOZ_ASSERT(aStartPoint->IsSetAndValid());
    MOZ_ASSERT(aEndPoint->IsSetAndValid());
    AutoTrackDOMPoint trackerStart(aHTMLEditor.RangeUpdaterRef(), aStartPoint);
    AutoTrackDOMPoint trackerEnd(aHTMLEditor.RangeUpdaterRef(), aEndPoint);
    Result<CaretPoint, nsresult> caretPointOrError =
        WhiteSpaceVisibilityKeeper::PrepareToDeleteRange(
            aHTMLEditor, EditorDOMRange(*aStartPoint, *aEndPoint),
            aEditingHost);
    NS_WARNING_ASSERTION(
        caretPointOrError.isOk(),
        "WhiteSpaceVisibilityKeeper::PrepareToDeleteRange() failed");
    return caretPointOrError;
  }
  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  PrepareToDeleteRange(HTMLEditor& aHTMLEditor,
                       const EditorDOMPoint& aStartPoint,
                       const EditorDOMPoint& aEndPoint,
                       const Element& aEditingHost) {
    MOZ_ASSERT(aStartPoint.IsSetAndValid());
    MOZ_ASSERT(aEndPoint.IsSetAndValid());
    Result<CaretPoint, nsresult> caretPointOrError =
        WhiteSpaceVisibilityKeeper::PrepareToDeleteRange(
            aHTMLEditor, EditorDOMRange(aStartPoint, aEndPoint), aEditingHost);
    NS_WARNING_ASSERTION(
        caretPointOrError.isOk(),
        "WhiteSpaceVisibilityKeeper::PrepareToDeleteRange() failed");
    return caretPointOrError;
  }
  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  PrepareToDeleteRange(HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange,
                       const Element& aEditingHost) {
    MOZ_ASSERT(aRange.IsPositionedAndValid());
    Result<CaretPoint, nsresult> caretPointOrError =
        WhiteSpaceVisibilityKeeper::
            MakeSureToKeepVisibleStateOfWhiteSpacesAroundDeletingRange(
                aHTMLEditor, aRange, aEditingHost);
    NS_WARNING_ASSERTION(
        caretPointOrError.isOk(),
        "WhiteSpaceVisibilityKeeper::"
        "MakeSureToKeepVisibleStateOfWhiteSpacesAroundDeletingRange() failed");
    return caretPointOrError;
  }

  /**
   * PrepareToSplitBlockElement() makes sure that the invisible white-spaces
   * not to become visible and returns splittable point.
   *
   * @param aHTMLEditor         The HTML editor.
   * @param aPointToSplit       The splitting point in aSplittingBlockElement.
   * @param aSplittingBlockElement  A block element which will be split.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<EditorDOMPoint, nsresult>
  PrepareToSplitBlockElement(HTMLEditor& aHTMLEditor,
                             const EditorDOMPoint& aPointToSplit,
                             const Element& aSplittingBlockElement);

  /**
   * MergeFirstLineOfRightBlockElementIntoDescendantLeftBlockElement() merges
   * first line in aRightBlockElement into end of aLeftBlockElement which
   * is a descendant of aRightBlockElement.
   *
   * @param aHTMLEditor         The HTML editor.
   * @param aLeftBlockElement   The content will be merged into end of
   *                            this element.
   * @param aRightBlockElement  The first line in this element will be
   *                            moved to aLeftBlockElement.
   * @param aAtRightBlockChild  At a child of aRightBlockElement and inclusive
   *                            ancestor of aLeftBlockElement.
   * @param aListElementTagName Set some if aRightBlockElement is a list
   *                            element and it'll be merged with another
   *                            list element.
   * @param aEditingHost        The editing host.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<MoveNodeResult, nsresult>
  MergeFirstLineOfRightBlockElementIntoDescendantLeftBlockElement(
      HTMLEditor& aHTMLEditor, Element& aLeftBlockElement,
      Element& aRightBlockElement, const EditorDOMPoint& aAtRightBlockChild,
      const Maybe<nsAtom*>& aListElementTagName,
      const HTMLBRElement* aPrecedingInvisibleBRElement,
      const Element& aEditingHost);

  /**
   * MergeFirstLineOfRightBlockElementIntoAncestorLeftBlockElement() merges
   * first line in aRightBlockElement into end of aLeftBlockElement which
   * is an ancestor of aRightBlockElement, then, removes aRightBlockElement
   * if it becomes empty.
   *
   * @param aHTMLEditor         The HTML editor.
   * @param aLeftBlockElement   The content will be merged into end of
   *                            this element.
   * @param aRightBlockElement  The first line in this element will be
   *                            moved to aLeftBlockElement and maybe
   *                            removed when this becomes empty.
   * @param aAtLeftBlockChild   At a child of aLeftBlockElement and inclusive
   *                            ancestor of aRightBlockElement.
   * @param aLeftContentInBlock The content whose inclusive ancestor is
   *                            aLeftBlockElement.
   * @param aListElementTagName Set some if aRightBlockElement is a list
   *                            element and it'll be merged with another
   *                            list element.
   * @param aEditingHost        The editing host.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<MoveNodeResult, nsresult>
  MergeFirstLineOfRightBlockElementIntoAncestorLeftBlockElement(
      HTMLEditor& aHTMLEditor, Element& aLeftBlockElement,
      Element& aRightBlockElement, const EditorDOMPoint& aAtLeftBlockChild,
      nsIContent& aLeftContentInBlock,
      const Maybe<nsAtom*>& aListElementTagName,
      const HTMLBRElement* aPrecedingInvisibleBRElement,
      const Element& aEditingHost);

  /**
   * MergeFirstLineOfRightBlockElementIntoLeftBlockElement() merges first
   * line in aRightBlockElement into end of aLeftBlockElement and removes
   * aRightBlockElement when it has only one line.
   *
   * @param aHTMLEditor         The HTML editor.
   * @param aLeftBlockElement   The content will be merged into end of
   *                            this element.
   * @param aRightBlockElement  The first line in this element will be
   *                            moved to aLeftBlockElement and maybe
   *                            removed when this becomes empty.
   * @param aListElementTagName Set some if aRightBlockElement is a list
   *                            element and its type needs to be changed.
   * @param aEditingHost        The editing host.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<MoveNodeResult, nsresult>
  MergeFirstLineOfRightBlockElementIntoLeftBlockElement(
      HTMLEditor& aHTMLEditor, Element& aLeftBlockElement,
      Element& aRightBlockElement, const Maybe<nsAtom*>& aListElementTagName,
      const HTMLBRElement* aPrecedingInvisibleBRElement,
      const Element& aEditingHost);

  /**
   * InsertLineBreak() inserts a line break at (before) aPointToInsert and
   * delete unnecessary white-spaces around there and/or replaces white-spaces
   * with non-breaking spaces.  Note that if the point is in a text node, the
   * text node will be split and insert new <br> node between the left node
   * and the right node.
   *
   * @param aPointToInsert  The point to insert new line break.  Note that
   *                        it'll be inserted before this point.  I.e., the
   *                        point will be the point of new line break.
   * @return                If succeeded, returns the new line break and
   *                        point to put caret.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CreateLineBreakResult,
                                                 nsresult>
  InsertLineBreak(LineBreakType aLineBreakType, HTMLEditor& aHTMLEditor,
                  const EditorDOMPoint& aPointToInsert);

  /**
   * Insert aStringToInsert to aPointToInsert and makes any needed adjustments
   * to white-spaces around the insertion point.
   *
   * @param aStringToInsert     The string to insert.
   * @param aRangeToBeReplaced  The range to be replaced.
   * @param aInsertTextTo       Whether forcibly creates a new `Text` node in
   *                            specific condition or use existing `Text` if
   *                            available.
   */

  template <typename EditorDOMPointType>
  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<InsertTextResult, nsresult>
  InsertText(HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert,
             const EditorDOMPointType& aPointToInsert,
             InsertTextTo aInsertTextTo) {
    return WhiteSpaceVisibilityKeeper::ReplaceText(
        aHTMLEditor, aStringToInsert, EditorDOMRange(aPointToInsert),
        aInsertTextTo);
  }

  /**
   * Replace aRangeToReplace with aStringToInsert and makes any needed
   * adjustments to white-spaces around both start of the range and end of the
   * range.
   *
   * @param aStringToInsert     The string to insert.
   * @param aRangeToBeReplaced  The range to be replaced.
   * @param aInsertTextTo       Whether forcibly creates a new `Text` node in
   *                            specific condition or use existing `Text` if
   *                            available.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<InsertTextResult, nsresult>
  ReplaceText(HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert,
              const EditorDOMRange& aRangeToBeReplaced,
              InsertTextTo aInsertTextTo);

  /**
   * Delete previous white-space of aPoint.  This automatically keeps visibility
   * of white-spaces around aPoint. E.g., may remove invisible leading
   * white-spaces.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  DeletePreviousWhiteSpace(HTMLEditor& aHTMLEditor,
                           const EditorDOMPoint& aPoint,
                           const Element& aEditingHost);

  /**
   * Delete inclusive next white-space of aPoint.  This automatically keeps
   * visiblity of white-spaces around aPoint. E.g., may remove invisible
   * trailing white-spaces.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  DeleteInclusiveNextWhiteSpace(HTMLEditor& aHTMLEditor,
                                const EditorDOMPoint& aPoint,
                                const Element& aEditingHost);

  /**
   * Delete aContentToDelete and may remove/replace white-spaces around it.
   * Then, if deleting content makes 2 text nodes around it are adjacent
   * siblings, this joins them and put selection at the joined point.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  DeleteContentNodeAndJoinTextNodesAroundIt(HTMLEditor& aHTMLEditor,
                                            nsIContent& aContentToDelete,
                                            const EditorDOMPoint& aCaretPoint,
                                            const Element& aEditingHost);

  /**
   * Try to normalize visible white-space sequence around aPoint.
   * This may collapse `Selection` after replaced text.  Therefore, the callers
   * of this need to restore `Selection` by themselves (this does not do it for
   * performance reason of multiple calls).
   */

  template <typename EditorDOMPointType>
  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
  NormalizeVisibleWhiteSpacesAt(HTMLEditor& aHTMLEditor,
                                const EditorDOMPointType& aPoint,
                                const Element& aEditingHost);

 private:
  /**
   * Maybe delete invisible white-spaces for keeping make them invisible and/or
   * may replace ASCII white-spaces with NBSPs for making visible white-spaces
   * to keep visible.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CaretPoint, nsresult>
  MakeSureToKeepVisibleStateOfWhiteSpacesAroundDeletingRange(
      HTMLEditor& aHTMLEditor, const EditorDOMRange& aRangeToDelete,
      const Element& aEditingHost);

  /**
   * MakeSureToKeepVisibleWhiteSpacesVisibleAfterSplit() replaces ASCII white-
   * spaces which becomes invisible after split with NBSPs.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
  MakeSureToKeepVisibleWhiteSpacesVisibleAfterSplit(
      HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToSplit);

  /**
   * ReplaceTextAndRemoveEmptyTextNodes() replaces the range between
   * aRangeToReplace with aReplaceString simply.  Additionally, removes
   * empty text nodes in the range.
   *
   * @param aRangeToReplace     Range to replace text.
   * @param aReplaceString      The new string.  Empty string is allowed.
   */

  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
  ReplaceTextAndRemoveEmptyTextNodes(
      HTMLEditor& aHTMLEditor, const EditorDOMRangeInTexts& aRangeToReplace,
      const nsAString& aReplaceString);
};

}  // namespace mozilla

#endif  // #ifndef WhiteSpaceVisibilityKeeper_h

Messung V0.5
C=94 H=100 G=96

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge