mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Merge m-c to b2g-inbound a=merge
This commit is contained in:
commit
3af458857c
@ -1088,3 +1088,6 @@ pref("dom.mozSettings.SettingsService.verbose.enabled", false);
|
||||
// IndexedDB transactions to be opened as readonly or keep everything as
|
||||
// readwrite.
|
||||
pref("dom.mozSettings.allowForceReadOnly", false);
|
||||
|
||||
// RequestSync API is enabled by default on B2G.
|
||||
pref("dom.requestSync.enabled", true);
|
||||
|
@ -15,6 +15,7 @@ Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
|
||||
Cu.import('resource://gre/modules/Keyboard.jsm');
|
||||
Cu.import('resource://gre/modules/ErrorPage.jsm');
|
||||
Cu.import('resource://gre/modules/AlertsHelper.jsm');
|
||||
Cu.import('resource://gre/modules/RequestSyncService.jsm');
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
Cu.import('resource://gre/modules/NetworkStatsService.jsm');
|
||||
Cu.import('resource://gre/modules/ResourceStatsService.jsm');
|
||||
@ -27,6 +28,7 @@ SignInToWebsiteController.init();
|
||||
Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
|
||||
Cu.import('resource://gre/modules/DownloadsAPI.jsm');
|
||||
Cu.import('resource://gre/modules/MobileIdentityManager.jsm');
|
||||
Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
@ -106,3 +106,7 @@ contract @mozilla.org/services/mobileid-ui-glue;1 {83dbe26a-81f3-4a75-9541-3d0b7
|
||||
component {7211ece0-b458-4635-9afc-f8d7f376ee95} B2GAppMigrator.js
|
||||
contract @mozilla.org/app-migrator;1 {7211ece0-b458-4635-9afc-f8d7f376ee95}
|
||||
|
||||
# B2GPresentationDevicePrompt.js
|
||||
component {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} B2GPresentationDevicePrompt.js
|
||||
contract @mozilla.org/presentation-device/prompt;1 {4a300c26-e99b-4018-ab9b-c48cf9bc4de1}
|
||||
|
||||
|
87
b2g/components/B2GPresentationDevicePrompt.js
Normal file
87
b2g/components/B2GPresentationDevicePrompt.js
Normal file
@ -0,0 +1,87 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
function debug(aMsg) {
|
||||
//dump("-*- B2GPresentationDevicePrompt: " + aMsg + "\n");
|
||||
}
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
const kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID = "@mozilla.org/presentation-device/prompt;1";
|
||||
const kB2GPRESENTATIONDEVICEPROMPT_CID = Components.ID("{4a300c26-e99b-4018-ab9b-c48cf9bc4de1}");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
function B2GPresentationDevicePrompt() {}
|
||||
|
||||
B2GPresentationDevicePrompt.prototype = {
|
||||
classID: kB2GPRESENTATIONDEVICEPROMPT_CID,
|
||||
contractID: kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID,
|
||||
classDescription: "B2G Presentation Device Prompt",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt]),
|
||||
|
||||
// nsIPresentationDevicePrompt
|
||||
promptDeviceSelection: function(aRequest) {
|
||||
let self = this;
|
||||
let requestId = Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
|
||||
SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(aEvent) {
|
||||
let detail = aEvent.detail;
|
||||
if (detail.id !== requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
SystemAppProxy.removeEventListener("mozContentEvent", contentEvent);
|
||||
|
||||
switch (detail.type) {
|
||||
case "presentation-select-result":
|
||||
debug("device " + detail.deviceId + " is selected by user");
|
||||
let device = self._getDeviceById(detail.deviceId);
|
||||
if (!device) {
|
||||
debug("cancel request because device is not found");
|
||||
aRequest.cancel();
|
||||
}
|
||||
aRequest.select(device);
|
||||
break;
|
||||
case "presentation-select-deny":
|
||||
debug("request canceled by user");
|
||||
aRequest.cancel();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
let detail = {
|
||||
type: "presentation-select-device",
|
||||
origin: aRequest.origin,
|
||||
requestURL: aRequest.requestURL,
|
||||
id: requestId,
|
||||
};
|
||||
|
||||
SystemAppProxy.dispatchEvent(detail);
|
||||
},
|
||||
|
||||
_getDeviceById: function(aDeviceId) {
|
||||
let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"]
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
let devices = deviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray);
|
||||
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
let device = devices.queryElementAt(i, Ci.nsIPresentationDevice);
|
||||
if (device.id === aDeviceId) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GPresentationDevicePrompt]);
|
@ -11,6 +11,7 @@ EXTRA_COMPONENTS += [
|
||||
'AlertsService.js',
|
||||
'B2GAboutRedirector.js',
|
||||
'B2GAppMigrator.js',
|
||||
'B2GPresentationDevicePrompt.js',
|
||||
'ContentPermissionPrompt.js',
|
||||
'FilePicker.js',
|
||||
'FxAccountsUIGlue.js',
|
||||
|
@ -5,6 +5,7 @@ support-files =
|
||||
SandboxPromptTest.html
|
||||
filepicker_path_handler_chrome.js
|
||||
systemapp_helper.js
|
||||
presentation_prompt_handler_chrome.js
|
||||
|
||||
[test_filepicker_path.html]
|
||||
[test_permission_deny.html]
|
||||
@ -12,3 +13,4 @@ support-files =
|
||||
skip-if = true # Bug 1019572 - frequent timeouts
|
||||
[test_sandbox_permission.html]
|
||||
[test_systemapp.html]
|
||||
[test_presentation_device_prompt.html]
|
||||
|
@ -0,0 +1,94 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
function debug(str) {
|
||||
dump('presentation_prompt_handler_chrome: ' + str + '\n');
|
||||
}
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
|
||||
|
||||
const manager = Cc["@mozilla.org/presentation-device/manager;1"]
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
|
||||
const prompt = Cc['@mozilla.org/presentation-device/prompt;1']
|
||||
.getService(Ci.nsIPresentationDevicePrompt);
|
||||
|
||||
function TestPresentationDevice(options) {
|
||||
this.id = options.id;
|
||||
this.name = options.name;
|
||||
this.type = options.type;
|
||||
}
|
||||
|
||||
TestPresentationDevice.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
|
||||
establishSessionTransport: function() {
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
function TestPresentationRequest(options) {
|
||||
this.origin = options.origin;
|
||||
this.requestURL = options.requestURL;
|
||||
}
|
||||
|
||||
TestPresentationRequest.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceRequest]),
|
||||
select: function(device) {
|
||||
let result = {
|
||||
type: 'select',
|
||||
device: {
|
||||
id: device.id,
|
||||
name: device.name,
|
||||
type: device.type,
|
||||
},
|
||||
};
|
||||
sendAsyncMessage('presentation-select-result', result);
|
||||
},
|
||||
cancel: function() {
|
||||
let result = {
|
||||
type: 'cancel',
|
||||
};
|
||||
sendAsyncMessage('presentation-select-result', result);
|
||||
},
|
||||
};
|
||||
|
||||
var testDevice = null;
|
||||
|
||||
addMessageListener('setup', function(device_options) {
|
||||
testDevice = new TestPresentationDevice(device_options);
|
||||
manager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(testDevice);
|
||||
sendAsyncMessage('setup-complete');
|
||||
});
|
||||
|
||||
let eventHandler = function(evt) {
|
||||
if (!evt.detail || evt.detail.type !== 'presentation-select-device') {
|
||||
return;
|
||||
}
|
||||
|
||||
sendAsyncMessage('presentation-select-device', evt.detail);
|
||||
};
|
||||
|
||||
SystemAppProxy.addEventListener('mozChromeEvent', eventHandler);
|
||||
|
||||
// need to remove ChromeEvent listener after test finished.
|
||||
addMessageListener('teardown', function() {
|
||||
if (testDevice) {
|
||||
manager.removeDevice(testDevice);
|
||||
}
|
||||
SystemAppProxy.removeEventListener('mozChromeEvent', eventHandler);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-device-prompt', function(request_options) {
|
||||
let request = new TestPresentationRequest(request_options);
|
||||
prompt.promptDeviceSelection(request);
|
||||
});
|
||||
|
||||
addMessageListener('presentation-select-response', function(detail) {
|
||||
SystemAppProxy._sendCustomEvent('mozContentEvent', detail);
|
||||
});
|
||||
|
@ -0,0 +1,145 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Presentation Device Selection</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Test for Presentation Device Selection</a>
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
'use strict';
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var contentEventHandler = null;
|
||||
|
||||
var gUrl = SimpleTest.getTestFileURL('presentation_prompt_handler_chrome.js');
|
||||
var gScript = SpecialPowers.loadChromeScript(gUrl);
|
||||
|
||||
function testSetup() {
|
||||
info('setup for device selection');
|
||||
return new Promise(function(resolve, reject) {
|
||||
let device = {
|
||||
id: 'test-id',
|
||||
name: 'test-name',
|
||||
type: 'test-type',
|
||||
};
|
||||
gScript.addMessageListener('setup-complete', function() {
|
||||
resolve(device);
|
||||
});
|
||||
gScript.sendAsyncMessage('setup', device);
|
||||
});
|
||||
}
|
||||
|
||||
function testSelected(device) {
|
||||
info('test device selected by user');
|
||||
return new Promise(function(resolve, reject) {
|
||||
let request = {
|
||||
origin: 'test-origin',
|
||||
requestURL: 'test-requestURL',
|
||||
};
|
||||
|
||||
gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
|
||||
gScript.removeMessageListener('presentation-select-device', contentEventHandler);
|
||||
ok(true, 'receive user prompt for device selection');
|
||||
is(detail.origin, request.origin, 'expected origin');
|
||||
is(detail.requestURL, request.requestURL, 'expected requestURL');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'presentation-select-result',
|
||||
deviceId: device.id,
|
||||
};
|
||||
gScript.sendAsyncMessage('presentation-select-response', response);
|
||||
|
||||
gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
|
||||
gScript.removeMessageListener('presentation-select-result', resultHandler);
|
||||
is(result.type, 'select', 'expect device selected');
|
||||
is(result.device.id, device.id, 'expected device id');
|
||||
is(result.device.name, device.name, 'expected device name');
|
||||
is(result.device.type, device.type, 'expected devcie type');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-device-prompt', request);
|
||||
});
|
||||
}
|
||||
|
||||
function testSelectedNotExisted() {
|
||||
info('test selected device doesn\'t exist');
|
||||
return new Promise(function(resolve, reject) {
|
||||
gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
|
||||
gScript.removeMessageListener('presentation-select-device', contentEventHandler);
|
||||
ok(true, 'receive user prompt for device selection');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'presentation-select-deny',
|
||||
deviceId: undefined, // simulate device Id that doesn't exist
|
||||
};
|
||||
gScript.sendAsyncMessage('presentation-select-response', response);
|
||||
|
||||
gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
|
||||
gScript.removeMessageListener('presentation-select-result', resultHandler);
|
||||
is(result.type, 'cancel', 'expect user cancel');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let request = {
|
||||
origin: 'test-origin',
|
||||
requestURL: 'test-requestURL',
|
||||
};
|
||||
gScript.sendAsyncMessage('trigger-device-prompt', request);
|
||||
});
|
||||
}
|
||||
|
||||
function testDenied() {
|
||||
info('test denial of device selection');
|
||||
return new Promise(function(resolve, reject) {
|
||||
gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
|
||||
gScript.removeMessageListener('presentation-select-device', contentEventHandler);
|
||||
ok(true, 'receive user prompt for device selection');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'presentation-select-deny',
|
||||
};
|
||||
gScript.sendAsyncMessage('presentation-select-response', response);
|
||||
|
||||
gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
|
||||
gScript.removeMessageListener('presentation-select-result', resultHandler);
|
||||
is(result.type, 'cancel', 'expect user cancel');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let request = {
|
||||
origin: 'test-origin',
|
||||
requestURL: 'test-requestURL',
|
||||
};
|
||||
gScript.sendAsyncMessage('trigger-device-prompt', request);
|
||||
});
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
testSetup()
|
||||
.then(testSelected)
|
||||
.then(testSelectedNotExisted)
|
||||
.then(testDenied)
|
||||
.then(function() {
|
||||
info('test finished, teardown');
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', runTests);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -27,7 +27,8 @@
|
||||
],
|
||||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1"
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2G_UPDATE_CHANNEL": "nightly"
|
||||
},
|
||||
"b2g_manifest": "dolphin.xml",
|
||||
"b2g_manifest_intree": true,
|
||||
|
@ -210,6 +210,7 @@
|
||||
@BINPATH@/components/dom_xul.xpt
|
||||
@BINPATH@/components/dom_time.xpt
|
||||
@BINPATH@/components/dom_engineeringmode.xpt
|
||||
@BINPATH@/components/dom_presentation.xpt
|
||||
@BINPATH@/components/downloads.xpt
|
||||
@BINPATH@/components/editor.xpt
|
||||
@BINPATH@/components/embed_base.xpt
|
||||
@ -342,6 +343,9 @@
|
||||
@BINPATH@/components/zipwriter.xpt
|
||||
|
||||
; JavaScript components
|
||||
@BINPATH@/components/RequestSync.manifest
|
||||
@BINPATH@/components/RequestSyncManager.js
|
||||
@BINPATH@/components/RequestSyncScheduler.js
|
||||
@BINPATH@/components/ChromeNotifications.js
|
||||
@BINPATH@/components/ChromeNotifications.manifest
|
||||
@BINPATH@/components/ConsoleAPI.manifest
|
||||
@ -373,7 +377,6 @@
|
||||
@BINPATH@/components/nsBrowserGlue.js
|
||||
@BINPATH@/components/nsSetDefaultBrowser.manifest
|
||||
@BINPATH@/components/nsSetDefaultBrowser.js
|
||||
@BINPATH@/components/BrowserPlaces.manifest
|
||||
@BINPATH@/components/toolkitsearch.manifest
|
||||
@BINPATH@/components/nsTryToClose.manifest
|
||||
@BINPATH@/components/nsTryToClose.js
|
||||
@ -401,6 +404,8 @@
|
||||
@BINPATH@/components/nsAsyncShutdown.js
|
||||
@BINPATH@/components/htmlMenuBuilder.js
|
||||
@BINPATH@/components/htmlMenuBuilder.manifest
|
||||
@BINPATH@/components/PresentationDeviceInfoManager.manifest
|
||||
@BINPATH@/components/PresentationDeviceInfoManager.js
|
||||
|
||||
; WiFi, NetworkManager, NetworkStats
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -497,7 +502,6 @@
|
||||
@BINPATH@/components/UnifiedComplete.manifest
|
||||
@BINPATH@/components/UnifiedComplete.js
|
||||
@BINPATH@/components/nsPlacesExpiration.js
|
||||
@BINPATH@/components/PlacesProtocolHandler.js
|
||||
@BINPATH@/components/PlacesCategoriesStarter.js
|
||||
@BINPATH@/components/nsDefaultCLH.manifest
|
||||
@BINPATH@/components/nsDefaultCLH.js
|
||||
@ -861,6 +865,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
||||
@BINPATH@/components/InterAppCommUIGlue.js
|
||||
@BINPATH@/components/SystemMessageGlue.js
|
||||
@BINPATH@/components/B2GAppMigrator.js
|
||||
@BINPATH@/components/B2GPresentationDevicePrompt.js
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
@BINPATH@/components/SimulatorScreen.js
|
||||
|
@ -1377,6 +1377,8 @@ pref("devtools.inspector.show_pseudo_elements", true);
|
||||
pref("devtools.inspector.imagePreviewTooltipSize", 300);
|
||||
// Enable user agent style inspection in rule-view
|
||||
pref("devtools.inspector.showUserAgentStyles", false);
|
||||
// Show all native anonymous content (like controls in <video> tags)
|
||||
pref("devtools.inspector.showAllAnonymousContent", false);
|
||||
|
||||
// DevTools default color unit
|
||||
pref("devtools.defaultColorUnit", "hex");
|
||||
@ -1781,7 +1783,7 @@ pref("privacy.trackingprotection.ui.enabled", false);
|
||||
#endif
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("browser.tabs.remote.autostart.1", false);
|
||||
pref("browser.tabs.remote.autostart.1", true);
|
||||
#endif
|
||||
|
||||
// Temporary pref to allow printing in e10s windows on some platforms.
|
||||
|
@ -550,6 +550,7 @@
|
||||
#endif
|
||||
command="View:PageInfo"/>
|
||||
<menu id="menu_mirrorTabCmd"
|
||||
hidden="true"
|
||||
accesskey="&mirrorTabCmd.accesskey;"
|
||||
label="&mirrorTabCmd.label;">
|
||||
<menupopup id="menu_mirrorTab-popup"
|
||||
|
@ -2940,7 +2940,7 @@ function BrowserFullScreen()
|
||||
|
||||
function mirrorShow(popup) {
|
||||
let services = CastingApps.getServicesForMirroring();
|
||||
popup.ownerDocument.getElementById("menu_mirrorTabCmd").disabled = !services.length;
|
||||
popup.ownerDocument.getElementById("menu_mirrorTabCmd").hidden = !services.length;
|
||||
}
|
||||
|
||||
function mirrorMenuItemClicked(event) {
|
||||
|
@ -249,7 +249,8 @@ Sanitizer.prototype = {
|
||||
try {
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
os.notifyObservers(null, "browser:purge-session-history", "");
|
||||
let clearStartingTime = this.range ? String(this.range[0]) : "";
|
||||
os.notifyObservers(null, "browser:purge-session-history", clearStartingTime);
|
||||
}
|
||||
catch (e) { }
|
||||
|
||||
|
@ -254,5 +254,20 @@ let tests = [
|
||||
this.notification2.remove();
|
||||
},
|
||||
onHidden: function(popup) { }
|
||||
},
|
||||
// The anchor icon should be shown for notifications in background windows.
|
||||
{ id: "Test#13",
|
||||
run: function() {
|
||||
let notifyObj = new BasicNotification(this.id);
|
||||
notifyObj.options.dismissed = true;
|
||||
let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
|
||||
whenDelayedStartupFinished(win, function() {
|
||||
showNotification(notifyObj);
|
||||
let anchor = document.getElementById("default-notification-icon");
|
||||
is(anchor.getAttribute("showing"), "true", "the anchor is shown");
|
||||
win.close();
|
||||
goNext();
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
|
@ -279,6 +279,8 @@ loop.store.ActiveRoomStore = (function() {
|
||||
* granted and starts joining the room.
|
||||
*/
|
||||
gotMediaPermission: function() {
|
||||
this.setStoreState({roomState: ROOM_STATES.JOINING});
|
||||
|
||||
this._mozLoop.rooms.join(this._storeState.roomToken,
|
||||
function(error, responseData) {
|
||||
if (error) {
|
||||
@ -461,7 +463,8 @@ loop.store.ActiveRoomStore = (function() {
|
||||
delete this._timeout;
|
||||
}
|
||||
|
||||
if (this._storeState.roomState === ROOM_STATES.JOINED ||
|
||||
if (this._storeState.roomState === ROOM_STATES.JOINING ||
|
||||
this._storeState.roomState === ROOM_STATES.JOINED ||
|
||||
this._storeState.roomState === ROOM_STATES.SESSION_CONNECTED ||
|
||||
this._storeState.roomState === ROOM_STATES.HAS_PARTICIPANTS) {
|
||||
this._mozLoop.rooms.leave(this._storeState.roomToken,
|
||||
|
@ -75,7 +75,7 @@ loop.shared.views.FeedbackView = (function(l10n) {
|
||||
audio_quality: l10n.get("feedback_category_audio_quality"),
|
||||
video_quality: l10n.get("feedback_category_video_quality"),
|
||||
disconnected : l10n.get("feedback_category_was_disconnected"),
|
||||
confusing: l10n.get("feedback_category_confusing"),
|
||||
confusing: l10n.get("feedback_category_confusing2"),
|
||||
other: l10n.get("feedback_category_other2")
|
||||
};
|
||||
},
|
||||
@ -142,7 +142,7 @@ loop.shared.views.FeedbackView = (function(l10n) {
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
React.createElement(FeedbackLayout, {title: l10n.get("feedback_what_makes_you_sad"),
|
||||
React.createElement(FeedbackLayout, {title: l10n.get("feedback_category_list_heading"),
|
||||
reset: this.props.reset},
|
||||
React.createElement("form", {onSubmit: this.handleFormSubmit},
|
||||
this._getCategoryFields(),
|
||||
|
@ -75,7 +75,7 @@ loop.shared.views.FeedbackView = (function(l10n) {
|
||||
audio_quality: l10n.get("feedback_category_audio_quality"),
|
||||
video_quality: l10n.get("feedback_category_video_quality"),
|
||||
disconnected : l10n.get("feedback_category_was_disconnected"),
|
||||
confusing: l10n.get("feedback_category_confusing"),
|
||||
confusing: l10n.get("feedback_category_confusing2"),
|
||||
other: l10n.get("feedback_category_other2")
|
||||
};
|
||||
},
|
||||
@ -142,7 +142,7 @@ loop.shared.views.FeedbackView = (function(l10n) {
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<FeedbackLayout title={l10n.get("feedback_what_makes_you_sad")}
|
||||
<FeedbackLayout title={l10n.get("feedback_category_list_heading")}
|
||||
reset={this.props.reset}>
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
{this._getCategoryFields()}
|
||||
|
@ -16,6 +16,8 @@ loop.store.ROOM_STATES = {
|
||||
READY: "room-ready",
|
||||
// Obtaining media from the user
|
||||
MEDIA_WAIT: "room-media-wait",
|
||||
// Joining the room is taking place
|
||||
JOINING: "room-joining",
|
||||
// The room is known to be joined on the loop-server
|
||||
JOINED: "room-joined",
|
||||
// The room is connected to the sdk server.
|
||||
|
@ -87,7 +87,9 @@ loop.CallConnectionWebSocket = (function() {
|
||||
* should we call this.
|
||||
*/
|
||||
close: function() {
|
||||
this.socket.close();
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
},
|
||||
|
||||
_clearConnectionFlags: function() {
|
||||
|
@ -94,6 +94,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
)
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.JOINING:
|
||||
case ROOM_STATES.JOINED:
|
||||
case ROOM_STATES.SESSION_CONNECTED: {
|
||||
return (
|
||||
@ -294,7 +295,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Watches for when we transition to JOINED room state, so we can request
|
||||
* Watches for when we transition to MEDIA_WAIT room state, so we can request
|
||||
* user media access.
|
||||
*
|
||||
* @param {Object} nextProps (Unused)
|
||||
|
@ -94,6 +94,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.JOINING:
|
||||
case ROOM_STATES.JOINED:
|
||||
case ROOM_STATES.SESSION_CONNECTED: {
|
||||
return (
|
||||
@ -294,7 +295,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Watches for when we transition to JOINED room state, so we can request
|
||||
* Watches for when we transition to MEDIA_WAIT room state, so we can request
|
||||
* user media access.
|
||||
*
|
||||
* @param {Object} nextProps (Unused)
|
||||
|
@ -68,12 +68,12 @@ call_progress_ringing_description=Ringing…
|
||||
fxos_app_needed=Please install the {{fxosAppName}} app from the Firefox Marketplace.
|
||||
|
||||
feedback_call_experience_heading2=How was your conversation?
|
||||
feedback_what_makes_you_sad=What makes you sad?
|
||||
feedback_thank_you_heading=Thank you for your feedback!
|
||||
feedback_category_list_heading=What made you sad?
|
||||
feedback_category_audio_quality=Audio quality
|
||||
feedback_category_video_quality=Video quality
|
||||
feedback_category_was_disconnected=Was disconnected
|
||||
feedback_category_confusing=Confusing
|
||||
feedback_category_confusing2=Confusing controls
|
||||
feedback_category_other2=Other
|
||||
feedback_custom_category_text_placeholder=What went wrong?
|
||||
feedback_submit_button=Submit
|
||||
|
@ -355,6 +355,12 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
store.setStoreState({roomToken: "tokenFake"});
|
||||
});
|
||||
|
||||
it("should set the room state to JOINING", function() {
|
||||
store.gotMediaPermission();
|
||||
|
||||
expect(store.getStoreState().roomState).eql(ROOM_STATES.JOINING);
|
||||
});
|
||||
|
||||
it("should call rooms.join on mozLoop", function() {
|
||||
store.gotMediaPermission();
|
||||
|
||||
@ -677,6 +683,17 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
"fakeToken", "1627384950");
|
||||
});
|
||||
|
||||
it("should call mozLoop.rooms.leave if the room state is JOINING",
|
||||
function() {
|
||||
store.setStoreState({roomState: ROOM_STATES.JOINING});
|
||||
|
||||
store.windowUnload();
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.rooms.leave);
|
||||
sinon.assert.calledWithExactly(fakeMozLoop.rooms.leave,
|
||||
"fakeToken", "1627384950");
|
||||
});
|
||||
|
||||
it("should set the state to CLOSING", function() {
|
||||
store.windowUnload();
|
||||
|
||||
|
@ -2469,19 +2469,19 @@ let DefaultBrowserCheck = {
|
||||
let promptTitle = shellBundle.getString("setDefaultBrowserTitle");
|
||||
let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
|
||||
[brandShortName]);
|
||||
let dontAskLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
|
||||
[brandShortName]);
|
||||
let askLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
|
||||
[brandShortName]);
|
||||
|
||||
let ps = Services.prompt;
|
||||
let dontAsk = { value: false };
|
||||
let shouldAsk = { value: true };
|
||||
let buttonFlags = (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0) +
|
||||
(ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_1) +
|
||||
ps.BUTTON_POS_0_DEFAULT;
|
||||
let rv = ps.confirmEx(win, promptTitle, promptMessage, buttonFlags,
|
||||
yesButton, notNowButton, null, dontAskLabel, dontAsk);
|
||||
yesButton, notNowButton, null, askLabel, shouldAsk);
|
||||
if (rv == 0) {
|
||||
this.setAsDefault();
|
||||
} else if (dontAsk.value) {
|
||||
} else if (!shouldAsk.value) {
|
||||
ShellService.shouldCheckDefaultBrowser = false;
|
||||
}
|
||||
}
|
||||
@ -2502,7 +2502,7 @@ let DefaultBrowserCheck = {
|
||||
let E10SUINotification = {
|
||||
// Increase this number each time we want to roll out an
|
||||
// e10s testing period to Nightly users.
|
||||
CURRENT_NOTICE_COUNT: 3,
|
||||
CURRENT_NOTICE_COUNT: 4,
|
||||
CURRENT_PROMPT_PREF: "browser.displayedE10SPrompt.1",
|
||||
PREVIOUS_PROMPT_PREF: "browser.displayedE10SPrompt",
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
component {6bcb9bde-9018-4443-a071-c32653469597} PlacesProtocolHandler.js
|
||||
contract @mozilla.org/network/protocol;1?name=place {6bcb9bde-9018-4443-a071-c32653469597}
|
@ -1,49 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et
|
||||
* 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/. */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const SCHEME = "place";
|
||||
const URL = "chrome://browser/content/places/content-ui/controller.xhtml";
|
||||
|
||||
function PlacesProtocolHandler() {}
|
||||
|
||||
PlacesProtocolHandler.prototype = {
|
||||
scheme: SCHEME,
|
||||
defaultPort: -1,
|
||||
protocolFlags: Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
|
||||
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
|
||||
Ci.nsIProtocolHandler.URI_NORELATIVE |
|
||||
Ci.nsIProtocolHandler.URI_NOAUTH,
|
||||
|
||||
newURI: function PPH_newURI(aSpec, aOriginCharset, aBaseUri) {
|
||||
let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
|
||||
uri.spec = aSpec;
|
||||
return uri;
|
||||
},
|
||||
|
||||
newChannel: function PPH_newChannel(aUri) {
|
||||
let chan = NetUtil.newChannel(URL);
|
||||
chan.originalURI = aUri;
|
||||
return chan;
|
||||
},
|
||||
|
||||
allowPort: function PPH_allowPort(aPort, aScheme) {
|
||||
return false;
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIProtocolHandler
|
||||
]),
|
||||
|
||||
classID: Components.ID("{6bcb9bde-9018-4443-a071-c32653469597}")
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PlacesProtocolHandler]);
|
@ -826,12 +826,12 @@ this.PlacesUIUtils = {
|
||||
* web panel.
|
||||
* see also openUILinkIn
|
||||
*/
|
||||
openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aView) {
|
||||
openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aView, aPrivate) {
|
||||
let window = aView.ownerWindow;
|
||||
this._openNodeIn(aNode, aWhere, window);
|
||||
this._openNodeIn(aNode, aWhere, window, aPrivate);
|
||||
},
|
||||
|
||||
_openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aWindow) {
|
||||
_openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aWindow, aPrivate=false) {
|
||||
if (aNode && PlacesUtils.nodeIsURI(aNode) &&
|
||||
this.checkURLSecurity(aNode, aWindow)) {
|
||||
let isBookmark = PlacesUtils.nodeIsBookmark(aNode);
|
||||
@ -855,8 +855,10 @@ this.PlacesUIUtils = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aWindow.openUILinkIn(aNode.uri, aWhere, {
|
||||
inBackground: Services.prefs.getBoolPref("browser.tabs.loadBookmarksInBackground")
|
||||
inBackground: Services.prefs.getBoolPref("browser.tabs.loadBookmarksInBackground"),
|
||||
private: aPrivate,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -7,6 +7,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "ForgetAboutSite",
|
||||
"resource://gre/modules/ForgetAboutSite.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
||||
// XXXmano: we should move most/all of these constants to PlacesUtils
|
||||
const ORGANIZER_ROOT_BOOKMARKS = "place:folder=BOOKMARKS_MENU&excludeItems=1&queryType=1";
|
||||
@ -178,6 +180,7 @@ PlacesController.prototype = {
|
||||
return false;
|
||||
case "placesCmd_open":
|
||||
case "placesCmd_open:window":
|
||||
case "placesCmd_open:privatewindow":
|
||||
case "placesCmd_open:tab":
|
||||
var selectedNode = this._view.selectedNode;
|
||||
return selectedNode && PlacesUtils.nodeIsURI(selectedNode);
|
||||
@ -263,6 +266,9 @@ PlacesController.prototype = {
|
||||
case "placesCmd_open:window":
|
||||
PlacesUIUtils.openNodeIn(this._view.selectedNode, "window", this._view);
|
||||
break;
|
||||
case "placesCmd_open:privatewindow":
|
||||
PlacesUIUtils.openNodeIn(this._view.selectedNode, "window", this._view, true);
|
||||
break;
|
||||
case "placesCmd_open:tab":
|
||||
PlacesUIUtils.openNodeIn(this._view.selectedNode, "tab", this._view);
|
||||
break;
|
||||
@ -601,7 +607,10 @@ PlacesController.prototype = {
|
||||
// We allow pasting into tag containers, so special case that.
|
||||
var hideIfNoIP = item.getAttribute("hideifnoinsertionpoint") == "true" &&
|
||||
noIp && !(ip && ip.isTag && item.id == "placesContext_paste");
|
||||
var shouldHideItem = hideIfNoIP || !this._shouldShowMenuItem(item, metadata);
|
||||
var hideIfPrivate = item.getAttribute("hideifprivatebrowsing") == "true" &&
|
||||
PrivateBrowsingUtils.isWindowPrivate(window);
|
||||
var shouldHideItem = hideIfNoIP || hideIfPrivate ||
|
||||
!this._shouldShowMenuItem(item, metadata);
|
||||
item.hidden = item.disabled = shouldHideItem;
|
||||
|
||||
if (!item.hidden) {
|
||||
@ -1690,6 +1699,7 @@ function goUpdatePlacesCommands() {
|
||||
|
||||
updatePlacesCommand("placesCmd_open");
|
||||
updatePlacesCommand("placesCmd_open:window");
|
||||
updatePlacesCommand("placesCmd_open:privatewindow");
|
||||
updatePlacesCommand("placesCmd_open:tab");
|
||||
updatePlacesCommand("placesCmd_new:folder");
|
||||
updatePlacesCommand("placesCmd_new:bookmark");
|
||||
|
@ -877,16 +877,21 @@ var gEditItemOverlay = {
|
||||
switch (aEvent.type) {
|
||||
case "CheckboxStateChange":
|
||||
// Update the tags field when items are checked/unchecked in the listbox
|
||||
var tags = this._getTagsArrayFromTagField();
|
||||
let tags = this._getTagsArrayFromTagField();
|
||||
let tagCheckbox = aEvent.target;
|
||||
|
||||
if (aEvent.target.checked) {
|
||||
if (tags.indexOf(aEvent.target.label) == -1)
|
||||
tags.push(aEvent.target.label);
|
||||
let curTagIndex = tags.indexOf(tagCheckbox.label);
|
||||
|
||||
let tagsSelector = this._element("tagsSelector");
|
||||
tagsSelector.selectedItem = tagCheckbox;
|
||||
|
||||
if (tagCheckbox.checked) {
|
||||
if (curTagIndex == -1)
|
||||
tags.push(tagCheckbox.label);
|
||||
}
|
||||
else {
|
||||
var indexOfItem = tags.indexOf(aEvent.target.label);
|
||||
if (indexOfItem != -1)
|
||||
tags.splice(indexOfItem, 1);
|
||||
if (curTagIndex != -1)
|
||||
tags.splice(curTagIndex, 1);
|
||||
}
|
||||
this._element("tagsField").value = tags.join(", ");
|
||||
this._updateTags();
|
||||
|
@ -54,6 +54,8 @@
|
||||
oncommand="goDoPlacesCommand('placesCmd_open');"/>
|
||||
<command id="placesCmd_open:window"
|
||||
oncommand="goDoPlacesCommand('placesCmd_open:window');"/>
|
||||
<command id="placesCmd_open:privatewindow"
|
||||
oncommand="goDoPlacesCommand('placesCmd_open:privatewindow');"/>
|
||||
<command id="placesCmd_open:tab"
|
||||
oncommand="goDoPlacesCommand('placesCmd_open:tab');"/>
|
||||
|
||||
@ -129,6 +131,13 @@
|
||||
accesskey="&cmd.open_window.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="link"/>
|
||||
<menuitem id="placesContext_open:newprivatewindow"
|
||||
command="placesCmd_open:privatewindow"
|
||||
label="&cmd.open_private_window.label;"
|
||||
accesskey="&cmd.open_private_window.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="link"
|
||||
hideifprivatebrowsing="true"/>
|
||||
<menuseparator id="placesContext_openSeparator"/>
|
||||
<menuitem id="placesContext_new:bookmark"
|
||||
command="placesCmd_new:bookmark"
|
||||
|
@ -10,11 +10,6 @@ BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'BrowserPlaces.manifest',
|
||||
'PlacesProtocolHandler.js',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'PlacesUIUtils.jsm',
|
||||
]
|
||||
|
@ -24,6 +24,12 @@ var gSearchPane = {
|
||||
document.getElementById("engineList").view = gEngineView;
|
||||
this.buildDefaultEngineDropDown();
|
||||
|
||||
window.addEventListener("click", this, false);
|
||||
window.addEventListener("command", this, false);
|
||||
window.addEventListener("dragstart", this, false);
|
||||
window.addEventListener("keypress", this, false);
|
||||
window.addEventListener("select", this, false);
|
||||
|
||||
Services.obs.addObserver(this, "browser-search-engine-modified", false);
|
||||
window.addEventListener("unload", () => {
|
||||
Services.obs.removeObserver(this, "browser-search-engine-modified", false);
|
||||
@ -63,6 +69,49 @@ var gSearchPane = {
|
||||
});
|
||||
},
|
||||
|
||||
handleEvent: function(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "click":
|
||||
if (aEvent.target.id == "addEngines" && aEvent.button == 0) {
|
||||
Services.wm.getMostRecentWindow('navigator:browser')
|
||||
.BrowserSearch.loadAddEngines();
|
||||
}
|
||||
break;
|
||||
case "command":
|
||||
switch (aEvent.target.id) {
|
||||
case "":
|
||||
if (aEvent.target.parentNode &&
|
||||
aEvent.target.parentNode.parentNode &&
|
||||
aEvent.target.parentNode.parentNode.id == "defaultEngine") {
|
||||
gSearchPane.setDefaultEngine();
|
||||
}
|
||||
break;
|
||||
case "restoreDefaultSearchEngines":
|
||||
gSearchPane.onRestoreDefaults();
|
||||
break;
|
||||
case "removeEngineButton":
|
||||
gSearchPane.remove();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "dragstart":
|
||||
if (aEvent.target.id == "engineChildren") {
|
||||
onDragEngineStart(aEvent);
|
||||
}
|
||||
break;
|
||||
case "keypress":
|
||||
if (aEvent.target.id == "engineList") {
|
||||
gSearchPane.onTreeKeyPress(aEvent);
|
||||
}
|
||||
break;
|
||||
case "select":
|
||||
if (aEvent.target.id == "engineList") {
|
||||
gSearchPane.onTreeSelect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function(aEngine, aTopic, aVerb) {
|
||||
if (aTopic == "browser-search-engine-modified") {
|
||||
aEngine.QueryInterface(Components.interfaces.nsISearchEngine);
|
||||
|
@ -28,7 +28,7 @@
|
||||
<groupbox id="defaultEngineGroup" align="start" data-category="paneSearch">
|
||||
<caption label="&defaultSearchEngine.label;"/>
|
||||
<label>&chooseYourDefaultSearchEngine.label;</label>
|
||||
<menulist id="defaultEngine" oncommand="gSearchPane.setDefaultEngine();">
|
||||
<menulist id="defaultEngine">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
<checkbox id="suggestionsInSearchFieldsCheckbox"
|
||||
@ -42,12 +42,10 @@
|
||||
<label>&chooseWhichOneToDisplay.label;</label>
|
||||
|
||||
<tree id="engineList" flex="1" rows="8" hidecolumnpicker="true" editable="true"
|
||||
seltype="single" onselect="gSearchPane.onTreeSelect();"
|
||||
onkeypress="gSearchPane.onTreeKeyPress(event);">
|
||||
<treechildren id="engineChildren" flex="1"
|
||||
ondragstart="onDragEngineStart(event);"/>
|
||||
seltype="single">
|
||||
<treechildren id="engineChildren" flex="1"/>
|
||||
<treecols>
|
||||
<treecol id="engineShown" type="checkbox" style="min-width: 26px;" editable="true"/>
|
||||
<treecol id="engineShown" type="checkbox" editable="true"/>
|
||||
<treecol id="engineName" flex="4" label="&engineNameColumn.label;"/>
|
||||
<treecol id="engineKeyword" flex="1" label="&engineKeywordColumn.label;" editable="true"/>
|
||||
</treecols>
|
||||
@ -57,19 +55,18 @@
|
||||
<button id="restoreDefaultSearchEngines"
|
||||
label="&restoreDefaultSearchEngines.label;"
|
||||
accesskey="&restoreDefaultSearchEngines.accesskey;"
|
||||
oncommand="gSearchPane.onRestoreDefaults();"/>
|
||||
/>
|
||||
<spacer flex="1"/>
|
||||
<button id="removeEngineButton"
|
||||
label="&removeEngine.label;"
|
||||
accesskey="&removeEngine.accesskey;"
|
||||
disabled="true"
|
||||
oncommand="gSearchPane.remove();"/>
|
||||
/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox pack="start" style="margin-bottom: 1em">
|
||||
<label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"
|
||||
onclick="if (event.button == 0) { Services.wm.getMostRecentWindow('navigator:browser').BrowserSearch.loadAddEngines(); }"/>
|
||||
<hbox id="addEnginesBox" pack="start">
|
||||
<label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
@ -10,11 +10,14 @@ const SAMPLE_SIZE = 50; // no of lines
|
||||
const INDENT_COUNT_THRESHOLD = 5; // percentage
|
||||
const CHARACTER_LIMIT = 250; // line character limit
|
||||
|
||||
// Maps known URLs to friendly source group names
|
||||
// Maps known URLs to friendly source group names and put them at the
|
||||
// bottom of source list.
|
||||
const KNOWN_SOURCE_GROUPS = {
|
||||
"Add-on SDK": "resource://gre/modules/commonjs/",
|
||||
};
|
||||
|
||||
KNOWN_SOURCE_GROUPS[L10N.getStr("evalGroupLabel")] = "eval";
|
||||
|
||||
/**
|
||||
* Functions handling the sources UI.
|
||||
*/
|
||||
@ -170,14 +173,22 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
let fullUrl = aSource.url || aSource.introductionUrl;
|
||||
let url = fullUrl.split(" -> ").pop();
|
||||
let label = aSource.addonPath ? aSource.addonPath : SourceUtils.getSourceLabel(url);
|
||||
let group;
|
||||
|
||||
if (!aSource.url && aSource.introductionUrl) {
|
||||
label += ' > eval';
|
||||
label += ' > ' + aSource.introductionType;
|
||||
group = L10N.getStr("evalGroupLabel");
|
||||
}
|
||||
else if(aSource.addonID) {
|
||||
group = aSource.addonID;
|
||||
}
|
||||
else {
|
||||
group = SourceUtils.getSourceGroup(url);
|
||||
}
|
||||
|
||||
return {
|
||||
label: label,
|
||||
group: aSource.addonID ? aSource.addonID : SourceUtils.getSourceGroup(url),
|
||||
group: group,
|
||||
unicodeUrl: NetworkHelper.convertToUnicode(unescape(fullUrl))
|
||||
};
|
||||
},
|
||||
|
@ -28,6 +28,11 @@ function test() {
|
||||
|
||||
is(gSources.values.length, 2, "Should have 2 sources");
|
||||
|
||||
let item = gSources.getItemForAttachment(e => e.label.indexOf("> eval") !== -1);
|
||||
ok(item, "Source label is incorrect.");
|
||||
is(item.attachment.group, gDebugger.L10N.getStr('evalGroupLabel'),
|
||||
'Source group is incorrect');
|
||||
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
|
@ -32,7 +32,8 @@ function test() {
|
||||
|
||||
let item = gSources.getItemForAttachment(e => e.label == "bar.js");
|
||||
ok(item, "Source label is incorrect.");
|
||||
ok(item.attachment.group === 'http://example.com', 'Source group is incorrect');
|
||||
is(item.attachment.group, 'http://example.com',
|
||||
'Source group is incorrect');
|
||||
|
||||
let shown = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedItem = item;
|
||||
|
@ -51,6 +51,7 @@ function setPrefDefaults() {
|
||||
Services.prefs.setBoolPref("devtools.inspector.showUserAgentStyles", true);
|
||||
Services.prefs.setBoolPref("devtools.profiler.ui.show-platform-data", true);
|
||||
Services.prefs.setBoolPref("browser.devedition.theme.showCustomizeButton", false);
|
||||
Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true);
|
||||
}
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
|
@ -1503,7 +1503,9 @@ Toolbox.prototype = {
|
||||
if (!this._initInspector) {
|
||||
this._initInspector = Task.spawn(function*() {
|
||||
this._inspector = InspectorFront(this._target.client, this._target.form);
|
||||
this._walker = yield this._inspector.getWalker();
|
||||
this._walker = yield this._inspector.getWalker(
|
||||
{showAllAnonymousContent: Services.prefs.getBoolPref("devtools.inspector.showAllAnonymousContent")}
|
||||
);
|
||||
this._selection = new Selection(this._walker);
|
||||
|
||||
if (this.highlighterUtils.isRemoteHighlightable()) {
|
||||
|
@ -34,6 +34,7 @@ support-files =
|
||||
[browser_markupview_anonymous_02.js]
|
||||
skip-if = e10s # scratchpad.xul is not loading in e10s window
|
||||
[browser_markupview_anonymous_03.js]
|
||||
[browser_markupview_anonymous_04.js]
|
||||
[browser_markupview_copy_image_data.js]
|
||||
[browser_markupview_css_completion_style_attribute.js]
|
||||
[browser_markupview_events.js]
|
||||
|
@ -27,4 +27,18 @@ add_task(function*() {
|
||||
info ("Checking the ::after pseudo element");
|
||||
let after = children.nodes[2];
|
||||
yield isEditingMenuDisabled(after, inspector);
|
||||
|
||||
let native = yield getNodeFront("#native", inspector);
|
||||
|
||||
// Markup looks like: <div><video controls /></div>
|
||||
let nativeChildren = yield inspector.walker.children(native);
|
||||
is (nativeChildren.nodes.length, 1, "Children returned from walker");
|
||||
|
||||
info ("Checking the video element");
|
||||
let video = nativeChildren.nodes[0];
|
||||
ok (!video.isAnonymous, "<video> is not anonymous");
|
||||
|
||||
let videoChildren = yield inspector.walker.children(video);
|
||||
is (videoChildren.nodes.length, 0,
|
||||
"No native children returned from walker for <video> by default");
|
||||
});
|
||||
|
@ -0,0 +1,36 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test native anonymous content in the markupview with devtools.inspector.showAllAnonymousContent
|
||||
// set to true
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_markup_anonymous.html";
|
||||
|
||||
add_task(function*() {
|
||||
Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true);
|
||||
|
||||
let {inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
let native = yield getNodeFront("#native", inspector);
|
||||
|
||||
// Markup looks like: <div><video controls /></div>
|
||||
let nativeChildren = yield inspector.walker.children(native);
|
||||
is (nativeChildren.nodes.length, 1, "Children returned from walker");
|
||||
|
||||
info ("Checking the video element");
|
||||
let video = nativeChildren.nodes[0];
|
||||
ok (!video.isAnonymous, "<video> is not anonymous");
|
||||
|
||||
let videoChildren = yield inspector.walker.children(video);
|
||||
is (videoChildren.nodes.length, 3, "<video> has native anonymous children");
|
||||
|
||||
for (let node of videoChildren.nodes) {
|
||||
ok (node.isAnonymous, "Child is anonymous");
|
||||
ok (!node._form.isXBLAnonymous, "Child is not XBL anonymous");
|
||||
ok (!node._form.isShadowAnonymous, "Child is not shadow anonymous");
|
||||
ok (node._form.isNativeAnonymous, "Child is native anonymous");
|
||||
yield isEditingMenuDisabled(node, inspector);
|
||||
}
|
||||
});
|
@ -20,6 +20,8 @@
|
||||
|
||||
<div id="shadow">light dom</div>
|
||||
|
||||
<div id="native"><video controls></video></div>
|
||||
|
||||
<script>
|
||||
var host = document.querySelector('#shadow');
|
||||
if (host.createShadowRoot) {
|
||||
|
@ -32,6 +32,7 @@ registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.dump.emit");
|
||||
Services.prefs.clearUserPref("devtools.markup.pagesize");
|
||||
Services.prefs.clearUserPref("dom.webcomponents.enabled");
|
||||
Services.prefs.clearUserPref("devtools.inspector.showAllAnonymousContent");
|
||||
});
|
||||
|
||||
// Auto close the toolbox and close the test tabs when the test ends
|
||||
|
@ -18,7 +18,8 @@ loader.lazyImporter(this, "NetUtil",
|
||||
// It isn't, of course, a definitive verification, but a Good Enough™
|
||||
// approximation before continuing the import. Don't localize this.
|
||||
const PERF_TOOL_SERIALIZER_IDENTIFIER = "Recorded Performance Data";
|
||||
const PERF_TOOL_SERIALIZER_VERSION = 1;
|
||||
const PERF_TOOL_SERIALIZER_LEGACY_VERSION = 1;
|
||||
const PERF_TOOL_SERIALIZER_CURRENT_VERSION = 2;
|
||||
|
||||
/**
|
||||
* Helpers for importing/exporting JSON.
|
||||
@ -51,7 +52,7 @@ let PerformanceIO = {
|
||||
let deferred = promise.defer();
|
||||
|
||||
recordingData.fileType = PERF_TOOL_SERIALIZER_IDENTIFIER;
|
||||
recordingData.version = PERF_TOOL_SERIALIZER_VERSION;
|
||||
recordingData.version = PERF_TOOL_SERIALIZER_CURRENT_VERSION;
|
||||
|
||||
let string = JSON.stringify(recordingData);
|
||||
let inputStream = this.getUnicodeConverter().convertToInputStream(string);
|
||||
@ -88,10 +89,13 @@ let PerformanceIO = {
|
||||
deferred.reject(new Error("Unrecognized recording data file."));
|
||||
return;
|
||||
}
|
||||
if (recordingData.version != PERF_TOOL_SERIALIZER_VERSION) {
|
||||
if (!isValidSerializerVersion(recordingData.version)) {
|
||||
deferred.reject(new Error("Unsupported recording data file version."));
|
||||
return;
|
||||
}
|
||||
if (recordingData.version === PERF_TOOL_SERIALIZER_LEGACY_VERSION) {
|
||||
recordingData = convertLegacyData(recordingData);
|
||||
}
|
||||
deferred.resolve(recordingData);
|
||||
});
|
||||
|
||||
@ -100,3 +104,49 @@ let PerformanceIO = {
|
||||
};
|
||||
|
||||
exports.PerformanceIO = PerformanceIO;
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether or not the passed in `version`
|
||||
* is supported by this serializer.
|
||||
*
|
||||
* @param number version
|
||||
* @return boolean
|
||||
*/
|
||||
function isValidSerializerVersion (version) {
|
||||
return !!~[
|
||||
PERF_TOOL_SERIALIZER_LEGACY_VERSION,
|
||||
PERF_TOOL_SERIALIZER_CURRENT_VERSION
|
||||
].indexOf(version);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes recording data (with version `1`, from the original profiler tool), and
|
||||
* massages the data to be line with the current performance tool's property names
|
||||
* and values.
|
||||
*
|
||||
* @param object legacyData
|
||||
* @return object
|
||||
*/
|
||||
function convertLegacyData (legacyData) {
|
||||
let { profilerData, ticksData, recordingDuration } = legacyData;
|
||||
|
||||
// The `profilerData` stays, and the previously unrecorded fields
|
||||
// just are empty arrays.
|
||||
let data = {
|
||||
markers: [],
|
||||
frames: [],
|
||||
memory: [],
|
||||
ticks: ticksData,
|
||||
profilerData: profilerData,
|
||||
// Data from the original profiler won't contain `interval` fields,
|
||||
// but a recording duration, as well as the current time, which can be used
|
||||
// to infer the interval startTime and endTime.
|
||||
interval: {
|
||||
startTime: profilerData.currentTime - recordingDuration,
|
||||
endTime: profilerData.currentTime
|
||||
}
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -39,3 +39,4 @@ support-files =
|
||||
[browser_perf_recordings-io-01.js]
|
||||
[browser_perf_recordings-io-02.js]
|
||||
[browser_perf_recordings-io-03.js]
|
||||
[browser_perf_recordings-io-04.js]
|
||||
|
@ -0,0 +1,90 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the performance tool can import profiler data from the
|
||||
* original profiler tool.
|
||||
*/
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController } = panel.panelWin;
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
// Get data from the current profiler
|
||||
let data = PerformanceController.getAllData();
|
||||
|
||||
// Create a structure from the data that mimics the old profiler's data.
|
||||
// Different name for `ticks`, different way of storing time,
|
||||
// and no memory, markers data.
|
||||
let oldProfilerData = {
|
||||
recordingDuration: data.interval.endTime - data.interval.startTime,
|
||||
ticksData: data.ticks,
|
||||
profilerData: data.profilerData,
|
||||
fileType: "Recorded Performance Data",
|
||||
version: 1
|
||||
};
|
||||
|
||||
// Save recording as an old profiler data.
|
||||
let file = FileUtils.getFile("TmpD", ["tmpprofile.json"]);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
|
||||
yield asyncCopy(oldProfilerData, file);
|
||||
|
||||
// Import recording.
|
||||
|
||||
let rerendered = waitForWidgetsRendered(panel);
|
||||
let imported = once(PerformanceController, EVENTS.RECORDING_IMPORTED);
|
||||
yield PerformanceController.importRecording("", file);
|
||||
|
||||
yield imported;
|
||||
ok(true, "The original profiler data appears to have been successfully imported.");
|
||||
|
||||
yield rerendered;
|
||||
ok(true, "The imported data was re-rendered.");
|
||||
|
||||
// Verify imported recording.
|
||||
|
||||
let importedData = PerformanceController.getAllData();
|
||||
|
||||
is(importedData.startTime, data.startTime,
|
||||
"The imported legacy data was successfully converted for the current tool (1).");
|
||||
is(importedData.endTime, data.endTime,
|
||||
"The imported legacy data was successfully converted for the current tool (2).");
|
||||
is(importedData.markers.toSource(), [].toSource(),
|
||||
"The imported legacy data was successfully converted for the current tool (3).");
|
||||
is(importedData.memory.toSource(), [].toSource(),
|
||||
"The imported legacy data was successfully converted for the current tool (4).");
|
||||
is(importedData.ticks.toSource(), data.ticks.toSource(),
|
||||
"The imported legacy data was successfully converted for the current tool (5).");
|
||||
is(importedData.profilerData.toSource(), data.profilerData.toSource(),
|
||||
"The imported legacy data was successfully converted for the current tool (6).");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
});
|
||||
|
||||
function getUnicodeConverter() {
|
||||
let className = "@mozilla.org/intl/scriptableunicodeconverter";
|
||||
let converter = Cc[className].createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
return converter;
|
||||
}
|
||||
|
||||
function asyncCopy(data, file) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let string = JSON.stringify(data);
|
||||
let inputStream = getUnicodeConverter().convertToInputStream(string);
|
||||
let outputStream = FileUtils.openSafeFileOutputStream(file);
|
||||
|
||||
NetUtil.asyncCopy(inputStream, outputStream, status => {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
deferred.reject(new Error("Could not save data to file."));
|
||||
}
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
@ -146,6 +146,7 @@ skip-if = buildapp == 'mulet' || e10s # Bug 1042253 - webconsole e10s tests (exp
|
||||
[browser_console_consolejsm_output.js]
|
||||
[browser_console_dead_objects.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_console_copy_entire_message_context_menu.js]
|
||||
[browser_console_error_source_click.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1042253 - webconsole e10s tests
|
||||
[browser_console_filters.js]
|
||||
|
@ -0,0 +1,64 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test copying of the entire console message when right-clicked
|
||||
// with no other text selected. See Bug 1100562.
|
||||
|
||||
function test() {
|
||||
let hud;
|
||||
let outputNode;
|
||||
let contextMenu;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
|
||||
const TEST_FILE = TEST_URI.substr(TEST_URI.lastIndexOf("/"));
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole(tab);
|
||||
outputNode = hud.outputNode;
|
||||
contextMenu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
hud = outputNode = contextMenu = null;
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
content.console.log("bug 1100562");
|
||||
|
||||
let [results] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "bug 1100562",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}]
|
||||
});
|
||||
|
||||
outputNode.focus();
|
||||
let message = [...results.matched][0];
|
||||
message.scrollIntoView();
|
||||
|
||||
yield waitForContextMenu(contextMenu, message, copyFromPopup, testContextMenuCopy);
|
||||
|
||||
function copyFromPopup() {
|
||||
let copyItem = contextMenu.querySelector("#cMenu_copy");
|
||||
copyItem.doCommand();
|
||||
|
||||
let controller = top.document.commandDispatcher.getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||
}
|
||||
|
||||
function testContextMenuCopy() {
|
||||
waitForClipboard((str) => { return message.textContent.trim() == str.trim(); },
|
||||
() => { goDoCommand("cmd_copy") },
|
||||
() => {}, () => {}
|
||||
);
|
||||
}
|
||||
|
||||
yield closeConsole(tab);
|
||||
}
|
||||
}
|
@ -2842,6 +2842,9 @@ WebConsoleFrame.prototype = {
|
||||
* - linkOnly:
|
||||
* An optional flag to copy only URL without timestamp and
|
||||
* other meta-information. Default is false.
|
||||
* - contextmenu:
|
||||
* An optional flag to copy the last clicked item which brought
|
||||
* up the context menu if nothing is selected. Default is false.
|
||||
*/
|
||||
copySelectedItems: function WCF_copySelectedItems(aOptions)
|
||||
{
|
||||
@ -2864,7 +2867,7 @@ WebConsoleFrame.prototype = {
|
||||
strings.push(item.url);
|
||||
}
|
||||
else {
|
||||
strings.push("[" + timestampString + "] " + item.clipboardText);
|
||||
strings.push(item.clipboardText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4783,6 +4786,14 @@ CommandController.prototype = {
|
||||
this.owner.copySelectedItems({ linkOnly: true, contextmenu: true });
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies the last clicked message.
|
||||
*/
|
||||
copyLastClicked: function CommandController_copy()
|
||||
{
|
||||
this.owner.copySelectedItems({ linkOnly: false, contextmenu: true });
|
||||
},
|
||||
|
||||
supportsCommand: function CommandController_supportsCommand(aCommand)
|
||||
{
|
||||
if (!this.owner || !this.owner.output) {
|
||||
@ -4801,6 +4812,12 @@ CommandController.prototype = {
|
||||
this.owner._contextMenuHandler.lastClickedMessage;
|
||||
return selectedItem && "url" in selectedItem;
|
||||
}
|
||||
case "cmd_copy": {
|
||||
// Only copy if we right-clicked the console and there's no selected text.
|
||||
// With text selected, we want to fall back onto the default copy behavior.
|
||||
return this.owner._contextMenuHandler.lastClickedMessage &&
|
||||
!this.owner.output.getSelectedMessages(1)[0];
|
||||
}
|
||||
case "consoleCmd_clearOutput":
|
||||
case "cmd_selectAll":
|
||||
case "cmd_find":
|
||||
@ -4826,6 +4843,9 @@ CommandController.prototype = {
|
||||
case "consoleCmd_clearOutput":
|
||||
this.owner.jsterm.clearOutput(true);
|
||||
break;
|
||||
case "cmd_copy":
|
||||
this.copyLastClicked();
|
||||
break;
|
||||
case "cmd_find":
|
||||
this.owner.filterBox.focus();
|
||||
break;
|
||||
|
@ -47,8 +47,7 @@ function BuildItem(addon, type) {
|
||||
status.textContent = Strings.GetStringFromName("addons_status_" + addon.status);
|
||||
break;
|
||||
case "failure":
|
||||
console.error(arg);
|
||||
window.alert(arg);
|
||||
window.parent.UI.reportError("error_operationFail", arg);
|
||||
break;
|
||||
case "progress":
|
||||
if (arg == -1) {
|
||||
|
@ -237,6 +237,7 @@
|
||||
@RESPATH@/components/dom_gamepad.xpt
|
||||
#endif
|
||||
@RESPATH@/components/dom_payment.xpt
|
||||
@RESPATH@/components/dom_presentation.xpt
|
||||
@RESPATH@/components/downloads.xpt
|
||||
@RESPATH@/components/editor.xpt
|
||||
@RESPATH@/components/embed_base.xpt
|
||||
@ -377,7 +378,6 @@
|
||||
@RESPATH@/browser/components/nsSetDefaultBrowser.js
|
||||
@RESPATH@/browser/components/BrowserDownloads.manifest
|
||||
@RESPATH@/browser/components/DownloadsStartup.js
|
||||
@RESPATH@/browser/components/BrowserPlaces.manifest
|
||||
@RESPATH@/browser/components/devtools-clhandler.manifest
|
||||
@RESPATH@/browser/components/devtools-clhandler.js
|
||||
@RESPATH@/browser/components/webideCli.js
|
||||
@ -452,7 +452,6 @@
|
||||
@RESPATH@/components/UnifiedComplete.manifest
|
||||
@RESPATH@/components/UnifiedComplete.js
|
||||
@RESPATH@/components/nsPlacesExpiration.js
|
||||
@RESPATH@/browser/components/PlacesProtocolHandler.js
|
||||
@RESPATH@/components/PlacesCategoriesStarter.js
|
||||
@RESPATH@/components/ColorAnalyzer.js
|
||||
@RESPATH@/components/PageThumbsProtocol.js
|
||||
@ -542,6 +541,10 @@
|
||||
@RESPATH@/components/htmlMenuBuilder.js
|
||||
@RESPATH@/components/htmlMenuBuilder.manifest
|
||||
|
||||
@RESPATH@/components/RequestSync.manifest
|
||||
@RESPATH@/components/RequestSyncManager.js
|
||||
@RESPATH@/components/RequestSyncScheduler.js
|
||||
|
||||
@RESPATH@/components/PermissionSettings.js
|
||||
@RESPATH@/components/PermissionSettings.manifest
|
||||
@RESPATH@/components/ContactManager.js
|
||||
@ -604,6 +607,9 @@
|
||||
@RESPATH@/components/nsAsyncShutdown.manifest
|
||||
@RESPATH@/components/nsAsyncShutdown.js
|
||||
|
||||
@RESPATH@/components/PresentationDeviceInfoManager.manifest
|
||||
@RESPATH@/components/PresentationDeviceInfoManager.js
|
||||
|
||||
; InputMethod API
|
||||
@RESPATH@/components/MozKeyboard.js
|
||||
@RESPATH@/components/InputMethod.manifest
|
||||
|
@ -315,3 +315,5 @@ functionSearchSeparatorLabel=←
|
||||
# The substitution parameter is the URL of the last paused window that must be
|
||||
# resumed first.
|
||||
resumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S
|
||||
|
||||
evalGroupLabel=Evaluated Sources
|
@ -271,12 +271,12 @@ powered_by_beforeLogo=Powered by
|
||||
powered_by_afterLogo=
|
||||
|
||||
feedback_call_experience_heading2=How was your conversation?
|
||||
feedback_what_makes_you_sad=What makes you sad?
|
||||
feedback_thank_you_heading=Thank you for your feedback!
|
||||
feedback_category_list_heading=What made you sad?
|
||||
feedback_category_audio_quality=Audio quality
|
||||
feedback_category_video_quality=Video quality
|
||||
feedback_category_was_disconnected=Was disconnected
|
||||
feedback_category_confusing=Confusing
|
||||
feedback_category_confusing2=Confusing controls
|
||||
feedback_category_other2=Other
|
||||
feedback_custom_category_text_placeholder=What went wrong?
|
||||
feedback_submit_button=Submit
|
||||
|
@ -52,6 +52,8 @@
|
||||
<!ENTITY cmd.open.accesskey "O">
|
||||
<!ENTITY cmd.open_window.label "Open in a New Window">
|
||||
<!ENTITY cmd.open_window.accesskey "N">
|
||||
<!ENTITY cmd.open_private_window.label "Open in a New Private Window">
|
||||
<!ENTITY cmd.open_private_window.accesskey "P">
|
||||
<!ENTITY cmd.open_tab.label "Open in a New Tab">
|
||||
<!ENTITY cmd.open_tab.accesskey "w">
|
||||
<!ENTITY cmd.open_all_in_tabs.label "Open All in Tabs">
|
||||
|
@ -19,9 +19,9 @@
|
||||
</DL><p>
|
||||
<DT><H3 ID="rdf:#$ZvPhC3">@firefox_heading@</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$22iCK1">@firefox_help@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$32iCK1">@firefox_customize@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/contribute/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$42iCK1">@firefox_community@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">@firefox_about@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$22iCK1">@firefox_help@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$32iCK1">@firefox_customize@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/contribute/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$42iCK1">@firefox_community@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$52iCK1">@firefox_about@</A>
|
||||
</DL><p>
|
||||
</DL><p>
|
||||
|
@ -533,6 +533,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
|
||||
list-style-image: url("moz-icon://stock/gtk-info?size=menu");
|
||||
}
|
||||
|
||||
#placesContext_open\:newprivatewindow,
|
||||
#privateBrowsingItem {
|
||||
list-style-image: url("chrome://browser/skin/Privacy-16.png");
|
||||
}
|
||||
@ -1777,7 +1778,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
#TabsToolbar {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
margin-bottom: -@tabToolbarNavbarOverlap@;
|
||||
margin-bottom: calc(-1 * var(--tab-toolbar-navbar-overlap));
|
||||
}
|
||||
|
||||
#TabsToolbar:not(:-moz-lwtheme) {
|
||||
@ -1852,7 +1853,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down {
|
||||
-moz-appearance: none;
|
||||
list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
|
||||
margin: 0 0 @tabToolbarNavbarOverlap@;
|
||||
margin: 0 0 var(--tab-toolbar-navbar-overlap);
|
||||
}
|
||||
|
||||
#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
@ -1880,7 +1881,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
}
|
||||
|
||||
#TabsToolbar .toolbarbutton-1 {
|
||||
margin-bottom: @tabToolbarNavbarOverlap@;
|
||||
margin-bottom: var(--tab-toolbar-navbar-overlap);
|
||||
}
|
||||
|
||||
#alltabs-button {
|
||||
|
@ -200,6 +200,11 @@ menuitem[command="placesCmd_open:window"] {
|
||||
-moz-image-region: rect(0px 80px 16px 64px);
|
||||
}
|
||||
|
||||
#placesContext_open\:newprivatewindow,
|
||||
menuitem[command="placesCmd_open:privatewindow"] {
|
||||
list-style-image: url("chrome://browser/skin/Privacy-16.png");
|
||||
}
|
||||
|
||||
#placesContext_open\:newtab,
|
||||
menuitem[command="placesCmd_open:tab"] {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
|
||||
|
@ -117,7 +117,7 @@
|
||||
* tabstrip can overlap it.
|
||||
*/
|
||||
#main-window[tabsintitlebar] > #titlebar {
|
||||
min-height: calc(@tabMinHeight@ + var(--space-above-tabbar) - @tabToolbarNavbarOverlap@);
|
||||
min-height: calc(var(--tab-min-height) + var(--space-above-tabbar) - var(--tab-toolbar-navbar-overlap));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,7 +191,7 @@ toolbarseparator {
|
||||
#TabsToolbar:not([collapsed="true"]) + #nav-bar:-moz-lwtheme {
|
||||
border-top: 1px solid hsla(0,0%,0%,.3);
|
||||
background-clip: padding-box;
|
||||
margin-top: -@tabToolbarNavbarOverlap@;
|
||||
margin-top: calc(-1 * var(--tab-toolbar-navbar-overlap));
|
||||
/* Position the toolbar above the bottom of background tabs */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@ -203,7 +203,7 @@ toolbarseparator {
|
||||
#main-window[tabsintitlebar] #TabsToolbar:not([collapsed="true"]) + #nav-bar:not(:-moz-lwtheme) {
|
||||
border-top: 1px solid hsla(0,0%,0%,.2);
|
||||
background-clip: padding-box;
|
||||
margin-top: -@tabToolbarNavbarOverlap@;
|
||||
margin-top: calc(-1 * var(--tab-toolbar-navbar-overlap));
|
||||
/* Position the toolbar above the bottom of background tabs */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@ -3184,7 +3184,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down {
|
||||
-moz-image-region: rect(0, 13px, 20px, 0);
|
||||
margin: 0 0 @tabToolbarNavbarOverlap@;
|
||||
margin: 0 0 var(--tab-toolbar-navbar-overlap);
|
||||
padding: 0 4px;
|
||||
border: none;
|
||||
}
|
||||
@ -3310,7 +3310,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
}
|
||||
|
||||
#TabsToolbar .toolbarbutton-1 {
|
||||
margin-bottom: @tabToolbarNavbarOverlap@;
|
||||
margin-bottom: var(--tab-toolbar-navbar-overlap);
|
||||
}
|
||||
|
||||
#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
|
||||
@ -4729,7 +4729,7 @@ window > chatbox {
|
||||
|
||||
@media (-moz-mac-lion-theme) {
|
||||
#TabsToolbar > .private-browsing-indicator {
|
||||
transform: translateY(calc(0px - var(--space-above-tabbar)));
|
||||
transform: translateY(calc(-1 * var(--space-above-tabbar)));
|
||||
/* We offset by 38px for mask graphic, plus 4px to account for the
|
||||
* margin-left, which sums to 42px.
|
||||
*/
|
||||
|
@ -11,5 +11,3 @@
|
||||
%endif
|
||||
|
||||
%define inAnyPanel :-moz-any(:not([cui-areatype="toolbar"]), [overflowedItem=true])
|
||||
%define tabToolbarNavbarOverlap 1px
|
||||
%define tabMinHeight 31px
|
||||
|
@ -27,16 +27,16 @@
|
||||
<rect x="7px" y="11px" width="9px" height="2.5px" rx="1" ry="1"/>
|
||||
</g>
|
||||
<g id="details-call-tree">
|
||||
<rect x="0px" y="3px" width="16px" height="2px"/>
|
||||
<rect x="3px" y="6px" width="7px" height="2px"/>
|
||||
<rect x="6px" y="9px" width="6px" height="2px"/>
|
||||
<rect x="9px" y="12px" width="5px" height="2px"/>
|
||||
<rect x="0px" y="3px" width="16px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="3px" y="6px" width="7px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="6px" y="9px" width="6px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="9px" y="12px" width="5px" height="2px" rx="1" ry="1"/>
|
||||
</g>
|
||||
<g id="details-flamegraph">
|
||||
<rect x="0px" y="3px" width="16px" height="2px"/>
|
||||
<rect x="0px" y="6px" width="8px" height="2px"/>
|
||||
<rect x="10px" y="6px" width="6px" height="2px"/>
|
||||
<rect x="2px" y="9px" width="6px" height="2px"/>
|
||||
<rect x="5px" y="12px" width="3px" height="2px"/>
|
||||
<rect x="0px" y="3px" width="16px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="0px" y="6px" width="8px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="10px" y="6px" width="6px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="2px" y="9px" width="6px" height="2px" rx="1" ry="1"/>
|
||||
<rect x="5px" y="12px" width="3px" height="2px" rx="1" ry="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
@ -43,3 +43,11 @@
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
#engineShown {
|
||||
min-width: 26px;
|
||||
}
|
||||
|
||||
#addEnginesBox {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
@ -4,6 +4,11 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
%endif
|
||||
|
||||
:root {
|
||||
--tab-toolbar-navbar-overlap: 1px;
|
||||
--tab-min-height: 31px;
|
||||
}
|
||||
|
||||
%define tabCurveWidth 30px
|
||||
%define tabCurveHalfWidth 15px
|
||||
|
||||
@ -20,7 +25,7 @@
|
||||
}
|
||||
|
||||
#tabbrowser-tabs {
|
||||
min-height: @tabMinHeight@;
|
||||
min-height: var(--tab-min-height);
|
||||
}
|
||||
|
||||
.tabbrowser-tab,
|
||||
@ -118,7 +123,7 @@
|
||||
background-image: url(chrome://browser/skin/tabbrowser/tab-overflow-indicator.png);
|
||||
background-size: 100% 100%;
|
||||
width: 14px;
|
||||
margin-bottom: @tabToolbarNavbarOverlap@;
|
||||
margin-bottom: var(--tab-toolbar-navbar-overlap);
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
z-index: 3; /* the selected tab's z-index + 1 */
|
||||
@ -155,7 +160,7 @@
|
||||
.tab-background-end,
|
||||
.tab-background-end[selected=true]::after,
|
||||
.tab-background-end[selected=true]::before {
|
||||
min-height: @tabMinHeight@;
|
||||
min-height: var(--tab-min-height);
|
||||
width: @tabCurveWidth@;
|
||||
}
|
||||
|
||||
@ -295,7 +300,7 @@
|
||||
|
||||
.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) > .tab-stack > .tab-content {
|
||||
background-image: radial-gradient(farthest-corner at center bottom, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 20%, rgba(127,179,255,0.25) 40%, transparent 70%);
|
||||
background-position: center bottom @tabToolbarNavbarOverlap@;
|
||||
background-position: center bottom var(--tab-toolbar-navbar-overlap);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 85% 100%;
|
||||
}
|
||||
@ -308,7 +313,7 @@
|
||||
-moz-margin-start: -1.5px;
|
||||
-moz-margin-end: -1.5px;
|
||||
background-image: url(chrome://browser/skin/tabbrowser/tab-separator.png);
|
||||
background-position: left bottom @tabToolbarNavbarOverlap@;
|
||||
background-position: left bottom var(--tab-toolbar-navbar-overlap);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 3px 100%;
|
||||
content: "";
|
||||
|
@ -887,7 +887,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
|
||||
}
|
||||
|
||||
#TabsToolbar .toolbarbutton-1 {
|
||||
margin-bottom: @tabToolbarNavbarOverlap@;
|
||||
margin-bottom: var(--tab-toolbar-navbar-overlap);
|
||||
}
|
||||
|
||||
#TabsToolbar .toolbarbutton-1:not([disabled=true]):hover,
|
||||
@ -1786,7 +1786,7 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
||||
#TabsToolbar {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
margin-bottom: -@tabToolbarNavbarOverlap@; /* overlap the nav-bar's top border */
|
||||
margin-bottom: calc(-1 * var(--tab-toolbar-navbar-overlap)); /* overlap the nav-bar's top border */
|
||||
}
|
||||
|
||||
%ifndef WINDOWS_AERO
|
||||
@ -1881,7 +1881,7 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down {
|
||||
list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
|
||||
margin: 0 0 @tabToolbarNavbarOverlap@;
|
||||
margin: 0 0 var(--tab-toolbar-navbar-overlap);
|
||||
}
|
||||
|
||||
#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
|
@ -526,6 +526,12 @@ this.PermissionsTable = { geolocation: {
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"presentation-device-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -129,10 +129,11 @@ AnonymousContent::GetElementById(const nsAString& aElementId)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
AnonymousContent::WrapObject(JSContext* aCx)
|
||||
bool
|
||||
AnonymousContent::WrapObject(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return AnonymousContentBinding::Wrap(aCx, this);
|
||||
return AnonymousContentBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
} // dom namespace
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
explicit AnonymousContent(Element* aContentNode);
|
||||
nsCOMPtr<Element> GetContentNode();
|
||||
void SetContentNode(Element* aContentNode);
|
||||
JSObject* WrapObject(JSContext* aCx);
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
// WebIDL methods
|
||||
void SetTextContentForElement(const nsAString& aElementId,
|
||||
|
@ -23,6 +23,11 @@ namespace dom {
|
||||
|
||||
static const double radPerDegree = 2.0 * M_PI / 360.0;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrixReadOnly, mParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrixReadOnly, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrixReadOnly, Release)
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrixReadOnly::Translate(double aTx,
|
||||
double aTy,
|
||||
@ -303,11 +308,6 @@ DOMMatrixReadOnly::Stringify(nsAString& aResult)
|
||||
aResult = matrixStr;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrix, mParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrix, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrix, Release)
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -40,6 +40,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrixReadOnly)
|
||||
|
||||
#define GetMatrixMember(entry2D, entry3D, default) \
|
||||
{ \
|
||||
if (mMatrix3D) { \
|
||||
@ -130,9 +133,8 @@ protected:
|
||||
nsAutoPtr<gfx::Matrix> mMatrix2D;
|
||||
nsAutoPtr<gfx::Matrix4x4> mMatrix3D;
|
||||
|
||||
~DOMMatrixReadOnly()
|
||||
{
|
||||
}
|
||||
virtual ~DOMMatrixReadOnly() {}
|
||||
|
||||
private:
|
||||
DOMMatrixReadOnly() = delete;
|
||||
DOMMatrixReadOnly(const DOMMatrixReadOnly&) = delete;
|
||||
@ -150,9 +152,6 @@ public:
|
||||
: DOMMatrixReadOnly(aParent, other)
|
||||
{}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrix)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrix)
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
@ -246,8 +245,6 @@ public:
|
||||
DOMMatrix* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
|
||||
private:
|
||||
void Ensure3DMatrix();
|
||||
|
||||
~DOMMatrix() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,10 +12,10 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPoint, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPointReadOnly, mParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPoint, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPoint, Release)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPointReadOnly, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPointReadOnly, Release)
|
||||
|
||||
already_AddRefed<DOMPoint>
|
||||
DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
|
||||
|
@ -33,29 +33,29 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPointReadOnly)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPointReadOnly)
|
||||
|
||||
double X() const { return mX; }
|
||||
double Y() const { return mY; }
|
||||
double Z() const { return mZ; }
|
||||
double W() const { return mW; }
|
||||
|
||||
protected:
|
||||
virtual ~DOMPointReadOnly() {}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
double mX, mY, mZ, mW;
|
||||
};
|
||||
|
||||
class DOMPoint MOZ_FINAL : public DOMPointReadOnly
|
||||
{
|
||||
~DOMPoint() {}
|
||||
|
||||
public:
|
||||
explicit DOMPoint(nsISupports* aParent, double aX = 0.0, double aY = 0.0,
|
||||
double aZ = 0.0, double aW = 1.0)
|
||||
: DOMPointReadOnly(aParent, aX, aY, aZ, aW)
|
||||
{}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPoint)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPoint)
|
||||
|
||||
static already_AddRefed<DOMPoint>
|
||||
Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
|
||||
ErrorResult& aRV);
|
||||
|
@ -1847,6 +1847,33 @@ Navigator::MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv)
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::MozSetMessageHandlerPromise(Promise& aPromise,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// The WebIDL binding is responsible for the pref check here.
|
||||
aRv = EnsureMessagesManager();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
aRv = mMessagesManager->MozIsHandlingMessage(&result);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
aRv = mMessagesManager->MozSetMessageHandlerPromise(&aPromise);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::MozSetMessageHandler(const nsAString& aType,
|
||||
systemMessageCallback* aCallback,
|
||||
|
@ -235,6 +235,8 @@ public:
|
||||
systemMessageCallback* aCallback,
|
||||
ErrorResult& aRv);
|
||||
bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
|
||||
void MozSetMessageHandlerPromise(Promise& aPromise, ErrorResult& aRv);
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
already_AddRefed<Promise> GetMobileIdAssertion(const MobileIdOptions& options,
|
||||
ErrorResult& aRv);
|
||||
|
@ -288,10 +288,10 @@ void NodeIterator::ContentRemoved(nsIDocument *aDocument,
|
||||
mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
NodeIterator::WrapObject(JSContext *cx)
|
||||
bool
|
||||
NodeIterator::WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return NodeIteratorBinding::Wrap(cx, this);
|
||||
return NodeIteratorBinding::Wrap(cx, this, aReflector);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
}
|
||||
// The XPCOM Detach() is fine for our purposes
|
||||
|
||||
JSObject* WrapObject(JSContext *cx);
|
||||
bool WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
private:
|
||||
virtual ~NodeIterator();
|
||||
|
@ -450,10 +450,10 @@ TreeWalker::NextSiblingInternal(bool aReversed, ErrorResult& aResult)
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
TreeWalker::WrapObject(JSContext *cx)
|
||||
bool
|
||||
TreeWalker::WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return TreeWalkerBinding::Wrap(cx, this);
|
||||
return TreeWalkerBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult);
|
||||
already_AddRefed<nsINode> NextNode(ErrorResult& aResult);
|
||||
|
||||
JSObject* WrapObject(JSContext *cx);
|
||||
bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsINode> mCurrentNode;
|
||||
|
@ -46,10 +46,10 @@ URL::URL(nsIURI* aURI)
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
URL::WrapObject(JSContext* aCx)
|
||||
bool
|
||||
URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return URLBinding::Wrap(aCx, this);
|
||||
return URLBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<URL>
|
||||
|
@ -43,8 +43,8 @@ public:
|
||||
explicit URL(nsIURI* aURI);
|
||||
|
||||
// WebIDL methods
|
||||
JSObject*
|
||||
WrapObject(JSContext* aCx);
|
||||
bool
|
||||
WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
static already_AddRefed<URL>
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
|
@ -646,13 +646,14 @@ WebSocketImpl::DoOnMessageAvailable(const nsACString& aMsg, bool isBinary)
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the message event");
|
||||
}
|
||||
} else {
|
||||
// CLOSING should be the only other state where it's possible to get msgs
|
||||
// from channel: Spec says to drop them.
|
||||
MOZ_ASSERT(readyState == WebSocket::CLOSING,
|
||||
"Received message while CONNECTING or CLOSED");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// CLOSING should be the only other state where it's possible to get msgs
|
||||
// from channel: Spec says to drop them.
|
||||
MOZ_ASSERT(readyState == WebSocket::CLOSING,
|
||||
"Received message while CONNECTING or CLOSED");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -718,14 +719,17 @@ WebSocketImpl::OnStart(nsISupports* aContext)
|
||||
|
||||
mWebSocket->SetReadyState(WebSocket::OPEN);
|
||||
|
||||
// Let's keep the object alive because the webSocket can be CCed in the
|
||||
// onopen callback.
|
||||
nsRefPtr<WebSocket> webSocket = mWebSocket;
|
||||
|
||||
// Call 'onopen'
|
||||
rv = mWebSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
|
||||
rv = webSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the open event");
|
||||
}
|
||||
|
||||
mWebSocket->UpdateMustKeepAlive();
|
||||
|
||||
webSocket->UpdateMustKeepAlive();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1596,23 +1600,27 @@ WebSocketImpl::DispatchConnectionCloseEvents()
|
||||
|
||||
mWebSocket->SetReadyState(WebSocket::CLOSED);
|
||||
|
||||
// Let's keep the object alive because the webSocket can be CCed in the
|
||||
// onerror or in the onclose callback.
|
||||
nsRefPtr<WebSocket> webSocket = mWebSocket;
|
||||
|
||||
// Call 'onerror' if needed
|
||||
if (mFailed) {
|
||||
nsresult rv =
|
||||
mWebSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
|
||||
webSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the error event");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = mWebSocket->CreateAndDispatchCloseEvent(mCloseEventWasClean,
|
||||
mCloseEventCode,
|
||||
mCloseEventReason);
|
||||
nsresult rv = webSocket->CreateAndDispatchCloseEvent(mCloseEventWasClean,
|
||||
mCloseEventCode,
|
||||
mCloseEventReason);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the close event");
|
||||
}
|
||||
|
||||
mWebSocket->UpdateMustKeepAlive();
|
||||
webSocket->UpdateMustKeepAlive();
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
|
@ -5300,8 +5300,8 @@ nsIDocument::RemoveAnonymousContent(AnonymousContent& aContent,
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over know customContents to get and remove the right one
|
||||
for (int32_t i = mAnonymousContents.Length() - 1; i >= 0; --i) {
|
||||
// Iterate over mAnonymousContents to find and remove the given node.
|
||||
for (size_t i = 0, len = mAnonymousContents.Length(); i < len; ++i) {
|
||||
if (mAnonymousContents[i] == &aContent) {
|
||||
// Get the node from the customContent
|
||||
nsCOMPtr<Element> node = aContent.GetContentNode();
|
||||
|
@ -2305,7 +2305,7 @@ nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
|
||||
bool
|
||||
nsFrameLoader::DoLoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
|
||||
{
|
||||
auto* tabParent = static_cast<TabParent*>(GetRemoteBrowser());
|
||||
mozilla::dom::PBrowserParent* tabParent = GetRemoteBrowser();
|
||||
if (tabParent) {
|
||||
return tabParent->SendLoadRemoteScript(nsString(aURL), aRunInGlobalScope);
|
||||
}
|
||||
@ -2421,7 +2421,13 @@ nsFrameLoader::EnsureMessageManager()
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mIsTopLevelContent && !OwnerIsBrowserOrAppFrame() && !mRemoteFrame) {
|
||||
if (!mIsTopLevelContent &&
|
||||
!OwnerIsBrowserOrAppFrame() &&
|
||||
!mRemoteFrame &&
|
||||
!(mOwnerContent->IsXUL() &&
|
||||
mOwnerContent->AttrValueIs(kNameSpaceID_None,
|
||||
nsGkAtoms::forcemessagemanager,
|
||||
nsGkAtoms::_true, eCaseMatters))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2117,6 +2117,7 @@ GK_ATOM(DisplayPort, "_displayport")
|
||||
GK_ATOM(DisplayPortMargins, "_displayportmargins")
|
||||
GK_ATOM(DisplayPortBase, "_displayportbase")
|
||||
GK_ATOM(AsyncScrollLayerCreationFailed, "_asyncscrolllayercreationfailed")
|
||||
GK_ATOM(forcemessagemanager, "forcemessagemanager")
|
||||
|
||||
// Names for system metrics
|
||||
GK_ATOM(color_picker_available, "color-picker-available")
|
||||
|
@ -2299,9 +2299,9 @@ CreateNativeGlobalForInner(JSContext* aCx,
|
||||
uint32_t flags = needComponents ? 0 : nsIXPConnect::OMIT_COMPONENTS_OBJECT;
|
||||
flags |= nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK;
|
||||
|
||||
aGlobal.set(WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
|
||||
nsJSPrincipals::get(aPrincipal), false));
|
||||
if (!aGlobal || !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
|
||||
if (!WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
|
||||
nsJSPrincipals::get(aPrincipal), false, aGlobal) ||
|
||||
!xpc::InitGlobalObject(aCx, aGlobal, flags)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -667,47 +667,70 @@ DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
|
||||
JS::Handle<JSObject*> obj,
|
||||
const NativeProperties* properties);
|
||||
|
||||
#define HAS_MEMBER_TYPEDEFS \
|
||||
private: \
|
||||
typedef char yes[1]; \
|
||||
typedef char no[2]
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define HAS_MEMBER_CHECK(_name) \
|
||||
template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
|
||||
template<typename V> static yes& Check##_name(char (*)[(&V::_name == 0) + 1])
|
||||
#else
|
||||
#define HAS_MEMBER_CHECK(_name) \
|
||||
template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
|
||||
template<typename V> static yes& Check##_name(char (*)[sizeof(&V::_name) + 1])
|
||||
#endif
|
||||
|
||||
#define HAS_MEMBER(_name) \
|
||||
template<typename T> \
|
||||
class Has##_name##Member { \
|
||||
typedef char yes[1]; \
|
||||
typedef char no[2]; \
|
||||
HAS_MEMBER_CHECK(_name); \
|
||||
template<typename V> static no& Check(...); \
|
||||
#define HAS_MEMBER(_memberName, _valueName) \
|
||||
private: \
|
||||
HAS_MEMBER_CHECK(_memberName); \
|
||||
template<typename V> static no& Check##_memberName(...); \
|
||||
\
|
||||
public: \
|
||||
static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes); \
|
||||
static bool const _valueName = \
|
||||
sizeof(Check##_memberName<T>(nullptr)) == sizeof(yes)
|
||||
|
||||
template<class T>
|
||||
struct NativeHasMember
|
||||
{
|
||||
HAS_MEMBER_TYPEDEFS;
|
||||
|
||||
HAS_MEMBER(GetParentObject, GetParentObject);
|
||||
HAS_MEMBER(JSBindingFinalized, JSBindingFinalized);
|
||||
HAS_MEMBER(WrapObject, WrapObject);
|
||||
};
|
||||
|
||||
HAS_MEMBER(WrapObject)
|
||||
|
||||
// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
|
||||
// not nsWrapperCache::WrapObject.
|
||||
template<typename T>
|
||||
struct HasWrapObject
|
||||
template<class T>
|
||||
struct IsSmartPtr
|
||||
{
|
||||
private:
|
||||
typedef char yes[1];
|
||||
typedef char no[2];
|
||||
typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*,
|
||||
JS::Handle<JSObject*>);
|
||||
template<typename U, U> struct SFINAE;
|
||||
template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
|
||||
template <typename V> static yes& Check(...);
|
||||
HAS_MEMBER_TYPEDEFS;
|
||||
|
||||
HAS_MEMBER(get, value);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct IsRefcounted
|
||||
{
|
||||
HAS_MEMBER_TYPEDEFS;
|
||||
|
||||
HAS_MEMBER(AddRef, HasAddref);
|
||||
HAS_MEMBER(Release, HasRelease);
|
||||
|
||||
public:
|
||||
static bool const Value = HasWrapObjectMember<T>::Value &&
|
||||
sizeof(Check<T>(nullptr)) == sizeof(yes);
|
||||
static bool const value = HasAddref && HasRelease;
|
||||
|
||||
private:
|
||||
// This struct only works if T is fully declared (not just forward declared).
|
||||
// The IsBaseOf check will ensure that, we don't really need it for any other
|
||||
// reason (the static assert will of course always be true).
|
||||
static_assert(!IsBaseOf<nsISupports, T>::value || IsRefcounted::value,
|
||||
"Classes derived from nsISupports are refcounted!");
|
||||
|
||||
};
|
||||
|
||||
#undef HAS_MEMBER
|
||||
#undef HAS_MEMBER_CHECK
|
||||
#undef HAS_MEMBER_TYPEDEFS
|
||||
|
||||
#ifdef DEBUG
|
||||
template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
|
||||
struct
|
||||
@ -976,6 +999,7 @@ WrapNewBindingNonWrapperCachedObject(JSContext* cx,
|
||||
T* value,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
static_assert(IsRefcounted<T>::value, "Don't pass owned classes in here.");
|
||||
MOZ_ASSERT(value);
|
||||
// We try to wrap in the compartment of the underlying object of "scope"
|
||||
JS::Rooted<JSObject*> obj(cx);
|
||||
@ -995,11 +1019,9 @@ WrapNewBindingNonWrapperCachedObject(JSContext* cx,
|
||||
}
|
||||
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
|
||||
obj = value->WrapObject(cx);
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
return false;
|
||||
if (!value->WrapObject(cx, &obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We can end up here in all sorts of compartments, per above. Make
|
||||
@ -1014,11 +1036,12 @@ WrapNewBindingNonWrapperCachedObject(JSContext* cx,
|
||||
// is true if the JSObject took ownership
|
||||
template <class T>
|
||||
inline bool
|
||||
WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
|
||||
JS::Handle<JSObject*> scopeArg,
|
||||
nsAutoPtr<T>& value,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
WrapNewBindingNonWrapperCachedObject(JSContext* cx,
|
||||
JS::Handle<JSObject*> scopeArg,
|
||||
nsAutoPtr<T>& value,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
static_assert(!IsRefcounted<T>::value, "Only pass owned classes in here.");
|
||||
// We do a runtime check on value, because otherwise we might in
|
||||
// fact end up wrapping a null and invoking methods on it later.
|
||||
if (!value) {
|
||||
@ -1041,17 +1064,12 @@ WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
|
||||
ac.emplace(cx, scope);
|
||||
}
|
||||
|
||||
bool tookOwnership = false;
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
|
||||
obj = value->WrapObject(cx, &tookOwnership);
|
||||
MOZ_ASSERT_IF(obj, tookOwnership);
|
||||
if (tookOwnership) {
|
||||
value.forget();
|
||||
if (!value->WrapObject(cx, &obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
return false;
|
||||
value.forget();
|
||||
}
|
||||
|
||||
// We can end up here in all sorts of compartments, per above. Make
|
||||
@ -1060,8 +1078,9 @@ WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
|
||||
return JS_WrapValue(cx, rval);
|
||||
}
|
||||
|
||||
// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
|
||||
template <template <typename> class SmartPtr, typename T>
|
||||
// Helper for smart pointers (nsRefPtr/nsCOMPtr).
|
||||
template <template <typename> class SmartPtr, typename T,
|
||||
typename U=typename EnableIf<IsRefcounted<T>::value, T>::Type>
|
||||
inline bool
|
||||
WrapNewBindingNonWrapperCachedObject(JSContext* cx, JS::Handle<JSObject*> scope,
|
||||
const SmartPtr<T>& value,
|
||||
@ -1100,9 +1119,8 @@ HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
|
||||
|
||||
// Helper for calling HandleNewBindingWrappingFailure with smart pointers
|
||||
// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
|
||||
HAS_MEMBER(get)
|
||||
|
||||
template <class T, bool isSmartPtr=HasgetMember<T>::Value>
|
||||
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
|
||||
struct HandleNewBindingWrappingFailureHelper
|
||||
{
|
||||
static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
|
||||
@ -1467,7 +1485,7 @@ struct WrapNativeParentFallback<T, true >
|
||||
|
||||
// Wrapping of our native parent, for cases when it's a WebIDL object (though
|
||||
// possibly preffed off).
|
||||
template<typename T, bool hasWrapObject=HasWrapObject<T>::Value >
|
||||
template<typename T, bool hasWrapObject=NativeHasMember<T>::WrapObject>
|
||||
struct WrapNativeParentHelper
|
||||
{
|
||||
static inline JSObject* Wrap(JSContext* cx, T* parent, nsWrapperCache* cache)
|
||||
@ -1493,7 +1511,7 @@ struct WrapNativeParentHelper
|
||||
// Wrapping of our native parent, for cases when it's not a WebIDL object. In
|
||||
// this case it must be nsISupports.
|
||||
template<typename T>
|
||||
struct WrapNativeParentHelper<T, false >
|
||||
struct WrapNativeParentHelper<T, false>
|
||||
{
|
||||
static inline JSObject* Wrap(JSContext* cx, T* parent, nsWrapperCache* cache)
|
||||
{
|
||||
@ -1551,9 +1569,7 @@ WrapNativeParent(JSContext* cx, const T& p)
|
||||
return WrapNativeParent(cx, GetParentPointer(p), GetWrapperCache(p), GetUseXBLScope(p));
|
||||
}
|
||||
|
||||
HAS_MEMBER(GetParentObject)
|
||||
|
||||
template<typename T, bool WrapperCached=HasGetParentObjectMember<T>::Value>
|
||||
template<typename T, bool WrapperCached=NativeHasMember<T>::GetParentObject>
|
||||
struct GetParentObject
|
||||
{
|
||||
static JSObject* Get(JSContext* cx, JS::Handle<JSObject*> obj)
|
||||
@ -1632,7 +1648,7 @@ WrapCallThisObject<JS::Rooted<JSObject*>>(JSContext* cx,
|
||||
|
||||
// Helper for calling GetOrCreateDOMReflector with smart pointers
|
||||
// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
|
||||
template <class T, bool isSmartPtr=HasgetMember<T>::Value>
|
||||
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
|
||||
struct GetOrCreateDOMReflectorHelper
|
||||
{
|
||||
static inline bool GetOrCreate(JSContext* cx, const T& value,
|
||||
@ -1648,6 +1664,7 @@ struct GetOrCreateDOMReflectorHelper<T, false>
|
||||
static inline bool GetOrCreate(JSContext* cx, T& value,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
static_assert(IsRefcounted<T>::value, "Don't pass owned classes in here.");
|
||||
return GetOrCreateDOMReflector(cx, &value, rval);
|
||||
}
|
||||
};
|
||||
@ -1673,7 +1690,7 @@ GetOrCreateDOMReflector(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
|
||||
|
||||
// Helper for calling GetOrCreateDOMReflectorNoWrap with smart pointers
|
||||
// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
|
||||
template <class T, bool isSmartPtr=HasgetMember<T>::Value>
|
||||
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
|
||||
struct GetOrCreateDOMReflectorNoWrapHelper
|
||||
{
|
||||
static inline bool GetOrCreate(JSContext* cx, const T& value,
|
||||
@ -1712,7 +1729,7 @@ GetCallbackFromCallbackObject(T* aObj)
|
||||
// Helper for getting the callback JSObject* of a smart ptr around a
|
||||
// CallbackObject or a reference to a CallbackObject or something like
|
||||
// that.
|
||||
template <class T, bool isSmartPtr=HasgetMember<T>::Value>
|
||||
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
|
||||
struct GetCallbackFromCallbackObjectHelper
|
||||
{
|
||||
static inline JSObject* Get(const T& aObj)
|
||||
@ -2503,30 +2520,7 @@ HasConstructor(JSObject* obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Transfer reference in ptr to smartPtr.
|
||||
template<class T>
|
||||
inline void
|
||||
Take(nsRefPtr<T>& smartPtr, T* ptr)
|
||||
{
|
||||
smartPtr = dont_AddRef(ptr);
|
||||
}
|
||||
|
||||
// Transfer ownership of ptr to smartPtr.
|
||||
template<class T>
|
||||
inline void
|
||||
Take(nsAutoPtr<T>& smartPtr, T* ptr)
|
||||
{
|
||||
smartPtr = ptr;
|
||||
}
|
||||
|
||||
inline void
|
||||
MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
|
||||
{
|
||||
}
|
||||
|
||||
HAS_MEMBER(JSBindingFinalized)
|
||||
|
||||
template<class T, bool hasCallback=HasJSBindingFinalizedMember<T>::Value>
|
||||
template<class T, bool hasCallback=NativeHasMember<T>::JSBindingFinalized>
|
||||
struct JSBindingFinalized
|
||||
{
|
||||
static void Finalized(T* self)
|
||||
@ -2753,11 +2747,119 @@ ToSupportsIsOnPrimaryInheritanceChain(T* aObject, nsWrapperCache* aCache)
|
||||
aCache);
|
||||
}
|
||||
|
||||
template<class T, template <typename> class SmartPtr,
|
||||
// The BindingJSObjectCreator class is supposed to be used by a caller that
|
||||
// wants to create and initialise a binding JSObject. After initialisation has
|
||||
// been successfully completed it should call ForgetObject().
|
||||
// The BindingJSObjectCreator object will root the JSObject until ForgetObject()
|
||||
// is called on it. If the native object for the binding is refcounted it will
|
||||
// also hold a strong reference to it, that reference is transferred to the
|
||||
// JSObject (which holds the native in a slot) when ForgetObject() is called. If
|
||||
// the BindingJSObjectCreator object is destroyed and ForgetObject() was never
|
||||
// called on it then the JSObject's slot holding the native will be set to
|
||||
// undefined, and for a refcounted native the strong reference will be released.
|
||||
template<class T>
|
||||
class MOZ_STACK_CLASS BindingJSObjectCreator
|
||||
{
|
||||
public:
|
||||
explicit BindingJSObjectCreator(JSContext* aCx)
|
||||
: mReflector(aCx)
|
||||
{
|
||||
}
|
||||
|
||||
~BindingJSObjectCreator()
|
||||
{
|
||||
if (mReflector) {
|
||||
js::SetReservedOrProxyPrivateSlot(mReflector, DOM_OBJECT_SLOT,
|
||||
JS::UndefinedValue());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CreateProxyObject(JSContext* aCx, const js::Class* aClass,
|
||||
const DOMProxyHandler* aHandler,
|
||||
JS::Handle<JSObject*> aProto,
|
||||
JS::Handle<JSObject*> aParent, T* aNative,
|
||||
JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
js::ProxyOptions options;
|
||||
options.setClass(aClass);
|
||||
JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aNative));
|
||||
aReflector.set(js::NewProxyObject(aCx, aHandler, proxyPrivateVal, aProto,
|
||||
aParent, options));
|
||||
if (aReflector) {
|
||||
mNative = aNative;
|
||||
mReflector = aReflector;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CreateObject(JSContext* aCx, const JSClass* aClass,
|
||||
JS::Handle<JSObject*> aProto, JS::Handle<JSObject*> aParent,
|
||||
T* aNative, JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
aReflector.set(JS_NewObject(aCx, aClass, aProto, aParent));
|
||||
if (aReflector) {
|
||||
js::SetReservedSlot(aReflector, DOM_OBJECT_SLOT, JS::PrivateValue(aNative));
|
||||
mNative = aNative;
|
||||
mReflector = aReflector;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InitializationSucceeded()
|
||||
{
|
||||
void* dummy;
|
||||
mNative.forget(&dummy);
|
||||
mReflector = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
struct OwnedNative
|
||||
{
|
||||
// Make sure the native objects inherit from NonRefcountedDOMObject so
|
||||
// that we log their ctor and dtor.
|
||||
static_assert(IsBaseOf<NonRefcountedDOMObject, T>::value,
|
||||
"Non-refcounted objects with DOM bindings should inherit "
|
||||
"from NonRefcountedDOMObject.");
|
||||
|
||||
OwnedNative&
|
||||
operator=(T* aNative)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
// This signature sucks, but it's the only one that will make a nsRefPtr
|
||||
// just forget about its pointer without warning.
|
||||
void
|
||||
forget(void**)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
JS::Rooted<JSObject*> mReflector;
|
||||
typename Conditional<IsRefcounted<T>::value, nsRefPtr<T>, OwnedNative>::Type mNative;
|
||||
};
|
||||
|
||||
template<class T,
|
||||
bool isISupports=IsBaseOf<nsISupports, T>::value>
|
||||
class DeferredFinalizer
|
||||
{
|
||||
typedef nsTArray<SmartPtr<T> > SmartPtrArray;
|
||||
typedef typename Conditional<IsRefcounted<T>::value,
|
||||
nsRefPtr<T>, nsAutoPtr<T>>::Type SmartPtr;
|
||||
typedef nsTArray<SmartPtr> SmartPtrArray;
|
||||
|
||||
template<class U>
|
||||
static inline void
|
||||
AppendAndTake(nsTArray<nsRefPtr<U>>& smartPtrArray, U* ptr)
|
||||
{
|
||||
smartPtrArray.AppendElement(dont_AddRef(ptr));
|
||||
}
|
||||
template<class U>
|
||||
static inline void
|
||||
AppendAndTake(nsTArray<nsAutoPtr<U>>& smartPtrArray, U* ptr)
|
||||
{
|
||||
smartPtrArray.AppendElement(ptr);
|
||||
}
|
||||
|
||||
static void*
|
||||
AppendDeferredFinalizePointer(void* aData, void* aObject)
|
||||
@ -2766,11 +2868,7 @@ class DeferredFinalizer
|
||||
if (!pointers) {
|
||||
pointers = new SmartPtrArray();
|
||||
}
|
||||
|
||||
T* self = static_cast<T*>(aObject);
|
||||
|
||||
SmartPtr<T>* defer = pointers->AppendElement();
|
||||
Take(*defer, self);
|
||||
AppendAndTake(*pointers, static_cast<T*>(aObject));
|
||||
return pointers;
|
||||
}
|
||||
static bool
|
||||
@ -2800,8 +2898,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, template <typename> class SmartPtr>
|
||||
class DeferredFinalizer<T, SmartPtr, true>
|
||||
template<class T>
|
||||
class DeferredFinalizer<T, true>
|
||||
{
|
||||
public:
|
||||
static void
|
||||
@ -2811,11 +2909,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, template <typename> class SmartPtr>
|
||||
template<class T>
|
||||
static void
|
||||
AddForDeferredFinalization(T* aObject)
|
||||
{
|
||||
DeferredFinalizer<T, SmartPtr>::AddForDeferredFinalization(aObject);
|
||||
DeferredFinalizer<T>::AddForDeferredFinalization(aObject);
|
||||
}
|
||||
|
||||
// This returns T's CC participant if it participates in CC or null if it
|
||||
@ -3109,17 +3207,26 @@ StrongOrRawPtr(already_AddRefed<S>&& aPtr)
|
||||
return aPtr.template downcast<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T*
|
||||
template<class T,
|
||||
class ReturnType=typename Conditional<IsRefcounted<T>::value, T*,
|
||||
nsAutoPtr<T>>::Type>
|
||||
inline ReturnType
|
||||
StrongOrRawPtr(T* aPtr)
|
||||
{
|
||||
return aPtr;
|
||||
return ReturnType(aPtr);
|
||||
}
|
||||
|
||||
template<class T, template<typename> class SmartPtr, class S>
|
||||
inline void
|
||||
StrongOrRawPtr(SmartPtr<S>&& aPtr) = delete;
|
||||
|
||||
template<class T>
|
||||
struct StrongPtrForMember
|
||||
{
|
||||
typedef typename Conditional<IsRefcounted<T>::value,
|
||||
nsRefPtr<T>, nsAutoPtr<T>>::Type Type;
|
||||
};
|
||||
|
||||
inline
|
||||
JSObject*
|
||||
GetErrorPrototype(JSContext* aCx, JS::Handle<JSObject*> aForObj)
|
||||
|
@ -44,22 +44,6 @@
|
||||
# Always true for worker descriptors for non-callback
|
||||
# interfaces. Defaults to true for non-worker non-callback
|
||||
# descriptors.
|
||||
# * nativeOwnership: Describes how the native object is held. 3 possible
|
||||
# types: worker object ('worker'), non-refcounted object
|
||||
# ('owned'), refcounted object ('refcounted').
|
||||
# Non-refcounted objects need to inherit from
|
||||
# mozilla::dom::NonRefcountedDOMObject and preferably use
|
||||
# MOZ_COUNT_CTOR/MOZ_COUNT_DTOR in their
|
||||
# constructor/destructor so they participate in leak
|
||||
# logging.
|
||||
# This mostly determines how the finalizer releases the
|
||||
# binding's hold on the native object. For a worker object
|
||||
# it'll call Release, for a non-refcounted object it'll
|
||||
# call delete through XPConnect's deferred finalization
|
||||
# mechanism, for a refcounted object it'll call Release
|
||||
# through XPConnect's deferred finalization mechanism.
|
||||
# 'worker' opts into old style worker models. Defaults to
|
||||
# 'refcounted'.
|
||||
#
|
||||
# The following fields are either a string, an array (defaults to an empty
|
||||
# array) or a dictionary with three possible keys (all, getterOnly and
|
||||
@ -1227,15 +1211,15 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'TextDecoder': {
|
||||
'nativeOwnership': 'owned',
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'TextEncoder': {
|
||||
'nativeOwnership': 'owned',
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'TextMetrics': {
|
||||
'nativeOwnership': 'owned',
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'TimeRanges': {
|
||||
@ -1271,8 +1255,13 @@ DOMInterfaces = {
|
||||
'wrapperCache': False,
|
||||
}],
|
||||
|
||||
'VRFieldOfView': {
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'VRFieldOfViewReadOnly': {
|
||||
'concrete': False
|
||||
'concrete': False,
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'VRDevice': {
|
||||
@ -1589,7 +1578,6 @@ DOMInterfaces = {
|
||||
|
||||
'XPathExpression': {
|
||||
'wrapperCache': False,
|
||||
'nativeOwnership': 'owned',
|
||||
},
|
||||
|
||||
'XSLTProcessor': {
|
||||
|
@ -1565,14 +1565,6 @@ class CGAddPropertyHook(CGAbstractClassHook):
|
||||
""")
|
||||
|
||||
|
||||
def DeferredFinalizeSmartPtr(descriptor):
|
||||
if descriptor.nativeOwnership == 'owned':
|
||||
smartPtr = 'nsAutoPtr'
|
||||
else:
|
||||
smartPtr = 'nsRefPtr'
|
||||
return smartPtr
|
||||
|
||||
|
||||
def finalizeHook(descriptor, hookName, freeOp):
|
||||
finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
|
||||
if descriptor.wrapperCache:
|
||||
@ -1581,8 +1573,8 @@ def finalizeHook(descriptor, hookName, freeOp):
|
||||
finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
|
||||
if descriptor.isGlobal():
|
||||
finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), obj);\n" % freeOp
|
||||
finalize += ("AddForDeferredFinalization<%s, %s >(self);\n" %
|
||||
(descriptor.nativeType, DeferredFinalizeSmartPtr(descriptor)))
|
||||
finalize += ("AddForDeferredFinalization<%s>(self);\n" %
|
||||
descriptor.nativeType)
|
||||
return CGIfWrapper(CGGeneric(finalize), "self")
|
||||
|
||||
|
||||
@ -3065,50 +3057,35 @@ class CGConstructorEnabled(CGAbstractMethod):
|
||||
|
||||
|
||||
def CreateBindingJSObject(descriptor, properties):
|
||||
objDecl = "BindingJSObjectCreator<%s> creator(aCx);\n" % descriptor.nativeType
|
||||
|
||||
# We don't always need to root obj, but there are a variety
|
||||
# of cases where we do, so for simplicity, just always root it.
|
||||
objDecl = "JS::Rooted<JSObject*> obj(aCx);\n"
|
||||
if descriptor.proxy:
|
||||
create = dedent(
|
||||
"""
|
||||
JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aObject));
|
||||
js::ProxyOptions options;
|
||||
options.setClass(&Class.mBase);
|
||||
obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
|
||||
proxyPrivateVal, proto, global, options);
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
creator.CreateProxyObject(aCx, &Class.mBase, DOMProxyHandler::getInstance(),
|
||||
proto, global, aObject, aReflector);
|
||||
if (!aReflector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
""")
|
||||
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
create += dedent("""
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
|
||||
js::SetProxyExtra(aReflector, JSPROXYSLOT_EXPANDO,
|
||||
JS::PrivateValue(&aObject->mExpandoAndGeneration));
|
||||
|
||||
""")
|
||||
else:
|
||||
create = dedent(
|
||||
"""
|
||||
obj = JS_NewObject(aCx, Class.ToJSClass(), proto, global);
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
creator.CreateObject(aCx, Class.ToJSClass(), proto, global, aObject, aReflector);
|
||||
if (!aReflector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
|
||||
""")
|
||||
create = objDecl + create
|
||||
|
||||
if descriptor.nativeOwnership == 'refcounted':
|
||||
create += "NS_ADDREF(aObject);\n"
|
||||
else:
|
||||
create += dedent("""
|
||||
// Make sure the native objects inherit from NonRefcountedDOMObject so that we
|
||||
// log their ctor and dtor.
|
||||
MustInheritFromNonRefcountedDOMObject(aObject);
|
||||
*aTookOwnership = true;
|
||||
""")
|
||||
return create
|
||||
return objDecl + create
|
||||
|
||||
|
||||
def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturnValue=""):
|
||||
@ -3181,7 +3158,7 @@ def InitUnforgeableProperties(descriptor, properties):
|
||||
"// by the interface prototype object.\n")
|
||||
else:
|
||||
unforgeableProperties = CGWrapper(
|
||||
InitUnforgeablePropertiesOnObject(descriptor, "obj", properties, "nullptr"),
|
||||
InitUnforgeablePropertiesOnObject(descriptor, "aReflector", properties, "false"),
|
||||
pre=(
|
||||
"// Important: do unforgeable property setup after we have handed\n"
|
||||
"// over ownership of the C++ object to obj as needed, so that if\n"
|
||||
@ -3219,9 +3196,9 @@ def InitMemberSlots(descriptor, wrapperCache):
|
||||
clearWrapper = " aCache->ClearWrapper();\n"
|
||||
else:
|
||||
clearWrapper = ""
|
||||
return ("if (!UpdateMemberSlots(aCx, obj, aObject)) {\n"
|
||||
return ("if (!UpdateMemberSlots(aCx, aReflector, aObject)) {\n"
|
||||
"%s"
|
||||
" return nullptr;\n"
|
||||
" return false;\n"
|
||||
"}\n" % clearWrapper)
|
||||
|
||||
|
||||
@ -3235,8 +3212,9 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
|
||||
assert descriptor.interface.hasInterfacePrototypeObject()
|
||||
args = [Argument('JSContext*', 'aCx'),
|
||||
Argument(descriptor.nativeType + '*', 'aObject'),
|
||||
Argument('nsWrapperCache*', 'aCache')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
|
||||
Argument('nsWrapperCache*', 'aCache'),
|
||||
Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
|
||||
self.properties = properties
|
||||
|
||||
def definition_body(self):
|
||||
@ -3249,33 +3227,31 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
|
||||
|
||||
JS::Rooted<JSObject*> parent(aCx, WrapNativeParent(aCx, aObject->GetParentObject()));
|
||||
if (!parent) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
// That might have ended up wrapping us already, due to the wonders
|
||||
// of XBL. Check for that, and bail out as needed. Scope so we don't
|
||||
// collide with the "obj" we declare in CreateBindingJSObject.
|
||||
{
|
||||
JSObject* obj = aCache->GetWrapper();
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
// of XBL. Check for that, and bail out as needed.
|
||||
aReflector.set(aCache->GetWrapper());
|
||||
if (aReflector) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JSAutoCompartment ac(aCx, parent);
|
||||
JS::Rooted<JSObject*> global(aCx, js::GetGlobalForObjectCrossCompartment(parent));
|
||||
JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
|
||||
if (!proto) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
$*{createObject}
|
||||
|
||||
$*{unforgeable}
|
||||
|
||||
aCache->SetWrapper(obj);
|
||||
aCache->SetWrapper(aReflector);
|
||||
$*{slots}
|
||||
return obj;
|
||||
creator.InitializationSucceeded();
|
||||
return true;
|
||||
""",
|
||||
assertion=AssertInheritanceChain(self.descriptor),
|
||||
createObject=CreateBindingJSObject(self.descriptor, self.properties),
|
||||
@ -3293,7 +3269,10 @@ class CGWrapMethod(CGAbstractMethod):
|
||||
inline=True, templateArgs=["class T"])
|
||||
|
||||
def definition_body(self):
|
||||
return "return Wrap(aCx, aObject, aObject);\n"
|
||||
return dedent("""
|
||||
JS::Rooted<JSObject*> reflector(aCx);
|
||||
return Wrap(aCx, aObject, aObject, &reflector) ? reflector.get() : nullptr;
|
||||
""")
|
||||
|
||||
|
||||
class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
@ -3307,10 +3286,9 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
# XXX can we wrap if we don't have an interface prototype object?
|
||||
assert descriptor.interface.hasInterfacePrototypeObject()
|
||||
args = [Argument('JSContext*', 'aCx'),
|
||||
Argument(descriptor.nativeType + '*', 'aObject')]
|
||||
if descriptor.nativeOwnership == 'owned':
|
||||
args.append(Argument('bool*', 'aTookOwnership'))
|
||||
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
|
||||
Argument(descriptor.nativeType + '*', 'aObject'),
|
||||
Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
|
||||
self.properties = properties
|
||||
|
||||
def definition_body(self):
|
||||
@ -3321,7 +3299,7 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
|
||||
if (!proto) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
$*{createObject}
|
||||
@ -3329,7 +3307,8 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
$*{unforgeable}
|
||||
|
||||
$*{slots}
|
||||
return obj;
|
||||
creator.InitializationSucceeded();
|
||||
return true;
|
||||
""",
|
||||
assertions=AssertInheritanceChain(self.descriptor),
|
||||
createObject=CreateBindingJSObject(self.descriptor, self.properties),
|
||||
@ -3351,8 +3330,9 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
||||
Argument('nsWrapperCache*', 'aCache'),
|
||||
Argument('JS::CompartmentOptions&', 'aOptions'),
|
||||
Argument('JSPrincipals*', 'aPrincipal'),
|
||||
Argument('bool', 'aInitStandardClasses')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
|
||||
Argument('bool', 'aInitStandardClasses'),
|
||||
Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
|
||||
self.descriptor = descriptor
|
||||
self.properties = properties
|
||||
|
||||
@ -3368,7 +3348,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
||||
|
||||
if self.descriptor.workers:
|
||||
fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
|
||||
// JS_FireOnNewGlobalObject(aCx, obj);
|
||||
// JS_FireOnNewGlobalObject(aCx, aReflector);
|
||||
"""
|
||||
else:
|
||||
fireOnNewGlobal = ""
|
||||
@ -3379,7 +3359,6 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
||||
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
|
||||
"nsISupports must be on our primary inheritance chain");
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx);
|
||||
CreateGlobal<${nativeType}, GetProtoObjectHandle>(aCx,
|
||||
aObject,
|
||||
aCache,
|
||||
@ -3387,24 +3366,24 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
||||
aOptions,
|
||||
aPrincipal,
|
||||
aInitStandardClasses,
|
||||
&obj);
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
aReflector);
|
||||
if (!aReflector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// obj is a new global, so has a new compartment. Enter it
|
||||
// aReflector is a new global, so has a new compartment. Enter it
|
||||
// before doing anything with it.
|
||||
JSAutoCompartment ac(aCx, obj);
|
||||
JSAutoCompartment ac(aCx, aReflector);
|
||||
|
||||
if (!DefineProperties(aCx, obj, ${properties}, ${chromeProperties})) {
|
||||
return nullptr;
|
||||
if (!DefineProperties(aCx, aReflector, ${properties}, ${chromeProperties})) {
|
||||
return false;
|
||||
}
|
||||
$*{unforgeable}
|
||||
|
||||
$*{slots}
|
||||
$*{fireOnNewGlobal}
|
||||
|
||||
return obj;
|
||||
return true;
|
||||
""",
|
||||
assertions=AssertInheritanceChain(self.descriptor),
|
||||
nativeType=self.descriptor.nativeType,
|
||||
@ -4704,12 +4683,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
isMember or
|
||||
isCallbackReturnValue)
|
||||
|
||||
if forceOwningType and descriptor.nativeOwnership == 'owned':
|
||||
raise TypeError("Interface %s has 'owned' nativeOwnership, so we "
|
||||
"don't know how to keep it alive in %s" %
|
||||
(descriptor.interface.identifier.name,
|
||||
sourceDescription))
|
||||
|
||||
typeName = descriptor.nativeType
|
||||
typePtr = typeName + "*"
|
||||
|
||||
@ -4733,6 +4706,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
declType = "NonNull<" + typeName + ">"
|
||||
|
||||
templateBody = ""
|
||||
if forceOwningType:
|
||||
templateBody += 'static_assert(IsRefcounted<%s>::value, "We can only store refcounted classes.");' % typeName
|
||||
if not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
|
||||
if failureCode is not None:
|
||||
templateBody += str(CastableObjectUnwrapper(
|
||||
@ -5769,15 +5744,11 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||
|
||||
if not descriptor.interface.isExternal() and not descriptor.skipGen:
|
||||
if descriptor.wrapperCache:
|
||||
assert descriptor.nativeOwnership != 'owned'
|
||||
wrapMethod = "GetOrCreateDOMReflector"
|
||||
else:
|
||||
if not returnsNewObject:
|
||||
raise MethodNotNewObjectError(descriptor.interface.identifier.name)
|
||||
if descriptor.nativeOwnership == 'owned':
|
||||
wrapMethod = "WrapNewBindingNonWrapperCachedOwnedObject"
|
||||
else:
|
||||
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
|
||||
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
|
||||
wrap = "%s(cx, ${obj}, %s, ${jsvalHandle})" % (wrapMethod, result)
|
||||
if not descriptor.hasXPConnectImpls:
|
||||
# Can only fail to wrap as a new-binding object
|
||||
@ -6098,11 +6069,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
|
||||
result = CGGeneric(descriptorProvider.getDescriptor(
|
||||
returnType.unroll().inner.identifier.name).nativeType)
|
||||
conversion = None
|
||||
if descriptorProvider.getDescriptor(
|
||||
returnType.unroll().inner.identifier.name).nativeOwnership == 'owned':
|
||||
result = CGTemplatedType("nsAutoPtr", result)
|
||||
elif isMember:
|
||||
result = CGTemplatedType("nsRefPtr", result)
|
||||
if isMember:
|
||||
result = CGGeneric("StrongPtrForMember<%s>::Type" % result.define())
|
||||
else:
|
||||
conversion = CGGeneric("StrongOrRawPtr<%s>" % result.define())
|
||||
result = CGGeneric("auto")
|
||||
@ -6693,8 +6661,7 @@ class CGPerSignatureCall(CGThing):
|
||||
|
||||
returnsNewObject = memberReturnsNewObject(self.idlNode)
|
||||
if (returnsNewObject and
|
||||
self.returnType.isGeckoInterface() and
|
||||
not self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'):
|
||||
self.returnType.isGeckoInterface()):
|
||||
wrapCode += dedent(
|
||||
"""
|
||||
static_assert(!IsPointer<decltype(result)>::value,
|
||||
@ -10994,16 +10961,17 @@ class CGDescriptor(CGThing):
|
||||
|
||||
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
|
||||
|
||||
if descriptor.nativeOwnership == 'owned' and (
|
||||
descriptor.interface.hasChildInterfaces() or
|
||||
descriptor.interface.parent):
|
||||
raise TypeError("Owned interface cannot have a parent or children")
|
||||
|
||||
self._deps = descriptor.interface.getDeps()
|
||||
|
||||
cgThings = []
|
||||
cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" %
|
||||
descriptor.nativeType))
|
||||
parent = descriptor.interface.parent
|
||||
if parent:
|
||||
cgThings.append(CGGeneric("static_assert(IsRefcounted<NativeType>::value == IsRefcounted<%s::NativeType>::value,\n"
|
||||
" \"Can't inherit from an interface with a different ownership model.\");\n" %
|
||||
toBindingNamespace(descriptor.parentPrototypeName)))
|
||||
|
||||
# These are set to true if at least one non-static
|
||||
# method/getter/setter or jsonifier exist on the interface.
|
||||
(hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter,
|
||||
@ -12213,7 +12181,10 @@ class CGBindingRoot(CGThing):
|
||||
declare or define to generate header or cpp code (respectively).
|
||||
"""
|
||||
def __init__(self, config, prefix, webIDLFile):
|
||||
bindingHeaders = {}
|
||||
bindingHeaders = dict.fromkeys((
|
||||
'mozilla/dom/NonRefcountedDOMObject.h',
|
||||
),
|
||||
True)
|
||||
bindingDeclareHeaders = dict.fromkeys((
|
||||
'mozilla/dom/BindingDeclarations.h',
|
||||
'mozilla/dom/Nullable.h',
|
||||
@ -12255,8 +12226,6 @@ class CGBindingRoot(CGThing):
|
||||
|
||||
bindingHeaders["mozilla/Preferences.h"] = any(
|
||||
descriptorRequiresPreferences(d) for d in descriptors)
|
||||
bindingHeaders["mozilla/dom/NonRefcountedDOMObject.h"] = any(
|
||||
d.nativeOwnership == 'owned' for d in descriptors)
|
||||
bindingHeaders["mozilla/dom/DOMJSProxyHandler.h"] = any(
|
||||
d.concrete and d.proxy for d in descriptors)
|
||||
|
||||
@ -13066,40 +13035,30 @@ class CGExampleClass(CGBindingImplClass):
|
||||
CGExampleMethod, CGExampleGetter, CGExampleSetter,
|
||||
wantGetParent=descriptor.wrapperCache)
|
||||
|
||||
self.refcounted = descriptor.nativeOwnership == "refcounted"
|
||||
|
||||
self.parentIface = descriptor.interface.parent
|
||||
if self.parentIface:
|
||||
self.parentDesc = descriptor.getDescriptor(
|
||||
self.parentIface.identifier.name)
|
||||
bases = [ClassBase(self.nativeLeafName(self.parentDesc))]
|
||||
else:
|
||||
bases = []
|
||||
if self.refcounted:
|
||||
bases.append(ClassBase("nsISupports /* Change nativeOwnership in the binding configuration if you don't want this */"))
|
||||
if descriptor.wrapperCache:
|
||||
bases.append(ClassBase("nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */"))
|
||||
else:
|
||||
bases.append(ClassBase("NonRefcountedDOMObject"))
|
||||
bases = [ ClassBase("nsISupports /* or NonRefcountedDOMObject if this is a non-refcounted object */") ]
|
||||
if descriptor.wrapperCache:
|
||||
bases.append(ClassBase("nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */"))
|
||||
|
||||
if self.refcounted:
|
||||
destructorVisibility = "protected"
|
||||
if self.parentIface:
|
||||
extradeclarations = (
|
||||
"public:\n"
|
||||
" NS_DECL_ISUPPORTS_INHERITED\n"
|
||||
" NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(%s, %s)\n"
|
||||
"\n" % (self.nativeLeafName(descriptor),
|
||||
self.nativeLeafName(self.parentDesc)))
|
||||
else:
|
||||
extradeclarations = (
|
||||
"public:\n"
|
||||
" NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n"
|
||||
" NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)\n"
|
||||
"\n" % self.nativeLeafName(descriptor))
|
||||
destructorVisibility = "protected"
|
||||
if self.parentIface:
|
||||
extradeclarations = (
|
||||
"public:\n"
|
||||
" NS_DECL_ISUPPORTS_INHERITED\n"
|
||||
" NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(%s, %s)\n"
|
||||
"\n" % (self.nativeLeafName(descriptor),
|
||||
self.nativeLeafName(self.parentDesc)))
|
||||
else:
|
||||
destructorVisibility = "public"
|
||||
extradeclarations = ""
|
||||
extradeclarations = (
|
||||
"public:\n"
|
||||
" NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n"
|
||||
" NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)\n"
|
||||
"\n" % self.nativeLeafName(descriptor))
|
||||
|
||||
if descriptor.interface.hasChildInterfaces():
|
||||
decorators = ""
|
||||
@ -13117,55 +13076,43 @@ class CGExampleClass(CGBindingImplClass):
|
||||
|
||||
def define(self):
|
||||
# Just override CGClass and do our own thing
|
||||
if self.refcounted:
|
||||
ctordtor = dedent("""
|
||||
${nativeType}::${nativeType}()
|
||||
{
|
||||
}
|
||||
ctordtor = dedent("""
|
||||
${nativeType}::${nativeType}()
|
||||
{
|
||||
// Add |MOZ_COUNT_CTOR(${nativeType});| for a non-refcounted object.
|
||||
}
|
||||
|
||||
${nativeType}::~${nativeType}()
|
||||
{
|
||||
// Add |MOZ_COUNT_DTOR(${nativeType});| for a non-refcounted object.
|
||||
}
|
||||
""")
|
||||
|
||||
if self.parentIface:
|
||||
ccImpl = dedent("""
|
||||
|
||||
// Only needed for refcounted objects.
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_0(${nativeType}, ${parentType})
|
||||
NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
|
||||
NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
|
||||
NS_INTERFACE_MAP_END_INHERITING(${parentType})
|
||||
|
||||
${nativeType}::~${nativeType}()
|
||||
{
|
||||
}
|
||||
""")
|
||||
else:
|
||||
ctordtor = dedent("""
|
||||
${nativeType}::${nativeType}()
|
||||
{
|
||||
MOZ_COUNT_CTOR(${nativeType});
|
||||
}
|
||||
ccImpl = dedent("""
|
||||
|
||||
// Only needed for refcounted objects.
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
${nativeType}::~${nativeType}()
|
||||
{
|
||||
MOZ_COUNT_DTOR(${nativeType});
|
||||
}
|
||||
""")
|
||||
|
||||
if self.refcounted:
|
||||
if self.parentIface:
|
||||
ccImpl = dedent("""
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_0(${nativeType}, ${parentType})
|
||||
NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
|
||||
NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
|
||||
NS_INTERFACE_MAP_END_INHERITING(${parentType})
|
||||
|
||||
""")
|
||||
else:
|
||||
ccImpl = dedent("""
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
""")
|
||||
else:
|
||||
ccImpl = ""
|
||||
|
||||
classImpl = ccImpl + ctordtor + "\n" + dedent("""
|
||||
JSObject*
|
||||
${nativeType}::WrapObject(JSContext* aCx)
|
||||
|
@ -468,16 +468,10 @@ class Descriptor(DescriptorProvider):
|
||||
iface.setUserData('hasProxyDescendant', True)
|
||||
iface = iface.parent
|
||||
|
||||
self.nativeOwnership = desc.get('nativeOwnership', 'refcounted')
|
||||
if not self.nativeOwnership in ('owned', 'refcounted'):
|
||||
raise TypeError("Descriptor for %s has unrecognized value (%s) "
|
||||
"for nativeOwnership" %
|
||||
(self.interface.identifier.name, self.nativeOwnership))
|
||||
if desc.get('wantsQI', None) != None:
|
||||
self._wantsQI = desc.get('wantsQI', None)
|
||||
self.wrapperCache = (not self.interface.isCallback() and
|
||||
(self.nativeOwnership != 'owned' and
|
||||
desc.get('wrapperCache', True)))
|
||||
desc.get('wrapperCache', True))
|
||||
|
||||
def make_name(name):
|
||||
return name + "_workers" if self.workers else name
|
||||
|
@ -12,12 +12,12 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
// Natives for DOM classes with 'owned' as the value for nativeOwnership in
|
||||
// Bindings.conf need to inherit from this class.
|
||||
// Natives for DOM classes that aren't refcounted need to inherit from this
|
||||
// class.
|
||||
// If you're seeing objects of this class leak then natives for one of the DOM
|
||||
// classes with 'owned' as the value for nativeOwnership in Bindings.conf is
|
||||
// leaking. If the native for that class has MOZ_COUNT_CTOR/DTOR in its
|
||||
// constructor/destructor then it should show up in the leak log too.
|
||||
// classes inheriting from it is leaking. If the native for that class has
|
||||
// MOZ_COUNT_CTOR/DTOR in its constructor/destructor then it should show up in
|
||||
// the leak log too.
|
||||
class NonRefcountedDOMObject
|
||||
{
|
||||
protected:
|
||||
|
@ -32,7 +32,9 @@ ReadStructuredCloneImageData(JSContext* aCx, JSStructuredCloneReader* aReader)
|
||||
nsRefPtr<ImageData> imageData = new ImageData(width, height,
|
||||
dataArray.toObject());
|
||||
// Wrap it in a JS::Value.
|
||||
result = imageData->WrapObject(aCx);
|
||||
if (!imageData->WrapObject(aCx, &result)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class TestNonWrapperCacheInterface : public nsISupports
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* cx);
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
};
|
||||
|
||||
class OnlyForUseInConstructor : public nsISupports,
|
||||
|
@ -108,10 +108,10 @@ ImageData::DropData()
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ImageData::WrapObject(JSContext* cx)
|
||||
bool
|
||||
ImageData::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return ImageDataBinding::Wrap(cx, this);
|
||||
return ImageDataBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
return mData;
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* cx);
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
private:
|
||||
void HoldData();
|
||||
|
@ -30,9 +30,9 @@ public:
|
||||
return width;
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, bool* aTookOwnership)
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return TextMetricsBinding::Wrap(aCx, this, aTookOwnership);
|
||||
return TextMetricsBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -11,10 +11,11 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
JSObject*
|
||||
WebGLActiveInfo::WrapObject(JSContext* cx)
|
||||
bool
|
||||
WebGLActiveInfo::WrapObject(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return dom::WebGLActiveInfoBinding::Wrap(cx, this);
|
||||
return dom::WebGLActiveInfoBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
retval = mName;
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* cx);
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
|
||||
|
||||
|
@ -10,10 +10,11 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
JSObject*
|
||||
WebGLShaderPrecisionFormat::WrapObject(JSContext* cx)
|
||||
bool
|
||||
WebGLShaderPrecisionFormat::WrapObject(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return dom::WebGLShaderPrecisionFormatBinding::Wrap(cx, this);
|
||||
return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
, mPrecision(precision)
|
||||
{ }
|
||||
|
||||
JSObject* WrapObject(JSContext* cx);
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
// WebIDL WebGLShaderPrecisionFormat API
|
||||
GLint RangeMin() const {
|
||||
|
@ -12,10 +12,11 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
JSObject*
|
||||
WebGLUniformLocation::WrapObject(JSContext* cx)
|
||||
bool
|
||||
WebGLUniformLocation::WrapObject(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aReflector)
|
||||
{
|
||||
return dom::WebGLUniformLocationBinding::Wrap(cx, this);
|
||||
return dom::WebGLUniformLocationBinding::Wrap(aCx, this, aReflector);
|
||||
}
|
||||
|
||||
WebGLUniformLocation::WebGLUniformLocation(WebGLContext* context,
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
uint32_t ProgramGeneration() const { return mProgramGeneration; }
|
||||
int ElementSize() const { return mElementSize; }
|
||||
|
||||
JSObject* WrapObject(JSContext* cx);
|
||||
bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocation)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WebGLUniformLocation)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user