mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-i to m-c
This commit is contained in:
commit
f097865b72
@ -384,6 +384,10 @@ const kEventConstructors = {
|
||||
return e;
|
||||
},
|
||||
},
|
||||
TrackEvent: { create: function (aName, aProps) {
|
||||
return new TrackEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
TransitionEvent: { create: function (aName, aProps) {
|
||||
return new TransitionEvent(aName, aProps);
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<img id="image1" src="">
|
||||
<input id="image3" type="image">
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "mozilla/dom/TextTrackList.h"
|
||||
#include "mozilla/dom/TextTrackListBinding.h"
|
||||
#include "mozilla/dom/TrackEvent.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -54,8 +56,10 @@ TextTrackList::AddTextTrack(HTMLMediaElement* aMediaElement,
|
||||
{
|
||||
nsRefPtr<TextTrack> track = new TextTrack(mGlobal, aMediaElement, aKind,
|
||||
aLabel, aLanguage);
|
||||
mTextTracks.AppendElement(track);
|
||||
// TODO: dispatch addtrack event
|
||||
if (mTextTracks.AppendElement(track)) {
|
||||
CreateAndDispatchTrackEventRunner(track, NS_LITERAL_STRING("addtrack"));
|
||||
}
|
||||
|
||||
return track.forget();
|
||||
}
|
||||
|
||||
@ -73,9 +77,11 @@ TextTrackList::GetTrackById(const nsAString& aId)
|
||||
}
|
||||
|
||||
void
|
||||
TextTrackList::RemoveTextTrack(const TextTrack& aTrack)
|
||||
TextTrackList::RemoveTextTrack(TextTrack& aTrack)
|
||||
{
|
||||
mTextTracks.RemoveElement(&aTrack);
|
||||
if (mTextTracks.RemoveElement(&aTrack)) {
|
||||
CreateAndDispatchTrackEventRunner(&aTrack, NS_LITERAL_STRING("removetrack"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -86,5 +92,45 @@ TextTrackList::DidSeek()
|
||||
}
|
||||
}
|
||||
|
||||
class TrackEventRunner MOZ_FINAL: public nsRunnable
|
||||
{
|
||||
public:
|
||||
TrackEventRunner(TextTrackList* aList, TrackEvent* aEvent)
|
||||
: mList(aList)
|
||||
, mEvent(aEvent)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE
|
||||
{
|
||||
return mList->DispatchTrackEvent(mEvent);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<TextTrackList> mList;
|
||||
nsRefPtr<TrackEvent> mEvent;
|
||||
};
|
||||
|
||||
nsresult
|
||||
TextTrackList::DispatchTrackEvent(TrackEvent* aEvent)
|
||||
{
|
||||
return DispatchTrustedEvent(aEvent);
|
||||
}
|
||||
|
||||
void
|
||||
TextTrackList::CreateAndDispatchTrackEventRunner(TextTrack* aTrack,
|
||||
const nsAString& aEventName)
|
||||
{
|
||||
TrackEventInitInitializer eventInit;
|
||||
eventInit.mBubbles = false;
|
||||
eventInit.mCancelable = false;
|
||||
eventInit.mTrack = aTrack;
|
||||
nsRefPtr<TrackEvent> trackEvent =
|
||||
TrackEvent::Constructor(this, aEventName, eventInit);
|
||||
|
||||
// Dispatch the TrackEvent asynchronously.
|
||||
nsCOMPtr<nsIRunnable> event = new TrackEventRunner(this, trackEvent);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -14,6 +14,9 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class TrackEvent;
|
||||
class TrackEventRunner;
|
||||
|
||||
class TextTrackList MOZ_FINAL : public nsDOMEventTargetHelper
|
||||
{
|
||||
public:
|
||||
@ -50,15 +53,20 @@ public:
|
||||
mTextTracks.AppendElement(aTextTrack);
|
||||
}
|
||||
|
||||
void RemoveTextTrack(const TextTrack& aTrack);
|
||||
void RemoveTextTrack(TextTrack& aTrack);
|
||||
void DidSeek();
|
||||
|
||||
nsresult DispatchTrackEvent(TrackEvent* aEvent);
|
||||
|
||||
IMPL_EVENT_HANDLER(addtrack)
|
||||
IMPL_EVENT_HANDLER(removetrack)
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupports> mGlobal;
|
||||
nsTArray< nsRefPtr<TextTrack> > mTextTracks;
|
||||
|
||||
void CreateAndDispatchTrackEventRunner(TextTrack* aTrack,
|
||||
const nsAString& aEventName);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -145,6 +145,7 @@ MOCHITEST_FILES = \
|
||||
$(filter disabled-for-intermittent-failures--bug-608634, test_error_in_video_document.html) \
|
||||
test_texttrack.html \
|
||||
test_texttrackcue.html \
|
||||
test_trackevent.html \
|
||||
test_texttrackregion.html \
|
||||
test_timeupdate_small_files.html \
|
||||
test_unseekable.html \
|
||||
|
62
content/media/test/test_trackevent.html
Normal file
62
content/media/test/test_trackevent.html
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 893309 - Implement TrackEvent</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
|
||||
function() {
|
||||
var video = document.createElement("video");
|
||||
isnot(video.textTracks, undefined, "HTMLMediaElement::TextTrack() property should be available.")
|
||||
ok(typeof video.addTextTrack == "function", "HTMLMediaElement::AddTextTrack() function should be available.")
|
||||
|
||||
var trackList = video.textTracks;
|
||||
is(trackList.length, 0, "Length should be 0.");
|
||||
|
||||
var evtTextTrack, numOfCalls = 0;
|
||||
trackList.onaddtrack = function(event) {
|
||||
ok(event instanceof TrackEvent, "Fired event from onaddtrack should be a TrackEvent");
|
||||
is(event.type, "addtrack", "Event type should be addtrack");
|
||||
ok(event.isTrusted, "Event should be trusted!");
|
||||
ok(!event.bubbles, "Event shouldn't bubble!");
|
||||
ok(!event.cancelable, "Event shouldn't be cancelable!");
|
||||
|
||||
evtTextTrack = event.track;
|
||||
ok(textTrack[numOfCalls] === evtTextTrack, "Text tracks should be the same");
|
||||
is(evtTextTrack.label, label[numOfCalls], "Label should be set to "+ label[numOfCalls]);
|
||||
is(evtTextTrack.language, language[numOfCalls], "Language should be " + language[numOfCalls]);
|
||||
is(evtTextTrack.kind, kind[numOfCalls], "Kind should be " + kind[numOfCalls]);
|
||||
|
||||
if (++numOfCalls == 3) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
|
||||
var label = ["Oasis", "Coldplay", "t.A.T.u"];
|
||||
language = ["en-CA", "en-GB", "ru" ];
|
||||
kind = ["subtitles", "captions", "chapters"];
|
||||
|
||||
var textTrack = new Array(3);
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
textTrack[i] = video.addTextTrack(kind[i], label[i], language[i]);
|
||||
is(trackList.length, i + 1, "Length should be " + (i+1));
|
||||
}
|
||||
|
||||
//TODO: Tests for removetrack event to be added along with bug 882677
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -123,12 +123,14 @@ nsDSURIContentListener::DoContent(const char* aContentType,
|
||||
|
||||
if (rv == NS_ERROR_REMOTE_XUL) {
|
||||
request->Cancel(rv);
|
||||
*aAbortProcess = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// it's okay if we don't know how to handle the content
|
||||
return NS_OK;
|
||||
// we don't know how to handle the content
|
||||
*aContentHandler = nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
|
||||
|
@ -44,14 +44,17 @@ WebappsRegistry.prototype = {
|
||||
let app = msg.app;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install:Return:OK":
|
||||
this.removeMessageListeners("Webapps:Install:Return:KO");
|
||||
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app));
|
||||
cpmm.sendAsyncMessage("Webapps:Install:Return:Ack",
|
||||
{ manifestURL : app.manifestURL });
|
||||
break;
|
||||
case "Webapps:Install:Return:KO":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
Services.DOMRequest.fireError(req, msg.error || "DENIED");
|
||||
break;
|
||||
case "Webapps:GetSelf:Return:OK":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
if (msg.apps.length) {
|
||||
app = msg.apps[0];
|
||||
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app));
|
||||
@ -60,9 +63,11 @@ WebappsRegistry.prototype = {
|
||||
}
|
||||
break;
|
||||
case "Webapps:CheckInstalled:Return:OK":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
Services.DOMRequest.fireSuccess(req, msg.app);
|
||||
break;
|
||||
case "Webapps:GetInstalled:Return:OK":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
Services.DOMRequest.fireSuccess(req, convertAppsArray(msg.apps, this._window));
|
||||
break;
|
||||
}
|
||||
@ -155,6 +160,7 @@ WebappsRegistry.prototype = {
|
||||
let request = this.createRequest();
|
||||
|
||||
if (this._ensureForeground(request)) {
|
||||
this.addMessageListeners("Webapps:Install:Return:KO");
|
||||
cpmm.sendAsyncMessage("Webapps:Install",
|
||||
this._prepareInstall(uri, request, aParams, false));
|
||||
}
|
||||
@ -164,6 +170,7 @@ WebappsRegistry.prototype = {
|
||||
|
||||
getSelf: function() {
|
||||
let request = this.createRequest();
|
||||
this.addMessageListeners("Webapps:GetSelf:Return:OK");
|
||||
cpmm.sendAsyncMessage("Webapps:GetSelf", { origin: this._getOrigin(this._window.location.href),
|
||||
appId: this._window.document.nodePrincipal.appId,
|
||||
oid: this._id,
|
||||
@ -176,6 +183,8 @@ WebappsRegistry.prototype = {
|
||||
this._window.document.nodePrincipal.checkMayLoad(manifestURL, true, false);
|
||||
|
||||
let request = this.createRequest();
|
||||
|
||||
this.addMessageListeners("Webapps:CheckInstalled:Return:OK");
|
||||
cpmm.sendAsyncMessage("Webapps:CheckInstalled", { origin: this._getOrigin(this._window.location.href),
|
||||
manifestURL: manifestURL.spec,
|
||||
oid: this._id,
|
||||
@ -185,6 +194,7 @@ WebappsRegistry.prototype = {
|
||||
|
||||
getInstalled: function() {
|
||||
let request = this.createRequest();
|
||||
this.addMessageListeners("Webapps:GetInstalled:Return:OK");
|
||||
cpmm.sendAsyncMessage("Webapps:GetInstalled", { origin: this._getOrigin(this._window.location.href),
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
@ -213,6 +223,7 @@ WebappsRegistry.prototype = {
|
||||
let request = this.createRequest();
|
||||
|
||||
if (this._ensureForeground(request)) {
|
||||
this.addMessageListeners("Webapps:Install:Return:KO");
|
||||
cpmm.sendAsyncMessage("Webapps:InstallPackage",
|
||||
this._prepareInstall(uri, request, aParams, true));
|
||||
}
|
||||
@ -222,10 +233,7 @@ WebappsRegistry.prototype = {
|
||||
|
||||
// nsIDOMGlobalPropertyInitializer implementation
|
||||
init: function(aWindow) {
|
||||
this.initDOMRequestHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
|
||||
"Webapps:GetInstalled:Return:OK",
|
||||
"Webapps:GetSelf:Return:OK",
|
||||
"Webapps:CheckInstalled:Return:OK" ]);
|
||||
this.initDOMRequestHelper(aWindow, "Webapps:Install:Return:OK");
|
||||
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
@ -338,16 +346,15 @@ WebappsApplication.prototype = {
|
||||
|
||||
this._downloadError = null;
|
||||
|
||||
this.initDOMRequestHelper(aWindow, ["Webapps:OfflineCache",
|
||||
"Webapps:CheckForUpdate:Return:OK",
|
||||
"Webapps:CheckForUpdate:Return:KO",
|
||||
"Webapps:Launch:Return:OK",
|
||||
"Webapps:Launch:Return:KO",
|
||||
"Webapps:PackageEvent",
|
||||
"Webapps:ClearBrowserData:Return",
|
||||
"Webapps:Connect:Return:OK",
|
||||
"Webapps:Connect:Return:KO",
|
||||
"Webapps:GetConnections:Return:OK"]);
|
||||
this.initDOMRequestHelper(aWindow, [
|
||||
"Webapps:OfflineCache",
|
||||
"Webapps:CheckForUpdate:Return:OK",
|
||||
"Webapps:CheckForUpdate:Return:KO",
|
||||
"Webapps:PackageEvent",
|
||||
"Webapps:Connect:Return:OK",
|
||||
"Webapps:Connect:Return:KO",
|
||||
"Webapps:GetConnections:Return:OK"
|
||||
]);
|
||||
|
||||
cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
|
||||
{
|
||||
@ -441,6 +448,8 @@ WebappsApplication.prototype = {
|
||||
|
||||
launch: function(aStartPoint) {
|
||||
let request = this.createRequest();
|
||||
this.addMessageListeners(["Webapps:Launch:Return:OK",
|
||||
"Webapps:Launch:Return:KO"]);
|
||||
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this.origin,
|
||||
manifestURL: this.manifestURL,
|
||||
startPoint: aStartPoint || "",
|
||||
@ -455,6 +464,7 @@ WebappsApplication.prototype = {
|
||||
let browserChild =
|
||||
BrowserElementPromptService.getBrowserElementChildForWindow(this._window);
|
||||
if (browserChild) {
|
||||
this.addMessageListeners("Webapps:ClearBrowserData:Return");
|
||||
browserChild.messageManager.sendAsyncMessage(
|
||||
"Webapps:ClearBrowserData",
|
||||
{ manifestURL: this.manifestURL,
|
||||
@ -536,9 +546,13 @@ WebappsApplication.prototype = {
|
||||
return;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Launch:Return:KO":
|
||||
this.removeMessageListeners(["Webapps:Launch:Return:OK",
|
||||
"Webapps:Launch:Return:KO"]);
|
||||
Services.DOMRequest.fireError(req, "APP_INSTALL_PENDING");
|
||||
break;
|
||||
case "Webapps:Launch:Return:OK":
|
||||
this.removeMessageListeners(["Webapps:Launch:Return:OK",
|
||||
"Webapps:Launch:Return:KO"]);
|
||||
Services.DOMRequest.fireSuccess(req, null);
|
||||
break;
|
||||
case "Webapps:CheckForUpdate:Return:KO":
|
||||
@ -648,6 +662,7 @@ WebappsApplication.prototype = {
|
||||
}
|
||||
break;
|
||||
case "Webapps:ClearBrowserData:Return":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
Services.DOMRequest.fireSuccess(req, null);
|
||||
break;
|
||||
case "Webapps:Connect:Return:OK":
|
||||
@ -691,13 +706,14 @@ WebappsApplication.prototype = {
|
||||
* mozIDOMApplicationMgmt object
|
||||
*/
|
||||
function WebappsApplicationMgmt(aWindow) {
|
||||
this.initDOMRequestHelper(aWindow, ["Webapps:GetAll:Return:OK",
|
||||
"Webapps:GetAll:Return:KO",
|
||||
"Webapps:Uninstall:Return:OK",
|
||||
"Webapps:Uninstall:Broadcast:Return:OK",
|
||||
"Webapps:Uninstall:Return:KO",
|
||||
"Webapps:Install:Return:OK",
|
||||
"Webapps:GetNotInstalled:Return:OK"]);
|
||||
this.initDOMRequestHelper(aWindow, [
|
||||
{ name: "Webapps:GetAll:Return:OK", strongRef: true },
|
||||
{ name: "Webapps:GetAll:Return:KO", strongRef: true },
|
||||
{ name: "Webapps:Uninstall:Return:OK", strongRef: true },
|
||||
{ name: "Webapps:Uninstall:Broadcast:Return:OK", strongRef: true },
|
||||
{ name: "Webapps:Uninstall:Return:KO", strongRef: true },
|
||||
{ name: "Webapps:Install:Return:OK", strongRef: true },
|
||||
{ name: "Webapps:GetNotInstalled:Return:OK", strongRef: true }]);
|
||||
|
||||
cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
|
||||
{
|
||||
|
@ -52,7 +52,8 @@ function checkApp(app) {
|
||||
installed(!!app);
|
||||
if (app) {
|
||||
var appName = "Really Rapid Release (APPTYPETOKEN)";
|
||||
is(app.manifest.name, appName, "Manifest name should be correct");
|
||||
var manifest = SpecialPowers.wrap(app.manifest);
|
||||
is(manifest.name, appName, "Manifest name should be correct");
|
||||
is(app.origin, "http://test", "App origin should be correct");
|
||||
is(app.installOrigin, "http://mochi.test:8888", "Install origin should be correct");
|
||||
}
|
||||
|
@ -3,12 +3,23 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Helper object for APIs that deal with DOMRequests and Promises and need to
|
||||
* release them when the window goes out of scope.
|
||||
* Helper object for APIs that deal with DOMRequests and Promises.
|
||||
* It allows objects inheriting from it to create and keep track of DOMRequests
|
||||
* and Promises objects in the common scenario where requests are created in
|
||||
* the child, handed out to content and delivered to the parent within an async
|
||||
* message (containing the identifiers of these requests). The parent may send
|
||||
* messages back as answers to different requests and the child will use this
|
||||
* helper to get the right request object. This helper also takes care of
|
||||
* releasing the requests objects when the window goes out of scope.
|
||||
*
|
||||
* DOMRequestIPCHelper also deals with message listeners, allowing to add them
|
||||
* to the child side of frame and process message manager and removing them
|
||||
* when needed.
|
||||
*/
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DOMRequestIpcHelper"];
|
||||
|
||||
@ -19,45 +30,148 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageListenerManager");
|
||||
|
||||
/**
|
||||
* We use DOMRequestIpcHelperMessageListener to avoid leaking objects which
|
||||
* "inherit" from DOMRequestIpcHelper.
|
||||
*
|
||||
* The issue is that the message manager will hold a strong ref to the message
|
||||
* listener we register with it. But we don't want to hold a strong ref to the
|
||||
* DOMRequestIpcHelper object, because that object may be arbitrarily large.
|
||||
*
|
||||
* So instead the message manager holds a strong ref to the
|
||||
* DOMRequestIpcHelperMessageListener, and that holds a /weak/ ref to its
|
||||
* DOMRequestIpcHelper.
|
||||
*
|
||||
* Additionally, we want to unhook all of these message listeners when the
|
||||
* appropriate window is destroyed. We use DOMRequestIpcHelperMessageListener
|
||||
* for this, too.
|
||||
*/
|
||||
this.DOMRequestIpcHelperMessageListener = function(aHelper, aWindow, aMessages) {
|
||||
this._weakHelper = Cu.getWeakReference(aHelper);
|
||||
|
||||
this._messages = aMessages;
|
||||
this._messages.forEach(function(msgName) {
|
||||
cpmm.addWeakMessageListener(msgName, this);
|
||||
}, this);
|
||||
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", /* weakRef */ true);
|
||||
|
||||
// aWindow may be null; in that case, the DOMRequestIpcHelperMessageListener
|
||||
// is not tied to a particular window and lives forever.
|
||||
if (aWindow) {
|
||||
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
this._innerWindowID = util.currentInnerWindowID;
|
||||
}
|
||||
this.DOMRequestIpcHelper = function DOMRequestIpcHelper() {
|
||||
// _listeners keeps a list of messages for which we added a listener and the
|
||||
// kind of listener that we added (strong or weak). It's an object of this
|
||||
// form:
|
||||
// {
|
||||
// "message1": true,
|
||||
// "messagen": false
|
||||
// }
|
||||
//
|
||||
// where each property is the name of the message and its value is a boolean
|
||||
// that indicates if the listener is strong or not.
|
||||
this._listeners = null;
|
||||
this._requests = null;
|
||||
this._window = null;
|
||||
}
|
||||
|
||||
DOMRequestIpcHelperMessageListener.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
DOMRequestIpcHelper.prototype = {
|
||||
/**
|
||||
* An object which "inherits" from DOMRequestIpcHelper, declares its own
|
||||
* queryInterface method and adds at least one weak listener to the Message
|
||||
* Manager MUST implement Ci.nsISupportsWeakReference.
|
||||
*/
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference]),
|
||||
|
||||
/**
|
||||
* 'aMessages' is expected to be an array of either:
|
||||
* - objects of this form:
|
||||
* {
|
||||
* name: "messageName",
|
||||
* strongRef: false
|
||||
* }
|
||||
* where 'name' is the message identifier and 'strongRef' a boolean
|
||||
* indicating if the listener should be a strong referred one or not.
|
||||
*
|
||||
* - or only strings containing the message name, in which case the listener
|
||||
* will be added as a weak reference by default.
|
||||
*/
|
||||
addMessageListeners: function(aMessages) {
|
||||
if (!aMessages) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._listeners) {
|
||||
this._listeners = {};
|
||||
}
|
||||
|
||||
if (!Array.isArray(aMessages)) {
|
||||
aMessages = [aMessages];
|
||||
}
|
||||
|
||||
aMessages.forEach((aMsg) => {
|
||||
let name = aMsg.name || aMsg;
|
||||
// If the listener is already set and it is of the same type we just
|
||||
// bail out. If it is not of the same type, we throw an exception.
|
||||
if (this._listeners[name] != undefined) {
|
||||
if (!!aMsg.strongRef == this._listeners[name]) {
|
||||
return;
|
||||
} else {
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
aMsg.strongRef ? cpmm.addMessageListener(name, this)
|
||||
: cpmm.addWeakMessageListener(name, this);
|
||||
this._listeners[name] = !!aMsg.strongRef;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 'aMessages' is expected to be a string or an array of strings containing
|
||||
* the message names of the listeners to be removed.
|
||||
*/
|
||||
removeMessageListeners: function(aMessages) {
|
||||
if (!this._listeners || !aMessages) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(aMessages)) {
|
||||
aMessages = [aMessages];
|
||||
}
|
||||
|
||||
aMessages.forEach((aName) => {
|
||||
if (this._listeners[aName] == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._listeners[aName] ? cpmm.removeMessageListener(aName, this)
|
||||
: cpmm.removeWeakMessageListener(aName, this);
|
||||
delete this._listeners[aName];
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the helper adding the corresponding listeners to the messages
|
||||
* provided as the second parameter.
|
||||
*
|
||||
* 'aMessages' is expected to be an array of either:
|
||||
*
|
||||
* - objects of this form:
|
||||
* {
|
||||
* name: 'messageName',
|
||||
* strongRef: false
|
||||
* }
|
||||
* where 'name' is the message identifier and 'strongRef' a boolean
|
||||
* indicating if the listener should be a strong referred one or not.
|
||||
*
|
||||
* - or only strings containing the message name, in which case the listener
|
||||
* will be added as a weak referred one by default.
|
||||
*/
|
||||
initDOMRequestHelper: function(aWindow, aMessages) {
|
||||
if (aMessages) {
|
||||
this.addMessageListeners(aMessages);
|
||||
}
|
||||
|
||||
this._id = this._getRandomId();
|
||||
|
||||
this._window = aWindow;
|
||||
if (this._window) {
|
||||
// We don't use this.innerWindowID, but other classes rely on it.
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
}
|
||||
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
},
|
||||
|
||||
destroyDOMRequestHelper: function() {
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
|
||||
if (this._listeners) {
|
||||
Object.keys(this._listeners).forEach((aName) => {
|
||||
this._listeners[aName] ? cpmm.removeMessageListener(aName, this)
|
||||
: cpmm.removeWeakMessageListener(aName, this);
|
||||
delete this._listeners[aName];
|
||||
});
|
||||
}
|
||||
|
||||
this._listeners = null;
|
||||
this._requests = null;
|
||||
this._window = null;
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic !== "inner-window-destroyed") {
|
||||
@ -65,70 +179,18 @@ DOMRequestIpcHelperMessageListener.prototype = {
|
||||
}
|
||||
|
||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (wId != this._innerWindowID) {
|
||||
if (wId != this.innerWindowID) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
receiveMessage: function(aMsg) {
|
||||
let helper = this._weakHelper.get();
|
||||
if (helper) {
|
||||
helper.receiveMessage(aMsg);
|
||||
} else {
|
||||
this.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
// DOMRequestIpcHelper.destroy() calls back into this function.
|
||||
if (this._destroyed) {
|
||||
return;
|
||||
}
|
||||
this._destroyed = true;
|
||||
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
|
||||
this._messages.forEach(function(msgName) {
|
||||
cpmm.removeWeakMessageListener(msgName, this);
|
||||
}, this);
|
||||
this._messages = null;
|
||||
|
||||
let helper = this._weakHelper.get();
|
||||
if (helper) {
|
||||
helper.destroyDOMRequestHelper();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.DOMRequestIpcHelper = function DOMRequestIpcHelper() {
|
||||
}
|
||||
|
||||
DOMRequestIpcHelper.prototype = {
|
||||
/**
|
||||
* An object which "inherits" from DOMRequestIpcHelper and declares its own
|
||||
* queryInterface method MUST implement Ci.nsISupportsWeakReference.
|
||||
*/
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference]),
|
||||
|
||||
initDOMRequestHelper: function(aWindow, aMessages) {
|
||||
this._DOMRequestIpcHelperMessageListener =
|
||||
new DOMRequestIpcHelperMessageListener(this, aWindow, aMessages);
|
||||
|
||||
this._window = aWindow;
|
||||
this._requests = {};
|
||||
this._id = this._getRandomId();
|
||||
|
||||
if (this._window) {
|
||||
// We don't use this.innerWindowID, but other classes rely on it.
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
}
|
||||
this.destroyDOMRequestHelper();
|
||||
},
|
||||
|
||||
getRequestId: function(aRequest) {
|
||||
if (!this._requests) {
|
||||
this._requests = {};
|
||||
}
|
||||
|
||||
let id = "id" + this._getRandomId();
|
||||
this._requests[id] = aRequest;
|
||||
return id;
|
||||
@ -141,8 +203,9 @@ DOMRequestIpcHelper.prototype = {
|
||||
},
|
||||
|
||||
getRequest: function(aId) {
|
||||
if (this._requests[aId])
|
||||
if (this._requests && this._requests[aId]) {
|
||||
return this._requests[aId];
|
||||
}
|
||||
},
|
||||
|
||||
getPromiseResolver: function(aId) {
|
||||
@ -152,8 +215,9 @@ DOMRequestIpcHelper.prototype = {
|
||||
},
|
||||
|
||||
removeRequest: function(aId) {
|
||||
if (this._requests[aId])
|
||||
if (this._requests && this._requests[aId]) {
|
||||
delete this._requests[aId];
|
||||
}
|
||||
},
|
||||
|
||||
removePromiseResolver: function(aId) {
|
||||
@ -163,8 +227,9 @@ DOMRequestIpcHelper.prototype = {
|
||||
},
|
||||
|
||||
takeRequest: function(aId) {
|
||||
if (!this._requests[aId])
|
||||
if (!this._requests || !this._requests[aId]) {
|
||||
return null;
|
||||
}
|
||||
let request = this._requests[aId];
|
||||
delete this._requests[aId];
|
||||
return request;
|
||||
@ -177,25 +242,8 @@ DOMRequestIpcHelper.prototype = {
|
||||
},
|
||||
|
||||
_getRandomId: function() {
|
||||
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
},
|
||||
|
||||
destroyDOMRequestHelper: function() {
|
||||
// This function is re-entrant --
|
||||
// DOMRequestIpcHelperMessageListener.destroy() calls back into this
|
||||
// function, and this.uninit() may also call it.
|
||||
if (this._destroyed) {
|
||||
return;
|
||||
}
|
||||
this._destroyed = true;
|
||||
|
||||
this._DOMRequestIpcHelperMessageListener.destroy();
|
||||
this._requests = {};
|
||||
this._window = null;
|
||||
|
||||
if(this.uninit) {
|
||||
this.uninit();
|
||||
}
|
||||
return Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
},
|
||||
|
||||
createRequest: function() {
|
||||
@ -212,19 +260,27 @@ DOMRequestIpcHelper.prototype = {
|
||||
},
|
||||
|
||||
forEachRequest: function(aCallback) {
|
||||
Object.keys(this._requests).forEach(function(k) {
|
||||
if (this.getRequest(k) instanceof this._window.DOMRequest) {
|
||||
aCallback(k);
|
||||
if (!this._requests) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(this._requests).forEach((aKey) => {
|
||||
if (this.getRequest(aKey) instanceof this._window.DOMRequest) {
|
||||
aCallback(aKey);
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
|
||||
forEachPromiseResolver: function(aCallback) {
|
||||
Object.keys(this._requests).forEach(function(k) {
|
||||
if ("resolve" in this.getPromiseResolver(k) &&
|
||||
"reject" in this.getPromiseResolver(k)) {
|
||||
aCallback(k);
|
||||
if (!this._requests) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(this._requests).forEach((aKey) => {
|
||||
if ("resolve" in this.getPromiseResolver(aKey) &&
|
||||
"reject" in this.getPromiseResolver(aKey)) {
|
||||
aCallback(aKey);
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
@ -17,91 +17,327 @@
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
Components.utils.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
function DummyHelperSubclass() {
|
||||
this.initDOMRequestHelper(window, []);
|
||||
}
|
||||
|
||||
function DummyHelperSubclass() {
|
||||
}
|
||||
DummyHelperSubclass.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype
|
||||
};
|
||||
|
||||
var dummy = new DummyHelperSubclass();
|
||||
|
||||
function createPromise() {
|
||||
ok(Promise, "Promise object should exist");
|
||||
/**
|
||||
* Init & destroy.
|
||||
*/
|
||||
function initDOMRequestHelperTest(aMessages) {
|
||||
is(dummy._requests, undefined, "Request is undefined");
|
||||
is(dummy._messages, undefined, "Messages is undefined");
|
||||
is(dummy._window, undefined, "Window is undefined");
|
||||
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
resolve(true);
|
||||
});
|
||||
ok(promise instanceof Promise, "returned a Promise");
|
||||
promise.then(runTest);
|
||||
dummy.initDOMRequestHelper(window, aMessages);
|
||||
|
||||
ok(dummy._window, "Window exists");
|
||||
is(dummy._window, window, "Correct window");
|
||||
if (aMessages) {
|
||||
is(typeof dummy._listeners, "object", "Listeners is an object");
|
||||
}
|
||||
}
|
||||
|
||||
function getResolver() {
|
||||
var id;
|
||||
var resolver;
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
var r = { resolve: resolve, reject: reject };
|
||||
id = dummy.getPromiseResolverId(r);
|
||||
resolver = r;
|
||||
ok(typeof id === "string", "id should be string");
|
||||
r.resolve(true);
|
||||
}).then(function(unused) {
|
||||
var r = dummy.getPromiseResolver(id);
|
||||
ok(resolver === r, "get should succeed");
|
||||
runTest();
|
||||
});
|
||||
function destroyDOMRequestHelperTest() {
|
||||
dummy.destroyDOMRequestHelper();
|
||||
|
||||
is(dummy._requests, undefined, "Request is undefined");
|
||||
is(dummy._messages, undefined, "Messages is undefined");
|
||||
is(dummy._window, undefined, "Window is undefined");
|
||||
}
|
||||
|
||||
function removeResolver() {
|
||||
var id;
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
var r = { resolve: resolve, reject: reject };
|
||||
id = dummy.getPromiseResolverId(r);
|
||||
ok(typeof id === "string", "id should be string");
|
||||
|
||||
var resolver = dummy.getPromiseResolver(id);
|
||||
ok(resolver === r, "resolver get should succeed");
|
||||
|
||||
r.resolve(true);
|
||||
}).then(function(unused) {
|
||||
dummy.removePromiseResolver(id);
|
||||
var resolver = dummy.getPromiseResolver(id);
|
||||
ok(resolver === undefined, "removeResolver: get should fail");
|
||||
runTest();
|
||||
/**
|
||||
* Message listeners.
|
||||
*/
|
||||
function checkMessageListeners(aExpectedListeners, aCount) {
|
||||
ok(true, "Checking message listeners\n" + "Expected listeners " +
|
||||
JSON.stringify(aExpectedListeners) + " \nExpected count " + aCount);
|
||||
let count = 0;
|
||||
Object.keys(dummy._listeners).forEach(function(name) {
|
||||
count++;
|
||||
is(aExpectedListeners[name], dummy._listeners[name],
|
||||
"Message found " + name + " - Same listeners");
|
||||
});
|
||||
is(aCount, count, "Correct number of listeners");
|
||||
}
|
||||
|
||||
function takeResolver() {
|
||||
var id;
|
||||
var resolver;
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
var r = { resolve: resolve, reject: reject };
|
||||
id = dummy.getPromiseResolverId(r);
|
||||
resolver = r;
|
||||
ok(typeof id === "string", "id should be string");
|
||||
|
||||
var gotR = dummy.getPromiseResolver(id);
|
||||
ok(gotR === r, "resolver get should succeed");
|
||||
|
||||
r.resolve(true);
|
||||
}).then(function(unused) {
|
||||
var r = dummy.takePromiseResolver(id);
|
||||
ok(resolver === r, "take should succeed");
|
||||
|
||||
r = dummy.getPromiseResolver(id);
|
||||
ok(r === undefined, "takeResolver: get should fail");
|
||||
runTest();
|
||||
});
|
||||
function addMessageListenersTest(aMessages, aExpectedListeners, aCount) {
|
||||
dummy.addMessageListeners(aMessages);
|
||||
ok(true, JSON.stringify(dummy._listeners));
|
||||
checkMessageListeners(aExpectedListeners, aCount);
|
||||
}
|
||||
|
||||
var tests = [ createPromise,
|
||||
getResolver,
|
||||
removeResolver,
|
||||
takeResolver,
|
||||
];
|
||||
function removeMessageListenersTest(aMessages, aExpectedListeners, aCount) {
|
||||
dummy.removeMessageListeners(aMessages);
|
||||
checkMessageListeners(aExpectedListeners, aCount);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
/**
|
||||
* Test steps.
|
||||
*/
|
||||
var tests = [
|
||||
function() {
|
||||
ok(true, "== InitDOMRequestHelper no messages");
|
||||
initDOMRequestHelperTest(null);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== DestroyDOMRequestHelper");
|
||||
destroyDOMRequestHelperTest();
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== InitDOMRequestHelper empty array");
|
||||
initDOMRequestHelperTest([]);
|
||||
checkMessageListeners({}, 0);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== DestroyDOMRequestHelper");
|
||||
destroyDOMRequestHelperTest();
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== InitDOMRequestHelper with strings array");
|
||||
initDOMRequestHelperTest(["name1", "nameN"]);
|
||||
checkMessageListeners({"name1": false, "nameN": false}, 2);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== DestroyDOMRequestHelper");
|
||||
destroyDOMRequestHelperTest();
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== InitDOMRequestHelper with objects array");
|
||||
initDOMRequestHelperTest([{
|
||||
name: "name1",
|
||||
strongRef: false
|
||||
}, {
|
||||
name: "nameN",
|
||||
strongRef: true
|
||||
}]);
|
||||
checkMessageListeners({"name1": false, "nameN": true}, 2);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== AddMessageListeners empty array");
|
||||
addMessageListenersTest([], {"name1": false, "nameN": true}, 2);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== AddMessageListeners null");
|
||||
addMessageListenersTest(null, {"name1": false, "nameN": true}, 2);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== AddMessageListeners new listener, string only");
|
||||
addMessageListenersTest("name2", {
|
||||
"name1": false,
|
||||
"name2": false,
|
||||
"nameN": true
|
||||
}, 3);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== AddMessageListeners new listeners, strings array");
|
||||
addMessageListenersTest(["name3", "name4"], {
|
||||
"name1": false,
|
||||
"name2": false,
|
||||
"name3": false,
|
||||
"name4": false,
|
||||
"nameN": true
|
||||
}, 5);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== AddMessageListeners new listeners, objects array");
|
||||
addMessageListenersTest([{
|
||||
name: "name5",
|
||||
strongRef: true
|
||||
}, {
|
||||
name: "name6",
|
||||
strongRef: false
|
||||
}], {
|
||||
"name1": false,
|
||||
"name2": false,
|
||||
"name3": false,
|
||||
"name4": false,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 7);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== RemoveMessageListeners, null");
|
||||
removeMessageListenersTest(null, {
|
||||
"name1": false,
|
||||
"name2": false,
|
||||
"name3": false,
|
||||
"name4": false,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 7);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== RemoveMessageListeners, one message");
|
||||
removeMessageListenersTest("name1", {
|
||||
"name2": false,
|
||||
"name3": false,
|
||||
"name4": false,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 6);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== RemoveMessageListeners, array of messages");
|
||||
removeMessageListenersTest(["name2", "name3"], {
|
||||
"name4": false,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 4);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== RemoveMessageListeners, unknown message");
|
||||
removeMessageListenersTest("unknown", {
|
||||
"name4": false,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 4);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
try {
|
||||
ok(true, "== AddMessageListeners, same message, same kind");
|
||||
addMessageListenersTest("name4", {
|
||||
"name4": false,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 4);
|
||||
next();
|
||||
} catch (ex) {
|
||||
ok(false, "Unexpected exception " + ex);
|
||||
}
|
||||
},
|
||||
function() {
|
||||
ok(true, "== AddMessageListeners, same message, different kind");
|
||||
try {
|
||||
addMessageListenersTest({name: "name4", strongRef: true}, {
|
||||
"name4": true,
|
||||
"name5": true,
|
||||
"name6": false,
|
||||
"nameN": true
|
||||
}, 4);
|
||||
ok(false, "Should have thrown an exception");
|
||||
} catch (ex) {
|
||||
ok(true, "Expected exception");
|
||||
next();
|
||||
}
|
||||
},
|
||||
function() {
|
||||
ok(true, "== Test createRequest()");
|
||||
ok(DOMRequest, "DOMRequest object exists");
|
||||
var req = dummy.createRequest();
|
||||
ok(req instanceof DOMRequest, "Returned a DOMRequest");
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== Test getRequestId(), removeRequest() and getRequest()");
|
||||
var req = dummy.createRequest();
|
||||
var id = dummy.getRequestId(req);
|
||||
is(typeof id, "string", "id is a string");
|
||||
var req_ = dummy.getRequest(id);
|
||||
is(req, req_, "Got correct request");
|
||||
dummy.removeRequest(id);
|
||||
req = dummy.getRequest(id);
|
||||
is(req, null, "No request");
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
ok(true, "== Test createPromise()");
|
||||
ok(Promise, "Promise object exists");
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
resolve(true);
|
||||
});
|
||||
ok(promise instanceof Promise, "Returned a Promise");
|
||||
promise.then(next);
|
||||
},
|
||||
function() {
|
||||
ok(true, "== Test getResolver()");
|
||||
var id;
|
||||
var resolver;
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
var r = { resolve: resolve, reject: reject };
|
||||
id = dummy.getPromiseResolverId(r);
|
||||
resolver = r;
|
||||
ok(typeof id === "string", "id is a string");
|
||||
r.resolve(true);
|
||||
}).then(function(unused) {
|
||||
var r = dummy.getPromiseResolver(id);
|
||||
ok(resolver === r, "Get succeeded");
|
||||
next();
|
||||
});
|
||||
},
|
||||
function() {
|
||||
ok(true, "== Test removeResolver");
|
||||
var id;
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
var r = { resolve: resolve, reject: reject };
|
||||
id = dummy.getPromiseResolverId(r);
|
||||
ok(typeof id === "string", "id is a string");
|
||||
|
||||
var resolver = dummy.getPromiseResolver(id);
|
||||
ok(true, "Got resolver " + JSON.stringify(resolver));
|
||||
ok(resolver === r, "Resolver get succeeded");
|
||||
|
||||
r.resolve(true);
|
||||
}).then(function(unused) {
|
||||
dummy.removePromiseResolver(id);
|
||||
var resolver = dummy.getPromiseResolver(id);
|
||||
ok(resolver === undefined, "removeResolver: get failed");
|
||||
next();
|
||||
});
|
||||
},
|
||||
function() {
|
||||
ok(true, "== Test takeResolver");
|
||||
var id;
|
||||
var resolver;
|
||||
var promise = dummy.createPromise(function(resolve, reject) {
|
||||
var r = { resolve: resolve, reject: reject };
|
||||
id = dummy.getPromiseResolverId(r);
|
||||
resolver = r;
|
||||
ok(typeof id === "string", "id is a string");
|
||||
|
||||
var gotR = dummy.getPromiseResolver(id);
|
||||
ok(gotR === r, "resolver get succeeded");
|
||||
|
||||
r.resolve(true);
|
||||
}).then(function(unused) {
|
||||
var r = dummy.takePromiseResolver(id);
|
||||
ok(resolver === r, "take should succeed");
|
||||
|
||||
r = dummy.getPromiseResolver(id);
|
||||
ok(r === undefined, "takeResolver: get failed");
|
||||
next();
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
@ -113,7 +349,7 @@
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
next();
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
@ -2886,7 +2886,6 @@
|
||||
"[[\"forwarddelete\",\"\"]] \"<p>foo[]</p><br><p>bar</p>\" compare innerHTML":true,
|
||||
"[[\"forwarddelete\",\"\"]] \"<p>foo[]</p><br><br><p>bar</p>\" compare innerHTML":true,
|
||||
"[[\"forwarddelete\",\"\"]] \"<p>foo[]</p><img src=/img/lion.svg><p>bar\" compare innerHTML":true,
|
||||
"[[\"forwarddelete\",\"\"]] \"foo[]<img src=/img/lion.svg>bar\" compare innerHTML":true,
|
||||
"[[\"forwarddelete\",\"\"]] \"foo [] \" compare innerHTML":true,
|
||||
"[[\"forwarddelete\",\"\"]] \"foo []<span> </span> bar\" compare innerHTML":true,
|
||||
"[[\"forwarddelete\",\"\"]] \"foo <span> </span>[] bar\" compare innerHTML":true,
|
||||
|
@ -475,7 +475,8 @@ MozInputContext.prototype = {
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIB2GInputContext,
|
||||
Ci.nsIObserver
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference
|
||||
]),
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({
|
||||
|
@ -91,7 +91,8 @@ PhoneNumberService.prototype = {
|
||||
|
||||
classID : Components.ID("{e2768710-eb17-11e2-91e2-0800200c9a66}"),
|
||||
contractID : "@mozilla.org/phoneNumberService;1",
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
}
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PhoneNumberService]);
|
||||
|
@ -544,6 +544,7 @@ var interfaceNamesInGlobalScope =
|
||||
"Touch",
|
||||
"TouchEvent",
|
||||
"TouchList",
|
||||
"TrackEvent",
|
||||
"TransitionEvent",
|
||||
{name: "TreeColumn", xbl: true},
|
||||
{name: "TreeColumns", xbl: true},
|
||||
|
17
dom/webidl/TrackEvent.webidl
Normal file
17
dom/webidl/TrackEvent.webidl
Normal file
@ -0,0 +1,17 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
|
||||
[Constructor(DOMString type, optional TrackEventInit eventInitDict)]
|
||||
interface TrackEvent : Event
|
||||
{
|
||||
readonly attribute TextTrack? track;
|
||||
};
|
||||
|
||||
dictionary TrackEventInit : EventInit
|
||||
{
|
||||
TextTrack? track = null;
|
||||
};
|
@ -548,6 +548,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
|
||||
'MozInterAppMessageEvent.webidl',
|
||||
'RTCDataChannelEvent.webidl',
|
||||
'RTCPeerConnectionIceEvent.webidl',
|
||||
'TrackEvent.webidl',
|
||||
'UserProximityEvent.webidl',
|
||||
]
|
||||
|
||||
|
@ -51,6 +51,7 @@ function initializeOnload() {
|
||||
var firstimg = document.createElement('img');
|
||||
firstimg.addEventListener("load", imageLoad, false);
|
||||
firstimg.addEventListener("error", imageLoad, false);
|
||||
firstimg.alt = "";
|
||||
firstimg.src = "bug733553.sjs";
|
||||
document.getElementById('content').appendChild(firstimg);
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
var imgURL = document.location.search.substr(1);
|
||||
document.images[0].onload = onImageLoad;
|
||||
document.images[0].onerror = onImageLoad;
|
||||
document.images[0].alt = "";
|
||||
document.images[0].src = imgURL;
|
||||
</script>
|
||||
</body>
|
||||
|
@ -20,6 +20,7 @@
|
||||
var imgURL = document.location.search.substr(1);
|
||||
document.images[0].onload = onImageLoad;
|
||||
document.images[0].onerror = onImageLoad;
|
||||
document.images[0].alt = "";
|
||||
document.images[0].src = imgURL;
|
||||
</script>
|
||||
</body>
|
||||
|
@ -20,6 +20,7 @@
|
||||
var imgURL = document.location.search.substr(1);
|
||||
document.images[0].onload = onImageLoad;
|
||||
document.images[0].onerror = onImageLoad;
|
||||
document.images[0].alt = "";
|
||||
document.images[0].src = imgURL;
|
||||
</script>
|
||||
</body>
|
||||
|
@ -20,6 +20,7 @@
|
||||
var imgURL = document.location.search.substr(1);
|
||||
document.images[0].onload = onImageLoad;
|
||||
document.images[0].onerror = onImageLoad;
|
||||
document.images[0].alt = "";
|
||||
document.images[0].src = imgURL;
|
||||
</script>
|
||||
</body>
|
||||
|
@ -839,7 +839,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
void *returnAddr)
|
||||
{
|
||||
// saveLive()
|
||||
masm.PushRegsInMask(liveRegs);
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
|
||||
// Remaining registers should basically be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
@ -890,7 +890,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
masm.Push(argUintNReg);
|
||||
attacher.pushStubCodePointer(masm);
|
||||
|
||||
if (!masm.buildOOLFakeExitFrame(returnAddr))
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(ION_FRAME_OOL_NATIVE);
|
||||
|
||||
@ -936,7 +936,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
|
||||
if (!masm.buildOOLFakeExitFrame(returnAddr))
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(ION_FRAME_OOL_PROPERTY_OP);
|
||||
|
||||
@ -1292,7 +1292,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
{
|
||||
JS_ASSERT(output.hasValue());
|
||||
// saveLive()
|
||||
masm.PushRegsInMask(liveRegs);
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
|
||||
// Remaining registers should be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
@ -1329,7 +1329,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
|
||||
if (!masm.buildOOLFakeExitFrame(returnAddr))
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(ION_FRAME_OOL_PROXY);
|
||||
|
||||
@ -2060,7 +2060,7 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
ConstantOrRegister value, void *returnAddr, bool strict)
|
||||
{
|
||||
// saveLive()
|
||||
masm.PushRegsInMask(liveRegs);
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
|
||||
// Remaining registers should be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
@ -2098,7 +2098,7 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
masm.move32(Imm32(strict? 1 : 0), argStrictReg);
|
||||
|
||||
if (!masm.buildOOLFakeExitFrame(returnAddr))
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(ION_FRAME_OOL_PROXY);
|
||||
|
||||
@ -2266,7 +2266,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
// Good to go for invoking setter.
|
||||
|
||||
// saveLive()
|
||||
masm.PushRegsInMask(liveRegs);
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
|
||||
// Remaining registers should basically be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
@ -2319,7 +2319,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
masm.Push(argUintNReg);
|
||||
attacher.pushStubCodePointer(masm);
|
||||
|
||||
if (!masm.buildOOLFakeExitFrame(returnAddr))
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(ION_FRAME_OOL_NATIVE);
|
||||
|
||||
@ -2362,7 +2362,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
|
||||
if (!masm.buildOOLFakeExitFrame(returnAddr))
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(ION_FRAME_OOL_PROPERTY_OP);
|
||||
|
||||
|
@ -237,6 +237,21 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
#endif
|
||||
}
|
||||
|
||||
MacroAssembler(JSContext *cx, IonScript *ion)
|
||||
: enoughMemory_(true),
|
||||
embedsNurseryPointers_(false),
|
||||
sps_(NULL)
|
||||
{
|
||||
constructRoot(cx);
|
||||
ionContext_.construct(cx, (js::jit::TempAllocator *)NULL);
|
||||
alloc_.construct(cx);
|
||||
#ifdef JS_CPU_ARM
|
||||
initWithAllocator();
|
||||
m_buffer.id = GetIonContext()->getNextAssemblerId();
|
||||
#endif
|
||||
setFramePushed(ion->frameSize());
|
||||
}
|
||||
|
||||
void setInstrumentation(IonInstrumentation *sps) {
|
||||
sps_ = sps;
|
||||
}
|
||||
@ -1314,6 +1329,26 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
{
|
||||
convertTypedOrValueToInt(src, temp, output, fail, IntConversion_ClampToUint8);
|
||||
}
|
||||
|
||||
public:
|
||||
class AfterICSaveLive {
|
||||
friend class MacroAssembler;
|
||||
AfterICSaveLive()
|
||||
{}
|
||||
};
|
||||
|
||||
AfterICSaveLive icSaveLive(RegisterSet &liveRegs) {
|
||||
PushRegsInMask(liveRegs);
|
||||
return AfterICSaveLive();
|
||||
}
|
||||
|
||||
bool icBuildOOLFakeExitFrame(void *fakeReturnAddr, AfterICSaveLive &aic) {
|
||||
return buildOOLFakeExitFrame(fakeReturnAddr);
|
||||
}
|
||||
|
||||
void icRestoreLive(RegisterSet &liveRegs, AfterICSaveLive &aic) {
|
||||
PopRegsInMask(liveRegs);
|
||||
}
|
||||
};
|
||||
|
||||
static inline Assembler::DoubleCondition
|
||||
|
@ -1191,7 +1191,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
// Builds an exit frame on the stack, with a return address to an internal
|
||||
// non-function. Returns offset to be passed to markSafepointAt().
|
||||
bool buildFakeExitFrame(const Register &scratch, uint32_t *offset);
|
||||
bool buildOOLFakeExitFrame(void *fakeReturnAddr);
|
||||
|
||||
void callWithExitFrame(IonCode *target);
|
||||
void callWithExitFrame(IonCode *target, Register dynStack);
|
||||
@ -1399,6 +1398,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
void passABIArg(const FloatRegister ®);
|
||||
void passABIArg(const ValueOperand ®s);
|
||||
|
||||
protected:
|
||||
bool buildOOLFakeExitFrame(void *fakeReturnAddr);
|
||||
|
||||
private:
|
||||
void callWithABIPre(uint32_t *stackAdjust);
|
||||
void callWithABIPost(uint32_t stackAdjust, Result result);
|
||||
|
@ -127,7 +127,7 @@ ToStackIndex(LAllocation *a)
|
||||
return a->toStackSlot()->slot();
|
||||
}
|
||||
JS_ASSERT(-int32_t(sizeof(IonJSFrameLayout)) <= a->toArgument()->index());
|
||||
return -(sizeof(IonJSFrameLayout) + a->toArgument()->index());
|
||||
return -int32_t(sizeof(IonJSFrameLayout) + a->toArgument()->index());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -638,13 +638,6 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
return addCodeLabel(cl);
|
||||
}
|
||||
|
||||
bool buildOOLFakeExitFrame(void *fakeReturnAddr) {
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), IonFrame_OptimizedJS);
|
||||
Push(Imm32(descriptor));
|
||||
Push(ImmPtr(fakeReturnAddr));
|
||||
return true;
|
||||
}
|
||||
|
||||
void callWithExitFrame(IonCode *target) {
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), IonFrame_OptimizedJS);
|
||||
Push(Imm32(descriptor));
|
||||
@ -665,6 +658,14 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
void abiret() {
|
||||
ret();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool buildOOLFakeExitFrame(void *fakeReturnAddr) {
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), IonFrame_OptimizedJS);
|
||||
Push(Imm32(descriptor));
|
||||
Push(ImmPtr(fakeReturnAddr));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -544,7 +544,11 @@ TypeSet::unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc)
|
||||
// discarded.
|
||||
|
||||
static LifoAlloc *IonAlloc() {
|
||||
#ifdef JS_ION
|
||||
return jit::GetIonContext()->temp->lifoAlloc();
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Superclass of all constraints generated during Ion compilation. These may
|
||||
@ -575,8 +579,12 @@ class types::CompilerConstraint
|
||||
void
|
||||
CompilerConstraintList::add(CompilerConstraint *constraint)
|
||||
{
|
||||
#ifdef JS_ION
|
||||
if (!constraint || !constraint->expected || !constraints.append(constraint))
|
||||
setFailed();
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -672,16 +680,21 @@ TypeObjectKey::newScript()
|
||||
bool
|
||||
TypeObjectKey::unknownProperties()
|
||||
{
|
||||
#ifdef JS_ION
|
||||
JSContext *cx = jit::GetIonContext()->cx;
|
||||
TypeObject *type = isSingleObject() ? asSingleObject()->getType(cx) : asTypeObject();
|
||||
if (!type)
|
||||
MOZ_CRASH();
|
||||
return type->unknownProperties();
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
HeapTypeSetKey
|
||||
TypeObjectKey::property(jsid id)
|
||||
{
|
||||
#ifdef JS_ION
|
||||
JSContext *cx = jit::GetIonContext()->cx;
|
||||
TypeObject *type = isSingleObject() ? asSingleObject()->getType(cx) : asTypeObject();
|
||||
if (!type)
|
||||
@ -691,6 +704,9 @@ TypeObjectKey::property(jsid id)
|
||||
if (!property.actualTypes)
|
||||
MOZ_CRASH();
|
||||
return property;
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
@ -938,6 +954,7 @@ class ConstraintDataFreezeObjectFlags
|
||||
bool
|
||||
TypeObjectKey::hasFlags(CompilerConstraintList *constraints, TypeObjectFlags flags)
|
||||
{
|
||||
#ifdef JS_ION
|
||||
JS_ASSERT(flags);
|
||||
|
||||
JSContext *cx = jit::GetIonContext()->cx;
|
||||
@ -950,6 +967,9 @@ TypeObjectKey::hasFlags(CompilerConstraintList *constraints, TypeObjectFlags fla
|
||||
HeapTypeSetKey objectProperty = property(JSID_EMPTY);
|
||||
constraints->add(IonAlloc()->new_<CompilerConstraintInstance<ConstraintDataFreezeObjectFlags> >(objectProperty, ConstraintDataFreezeObjectFlags(this, flags)));
|
||||
return false;
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -1653,11 +1673,15 @@ bool
|
||||
types::ArrayPrototypeHasIndexedProperty(CompilerConstraintList *constraints,
|
||||
HandleScript script)
|
||||
{
|
||||
#ifdef JS_ION
|
||||
JSObject *proto = script->global().getOrCreateArrayPrototype(jit::GetIonContext()->cx);
|
||||
if (!proto)
|
||||
return true;
|
||||
|
||||
return PrototypeHasIndexedProperty(constraints, proto);
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1402,8 +1402,10 @@ FinishCompilation(JSContext *cx, JSScript *script, jit::ExecutionMode executionM
|
||||
class CompilerConstraint;
|
||||
class CompilerConstraintList
|
||||
{
|
||||
#ifdef JS_ION
|
||||
// Generated constraints.
|
||||
Vector<CompilerConstraint *, 0, jit::IonAllocPolicy> constraints;
|
||||
#endif
|
||||
|
||||
// OOM during generation of some constraint.
|
||||
bool failed_;
|
||||
@ -1416,10 +1418,18 @@ class CompilerConstraintList
|
||||
void add(CompilerConstraint *constraint);
|
||||
|
||||
size_t length() {
|
||||
#ifdef JS_ION
|
||||
return constraints.length();
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
CompilerConstraint *get(size_t i) {
|
||||
#ifdef JS_ION
|
||||
return constraints[i];
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool failed() {
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include "jswatchpoint.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "assembler/assembler/MacroAssembler.h"
|
||||
#if defined(JS_ION)
|
||||
# include "assembler/assembler/MacroAssembler.h"
|
||||
#endif
|
||||
#include "jit/AsmJSSignalHandlers.h"
|
||||
#include "jit/IonCompartment.h"
|
||||
#include "jit/PcScriptCache.h"
|
||||
|
@ -451,9 +451,9 @@ nsImageFrame::ShouldCreateImageFrameFor(Element* aElement,
|
||||
// - if our special "force icons" style is set, show an icon
|
||||
// - else if our "do not show placeholders" pref is set, skip the icon
|
||||
// - else:
|
||||
// - if QuirksMode, and there is no alt attribute, and this is not an
|
||||
// <object> (which could not possibly have such an attribute), show an
|
||||
// icon.
|
||||
// - if there is a src attribute, there is no alt attribute,
|
||||
// and this is not an <object> (which could not possibly have
|
||||
// such an attribute), show an icon.
|
||||
// - if QuirksMode, and the IMG has a size show an icon.
|
||||
// - otherwise, skip the icon
|
||||
bool useSizedBox;
|
||||
@ -464,29 +464,22 @@ nsImageFrame::ShouldCreateImageFrameFor(Element* aElement,
|
||||
else if (gIconLoad && gIconLoad->mPrefForceInlineAltText) {
|
||||
useSizedBox = false;
|
||||
}
|
||||
else if (aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::src) &&
|
||||
!aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::alt) &&
|
||||
!aElement->IsHTML(nsGkAtoms::object) &&
|
||||
!aElement->IsHTML(nsGkAtoms::input)) {
|
||||
// Use a sized box if we have no alt text. This means no alt attribute
|
||||
// and the node is not an object or an input (since those always have alt
|
||||
// text).
|
||||
useSizedBox = true;
|
||||
}
|
||||
else if (aStyleContext->PresContext()->CompatibilityMode() !=
|
||||
eCompatibility_NavQuirks) {
|
||||
useSizedBox = false;
|
||||
}
|
||||
else {
|
||||
if (aStyleContext->PresContext()->CompatibilityMode() !=
|
||||
eCompatibility_NavQuirks) {
|
||||
useSizedBox = false;
|
||||
}
|
||||
else {
|
||||
// We are in quirks mode, so we can just check the tag name; no need to
|
||||
// check the namespace.
|
||||
nsIAtom *localName = aElement->Tag();
|
||||
|
||||
// Use a sized box if we have no alt text. This means no alt attribute
|
||||
// and the node is not an object or an input (since those always have alt
|
||||
// text).
|
||||
if (!aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::alt) &&
|
||||
localName != nsGkAtoms::object &&
|
||||
localName != nsGkAtoms::input) {
|
||||
useSizedBox = true;
|
||||
}
|
||||
else {
|
||||
// check whether we have fixed size
|
||||
useSizedBox = HaveFixedSize(aStyleContext->StylePosition());
|
||||
}
|
||||
}
|
||||
// check whether we have fixed size
|
||||
useSizedBox = HaveFixedSize(aStyleContext->StylePosition());
|
||||
}
|
||||
|
||||
return useSizedBox;
|
||||
@ -720,9 +713,7 @@ nsImageFrame::EnsureIntrinsicSizeAndRatio(nsPresContext* aPresContext)
|
||||
// invalid image specified
|
||||
// - make the image big enough for the icon (it may not be
|
||||
// used if inline alt expansion is used instead)
|
||||
// XXX: we need this in composer, but it is also good for
|
||||
// XXX: general quirks mode to always have room for the icon
|
||||
if (aPresContext->CompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
if (!(GetStateBits() & NS_FRAME_GENERATED_CONTENT)) {
|
||||
nscoord edgeLengthToUse =
|
||||
nsPresContext::CSSPixelsToAppUnits(
|
||||
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
|
||||
|
@ -1,3 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<img>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<img src="http://www.foo oo.com">
|
||||
<img src="http://www.foo oo.com" alt="">
|
||||
<input type="image" src="http://www.foo oo.com">
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,35 +7,35 @@
|
||||
MODULE = 'jemalloc'
|
||||
|
||||
CSRCS += [
|
||||
'arena.c',
|
||||
'atomic.c',
|
||||
'base.c',
|
||||
'bitmap.c',
|
||||
'chunk.c',
|
||||
'chunk_dss.c',
|
||||
'chunk_mmap.c',
|
||||
'ckh.c',
|
||||
'ctl.c',
|
||||
'extent.c',
|
||||
'hash.c',
|
||||
'huge.c',
|
||||
'jemalloc.c',
|
||||
'mb.c',
|
||||
'mutex.c',
|
||||
'prof.c',
|
||||
'quarantine.c',
|
||||
'rtree.c',
|
||||
'stats.c',
|
||||
'tcache.c',
|
||||
'tsd.c',
|
||||
'util.c',
|
||||
'src/src/arena.c',
|
||||
'src/src/atomic.c',
|
||||
'src/src/base.c',
|
||||
'src/src/bitmap.c',
|
||||
'src/src/chunk.c',
|
||||
'src/src/chunk_dss.c',
|
||||
'src/src/chunk_mmap.c',
|
||||
'src/src/ckh.c',
|
||||
'src/src/ctl.c',
|
||||
'src/src/extent.c',
|
||||
'src/src/hash.c',
|
||||
'src/src/huge.c',
|
||||
'src/src/jemalloc.c',
|
||||
'src/src/mb.c',
|
||||
'src/src/mutex.c',
|
||||
'src/src/prof.c',
|
||||
'src/src/quarantine.c',
|
||||
'src/src/rtree.c',
|
||||
'src/src/stats.c',
|
||||
'src/src/tcache.c',
|
||||
'src/src/tsd.c',
|
||||
'src/src/util.c',
|
||||
]
|
||||
|
||||
# Only OSX needs the zone allocation implementation,
|
||||
# but only if replace-malloc is not enabled.
|
||||
if CONFIG['OS_TARGET'] == 'Darwin' and not CONFIG['MOZ_REPLACE_MALLOC']:
|
||||
CSRCS += [
|
||||
'zone.c',
|
||||
'src/src/zone.c',
|
||||
]
|
||||
|
||||
LIBRARY_NAME = 'jemalloc'
|
||||
|
@ -7,10 +7,6 @@ FORCE_SHARED_LIB= 1
|
||||
|
||||
DEFINES += -DMOZ_NO_MOZALLOC
|
||||
|
||||
VPATH += $(topsrcdir)/xpcom/base
|
||||
VPATH += $(topsrcdir)/nsprpub/lib/libc/src
|
||||
VPATH += $(topsrcdir)/mfbt
|
||||
|
||||
# Disable mozglue.
|
||||
WRAP_LDFLAGS =
|
||||
MOZ_GLUE_LDFLAGS=
|
||||
|
@ -12,12 +12,12 @@ EXPORTS += [
|
||||
|
||||
CPP_SOURCES += [
|
||||
'DMD.cpp',
|
||||
'HashFunctions.cpp',
|
||||
'nsStackWalk.cpp',
|
||||
'../../../mfbt/HashFunctions.cpp',
|
||||
'../../../xpcom/base/nsStackWalk.cpp',
|
||||
]
|
||||
|
||||
CSRCS += [
|
||||
'strcpy.c',
|
||||
'../../../nsprpub/lib/libc/src/strcpy.c',
|
||||
]
|
||||
|
||||
LIBRARY_NAME = 'dmd'
|
||||
|
@ -8,8 +8,8 @@ MODULE = 'memory'
|
||||
NO_DIST_INSTALL = True
|
||||
|
||||
CSRCS += [
|
||||
'jemalloc_config.c',
|
||||
'mozjemalloc_compat.c',
|
||||
'../../build/jemalloc_config.c',
|
||||
'../../build/mozjemalloc_compat.c',
|
||||
]
|
||||
|
||||
# Android doesn't have pthread_atfork, so just implement a dummy function.
|
||||
|
@ -70,6 +70,15 @@
|
||||
#define SECCOMP_WHITELIST_ADD_ARM_LAST
|
||||
#endif
|
||||
|
||||
/* System calls used by the profiler */
|
||||
#ifdef MOZ_PROFILING
|
||||
#define PROFILING_WHITELIST_ADD \
|
||||
ALLOW_SYSCALL(sigaction), \
|
||||
ALLOW_SYSCALL(tgkill),
|
||||
#else
|
||||
#define PROFILING_WHITELIST_ADD
|
||||
#endif
|
||||
|
||||
/* Syscalls specific to arm that should eventually be removed */
|
||||
#if defined(__arm__)
|
||||
#define SECCOMP_WHITELIST_REMOVE_ARM \
|
||||
@ -151,6 +160,7 @@
|
||||
ALLOW_SYSCALL(getpriority), \
|
||||
ALLOW_SYSCALL(setpriority), \
|
||||
ALLOW_SYSCALL(sched_setscheduler), \
|
||||
PROFILING_WHITELIST_ADD \
|
||||
/* Always last and always OK calls */ \
|
||||
SECCOMP_WHITELIST_ADD_ARM_LAST \
|
||||
/* restart_syscall is called internally, generally when debugging */ \
|
||||
|
@ -41,9 +41,11 @@ interface nsIURIContentListener : nsISupports
|
||||
* @param aContentHandler nsIStreamListener that will consume the data.
|
||||
* This should be set to <code>nullptr</code> if
|
||||
* this content listener can't handle the content
|
||||
* type.
|
||||
* type; in this case, doContent should also fail
|
||||
* (i.e., return failure nsresult).
|
||||
*
|
||||
* @return <code>true</code> if the consumer wants to
|
||||
* @return <code>true</code> if the load should
|
||||
* be aborted and consumer wants to
|
||||
* handle the load completely by itself. This
|
||||
* causes the URI Loader do nothing else...
|
||||
* <code>false</code> if the URI Loader should
|
||||
|
Loading…
Reference in New Issue
Block a user