зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1153322 - Implement Document.scrollingElement, r=bz
--HG-- extra : rebase_source : 733ede0178b80b518e488bf9768e57498080f0b2
This commit is contained in:
Родитель
94dd6e702f
Коммит
baf69da299
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
#include "nsDocument.h"
|
||||
|
||||
#include "nsIDocumentInlines.h"
|
||||
#include "mozilla/AnimationComparator.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
|
@ -10731,6 +10731,54 @@ nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsPotentiallyScrollable(HTMLBodyElement* aBody)
|
||||
{
|
||||
// An element is potentially scrollable if all of the following conditions are
|
||||
// true:
|
||||
|
||||
// The element has an associated CSS layout box.
|
||||
nsIFrame* bodyFrame = aBody->GetPrimaryFrame();
|
||||
if (!bodyFrame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The element is not the HTML body element, or it is and the root element's
|
||||
// used value of the overflow-x or overflow-y properties is not visible.
|
||||
MOZ_ASSERT(aBody->GetParent() == aBody->OwnerDoc()->GetRootElement());
|
||||
nsIFrame* parentFrame = aBody->GetParent()->GetPrimaryFrame();
|
||||
if (parentFrame &&
|
||||
parentFrame->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE &&
|
||||
parentFrame->StyleDisplay()->mOverflowY == NS_STYLE_OVERFLOW_VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The element's used value of the overflow-x or overflow-y properties is not
|
||||
// visible.
|
||||
if (bodyFrame->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE &&
|
||||
bodyFrame->StyleDisplay()->mOverflowY == NS_STYLE_OVERFLOW_VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsIDocument::GetScrollingElement()
|
||||
{
|
||||
if (GetCompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
HTMLBodyElement* body = GetBodyElement();
|
||||
if (body && !IsPotentiallyScrollable(body)) {
|
||||
return body;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetRootElement();
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::ObsoleteSheet(nsIURI *aSheetURI, ErrorResult& rv)
|
||||
{
|
||||
|
|
|
@ -2544,6 +2544,8 @@ public:
|
|||
already_AddRefed<nsDOMCaretPosition>
|
||||
CaretPositionFromPoint(float aX, float aY);
|
||||
|
||||
Element* GetScrollingElement();
|
||||
|
||||
// QuerySelector and QuerySelectorAll already defined on nsINode
|
||||
nsINodeList* GetAnonymousNodes(Element& aElement);
|
||||
Element* GetAnonymousElementByAttribute(Element& aElement,
|
||||
|
|
|
@ -280,6 +280,9 @@ partial interface Document {
|
|||
Element? elementFromPoint (float x, float y);
|
||||
|
||||
CaretPosition? caretPositionFromPoint (float x, float y);
|
||||
|
||||
[Pref="dom.document.scrollingElement.enabled"]
|
||||
readonly attribute Element? scrollingElement;
|
||||
};
|
||||
|
||||
// http://dvcs.w3.org/hg/undomanager/raw-file/tip/undomanager.html
|
||||
|
|
|
@ -206,6 +206,12 @@ pref("dom.url.getters_decode_hash", false);
|
|||
// significantly increase the number of compartments in the system.
|
||||
pref("dom.compartment_per_addon", true);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("dom.document.scrollingElement.enabled", true);
|
||||
#else
|
||||
pref("dom.document.scrollingElement.enabled", false);
|
||||
#endif
|
||||
|
||||
// Fastback caching - if this pref is negative, then we calculate the number
|
||||
// of content viewers to cache based on the amount of available memory.
|
||||
pref("browser.sessionhistory.max_total_viewers", -1);
|
||||
|
|
|
@ -33330,6 +33330,12 @@
|
|||
"deleted": [],
|
||||
"items": {
|
||||
"testharness": {
|
||||
"cssom-view/scrollingElement.html": [
|
||||
{
|
||||
"path": "cssom-view/scrollingElement.html",
|
||||
"url": "/cssom-view/scrollingElement.html"
|
||||
}
|
||||
],
|
||||
"html/semantics/embedded-content/the-embed-element/embed-document.html": [
|
||||
{
|
||||
"path": "html/semantics/embedded-content/the-embed-element/embed-document.html",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[scrollingElement.html]
|
||||
type: testharness
|
||||
prefs: [dom.document.scrollingElement.enabled:true]
|
|
@ -0,0 +1,97 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>cssom-view - scrollingElement</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<iframe id="quirksframe"></iframe>
|
||||
<iframe id="nonquirksframe"></iframe>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
var quirksFrame;
|
||||
var nonQuirksFrame;
|
||||
|
||||
function loadTestFrames(callback) {
|
||||
quirksFrame = document.getElementById("quirksframe");
|
||||
quirksFrame.onload = function() {
|
||||
nonQuirksFrame = document.getElementById("nonquirksframe");
|
||||
nonQuirksFrame.onload = callback;
|
||||
nonQuirksFrame.src =
|
||||
URL.createObjectURL(new Blob(["<!doctype html>"], { type: "text/html" }));
|
||||
}
|
||||
quirksFrame.src =
|
||||
URL.createObjectURL(new Blob([""], { type: "text/html" }));
|
||||
}
|
||||
|
||||
var test = async_test("Tests for scrollingElement");
|
||||
loadTestFrames(function() {
|
||||
test.step(function() {
|
||||
var quirksDoc = quirksFrame.contentDocument;
|
||||
var nonQuirksDoc = nonQuirksFrame.contentDocument;
|
||||
|
||||
// Initial checks that we have the expected kinds of documents.
|
||||
assert_equals(quirksDoc.compatMode, "BackCompat", "Should be in quirks mode.");
|
||||
assert_equals(nonQuirksDoc.compatMode, "CSS1Compat", "Should be in standards mode.");
|
||||
|
||||
assert_not_equals(quirksDoc.body, null, "Should have a body element");
|
||||
assert_not_equals(nonQuirksDoc.body, null, "Should have a body element");
|
||||
|
||||
// Tests for quirks mode document.
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body,
|
||||
"scrollingElement in quirks mode should default to body element.");
|
||||
|
||||
quirksDoc.documentElement.style.overflow = "scroll";
|
||||
quirksDoc.body.style.overflow = "scroll";
|
||||
assert_equals(quirksDoc.scrollingElement, null,
|
||||
"scrollingElement in quirks mode should be null if overflow of body and root element isn't visible.");
|
||||
quirksDoc.documentElement.style.overflow = "visible";
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body);
|
||||
quirksDoc.documentElement.style.overflow = "scroll";
|
||||
quirksDoc.body.style.overflow = "visible";
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body);
|
||||
quirksDoc.documentElement.style.overflow = "visible";
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body);
|
||||
|
||||
quirksDoc.body.style.display = "none";
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body)
|
||||
quirksDoc.body.style.display = "block";
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body);
|
||||
|
||||
quirksDoc.documentElement.appendChild(quirksDoc.createElement("body"));
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body);
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.getElementsByTagName("body")[0]);
|
||||
quirksDoc.documentElement.removeChild(quirksDoc.documentElement.lastChild);
|
||||
assert_equals(quirksDoc.scrollingElement, quirksDoc.body);
|
||||
|
||||
quirksDoc.documentElement.removeChild(quirksDoc.body);
|
||||
assert_equals(quirksDoc.scrollingElement, null);
|
||||
quirksDoc.documentElement.appendChild(quirksDoc.createElementNS("foobarNS", "body"));
|
||||
assert_equals(quirksDoc.scrollingElement, null);
|
||||
|
||||
quirksDoc.removeChild(quirksDoc.documentElement);
|
||||
assert_equals(quirksDoc.scrollingElement, null);
|
||||
|
||||
quirksDoc.appendChild(quirksDoc.createElementNS("foobarNS", "html"));
|
||||
quirksDoc.documentElement.appendChild(quirksDoc.createElement("body"));
|
||||
assert_equals(quirksDoc.scrollingElement, null);
|
||||
|
||||
quirksDoc.removeChild(quirksDoc.documentElement);
|
||||
quirksDoc.appendChild(quirksDoc.createElement("body"));
|
||||
assert_equals(quirksDoc.scrollingElement, null);
|
||||
|
||||
// Tests for standards mode document.
|
||||
assert_equals(nonQuirksDoc.scrollingElement, nonQuirksDoc.documentElement,
|
||||
"scrollingElement in standards mode should be the document element.");
|
||||
nonQuirksDoc.documentElement.style.overflow = "scroll";
|
||||
nonQuirksDoc.body.style.overflow = "scroll";
|
||||
assert_equals(nonQuirksDoc.scrollingElement, nonQuirksDoc.documentElement);
|
||||
|
||||
nonQuirksDoc.removeChild(nonQuirksDoc.documentElement);
|
||||
assert_equals(nonQuirksDoc.scrollingElement, null);
|
||||
nonQuirksDoc.appendChild(nonQuirksDoc.createElement("foobar"));
|
||||
assert_equals(nonQuirksDoc.scrollingElement.localName, "foobar");
|
||||
|
||||
});
|
||||
test.done();
|
||||
});
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче