mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 924692 - Part 1: Add touch caret rendering support; r=roc
This commit is contained in:
parent
90fde7deef
commit
a37fc5efe4
@ -671,6 +671,9 @@
|
||||
@BINPATH@/res/table-remove-row-active.gif
|
||||
@BINPATH@/res/table-remove-row-hover.gif
|
||||
@BINPATH@/res/table-remove-row.gif
|
||||
@BINPATH@/res/text_selection_handle.png
|
||||
@BINPATH@/res/text_selection_handle@1.5.png
|
||||
@BINPATH@/res/text_selection_handle@2.png
|
||||
@BINPATH@/res/grabber.gif
|
||||
#ifdef XP_MACOSX
|
||||
@BINPATH@/res/cursors/*
|
||||
|
@ -39,4 +39,7 @@ RESOURCE_FILES += [
|
||||
'res/table-remove-row-active.gif',
|
||||
'res/table-remove-row-hover.gif',
|
||||
'res/table-remove-row.gif',
|
||||
'res/text_selection_handle.png',
|
||||
'res/text_selection_handle@1.5.png',
|
||||
'res/text_selection_handle@2.png',
|
||||
]
|
||||
|
BIN
editor/composer/src/res/text_selection_handle.png
Normal file
BIN
editor/composer/src/res/text_selection_handle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
editor/composer/src/res/text_selection_handle@1.5.png
Normal file
BIN
editor/composer/src/res/text_selection_handle@1.5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
editor/composer/src/res/text_selection_handle@2.png
Normal file
BIN
editor/composer/src/res/text_selection_handle@2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
@ -29,6 +29,7 @@
|
||||
#include "nsTableCellFrame.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsPresShell.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsStyleSet.h"
|
||||
@ -2597,6 +2598,12 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
|
||||
|
||||
SetInitialSingleChild(mDocElementContainingBlock, newFrame);
|
||||
|
||||
// Create touch caret frame if there is a canvas frame
|
||||
if (mDocElementContainingBlock->GetType() == nsGkAtoms::canvasFrame) {
|
||||
ConstructAnonymousContentForCanvas(state, mDocElementContainingBlock,
|
||||
aDocElement);
|
||||
}
|
||||
|
||||
return newFrame;
|
||||
}
|
||||
|
||||
@ -2852,6 +2859,29 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSFrameConstructor::ConstructAnonymousContentForCanvas(nsFrameConstructorState& aState,
|
||||
nsIFrame* aFrame,
|
||||
nsIContent* aDocElement)
|
||||
{
|
||||
NS_ASSERTION(aFrame->GetType() == nsGkAtoms::canvasFrame, "aFrame should be canvas frame!");
|
||||
|
||||
nsAutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> anonymousItems;
|
||||
GetAnonymousContent(aDocElement, aFrame, anonymousItems);
|
||||
if (anonymousItems.IsEmpty()) {
|
||||
// Touch caret is not enabled.
|
||||
return;
|
||||
}
|
||||
|
||||
FrameConstructionItemList itemsToConstruct;
|
||||
nsContainerFrame* frameAsContainer = do_QueryFrame(aFrame);
|
||||
AddFCItemsForAnonymousContent(aState, frameAsContainer, anonymousItems, itemsToConstruct);
|
||||
|
||||
nsFrameItems frameItems;
|
||||
ConstructFramesFromItemList(aState, itemsToConstruct, frameAsContainer, frameItems);
|
||||
frameAsContainer->AppendFrames(kPrincipalList, frameItems);
|
||||
}
|
||||
|
||||
nsContainerFrame*
|
||||
nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
nsPresContext* aPresContext,
|
||||
|
@ -1769,6 +1769,10 @@ private:
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aStyleContext,
|
||||
bool aIsGeneratedContent);
|
||||
// Create touch caret frame.
|
||||
void ConstructAnonymousContentForCanvas(nsFrameConstructorState& aState,
|
||||
nsIFrame* aFrame,
|
||||
nsIContent* aDocElement);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -53,6 +53,7 @@ class nsViewManager;
|
||||
class nsView;
|
||||
class nsRenderingContext;
|
||||
class nsIPageSequenceFrame;
|
||||
class nsCanvasFrame;
|
||||
class nsAString;
|
||||
class nsCaret;
|
||||
class nsFrameSelection;
|
||||
@ -467,6 +468,12 @@ public:
|
||||
*/
|
||||
virtual nsIPageSequenceFrame* GetPageSequenceFrame() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the canvas frame associated with the frame hierarchy.
|
||||
* Returns nullptr if is XUL document.
|
||||
*/
|
||||
virtual nsCanvasFrame* GetCanvasFrame() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the real primary frame associated with the content object.
|
||||
*
|
||||
@ -735,6 +742,11 @@ public:
|
||||
*/
|
||||
virtual void NotifyDestroyingFrame(nsIFrame* aFrame) = 0;
|
||||
|
||||
/**
|
||||
* Returns the touch caret element of the presshell.
|
||||
*/
|
||||
virtual mozilla::dom::Element* GetTouchCaretElement() const = 0;
|
||||
|
||||
/**
|
||||
* Get the caret, if it exists. AddRefs it.
|
||||
*/
|
||||
|
@ -701,6 +701,18 @@ nsIPresShell::FrameSelection()
|
||||
static bool sSynthMouseMove = true;
|
||||
static uint32_t sNextPresShellId;
|
||||
static bool sPointerEventEnabled = true;
|
||||
static bool sTouchCaretEnabled = false;
|
||||
|
||||
/* static */ bool
|
||||
PresShell::TouchCaretPrefEnabled()
|
||||
{
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
Preferences::AddBoolVarCache(&sTouchCaretEnabled, "touchcaret.enabled");
|
||||
initialized = true;
|
||||
}
|
||||
return sTouchCaretEnabled;
|
||||
}
|
||||
|
||||
PresShell::PresShell()
|
||||
: mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)
|
||||
@ -2472,6 +2484,19 @@ PresShell::GetPageSequenceFrame() const
|
||||
return do_QueryFrame(frame);
|
||||
}
|
||||
|
||||
nsCanvasFrame*
|
||||
PresShell::GetCanvasFrame() const
|
||||
{
|
||||
nsIFrame* frame = mFrameConstructor->GetDocElementContainingBlock();
|
||||
return do_QueryFrame(frame);
|
||||
}
|
||||
|
||||
Element*
|
||||
PresShell::GetTouchCaretElement() const
|
||||
{
|
||||
return GetCanvasFrame() ? GetCanvasFrame()->GetTouchCaretElement() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
|
||||
{
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// Touch caret preference
|
||||
static bool TouchCaretPrefEnabled();
|
||||
|
||||
void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
|
||||
nsViewManager* aViewManager, nsStyleSet* aStyleSet,
|
||||
nsCompatibility aCompatMode);
|
||||
@ -90,6 +93,7 @@ public:
|
||||
virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight) MOZ_OVERRIDE;
|
||||
virtual nsresult ResizeReflowOverride(nscoord aWidth, nscoord aHeight) MOZ_OVERRIDE;
|
||||
virtual nsIPageSequenceFrame* GetPageSequenceFrame() const MOZ_OVERRIDE;
|
||||
virtual nsCanvasFrame* GetCanvasFrame() const MOZ_OVERRIDE;
|
||||
virtual nsIFrame* GetRealPrimaryFrameFor(nsIContent* aContent) const MOZ_OVERRIDE;
|
||||
|
||||
virtual nsIFrame* GetPlaceholderFrameFor(nsIFrame* aFrame) const MOZ_OVERRIDE;
|
||||
@ -207,6 +211,8 @@ public:
|
||||
virtual void ClearMouseCaptureOnView(nsView* aView) MOZ_OVERRIDE;
|
||||
virtual bool IsVisible() MOZ_OVERRIDE;
|
||||
|
||||
// touch caret
|
||||
virtual mozilla::dom::Element* GetTouchCaretElement() const MOZ_OVERRIDE;
|
||||
// caret handling
|
||||
virtual already_AddRefed<nsCaret> GetCaret() const MOZ_OVERRIDE;
|
||||
virtual void MaybeInvalidateCaretPosition() MOZ_OVERRIDE;
|
||||
|
@ -12,12 +12,17 @@
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsPresShell.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
// for touchcaret
|
||||
#include "nsContentList.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsStyleSet.h"
|
||||
// for focus
|
||||
#include "nsIScrollableFrame.h"
|
||||
#ifdef DEBUG_CANVAS_FOCUS
|
||||
@ -40,8 +45,53 @@ NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsCanvasFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsCanvasFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
nsresult
|
||||
nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
{
|
||||
// We won't create touch caret element if preference is not enabled.
|
||||
if (!PresShell::TouchCaretPrefEnabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = mContent->OwnerDoc();
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
|
||||
// Create and append touch caret frame.
|
||||
nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nullptr,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = NS_NewHTMLElement(getter_AddRefs(mTouchCaretElement), nodeInfo.forget(),
|
||||
mozilla::dom::NOT_FROM_PARSER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
aElements.AppendElement(mTouchCaretElement);
|
||||
|
||||
// Add a _moz_anonclass attribute as touch caret selector.
|
||||
ErrorResult er;
|
||||
mTouchCaretElement->SetAttribute(NS_LITERAL_STRING("_moz_anonclass"),
|
||||
NS_LITERAL_STRING("mozTouchCaret"), er);
|
||||
NS_ENSURE_SUCCESS(er.ErrorCode(), er.ErrorCode());
|
||||
|
||||
// Set touch caret to visibility: hidden by default.
|
||||
nsAutoString classValue;
|
||||
classValue.AppendLiteral("moz-touchcaret hidden");
|
||||
rv = mTouchCaretElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
classValue, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsCanvasFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter)
|
||||
{
|
||||
aElements.MaybeAppendElement(mTouchCaretElement);
|
||||
}
|
||||
|
||||
void
|
||||
nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
@ -51,6 +101,7 @@ nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
sf->RemoveScrollPositionListener(this);
|
||||
}
|
||||
|
||||
nsContentUtils::DestroyAnonymousContent(&mTouchCaretElement);
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
@ -98,9 +149,14 @@ nsCanvasFrame::AppendFrames(ChildListID aListID,
|
||||
nsFrameList& aFrameList)
|
||||
{
|
||||
MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
|
||||
MOZ_ASSERT(mFrames.IsEmpty(), "already have a child frame");
|
||||
MOZ_ASSERT(aFrameList.FirstChild() == aFrameList.LastChild(),
|
||||
"Only one principal child frame allowed");
|
||||
if (!mFrames.IsEmpty()) {
|
||||
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
|
||||
// We only allow native anonymous child frame for touch caret,
|
||||
// which its placeholder is added to the Principal child lists.
|
||||
MOZ_ASSERT(e.get()->GetContent()->IsInNativeAnonymousSubtree(),
|
||||
"invalid child list");
|
||||
}
|
||||
}
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
nsContainerFrame::AppendFrames(aListID, aFrameList);
|
||||
}
|
||||
@ -121,7 +177,6 @@ nsCanvasFrame::RemoveFrame(ChildListID aListID,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
|
||||
MOZ_ASSERT(aOldFrame == mFrames.FirstChild(), "unknown aOldFrame");
|
||||
nsContainerFrame::RemoveFrame(aListID, aOldFrame);
|
||||
}
|
||||
#endif
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
|
||||
class nsPresContext;
|
||||
class nsRenderingContext;
|
||||
@ -25,7 +26,8 @@ class nsRenderingContext;
|
||||
* frame
|
||||
*/
|
||||
class nsCanvasFrame : public nsContainerFrame,
|
||||
public nsIScrollPositionListener
|
||||
public nsIScrollPositionListener,
|
||||
public nsIAnonymousContentCreator
|
||||
{
|
||||
public:
|
||||
nsCanvasFrame(nsStyleContext* aContext)
|
||||
@ -64,6 +66,16 @@ public:
|
||||
~(nsIFrame::eCanContainOverflowContainers));
|
||||
}
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
|
||||
virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter) MOZ_OVERRIDE;
|
||||
|
||||
// Touch caret handle function
|
||||
mozilla::dom::Element* GetTouchCaretElement() const
|
||||
{
|
||||
return mTouchCaretElement;
|
||||
}
|
||||
|
||||
/** SetHasFocus tells the CanvasFrame to draw with focus ring
|
||||
* @param aHasFocus true to show focus ring, false to hide it
|
||||
*/
|
||||
@ -111,6 +123,8 @@ protected:
|
||||
// Data members
|
||||
bool mDoPaintFocus;
|
||||
bool mAddedScrollPositionListener;
|
||||
|
||||
nsCOMPtr<mozilla::dom::Element> mTouchCaretElement;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -283,3 +283,41 @@ parsererror|sourcetext {
|
||||
font-weight: bold;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
div[\_moz_anonclass="mozTouchCaret"].moz-touchcaret {
|
||||
background-image: url("resource://gre/res/text_selection_handle.png");
|
||||
position: absolute;
|
||||
width: 19px;
|
||||
height: 24px;
|
||||
margin-left: -10px;
|
||||
background-position: center center;
|
||||
z-index: 2147483647;
|
||||
}
|
||||
|
||||
@media (min-resolution: 1.5dppx) {
|
||||
div[\_moz_anonclass="mozTouchCaret"].moz-touchcaret {
|
||||
background-image: url("resource://gre/res/text_selection_handle@1.5.png");
|
||||
position: absolute;
|
||||
width: 29px;
|
||||
height: 36px;
|
||||
margin-left: -15px;
|
||||
background-position: center center;
|
||||
z-index: 2147483647;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
div[\_moz_anonclass="mozTouchCaret"].moz-touchcaret {
|
||||
background-image: url("resource://gre/res/text_selection_handle@2.png");
|
||||
position: absolute;
|
||||
width: 38px;
|
||||
height: 48px;
|
||||
margin-left: -19px;
|
||||
background-position: center center;
|
||||
z-index: 2147483647;
|
||||
}
|
||||
}
|
||||
|
||||
div[\_moz_anonclass="mozTouchCaret"].moz-touchcaret.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -2087,7 +2087,7 @@ pref("svg.svg-iframe.enabled", false);
|
||||
pref("svg.svg-iframe.enabled", false);
|
||||
#endif
|
||||
|
||||
// Is support for the new getBBox method from SVG 2 enabled?
|
||||
// Is support for the new getBBox method from SVG 2 enabled?
|
||||
// See https://svgwg.org/svg2-draft/single-page.html#types-SVGBoundingBoxOptions
|
||||
#ifdef RELEASE_BUILD
|
||||
pref("svg.new-getBBox.enabled", false);
|
||||
@ -4148,6 +4148,9 @@ pref("urlclassifier.disallow_completions", "test-malware-simple,test-phish-simpl
|
||||
// Turn off Spatial navigation by default.
|
||||
pref("snav.enabled", false);
|
||||
|
||||
// Turn off touch caret by default.
|
||||
pref("touchcaret.enabled", false);
|
||||
|
||||
// Wakelock is disabled by default.
|
||||
pref("dom.wakelock.enabled", false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user