mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1110039 - Part 2.2 - Add AccessibleCaret. r=roc
See AccessibleCaret.h for the class description. Technical difference between AccessibleCaret and Touch/SelectionCarets: The anonymous dom element containing a caret image will be created by AccessibleCaret by using the API landed in bug 1020244 instead of being created by nsCanvasFrame.
This commit is contained in:
parent
7116f8917d
commit
206548e5fb
269
layout/base/AccessibleCaret.cpp
Normal file
269
layout/base/AccessibleCaret.cpp
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/* -*- 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 "AccessibleCaret.h"
|
||||||
|
|
||||||
|
#include "AccessibleCaretLogger.h"
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "nsCanvasFrame.h"
|
||||||
|
#include "nsCaret.h"
|
||||||
|
#include "nsDOMTokenList.h"
|
||||||
|
#include "nsIFrame.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
using namespace dom;
|
||||||
|
|
||||||
|
#undef AC_LOG
|
||||||
|
#define AC_LOG(message, ...) \
|
||||||
|
AC_LOG_BASE("AccessibleCaret (%p): " message, this, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#undef AC_LOGV
|
||||||
|
#define AC_LOGV(message, ...) \
|
||||||
|
AC_LOGV_BASE("AccessibleCaret (%p): " message, this, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(AccessibleCaret::DummyTouchListener, nsIDOMEventListener)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Implementation of AccessibleCaret methods
|
||||||
|
|
||||||
|
AccessibleCaret::AccessibleCaret(nsIPresShell* aPresShell)
|
||||||
|
: mPresShell(aPresShell)
|
||||||
|
{
|
||||||
|
// Check all resources required.
|
||||||
|
MOZ_ASSERT(mPresShell);
|
||||||
|
MOZ_ASSERT(RootFrame());
|
||||||
|
MOZ_ASSERT(mPresShell->GetDocument());
|
||||||
|
MOZ_ASSERT(mPresShell->GetCanvasFrame());
|
||||||
|
MOZ_ASSERT(mPresShell->GetCanvasFrame()->GetCustomContentContainer());
|
||||||
|
|
||||||
|
InjectCaretElement(mPresShell->GetDocument());
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessibleCaret::~AccessibleCaret()
|
||||||
|
{
|
||||||
|
RemoveCaretElement(mPresShell->GetDocument());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccessibleCaret::SetAppearance(Appearance aAppearance)
|
||||||
|
{
|
||||||
|
if (mAppearance == aAppearance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
CaretElement()->ClassList()->Remove(AppearanceString(mAppearance), rv);
|
||||||
|
MOZ_ASSERT(!rv.Failed(), "Remove old appearance failed!");
|
||||||
|
|
||||||
|
CaretElement()->ClassList()->Add(AppearanceString(aAppearance), rv);
|
||||||
|
MOZ_ASSERT(!rv.Failed(), "Add new appearance failed!");
|
||||||
|
|
||||||
|
mAppearance = aAppearance;
|
||||||
|
|
||||||
|
// Need to reset rect since the cached rect will be compared in SetPosition.
|
||||||
|
if (mAppearance == Appearance::None) {
|
||||||
|
mImaginaryCaretRect = nsRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccessibleCaret::SetSelectionBarEnabled(bool aEnabled)
|
||||||
|
{
|
||||||
|
if (mSelectionBarEnabled == aEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AC_LOG("%s, enabled %d", __FUNCTION__, aEnabled);
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
CaretElement()->ClassList()->Toggle(NS_LITERAL_STRING("no-bar"),
|
||||||
|
Optional<bool>(!aEnabled), rv);
|
||||||
|
MOZ_ASSERT(!rv.Failed());
|
||||||
|
|
||||||
|
mSelectionBarEnabled = aEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsString
|
||||||
|
AccessibleCaret::AppearanceString(Appearance aAppearance)
|
||||||
|
{
|
||||||
|
nsAutoString string;
|
||||||
|
switch (aAppearance) {
|
||||||
|
case Appearance::None:
|
||||||
|
case Appearance::NormalNotShown:
|
||||||
|
string = NS_LITERAL_STRING("none");
|
||||||
|
break;
|
||||||
|
case Appearance::Normal:
|
||||||
|
string = NS_LITERAL_STRING("normal");
|
||||||
|
break;
|
||||||
|
case Appearance::Right:
|
||||||
|
string = NS_LITERAL_STRING("right");
|
||||||
|
break;
|
||||||
|
case Appearance::Left:
|
||||||
|
string = NS_LITERAL_STRING("left");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AccessibleCaret::Intersects(const AccessibleCaret& aCaret) const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mPresShell == aCaret.mPresShell);
|
||||||
|
|
||||||
|
if (!IsVisuallyVisible() || !aCaret.IsVisuallyVisible()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect rect = nsLayoutUtils::GetRectRelativeToFrame(CaretElement(), RootFrame());
|
||||||
|
nsRect rhsRect = nsLayoutUtils::GetRectRelativeToFrame(aCaret.CaretElement(), RootFrame());
|
||||||
|
return rect.Intersects(rhsRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AccessibleCaret::Contains(const nsPoint& aPoint) const
|
||||||
|
{
|
||||||
|
if (!IsVisuallyVisible()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect rect =
|
||||||
|
nsLayoutUtils::GetRectRelativeToFrame(CaretImageElement(), RootFrame());
|
||||||
|
|
||||||
|
return rect.Contains(aPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccessibleCaret::InjectCaretElement(nsIDocument* aDocument)
|
||||||
|
{
|
||||||
|
ErrorResult rv;
|
||||||
|
nsCOMPtr<Element> element = CreateCaretElement(aDocument);
|
||||||
|
mCaretElementHolder = aDocument->InsertAnonymousContent(*element, rv);
|
||||||
|
|
||||||
|
MOZ_ASSERT(!rv.Failed(), "Insert anonymous content should not fail!");
|
||||||
|
MOZ_ASSERT(mCaretElementHolder.get(), "We must have anonymous content!");
|
||||||
|
|
||||||
|
// InsertAnonymousContent will clone the element to make an AnonymousContent.
|
||||||
|
// Since event listeners are not being cloned when cloning a node, we need to
|
||||||
|
// add the listener here.
|
||||||
|
CaretElement()->AddEventListener(NS_LITERAL_STRING("touchstart"),
|
||||||
|
mDummyTouchListener, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Element>
|
||||||
|
AccessibleCaret::CreateCaretElement(nsIDocument* aDocument) const
|
||||||
|
{
|
||||||
|
// Content structure of AccessibleCaret
|
||||||
|
// <div class="moz-accessiblecaret"> <- CaretElement()
|
||||||
|
// <div class="image"> <- CaretImageElement()
|
||||||
|
// <div class="bar"> <- SelectionBarElement()
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
nsCOMPtr<Element> parent = aDocument->CreateHTMLElement(nsGkAtoms::div);
|
||||||
|
parent->ClassList()->Add(NS_LITERAL_STRING("moz-accessiblecaret"), rv);
|
||||||
|
parent->ClassList()->Add(NS_LITERAL_STRING("none"), rv);
|
||||||
|
parent->ClassList()->Add(NS_LITERAL_STRING("no-bar"), rv);
|
||||||
|
|
||||||
|
nsCOMPtr<Element> image = aDocument->CreateHTMLElement(nsGkAtoms::div);
|
||||||
|
image->ClassList()->Add(NS_LITERAL_STRING("image"), rv);
|
||||||
|
parent->AppendChildTo(image, false);
|
||||||
|
|
||||||
|
nsCOMPtr<Element> bar = aDocument->CreateHTMLElement(nsGkAtoms::div);
|
||||||
|
bar->ClassList()->Add(NS_LITERAL_STRING("bar"), rv);
|
||||||
|
parent->AppendChildTo(bar, false);
|
||||||
|
|
||||||
|
return parent.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccessibleCaret::RemoveCaretElement(nsIDocument* aDocument)
|
||||||
|
{
|
||||||
|
CaretElement()->RemoveEventListener(NS_LITERAL_STRING("touchstart"),
|
||||||
|
mDummyTouchListener, false);
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
aDocument->RemoveAnonymousContent(*mCaretElementHolder, rv);
|
||||||
|
// It's OK rv is failed since nsCanvasFrame might not exists now.
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessibleCaret::PositionChangedResult
|
||||||
|
AccessibleCaret::SetPosition(nsIFrame* aFrame, int32_t aOffset)
|
||||||
|
{
|
||||||
|
if (!CustomContentContainerFrame()) {
|
||||||
|
return PositionChangedResult::NotChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect imaginaryCaretRectInFrame =
|
||||||
|
nsCaret::GetGeometryForFrame(aFrame, aOffset, nullptr);
|
||||||
|
|
||||||
|
imaginaryCaretRectInFrame =
|
||||||
|
nsLayoutUtils::ClampRectToScrollFrames(aFrame, imaginaryCaretRectInFrame);
|
||||||
|
|
||||||
|
if (imaginaryCaretRectInFrame.IsEmpty()) {
|
||||||
|
// Don't bother to set the caret position since it's invisible.
|
||||||
|
return PositionChangedResult::Invisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect imaginaryCaretRect = imaginaryCaretRectInFrame;
|
||||||
|
nsLayoutUtils::TransformRect(aFrame, RootFrame(), imaginaryCaretRect);
|
||||||
|
|
||||||
|
if (imaginaryCaretRect.IsEqualEdges(mImaginaryCaretRect)) {
|
||||||
|
return PositionChangedResult::NotChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
mImaginaryCaretRect = imaginaryCaretRect;
|
||||||
|
|
||||||
|
// SetCaretElementPosition() and SetSelectionBarElementPosition() require the
|
||||||
|
// input rect relative to container frame.
|
||||||
|
nsRect imaginaryCaretRectInContainerFrame = imaginaryCaretRectInFrame;
|
||||||
|
nsLayoutUtils::TransformRect(aFrame, CustomContentContainerFrame(),
|
||||||
|
imaginaryCaretRectInContainerFrame);
|
||||||
|
SetCaretElementPosition(imaginaryCaretRectInContainerFrame);
|
||||||
|
SetSelectionBarElementPosition(imaginaryCaretRectInContainerFrame);
|
||||||
|
|
||||||
|
return PositionChangedResult::Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame*
|
||||||
|
AccessibleCaret::CustomContentContainerFrame() const
|
||||||
|
{
|
||||||
|
nsCanvasFrame* canvasFrame = mPresShell->GetCanvasFrame();
|
||||||
|
Element* container = canvasFrame->GetCustomContentContainer();
|
||||||
|
nsIFrame* containerFrame = container->GetPrimaryFrame();
|
||||||
|
return containerFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccessibleCaret::SetCaretElementPosition(const nsRect& aRect)
|
||||||
|
{
|
||||||
|
nsPoint position = CaretElementPosition(aRect);
|
||||||
|
nsAutoString styleStr;
|
||||||
|
styleStr.AppendPrintf("left: %dpx; top: %dpx;",
|
||||||
|
nsPresContext::AppUnitsToIntCSSPixels(position.x),
|
||||||
|
nsPresContext::AppUnitsToIntCSSPixels(position.y));
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
CaretElement()->SetAttribute(NS_LITERAL_STRING("style"), styleStr, rv);
|
||||||
|
MOZ_ASSERT(!rv.Failed());
|
||||||
|
|
||||||
|
AC_LOG("Set caret style: %s", NS_ConvertUTF16toUTF8(styleStr).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccessibleCaret::SetSelectionBarElementPosition(const nsRect& aRect)
|
||||||
|
{
|
||||||
|
int32_t height = nsPresContext::AppUnitsToIntCSSPixels(aRect.height);
|
||||||
|
nsAutoString barStyleStr;
|
||||||
|
barStyleStr.AppendPrintf("margin-top: -%dpx; height: %dpx;",
|
||||||
|
height, height);
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
SelectionBarElement()->SetAttribute(NS_LITERAL_STRING("style"), barStyleStr, rv);
|
||||||
|
MOZ_ASSERT(!rv.Failed());
|
||||||
|
|
||||||
|
AC_LOG("Set bar style: %s", NS_ConvertUTF16toUTF8(barStyleStr).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
209
layout/base/AccessibleCaret.h
Normal file
209
layout/base/AccessibleCaret.h
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/* -*- 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 AccessibleCaret_h__
|
||||||
|
#define AccessibleCaret_h__
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/dom/AnonymousContent.h"
|
||||||
|
#include "mozilla/dom/Element.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIDOMEventListener.h"
|
||||||
|
#include "nsISupportsBase.h"
|
||||||
|
#include "nsISupportsImpl.h"
|
||||||
|
#include "nsRect.h"
|
||||||
|
#include "nsRefPtr.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
class nsIDocument;
|
||||||
|
class nsIFrame;
|
||||||
|
class nsIPresShell;
|
||||||
|
struct nsPoint;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Upon the creation of AccessibleCaret, it will insert DOM Element as an
|
||||||
|
// anonymous content containing the caret image. The caret appearance and
|
||||||
|
// position can be controlled by SetAppearance() and SetPosition().
|
||||||
|
//
|
||||||
|
// All the rect or point are relative to root frame except being specified
|
||||||
|
// explicitly.
|
||||||
|
//
|
||||||
|
// None of the methods in AccessibleCaret will flush layout or style. To ensure
|
||||||
|
// that SetPosition() works correctly, the caller must make sure the layout is
|
||||||
|
// up to date.
|
||||||
|
//
|
||||||
|
class AccessibleCaret final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit AccessibleCaret(nsIPresShell* aPresShell);
|
||||||
|
~AccessibleCaret();
|
||||||
|
|
||||||
|
// This enumeration representing the visibility and visual style of an
|
||||||
|
// AccessibleCaret.
|
||||||
|
//
|
||||||
|
// Use SetAppearance() to change the appearance, and use GetAppearance() to
|
||||||
|
// get the current appearance.
|
||||||
|
enum class Appearance : uint8_t {
|
||||||
|
// Do not display the caret at all.
|
||||||
|
None,
|
||||||
|
|
||||||
|
// Display the caret in default style.
|
||||||
|
Normal,
|
||||||
|
|
||||||
|
// The caret should be displayed logically but it is kept invisible to the
|
||||||
|
// user. This enum is the only difference between "logically visible" and
|
||||||
|
// "visually visible". It can be used for reasons such as:
|
||||||
|
// 1. Out of scroll port.
|
||||||
|
// 2. For UX requirement such as hide a caret in an empty text area.
|
||||||
|
NormalNotShown,
|
||||||
|
|
||||||
|
// Display the caret which is tilted to the left.
|
||||||
|
Left,
|
||||||
|
|
||||||
|
// Display the caret which is tilted to the right.
|
||||||
|
Right
|
||||||
|
};
|
||||||
|
|
||||||
|
Appearance GetAppearance() const
|
||||||
|
{
|
||||||
|
return mAppearance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAppearance(Appearance aAppearance);
|
||||||
|
|
||||||
|
// Return true if current appearance is either Normal, NormalNotShown, Left,
|
||||||
|
// or Right.
|
||||||
|
bool IsLogicallyVisible() const
|
||||||
|
{
|
||||||
|
return mAppearance != Appearance::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if current appearance is either Normal, Left, or Right.
|
||||||
|
bool IsVisuallyVisible() const
|
||||||
|
{
|
||||||
|
return (mAppearance != Appearance::None) &&
|
||||||
|
(mAppearance != Appearance::NormalNotShown);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set true to enable the "Text Selection Bar" described in "Text Selection
|
||||||
|
// Visual Spec" in bug 921965.
|
||||||
|
void SetSelectionBarEnabled(bool aEnabled);
|
||||||
|
|
||||||
|
// This enumeration representing the result returned by SetPosition().
|
||||||
|
enum class PositionChangedResult : uint8_t {
|
||||||
|
// Position is not changed.
|
||||||
|
NotChanged,
|
||||||
|
|
||||||
|
// Position is changed.
|
||||||
|
Changed,
|
||||||
|
|
||||||
|
// Position is out of scroll port.
|
||||||
|
Invisible
|
||||||
|
};
|
||||||
|
PositionChangedResult SetPosition(nsIFrame* aFrame, int32_t aOffset);
|
||||||
|
|
||||||
|
// Does two AccessibleCarets overlap?
|
||||||
|
bool Intersects(const AccessibleCaret& aCaret) const;
|
||||||
|
|
||||||
|
// Is the point within the caret's rect? The point should be relative to root
|
||||||
|
// frame.
|
||||||
|
bool Contains(const nsPoint& aPoint) const;
|
||||||
|
|
||||||
|
// The geometry center of the imaginary caret (nsCaret) to which this
|
||||||
|
// AccessibleCaret is attached. It is needed when dragging the caret.
|
||||||
|
nsPoint LogicalPosition() const
|
||||||
|
{
|
||||||
|
return mImaginaryCaretRect.Center();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Element for 'Intersects' test. Container of image and bar elements.
|
||||||
|
dom::Element* CaretElement() const
|
||||||
|
{
|
||||||
|
return mCaretElementHolder->GetContentNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Argument aRect should be relative to CustomContentContainerFrame().
|
||||||
|
void SetCaretElementPosition(const nsRect& aRect);
|
||||||
|
void SetSelectionBarElementPosition(const nsRect& aRect);
|
||||||
|
|
||||||
|
// Element which contains the caret image for 'Contains' test.
|
||||||
|
dom::Element* CaretImageElement() const
|
||||||
|
{
|
||||||
|
return CaretElement()->GetFirstElementChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Element which represents the text selection bar.
|
||||||
|
dom::Element* SelectionBarElement() const
|
||||||
|
{
|
||||||
|
return CaretElement()->GetLastElementChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* RootFrame() const
|
||||||
|
{
|
||||||
|
return mPresShell->GetRootFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* CustomContentContainerFrame() const;
|
||||||
|
|
||||||
|
// Transform Appearance to CSS class name in ua.css.
|
||||||
|
static nsString AppearanceString(Appearance aAppearance);
|
||||||
|
|
||||||
|
already_AddRefed<dom::Element> CreateCaretElement(nsIDocument* aDocument) const;
|
||||||
|
|
||||||
|
// Inject caret element into custom content container.
|
||||||
|
void InjectCaretElement(nsIDocument* aDocument);
|
||||||
|
|
||||||
|
// Remove caret element from custom content container.
|
||||||
|
void RemoveCaretElement(nsIDocument* aDocument);
|
||||||
|
|
||||||
|
// The bottom-center of the imaginary caret to which this AccessibleCaret is
|
||||||
|
// attached.
|
||||||
|
static nsPoint CaretElementPosition(const nsRect& aRect)
|
||||||
|
{
|
||||||
|
return aRect.TopLeft() + nsPoint(aRect.width / 2, aRect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DummyTouchListener final : public nsIDOMEventListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual ~DummyTouchListener() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member variables
|
||||||
|
Appearance mAppearance = Appearance::None;
|
||||||
|
|
||||||
|
bool mSelectionBarEnabled = false;
|
||||||
|
|
||||||
|
// AccessibleCaretManager owns us. When it's destroyed by
|
||||||
|
// AccessibleCaretEventHub::Terminate() which is called in
|
||||||
|
// PresShell::Destroy(), it frees us automatically. No need to worry we
|
||||||
|
// outlive mPresShell.
|
||||||
|
nsIPresShell* MOZ_NON_OWNING_REF const mPresShell = nullptr;
|
||||||
|
|
||||||
|
nsRefPtr<dom::AnonymousContent> mCaretElementHolder;
|
||||||
|
|
||||||
|
// mImaginaryCaretRect is relative to root frame.
|
||||||
|
nsRect mImaginaryCaretRect;
|
||||||
|
|
||||||
|
// A no-op touch-start listener which prevents APZ from panning when dragging
|
||||||
|
// the caret.
|
||||||
|
nsRefPtr<DummyTouchListener> mDummyTouchListener{new DummyTouchListener()};
|
||||||
|
|
||||||
|
}; // class AccessibleCaret
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // AccessibleCaret_h__
|
@ -314,6 +314,100 @@ parsererror|sourcetext {
|
|||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret,
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret > div.image,
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret > div.bar {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2147483647;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret {
|
||||||
|
width: 44px;
|
||||||
|
height: 47px;
|
||||||
|
margin-left: -23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret > div.image {
|
||||||
|
background-position: center center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
/* Override this property in moz-custom-content-container to make dummy touch
|
||||||
|
* listener work. */
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret > div.bar {
|
||||||
|
margin-left: 49%;
|
||||||
|
width: 2px;
|
||||||
|
background-color: #008aa0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.no-bar > div.bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.normal > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.left > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_left.png");
|
||||||
|
margin-left: -39%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.right > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_right.png");
|
||||||
|
margin-left: 41%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.none {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-resolution: 1.5dppx) {
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.normal > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret@1.5x.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.left > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_left@1.5x.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.right > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_right@1.5x.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-resolution: 2dppx) {
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.normal > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret@2x.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.left > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_left@2x.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.right > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_right@2x.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-resolution: 2.25dppx) {
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.normal > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret@2.25x.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.left > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_left@2.25x.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
div:-moz-native-anonymous.moz-accessiblecaret.right > div.image {
|
||||||
|
background-image: url("resource://gre/res/text_caret_tilt_right@2.25x.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
div:-moz-native-anonymous.moz-touchcaret,
|
div:-moz-native-anonymous.moz-touchcaret,
|
||||||
div:-moz-native-anonymous.moz-selectioncaret-left,
|
div:-moz-native-anonymous.moz-selectioncaret-left,
|
||||||
div:-moz-native-anonymous.moz-selectioncaret-right {
|
div:-moz-native-anonymous.moz-selectioncaret-right {
|
||||||
|
Loading…
Reference in New Issue
Block a user