зеркало из https://github.com/mozilla/gecko-dev.git
Bug 808231 - Implement add/removeNextPaintListener() methods for mozbrowsers r=jlebar a=blocking-basecamp
This commit is contained in:
Родитель
6eb7404ed3
Коммит
e72bf0686b
|
@ -58,6 +58,8 @@ function BrowserElementChild() {
|
|||
this._forcedVisible = true;
|
||||
this._ownerVisible = true;
|
||||
|
||||
this._nextPaintHandler = null;
|
||||
|
||||
this._init();
|
||||
};
|
||||
|
||||
|
@ -109,11 +111,10 @@ BrowserElementChild.prototype = {
|
|||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
this._afterPaintHandlerClosure = this._afterPaintHandler.bind(this);
|
||||
addEventListener('MozAfterPaint',
|
||||
this._afterPaintHandlerClosure,
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
// Registers a MozAfterPaint handler for the very first paint.
|
||||
this._addMozAfterPaintHandler(function () {
|
||||
sendAsyncMsg('firstpaint');
|
||||
});
|
||||
|
||||
var self = this;
|
||||
function addMsgListener(msg, handler) {
|
||||
|
@ -135,6 +136,8 @@ BrowserElementChild.prototype = {
|
|||
addMsgListener("fire-ctx-callback", this._recvFireCtxCallback);
|
||||
addMsgListener("owner-visibility-change", this._recvOwnerVisibilityChange);
|
||||
addMsgListener("exit-fullscreen", this._recvExitFullscreen.bind(this));
|
||||
addMsgListener("activate-next-paint-listener", this._activateNextPaintListener.bind(this));
|
||||
addMsgListener("deactivate-next-paint-listener", this._deactivateNextPaintListener.bind(this));
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService);
|
||||
|
@ -361,16 +364,39 @@ BrowserElementChild.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
_afterPaintHandler: function(e) {
|
||||
let uri = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
|
||||
debug("Got afterpaint event: " + uri.spec);
|
||||
if (uri.spec != "about:blank") {
|
||||
/* this._afterPaintHandlerClosure == arguments.callee, except we're in
|
||||
* strict mode so we don't have arguments.callee. */
|
||||
removeEventListener('MozAfterPaint', this._afterPaintHandlerClosure,
|
||||
/* useCapture */ true);
|
||||
_addMozAfterPaintHandler: function(callback) {
|
||||
function onMozAfterPaint() {
|
||||
let uri = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
|
||||
debug("Got afterpaint event: " + uri.spec);
|
||||
if (uri.spec != "about:blank") {
|
||||
removeEventListener('MozAfterPaint', onMozAfterPaint,
|
||||
/* useCapture = */ true);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
sendAsyncMsg('firstpaint');
|
||||
addEventListener('MozAfterPaint', onMozAfterPaint, /* useCapture = */ true);
|
||||
return onMozAfterPaint;
|
||||
},
|
||||
|
||||
_removeMozAfterPaintHandler: function(listener) {
|
||||
removeEventListener('MozAfterPaint', listener,
|
||||
/* useCapture = */ true);
|
||||
},
|
||||
|
||||
_activateNextPaintListener: function(e) {
|
||||
if (!this._nextPaintHandler) {
|
||||
this._nextPaintHandler = this._addMozAfterPaintHandler(function () {
|
||||
this._nextPaintHandler = null;
|
||||
sendAsyncMsg('nextpaint');
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
_deactivateNextPaintListener: function(e) {
|
||||
if (this._nextPaintHandler) {
|
||||
this._removeMozAfterPaintHandler(this._nextPaintHandler);
|
||||
this._nextPaintHandler = null;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
|
|||
this._domRequestCounter = 0;
|
||||
this._pendingDOMRequests = {};
|
||||
this._hasRemoteFrame = hasRemoteFrame;
|
||||
this._nextPaintListeners = [];
|
||||
|
||||
this._frameLoader = frameLoader;
|
||||
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||
|
@ -213,6 +214,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
|
|||
addMessageListener("error", this._fireEventFromMsg);
|
||||
addMessageListener("scroll", this._fireEventFromMsg);
|
||||
addMessageListener("firstpaint", this._fireEventFromMsg);
|
||||
addMessageListener("nextpaint", this._recvNextPaint);
|
||||
addMessageListener("keyevent", this._fireKeyEvent);
|
||||
addMessageListener("showmodalprompt", this._handleShowModalPrompt);
|
||||
addMessageListener('got-purge-history', this._gotDOMRequestResult);
|
||||
|
@ -257,6 +259,8 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
|
|||
defineMethod('stop', this._stop);
|
||||
defineMethod('purgeHistory', this._purgeHistory);
|
||||
defineMethod('getScreenshot', this._getScreenshot);
|
||||
defineMethod('addNextPaintListener', this._addNextPaintListener);
|
||||
defineMethod('removeNextPaintListener', this._removeNextPaintListener);
|
||||
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
||||
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
||||
|
||||
|
@ -594,6 +598,41 @@ BrowserElementParent.prototype = {
|
|||
{width: width, height: height});
|
||||
},
|
||||
|
||||
_recvNextPaint: function(data) {
|
||||
let listeners = this._nextPaintListeners;
|
||||
this._nextPaintListeners = [];
|
||||
for (let listener of listeners) {
|
||||
try {
|
||||
listener();
|
||||
} catch (e) {
|
||||
// If a listener throws we'll continue.
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_addNextPaintListener: function(listener) {
|
||||
if (typeof listener != 'function')
|
||||
throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (this._nextPaintListeners.push(listener) == 1)
|
||||
this._sendAsyncMsg('activate-next-paint-listener');
|
||||
},
|
||||
|
||||
_removeNextPaintListener: function(listener) {
|
||||
if (typeof listener != 'function')
|
||||
throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
for (let i = this._nextPaintListeners.length - 1; i >= 0; i--) {
|
||||
if (this._nextPaintListeners[i] == listener) {
|
||||
this._nextPaintListeners.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this._nextPaintListeners.length == 0)
|
||||
this._sendAsyncMsg('deactivate-next-paint-listener');
|
||||
},
|
||||
|
||||
_fireKeyEvent: function(data) {
|
||||
let evt = this._window.document.createEvent("KeyboardEvent");
|
||||
evt.initKeyEvent(data.json.type, true, true, this._window,
|
||||
|
|
|
@ -71,6 +71,10 @@ MOCHITEST_FILES = \
|
|||
file_browserElement_XFrameOptionsAllowFrom.sjs \
|
||||
browserElement_FirstPaint.js \
|
||||
test_browserElement_inproc_FirstPaint.html \
|
||||
browserElement_NextPaint.js \
|
||||
test_browserElement_inproc_NextPaint.html \
|
||||
test_browserElement_oop_NextPaint.html \
|
||||
file_browserElement_NextPaint.html \
|
||||
browserElement_Alert.js \
|
||||
test_browserElement_inproc_Alert.html \
|
||||
browserElement_AlertInFrame.js \
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 808231 - Add mozbrowsernextpaint event.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// Add a first listener that we'll remove shortly after.
|
||||
iframe.addNextPaintListener(wrongListener);
|
||||
|
||||
var gotFirstNextPaintEvent = false;
|
||||
iframe.addNextPaintListener(function () {
|
||||
ok(!gotFirstNextPaintEvent, 'got the first nextpaint event');
|
||||
|
||||
// Make sure we're only called once.
|
||||
gotFirstNextPaintEvent = true;
|
||||
|
||||
iframe.addNextPaintListener(function () {
|
||||
info('got the second nextpaint event');
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
// Force the iframe to repaint.
|
||||
SimpleTest.executeSoon(function () iframe.src += '#next');
|
||||
});
|
||||
|
||||
// Remove the first listener to make sure it's not called.
|
||||
iframe.removeNextPaintListener(wrongListener);
|
||||
iframe.src = 'file_browserElement_NextPaint.html';
|
||||
}
|
||||
|
||||
function wrongListener() {
|
||||
ok(false, 'first listener should have been removed');
|
||||
}
|
||||
|
||||
runTest();
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
addEventListener("hashchange", function () {
|
||||
document.body.style.backgroundColor = "red";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 808231</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_NextPaint.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 808231</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_NextPaint.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче