From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/events/ContentEventHandler.cpp | 3080 ++++++++++++++++++++++++++++++++++++ 1 file changed, 3080 insertions(+) create mode 100644 dom/events/ContentEventHandler.cpp (limited to 'dom/events/ContentEventHandler.cpp') diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp new file mode 100644 index 000000000..935ade23f --- /dev/null +++ b/dom/events/ContentEventHandler.cpp @@ -0,0 +1,3080 @@ +/* -*- 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/. */ + +#include "ContentEventHandler.h" +#include "mozilla/IMEStateManager.h" +#include "mozilla/TextComposition.h" +#include "mozilla/TextEvents.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/HTMLUnknownElement.h" +#include "mozilla/dom/Selection.h" +#include "nsCaret.h" +#include "nsCOMPtr.h" +#include "nsContentUtils.h" +#include "nsCopySupport.h" +#include "nsFocusManager.h" +#include "nsFontMetrics.h" +#include "nsFrameSelection.h" +#include "nsIContentIterator.h" +#include "nsIPresShell.h" +#include "nsISelection.h" +#include "nsIFrame.h" +#include "nsIObjectFrame.h" +#include "nsLayoutUtils.h" +#include "nsPresContext.h" +#include "nsQueryObject.h" +#include "nsRange.h" +#include "nsTextFragment.h" +#include "nsTextFrame.h" +#include "nsView.h" + +#include + +namespace mozilla { + +using namespace dom; +using namespace widget; + +/******************************************************************/ +/* ContentEventHandler */ +/******************************************************************/ + +// NOTE +// +// ContentEventHandler *creates* ranges as following rules: +// 1. Start of range: +// 1.1. Cases: [textNode or text[Node or textNode[ +// When text node is start of a range, start node is the text node and +// start offset is any number between 0 and the length of the text. +// 1.2. Case: [: +// When start of an element node is start of a range, start node is +// parent of the element and start offset is the element's index in the +// parent. +// 1.3. Case: [ +// When after an empty element node is start of a range, start node is +// parent of the element and start offset is the element's index in the +// parent + 1. +// 1.4. Case: [ +// When start of a non-empty element is start of a range, start node is +// the element and start offset is 0. +// 1.5. Case: [ +// When start of a range is 0 and there are no nodes causing text, +// start node is the root node and start offset is 0. +// 1.6. Case: [ +// When start of a range is out of bounds, start node is the root node +// and start offset is number of the children. +// 2. End of range: +// 2.1. Cases: ]textNode or text]Node or textNode] +// When a text node is end of a range, end node is the text node and +// end offset is any number between 0 and the length of the text. +// 2.2. Case: ] +// When before an element node (meaning before the open tag of the +// element) is end of a range, end node is previous node causing text. +// Note that this case shouldn't be handled directly. If rule 2.1 and +// 2.3 are handled correctly, the loop with nsContentIterator shouldn't +// reach the element node since the loop should've finished already at +// handling the last node which caused some text. +// 2.3. Case: ] +// When a line break is caused before a non-empty element node and it's +// end of a range, end node is the element and end offset is 0. +// (i.e., including open tag of the element) +// 2.4. Cases: ] +// When after an empty element node is end of a range, end node is +// parent of the element node and end offset is the element's index in +// the parent + 1. (i.e., including close tag of the element or empty +// element) +// 2.5. Case: ] +// When end of a range is out of bounds, end node is the root node and +// end offset is number of the children. +// +// ContentEventHandler *treats* ranges as following additional rules: +// 1. When the start node is an element node which doesn't have children, +// it includes a line break caused before itself (i.e., includes its open +// tag). For example, if start position is {
, 0 }, the line break +// caused by
should be included into the flatten text. +// 2. When the end node is an element node which doesn't have children, +// it includes the end (i.e., includes its close tag except empty element). +// Although, currently, any close tags don't cause line break, this also +// includes its open tag. For example, if end position is {
, 0 }, the +// line break caused by the
should be included into the flatten text. + +ContentEventHandler::ContentEventHandler(nsPresContext* aPresContext) + : mPresContext(aPresContext) + , mPresShell(aPresContext->GetPresShell()) + , mSelection(nullptr) + , mFirstSelectedRange(nullptr) + , mRootContent(nullptr) +{ +} + +nsresult +ContentEventHandler::InitBasic() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); + + // If text frame which has overflowing selection underline is dirty, + // we need to flush the pending reflow here. + mPresShell->FlushPendingNotifications(Flush_Layout); + + // Flushing notifications can cause mPresShell to be destroyed (bug 577963). + NS_ENSURE_TRUE(!mPresShell->IsDestroying(), NS_ERROR_FAILURE); + + return NS_OK; +} + +nsresult +ContentEventHandler::InitRootContent(Selection* aNormalSelection) +{ + MOZ_ASSERT(aNormalSelection); + + // Root content should be computed with normal selection because normal + // selection is typically has at least one range but the other selections + // not so. If there is a range, computing its root is easy, but if + // there are no ranges, we need to use ancestor limit instead. + MOZ_ASSERT(aNormalSelection->Type() == SelectionType::eNormal); + + if (!aNormalSelection->RangeCount()) { + // If there is no selection range, we should compute the selection root + // from ancestor limiter or root content of the document. + nsresult rv = + aNormalSelection->GetAncestorLimiter(getter_AddRefs(mRootContent)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return NS_ERROR_FAILURE; + } + if (!mRootContent) { + mRootContent = mPresShell->GetDocument()->GetRootElement(); + if (NS_WARN_IF(!mRootContent)) { + return NS_ERROR_NOT_AVAILABLE; + } + } + return NS_OK; + } + + RefPtr range(aNormalSelection->GetRangeAt(0)); + if (NS_WARN_IF(!range)) { + return NS_ERROR_UNEXPECTED; + } + + // If there is a selection, we should retrieve the selection root from + // the range since when the window is inactivated, the ancestor limiter + // of selection was cleared by blur event handler of EditorBase but the + // selection range still keeps storing the nodes. If the active element of + // the deactive window is or