mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to fx-team
This commit is contained in:
commit
2a6c6a2d7a
@ -88,9 +88,9 @@ pref("network.buffer.cache.count", 24);
|
||||
pref("network.buffer.cache.size", 16384);
|
||||
|
||||
// predictive actions
|
||||
pref("network.seer.enable", false); // disabled on b2g
|
||||
pref("network.seer.max-db-size", 2097152); // bytes
|
||||
pref("network.seer.preserve", 50); // percentage of seer data to keep when cleaning up
|
||||
pref("network.predictor.enable", false); // disabled on b2g
|
||||
pref("network.predictor.max-db-size", 2097152); // bytes
|
||||
pref("network.predictor.preserve", 50); // percentage of predictor data to keep when cleaning up
|
||||
|
||||
/* session history */
|
||||
pref("browser.sessionhistory.max_total_viewers", 1);
|
||||
|
@ -370,10 +370,6 @@ var shell = {
|
||||
window.removeEventListener('sizemodechange', this);
|
||||
this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
|
||||
ppmm.removeMessageListener("content-handler", this);
|
||||
if (this.timer) {
|
||||
this.timer.cancel();
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
UserAgentOverrides.uninit();
|
||||
IndexedDBPromptHelper.uninit();
|
||||
@ -475,9 +471,6 @@ var shell = {
|
||||
},
|
||||
|
||||
lastHardwareButtonEventType: null, // property for the hack above
|
||||
needBufferOpenAppReq: true,
|
||||
bufferedOpenAppReqs: [],
|
||||
timer: null,
|
||||
visibleNormalAudioActive: false,
|
||||
|
||||
handleEvent: function shell_handleEvent(evt) {
|
||||
@ -595,20 +588,6 @@ var shell = {
|
||||
Cu.cloneInto(details, getContentWindow()));
|
||||
},
|
||||
|
||||
openAppForSystemMessage: function shell_openAppForSystemMessage(msg) {
|
||||
let payload = {
|
||||
url: msg.pageURL,
|
||||
manifestURL: msg.manifestURL,
|
||||
isActivity: (msg.type == 'activity'),
|
||||
onlyShowApp: msg.onlyShowApp,
|
||||
showApp: msg.showApp,
|
||||
target: msg.target,
|
||||
expectingSystemMessage: true,
|
||||
extra: msg.extra
|
||||
}
|
||||
this.sendCustomEvent('open-app', payload);
|
||||
},
|
||||
|
||||
receiveMessage: function shell_receiveMessage(message) {
|
||||
var activities = { 'content-handler': { name: 'view', response: null },
|
||||
'dial-handler': { name: 'dial', response: null },
|
||||
@ -677,18 +656,6 @@ var shell = {
|
||||
}
|
||||
};
|
||||
|
||||
// Listen for the request of opening app and relay them to Gaia.
|
||||
Services.obs.addObserver(function onSystemMessageOpenApp(subject, topic, data) {
|
||||
let msg = JSON.parse(data);
|
||||
// Buffer non-activity request until content starts to load for 10 seconds.
|
||||
// We'll revisit this later if new kind of requests don't need to be cached.
|
||||
if (shell.needBufferOpenAppReq && msg.type !== 'activity') {
|
||||
shell.bufferedOpenAppReqs.push(msg);
|
||||
return;
|
||||
}
|
||||
shell.openAppForSystemMessage(msg);
|
||||
}, 'system-messages-open-app', false);
|
||||
|
||||
Services.obs.addObserver(function onFullscreenOriginChange(subject, topic, data) {
|
||||
shell.sendChromeEvent({ type: "fullscreenoriginchange",
|
||||
fullscreenorigin: data });
|
||||
@ -717,21 +684,6 @@ var CustomEventManager = {
|
||||
window.addEventListener("ContentStart", (function(evt) {
|
||||
let content = shell.contentBrowser.contentWindow;
|
||||
content.addEventListener("mozContentEvent", this, false, true);
|
||||
|
||||
// After content starts to load for 10 seconds, send and
|
||||
// clean up the buffered open-app requests if there is any.
|
||||
//
|
||||
// TODO: Bug 793420 - Remove the waiting timer for the 'open-app'
|
||||
// mozChromeEvents requested by System Message
|
||||
shell.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
shell.timer.initWithCallback(function timerCallback() {
|
||||
shell.bufferedOpenAppReqs.forEach(function bufferOpenAppReq(msg) {
|
||||
shell.openAppForSystemMessage(msg);
|
||||
});
|
||||
shell.bufferedOpenAppReqs.length = 0;
|
||||
shell.needBufferOpenAppReq = false;
|
||||
shell.timer = null;
|
||||
}, 10000, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}).bind(this), false);
|
||||
},
|
||||
|
||||
|
@ -28,6 +28,10 @@ contract @mozilla.org/dom/activities/ui-glue;1 {3a54788b-48cc-4ab4-93d6-0d6a8ef7
|
||||
component {879ee66c-e246-11e3-9910-74d02b97e723} InterAppCommUIGlue.js
|
||||
contract @mozilla.org/dom/apps/inter-app-comm-ui-glue;1 {879ee66c-e246-11e3-9910-74d02b97e723}
|
||||
|
||||
# SystemMessageGlue.js
|
||||
component {2846f034-e614-11e3-93cd-74d02b97e723} SystemMessageGlue.js
|
||||
contract @mozilla.org/dom/messages/system-message-glue;1 {2846f034-e614-11e3-93cd-74d02b97e723}
|
||||
|
||||
# ProcessGlobal.js
|
||||
component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js
|
||||
contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28}
|
||||
|
@ -52,13 +52,18 @@ let SystemAppProxy = {
|
||||
* window.addEventListener('foo', function (event) {
|
||||
* event.details == 'bar'
|
||||
* });
|
||||
*
|
||||
* @param type The custom event type.
|
||||
* @param details The event details.
|
||||
* @param noPending Set to true to emit this event even before the system
|
||||
* app is ready.
|
||||
*/
|
||||
_sendCustomEvent: function systemApp_sendCustomEvent(type, details) {
|
||||
_sendCustomEvent: function systemApp_sendCustomEvent(type, details, noPending) {
|
||||
let content = this._frame ? this._frame.contentWindow : null;
|
||||
|
||||
// If the system app isn't ready yet,
|
||||
// queue events until someone calls setIsLoaded
|
||||
if (!this._isReady || !content) {
|
||||
// queue events until someone calls setIsReady
|
||||
if (!content || (!this._isReady && !noPending)) {
|
||||
this._pendingEvents.push([type, details]);
|
||||
return null;
|
||||
}
|
||||
|
42
b2g/components/SystemMessageGlue.js
Normal file
42
b2g/components/SystemMessageGlue.js
Normal file
@ -0,0 +1,42 @@
|
||||
/* 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/. */
|
||||
|
||||
"use strict"
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
function SystemMessageGlue() {
|
||||
}
|
||||
|
||||
SystemMessageGlue.prototype = {
|
||||
openApp: function(aPageURL, aManifestURL, aType, aTarget, aShowApp,
|
||||
aOnlyShowApp, aExtra) {
|
||||
let payload = { url: aPageURL,
|
||||
manifestURL: aManifestURL,
|
||||
isActivity: (aType == "activity"),
|
||||
target: aTarget,
|
||||
showApp: aShowApp,
|
||||
onlyShowApp: aOnlyShowApp,
|
||||
expectingSystemMessage: true,
|
||||
extra: aExtra };
|
||||
|
||||
// |SystemAppProxy| will queue "open-app" events for non-activity system
|
||||
// messages without actually sending them until the system app is ready.
|
||||
SystemAppProxy._sendCustomEvent("open-app", payload, (aType == "activity"));
|
||||
},
|
||||
|
||||
classID: Components.ID("{2846f034-e614-11e3-93cd-74d02b97e723}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessageGlue])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemMessageGlue]);
|
@ -18,6 +18,7 @@ EXTRA_COMPONENTS += [
|
||||
'PaymentGlue.js',
|
||||
'ProcessGlobal.js',
|
||||
'SmsProtocolHandler.js',
|
||||
'SystemMessageGlue.js',
|
||||
'TelProtocolHandler.js',
|
||||
'WebappsUpdateTimer.js',
|
||||
'YoutubeProtocolHandler.js',
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "33a8ca00e3128502d0c4c834236be335c0060f43",
|
||||
"revision": "cd1a16d6212a1867ecf1d1cfcd62f80abf9ae0b1",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -802,6 +802,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
||||
@BINPATH@/components/HelperAppDialog.js
|
||||
@BINPATH@/components/DownloadsUI.js
|
||||
@BINPATH@/components/InterAppCommUIGlue.js
|
||||
@BINPATH@/components/SystemMessageGlue.js
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
@BINPATH@/components/SimulatorScreen.js
|
||||
|
@ -221,9 +221,9 @@ Sanitizer.prototype = {
|
||||
catch (e) { }
|
||||
|
||||
try {
|
||||
var seer = Components.classes["@mozilla.org/network/seer;1"]
|
||||
.getService(Components.interfaces.nsINetworkSeer);
|
||||
seer.reset();
|
||||
var predictor = Components.classes["@mozilla.org/network/predictor;1"]
|
||||
.getService(Components.interfaces.nsINetworkPredictor);
|
||||
predictor.reset();
|
||||
} catch (e) { }
|
||||
},
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#define ERROR_STR "error"
|
||||
@ -105,27 +105,21 @@ FileIOObject::DispatchError(nsresult rv, nsAString& finalEvent)
|
||||
nsresult
|
||||
FileIOObject::DispatchProgressEvent(const nsAString& aType)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
|
||||
nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ProgressEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
init.mLoaded = mTransferred;
|
||||
|
||||
event->SetTrusted(true);
|
||||
nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
|
||||
NS_ENSURE_TRUE(progress, NS_ERROR_UNEXPECTED);
|
||||
|
||||
bool known;
|
||||
uint64_t size;
|
||||
if (mTotal != kUnknownSize) {
|
||||
known = true;
|
||||
size = mTotal;
|
||||
init.mLengthComputable = true;
|
||||
init.mTotal = mTotal;
|
||||
} else {
|
||||
known = false;
|
||||
size = 0;
|
||||
init.mLengthComputable = false;
|
||||
init.mTotal = 0;
|
||||
}
|
||||
rv = progress->InitProgressEvent(aType, false, false, known,
|
||||
mTransferred, size);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRefPtr<ProgressEvent> event =
|
||||
ProgressEvent::Constructor(this, aType, init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
}
|
||||
|
@ -4639,6 +4639,16 @@ nsContentUtils::GetAccelKeyCandidates(nsIDOMKeyEvent* aDOMKeyEvent,
|
||||
aCandidates.AppendElement(key);
|
||||
}
|
||||
}
|
||||
|
||||
// Special case for "Space" key. With some keyboard layouts, "Space" with
|
||||
// or without Shift key causes non-ASCII space. For such keyboard layouts,
|
||||
// we should guarantee that the key press works as an ASCII white space key
|
||||
// press.
|
||||
if (nativeKeyEvent->mCodeNameIndex == CODE_NAME_INDEX_Space &&
|
||||
nativeKeyEvent->charCode != static_cast<uint32_t>(' ')) {
|
||||
nsShortcutCandidate spaceKey(static_cast<uint32_t>(' '), false);
|
||||
aCandidates.AppendElement(spaceKey);
|
||||
}
|
||||
} else {
|
||||
uint32_t charCode;
|
||||
aDOMKeyEvent->GetCharCode(&charCode);
|
||||
@ -4681,6 +4691,14 @@ nsContentUtils::GetAccessKeyCandidates(WidgetKeyboardEvent* aNativeKeyEvent,
|
||||
aCandidates.AppendElement(ch[j]);
|
||||
}
|
||||
}
|
||||
// Special case for "Space" key. With some keyboard layouts, "Space" with
|
||||
// or without Shift key causes non-ASCII space. For such keyboard layouts,
|
||||
// we should guarantee that the key press works as an ASCII white space key
|
||||
// press.
|
||||
if (aNativeKeyEvent->mCodeNameIndex == CODE_NAME_INDEX_Space &&
|
||||
aNativeKeyEvent->charCode != static_cast<uint32_t>(' ')) {
|
||||
aCandidates.AppendElement(static_cast<uint32_t>(' '));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include "nsCrossSiteListenerProxy.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "nsINetworkSeer.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
|
||||
#include "mozilla/CORSMode.h"
|
||||
@ -345,8 +345,8 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(docshell));
|
||||
mozilla::net::SeerLearn(aRequest->mURI, mDocument->GetDocumentURI(),
|
||||
nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, loadContext);
|
||||
mozilla::net::PredictorLearn(aRequest->mURI, mDocument->GetDocumentURI(),
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, loadContext);
|
||||
|
||||
// Set the initiator type
|
||||
nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel));
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsDOMBlobBuilder.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "nsIJARChannel.h"
|
||||
#include "nsIJARURI.h"
|
||||
#include "nsLayoutCID.h"
|
||||
@ -1465,21 +1465,15 @@ nsXMLHttpRequest::DispatchProgressEvent(DOMEventTargetHelper* aTarget,
|
||||
aType.EqualsLiteral(TIMEOUT_STR) ||
|
||||
aType.EqualsLiteral(ABORT_STR);
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
|
||||
nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
|
||||
if (!progress) {
|
||||
return;
|
||||
}
|
||||
|
||||
progress->InitProgressEvent(aType, false, false, aLengthComputable,
|
||||
aLoaded, (aTotal == UINT64_MAX) ? 0 : aTotal);
|
||||
ProgressEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
init.mLengthComputable = aLengthComputable;
|
||||
init.mLoaded = aLoaded;
|
||||
init.mTotal = (aTotal == UINT64_MAX) ? 0 : aTotal;
|
||||
|
||||
nsRefPtr<ProgressEvent> event =
|
||||
ProgressEvent::Constructor(aTarget, aType, init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
aTarget->DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "nsContentCID.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
@ -2725,25 +2725,19 @@ HTMLInputElement::DispatchProgressEvent(const nsAString& aType,
|
||||
{
|
||||
NS_ASSERTION(!aType.IsEmpty(), "missing event type");
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
|
||||
nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
|
||||
if (!progress) {
|
||||
return;
|
||||
}
|
||||
|
||||
progress->InitProgressEvent(aType, false, true, aLengthComputable,
|
||||
aLoaded, (aTotal == UINT64_MAX) ? 0 : aTotal);
|
||||
ProgressEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = true; // XXXkhuey why?
|
||||
init.mLengthComputable = aLengthComputable;
|
||||
init.mLoaded = aLoaded;
|
||||
init.mTotal = (aTotal == UINT64_MAX) ? 0 : aTotal;
|
||||
|
||||
nsRefPtr<ProgressEvent> event =
|
||||
ProgressEvent::Constructor(this, aType, init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
bool doDefaultAction;
|
||||
rv = DispatchEvent(event, &doDefaultAction);
|
||||
nsresult rv = DispatchEvent(event, &doDefaultAction);
|
||||
if (NS_SUCCEEDED(rv) && !doDefaultAction) {
|
||||
CancelDirectoryPickerScanIfRunning();
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "MediaError.h"
|
||||
#include "MediaDecoder.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -120,7 +120,7 @@
|
||||
#include "nsIFaviconService.h"
|
||||
#include "mozIAsyncFavicons.h"
|
||||
#endif
|
||||
#include "nsINetworkSeer.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
|
||||
// Editor-related
|
||||
#include "nsIEditingSession.h"
|
||||
@ -7211,7 +7211,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
|
||||
}
|
||||
} // if we have a host
|
||||
else if (url && NS_SUCCEEDED(aStatus)) {
|
||||
mozilla::net::SeerLearnRedirect(url, aChannel, this);
|
||||
mozilla::net::PredictorLearnRedirect(url, aChannel, this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -9603,8 +9603,9 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
else
|
||||
srcdoc = NullString();
|
||||
|
||||
mozilla::net::SeerPredict(aURI, nullptr, nsINetworkSeer::PREDICT_LOAD,
|
||||
this, nullptr);
|
||||
mozilla::net::PredictorPredict(aURI, nullptr,
|
||||
nsINetworkPredictor::PREDICT_LOAD,
|
||||
this, nullptr);
|
||||
|
||||
nsCOMPtr<nsIRequest> req;
|
||||
rv = DoURILoad(aURI, aReferrer,
|
||||
@ -12733,8 +12734,9 @@ nsDocShell::OnOverLink(nsIContent* aContent,
|
||||
rv = textToSubURI->UnEscapeURIForUI(charset, spec, uStr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mozilla::net::SeerPredict(aURI, mCurrentURI, nsINetworkSeer::PREDICT_LINK,
|
||||
this, nullptr);
|
||||
mozilla::net::PredictorPredict(aURI, mCurrentURI,
|
||||
nsINetworkPredictor::PREDICT_LINK,
|
||||
this, nullptr);
|
||||
|
||||
if (browserChrome2) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
|
||||
|
@ -29,6 +29,7 @@ namespace dom {
|
||||
|
||||
class EventTarget;
|
||||
class ErrorEvent;
|
||||
class ProgressEvent;
|
||||
|
||||
// Dummy class so we can cast through it to get from nsISupports to
|
||||
// Event subclasses with only two non-ambiguous static casts.
|
||||
@ -97,6 +98,11 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual ProgressEvent* AsProgressEvent()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// nsIDOMEvent Interface
|
||||
NS_DECL_NSIDOMEVENT
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsLiteralString.h"
|
||||
|
||||
@ -135,21 +135,15 @@ FileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
|
||||
nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
|
||||
MOZ_ASSERT(progress);
|
||||
rv = progress->InitProgressEvent(NS_LITERAL_STRING("progress"), false, false,
|
||||
false, aLoaded, aTotal);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
ProgressEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
init.mLengthComputable = false;
|
||||
init.mLoaded = aLoaded;
|
||||
init.mTotal = aTotal;
|
||||
|
||||
nsRefPtr<ProgressEvent> event =
|
||||
ProgressEvent::Constructor(this, NS_LITERAL_STRING("progress"), init);
|
||||
DispatchTrustedEvent(event);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,6 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMPaintRequest.idl',
|
||||
'nsIDOMPopStateEvent.idl',
|
||||
'nsIDOMPopupBlockedEvent.idl',
|
||||
'nsIDOMProgressEvent.idl',
|
||||
'nsIDOMRecordErrorEvent.idl',
|
||||
'nsIDOMScrollAreaEvent.idl',
|
||||
'nsIDOMSimpleGestureEvent.idl',
|
||||
|
@ -327,11 +327,6 @@ NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
mozilla::dom::EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
mozilla::WidgetEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
mozilla::dom::EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
mozilla::WidgetEvent* aEvent);
|
||||
// This empties aInvalidateRequests.
|
||||
nsresult
|
||||
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult,
|
||||
|
@ -1,26 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsIDOMEvent.idl"
|
||||
|
||||
/**
|
||||
* ProgressEvent can be used for measuring progress.
|
||||
*/
|
||||
|
||||
[builtinclass, uuid(e0682338-4c3f-4d3a-9487-d7492ea76335)]
|
||||
interface nsIDOMProgressEvent : nsIDOMEvent
|
||||
{
|
||||
readonly attribute boolean lengthComputable;
|
||||
readonly attribute unsigned long long loaded;
|
||||
readonly attribute unsigned long long total;
|
||||
[noscript]
|
||||
void initProgressEvent(in DOMString typeArg,
|
||||
in boolean canBubbleArg,
|
||||
in boolean cancelableArg,
|
||||
in boolean lengthComputableArg,
|
||||
in unsigned long long loadedArg,
|
||||
in unsigned long long totalArg);
|
||||
};
|
@ -548,6 +548,7 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
|
||||
GetCPOWManager();
|
||||
|
||||
SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
|
||||
InitProcessAttributes();
|
||||
|
||||
return true;
|
||||
@ -556,8 +557,6 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
void
|
||||
ContentChild::InitProcessAttributes()
|
||||
{
|
||||
SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
SetProcessName(NS_LITERAL_STRING("(Nuwa)"), false);
|
||||
@ -925,7 +924,10 @@ ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
|
||||
|
||||
PBrowserChild*
|
||||
ContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags)
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
// We'll happily accept any kind of IPCTabContext here; we don't need to
|
||||
// check that it's of a certain type for security purposes, because we
|
||||
@ -946,9 +948,12 @@ ContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvPBrowserConstructor(PBrowserChild* actor,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags)
|
||||
ContentChild::RecvPBrowserConstructor(PBrowserChild* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
// This runs after AllocPBrowserChild() returns and the IPC machinery for this
|
||||
// PBrowserChild has been set up.
|
||||
@ -956,7 +961,7 @@ ContentChild::RecvPBrowserConstructor(PBrowserChild* actor,
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
nsITabChild* tc =
|
||||
static_cast<nsITabChild*>(static_cast<TabChild*>(actor));
|
||||
static_cast<nsITabChild*>(static_cast<TabChild*>(aActor));
|
||||
os->NotifyObservers(tc, "tab-child-created", nullptr);
|
||||
}
|
||||
|
||||
@ -970,6 +975,9 @@ ContentChild::RecvPBrowserConstructor(PBrowserChild* actor,
|
||||
|
||||
// Redo InitProcessAttributes() when the app or browser is really
|
||||
// launching so the attributes will be correct.
|
||||
mID = aID;
|
||||
mIsForApp = aIsForApp;
|
||||
mIsForBrowser = aIsForBrowser;
|
||||
InitProcessAttributes();
|
||||
}
|
||||
|
||||
|
@ -104,8 +104,11 @@ public:
|
||||
AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext &aContext,
|
||||
const uint32_t &chromeFlags);
|
||||
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser);
|
||||
virtual bool DeallocPBrowserChild(PBrowserChild*);
|
||||
|
||||
virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequestChild(const DeviceStorageParams&);
|
||||
@ -305,9 +308,12 @@ public:
|
||||
DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual bool RecvPBrowserConstructor(PBrowserChild* actor,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags) MOZ_OVERRIDE;
|
||||
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
@ -800,7 +800,10 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
// DeallocPBrowserParent() releases this ref.
|
||||
tp.forget().take(),
|
||||
aContext.AsIPCTabContext(),
|
||||
chromeFlags);
|
||||
chromeFlags,
|
||||
cp->ChildID(),
|
||||
cp->IsForApp(),
|
||||
cp->IsForBrowser());
|
||||
return static_cast<TabParent*>(browser);
|
||||
}
|
||||
return nullptr;
|
||||
@ -898,7 +901,10 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
// DeallocPBrowserParent() releases this ref.
|
||||
nsRefPtr<TabParent>(tp).forget().take(),
|
||||
aContext.AsIPCTabContext(),
|
||||
chromeFlags);
|
||||
chromeFlags,
|
||||
p->ChildID(),
|
||||
p->IsForApp(),
|
||||
p->IsForBrowser());
|
||||
|
||||
p->MaybeTakeCPUWakeLock(aFrameElement);
|
||||
|
||||
@ -2416,7 +2422,10 @@ ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
|
||||
|
||||
PBrowserParent*
|
||||
ContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
const uint32_t &aChromeFlags)
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
unused << aChromeFlags;
|
||||
|
||||
|
@ -152,6 +152,10 @@ public:
|
||||
|
||||
bool IsAlive();
|
||||
bool IsForApp();
|
||||
bool IsForBrowser()
|
||||
{
|
||||
return mIsForBrowser;
|
||||
}
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
bool IsNuwaProcess();
|
||||
#endif
|
||||
@ -360,7 +364,10 @@ private:
|
||||
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserParent* AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags) MOZ_OVERRIDE;
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPBrowserParent(PBrowserParent* frame) MOZ_OVERRIDE;
|
||||
|
||||
virtual PDeviceStorageRequestParent*
|
||||
|
@ -323,7 +323,10 @@ both:
|
||||
// privileges by requesting a PBrowser corresponding to a highly-privileged
|
||||
// app; the child can only request privileges for an app which the child has
|
||||
// access to (in the form of a TabChild).
|
||||
async PBrowser(IPCTabContext context, uint32_t chromeFlags);
|
||||
//
|
||||
// Keep the last 3 attributes in sync with GetProcessAttributes!
|
||||
async PBrowser(IPCTabContext context, uint32_t chromeFlags,
|
||||
uint64_t id, bool isForApp, bool isForBrowser);
|
||||
|
||||
async PBlob(BlobConstructorParams params);
|
||||
|
||||
@ -432,6 +435,8 @@ parent:
|
||||
* isForBrowser|, we're loading <browser> for an app. When
|
||||
* |isForBrowser|, we're loading <browser>. When |!isForApp &&
|
||||
* !isForBrowser|, we're probably loading <xul:browser remote>.
|
||||
*
|
||||
* Keep the return values in sync with PBrowser()!
|
||||
*/
|
||||
sync GetProcessAttributes()
|
||||
returns (uint64_t id, bool isForApp, bool isForBrowser);
|
||||
|
@ -1257,10 +1257,12 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
context.openerChild() = this;
|
||||
context.isBrowserElement() = IsBrowserElement();
|
||||
|
||||
ContentChild* cc = static_cast<ContentChild*>(Manager());
|
||||
unused << Manager()->SendPBrowserConstructor(
|
||||
// We release this ref in DeallocPBrowserChild
|
||||
nsRefPtr<TabChild>(newChild).forget().take(),
|
||||
IPCTabContext(context, mScrolling), /* chromeFlags */ 0);
|
||||
IPCTabContext(context, mScrolling), /* chromeFlags */ 0,
|
||||
cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
|
||||
|
||||
nsAutoCString spec;
|
||||
if (aURI) {
|
||||
|
@ -585,18 +585,20 @@ SystemMessageInternal.prototype = {
|
||||
// and we don't need to load the app to handle messages.
|
||||
let onlyShowApp = (aMsgSentStatus === MSG_SENT_SUCCESS) && showApp;
|
||||
|
||||
// We don't need to send the full object to observers.
|
||||
let page = { pageURL: aPage.pageURL,
|
||||
manifestURL: aPage.manifestURL,
|
||||
type: aPage.type,
|
||||
extra: aExtra,
|
||||
target: aMessage.target,
|
||||
onlyShowApp: onlyShowApp,
|
||||
showApp: showApp };
|
||||
debug("Asking to open " + JSON.stringify(page));
|
||||
Services.obs.notifyObservers(this,
|
||||
"system-messages-open-app",
|
||||
JSON.stringify(page));
|
||||
debug("Asking to open pageURL: " + aPage.pageURL +
|
||||
", manifestURL: " + aPage.manifestURL + ", type: " + aPage.type +
|
||||
", target: " + JSON.stringify(aMessage.target) +
|
||||
", showApp: " + showApp + ", onlyShowApp: " + onlyShowApp +
|
||||
", extra: " + JSON.stringify(aExtra));
|
||||
|
||||
let glue = Cc["@mozilla.org/dom/messages/system-message-glue;1"]
|
||||
.createInstance(Ci.nsISystemMessageGlue);
|
||||
if (glue) {
|
||||
glue.openApp(aPage.pageURL, aPage.manifestURL, aPage.type, aMessage.target,
|
||||
showApp, onlyShowApp, aExtra);
|
||||
} else {
|
||||
debug("Error! The UI glue component is not implemented.");
|
||||
}
|
||||
},
|
||||
|
||||
_isPageMatched: function(aPage, aType, aPageURL, aManifestURL) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMNavigatorSystemMessages.idl',
|
||||
'nsISystemMessageGlue.idl',
|
||||
'nsISystemMessagesInternal.idl',
|
||||
]
|
||||
|
||||
|
31
dom/messages/interfaces/nsISystemMessageGlue.idl
Normal file
31
dom/messages/interfaces/nsISystemMessageGlue.idl
Normal file
@ -0,0 +1,31 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
// Implemented by the contract id @mozilla.org/dom/messages/system-message-glue;1
|
||||
|
||||
[scriptable, uuid(b5d98286-e7cc-11e3-92fb-74d02b97e723)]
|
||||
interface nsISystemMessageGlue : nsISupports
|
||||
{
|
||||
/* Notify the system app to open the target app.
|
||||
*
|
||||
* @param pageURL The URL of the page that will be opened.
|
||||
* @param manifestURL The webapp's manifest URL.
|
||||
* @param type The message type.
|
||||
* @param target The target which the message is associated with.
|
||||
* @param showApp This flag indicates the app must be brought to the
|
||||
* foreground.
|
||||
* @param onlyShowApp This flag indicates the app must be *only* brought to
|
||||
* the foreground without loading to handle messages.
|
||||
* @param extra Extra opaque info to pass around for opening the page.
|
||||
*/
|
||||
void openApp(in DOMString pageURL,
|
||||
in DOMString manifestURL,
|
||||
in DOMString type,
|
||||
in jsval target,
|
||||
in boolean showApp,
|
||||
in boolean onlyShowApp,
|
||||
[optional] in jsval extra);
|
||||
};
|
@ -53,6 +53,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
|
||||
[test_resource_timing.html]
|
||||
skip-if = buildapp == 'b2g' # b2g(No clipboard) b2g-debug(No clipboard) b2g-desktop(No clipboard)
|
||||
[test_performance_now.html]
|
||||
[test_srcset_pref.html]
|
||||
[test_showModalDialog.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #Don't run modal tests on Android # b2g(showmodaldialog) b2g-debug(showmodaldialog) b2g-desktop(showmodaldialog)
|
||||
[test_stylesheetPI.html]
|
||||
|
43
dom/tests/mochitest/general/test_srcset_pref.html
Normal file
43
dom/tests/mochitest/general/test_srcset_pref.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=870021
|
||||
-->
|
||||
<head>
|
||||
<title>Test for dom.image.srcset.enabled (Bug 870021)</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runTest()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=870021">Mozilla Bug 870021</a>
|
||||
|
||||
<img src="http://example.com/tests/image/test/mochitest/blue.png"
|
||||
srcset="http://example.com/tests/image/test/mochitest/big.png">
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
const srcsetPref = 'dom.image.srcset.enabled';
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
is(SpecialPowers.getBoolPref(srcsetPref), false, "srcset should be disabled pending bug 1018389");
|
||||
|
||||
function runTest() {
|
||||
var img = document.querySelector("img");
|
||||
is(img.currentSrc, undefined, "currentSrc should not be visible");
|
||||
is(img.srcset, undefined, "srcset should not be visible");
|
||||
|
||||
var currentSrcDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "currentSrc");
|
||||
var srcsetDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "srcset");
|
||||
is(currentSrcDesc, undefined, "HTMLImageElement should know nothing of currentSrc");
|
||||
is(srcsetDesc, undefined, "HTMLImageElement should know nothing of srcset");
|
||||
|
||||
// Make sure the test image loaded the src image, which is 1x1, not the srcset image
|
||||
is(img.naturalWidth, 1, "Image should have loaded small source");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -58,9 +58,9 @@ partial interface HTMLImageElement {
|
||||
|
||||
// [Update me: not in whatwg spec yet]
|
||||
// http://picture.responsiveimages.org/#the-img-element
|
||||
[Pref="dom.image.srcset.enabled"]
|
||||
partial interface HTMLImageElement {
|
||||
readonly attribute DOMString? currentSrc;
|
||||
[Pref="dom.image.srcset.enabled"]
|
||||
readonly attribute DOMString? currentSrc;
|
||||
};
|
||||
|
||||
// Mozilla extensions.
|
||||
|
@ -4,7 +4,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
[Constructor(DOMString type, optional ProgressEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
|
||||
[Constructor(DOMString type, optional ProgressEventInit eventInitDict)]
|
||||
interface ProgressEvent : Event
|
||||
{
|
||||
readonly attribute boolean lengthComputable;
|
||||
|
@ -640,6 +640,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
|
||||
'MozInterAppMessageEvent.webidl',
|
||||
'MozOtaStatusEvent.webidl',
|
||||
'MozStkCommandEvent.webidl',
|
||||
'ProgressEvent.webidl',
|
||||
'RTCDataChannelEvent.webidl',
|
||||
'RTCPeerConnectionIceEvent.webidl',
|
||||
'RTCPeerConnectionIdentityErrorEvent.webidl',
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
@ -16,6 +15,7 @@
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
@ -1040,7 +1040,7 @@ Proxy::HandleEvent(nsIDOMEvent* aEvent)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXMLHttpRequestUpload> uploadTarget = do_QueryInterface(target);
|
||||
nsCOMPtr<nsIDOMProgressEvent> progressEvent = do_QueryInterface(aEvent);
|
||||
ProgressEvent* progressEvent = aEvent->InternalDOMEvent()->AsProgressEvent();
|
||||
|
||||
nsRefPtr<EventRunnable> runnable;
|
||||
|
||||
@ -1053,16 +1053,10 @@ Proxy::HandleEvent(nsIDOMEvent* aEvent)
|
||||
}
|
||||
|
||||
if (progressEvent) {
|
||||
bool lengthComputable;
|
||||
uint64_t loaded, total;
|
||||
if (NS_FAILED(progressEvent->GetLengthComputable(&lengthComputable)) ||
|
||||
NS_FAILED(progressEvent->GetLoaded(&loaded)) ||
|
||||
NS_FAILED(progressEvent->GetTotal(&total))) {
|
||||
NS_WARNING("Bad progress event!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
runnable = new EventRunnable(this, !!uploadTarget, type, lengthComputable,
|
||||
loaded, total);
|
||||
runnable = new EventRunnable(this, !!uploadTarget, type,
|
||||
progressEvent->LengthComputable(),
|
||||
progressEvent->Loaded(),
|
||||
progressEvent->Total());
|
||||
}
|
||||
else {
|
||||
runnable = new EventRunnable(this, !!uploadTarget, type);
|
||||
@ -1343,13 +1337,14 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
if (mProgressEvent) {
|
||||
NS_NewDOMProgressEvent(getter_AddRefs(event), target, nullptr, nullptr);
|
||||
nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
|
||||
ProgressEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
init.mLengthComputable = mLengthComputable;
|
||||
init.mLoaded = mLoaded;
|
||||
init.mTotal = mTotal;
|
||||
|
||||
if (progress) {
|
||||
progress->InitProgressEvent(mType, false, false, mLengthComputable,
|
||||
mLoaded, mTotal);
|
||||
}
|
||||
event = ProgressEvent::Constructor(target, mType, init);
|
||||
}
|
||||
else {
|
||||
NS_NewDOMEvent(getter_AddRefs(event), target, nullptr, nullptr);
|
||||
@ -1739,23 +1734,20 @@ XMLHttpRequest::DispatchPrematureAbortEvent(EventTarget* aTarget,
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_NewDOMProgressEvent(getter_AddRefs(event), aTarget, nullptr, nullptr);
|
||||
|
||||
nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
|
||||
if (progress) {
|
||||
if (aUploadTarget) {
|
||||
progress->InitProgressEvent(aEventType, false, false,
|
||||
mProxy->mLastUploadLengthComputable,
|
||||
mProxy->mLastUploadLoaded,
|
||||
mProxy->mLastUploadTotal);
|
||||
}
|
||||
else {
|
||||
progress->InitProgressEvent(aEventType, false, false,
|
||||
mProxy->mLastLengthComputable,
|
||||
mProxy->mLastLoaded,
|
||||
mProxy->mLastTotal);
|
||||
}
|
||||
ProgressEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
if (aUploadTarget) {
|
||||
init.mLengthComputable = mProxy->mLastUploadLengthComputable;
|
||||
init.mLoaded = mProxy->mLastUploadLoaded;
|
||||
init.mTotal = mProxy->mLastUploadTotal;
|
||||
}
|
||||
else {
|
||||
init.mLengthComputable = mProxy->mLastLengthComputable;
|
||||
init.mLoaded = mProxy->mLastLoaded;
|
||||
init.mTotal = mProxy->mLastTotal;
|
||||
}
|
||||
event = ProgressEvent::Constructor(aTarget, aEventType, init);
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
|
@ -31,9 +31,6 @@ public:
|
||||
~TextureImageCGL();
|
||||
|
||||
protected:
|
||||
already_AddRefed<gfxASurface>
|
||||
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
|
||||
|
||||
bool FinishedSurfaceUpdate();
|
||||
|
||||
void FinishedSurfaceUpload();
|
||||
@ -41,7 +38,6 @@ protected:
|
||||
private:
|
||||
|
||||
GLuint mPixelBuffer;
|
||||
int32_t mPixelBufferSize;
|
||||
bool mBoundPixelBuffer;
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,6 @@ TextureImageCGL::TextureImageCGL(GLuint aTexture,
|
||||
: BasicTextureImage(aTexture, aSize, aWrapMode, aContentType,
|
||||
aContext, aFlags, aImageFormat)
|
||||
, mPixelBuffer(0)
|
||||
, mPixelBufferSize(0)
|
||||
, mBoundPixelBuffer(false)
|
||||
{}
|
||||
|
||||
@ -38,56 +37,6 @@ TextureImageCGL::~TextureImageCGL()
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
TextureImageCGL::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
|
||||
{
|
||||
IntSize size(aSize.width + 1, aSize.height + 1);
|
||||
mGLContext->MakeCurrent();
|
||||
if (!mGLContext->
|
||||
IsExtensionSupported(GLContext::ARB_pixel_buffer_object))
|
||||
{
|
||||
return gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(size,
|
||||
gfxASurface::ContentFromFormat(aFmt));
|
||||
}
|
||||
|
||||
if (!mPixelBuffer) {
|
||||
mGLContext->fGenBuffers(1, &mPixelBuffer);
|
||||
}
|
||||
mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
|
||||
int32_t length = size.width * 4 * size.height;
|
||||
|
||||
if (length > mPixelBufferSize) {
|
||||
mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, length,
|
||||
NULL, LOCAL_GL_STREAM_DRAW);
|
||||
mPixelBufferSize = length;
|
||||
}
|
||||
unsigned char* data =
|
||||
(unsigned char*)mGLContext->
|
||||
fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER,
|
||||
LOCAL_GL_WRITE_ONLY);
|
||||
|
||||
mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
if (!data) {
|
||||
nsAutoCString failure;
|
||||
failure += "Pixel buffer binding failed: ";
|
||||
failure.AppendPrintf("%dx%d\n", size.width, size.height);
|
||||
gfx::LogFailure(failure);
|
||||
|
||||
mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
return gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(size,
|
||||
gfxASurface::ContentFromFormat(aFmt));
|
||||
}
|
||||
|
||||
nsRefPtr<gfxQuartzSurface> surf =
|
||||
new gfxQuartzSurface(data, ThebesIntSize(size), size.width * 4, aFmt);
|
||||
|
||||
mBoundPixelBuffer = true;
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
TextureImageCGL::FinishedSurfaceUpdate()
|
||||
{
|
||||
|
@ -69,14 +69,6 @@ AddRegion(nsIntRegion& aDest, const nsIntRegion& aSource)
|
||||
aDest.SimplifyOutward(20);
|
||||
}
|
||||
|
||||
|
||||
static nsIntRegion
|
||||
TransformRegion(nsIntRegion& aRegion, const gfx3DMatrix& aTransform)
|
||||
{
|
||||
aRegion.Transform(aTransform);
|
||||
return aRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks over this layer, and all descendant layers.
|
||||
* If any of these are a ContainerLayer that reports invalidations to a PresShell,
|
||||
@ -325,7 +317,8 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
|
||||
gfx3DMatrix transform;
|
||||
gfx::To3DMatrix(mLayer->GetTransform(), transform);
|
||||
return TransformRegion(result, transform);
|
||||
result.Transform(transform);
|
||||
return result;
|
||||
}
|
||||
|
||||
// The old list of children:
|
||||
|
@ -390,7 +390,9 @@ ContainerRender(ContainerT* aContainer,
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (gfxUtils::sDumpPainting) {
|
||||
RefPtr<gfx::DataSourceSurface> surf = surface->Dump(aManager->GetCompositor());
|
||||
WriteSnapshotToDumpFile(aContainer, surf);
|
||||
if (surf) {
|
||||
WriteSnapshotToDumpFile(aContainer, surf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
@ -19,6 +21,7 @@
|
||||
#include "gfxFontTest.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
enum {
|
||||
S_UTF8 = 0,
|
||||
@ -185,12 +188,11 @@ MakeContext ()
|
||||
{
|
||||
const int size = 200;
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenContentDrawTarget(IntSize(size, size),
|
||||
SurfaceFormat::B8G8R8X8);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
|
||||
|
||||
surface = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(IntSize(size, size),
|
||||
gfxASurface::ContentFromFormat(gfxImageFormat::RGB24));
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surface);
|
||||
return ctx.forget();
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
@ -21,6 +23,7 @@
|
||||
#include "gfxFontTest.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
struct TestEntry {
|
||||
const char* mFamilies;
|
||||
@ -37,12 +40,11 @@ MakeContext ()
|
||||
{
|
||||
const int size = 200;
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenContentDrawTarget(IntSize(size, size),
|
||||
SurfaceFormat::B8G8R8X8);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
|
||||
|
||||
surface = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(IntSize(size, size),
|
||||
gfxASurface::ContentFromFormat(gfxImageFormat::RGB24));
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surface);
|
||||
return ctx.forget();
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
@ -19,6 +21,9 @@
|
||||
#include "gfxFontTest.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
class FrameTextRunCache;
|
||||
|
||||
static FrameTextRunCache *gTextRuns = nullptr;
|
||||
@ -78,13 +83,12 @@ MakeContext ()
|
||||
{
|
||||
const int size = 200;
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenContentDrawTarget(IntSize(size, size),
|
||||
SurfaceFormat::B8G8R8X8);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
|
||||
|
||||
surface = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(IntSize(size, size),
|
||||
gfxASurface::ContentFromFormat(gfxImageFormat::RGB24));
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surface);
|
||||
return ctx.forget();
|
||||
return ctx.forget();
|
||||
}
|
||||
|
||||
TEST(Gfx, WordCache) {
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINetworkSeer.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
|
||||
#include "nsIApplicationCache.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
@ -1429,8 +1429,8 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
||||
// Add the proxy without notifying
|
||||
hvc->AddProxy(proxy);
|
||||
|
||||
mozilla::net::SeerLearn(aURI, aInitialDocumentURI,
|
||||
nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
|
||||
mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
|
||||
|
||||
rv = newChannel->AsyncOpen(listener, nullptr);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
@ -1928,8 +1928,8 @@ nsresult imgLoader::LoadImage(nsIURI *aURI,
|
||||
PR_LOG(GetImgLog(), PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this));
|
||||
|
||||
mozilla::net::SeerLearn(aURI, aInitialDocumentURI,
|
||||
nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
|
||||
mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
|
||||
|
||||
nsresult openRes = newChannel->AsyncOpen(listener, nullptr);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#endif
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/PropDesc.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
@ -64,6 +65,7 @@ MarkExactStackRoot(JSTracer *trc, Rooted<void*> *rooter, ThingRootKind kind)
|
||||
case THING_ROOT_ID: MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
|
||||
case THING_ROOT_BINDINGS: ((Bindings *)addr)->trace(trc); break;
|
||||
case THING_ROOT_PROPERTY_DESCRIPTOR: ((JSPropertyDescriptor *)addr)->trace(trc); break;
|
||||
case THING_ROOT_PROP_DESC: ((PropDesc *)addr)->trace(trc); break;
|
||||
case THING_ROOT_CUSTOM: {
|
||||
// 'rooter' is a member within a class containing a vtable. Back up
|
||||
// to the vtable and call trace() through it.
|
||||
|
@ -263,8 +263,7 @@ js::NewPropertyDescriptorObject(JSContext *cx, Handle<PropertyDescriptor> desc,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We have our own property, so start creating the descriptor. */
|
||||
AutoPropDescRooter d(cx);
|
||||
Rooted<PropDesc> d(cx);
|
||||
|
||||
d.initFromPropertyDescriptor(desc);
|
||||
if (!d.makeObject(cx))
|
||||
@ -1062,13 +1061,12 @@ bool
|
||||
js::DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue descriptor,
|
||||
bool *bp)
|
||||
{
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *desc = descs.append();
|
||||
if (!desc || !desc->initialize(cx, descriptor))
|
||||
Rooted<PropDesc> desc(cx);
|
||||
if (!desc.initialize(cx, descriptor))
|
||||
return false;
|
||||
|
||||
bool rval;
|
||||
if (!DefineProperty(cx, obj, id, *desc, true, &rval))
|
||||
if (!DefineProperty(cx, obj, id, desc, true, &rval))
|
||||
return false;
|
||||
*bp = !!rval;
|
||||
return true;
|
||||
@ -1078,15 +1076,12 @@ bool
|
||||
js::DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> descriptor, bool *bp)
|
||||
{
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *desc = descs.append();
|
||||
if (!desc)
|
||||
return false;
|
||||
Rooted<PropDesc> desc(cx);
|
||||
|
||||
desc->initFromPropertyDescriptor(descriptor);
|
||||
desc.initFromPropertyDescriptor(descriptor);
|
||||
|
||||
bool rval;
|
||||
if (!DefineProperty(cx, obj, id, *desc, true, &rval))
|
||||
if (!DefineProperty(cx, obj, id, desc, true, &rval))
|
||||
return false;
|
||||
*bp = !!rval;
|
||||
return true;
|
||||
|
@ -678,17 +678,16 @@ static bool
|
||||
ParsePropertyDescriptorObject(JSContext *cx, HandleObject obj, const Value &v,
|
||||
MutableHandle<PropertyDescriptor> desc, bool complete = false)
|
||||
{
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *d = descs.append();
|
||||
if (!d || !d->initialize(cx, v))
|
||||
Rooted<PropDesc> d(cx);
|
||||
if (!d.initialize(cx, v))
|
||||
return false;
|
||||
if (complete)
|
||||
d->complete();
|
||||
d.complete();
|
||||
desc.object().set(obj);
|
||||
desc.value().set(d->hasValue() ? d->value() : UndefinedValue());
|
||||
desc.setAttributes(d->attributes());
|
||||
desc.setGetter(d->getter());
|
||||
desc.setSetter(d->setter());
|
||||
desc.value().set(d.hasValue() ? d.value() : UndefinedValue());
|
||||
desc.setAttributes(d.attributes());
|
||||
desc.setGetter(d.getter());
|
||||
desc.setSetter(d.setter());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1101,18 +1100,18 @@ static const char sScriptedDirectProxyHandlerFamily = 0;
|
||||
|
||||
// Aux.2 FromGenericPropertyDescriptor(Desc)
|
||||
static bool
|
||||
FromGenericPropertyDescriptor(JSContext *cx, PropDesc *desc, MutableHandleValue rval)
|
||||
FromGenericPropertyDescriptor(JSContext *cx, MutableHandle<PropDesc> desc, MutableHandleValue rval)
|
||||
{
|
||||
// Aux.2 step 1
|
||||
if (desc->isUndefined()) {
|
||||
if (desc.isUndefined()) {
|
||||
rval.setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
// steps 3-9
|
||||
if (!desc->makeObject(cx))
|
||||
if (!desc.makeObject(cx))
|
||||
return false;
|
||||
rval.set(desc->pd());
|
||||
rval.set(desc.pd());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1131,12 +1130,11 @@ NormalizePropertyDescriptor(JSContext *cx, MutableHandleValue vp, bool complete
|
||||
return true;
|
||||
|
||||
// Aux.3 steps 1-2 / Aux.4 steps 2-3
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *desc = descs.append();
|
||||
if (!desc || !desc->initialize(cx, vp.get()))
|
||||
Rooted<PropDesc> desc(cx);
|
||||
if (!desc.initialize(cx, vp.get()))
|
||||
return false;
|
||||
if (complete)
|
||||
desc->complete();
|
||||
desc.complete();
|
||||
JS_ASSERT(vp.isObject()); // due to desc->initialize
|
||||
RootedObject attributes(cx, &vp.toObject());
|
||||
|
||||
@ -1149,7 +1147,7 @@ NormalizePropertyDescriptor(JSContext *cx, MutableHandleValue vp, bool complete
|
||||
* and is in fact used to implement the latter, so we might as well call it
|
||||
* directly.
|
||||
*/
|
||||
if (!FromGenericPropertyDescriptor(cx, desc, vp))
|
||||
if (!FromGenericPropertyDescriptor(cx, &desc, vp))
|
||||
return false;
|
||||
if (vp.isUndefined())
|
||||
return true;
|
||||
@ -1203,7 +1201,7 @@ IsAccessorDescriptor(const PropertyDescriptor &desc)
|
||||
|
||||
// Aux.5 ValidateProperty(O, P, Desc)
|
||||
static bool
|
||||
ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, PropDesc *desc, bool *bp)
|
||||
ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, Handle<PropDesc> desc, bool *bp)
|
||||
{
|
||||
// step 1
|
||||
Rooted<PropertyDescriptor> current(cx);
|
||||
@ -1217,26 +1215,26 @@ ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, PropDesc *desc, b
|
||||
JS_ASSERT(current.object());
|
||||
|
||||
// step 5
|
||||
if (!desc->hasValue() && !desc->hasWritable() && !desc->hasGet() && !desc->hasSet() &&
|
||||
!desc->hasEnumerable() && !desc->hasConfigurable())
|
||||
if (!desc.hasValue() && !desc.hasWritable() && !desc.hasGet() && !desc.hasSet() &&
|
||||
!desc.hasEnumerable() && !desc.hasConfigurable())
|
||||
{
|
||||
*bp = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// step 6
|
||||
if ((!desc->hasWritable() || desc->writable() == !current.isReadonly()) &&
|
||||
(!desc->hasGet() || desc->getter() == current.getter()) &&
|
||||
(!desc->hasSet() || desc->setter() == current.setter()) &&
|
||||
(!desc->hasEnumerable() || desc->enumerable() == current.isEnumerable()) &&
|
||||
(!desc->hasConfigurable() || desc->configurable() == !current.isPermanent()))
|
||||
if ((!desc.hasWritable() || desc.writable() == !current.isReadonly()) &&
|
||||
(!desc.hasGet() || desc.getter() == current.getter()) &&
|
||||
(!desc.hasSet() || desc.setter() == current.setter()) &&
|
||||
(!desc.hasEnumerable() || desc.enumerable() == current.isEnumerable()) &&
|
||||
(!desc.hasConfigurable() || desc.configurable() == !current.isPermanent()))
|
||||
{
|
||||
if (!desc->hasValue()) {
|
||||
if (!desc.hasValue()) {
|
||||
*bp = true;
|
||||
return true;
|
||||
}
|
||||
bool same = false;
|
||||
if (!SameValue(cx, desc->value(), current.value(), &same))
|
||||
if (!SameValue(cx, desc.value(), current.value(), &same))
|
||||
return false;
|
||||
if (same) {
|
||||
*bp = true;
|
||||
@ -1246,13 +1244,13 @@ ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, PropDesc *desc, b
|
||||
|
||||
// step 7
|
||||
if (current.isPermanent()) {
|
||||
if (desc->hasConfigurable() && desc->configurable()) {
|
||||
if (desc.hasConfigurable() && desc.configurable()) {
|
||||
*bp = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (desc->hasEnumerable() &&
|
||||
desc->enumerable() != current.isEnumerable())
|
||||
if (desc.hasEnumerable() &&
|
||||
desc.enumerable() != current.isEnumerable())
|
||||
{
|
||||
*bp = false;
|
||||
return true;
|
||||
@ -1260,29 +1258,29 @@ ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, PropDesc *desc, b
|
||||
}
|
||||
|
||||
// step 8
|
||||
if (desc->isGenericDescriptor()) {
|
||||
if (desc.isGenericDescriptor()) {
|
||||
*bp = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// step 9
|
||||
if (IsDataDescriptor(current) != desc->isDataDescriptor()) {
|
||||
if (IsDataDescriptor(current) != desc.isDataDescriptor()) {
|
||||
*bp = !current.isPermanent();
|
||||
return true;
|
||||
}
|
||||
|
||||
// step 10
|
||||
if (IsDataDescriptor(current)) {
|
||||
JS_ASSERT(desc->isDataDescriptor()); // by step 9
|
||||
JS_ASSERT(desc.isDataDescriptor()); // by step 9
|
||||
if (current.isPermanent() && current.isReadonly()) {
|
||||
if (desc->hasWritable() && desc->writable()) {
|
||||
if (desc.hasWritable() && desc.writable()) {
|
||||
*bp = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (desc->hasValue()) {
|
||||
if (desc.hasValue()) {
|
||||
bool same;
|
||||
if (!SameValue(cx, desc->value(), current.value(), &same))
|
||||
if (!SameValue(cx, desc.value(), current.value(), &same))
|
||||
return false;
|
||||
if (!same) {
|
||||
*bp = false;
|
||||
@ -1297,10 +1295,10 @@ ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, PropDesc *desc, b
|
||||
|
||||
// steps 11-12
|
||||
JS_ASSERT(IsAccessorDescriptor(current)); // by step 10
|
||||
JS_ASSERT(desc->isAccessorDescriptor()); // by step 9
|
||||
JS_ASSERT(desc.isAccessorDescriptor()); // by step 9
|
||||
*bp = (!current.isPermanent() ||
|
||||
((!desc->hasSet() || desc->setter() == current.setter()) &&
|
||||
(!desc->hasGet() || desc->getter() == current.getter())));
|
||||
((!desc.hasSet() || desc.setter() == current.setter()) &&
|
||||
(!desc.hasGet() || desc.getter() == current.getter())));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1429,9 +1427,8 @@ TrapGetOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *desc = descs.append();
|
||||
if (!desc || !desc->initialize(cx, trapResult))
|
||||
Rooted<PropDesc> desc(cx);
|
||||
if (!desc.initialize(cx, trapResult))
|
||||
return false;
|
||||
|
||||
/* step 10 */
|
||||
@ -1447,7 +1444,7 @@ TrapGetOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle
|
||||
}
|
||||
|
||||
// step 11
|
||||
if (!desc->configurable() && !isFixed) {
|
||||
if (!desc.configurable() && !isFixed) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NE_AS_NC);
|
||||
return false;
|
||||
}
|
||||
@ -1513,9 +1510,8 @@ TrapDefineOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHan
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *desc = descs.append();
|
||||
if (!desc || !desc->initialize(cx, normalizedDesc))
|
||||
Rooted<PropDesc> desc(cx);
|
||||
if (!desc.initialize(cx, normalizedDesc))
|
||||
return false;
|
||||
|
||||
if (isFixed) {
|
||||
@ -1528,7 +1524,7 @@ TrapDefineOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHan
|
||||
}
|
||||
}
|
||||
|
||||
if (!desc->configurable() && !isFixed) {
|
||||
if (!desc.configurable() && !isFixed) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NE_AS_NC);
|
||||
return false;
|
||||
}
|
||||
@ -1753,11 +1749,10 @@ ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, Ha
|
||||
MutableHandle<PropertyDescriptor> desc)
|
||||
{
|
||||
// step 1
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *d = descs.append();
|
||||
d->initFromPropertyDescriptor(desc);
|
||||
Rooted<PropDesc> d(cx);
|
||||
d.initFromPropertyDescriptor(desc);
|
||||
RootedValue v(cx);
|
||||
if (!FromGenericPropertyDescriptor(cx, d, &v))
|
||||
if (!FromGenericPropertyDescriptor(cx, &d, &v))
|
||||
return false;
|
||||
|
||||
// step 2
|
||||
|
@ -279,6 +279,7 @@ enum ThingRootKind
|
||||
THING_ROOT_TYPE,
|
||||
THING_ROOT_BINDINGS,
|
||||
THING_ROOT_PROPERTY_DESCRIPTOR,
|
||||
THING_ROOT_PROP_DESC,
|
||||
THING_ROOT_CUSTOM,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
@ -5257,34 +5257,27 @@ DebuggerObject_defineProperty(JSContext *cx, unsigned argc, Value *vp)
|
||||
if (!ValueToId<CanGC>(cx, args[0], &id))
|
||||
return false;
|
||||
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
if (!descs.reserve(3)) // desc, unwrappedDesc, rewrappedDesc
|
||||
Rooted<PropDesc> desc(cx);
|
||||
if (!desc.initialize(cx, args[1], false))
|
||||
return false;
|
||||
PropDesc *desc = descs.append();
|
||||
if (!desc || !desc->initialize(cx, args[1], false))
|
||||
return false;
|
||||
desc->clearPd();
|
||||
desc.clearPd();
|
||||
|
||||
PropDesc *unwrappedDesc = descs.append();
|
||||
if (!unwrappedDesc || !desc->unwrapDebuggerObjectsInto(cx, dbg, obj, unwrappedDesc))
|
||||
if (!desc.get().unwrapDebuggerObjectsInto(cx, dbg, obj, desc.address()))
|
||||
return false;
|
||||
if (!unwrappedDesc->checkGetter(cx) || !unwrappedDesc->checkSetter(cx))
|
||||
if (!desc.checkGetter(cx) || !desc.checkSetter(cx))
|
||||
return false;
|
||||
|
||||
{
|
||||
PropDesc *rewrappedDesc = descs.append();
|
||||
if (!rewrappedDesc)
|
||||
return false;
|
||||
RootedId wrappedId(cx);
|
||||
|
||||
Maybe<AutoCompartment> ac;
|
||||
ac.construct(cx, obj);
|
||||
if (!unwrappedDesc->wrapInto(cx, obj, id, wrappedId.address(), rewrappedDesc))
|
||||
if (!desc.get().wrapInto(cx, obj, id, wrappedId.address(), desc.address()))
|
||||
return false;
|
||||
|
||||
ErrorCopier ec(ac, dbg->toJSObject());
|
||||
bool dummy;
|
||||
if (!DefineProperty(cx, obj, wrappedId, *rewrappedDesc, true, &dummy))
|
||||
if (!DefineProperty(cx, obj, wrappedId, desc, true, &dummy))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -380,10 +380,10 @@ js::ObjectImpl::markChildren(JSTracer *trc)
|
||||
}
|
||||
|
||||
void
|
||||
AutoPropDescRooter::trace(JSTracer *trc)
|
||||
PropDesc::trace(JSTracer *trc)
|
||||
{
|
||||
gc::MarkValueRoot(trc, &propDesc.pd_, "AutoPropDescRooter pd");
|
||||
gc::MarkValueRoot(trc, &propDesc.value_, "AutoPropDescRooter value");
|
||||
gc::MarkValueRoot(trc, &propDesc.get_, "AutoPropDescRooter get");
|
||||
gc::MarkValueRoot(trc, &propDesc.set_, "AutoPropDescRooter set");
|
||||
gc::MarkValueRoot(trc, &pd_, "PropDesc pd");
|
||||
gc::MarkValueRoot(trc, &value_, "PropDesc value");
|
||||
gc::MarkValueRoot(trc, &get_, "PropDesc get");
|
||||
gc::MarkValueRoot(trc, &set_, "PropDesc set");
|
||||
}
|
||||
|
366
js/src/vm/PropDesc.h
Normal file
366
js/src/vm/PropDesc.h
Normal file
@ -0,0 +1,366 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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/. */
|
||||
|
||||
#ifndef vm_PropDesc_h
|
||||
#define vm_PropDesc_h
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
class Debugger;
|
||||
|
||||
static inline JSPropertyOp
|
||||
CastAsPropertyOp(JSObject *object)
|
||||
{
|
||||
return JS_DATA_TO_FUNC_PTR(JSPropertyOp, object);
|
||||
}
|
||||
|
||||
static inline JSStrictPropertyOp
|
||||
CastAsStrictPropertyOp(JSObject *object)
|
||||
{
|
||||
return JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, object);
|
||||
}
|
||||
|
||||
/*
|
||||
* A representation of ECMA-262 ed. 5's internal Property Descriptor data
|
||||
* structure.
|
||||
*/
|
||||
struct PropDesc {
|
||||
private:
|
||||
/*
|
||||
* Original object from which this descriptor derives, passed through for
|
||||
* the benefit of proxies.
|
||||
*/
|
||||
Value pd_;
|
||||
|
||||
Value value_, get_, set_;
|
||||
|
||||
/* Property descriptor boolean fields. */
|
||||
uint8_t attrs;
|
||||
|
||||
/* Bits indicating which values are set. */
|
||||
bool hasGet_ : 1;
|
||||
bool hasSet_ : 1;
|
||||
bool hasValue_ : 1;
|
||||
bool hasWritable_ : 1;
|
||||
bool hasEnumerable_ : 1;
|
||||
bool hasConfigurable_ : 1;
|
||||
|
||||
/* Or maybe this represents a property's absence, and it's undefined. */
|
||||
bool isUndefined_ : 1;
|
||||
|
||||
explicit PropDesc(const Value &v)
|
||||
: pd_(UndefinedValue()),
|
||||
value_(v),
|
||||
get_(UndefinedValue()), set_(UndefinedValue()),
|
||||
attrs(0),
|
||||
hasGet_(false), hasSet_(false),
|
||||
hasValue_(true), hasWritable_(false), hasEnumerable_(false), hasConfigurable_(false),
|
||||
isUndefined_(false)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
friend void JS::AutoGCRooter::trace(JSTracer *trc);
|
||||
friend struct GCMethods<PropDesc>;
|
||||
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
enum Enumerability { Enumerable = true, NonEnumerable = false };
|
||||
enum Configurability { Configurable = true, NonConfigurable = false };
|
||||
enum Writability { Writable = true, NonWritable = false };
|
||||
|
||||
PropDesc();
|
||||
|
||||
static PropDesc undefined() { return PropDesc(); }
|
||||
static PropDesc valueOnly(const Value &v) { return PropDesc(v); }
|
||||
|
||||
PropDesc(const Value &v, Writability writable,
|
||||
Enumerability enumerable, Configurability configurable)
|
||||
: pd_(UndefinedValue()),
|
||||
value_(v),
|
||||
get_(UndefinedValue()), set_(UndefinedValue()),
|
||||
attrs((writable ? 0 : JSPROP_READONLY) |
|
||||
(enumerable ? JSPROP_ENUMERATE : 0) |
|
||||
(configurable ? 0 : JSPROP_PERMANENT)),
|
||||
hasGet_(false), hasSet_(false),
|
||||
hasValue_(true), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true),
|
||||
isUndefined_(false)
|
||||
{}
|
||||
|
||||
inline PropDesc(const Value &getter, const Value &setter,
|
||||
Enumerability enumerable, Configurability configurable);
|
||||
|
||||
/*
|
||||
* 8.10.5 ToPropertyDescriptor(Obj)
|
||||
*
|
||||
* If checkAccessors is false, skip steps 7.b and 8.b, which throw a
|
||||
* TypeError if .get or .set is neither a callable object nor undefined.
|
||||
*
|
||||
* (DebuggerObject_defineProperty uses this: the .get and .set properties
|
||||
* are expected to be Debugger.Object wrappers of functions, which are not
|
||||
* themselves callable.)
|
||||
*/
|
||||
bool initialize(JSContext *cx, const Value &v, bool checkAccessors = true);
|
||||
|
||||
/*
|
||||
* If IsGenericDescriptor(desc) or IsDataDescriptor(desc) is true, then if
|
||||
* the value of an attribute field of desc, considered as a data
|
||||
* descriptor, is absent, set it to its default value. Else if the value of
|
||||
* an attribute field of desc, considered as an attribute descriptor, is
|
||||
* absent, set it to its default value.
|
||||
*/
|
||||
void complete();
|
||||
|
||||
/*
|
||||
* 8.10.4 FromPropertyDescriptor(Desc)
|
||||
*
|
||||
* initFromPropertyDescriptor sets pd to undefined and populates all the
|
||||
* other fields of this PropDesc from desc.
|
||||
*
|
||||
* makeObject populates pd based on the other fields of *this, creating a
|
||||
* new property descriptor JSObject and defining properties on it.
|
||||
*/
|
||||
void initFromPropertyDescriptor(Handle<JSPropertyDescriptor> desc);
|
||||
bool makeObject(JSContext *cx);
|
||||
|
||||
void setUndefined() { isUndefined_ = true; }
|
||||
|
||||
bool isUndefined() const { return isUndefined_; }
|
||||
|
||||
bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
|
||||
bool hasSet() const { MOZ_ASSERT(!isUndefined()); return hasSet_; }
|
||||
bool hasValue() const { MOZ_ASSERT(!isUndefined()); return hasValue_; }
|
||||
bool hasWritable() const { MOZ_ASSERT(!isUndefined()); return hasWritable_; }
|
||||
bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
|
||||
bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
|
||||
|
||||
Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
|
||||
void clearPd() { pd_ = UndefinedValue(); }
|
||||
|
||||
uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
|
||||
|
||||
/* 8.10.1 IsAccessorDescriptor(desc) */
|
||||
bool isAccessorDescriptor() const {
|
||||
return !isUndefined() && (hasGet() || hasSet());
|
||||
}
|
||||
|
||||
/* 8.10.2 IsDataDescriptor(desc) */
|
||||
bool isDataDescriptor() const {
|
||||
return !isUndefined() && (hasValue() || hasWritable());
|
||||
}
|
||||
|
||||
/* 8.10.3 IsGenericDescriptor(desc) */
|
||||
bool isGenericDescriptor() const {
|
||||
return !isUndefined() && !isAccessorDescriptor() && !isDataDescriptor();
|
||||
}
|
||||
|
||||
bool configurable() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasConfigurable());
|
||||
return (attrs & JSPROP_PERMANENT) == 0;
|
||||
}
|
||||
|
||||
bool enumerable() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasEnumerable());
|
||||
return (attrs & JSPROP_ENUMERATE) != 0;
|
||||
}
|
||||
|
||||
bool writable() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasWritable());
|
||||
return (attrs & JSPROP_READONLY) == 0;
|
||||
}
|
||||
|
||||
HandleValue value() const {
|
||||
MOZ_ASSERT(hasValue());
|
||||
return HandleValue::fromMarkedLocation(&value_);
|
||||
}
|
||||
|
||||
JSObject * getterObject() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasGet());
|
||||
return get_.isUndefined() ? nullptr : &get_.toObject();
|
||||
}
|
||||
JSObject * setterObject() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasSet());
|
||||
return set_.isUndefined() ? nullptr : &set_.toObject();
|
||||
}
|
||||
|
||||
HandleValue getterValue() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasGet());
|
||||
return HandleValue::fromMarkedLocation(&get_);
|
||||
}
|
||||
HandleValue setterValue() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasSet());
|
||||
return HandleValue::fromMarkedLocation(&set_);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unfortunately the values produced by these methods are used such that
|
||||
* we can't assert anything here. :-(
|
||||
*/
|
||||
JSPropertyOp getter() const {
|
||||
return CastAsPropertyOp(get_.isUndefined() ? nullptr : &get_.toObject());
|
||||
}
|
||||
JSStrictPropertyOp setter() const {
|
||||
return CastAsStrictPropertyOp(set_.isUndefined() ? nullptr : &set_.toObject());
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw a TypeError if a getter/setter is present and is neither callable
|
||||
* nor undefined. These methods do exactly the type checks that are skipped
|
||||
* by passing false as the checkAccessors parameter of initialize.
|
||||
*/
|
||||
bool checkGetter(JSContext *cx);
|
||||
bool checkSetter(JSContext *cx);
|
||||
|
||||
bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
|
||||
PropDesc *unwrapped) const;
|
||||
|
||||
bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
|
||||
PropDesc *wrappedDesc) const;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename Outer>
|
||||
class PropDescOperations
|
||||
{
|
||||
const js::PropDesc * desc() const { return static_cast<const Outer*>(this)->extract(); }
|
||||
|
||||
public:
|
||||
bool isUndefined() const { return desc()->isUndefined(); }
|
||||
|
||||
bool hasGet() const { return desc()->hasGet(); }
|
||||
bool hasSet() const { return desc()->hasSet(); }
|
||||
bool hasValue() const { return desc()->hasValue(); }
|
||||
bool hasWritable() const { return desc()->hasWritable(); }
|
||||
bool hasEnumerable() const { return desc()->hasEnumerable(); }
|
||||
bool hasConfigurable() const { return desc()->hasConfigurable(); }
|
||||
|
||||
Value pd() const { return desc()->pd(); }
|
||||
|
||||
uint8_t attributes() const { return desc()->attributes(); }
|
||||
|
||||
bool isAccessorDescriptor() const { return desc()->isAccessorDescriptor(); }
|
||||
bool isDataDescriptor() const { return desc()->isDataDescriptor(); }
|
||||
bool isGenericDescriptor() const { return desc()->isGenericDescriptor(); }
|
||||
bool configurable() const { return desc()->configurable(); }
|
||||
bool enumerable() const { return desc()->enumerable(); }
|
||||
bool writable() const { return desc()->writable(); }
|
||||
|
||||
HandleValue value() const { return desc()->value(); }
|
||||
JSObject *getterObject() const { return desc()->getterObject(); }
|
||||
JSObject *setterObject() const { return desc()->setterObject(); }
|
||||
HandleValue getterValue() const { return desc()->getterValue(); }
|
||||
HandleValue setterValue() const { return desc()->setterValue(); }
|
||||
|
||||
JSPropertyOp getter() const { return desc()->getter(); }
|
||||
JSStrictPropertyOp setter() const { return desc()->setter(); }
|
||||
|
||||
// We choose not to expose the debugger-specific parts of PropDesc, both
|
||||
// because they are not really general use, but also because they are a
|
||||
// pain to expose.
|
||||
};
|
||||
|
||||
template <typename Outer>
|
||||
class MutablePropDescOperations : public PropDescOperations<Outer>
|
||||
{
|
||||
js::PropDesc * desc() { return static_cast<Outer*>(this)->extractMutable(); }
|
||||
|
||||
public:
|
||||
|
||||
bool initialize(JSContext *cx, const Value &v, bool checkAccessors = true) {
|
||||
return desc()->initialize(cx, v, checkAccessors);
|
||||
}
|
||||
void complete() {
|
||||
desc()->complete();
|
||||
}
|
||||
|
||||
bool checkGetter(JSContext *cx) { return desc()->checkGetter(cx); }
|
||||
bool checkSetter(JSContext *cx) { return desc()->checkSetter(cx); }
|
||||
|
||||
void initFromPropertyDescriptor(Handle<JSPropertyDescriptor> descriptor) {
|
||||
desc()->initFromPropertyDescriptor(descriptor);
|
||||
}
|
||||
bool makeObject(JSContext *cx) {
|
||||
return desc()->makeObject(cx);
|
||||
}
|
||||
|
||||
void setUndefined() { desc()->setUndefined(); }
|
||||
void clearPd() { desc()->clearPd(); }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
template <>
|
||||
struct GCMethods<PropDesc> {
|
||||
static PropDesc initial() { return PropDesc(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_PROP_DESC; }
|
||||
static bool poisoned(const PropDesc &desc) {
|
||||
return (desc.pd_.isGCThing() &&
|
||||
JS::IsPoisonedPtr(desc.pd_.toGCThing())) ||
|
||||
(desc.value_.isGCThing() &&
|
||||
JS::IsPoisonedPtr(desc.value_.toGCThing())) ||
|
||||
(desc.get_.isGCThing() &&
|
||||
JS::IsPoisonedPtr(desc.get_.toGCThing())) ||
|
||||
(desc.set_.isGCThing() &&
|
||||
JS::IsPoisonedPtr(desc.set_.toGCThing()));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class RootedBase<PropDesc>
|
||||
: public JS::MutablePropDescOperations<JS::Rooted<PropDesc> >
|
||||
{
|
||||
friend class JS::PropDescOperations<JS::Rooted<PropDesc> >;
|
||||
friend class JS::MutablePropDescOperations<JS::Rooted<PropDesc> >;
|
||||
const PropDesc *extract() const {
|
||||
return static_cast<const JS::Rooted<PropDesc>*>(this)->address();
|
||||
}
|
||||
PropDesc *extractMutable() {
|
||||
return static_cast<JS::Rooted<PropDesc>*>(this)->address();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class HandleBase<PropDesc>
|
||||
: public JS::PropDescOperations<JS::Handle<PropDesc> >
|
||||
{
|
||||
friend class JS::PropDescOperations<JS::Handle<PropDesc> >;
|
||||
const PropDesc *extract() const {
|
||||
return static_cast<const JS::Handle<PropDesc>*>(this)->address();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class MutableHandleBase<PropDesc>
|
||||
: public JS::MutablePropDescOperations<JS::MutableHandle<PropDesc> >
|
||||
{
|
||||
friend class JS::PropDescOperations<JS::MutableHandle<PropDesc> >;
|
||||
friend class JS::MutablePropDescOperations<JS::MutableHandle<PropDesc> >;
|
||||
const PropDesc *extract() const {
|
||||
return static_cast<const JS::MutableHandle<PropDesc>*>(this)->address();
|
||||
}
|
||||
PropDesc *extractMutable() {
|
||||
return static_cast<JS::MutableHandle<PropDesc>*>(this)->address();
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* vm_PropDesc_h */
|
@ -27,6 +27,7 @@
|
||||
#include "gc/Rooting.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "vm/PropDesc.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
@ -118,279 +119,6 @@ typedef JSPropertyDescriptor PropertyDescriptor;
|
||||
static const uint32_t SHAPE_INVALID_SLOT = JS_BIT(24) - 1;
|
||||
static const uint32_t SHAPE_MAXIMUM_SLOT = JS_BIT(24) - 2;
|
||||
|
||||
static inline PropertyOp
|
||||
CastAsPropertyOp(JSObject *object)
|
||||
{
|
||||
return JS_DATA_TO_FUNC_PTR(PropertyOp, object);
|
||||
}
|
||||
|
||||
static inline StrictPropertyOp
|
||||
CastAsStrictPropertyOp(JSObject *object)
|
||||
{
|
||||
return JS_DATA_TO_FUNC_PTR(StrictPropertyOp, object);
|
||||
}
|
||||
|
||||
/*
|
||||
* A representation of ECMA-262 ed. 5's internal Property Descriptor data
|
||||
* structure.
|
||||
*/
|
||||
struct PropDesc {
|
||||
private:
|
||||
/*
|
||||
* Original object from which this descriptor derives, passed through for
|
||||
* the benefit of proxies. FIXME: Remove this when direct proxies happen.
|
||||
*/
|
||||
Value pd_;
|
||||
|
||||
Value value_, get_, set_;
|
||||
|
||||
/* Property descriptor boolean fields. */
|
||||
uint8_t attrs;
|
||||
|
||||
/* Bits indicating which values are set. */
|
||||
bool hasGet_ : 1;
|
||||
bool hasSet_ : 1;
|
||||
bool hasValue_ : 1;
|
||||
bool hasWritable_ : 1;
|
||||
bool hasEnumerable_ : 1;
|
||||
bool hasConfigurable_ : 1;
|
||||
|
||||
/* Or maybe this represents a property's absence, and it's undefined. */
|
||||
bool isUndefined_ : 1;
|
||||
|
||||
explicit PropDesc(const Value &v)
|
||||
: pd_(UndefinedValue()),
|
||||
value_(v),
|
||||
get_(UndefinedValue()), set_(UndefinedValue()),
|
||||
attrs(0),
|
||||
hasGet_(false), hasSet_(false),
|
||||
hasValue_(true), hasWritable_(false), hasEnumerable_(false), hasConfigurable_(false),
|
||||
isUndefined_(false)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
friend class AutoPropDescRooter;
|
||||
friend void JS::AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
enum Enumerability { Enumerable = true, NonEnumerable = false };
|
||||
enum Configurability { Configurable = true, NonConfigurable = false };
|
||||
enum Writability { Writable = true, NonWritable = false };
|
||||
|
||||
PropDesc();
|
||||
|
||||
static PropDesc undefined() { return PropDesc(); }
|
||||
static PropDesc valueOnly(const Value &v) { return PropDesc(v); }
|
||||
|
||||
PropDesc(const Value &v, Writability writable,
|
||||
Enumerability enumerable, Configurability configurable)
|
||||
: pd_(UndefinedValue()),
|
||||
value_(v),
|
||||
get_(UndefinedValue()), set_(UndefinedValue()),
|
||||
attrs((writable ? 0 : JSPROP_READONLY) |
|
||||
(enumerable ? JSPROP_ENUMERATE : 0) |
|
||||
(configurable ? 0 : JSPROP_PERMANENT)),
|
||||
hasGet_(false), hasSet_(false),
|
||||
hasValue_(true), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true),
|
||||
isUndefined_(false)
|
||||
{}
|
||||
|
||||
inline PropDesc(const Value &getter, const Value &setter,
|
||||
Enumerability enumerable, Configurability configurable);
|
||||
|
||||
/*
|
||||
* 8.10.5 ToPropertyDescriptor(Obj)
|
||||
*
|
||||
* If checkAccessors is false, skip steps 7.b and 8.b, which throw a
|
||||
* TypeError if .get or .set is neither a callable object nor undefined.
|
||||
*
|
||||
* (DebuggerObject_defineProperty uses this: the .get and .set properties
|
||||
* are expected to be Debugger.Object wrappers of functions, which are not
|
||||
* themselves callable.)
|
||||
*/
|
||||
bool initialize(JSContext *cx, const Value &v, bool checkAccessors = true);
|
||||
|
||||
/*
|
||||
* If IsGenericDescriptor(desc) or IsDataDescriptor(desc) is true, then if
|
||||
* the value of an attribute field of desc, considered as a data
|
||||
* descriptor, is absent, set it to its default value. Else if the value of
|
||||
* an attribute field of desc, considered as an attribute descriptor, is
|
||||
* absent, set it to its default value.
|
||||
*/
|
||||
void complete();
|
||||
|
||||
/*
|
||||
* 8.10.4 FromPropertyDescriptor(Desc)
|
||||
*
|
||||
* initFromPropertyDescriptor sets pd to undefined and populates all the
|
||||
* other fields of this PropDesc from desc.
|
||||
*
|
||||
* makeObject populates pd based on the other fields of *this, creating a
|
||||
* new property descriptor JSObject and defining properties on it.
|
||||
*/
|
||||
void initFromPropertyDescriptor(Handle<PropertyDescriptor> desc);
|
||||
bool makeObject(JSContext *cx);
|
||||
|
||||
void setUndefined() { isUndefined_ = true; }
|
||||
|
||||
bool isUndefined() const { return isUndefined_; }
|
||||
|
||||
bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
|
||||
bool hasSet() const { MOZ_ASSERT(!isUndefined()); return hasSet_; }
|
||||
bool hasValue() const { MOZ_ASSERT(!isUndefined()); return hasValue_; }
|
||||
bool hasWritable() const { MOZ_ASSERT(!isUndefined()); return hasWritable_; }
|
||||
bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
|
||||
bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
|
||||
|
||||
Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
|
||||
void clearPd() { pd_ = UndefinedValue(); }
|
||||
|
||||
uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
|
||||
|
||||
/* 8.10.1 IsAccessorDescriptor(desc) */
|
||||
bool isAccessorDescriptor() const {
|
||||
return !isUndefined() && (hasGet() || hasSet());
|
||||
}
|
||||
|
||||
/* 8.10.2 IsDataDescriptor(desc) */
|
||||
bool isDataDescriptor() const {
|
||||
return !isUndefined() && (hasValue() || hasWritable());
|
||||
}
|
||||
|
||||
/* 8.10.3 IsGenericDescriptor(desc) */
|
||||
bool isGenericDescriptor() const {
|
||||
return !isUndefined() && !isAccessorDescriptor() && !isDataDescriptor();
|
||||
}
|
||||
|
||||
bool configurable() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasConfigurable());
|
||||
return (attrs & JSPROP_PERMANENT) == 0;
|
||||
}
|
||||
|
||||
bool enumerable() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasEnumerable());
|
||||
return (attrs & JSPROP_ENUMERATE) != 0;
|
||||
}
|
||||
|
||||
bool writable() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasWritable());
|
||||
return (attrs & JSPROP_READONLY) == 0;
|
||||
}
|
||||
|
||||
HandleValue value() const {
|
||||
MOZ_ASSERT(hasValue());
|
||||
return HandleValue::fromMarkedLocation(&value_);
|
||||
}
|
||||
|
||||
JSObject * getterObject() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasGet());
|
||||
return get_.isUndefined() ? nullptr : &get_.toObject();
|
||||
}
|
||||
JSObject * setterObject() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasSet());
|
||||
return set_.isUndefined() ? nullptr : &set_.toObject();
|
||||
}
|
||||
|
||||
HandleValue getterValue() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasGet());
|
||||
return HandleValue::fromMarkedLocation(&get_);
|
||||
}
|
||||
HandleValue setterValue() const {
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasSet());
|
||||
return HandleValue::fromMarkedLocation(&set_);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unfortunately the values produced by these methods are used such that
|
||||
* we can't assert anything here. :-(
|
||||
*/
|
||||
PropertyOp getter() const {
|
||||
return CastAsPropertyOp(get_.isUndefined() ? nullptr : &get_.toObject());
|
||||
}
|
||||
StrictPropertyOp setter() const {
|
||||
return CastAsStrictPropertyOp(set_.isUndefined() ? nullptr : &set_.toObject());
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw a TypeError if a getter/setter is present and is neither callable
|
||||
* nor undefined. These methods do exactly the type checks that are skipped
|
||||
* by passing false as the checkAccessors parameter of initialize.
|
||||
*/
|
||||
bool checkGetter(JSContext *cx);
|
||||
bool checkSetter(JSContext *cx);
|
||||
|
||||
bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
|
||||
PropDesc *unwrapped) const;
|
||||
|
||||
bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
|
||||
PropDesc *wrappedDesc) const;
|
||||
};
|
||||
|
||||
class AutoPropDescRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoPropDescRooter(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: CustomAutoRooter(cx)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
PropDesc& getPropDesc() { return propDesc; }
|
||||
|
||||
void initFromPropertyDescriptor(Handle<PropertyDescriptor> desc) {
|
||||
propDesc.initFromPropertyDescriptor(desc);
|
||||
}
|
||||
|
||||
bool makeObject(JSContext *cx) {
|
||||
return propDesc.makeObject(cx);
|
||||
}
|
||||
|
||||
void setUndefined() { propDesc.setUndefined(); }
|
||||
bool isUndefined() const { return propDesc.isUndefined(); }
|
||||
|
||||
bool hasGet() const { return propDesc.hasGet(); }
|
||||
bool hasSet() const { return propDesc.hasSet(); }
|
||||
bool hasValue() const { return propDesc.hasValue(); }
|
||||
bool hasWritable() const { return propDesc.hasWritable(); }
|
||||
bool hasEnumerable() const { return propDesc.hasEnumerable(); }
|
||||
bool hasConfigurable() const { return propDesc.hasConfigurable(); }
|
||||
|
||||
Value pd() const { return propDesc.pd(); }
|
||||
void clearPd() { propDesc.clearPd(); }
|
||||
|
||||
uint8_t attributes() const { return propDesc.attributes(); }
|
||||
|
||||
bool isAccessorDescriptor() const { return propDesc.isAccessorDescriptor(); }
|
||||
bool isDataDescriptor() const { return propDesc.isDataDescriptor(); }
|
||||
bool isGenericDescriptor() const { return propDesc.isGenericDescriptor(); }
|
||||
bool configurable() const { return propDesc.configurable(); }
|
||||
bool enumerable() const { return propDesc.enumerable(); }
|
||||
bool writable() const { return propDesc.writable(); }
|
||||
|
||||
HandleValue value() const { return propDesc.value(); }
|
||||
JSObject *getterObject() const { return propDesc.getterObject(); }
|
||||
JSObject *setterObject() const { return propDesc.setterObject(); }
|
||||
HandleValue getterValue() const { return propDesc.getterValue(); }
|
||||
HandleValue setterValue() const { return propDesc.setterValue(); }
|
||||
|
||||
PropertyOp getter() const { return propDesc.getter(); }
|
||||
StrictPropertyOp setter() const { return propDesc.setter(); }
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc);
|
||||
|
||||
PropDesc propDesc;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/*
|
||||
* Shapes use multiplicative hashing, but specialized to
|
||||
* minimize footprint.
|
||||
|
@ -8,7 +8,6 @@
|
||||
<name>Init dictionary for the event constructor. """
|
||||
|
||||
simple_events = [
|
||||
'ProgressEvent',
|
||||
'MozSettingsEvent',
|
||||
'CustomEvent',
|
||||
'PageTransitionEvent',
|
||||
|
@ -6662,6 +6662,11 @@ nsLayoutUtils::DoLogTestDataForPaint(nsIPresShell* aPresShell,
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsLayoutUtils::IsAPZTestLoggingEnabled()
|
||||
{
|
||||
return gfxPrefs::APZTestLoggingEnabled();
|
||||
}
|
||||
|
||||
nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
|
||||
// Use safe default values here
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "Units.h"
|
||||
#include "mozilla/ToString.h"
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
@ -2202,7 +2201,7 @@ public:
|
||||
ViewID aScrollId,
|
||||
const std::string& aKey,
|
||||
const std::string& aValue) {
|
||||
if (gfxPrefs::APZTestLoggingEnabled()) {
|
||||
if (IsAPZTestLoggingEnabled()) {
|
||||
DoLogTestDataForPaint(aPresShell, aScrollId, aKey, aValue);
|
||||
}
|
||||
}
|
||||
@ -2217,7 +2216,7 @@ public:
|
||||
ViewID aScrollId,
|
||||
const std::string& aKey,
|
||||
const Value& aValue) {
|
||||
if (gfxPrefs::APZTestLoggingEnabled()) {
|
||||
if (IsAPZTestLoggingEnabled()) {
|
||||
DoLogTestDataForPaint(aPresShell, aScrollId, aKey,
|
||||
mozilla::ToString(aValue));
|
||||
}
|
||||
@ -2262,6 +2261,8 @@ private:
|
||||
ViewID aScrollId,
|
||||
const std::string& aKey,
|
||||
const std::string& aValue);
|
||||
|
||||
static bool IsAPZTestLoggingEnabled();
|
||||
};
|
||||
|
||||
MOZ_FINISH_NESTED_ENUM_CLASS(nsLayoutUtils::RepaintMode)
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "nsPrintfCString.h"
|
||||
// for touchcaret
|
||||
#include "nsContentList.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
@ -208,6 +209,16 @@ nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
void
|
||||
nsDisplayCanvasBackgroundColor::WriteDebugInfo(nsACString& aTo)
|
||||
{
|
||||
aTo += nsPrintfCString(" (rgba %d,%d,%d,%d)",
|
||||
NS_GET_R(mColor), NS_GET_G(mColor),
|
||||
NS_GET_B(mColor), NS_GET_A(mColor));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void BlitSurface(gfxContext* aDest, const gfxRect& aRect, gfxASurface* aSource)
|
||||
{
|
||||
aDest->Translate(gfxPoint(aRect.x, aRect.y));
|
||||
|
@ -195,6 +195,9 @@ public:
|
||||
}
|
||||
|
||||
NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR)
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
private:
|
||||
nscolor mColor;
|
||||
|
@ -1476,8 +1476,8 @@ nsLineLayout::BlockDirAlignLine()
|
||||
#ifdef NOISY_BLOCKDIR_ALIGN
|
||||
printf(
|
||||
" [line]==> bounds{x,y,w,h}={%d,%d,%d,%d} lh=%d a=%d\n",
|
||||
mLineBox->mBounds.IStart(lineWM), mLineBox->mBounds.BStart(lineWM),
|
||||
mLineBox->mBounds.ISize(lineWM), mLineBox->mBounds.BSize(lineWM),
|
||||
mLineBox->GetBounds().IStart(lineWM), mLineBox->GetBounds().BStart(lineWM),
|
||||
mLineBox->GetBounds().ISize(lineWM), mLineBox->GetBounds().BSize(lineWM),
|
||||
mFinalLineBSize, mLineBox->GetAscent());
|
||||
#endif
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
#include "nsCrossSiteListenerProxy.h"
|
||||
#include "nsINetworkSeer.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/dom/URL.h"
|
||||
|
||||
@ -1423,9 +1423,9 @@ Loader::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState)
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mozilla::net::SeerLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
|
||||
nsINetworkSeer::LEARN_LOAD_SUBRESOURCE,
|
||||
mDocument);
|
||||
mozilla::net::PredictorLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
|
||||
mDocument);
|
||||
}
|
||||
|
||||
// Just load it
|
||||
@ -1612,8 +1612,9 @@ Loader::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState)
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mozilla::net::SeerLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
|
||||
nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, mDocument);
|
||||
mozilla::net::PredictorLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
|
||||
mDocument);
|
||||
}
|
||||
|
||||
rv = channel->AsyncOpen(channelListener, nullptr);
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "nsINetworkSeer.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
|
||||
#include "nsIConsoleService.h"
|
||||
|
||||
@ -383,8 +383,9 @@ nsUserFontSet::StartLoad(gfxMixedFontFamily* aFamily,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIDocument *document = ps->GetDocument();
|
||||
mozilla::net::SeerLearn(aFontFaceSrc->mURI, document->GetDocumentURI(),
|
||||
nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, loadGroup);
|
||||
mozilla::net::PredictorLearn(aFontFaceSrc->mURI, document->GetDocumentURI(),
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
|
||||
loadGroup);
|
||||
|
||||
bool inherits = false;
|
||||
rv = NS_URIChainHasFlags(aFontFaceSrc->mURI,
|
||||
|
@ -103,9 +103,9 @@ pref("network.buffer.cache.count", 24);
|
||||
pref("network.buffer.cache.size", 16384);
|
||||
|
||||
// predictive actions
|
||||
pref("network.seer.enabled", false);
|
||||
pref("network.seer.max-db-size", 2097152); // bytes
|
||||
pref("network.seer.preserve", 50); // percentage of seer data to keep when cleaning up
|
||||
pref("network.predictor.enabled", false);
|
||||
pref("network.predictor.max-db-size", 2097152); // bytes
|
||||
pref("network.predictor.preserve", 50); // percentage of predictor data to keep when cleaning up
|
||||
|
||||
/* history max results display */
|
||||
pref("browser.display.history.maxresults", 100);
|
||||
|
@ -146,8 +146,8 @@ Sanitizer.prototype = {
|
||||
catch (e) { }
|
||||
|
||||
try {
|
||||
var seer = Cc["@mozilla.org/network/seer;1"].getService(Ci.nsINetworkSeer);
|
||||
seer.reset();
|
||||
var predictor = Cc["@mozilla.org/network/predictor;1"].getService(Ci.nsINetworkPredictor);
|
||||
predictor.reset();
|
||||
} catch (e) { }
|
||||
},
|
||||
|
||||
|
@ -1327,24 +1327,24 @@ pref("network.dir.format", 2);
|
||||
pref("network.prefetch-next", true);
|
||||
|
||||
// enables the predictive service
|
||||
pref("network.seer.enabled", false);
|
||||
pref("network.seer.enable-hover-on-ssl", false);
|
||||
pref("network.seer.page-degradation.day", 0);
|
||||
pref("network.seer.page-degradation.week", 5);
|
||||
pref("network.seer.page-degradation.month", 10);
|
||||
pref("network.seer.page-degradation.year", 25);
|
||||
pref("network.seer.page-degradation.max", 50);
|
||||
pref("network.seer.subresource-degradation.day", 1);
|
||||
pref("network.seer.subresource-degradation.week", 10);
|
||||
pref("network.seer.subresource-degradation.month", 25);
|
||||
pref("network.seer.subresource-degradation.year", 50);
|
||||
pref("network.seer.subresource-degradation.max", 100);
|
||||
pref("network.seer.preconnect-min-confidence", 90);
|
||||
pref("network.seer.preresolve-min-confidence", 60);
|
||||
pref("network.seer.redirect-likely-confidence", 75);
|
||||
pref("network.seer.max-queue-size", 50);
|
||||
pref("network.seer.max-db-size", 157286400); // bytes
|
||||
pref("network.seer.preserve", 80); // percentage of seer data to keep when cleaning up
|
||||
pref("network.predictor.enabled", false);
|
||||
pref("network.predictor.enable-hover-on-ssl", false);
|
||||
pref("network.predictor.page-degradation.day", 0);
|
||||
pref("network.predictor.page-degradation.week", 5);
|
||||
pref("network.predictor.page-degradation.month", 10);
|
||||
pref("network.predictor.page-degradation.year", 25);
|
||||
pref("network.predictor.page-degradation.max", 50);
|
||||
pref("network.predictor.subresource-degradation.day", 1);
|
||||
pref("network.predictor.subresource-degradation.week", 10);
|
||||
pref("network.predictor.subresource-degradation.month", 25);
|
||||
pref("network.predictor.subresource-degradation.year", 50);
|
||||
pref("network.predictor.subresource-degradation.max", 100);
|
||||
pref("network.predictor.preconnect-min-confidence", 90);
|
||||
pref("network.predictor.preresolve-min-confidence", 60);
|
||||
pref("network.predictor.redirect-likely-confidence", 75);
|
||||
pref("network.predictor.max-queue-size", 50);
|
||||
pref("network.predictor.max-db-size", 157286400); // bytes
|
||||
pref("network.predictor.preserve", 80); // percentage of predictor data to keep when cleaning up
|
||||
|
||||
|
||||
// The following prefs pertain to the negotiate-auth extension (see bug 17578),
|
||||
|
@ -57,9 +57,9 @@ XPIDL_SOURCES += [
|
||||
'nsINetAddr.idl',
|
||||
'nsINetUtil.idl',
|
||||
'nsINetworkLinkService.idl',
|
||||
'nsINetworkPredictor.idl',
|
||||
'nsINetworkPredictorVerifier.idl',
|
||||
'nsINetworkProperties.idl',
|
||||
'nsINetworkSeer.idl',
|
||||
'nsINetworkSeerVerifier.idl',
|
||||
'nsINSSErrorsService.idl',
|
||||
'nsIParentChannel.idl',
|
||||
'nsIParentRedirectingChannel.idl',
|
||||
|
@ -7,18 +7,19 @@
|
||||
|
||||
interface nsIURI;
|
||||
interface nsILoadContext;
|
||||
interface nsINetworkSeerVerifier;
|
||||
interface nsINetworkPredictorVerifier;
|
||||
|
||||
typedef unsigned long SeerPredictReason;
|
||||
typedef unsigned long SeerLearnReason;
|
||||
typedef unsigned long PredictorPredictReason;
|
||||
typedef unsigned long PredictorLearnReason;
|
||||
|
||||
/**
|
||||
* nsINetworkSeer - learn about pages users visit, and allow us to take
|
||||
* predictive actions upon future visits.
|
||||
* NOTE: nsINetworkSeer should only be used on the main thread
|
||||
* nsINetworkPredictor - learn about pages users visit, and allow us to take
|
||||
* predictive actions upon future visits.
|
||||
* NOTE: nsINetworkPredictor should only
|
||||
* be used on the main thread.
|
||||
*/
|
||||
[scriptable, uuid(25e323b6-99e0-4274-b5b3-1a9eb56e28ac)]
|
||||
interface nsINetworkSeer : nsISupports
|
||||
[scriptable, uuid(980f70bc-0487-4b22-a4c1-bf1185c8ae1f)]
|
||||
interface nsINetworkPredictor : nsISupports
|
||||
{
|
||||
/**
|
||||
* Prediction reasons
|
||||
@ -32,14 +33,14 @@ interface nsINetworkSeer : nsISupports
|
||||
* PREDICT_STARTUP - we are being asked to take predictive action
|
||||
* because the browser is starting up.
|
||||
*/
|
||||
const SeerPredictReason PREDICT_LINK = 0;
|
||||
const SeerPredictReason PREDICT_LOAD = 1;
|
||||
const SeerPredictReason PREDICT_STARTUP = 2;
|
||||
const PredictorPredictReason PREDICT_LINK = 0;
|
||||
const PredictorPredictReason PREDICT_LOAD = 1;
|
||||
const PredictorPredictReason PREDICT_STARTUP = 2;
|
||||
|
||||
/**
|
||||
* Start taking predictive actions
|
||||
*
|
||||
* Calling this will cause the seer to (possibly) start
|
||||
* Calling this will cause the predictor to (possibly) start
|
||||
* taking actions such as DNS prefetch and/or TCP preconnect based on
|
||||
* (1) the host name that we are given, and (2) the reason we are being
|
||||
* asked to take actions.
|
||||
@ -59,15 +60,15 @@ interface nsINetworkSeer : nsISupports
|
||||
* null.
|
||||
* @param loadContext - The nsILoadContext of the page load we are predicting
|
||||
* about.
|
||||
* @param verifier - An nsINetworkSeerVerifier used in testing to ensure we're
|
||||
* predicting the way we expect to. Not necessary (or desired) for normal
|
||||
* operation.
|
||||
* @param verifier - An nsINetworkPredictorVerifier used in testing to ensure
|
||||
* we're predicting the way we expect to. Not necessary (or desired) for
|
||||
* normal operation.
|
||||
*/
|
||||
void predict(in nsIURI targetURI,
|
||||
in nsIURI sourceURI,
|
||||
in SeerPredictReason reason,
|
||||
in PredictorPredictReason reason,
|
||||
in nsILoadContext loadContext,
|
||||
in nsINetworkSeerVerifier verifier);
|
||||
in nsINetworkPredictorVerifier verifier);
|
||||
|
||||
|
||||
/*
|
||||
@ -82,10 +83,10 @@ interface nsINetworkSeer : nsISupports
|
||||
*
|
||||
* LEARN_STARTUP - we are learning about a page loaded during startup
|
||||
*/
|
||||
const SeerLearnReason LEARN_LOAD_TOPLEVEL = 0;
|
||||
const SeerLearnReason LEARN_LOAD_SUBRESOURCE = 1;
|
||||
const SeerLearnReason LEARN_LOAD_REDIRECT = 2;
|
||||
const SeerLearnReason LEARN_STARTUP = 3;
|
||||
const PredictorLearnReason LEARN_LOAD_TOPLEVEL = 0;
|
||||
const PredictorLearnReason LEARN_LOAD_SUBRESOURCE = 1;
|
||||
const PredictorLearnReason LEARN_LOAD_REDIRECT = 2;
|
||||
const PredictorLearnReason LEARN_STARTUP = 3;
|
||||
|
||||
/**
|
||||
* Add to our compendium of knowledge
|
||||
@ -111,7 +112,7 @@ interface nsINetworkSeer : nsISupports
|
||||
*/
|
||||
void learn(in nsIURI targetURI,
|
||||
in nsIURI sourceURI,
|
||||
in SeerLearnReason reason,
|
||||
in PredictorLearnReason reason,
|
||||
in nsILoadContext loadContext);
|
||||
|
||||
/**
|
||||
@ -130,40 +131,40 @@ interface nsINetworkSeer : nsISupports
|
||||
};
|
||||
|
||||
%{C++
|
||||
// Wrapper functions to make use of the seer easier and less invasive
|
||||
// Wrapper functions to make use of the predictor easier and less invasive
|
||||
class nsIChannel;
|
||||
class nsIDocument;
|
||||
class nsILoadContext;
|
||||
class nsILoadGroup;
|
||||
class nsINetworkSeerVerifier;
|
||||
class nsINetworkPredictorVerifier;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
nsresult SeerPredict(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
SeerPredictReason reason,
|
||||
nsILoadContext *loadContext,
|
||||
nsINetworkSeerVerifier *verifier);
|
||||
nsresult PredictorPredict(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
PredictorPredictReason reason,
|
||||
nsILoadContext *loadContext,
|
||||
nsINetworkPredictorVerifier *verifier);
|
||||
|
||||
nsresult SeerLearn(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
SeerLearnReason reason,
|
||||
nsILoadContext *loadContext);
|
||||
nsresult PredictorLearn(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
PredictorLearnReason reason,
|
||||
nsILoadContext *loadContext);
|
||||
|
||||
nsresult SeerLearn(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
SeerLearnReason reason,
|
||||
nsILoadGroup *loadGroup);
|
||||
nsresult PredictorLearn(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
PredictorLearnReason reason,
|
||||
nsILoadGroup *loadGroup);
|
||||
|
||||
nsresult SeerLearn(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
SeerLearnReason reason,
|
||||
nsIDocument *document);
|
||||
nsresult PredictorLearn(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
PredictorLearnReason reason,
|
||||
nsIDocument *document);
|
||||
|
||||
nsresult SeerLearnRedirect(nsIURI *targetURI,
|
||||
nsIChannel *channel,
|
||||
nsILoadContext *loadContext);
|
||||
nsresult PredictorLearnRedirect(nsIURI *targetURI,
|
||||
nsIChannel *channel,
|
||||
nsILoadContext *loadContext);
|
||||
|
||||
} // mozilla::net
|
||||
} // mozilla
|
@ -4,16 +4,16 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* nsINetworkSeerVerifier - used for testing the network seer to ensure it
|
||||
* does what we expect it to do.
|
||||
* nsINetworkPredictorVerifier - used for testing the network predictor to
|
||||
* ensure it does what we expect it to do.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
[scriptable, uuid(ea273653-43a8-4632-8b30-4032e0918e8b)]
|
||||
interface nsINetworkSeerVerifier : nsISupports
|
||||
[scriptable, uuid(00360c7d-a046-4f8d-a1fc-8bdc0f0fb444)]
|
||||
interface nsINetworkPredictorVerifier : nsISupports
|
||||
{
|
||||
/**
|
||||
* Callback for when we do a predictive preconnect
|
File diff suppressed because it is too large
Load Diff
@ -3,10 +3,10 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef mozilla_net_Seer_h
|
||||
#define mozilla_net_Seer_h
|
||||
#ifndef mozilla_net_Predictor_h
|
||||
#define mozilla_net_Predictor_h
|
||||
|
||||
#include "nsINetworkSeer.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDNSListener.h"
|
||||
@ -14,13 +14,12 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsISpeculativeConnect.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/storage/StatementCache.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
class nsIDNSService;
|
||||
class nsINetworkSeerVerifier;
|
||||
class nsINetworkPredictorVerifier;
|
||||
class nsIThread;
|
||||
class nsITimer;
|
||||
|
||||
@ -31,40 +30,40 @@ class mozIStorageStatement;
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
typedef nsMainThreadPtrHandle<nsINetworkSeerVerifier> SeerVerifierHandle;
|
||||
typedef nsMainThreadPtrHandle<nsINetworkPredictorVerifier> PredictorVerifierHandle;
|
||||
|
||||
class SeerPredictionRunner;
|
||||
struct SeerTelemetryAccumulators;
|
||||
class SeerDNSListener;
|
||||
class PredictionRunner;
|
||||
struct PredictorTelemetryAccumulators;
|
||||
class PredictorDNSListener;
|
||||
|
||||
class Seer : public nsINetworkSeer
|
||||
, public nsIObserver
|
||||
, public nsISpeculativeConnectionOverrider
|
||||
, public nsIInterfaceRequestor
|
||||
class Predictor : public nsINetworkPredictor
|
||||
, public nsIObserver
|
||||
, public nsISpeculativeConnectionOverrider
|
||||
, public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINETWORKSEER
|
||||
NS_DECL_NSINETWORKPREDICTOR
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
Seer();
|
||||
virtual ~Seer();
|
||||
Predictor();
|
||||
virtual ~Predictor();
|
||||
|
||||
nsresult Init();
|
||||
void Shutdown();
|
||||
static nsresult Create(nsISupports *outer, const nsIID& iid, void **result);
|
||||
|
||||
private:
|
||||
friend class SeerPredictionEvent;
|
||||
friend class SeerLearnEvent;
|
||||
friend class SeerResetEvent;
|
||||
friend class SeerPredictionRunner;
|
||||
friend class SeerDBShutdownRunner;
|
||||
friend class SeerCommitTimerInitEvent;
|
||||
friend class SeerNewTransactionEvent;
|
||||
friend class SeerCleanupEvent;
|
||||
friend class PredictionEvent;
|
||||
friend class LearnEvent;
|
||||
friend class PredictorResetEvent;
|
||||
friend class PredictionRunner;
|
||||
friend class PredictorDBShutdownRunner;
|
||||
friend class PredictorCommitTimerInitEvent;
|
||||
friend class PredictorNewTransactionEvent;
|
||||
friend class PredictorCleanupEvent;
|
||||
|
||||
void CheckForAndDeleteOldDBFile();
|
||||
nsresult EnsureInitStorage();
|
||||
@ -77,12 +76,12 @@ private:
|
||||
|
||||
void PredictForLink(nsIURI *targetURI,
|
||||
nsIURI *sourceURI,
|
||||
nsINetworkSeerVerifier *verifier);
|
||||
nsINetworkPredictorVerifier *verifier);
|
||||
void PredictForPageload(const UriInfo &dest,
|
||||
SeerVerifierHandle &verifier,
|
||||
PredictorVerifierHandle &verifier,
|
||||
int stackCount,
|
||||
TimeStamp &predictStartTime);
|
||||
void PredictForStartup(SeerVerifierHandle &verifier,
|
||||
void PredictForStartup(PredictorVerifierHandle &verifier,
|
||||
TimeStamp &predictStartTime);
|
||||
|
||||
// Whether we're working on a page or an origin
|
||||
@ -116,7 +115,7 @@ private:
|
||||
int globalDegradation);
|
||||
void SetupPrediction(int confidence,
|
||||
const nsACString &uri,
|
||||
SeerPredictionRunner *runner);
|
||||
PredictionRunner *runner);
|
||||
|
||||
bool LookupTopLevel(QueryType queryType,
|
||||
const nsACString &key,
|
||||
@ -130,7 +129,7 @@ private:
|
||||
bool TryPredict(QueryType queryType,
|
||||
const TopLevelInfo &info,
|
||||
PRTime now,
|
||||
SeerVerifierHandle &verifier,
|
||||
PredictorVerifierHandle &verifier,
|
||||
TimeStamp &predictStartTime);
|
||||
bool WouldRedirect(const TopLevelInfo &info,
|
||||
PRTime now,
|
||||
@ -222,14 +221,14 @@ private:
|
||||
int32_t mQueueSize;
|
||||
mozilla::Mutex mQueueSizeLock;
|
||||
|
||||
nsAutoPtr<SeerTelemetryAccumulators> mAccumulators;
|
||||
nsAutoPtr<PredictorTelemetryAccumulators> mAccumulators;
|
||||
|
||||
nsRefPtr<SeerDNSListener> mDNSListener;
|
||||
nsRefPtr<PredictorDNSListener> mDNSListener;
|
||||
|
||||
nsCOMPtr<nsITimer> mCommitTimer;
|
||||
|
||||
#ifdef SEER_TESTS
|
||||
friend class SeerPrepareForDnsTestEvent;
|
||||
#ifdef PREDICTOR_TESTS
|
||||
friend class PredictorPrepareForDnsTestEvent;
|
||||
void PrepareForDnsTestInternal(int64_t timestamp, const nsACString &uri);
|
||||
#endif
|
||||
|
||||
@ -242,4 +241,4 @@ private:
|
||||
} // ::mozilla::net
|
||||
} // ::mozilla
|
||||
|
||||
#endif // mozilla_net_Seer_h
|
||||
#endif // mozilla_net_Predictor_h
|
@ -70,9 +70,9 @@ UNIFIED_SOURCES += [
|
||||
'nsURIChecker.cpp',
|
||||
'nsURLHelper.cpp',
|
||||
'nsURLParsers.cpp',
|
||||
'Predictor.cpp',
|
||||
'ProxyAutoConfig.cpp',
|
||||
'RedirectChannelRegistrar.cpp',
|
||||
'Seer.cpp',
|
||||
'StreamingProtocolService.cpp',
|
||||
'Tickler.cpp',
|
||||
]
|
||||
@ -132,4 +132,4 @@ if CONFIG['MOZ_ENABLE_QTNETWORK']:
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
DEFINES['SEER_TESTS'] = True
|
||||
DEFINES['PREDICTOR_TESTS'] = True
|
||||
|
@ -446,15 +446,15 @@
|
||||
{ 0x8d, 0x17, 0xa2, 0x7e, 0x44, 0xa8, 0x39, 0x3e } \
|
||||
}
|
||||
|
||||
// service implementing nsINetworkSeer
|
||||
#define NS_NETWORKSEER_CONTRACTID \
|
||||
"@mozilla.org/network/seer;1"
|
||||
#define NS_NETWORKSEER_CID \
|
||||
{ /* {1C218009-A531-46AD-8351-1E7F45D5A3C4} */ \
|
||||
0x1C218009, \
|
||||
0xA531, \
|
||||
0x46AD, \
|
||||
{ 0x83, 0x51, 0x1E, 0x7F, 0x45, 0xD5, 0xA3, 0xC4 } \
|
||||
// service implementing nsINetworkPredictor
|
||||
#define NS_NETWORKPREDICTOR_CONTRACTID \
|
||||
"@mozilla.org/network/predictor;1"
|
||||
#define NS_NETWORKPREDICTOR_CID \
|
||||
{ /* {969adfdf-7221-4419-aecf-05f8faf00c9b} */ \
|
||||
0x969adfdf, \
|
||||
0x7221, \
|
||||
0x4419, \
|
||||
{ 0xae, 0xcf, 0x05, 0xf8, 0xfa, 0xf0, 0x0c, 0x9b } \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -927,7 +927,7 @@
|
||||
0x40f7, \
|
||||
{ 0x86, 0xf8, 0x63, 0xf2, 0x25, 0xb9, 0x40, 0xae } \
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Contracts that can be implemented by necko users.
|
||||
*/
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsCategoryCache.h"
|
||||
#include "nsIContentSniffer.h"
|
||||
#include "Seer.h"
|
||||
#include "Predictor.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIThreadPool.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
@ -822,7 +822,7 @@ NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NETWORKSEER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
||||
{ &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
|
||||
@ -965,7 +965,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
||||
{ &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
|
||||
{ &kNS_REDIRECTCHANNELREGISTRAR_CID, false, nullptr, RedirectChannelRegistrarConstructor },
|
||||
{ &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
|
||||
{ &kNS_NETWORKSEER_CID, false, nullptr, mozilla::net::Seer::Create },
|
||||
{ &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
@ -1111,7 +1111,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
||||
{ NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
|
||||
{ NS_REDIRECTCHANNELREGISTRAR_CONTRACTID, &kNS_REDIRECTCHANNELREGISTRAR_CID },
|
||||
{ NS_CACHE_STORAGE_SERVICE_CONTRACTID, &kNS_CACHE_STORAGE_SERVICE_CID },
|
||||
{ NS_NETWORKSEER_CONTRACTID, &kNS_NETWORKSEER_CID },
|
||||
{ NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
|
@ -1470,10 +1470,17 @@ Http2Compressor::ProcessHeader(const nvPair inputPair, bool neverIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
// Need to ensure we have room for a new static entry before emitting
|
||||
// anything, see bug 1019577
|
||||
bool isStatic = (matchedIndex >= mHeaderTable.VariableLength());
|
||||
if (isStatic) {
|
||||
MakeRoom(newSize);
|
||||
}
|
||||
|
||||
// emit an index to add to reference set
|
||||
DoOutput(kToggleOn, &inputPair, matchedIndex);
|
||||
if (matchedIndex >= mHeaderTable.VariableLength()) {
|
||||
MakeRoom(newSize);
|
||||
|
||||
if (isStatic) {
|
||||
mHeaderTable.AddElement(inputPair.mName, inputPair.mValue);
|
||||
IncrementReferenceSetIndices();
|
||||
mAlternateReferenceSet.AppendElement(0);
|
||||
|
@ -2738,7 +2738,12 @@ Http2Session::OnWriteSegment(char *buf,
|
||||
// sake of goodness and sanity. No matter what, any future calls to
|
||||
// WriteSegments need to just discard data until we reach the end of this
|
||||
// frame.
|
||||
ChangeDownstreamState(DISCARDING_DATA_FRAME_PADDING);
|
||||
if (mInputFrameDataSize != mInputFrameDataRead) {
|
||||
// Only change state if we still have padding to read. If we don't do
|
||||
// this, we can end up hanging on frames that combine real data,
|
||||
// padding, and END_STREAM (see bug 1019921)
|
||||
ChangeDownstreamState(DISCARDING_DATA_FRAME_PADDING);
|
||||
}
|
||||
uint32_t paddingRead = mPaddingLength - (mInputFrameDataSize - mInputFrameDataRead);
|
||||
LOG3(("Http2Session::OnWriteSegment %p stream 0x%X len=%d read=%d "
|
||||
"crossed from HTTP data into padding (%d of %d) countWritten=%d",
|
||||
|
@ -2942,6 +2942,11 @@ WebSocketChannel::OnTransportAvailable(nsISocketTransport *aTransport,
|
||||
LOG(("WebSocketChannel::OnTransportAvailable %p [%p %p %p] rcvdonstart=%d\n",
|
||||
this, aTransport, aSocketIn, aSocketOut, mGotUpgradeOK));
|
||||
|
||||
if (mStopped) {
|
||||
LOG(("WebSocketChannel::OnTransportAvailable: Already stopped"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
||||
NS_ABORT_IF_FALSE(!mRecvdHttpUpgradeTransport, "OTA duplicated");
|
||||
NS_ABORT_IF_FALSE(aSocketIn, "OTA with invalid socketIn");
|
||||
|
@ -6,7 +6,7 @@ var Cr = Components.results;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
var seer = null;
|
||||
var predictor = null;
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
var profile = null;
|
||||
|
||||
@ -29,7 +29,7 @@ LoadContext.prototype = {
|
||||
},
|
||||
|
||||
QueryInterface: function loadContext_QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsINetworkSeerVerifier) ||
|
||||
if (iid.equals(Ci.nsINetworkPredictorVerifier) ||
|
||||
iid.equals(Ci.nsILoadContext)) {
|
||||
return this;
|
||||
}
|
||||
@ -56,7 +56,7 @@ Verifier.prototype = {
|
||||
},
|
||||
|
||||
QueryInterface: function verifier_QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsINetworkSeerVerifier) ||
|
||||
if (iid.equals(Ci.nsINetworkPredictorVerifier) ||
|
||||
iid.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
@ -95,8 +95,8 @@ Verifier.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function reset_seer() {
|
||||
seer.reset();
|
||||
function reset_predictor() {
|
||||
predictor.reset();
|
||||
}
|
||||
|
||||
function newURI(s) {
|
||||
@ -104,17 +104,17 @@ function newURI(s) {
|
||||
}
|
||||
|
||||
function test_link_hover() {
|
||||
reset_seer();
|
||||
reset_predictor();
|
||||
var uri = newURI("http://localhost:4444/foo/bar");
|
||||
var referrer = newURI("http://localhost:4444/foo");
|
||||
var preconns = ["http://localhost:4444"];
|
||||
|
||||
var verifier = new Verifier("hover", preconns, []);
|
||||
seer.predict(uri, referrer, seer.PREDICT_LINK, load_context, verifier);
|
||||
predictor.predict(uri, referrer, predictor.PREDICT_LINK, load_context, verifier);
|
||||
}
|
||||
|
||||
function test_pageload() {
|
||||
reset_seer();
|
||||
reset_predictor();
|
||||
var toplevel = "http://localhost:4444/index.html";
|
||||
var subresources = [
|
||||
"http://localhost:4444/style.css",
|
||||
@ -123,20 +123,20 @@ function test_pageload() {
|
||||
];
|
||||
|
||||
var tluri = newURI(toplevel);
|
||||
seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
predictor.learn(tluri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
var preconns = [];
|
||||
for (var i = 0; i < subresources.length; i++) {
|
||||
var sruri = newURI(subresources[i]);
|
||||
seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
predictor.learn(sruri, tluri, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
preconns.push(extract_origin(sruri));
|
||||
}
|
||||
|
||||
var verifier = new Verifier("pageload", preconns, []);
|
||||
seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, verifier);
|
||||
predictor.predict(tluri, null, predictor.PREDICT_LOAD, load_context, verifier);
|
||||
}
|
||||
|
||||
function test_redirect() {
|
||||
reset_seer();
|
||||
reset_predictor();
|
||||
var initial = "http://localhost:4443/redirect";
|
||||
var target = "http://localhost:4444/index.html";
|
||||
var subresources = [
|
||||
@ -147,24 +147,24 @@ function test_redirect() {
|
||||
|
||||
var inituri = newURI(initial);
|
||||
var targeturi = newURI(target);
|
||||
seer.learn(inituri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
seer.learn(targeturi, inituri, seer.LEARN_LOAD_REDIRECT, load_context);
|
||||
seer.learn(targeturi, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
predictor.learn(inituri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
predictor.learn(targeturi, inituri, predictor.LEARN_LOAD_REDIRECT, load_context);
|
||||
predictor.learn(targeturi, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
|
||||
var preconns = [];
|
||||
preconns.push(extract_origin(targeturi));
|
||||
for (var i = 0; i < subresources.length; i++) {
|
||||
var sruri = newURI(subresources[i]);
|
||||
seer.learn(sruri, targeturi, seer.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
predictor.learn(sruri, targeturi, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
preconns.push(extract_origin(sruri));
|
||||
}
|
||||
|
||||
var verifier = new Verifier("redirect", preconns, []);
|
||||
seer.predict(inituri, null, seer.PREDICT_LOAD, load_context, verifier);
|
||||
predictor.predict(inituri, null, predictor.PREDICT_LOAD, load_context, verifier);
|
||||
}
|
||||
|
||||
function test_startup() {
|
||||
reset_seer();
|
||||
reset_predictor();
|
||||
var uris = [
|
||||
"http://localhost:4444/startup",
|
||||
"http://localhost:4443/startup"
|
||||
@ -172,16 +172,16 @@ function test_startup() {
|
||||
var preconns = [];
|
||||
for (var i = 0; i < uris.length; i++) {
|
||||
var uri = newURI(uris[i]);
|
||||
seer.learn(uri, null, seer.LEARN_STARTUP, load_context);
|
||||
predictor.learn(uri, null, predictor.LEARN_STARTUP, load_context);
|
||||
preconns.push(extract_origin(uri));
|
||||
}
|
||||
|
||||
var verifier = new Verifier("startup", preconns, []);
|
||||
seer.predict(null, null, seer.PREDICT_STARTUP, load_context, verifier);
|
||||
predictor.predict(null, null, predictor.PREDICT_STARTUP, load_context, verifier);
|
||||
}
|
||||
|
||||
// A class used to guarantee serialization of SQL queries so we can properly
|
||||
// update last hit times on subresources to ensure the seer tries to do DNS
|
||||
// update last hit times on subresources to ensure the predictor tries to do DNS
|
||||
// preresolve on them instead of preconnecting
|
||||
var DnsContinueVerifier = function _dnsContinueVerifier(subresource, tluri, preresolves) {
|
||||
this.subresource = subresource;
|
||||
@ -200,7 +200,7 @@ DnsContinueVerifier.prototype = {
|
||||
|
||||
QueryInterface: function _dnsContinueVerifier_QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsINetworkSeerVerifier)) {
|
||||
iid.equals(Ci.nsINetworkPredictorVerifier)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ DnsContinueVerifier.prototype = {
|
||||
},
|
||||
|
||||
onPredictPreconnect: function _dnsContinueVerifier_onPredictPreconnect() {
|
||||
// This means that the seer has learned and done our "checkpoint" prediction
|
||||
// This means that the predictor has learned and done our "checkpoint" prediction
|
||||
// Now we can get on with the prediction we actually want to test
|
||||
|
||||
// tstamp is 10 days older than now - just over 1 week, which will ensure we
|
||||
@ -216,10 +216,10 @@ DnsContinueVerifier.prototype = {
|
||||
// x1000 on the Date object value.
|
||||
var tstamp = (new Date().valueOf() * 1000) - (10 * 86400 * 1000000);
|
||||
|
||||
seer.prepareForDnsTest(tstamp, this.subresource);
|
||||
predictor.prepareForDnsTest(tstamp, this.subresource);
|
||||
|
||||
var verifier = new Verifier("dns", [], this.preresolves);
|
||||
seer.predict(this.tluri, null, seer.PREDICT_LOAD, load_context, verifier);
|
||||
predictor.predict(this.tluri, null, predictor.PREDICT_LOAD, load_context, verifier);
|
||||
},
|
||||
|
||||
onPredictDNS: function _dnsContinueVerifier_onPredictDNS() {
|
||||
@ -228,24 +228,24 @@ DnsContinueVerifier.prototype = {
|
||||
};
|
||||
|
||||
function test_dns() {
|
||||
reset_seer();
|
||||
reset_predictor();
|
||||
var toplevel = "http://localhost:4444/index.html";
|
||||
var subresource = "http://localhost:4443/jquery.js";
|
||||
|
||||
var tluri = newURI(toplevel);
|
||||
seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
predictor.learn(tluri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
var sruri = newURI(subresource);
|
||||
seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
predictor.learn(sruri, tluri, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
|
||||
var preresolves = [extract_origin(sruri)];
|
||||
var continue_verifier = new DnsContinueVerifier(subresource, tluri, preresolves);
|
||||
// Fire off a prediction that will do preconnects so we know when the seer
|
||||
// Fire off a prediction that will do preconnects so we know when the predictor
|
||||
// thread has gotten to the point where we can update the database manually
|
||||
seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, continue_verifier);
|
||||
predictor.predict(tluri, null, predictor.PREDICT_LOAD, load_context, continue_verifier);
|
||||
}
|
||||
|
||||
function test_origin() {
|
||||
reset_seer();
|
||||
reset_predictor();
|
||||
var toplevel = "http://localhost:4444/index.html";
|
||||
var subresources = [
|
||||
"http://localhost:4444/style.css",
|
||||
@ -254,11 +254,11 @@ function test_origin() {
|
||||
];
|
||||
|
||||
var tluri = newURI(toplevel);
|
||||
seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
predictor.learn(tluri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
|
||||
var preconns = [];
|
||||
for (var i = 0; i < subresources.length; i++) {
|
||||
var sruri = newURI(subresources[i]);
|
||||
seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
predictor.learn(sruri, tluri, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
|
||||
var origin = extract_origin(sruri);
|
||||
if (preconns.indexOf(origin) === -1) {
|
||||
preconns.push(origin);
|
||||
@ -267,15 +267,15 @@ function test_origin() {
|
||||
|
||||
var loaduri = newURI("http://localhost:4444/anotherpage.html");
|
||||
var verifier = new Verifier("origin", preconns, []);
|
||||
seer.predict(loaduri, null, seer.PREDICT_LOAD, load_context, verifier);
|
||||
predictor.predict(loaduri, null, predictor.PREDICT_LOAD, load_context, verifier);
|
||||
}
|
||||
|
||||
var prefs;
|
||||
var seer_pref;
|
||||
var predictor_pref;
|
||||
|
||||
function cleanup() {
|
||||
reset_seer();
|
||||
prefs.setBoolPref("network.seer.enabled", seer_pref);
|
||||
reset_predictor();
|
||||
prefs.setBoolPref("network.predictor.enabled", predictor_pref);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
@ -291,9 +291,9 @@ function run_test() {
|
||||
tests.forEach(add_test);
|
||||
profile = do_get_profile();
|
||||
prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
seer_pref = prefs.getBoolPref("network.seer.enabled");
|
||||
prefs.setBoolPref("network.seer.enabled", true);
|
||||
seer = Cc["@mozilla.org/network/seer;1"].getService(Ci.nsINetworkSeer);
|
||||
predictor_pref = prefs.getBoolPref("network.predictor.enabled");
|
||||
prefs.setBoolPref("network.predictor.enabled", true);
|
||||
predictor = Cc["@mozilla.org/network/predictor;1"].getService(Ci.nsINetworkPredictor);
|
||||
do_register_cleanup(cleanup);
|
||||
run_next_test();
|
||||
}
|
@ -316,7 +316,7 @@ skip-if = os == "android"
|
||||
[test_about_networking.js]
|
||||
[test_ping_aboutnetworking.js]
|
||||
[test_referrer.js]
|
||||
[test_seer.js]
|
||||
[test_predictor.js]
|
||||
# Android version detection w/in gecko does not work right on infra, so we just
|
||||
# disable this test on all android versions, even though it's enabled on 2.3+ in
|
||||
# the wild.
|
||||
|
@ -104,14 +104,13 @@ AppTrustDomain::FindPotentialIssuers(const SECItem* encodedIssuerName,
|
||||
SECStatus
|
||||
AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
const CertPolicyId& policy,
|
||||
const CERTCertificate* candidateCert,
|
||||
const SECItem& candidateCertDER,
|
||||
/*out*/ TrustLevel* trustLevel)
|
||||
{
|
||||
MOZ_ASSERT(policy.IsAnyPolicy());
|
||||
MOZ_ASSERT(candidateCert);
|
||||
MOZ_ASSERT(trustLevel);
|
||||
MOZ_ASSERT(mTrustedRoot);
|
||||
if (!candidateCert || !trustLevel || !policy.IsAnyPolicy()) {
|
||||
if (!trustLevel || !policy.IsAnyPolicy()) {
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -121,8 +120,20 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
}
|
||||
|
||||
// Handle active distrust of the certificate.
|
||||
|
||||
// XXX: This would be cleaner and more efficient if we could get the trust
|
||||
// information without constructing a CERTCertificate here, but NSS doesn't
|
||||
// expose it in any other easy-to-use fashion.
|
||||
ScopedCERTCertificate candidateCert(
|
||||
CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
|
||||
const_cast<SECItem*>(&candidateCertDER), nullptr,
|
||||
false, true));
|
||||
if (!candidateCert) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
CERTCertTrust trust;
|
||||
if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
|
||||
if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
|
||||
PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, trustObjectSigning);
|
||||
|
||||
// For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
|
||||
@ -141,7 +152,7 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
}
|
||||
|
||||
// mTrustedRoot is the only trust anchor for this validation.
|
||||
if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert)) {
|
||||
if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert.get())) {
|
||||
*trustLevel = TrustLevel::TrustAnchor;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
|
||||
SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA,
|
||||
const mozilla::pkix::CertPolicyId& policy,
|
||||
const CERTCertificate* candidateCert,
|
||||
const SECItem& candidateCertDER,
|
||||
/*out*/ mozilla::pkix::TrustLevel* trustLevel) MOZ_OVERRIDE;
|
||||
SECStatus FindPotentialIssuers(const SECItem* encodedIssuerName,
|
||||
PRTime time,
|
||||
|
@ -72,13 +72,12 @@ NSSCertDBTrustDomain::FindPotentialIssuers(
|
||||
SECStatus
|
||||
NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
const CertPolicyId& policy,
|
||||
const CERTCertificate* candidateCert,
|
||||
const SECItem& candidateCertDER,
|
||||
/*out*/ TrustLevel* trustLevel)
|
||||
{
|
||||
PR_ASSERT(candidateCert);
|
||||
PR_ASSERT(trustLevel);
|
||||
|
||||
if (!candidateCert || !trustLevel) {
|
||||
if (!trustLevel) {
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -90,13 +89,27 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX: This would be cleaner and more efficient if we could get the trust
|
||||
// information without constructing a CERTCertificate here, but NSS doesn't
|
||||
// expose it in any other easy-to-use fashion. The use of
|
||||
// CERT_NewTempCertificate to get a CERTCertificate shouldn't be a
|
||||
// performance problem because NSS will just find the existing
|
||||
// CERTCertificate in its in-memory cache and return it.
|
||||
ScopedCERTCertificate candidateCert(
|
||||
CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
|
||||
const_cast<SECItem*>(&candidateCertDER), nullptr,
|
||||
false, true));
|
||||
if (!candidateCert) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// XXX: CERT_GetCertTrust seems to be abusing SECStatus as a boolean, where
|
||||
// SECSuccess means that there is a trust record and SECFailure means there
|
||||
// is not a trust record. I looked at NSS's internal uses of
|
||||
// CERT_GetCertTrust, and all that code uses the result as a boolean meaning
|
||||
// "We have a trust record."
|
||||
CERTCertTrust trust;
|
||||
if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
|
||||
if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
|
||||
PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, mCertDBTrustType);
|
||||
|
||||
// For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
|
||||
@ -122,7 +135,7 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
return SECSuccess;
|
||||
}
|
||||
#ifndef MOZ_NO_EV_CERTS
|
||||
if (CertIsAuthoritativeForEVPolicy(candidateCert, policy)) {
|
||||
if (CertIsAuthoritativeForEVPolicy(candidateCert.get(), policy)) {
|
||||
*trustLevel = TrustLevel::TrustAnchor;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
|
||||
virtual SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA,
|
||||
const mozilla::pkix::CertPolicyId& policy,
|
||||
const CERTCertificate* candidateCert,
|
||||
const SECItem& candidateCertDER,
|
||||
/*out*/ mozilla::pkix::TrustLevel* trustLevel);
|
||||
|
||||
virtual SECStatus VerifySignedData(const CERTSignedData* signedData,
|
||||
|
@ -661,8 +661,8 @@ struct TransportSecurityPreload {
|
||||
/* Sort hostnames for binary search. */
|
||||
static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||
{ "accounts.google.com", true, true, false, -1, &kPinset_google_root_pems },
|
||||
{ "addons.mozilla.net", true, true, true, 2, &kPinset_mozilla },
|
||||
{ "addons.mozilla.org", true, true, true, 1, &kPinset_mozilla },
|
||||
{ "addons.mozilla.net", true, false, true, 2, &kPinset_mozilla },
|
||||
{ "addons.mozilla.org", true, false, true, 1, &kPinset_mozilla },
|
||||
{ "admin.google.com", true, true, false, -1, &kPinset_google_root_pems },
|
||||
{ "android.com", true, true, false, -1, &kPinset_google_root_pems },
|
||||
{ "api.twitter.com", true, false, false, -1, &kPinset_twitterCDN },
|
||||
@ -988,4 +988,4 @@ static const int kPublicKeyPinningPreloadListLength = 322;
|
||||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1412099175458000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1412704831237000);
|
||||
|
@ -845,9 +845,6 @@ ProcessName(CERTName *name, nsINSSComponent *nssComponent, char16_t **value)
|
||||
|
||||
nsresult rv;
|
||||
CERTRDN **lastRdn;
|
||||
lastRdn = rdns;
|
||||
|
||||
|
||||
/* find last RDN */
|
||||
lastRdn = rdns;
|
||||
while (*lastRdn) lastRdn++;
|
||||
|
@ -432,6 +432,12 @@ function getFailingHttpServer(serverPort, serverIdentities) {
|
||||
// Starts an http OCSP responder that serves good OCSP responses and
|
||||
// returns an object with a method stop that should be called to stop
|
||||
// the http server.
|
||||
// NB: Because generating OCSP responses inside the HTTP request
|
||||
// handler can cause timeouts, the expected responses are pre-generated
|
||||
// all at once before starting the server. This means that their producedAt
|
||||
// times will all be the same. If a test depends on this not being the case,
|
||||
// perhaps calling startOCSPResponder twice (at different times) will be
|
||||
// necessary.
|
||||
//
|
||||
// serverPort is the port of the http OCSP responder
|
||||
// identity is the http hostname that will answer the OCSP requests
|
||||
@ -446,6 +452,17 @@ function startOCSPResponder(serverPort, identity, invalidIdentities,
|
||||
nssDBLocation, expectedCertNames,
|
||||
expectedBasePaths, expectedMethods,
|
||||
expectedResponseTypes) {
|
||||
let ocspResponseGenerationArgs = expectedCertNames.map(
|
||||
function(expectedNick) {
|
||||
let responseType = "good";
|
||||
if (expectedResponseTypes && expectedResponseTypes.length >= 1) {
|
||||
responseType = expectedResponseTypes.shift();
|
||||
}
|
||||
return [responseType, expectedNick, "unused"];
|
||||
}
|
||||
);
|
||||
let ocspResponses = generateOCSPResponses(ocspResponseGenerationArgs,
|
||||
nssDBLocation);
|
||||
let httpServer = new HttpServer();
|
||||
httpServer.registerPrefixHandler("/",
|
||||
function handleServerCallback(aRequest, aResponse) {
|
||||
@ -461,19 +478,9 @@ function startOCSPResponder(serverPort, identity, invalidIdentities,
|
||||
if (expectedMethods && expectedMethods.length >= 1) {
|
||||
do_check_eq(aRequest.method, expectedMethods.shift());
|
||||
}
|
||||
let responseType = "good";
|
||||
if (expectedResponseTypes && expectedResponseTypes.length >= 1) {
|
||||
responseType = expectedResponseTypes.shift();
|
||||
}
|
||||
let expectedNick = expectedCertNames.shift();
|
||||
do_print("Generating ocsp response(" + responseType + ") for '" +
|
||||
expectedNick + "(" + basePath + ")'");
|
||||
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
|
||||
aResponse.setHeader("Content-Type", "application/ocsp-response");
|
||||
let args = [ [responseType, expectedNick, "unused" ] ];
|
||||
let retArray = generateOCSPResponses(args, nssDBLocation);
|
||||
let responseBody = retArray[0];
|
||||
aResponse.bodyOutputStream.write(responseBody, responseBody.length);
|
||||
aResponse.write(ocspResponses.shift());
|
||||
});
|
||||
httpServer.identity.setPrimary("http", identity, serverPort);
|
||||
invalidIdentities.forEach(function(identity) {
|
||||
@ -482,7 +489,8 @@ function startOCSPResponder(serverPort, identity, invalidIdentities,
|
||||
httpServer.start(serverPort);
|
||||
return {
|
||||
stop: function(callback) {
|
||||
do_check_eq(expectedCertNames.length, 0);
|
||||
// make sure we consumed each expected response
|
||||
do_check_eq(ocspResponses.length, 0);
|
||||
if (expectedMethods) {
|
||||
do_check_eq(expectedMethods.length, 0);
|
||||
}
|
||||
|
@ -5,6 +5,13 @@
|
||||
"use strict";
|
||||
|
||||
let gFetchCount = 0;
|
||||
let gGoodOCSPResponse = null;
|
||||
|
||||
function generateGoodOCSPResponse() {
|
||||
let args = [ ["good", "localhostAndExampleCom", "unused" ] ];
|
||||
let responses = generateOCSPResponses(args, "tlsserver");
|
||||
return responses[0];
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
@ -27,16 +34,9 @@ function run_test() {
|
||||
}
|
||||
|
||||
do_print("returning 200 OK");
|
||||
|
||||
let nickname = "localhostAndExampleCom";
|
||||
do_print("Generating ocsp response for '" + nickname + "'");
|
||||
let args = [ ["good", nickname, "unused" ] ];
|
||||
let ocspResponses = generateOCSPResponses(args, "tlsserver");
|
||||
let goodResponse = ocspResponses[0];
|
||||
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "application/ocsp-response");
|
||||
response.bodyOutputStream.write(goodResponse, goodResponse.length);
|
||||
response.write(gGoodOCSPResponse);
|
||||
});
|
||||
ocspResponder.start(8080);
|
||||
|
||||
@ -84,6 +84,10 @@ function add_tests_in_mode(useMozillaPKIX) {
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback(run_next_test, duration, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
});
|
||||
add_test(function() {
|
||||
gGoodOCSPResponse = generateGoodOCSPResponse();
|
||||
run_next_test();
|
||||
});
|
||||
add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK,
|
||||
clearSessionCache);
|
||||
add_test(function() { do_check_eq(gFetchCount, 2); run_next_test(); });
|
||||
|
@ -171,9 +171,9 @@
|
||||
// Only domains that are operationally crucial to Firefox can have per-host
|
||||
// telemetry reporting (the "id") field
|
||||
{ "name": "addons.mozilla.org", "include_subdomains": true,
|
||||
"pins": "mozilla", "test_mode": true, "id": 1 },
|
||||
"pins": "mozilla", "test_mode": false, "id": 1 },
|
||||
{ "name": "addons.mozilla.net", "include_subdomains": true,
|
||||
"pins": "mozilla", "test_mode": true, "id": 2 },
|
||||
"pins": "mozilla", "test_mode": false, "id": 2 },
|
||||
{ "name": "aus4.mozilla.org", "include_subdomains": true,
|
||||
"pins": "mozilla", "test_mode": true, "id": 3 },
|
||||
{ "name": "cdn.mozilla.net", "include_subdomains": true,
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
// (assuming the candidate cert is not actively distrusted).
|
||||
virtual SECStatus GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
const CertPolicyId& policy,
|
||||
const CERTCertificate* candidateCert,
|
||||
const SECItem& candidateCertDER,
|
||||
/*out*/ TrustLevel* trustLevel) = 0;
|
||||
|
||||
// Find all certificates (intermediate and/or root) in the certificate
|
||||
|
@ -558,10 +558,8 @@ CheckIssuerIndependentProperties(TrustDomain& trustDomain,
|
||||
Result rv;
|
||||
|
||||
TrustLevel trustLevel;
|
||||
rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA,
|
||||
requiredPolicy,
|
||||
cert.GetNSSCert(),
|
||||
&trustLevel));
|
||||
rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA, requiredPolicy,
|
||||
cert.GetDER(), &trustLevel));
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -111,6 +111,8 @@ public:
|
||||
|
||||
Result Init();
|
||||
|
||||
const SECItem& GetDER() const { return nssCert->derCert; }
|
||||
|
||||
const SECItem* encodedBasicConstraints;
|
||||
const SECItem* encodedCertificatePolicies;
|
||||
const SECItem* encodedExtendedKeyUsage;
|
||||
|
@ -115,10 +115,10 @@ public:
|
||||
private:
|
||||
SECStatus GetCertTrust(EndEntityOrCA,
|
||||
const CertPolicyId&,
|
||||
const CERTCertificate* candidateCert,
|
||||
const SECItem& candidateCert,
|
||||
/*out*/ TrustLevel* trustLevel)
|
||||
{
|
||||
if (candidateCert == certChainTail[0].get()) {
|
||||
if (SECITEM_ItemsAreEqual(&candidateCert, &certChainTail[0]->derCert)) {
|
||||
*trustLevel = TrustLevel::TrustAnchor;
|
||||
} else {
|
||||
*trustLevel = TrustLevel::InheritsTrust;
|
||||
|
113
security/pkix/tools/DottedOIDToCode.py
Normal file
113
security/pkix/tools/DottedOIDToCode.py
Normal file
@ -0,0 +1,113 @@
|
||||
# This code is made available to you under your choice of the following sets
|
||||
# of licensing terms:
|
||||
###############################################################################
|
||||
# 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/.
|
||||
###############################################################################
|
||||
# Copyright 2013 Mozilla Contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
|
||||
def base128Stringified(value):
|
||||
"""
|
||||
Encodes the given integral value into a string that is an encoded comma-
|
||||
separated series of bytes, base-128, with all but the last byte having
|
||||
the high bit set, in C++ hex notation, as required by the DER rules for the
|
||||
nodes of an OID after the first two.
|
||||
|
||||
>>> base128Stringified(1)
|
||||
'0x01'
|
||||
>>> base128Stringified(10045)
|
||||
'0xce, 0x3d'
|
||||
"""
|
||||
if value < 0:
|
||||
raise ValueError("An OID must have only positive-value nodes.")
|
||||
|
||||
format = "0x%.2x"
|
||||
|
||||
# least significant byte has highest bit unset
|
||||
result = format % (value % 0x80)
|
||||
value /= 0x80
|
||||
|
||||
while value != 0:
|
||||
# other bytes have highest bit set
|
||||
result = (format % (0x80 | (value % 0x80))) + ", " + result
|
||||
value /= 0x80
|
||||
|
||||
return result
|
||||
|
||||
def dottedOIDToCEncoding(dottedOID):
|
||||
"""
|
||||
Takes a dotted OID string (e.g. '1.2.840.10045.4.3.4') as input, and
|
||||
returns a string that contains the hex encoding of the OID in C++ literal
|
||||
notation, e.g. '0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04'. Note that
|
||||
the ASN.1 tag and length are *not* included in the result.
|
||||
"""
|
||||
nodes = [int(x) for x in dottedOID.strip().split(".")]
|
||||
if len(nodes) < 2:
|
||||
raise ValueError("An OID must have at least two nodes.")
|
||||
if not (0 <= nodes[0] <= 2):
|
||||
raise ValueError("The first node of an OID must be 0, 1, or 2.")
|
||||
if not (0 <= nodes[1] <= 39):
|
||||
# XXX: Does this restriction apply when the first part is 2?
|
||||
raise ValueError("The second node of an OID must be 0-39.")
|
||||
firstByte = (40 * nodes[0]) + nodes[1]
|
||||
allStringified = [base128Stringified(x) for x in [firstByte] + nodes[2:]]
|
||||
return ", ".join(allStringified)
|
||||
|
||||
def specNameToCName(specName):
|
||||
"""
|
||||
Given an string containing an ASN.1 name, returns a string that is a valid
|
||||
C++ identifier that is as similar to that name as possible. Since most
|
||||
ASN.1 identifiers used in PKIX specifications are legal C++ names except
|
||||
for containing hyphens, this function just converts the hyphens to
|
||||
underscores. This may need to be improved in the future if we encounter
|
||||
names with other funny characters.
|
||||
"""
|
||||
return specName.replace("-", "_")
|
||||
|
||||
def toCode(programName, specName, dottedOID):
|
||||
"""
|
||||
Given an ASN.1 name and a string containing the dotted representation of an
|
||||
OID, returns a string that contains a C++ declaration for a named constant
|
||||
that contains that OID value. Note that the ASN.1 tag and length are *not*
|
||||
included in the result.
|
||||
|
||||
This:
|
||||
toCode("DottedOIDToCode.py", "ecdsa-with-SHA512", "1.2.840.10045.4.3.4")
|
||||
would result in a string like:
|
||||
// python DottedOIDToCode.py ecdsa-with-SHA512 1.2.840.10045.4.3.4
|
||||
static const uint8_t ecdsa_with_SHA512[] = {
|
||||
0x2a, 0x86,0x48, 0xce,0x3d, 0x04, 0x03, 0x04
|
||||
};
|
||||
"""
|
||||
return (" // python %s %s %s\n" +
|
||||
" static const uint8_t %s[] = {\n" +
|
||||
" %s\n" +
|
||||
" };\n") % (programName, specName, dottedOID,
|
||||
specNameToCName(specName),
|
||||
dottedOIDToCEncoding(dottedOID))
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
print("usage: python %s <name> <dotted-oid>" % sys.argv[0],
|
||||
file=sys.stderr)
|
||||
print("example: python %s ecdsa-with-SHA1 1.2.840.10045.4.1" %
|
||||
sys.argv[0], file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(toCode(sys.argv[0], sys.argv[1], sys.argv[2]))
|
@ -152,6 +152,7 @@ SandboxFilterImpl::Build() {
|
||||
Allow(SYSCALL(getpid));
|
||||
Allow(SYSCALL(gettid));
|
||||
Allow(SYSCALL(getrusage));
|
||||
Allow(SYSCALL(times));
|
||||
Allow(SYSCALL(madvise));
|
||||
Allow(SYSCALL(dup));
|
||||
Allow(SYSCALL(nanosleep));
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user