Bug 1246290 - Add a disableapz HTML attribute that allows disabling APZ on specific scrollframes in chrome documents. r?botond,ehsan
MozReview-Commit-ID: TQ6efi14z4
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -6363,16 +6363,23 @@ nsContentUtils::IsUserFocusIgnored(nsINo
bool
nsContentUtils::HasScrollgrab(nsIContent* aContent)
{
nsGenericHTMLElement* element = nsGenericHTMLElement::FromContentOrNull(aContent);
return element && element->Scrollgrab();
}
+bool
+nsContentUtils::HasDisableApz(nsIContent* aContent)
+{
+ nsGenericHTMLElement* element = nsGenericHTMLElement::FromContentOrNull(aContent);
+ return element && element->Disableapz();
+}
+
void
nsContentUtils::FlushLayoutForTree(nsPIDOMWindowOuter* aWindow)
{
if (!aWindow) {
return;
}
// Note that because FlushPendingNotifications flushes parents, this
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2106,16 +2106,22 @@ public:
/**
* Returns if aContent has the 'scrollgrab' property.
* aContent may be null (in this case false is returned).
*/
static bool HasScrollgrab(nsIContent* aContent);
/**
+ * Returns true if aContent is a non-null HTML element and has the
+ * 'disableapz' property. Returns false otherwise.
+ */
+ static bool HasDisableApz(nsIContent* aContent);
+
+ /**
* Flushes the layout tree (recursively)
*
* @param aWindow the window the flush should start at
*
*/
static void FlushLayoutForTree(nsPIDOMWindowOuter* aWindow);
/**
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1763,16 +1763,23 @@ nsGenericHTMLElement::GetURIAttr(nsIAtom
nsGenericHTMLElement::IsScrollGrabAllowed(JSContext*, JSObject*)
{
// Only allow scroll grabbing in chrome and certified apps.
nsIPrincipal* prin = nsContentUtils::SubjectPrincipal();
return nsContentUtils::IsSystemPrincipal(prin) ||
prin->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED;
}
+/* static */ bool
+nsGenericHTMLElement::IsDisablingApzAllowed(JSContext*, JSObject*)
+{
+ // Only allow this in chrome code.
+ return nsContentUtils::IsSystemPrincipal(nsContentUtils::SubjectPrincipal());
+}
+
nsresult
nsGenericHTMLElement::GetURIListAttr(nsIAtom* aAttr, nsAString& aResult)
{
aResult.Truncate();
nsAutoString value;
if (!GetAttr(kNameSpaceID_None, aAttr, value))
return NS_OK;
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -48,18 +48,19 @@ typedef nsMappedAttributeElement nsGener
/**
* A common superclass for HTML elements
*/
class nsGenericHTMLElement : public nsGenericHTMLElementBase,
public nsIDOMHTMLElement
{
public:
explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
- : nsGenericHTMLElementBase(aNodeInfo),
- mScrollgrab(false)
+ : nsGenericHTMLElementBase(aNodeInfo)
+ , mScrollgrab(false)
+ , mDisableApz(false)
{
NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
"Unexpected namespace");
AddStatesSilently(NS_EVENT_STATE_LTR);
SetFlags(NODE_HAS_DIRECTION_LTR);
}
NS_DECL_ISUPPORTS_INHERITED
@@ -235,16 +236,24 @@ public:
bool Scrollgrab() const
{
return mScrollgrab;
}
void SetScrollgrab(bool aValue)
{
mScrollgrab = aValue;
}
+ bool Disableapz() const
+ {
+ return mDisableApz;
+ }
+ void SetDisableapz(bool aValue)
+ {
+ mDisableApz = aValue;
+ }
void GetInnerText(mozilla::dom::DOMString& aValue, mozilla::ErrorResult& aError);
void SetInnerText(const nsAString& aValue);
/**
* Determine whether an attribute is an event (onclick, etc.)
* @param aName the attribute
* @return whether the name is an event handler name
@@ -970,16 +979,19 @@ public:
// name (which doesn't have to match the id or anything).
// HasName() is true precisely when name is nonempty.
return aElement->IsHTMLElement(nsGkAtoms::img) && aElement->HasName();
}
static bool
IsScrollGrabAllowed(JSContext*, JSObject*);
+ static bool
+ IsDisablingApzAllowed(JSContext*, JSObject*);
+
protected:
/**
* Add/remove this element to the documents name cache
*/
void AddToNameTable(nsIAtom* aName) {
NS_ASSERTION(HasName(), "Node doesn't have name?");
nsIDocument* doc = GetCurrentDoc();
if (doc && !IsInAnonymousSubtree()) {
@@ -1240,16 +1252,17 @@ protected:
bool IsEditableRoot() const;
nsresult SetUndoScopeInternal(bool aUndoScope);
private:
void ChangeEditableState(int32_t aChange);
bool mScrollgrab;
+ bool mDisableApz;
};
namespace mozilla {
namespace dom {
class HTMLFieldSetElement;
} // namespace dom
} // namespace mozilla
--- a/dom/webidl/HTMLElement.webidl
+++ b/dom/webidl/HTMLElement.webidl
@@ -96,16 +96,24 @@ partial interface HTMLElement {
// Extension for scroll-grabbing, used in the B2G dynamic toolbar.
// This is likely to be revised.
partial interface HTMLElement {
[Func="nsGenericHTMLElement::IsScrollGrabAllowed"]
attribute boolean scrollgrab;
};
+// Extension for disabling APZ-scrolling in chrome code. This is
+// a temporary hack, mostly for the DevTools team until they can make
+// their CodeMirror-based tooling APZ-friendly.
+partial interface HTMLElement {
+ [Func="nsGenericHTMLElement::IsDisablingApzAllowed"]
+ attribute boolean disableapz;
+};
+
[NoInterfaceObject]
interface TouchEventHandlers {
[Func="nsGenericHTMLElement::TouchEventsEnabled"]
attribute EventHandler ontouchstart;
[Func="nsGenericHTMLElement::TouchEventsEnabled"]
attribute EventHandler ontouchend;
[Func="nsGenericHTMLElement::TouchEventsEnabled"]
attribute EventHandler ontouchmove;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1031,16 +1031,19 @@ GetDisplayPortFromMarginsData(nsIContent
result = result.MoveInsideAndClamp(expandedScrollableRect - scrollPos);
return result;
}
static bool
DisableApzForElement(nsIContent* aContent)
{
+ if (nsContentUtils::HasDisableApz(aContent)) {
+ return true;
+ }
if (gfxPrefs::APZDisableForSLEPages() && aContent) {
nsIDocument* doc = aContent->GetComposedDoc();
return (doc && doc->HasScrollLinkedEffect());
}
return false;
}
static bool