mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Merge from mozilla-central.
This commit is contained in:
commit
07f7d8e680
@ -1626,21 +1626,17 @@ AccessibleWrap::GetHWNDFor(Accessible* aAccessible)
|
||||
nsIFrame* frame = aAccessible->GetFrame();
|
||||
if (frame) {
|
||||
nsIWidget* widget = frame->GetNearestWidget();
|
||||
if (widget) {
|
||||
bool isVisible = false;
|
||||
widget->IsVisible(isVisible);
|
||||
if (isVisible) {
|
||||
nsIPresShell* shell = document->PresShell();
|
||||
nsIViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
||||
// Make sure the accessible belongs to popup. If not then use
|
||||
// document HWND (which might be different from root widget in the
|
||||
// case of window emulation).
|
||||
if (rootWidget != widget)
|
||||
return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
}
|
||||
if (widget && widget->IsVisible()) {
|
||||
nsIPresShell* shell = document->PresShell();
|
||||
nsIViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
||||
// Make sure the accessible belongs to popup. If not then use
|
||||
// document HWND (which might be different from root widget in the
|
||||
// case of window emulation).
|
||||
if (rootWidget != widget)
|
||||
return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,6 +146,43 @@ uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
|
||||
if (!aPropertyValue)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (mAcc->IsDefunct())
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
aPropertyValue->vt = VT_EMPTY;
|
||||
|
||||
switch (aPropertyId) {
|
||||
// Accelerator Key / shortcut.
|
||||
case UIA_AcceleratorKeyPropertyId: {
|
||||
nsAutoString keyString;
|
||||
|
||||
mAcc->KeyboardShortcut().ToString(keyString);
|
||||
|
||||
if (!keyString.IsEmpty()) {
|
||||
aPropertyValue->vt = VT_BSTR;
|
||||
aPropertyValue->bstrVal = ::SysAllocString(keyString.get());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Access Key / mneumonic.
|
||||
case UIA_AccessKeyPropertyId: {
|
||||
nsAutoString keyString;
|
||||
|
||||
mAcc->AccessKey().ToString(keyString);
|
||||
|
||||
if (!keyString.IsEmpty()) {
|
||||
aPropertyValue->vt = VT_BSTR;
|
||||
aPropertyValue->bstrVal = ::SysAllocString(keyString.get());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// UI Automation will attempt to get the property from the host
|
||||
//window provider.
|
||||
aPropertyValue->vt = VT_EMPTY;
|
||||
|
2
aclocal.m4
vendored
2
aclocal.m4
vendored
@ -3,6 +3,8 @@ dnl Local autoconf macros used with mozilla
|
||||
dnl The contents of this file are under the Public Domain.
|
||||
dnl
|
||||
|
||||
builtin(include, build/autoconf/toolchain.m4)dnl
|
||||
builtin(include, build/autoconf/ccache.m4)dnl
|
||||
builtin(include, build/autoconf/nspr.m4)dnl
|
||||
builtin(include, build/autoconf/nss.m4)dnl
|
||||
builtin(include, build/autoconf/pkg.m4)dnl
|
||||
|
@ -247,6 +247,7 @@ pref("ui.dragThresholdY", 25);
|
||||
pref("layers.acceleration.disabled", false);
|
||||
pref("layers.offmainthreadcomposition.enabled", true);
|
||||
pref("layers.async-video.enabled", true);
|
||||
pref("layers.async-pan-zoom.enabled", true);
|
||||
|
||||
// Web Notifications
|
||||
pref("notification.feature.enabled", true);
|
||||
|
@ -16,7 +16,6 @@ chrome.jar:
|
||||
#ifndef ANDROID
|
||||
content/screen.js (content/screen.js)
|
||||
#endif
|
||||
content/webapi.js (content/webapi.js)
|
||||
content/content.css (content/content.css)
|
||||
content/touchcontrols.css (content/touchcontrols.css)
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const kWebApiShimFile = 'chrome://browser/content/webapi.js';
|
||||
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
@ -41,8 +40,6 @@ ProcessGlobal.prototype = {
|
||||
switch (topic) {
|
||||
case 'app-startup': {
|
||||
Services.obs.addObserver(this, 'console-api-log-event', false);
|
||||
Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
|
||||
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
|
||||
break;
|
||||
}
|
||||
case 'console-api-log-event': {
|
||||
@ -56,17 +53,6 @@ ProcessGlobal.prototype = {
|
||||
' '));
|
||||
break;
|
||||
}
|
||||
case 'remote-browser-frame-shown':
|
||||
case 'in-process-browser-frame-shown': {
|
||||
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
|
||||
let mm = frameLoader.messageManager;
|
||||
try {
|
||||
mm.loadFrameScript(kWebApiShimFile, true);
|
||||
} catch (e) {
|
||||
log('Error loading ' + kWebApiShimFile + ' as frame script: ' + e + '\n');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -1184,4 +1184,5 @@ pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
||||
pref("image.mem.max_decoded_image_kb", 256000);
|
||||
|
||||
// Example social provider
|
||||
pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\"}");
|
||||
pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\",\"sidebarURL\":\"https://motown-dev.mozillalabs.com/social/sidebar\"}");
|
||||
pref("social.sidebar.open", true);
|
||||
|
@ -171,7 +171,7 @@ body[dir=rtl] #defaultSnippet2 {
|
||||
converts em from units of font-size to units of line-height. The goal is to
|
||||
preset the height of a three-line snippet to avoid visual moving/flickering as
|
||||
the snippets load. */
|
||||
min-height: -moz-calc(15/12 * 3em);
|
||||
min-height: calc(15/12 * 3em);
|
||||
}
|
||||
|
||||
#launcher {
|
||||
|
@ -107,6 +107,7 @@
|
||||
<command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
|
||||
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
|
||||
<command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
|
||||
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
|
||||
</commandset>
|
||||
|
||||
<commandset id="placesCommands">
|
||||
@ -181,6 +182,7 @@
|
||||
<broadcaster id="sync-syncnow-state"/>
|
||||
#endif
|
||||
<broadcaster id="workOfflineMenuitemState"/>
|
||||
<broadcaster id="socialSidebarBroadcaster" hidden="true"/>
|
||||
</broadcasterset>
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
|
@ -9,6 +9,8 @@ let SocialUI = {
|
||||
Services.obs.addObserver(this, "social:ambient-notification-changed", false);
|
||||
Services.obs.addObserver(this, "social:profile-changed", false);
|
||||
|
||||
Services.prefs.addObserver("social.sidebar.open", this, false);
|
||||
|
||||
Social.init(this._providerReady.bind(this));
|
||||
},
|
||||
|
||||
@ -17,6 +19,8 @@ let SocialUI = {
|
||||
Services.obs.removeObserver(this, "social:pref-changed");
|
||||
Services.obs.removeObserver(this, "social:ambient-notification-changed");
|
||||
Services.obs.removeObserver(this, "social:profile-changed");
|
||||
|
||||
Services.prefs.removeObserver("social.sidebar.open", this);
|
||||
},
|
||||
|
||||
showProfile: function SocialUI_showProfile() {
|
||||
@ -29,6 +33,7 @@ let SocialUI = {
|
||||
case "social:pref-changed":
|
||||
SocialShareButton.updateButtonHiddenState();
|
||||
SocialToolbar.updateButtonHiddenState();
|
||||
SocialSidebar.updateSidebar();
|
||||
break;
|
||||
case "social:ambient-notification-changed":
|
||||
SocialToolbar.updateButton();
|
||||
@ -36,6 +41,8 @@ let SocialUI = {
|
||||
case "social:profile-changed":
|
||||
SocialToolbar.updateProfile();
|
||||
break;
|
||||
case "nsPref:changed":
|
||||
SocialSidebar.updateSidebar();
|
||||
}
|
||||
},
|
||||
|
||||
@ -43,12 +50,13 @@ let SocialUI = {
|
||||
_providerReady: function SocialUI_providerReady() {
|
||||
SocialToolbar.init();
|
||||
SocialShareButton.init();
|
||||
SocialSidebar.init();
|
||||
}
|
||||
}
|
||||
|
||||
let SocialShareButton = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
init: function SSB_init() {
|
||||
this.sharePopup.hidden = false;
|
||||
this.updateButtonHiddenState();
|
||||
|
||||
let profileRow = document.getElementById("editSharePopupHeader");
|
||||
@ -98,6 +106,8 @@ let SocialShareButton = {
|
||||
},
|
||||
|
||||
sharePage: function SSB_sharePage() {
|
||||
this.sharePopup.hidden = false;
|
||||
|
||||
let uri = gBrowser.currentURI;
|
||||
if (!Social.isPageShared(uri)) {
|
||||
Social.sharePage(uri);
|
||||
@ -248,9 +258,60 @@ var SocialToolbar = {
|
||||
notifBrowser.setAttribute("src", "about:blank");
|
||||
});
|
||||
|
||||
notifBrowser.service = Social.provider;
|
||||
notifBrowser.setAttribute("origin", Social.provider.origin);
|
||||
notifBrowser.setAttribute("src", iconImage.getAttribute("contentPanel"));
|
||||
document.getElementById("social-toolbar-button").setAttribute("open", "true");
|
||||
panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
var SocialSidebar = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
init: function SocialSidebar_init() {
|
||||
this.updateSidebar();
|
||||
},
|
||||
|
||||
// Whether the sidebar can be shown for this window.
|
||||
get canShow() {
|
||||
return Social.uiVisible && Social.provider.sidebarURL && !this.chromeless;
|
||||
},
|
||||
|
||||
// Whether this is a "chromeless window" (e.g. popup window). We don't show
|
||||
// the sidebar in these windows.
|
||||
get chromeless() {
|
||||
let docElem = document.documentElement;
|
||||
return docElem.getAttribute('disablechrome') ||
|
||||
docElem.getAttribute('chromehidden').indexOf("extrachrome") >= 0;
|
||||
},
|
||||
|
||||
// Whether the user has toggled the sidebar on (for windows where it can appear)
|
||||
get enabled() {
|
||||
return Services.prefs.getBoolPref("social.sidebar.open");
|
||||
},
|
||||
|
||||
updateSidebar: function SocialSidebar_updateSidebar() {
|
||||
// Hide the toggle menu item if the sidebar cannot appear
|
||||
let command = document.getElementById("Social:ToggleSidebar");
|
||||
command.hidden = !this.canShow;
|
||||
|
||||
// Hide the sidebar if it cannot appear, or has been toggled off.
|
||||
// Also set the command "checked" state accordingly.
|
||||
let hideSidebar = !this.canShow || !this.enabled;
|
||||
let broadcaster = document.getElementById("socialSidebarBroadcaster");
|
||||
broadcaster.hidden = hideSidebar;
|
||||
command.setAttribute("checked", !hideSidebar);
|
||||
|
||||
// If the sidebar is hidden, unload its document
|
||||
// XXX this results in a poor UX, we should revisit
|
||||
let sbrowser = document.getElementById("social-sidebar-browser");
|
||||
if (broadcaster.hidden) {
|
||||
sbrowser.removeAttribute("origin");
|
||||
sbrowser.setAttribute("src", "about:blank");
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the sidebar document
|
||||
sbrowser.setAttribute("origin", Social.provider.origin);
|
||||
sbrowser.setAttribute("src", Social.provider.sidebarURL);
|
||||
}
|
||||
}
|
||||
|
@ -493,7 +493,7 @@ statuspanel {
|
||||
position: fixed;
|
||||
margin-top: -3em;
|
||||
left: 0;
|
||||
max-width: -moz-calc(100% - 5px);
|
||||
max-width: calc(100% - 5px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
@ -638,6 +638,12 @@
|
||||
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<menuitem id="social-toggle-sidebar-menuitem"
|
||||
type="checkbox"
|
||||
autocheck="false"
|
||||
command="Social:ToggleSidebar"
|
||||
label="&social.toggleSidebar.label;"
|
||||
accesskey="&social.toggleSidebar.accesskey;"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
<hbox id="social-status-iconbox" flex="1">
|
||||
@ -1024,6 +1030,17 @@
|
||||
onclick="contentAreaClick(event, false);"/>
|
||||
<statuspanel id="statusbar-display" inactive="true"/>
|
||||
</vbox>
|
||||
<splitter id="social-sidebar-splitter"
|
||||
class="chromeclass-extrachrome"
|
||||
observes="socialSidebarBroadcaster"/>
|
||||
<vbox id="social-sidebar-box"
|
||||
class="chromeclass-extrachrome"
|
||||
observes="socialSidebarBroadcaster">
|
||||
<browser id="social-sidebar-browser"
|
||||
type="content"
|
||||
flex="1"
|
||||
style="min-width: 14em; width: 18em; max-width: 36em;"/>
|
||||
</vbox>
|
||||
<splitter id="devtools-side-splitter" hidden="true"/>
|
||||
<vbox id="devtools-sidebar-box" hidden="true"
|
||||
style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
|
||||
|
@ -257,6 +257,7 @@ _BROWSER_FILES = \
|
||||
browser_lastAccessedTab.js \
|
||||
browser_bug734076.js \
|
||||
browser_social_toolbar.js \
|
||||
browser_social_sidebar.js \
|
||||
$(NULL)
|
||||
|
||||
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
|
@ -71,6 +71,22 @@ function wait_for_install_dialog(aCallback) {
|
||||
});
|
||||
}
|
||||
|
||||
function wait_for_single_notification(aCallback) {
|
||||
function inner_waiter() {
|
||||
info("Waiting for single notification");
|
||||
// Notification should never close while we wait
|
||||
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
|
||||
if (PopupNotifications.panel.childNodes.length == 2) {
|
||||
executeSoon(inner_waiter);
|
||||
return;
|
||||
}
|
||||
|
||||
aCallback();
|
||||
}
|
||||
|
||||
executeSoon(inner_waiter);
|
||||
}
|
||||
|
||||
function setup_redirect(aSettings) {
|
||||
var url = "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/redirect.sjs?mode=setup";
|
||||
for (var name in aSettings) {
|
||||
@ -438,7 +454,7 @@ function test_localfile() {
|
||||
Services.obs.removeObserver(arguments.callee, "addon-install-failed");
|
||||
|
||||
// Wait for the browser code to add the failure notification
|
||||
executeSoon(function() {
|
||||
wait_for_single_notification(function() {
|
||||
let notification = PopupNotifications.panel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
is(notification.getAttribute("label"),
|
||||
@ -798,14 +814,9 @@ function test_failed_security() {
|
||||
Services.obs.addObserver(function() {
|
||||
Services.obs.removeObserver(arguments.callee, "addon-install-failed");
|
||||
|
||||
function waitForSingleNotification() {
|
||||
// Notification should never close while we wait
|
||||
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
|
||||
if (PopupNotifications.panel.childNodes.length == 2) {
|
||||
executeSoon(waitForSingleNotification);
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow the browser code to add the failure notification and then wait
|
||||
// for the progress notification to dismiss itself
|
||||
wait_for_single_notification(function() {
|
||||
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
|
||||
notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
@ -813,11 +824,7 @@ function test_failed_security() {
|
||||
Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, true);
|
||||
wait_for_notification_close(runNextTest);
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
// Allow the browser code to add the failure notification and then wait
|
||||
// for the progress notification to dismiss itself
|
||||
executeSoon(waitForSingleNotification);
|
||||
});
|
||||
}, "addon-install-failed", false);
|
||||
});
|
||||
|
||||
|
@ -51,7 +51,6 @@ function testInitial() {
|
||||
sharePopup = SocialShareButton.sharePopup;
|
||||
ok(shareButton, "share button exists");
|
||||
ok(sharePopup, "share popup exists");
|
||||
ok(!sharePopup.hidden, "share popup is not hidden");
|
||||
|
||||
okButton = document.getElementById("editSharePopupOkButton");
|
||||
undoButton = document.getElementById("editSharePopupUndoButton");
|
||||
|
52
browser/base/content/test/browser_social_sidebar.js
Normal file
52
browser/base/content/test/browser_social_sidebar.js
Normal file
@ -0,0 +1,52 @@
|
||||
/* 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/. */
|
||||
|
||||
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
function test() {
|
||||
// XXX Bug 775779
|
||||
if (Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild) {
|
||||
ok(true, "can't run social sidebar test in debug builds because they falsely report leaks");
|
||||
return;
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
sidebarURL: "https://example1.com/sidebar.html",
|
||||
workerURL: "https://example1.com/worker.js",
|
||||
iconURL: "chrome://branding/content/icon48.png"
|
||||
};
|
||||
runSocialTestWithProvider(manifest, doTest);
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
ok(SocialSidebar.canShow, "social sidebar should be able to be shown");
|
||||
ok(SocialSidebar.enabled, "social sidebar should be on by default");
|
||||
|
||||
let command = document.getElementById("Social:ToggleSidebar");
|
||||
let sidebar = document.getElementById("social-sidebar-box");
|
||||
|
||||
// Check the the sidebar is initially visible, and loaded
|
||||
ok(!command.hidden, "sidebar toggle command should be visible");
|
||||
is(command.getAttribute("checked"), "true", "sidebar toggle command should be checked");
|
||||
ok(!sidebar.hidden, "sidebar itself should be visible");
|
||||
ok(Services.prefs.getBoolPref("social.sidebar.open"), "sidebar open pref should be true");
|
||||
is(sidebar.firstChild.getAttribute('src'), "https://example1.com/sidebar.html", "sidebar url should be set");
|
||||
|
||||
// Now toggle it!
|
||||
info("Toggling sidebar");
|
||||
Social.toggleSidebar();
|
||||
is(command.getAttribute("checked"), "false", "sidebar toggle command should not be checked");
|
||||
ok(sidebar.hidden, "sidebar itself should not be visible");
|
||||
ok(!Services.prefs.getBoolPref("social.sidebar.open"), "sidebar open pref should be false");
|
||||
is(sidebar.firstChild.getAttribute('src'), "about:blank", "sidebar url should not be set");
|
||||
|
||||
// Remove the test provider
|
||||
SocialService.removeProvider(Social.provider.origin, finish);
|
||||
}
|
||||
|
||||
// XXX test sidebar in popup
|
@ -3,45 +3,20 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
||||
let gProvider;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref("social.enabled", true);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
});
|
||||
|
||||
let oldProvider;
|
||||
function saveOldProviderAndStartTestWith(provider) {
|
||||
oldProvider = Social.provider;
|
||||
registerCleanupFunction(function () {
|
||||
Social.provider = oldProvider;
|
||||
});
|
||||
Social.provider = gProvider = provider;
|
||||
runTests(tests, undefined, undefined, function () {
|
||||
SocialService.removeProvider(provider.origin, finish);
|
||||
});
|
||||
}
|
||||
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
workerURL: "https://example1.com/worker.js",
|
||||
iconURL: "chrome://branding/content/icon48.png"
|
||||
};
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
// If the UI is already active, run the test immediately, otherwise wait
|
||||
// for initialization.
|
||||
if (Social.provider) {
|
||||
saveOldProviderAndStartTestWith(provider);
|
||||
} else {
|
||||
Services.obs.addObserver(function obs() {
|
||||
Services.obs.removeObserver(obs, "test-social-ui-ready");
|
||||
saveOldProviderAndStartTestWith(provider);
|
||||
}, "test-social-ui-ready", false);
|
||||
}
|
||||
runSocialTestWithProvider(manifest, function () {
|
||||
runTests(tests, undefined, undefined, function () {
|
||||
SocialService.removeProvider(Social.provider.origin, finish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -53,7 +28,7 @@ var tests = {
|
||||
displayName: "Kuma Lisa",
|
||||
profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa"
|
||||
}
|
||||
gProvider.updateUserProfile(profile);
|
||||
Social.provider.updateUserProfile(profile);
|
||||
// check dom values
|
||||
let portrait = document.getElementById("social-statusarea-user-portrait").getAttribute("src");
|
||||
is(portrait, profile.portrait, "portrait is set");
|
||||
@ -69,7 +44,7 @@ var tests = {
|
||||
contentPanel: "about:blank",
|
||||
counter: 42
|
||||
};
|
||||
gProvider.setAmbientNotification(ambience);
|
||||
Social.provider.setAmbientNotification(ambience);
|
||||
|
||||
let statusIcons = document.getElementById("social-status-iconbox");
|
||||
ok(!statusIcons.firstChild.collapsed, "status icon is visible");
|
||||
@ -77,13 +52,13 @@ var tests = {
|
||||
is(statusIcons.firstChild.lastChild.textContent, "42", "status value is correct");
|
||||
|
||||
ambience.counter = 0;
|
||||
gProvider.setAmbientNotification(ambience);
|
||||
Social.provider.setAmbientNotification(ambience);
|
||||
ok(statusIcons.firstChild.lastChild.collapsed, "status value is not visible");
|
||||
is(statusIcons.firstChild.lastChild.textContent, "", "status value is correct");
|
||||
next();
|
||||
},
|
||||
testProfileUnset: function(next) {
|
||||
gProvider.updateUserProfile({});
|
||||
Social.provider.updateUserProfile({});
|
||||
// check dom values
|
||||
let portrait = document.getElementById("social-statusarea-user-portrait").getAttribute("src");
|
||||
is(portrait, "chrome://browser/skin/social/social.png", "portrait is generic");
|
||||
|
@ -87,3 +87,34 @@ function waitForCondition(condition, nextTest, errorMsg) {
|
||||
}, 100);
|
||||
var moveOn = function() { clearInterval(interval); nextTest(); };
|
||||
}
|
||||
|
||||
function runSocialTestWithProvider(manifest, callback) {
|
||||
let oldProvider;
|
||||
function saveOldProviderAndStartTestWith(provider) {
|
||||
oldProvider = Social.provider;
|
||||
Social.provider = provider;
|
||||
|
||||
// Now that we've set the UI's provider, enable the social functionality
|
||||
Services.prefs.setBoolPref("social.enabled", true);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Social.provider = oldProvider;
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
});
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
// If the UI is already active, run the test immediately, otherwise wait
|
||||
// for initialization.
|
||||
if (Social.provider) {
|
||||
saveOldProviderAndStartTestWith(provider);
|
||||
} else {
|
||||
Services.obs.addObserver(function obs() {
|
||||
Services.obs.removeObserver(obs, "test-social-ui-ready");
|
||||
saveOldProviderAndStartTestWith(provider);
|
||||
}, "test-social-ui-ready", false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ MOCHITEST_BROWSER_FILES = \
|
||||
head.js \
|
||||
browser_console_clear.js \
|
||||
browser_privatebrowsing_certexceptionsui.js \
|
||||
browser_privatebrowsing_clearplugindata.js \
|
||||
browser_privatebrowsing_clearplugindata.html \
|
||||
browser_privatebrowsing_commandline_toggle.js \
|
||||
browser_privatebrowsing_concurrent.js \
|
||||
browser_privatebrowsing_concurrent_page.html \
|
||||
@ -34,6 +36,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_privatebrowsing_newwindow_stopcmd.js \
|
||||
browser_privatebrowsing_opendir.js \
|
||||
browser_privatebrowsing_openlocation.js \
|
||||
browser_privatebrowsing_openLocationLastURL.js \
|
||||
browser_privatebrowsing_pageinfo.js \
|
||||
browser_privatebrowsing_placestitle.js \
|
||||
browser_privatebrowsing_popupblocker.js \
|
||||
@ -52,8 +55,6 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_privatebrowsing_windowtitle_page.html \
|
||||
browser_privatebrowsing_zoom.js \
|
||||
browser_privatebrowsing_zoomrestore.js \
|
||||
browser_privatebrowsing_clearplugindata.js \
|
||||
browser_privatebrowsing_clearplugindata.html \
|
||||
ctxmenu.html \
|
||||
ctxmenu-image.png \
|
||||
popup.html \
|
||||
|
@ -0,0 +1,63 @@
|
||||
/* 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/. */
|
||||
|
||||
function test() {
|
||||
const URL_1 = "mozilla.org";
|
||||
const URL_2 = "mozilla.com";
|
||||
|
||||
let openLocationLastURL = getLocationModule();
|
||||
let privateBrowsingService =
|
||||
Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
|
||||
function clearHistory() {
|
||||
Services.obs.notifyObservers(null, "browser:purge-session-history", "");
|
||||
}
|
||||
function testURL(aTestNumber, aValue) {
|
||||
is(openLocationLastURL.value, aValue,
|
||||
"Test: " + aTestNumber + ": Validate last url value.");
|
||||
}
|
||||
|
||||
// Clean to start testing.
|
||||
is(typeof openLocationLastURL, "object", "Validate type of last url.");
|
||||
openLocationLastURL.reset();
|
||||
testURL(1, "");
|
||||
|
||||
// Test without private browsing.
|
||||
openLocationLastURL.value = URL_1;
|
||||
testURL(2, URL_1);
|
||||
openLocationLastURL.value = "";
|
||||
testURL(3, "");
|
||||
openLocationLastURL.value = URL_2;
|
||||
testURL(4, URL_2);
|
||||
clearHistory();
|
||||
testURL(5, "");
|
||||
|
||||
// Test changing private browsing.
|
||||
openLocationLastURL.value = URL_2;
|
||||
privateBrowsingService.privateBrowsingEnabled = true;
|
||||
testURL(6, "");
|
||||
privateBrowsingService.privateBrowsingEnabled = false;
|
||||
testURL(7, URL_2);
|
||||
privateBrowsingService.privateBrowsingEnabled = true;
|
||||
openLocationLastURL.value = URL_1;
|
||||
testURL(8, URL_1);
|
||||
privateBrowsingService.privateBrowsingEnabled = false;
|
||||
testURL(9, URL_2);
|
||||
privateBrowsingService.privateBrowsingEnabled = true;
|
||||
openLocationLastURL.value = URL_1;
|
||||
testURL(10, URL_1);
|
||||
|
||||
// Test cleaning history.
|
||||
clearHistory();
|
||||
testURL(11, "");
|
||||
privateBrowsingService.privateBrowsingEnabled = false;
|
||||
testURL(12, "");
|
||||
}
|
||||
|
||||
function getLocationModule() {
|
||||
let openLocationModule = {};
|
||||
Cu.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
|
||||
return new openLocationModule.OpenLocationLastURL(window);
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
// Test the correct behavior of the openLocationLastURL.jsm JS module.
|
||||
|
||||
function run_test_on_service()
|
||||
{
|
||||
let openLocationModule = {};
|
||||
// This variable fakes the window required for getting the PB flag
|
||||
let window = { gPrivateBrowsingUI: { privateWindow: false } };
|
||||
Cu.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
|
||||
let gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window);
|
||||
|
||||
function clearHistory() {
|
||||
// simulate clearing the private data
|
||||
Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService).
|
||||
notifyObservers(null, "browser:purge-session-history", "");
|
||||
}
|
||||
|
||||
let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
let pref = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
gOpenLocationLastURL.reset();
|
||||
|
||||
do_check_eq(typeof gOpenLocationLastURL, "object");
|
||||
do_check_eq(gOpenLocationLastURL.value, "");
|
||||
|
||||
function switchPrivateBrowsing(flag) {
|
||||
pb.privateBrowsingEnabled = flag;
|
||||
window.gPrivateBrowsingUI.privateWindow = flag;
|
||||
}
|
||||
|
||||
const url1 = "mozilla.org";
|
||||
const url2 = "mozilla.com";
|
||||
|
||||
gOpenLocationLastURL.value = url1;
|
||||
do_check_eq(gOpenLocationLastURL.value, url1);
|
||||
|
||||
gOpenLocationLastURL.value = "";
|
||||
do_check_eq(gOpenLocationLastURL.value, "");
|
||||
|
||||
gOpenLocationLastURL.value = url2;
|
||||
do_check_eq(gOpenLocationLastURL.value, url2);
|
||||
|
||||
clearHistory();
|
||||
do_check_eq(gOpenLocationLastURL.value, "");
|
||||
gOpenLocationLastURL.value = url2;
|
||||
|
||||
switchPrivateBrowsing(true);
|
||||
do_check_eq(gOpenLocationLastURL.value, "");
|
||||
|
||||
switchPrivateBrowsing(false);
|
||||
do_check_eq(gOpenLocationLastURL.value, url2);
|
||||
switchPrivateBrowsing(true);
|
||||
|
||||
gOpenLocationLastURL.value = url1;
|
||||
do_check_eq(gOpenLocationLastURL.value, url1);
|
||||
|
||||
switchPrivateBrowsing(false);
|
||||
do_check_eq(gOpenLocationLastURL.value, url2);
|
||||
|
||||
switchPrivateBrowsing(true);
|
||||
gOpenLocationLastURL.value = url1;
|
||||
do_check_neq(gOpenLocationLastURL.value, "");
|
||||
clearHistory();
|
||||
do_check_eq(gOpenLocationLastURL.value, "");
|
||||
|
||||
switchPrivateBrowsing(false);
|
||||
do_check_eq(gOpenLocationLastURL.value, "");
|
||||
}
|
||||
|
||||
// Support running tests on both the service itself and its wrapper
|
||||
function run_test() {
|
||||
run_test_on_all_services();
|
||||
}
|
@ -7,7 +7,6 @@ tail = tail_privatebrowsing.js
|
||||
[test_aboutprivatebrowsing.js]
|
||||
[test_geoClearCookie.js]
|
||||
[test_httpauth.js]
|
||||
[test_openLocationLastURL.js]
|
||||
[test_placesTitleNoUpdate.js]
|
||||
[test_privatebrowsing_autostart.js]
|
||||
[test_privatebrowsing_commandline.js]
|
||||
|
@ -117,7 +117,7 @@ body {
|
||||
/* We want the title container to leave out width, position of the .close
|
||||
button and space between input and .close button. Keep an eye on LTR and
|
||||
RTL differences in .close. */
|
||||
width: -moz-calc(100% - 16px - 6px - 6px);
|
||||
width: calc(100% - 16px - 6px - 6px);
|
||||
}
|
||||
|
||||
input.name {
|
||||
|
@ -72,14 +72,13 @@ let DebuggerController = {
|
||||
this._isDestroyed = true;
|
||||
window.removeEventListener("unload", this._shutdownDebugger, true);
|
||||
|
||||
DebuggerView.destroyPanes();
|
||||
DebuggerView.destroyEditor();
|
||||
DebuggerView.Scripts.destroy();
|
||||
DebuggerView.StackFrames.destroy();
|
||||
DebuggerView.Breakpoints.destroy();
|
||||
DebuggerView.Properties.destroy();
|
||||
DebuggerView.destroyPanes();
|
||||
DebuggerView.destroyEditor();
|
||||
|
||||
DebuggerController.Breakpoints.destroy();
|
||||
DebuggerController.SourceScripts.disconnect();
|
||||
DebuggerController.StackFrames.disconnect();
|
||||
DebuggerController.ThreadState.disconnect();
|
||||
|
@ -57,6 +57,14 @@ let DebuggerView = {
|
||||
|
||||
let variables = document.getElementById("variables");
|
||||
Prefs.variablesWidth = variables.getAttribute("width");
|
||||
|
||||
let bkps = document.getElementById("breakpoints");
|
||||
let frames = document.getElementById("stackframes");
|
||||
bkps.parentNode.removeChild(bkps);
|
||||
frames.parentNode.removeChild(frames);
|
||||
|
||||
stackframes.parentNode.removeChild(stackframes);
|
||||
variables.parentNode.removeChild(variables);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -544,6 +552,8 @@ ScriptsView.prototype = {
|
||||
this._searchbox.removeEventListener("select", this._onScriptsSearch, false);
|
||||
this._searchbox.removeEventListener("input", this._onScriptsSearch, false);
|
||||
this._searchbox.removeEventListener("keyup", this._onScriptsKeyUp, false);
|
||||
|
||||
this.empty();
|
||||
this._scripts = null;
|
||||
this._searchbox = null;
|
||||
}
|
||||
@ -859,6 +869,7 @@ StackFramesView.prototype = {
|
||||
frames.removeEventListener("scroll", this._onFramesScroll, false);
|
||||
window.removeEventListener("resize", this._onFramesScroll, false);
|
||||
|
||||
this.empty();
|
||||
this._frames = null;
|
||||
}
|
||||
};
|
||||
@ -878,6 +889,7 @@ BreakpointsView.prototype = {
|
||||
*/
|
||||
empty: function DVB_empty() {
|
||||
let firstChild;
|
||||
|
||||
while (firstChild = this._breakpoints.firstChild) {
|
||||
this._destroyContextMenu(firstChild);
|
||||
this._breakpoints.removeChild(firstChild);
|
||||
@ -1287,8 +1299,8 @@ BreakpointsView.prototype = {
|
||||
let commandsetId = "breakpointMenuCommands-" + aBreakpoint.id;
|
||||
let menupopupId = "breakpointContextMenu-" + aBreakpoint.id;
|
||||
|
||||
let commandsset = document.createElement("commandsset");
|
||||
commandsset.setAttribute("id", commandsetId);
|
||||
let commandset = document.createElement("commandset");
|
||||
commandset.setAttribute("id", commandsetId);
|
||||
|
||||
let menupopup = document.createElement("menupopup");
|
||||
menupopup.setAttribute("id", menupopupId);
|
||||
@ -1321,7 +1333,7 @@ BreakpointsView.prototype = {
|
||||
menuitem.setAttribute("command", commandId);
|
||||
menuitem.setAttribute("hidden", aHiddenFlag);
|
||||
|
||||
commandsset.appendChild(command);
|
||||
commandset.appendChild(command);
|
||||
menupopup.appendChild(menuitem);
|
||||
|
||||
aBreakpoint[aName] = {
|
||||
@ -1354,7 +1366,10 @@ BreakpointsView.prototype = {
|
||||
|
||||
let popupset = document.getElementById("debugger-popups");
|
||||
popupset.appendChild(menupopup);
|
||||
document.documentElement.appendChild(commandsset);
|
||||
document.documentElement.appendChild(commandset);
|
||||
|
||||
aBreakpoint.commandsetId = commandsetId;
|
||||
aBreakpoint.menupopupId = menupopupId;
|
||||
|
||||
return menupopupId;
|
||||
},
|
||||
@ -1366,18 +1381,15 @@ BreakpointsView.prototype = {
|
||||
* An element representing a breakpoint.
|
||||
*/
|
||||
_destroyContextMenu: function DVB__destroyContextMenu(aBreakpoint) {
|
||||
let commandsetId = "breakpointMenuCommands-" + aBreakpoint.id;
|
||||
let menupopupId = "breakpointContextMenu-" + aBreakpoint.id;
|
||||
|
||||
let commandset = document.getElementById(commandsetId);
|
||||
let menupopup = document.getElementById(menupopupId);
|
||||
|
||||
if (commandset) {
|
||||
commandset.parentNode.removeChild(commandset);
|
||||
}
|
||||
if (menupopup) {
|
||||
menupopup.parentNode.removeChild(menupopup);
|
||||
if (!aBreakpoint.commandsetId || !aBreakpoint.menupopupId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let commandset = document.getElementById(aBreakpoint.commandsetId);
|
||||
let menupopup = document.getElementById(aBreakpoint.menupopupId);
|
||||
|
||||
commandset.parentNode.removeChild(commandset);
|
||||
menupopup.parentNode.removeChild(menupopup);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1398,6 +1410,7 @@ BreakpointsView.prototype = {
|
||||
let breakpoints = this._breakpoints;
|
||||
breakpoints.removeEventListener("click", this._onBreakpointClick, false);
|
||||
|
||||
this.empty();
|
||||
this._breakpoints = null;
|
||||
}
|
||||
};
|
||||
@ -2499,6 +2512,8 @@ PropertiesView.prototype = {
|
||||
* Destruction function, called when the debugger is shut down.
|
||||
*/
|
||||
destroy: function DVP_destroy() {
|
||||
this.empty();
|
||||
|
||||
this._currHierarchy = null;
|
||||
this._prevHierarchy = null;
|
||||
this._vars = null;
|
||||
|
@ -11,6 +11,7 @@ relativesrcdir = browser/devtools/debugger/test
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_leaktest.js \
|
||||
browser_dbg_createRemote.js \
|
||||
browser_dbg_createChrome.js \
|
||||
browser_dbg_debugger-tab-switch.js \
|
||||
|
@ -49,24 +49,22 @@ function testAddBreakpoint()
|
||||
|
||||
function testResume()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function test() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("paused", function test() {
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
thread.addOneTimeListener("paused", function() {
|
||||
executeSoon(testBreakpointHit);
|
||||
}, false);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
content.document.querySelector("button"),
|
||||
content.window);
|
||||
content.document.querySelector("button"));
|
||||
|
||||
});
|
||||
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
function testBreakpointHit()
|
||||
{
|
||||
var frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
@ -76,10 +74,14 @@ function testBreakpointHit()
|
||||
function resumeAndFinish() {
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
executeSoon(closeDebuggerAndFinish);
|
||||
});
|
||||
|
||||
is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
|
||||
thread.resume();
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
|
@ -275,15 +275,21 @@ function test()
|
||||
is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(finish);
|
||||
gDebugger.gClient.addOneTimeListener("resumed", function() {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
function finalCheck() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
|
||||
"getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
is(breakpointsAdded, 2, "correct number of breakpoints have been added");
|
||||
is(breakpointsRemoved, 1, "correct number of breakpoints have been removed");
|
||||
|
@ -142,7 +142,13 @@ function test()
|
||||
gBreakpointsElement.querySelectorAll(".list-item.empty").length,
|
||||
"Found junk in the breakpoints container.");
|
||||
|
||||
finish();
|
||||
executeSoon(function() {
|
||||
gDebugger.gClient.addOneTimeListener("resumed", function() {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -261,11 +267,13 @@ function test()
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
function finalCheck() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
|
||||
"getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(breakpointsAdded, 3, "correct number of breakpoints have been added");
|
||||
is(breakpointsDisabled, 3, "correct number of breakpoints have been disabled");
|
||||
is(breakpointsRemoved, 3, "correct number of breakpoints have been removed");
|
||||
|
@ -113,7 +113,7 @@ function test()
|
||||
|
||||
executeSoon(function() {
|
||||
contextMenu.hidePopup();
|
||||
gDebugger.DebuggerController.activeThread.resume(finish);
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
}
|
||||
|
||||
|
69
browser/devtools/debugger/test/browser_dbg_leaktest.js
Normal file
69
browser/devtools/debugger/test/browser_dbg_leaktest.js
Normal file
@ -0,0 +1,69 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This tests if the debugger leaks.
|
||||
* If leaks happen here, there's something very, very fishy going on.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.contentWindow;
|
||||
resumed = true;
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
window.addEventListener("Debugger:ScriptShown", onScriptShown);
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
window.removeEventListener("Debugger:ScriptShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
closeDebuggerAndFinish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
}
|
@ -45,7 +45,7 @@ body[dir=rtl] > #header > #element-size {
|
||||
#main {
|
||||
margin: 0 10px 10px 10px;
|
||||
-moz-box-sizing: border-box;
|
||||
width: -moz-calc(100% - 2 * 10px);
|
||||
width: calc(100% - 2 * 10px);
|
||||
position: absolute;
|
||||
border-width: 1px;
|
||||
font: 10px/12px monospace;
|
||||
@ -108,7 +108,7 @@ body[dir=rtl] > #header > #element-size {
|
||||
}
|
||||
|
||||
.top, .bottom {
|
||||
width: -moz-calc(100% - 2px);
|
||||
width: calc(100% - 2px);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ body[dir=rtl] > #header > #element-size {
|
||||
}
|
||||
|
||||
.size {
|
||||
width: -moz-calc(100% - 2px);
|
||||
width: calc(100% - 2px);
|
||||
}
|
||||
|
||||
.margin.right,
|
||||
|
@ -662,3 +662,5 @@ toolbar button -->
|
||||
<!ENTITY social.sharePopup.ok.accesskey "O">
|
||||
<!ENTITY social.sharePopup.shared.label "You shared this page.">
|
||||
<!ENTITY social.sharePopup.portrait.arialabel "User profile picture">
|
||||
<!ENTITY social.toggleSidebar.label "Show sidebar">
|
||||
<!ENTITY social.toggleSidebar.accesskey "s">
|
||||
|
@ -34,14 +34,15 @@ let Social = {
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
return SocialService.enabled;
|
||||
},
|
||||
|
||||
get uiVisible() {
|
||||
return this.provider && this.provider.enabled && this.provider.port;
|
||||
},
|
||||
|
||||
toggleSidebar: function SocialSidebar_toggle() {
|
||||
let prefValue = Services.prefs.getBoolPref("social.sidebar.open");
|
||||
Services.prefs.setBoolPref("social.sidebar.open", !prefValue);
|
||||
},
|
||||
|
||||
sendWorkerMessage: function Social_sendWorkerMessage(message) {
|
||||
// Responses aren't handled yet because there is no actions to perform
|
||||
// based on the response from the provider at this point.
|
||||
|
@ -1528,7 +1528,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
background: -moz-linear-gradient(hsla(0,0%,100%,.2), hsla(0,0%,45%,.2) 2px, hsla(0,0%,32%,.2) 80%);
|
||||
background-origin: border-box;
|
||||
background-position: 1px 2px;
|
||||
background-size: 100% -moz-calc(100% - 2px);
|
||||
background-size: 100% calc(100% - 2px);
|
||||
background-repeat: no-repeat;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
@ -2040,7 +2040,7 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
|
||||
|
||||
#highlighter-nodeinfobar-text {
|
||||
/* 100% - size of the buttons and margins */
|
||||
max-width: -moz-calc(100% - 2 * (26px + 6px));
|
||||
max-width: calc(100% - 2 * (26px + 6px));
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
@ -2105,7 +2105,7 @@ html|*#highlighter-nodeinfobar-pseudo-classes {
|
||||
.highlighter-nodeinfobar-arrow {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
-moz-margin-start: -moz-calc(50% - 7px);
|
||||
-moz-margin-start: calc(50% - 7px);
|
||||
transform: rotate(-45deg);
|
||||
border: 1px solid transparent;
|
||||
background-clip: padding-box;
|
||||
|
@ -93,7 +93,7 @@
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl) {
|
||||
background-position: -moz-calc(100% - 4px) 3px, top left, top left;
|
||||
background-position: calc(100% - 4px) 3px, top left, top left;
|
||||
}
|
||||
|
||||
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
|
||||
|
@ -2796,7 +2796,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
|
||||
#highlighter-nodeinfobar-text {
|
||||
/* 100% - size of the buttons + margins */
|
||||
max-width: -moz-calc(100% - 2 * (26px + 6px));
|
||||
max-width: calc(100% - 2 * (26px + 6px));
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
@ -2862,7 +2862,7 @@ html|*#highlighter-nodeinfobar-pseudo-classes {
|
||||
.highlighter-nodeinfobar-arrow {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
-moz-margin-start: -moz-calc(50% - 7px);
|
||||
-moz-margin-start: calc(50% - 7px);
|
||||
transform: rotate(-45deg);
|
||||
border: 1px solid transparent;
|
||||
background-clip: padding-box;
|
||||
|
@ -99,7 +99,7 @@
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl) {
|
||||
background-position: -moz-calc(100% - 4px) 3px, top left, top left;
|
||||
background-position: calc(100% - 4px) 3px, top left, top left;
|
||||
}
|
||||
|
||||
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
|
||||
|
@ -348,7 +348,7 @@
|
||||
%ifdef WINSTRIPE_AERO
|
||||
-moz-margin-start: 30px;
|
||||
%else
|
||||
-moz-margin-start: -moz-calc(1.45em + 4px);
|
||||
-moz-margin-start: calc(1.45em + 4px);
|
||||
%endif
|
||||
padding: 0;
|
||||
border-top: 1px solid #d6e5f5;
|
||||
@ -809,7 +809,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
-moz-linear-gradient(transparent, rgba(0,0,0,.25) 30%),
|
||||
-moz-linear-gradient(transparent, rgba(0,0,0,.25) 30%);
|
||||
background-position: 1px -1px, 0 -1px, 100% -1px;
|
||||
background-size: -moz-calc(100% - 2px) 100%, 1px 100%, 1px 100%;
|
||||
background-size: calc(100% - 2px) 100%, 1px 100%, 1px 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
@ -1834,7 +1834,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
-moz-linear-gradient(-moz-dialog, -moz-dialog);
|
||||
background-origin: border-box;
|
||||
background-position: 1px 2px;
|
||||
background-size: -moz-calc(100% - 2px) -moz-calc(100% - 2px);
|
||||
background-size: calc(100% - 2px) calc(100% - 2px);
|
||||
background-repeat: no-repeat;
|
||||
margin: 0;
|
||||
padding: 2px 0 4px;
|
||||
@ -1992,7 +1992,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
min-height: -moz-calc(6.8mozmm - 7px); /* subtract borders from the desired height */
|
||||
min-height: calc(6.8mozmm - 7px); /* subtract borders from the desired height */
|
||||
}
|
||||
}
|
||||
|
||||
@ -2718,7 +2718,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
||||
|
||||
#highlighter-nodeinfobar-text {
|
||||
/* 100% - size of the buttons and margins */
|
||||
max-width: -moz-calc(100% - 2 * (26px + 6px));
|
||||
max-width: calc(100% - 2 * (26px + 6px));
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
@ -2784,7 +2784,7 @@ html|*#highlighter-nodeinfobar-pseudo-classes {
|
||||
.highlighter-nodeinfobar-arrow {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
-moz-margin-start: -moz-calc(50% - 7px);
|
||||
-moz-margin-start: calc(50% - 7px);
|
||||
transform: rotate(-45deg);
|
||||
border: 1px solid transparent;
|
||||
background-clip: padding-box;
|
||||
|
@ -106,7 +106,7 @@
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl) {
|
||||
background-position: -moz-calc(100% - 4px) 3px, top left, top left;
|
||||
background-position: calc(100% - 4px) 3px, top left, top left;
|
||||
}
|
||||
|
||||
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
|
||||
|
36
build/autoconf/ccache.m4
Normal file
36
build/autoconf/ccache.m4
Normal file
@ -0,0 +1,36 @@
|
||||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
dnl ======================================================
|
||||
dnl = Enable compiling with ccache
|
||||
dnl ======================================================
|
||||
AC_DEFUN([MOZ_CHECK_CCACHE],
|
||||
[
|
||||
MOZ_ARG_WITH_STRING(ccache,
|
||||
[ --with-ccache[=path/to/ccache]
|
||||
Enable compiling with ccache],
|
||||
CCACHE=$withval, CCACHE="no")
|
||||
|
||||
if test "$CCACHE" != "no"; then
|
||||
if test -z "$CCACHE" -o "$CCACHE" = "yes"; then
|
||||
CCACHE=
|
||||
else
|
||||
if test ! -e "$CCACHE"; then
|
||||
AC_MSG_ERROR([$CCACHE not found])
|
||||
fi
|
||||
fi
|
||||
MOZ_PATH_PROGS(CCACHE, $CCACHE ccache)
|
||||
if test -z "$CCACHE" -o "$CCACHE" = ":"; then
|
||||
AC_MSG_ERROR([ccache not found])
|
||||
elif test -x "$CCACHE"; then
|
||||
CC="$CCACHE $CC"
|
||||
CXX="$CCACHE $CXX"
|
||||
MOZ_USING_CCACHE=1
|
||||
else
|
||||
AC_MSG_ERROR([$CCACHE is not executable])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_USING_CCACHE)
|
||||
])
|
62
build/autoconf/toolchain.m4
Normal file
62
build/autoconf/toolchain.m4
Normal file
@ -0,0 +1,62 @@
|
||||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
AC_DEFUN([MOZ_TOOL_VARIABLES],
|
||||
[
|
||||
GNU_AS=
|
||||
GNU_LD=
|
||||
GNU_CC=
|
||||
GNU_CXX=
|
||||
CC_VERSION='N/A'
|
||||
CXX_VERSION='N/A'
|
||||
if test "$GCC" = "yes"; then
|
||||
GNU_CC=1
|
||||
CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
|
||||
fi
|
||||
if test "$GXX" = "yes"; then
|
||||
GNU_CXX=1
|
||||
CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
|
||||
fi
|
||||
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_AS=1
|
||||
fi
|
||||
rm -f conftest.out
|
||||
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_LD=1
|
||||
fi
|
||||
if test "$GNU_CC"; then
|
||||
if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
|
||||
GCC_USE_GNU_LD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
INTEL_CC=
|
||||
INTEL_CXX=
|
||||
if test "$GCC" = yes; then
|
||||
if test "`$CC -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
|
||||
INTEL_CC=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$GXX" = yes; then
|
||||
if test "`$CXX -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
|
||||
INTEL_CXX=1
|
||||
fi
|
||||
fi
|
||||
|
||||
CLANG_CC=
|
||||
CLANG_CXX=
|
||||
if test "$GCC" = yes; then
|
||||
if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
|
||||
CLANG_CC=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$GXX" = yes; then
|
||||
if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
|
||||
CLANG_CXX=1
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(CLANG_CXX)
|
||||
])
|
@ -18,6 +18,7 @@ import sys
|
||||
import threading
|
||||
import tempfile
|
||||
import sqlite3
|
||||
from string import Template
|
||||
|
||||
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
|
||||
sys.path.insert(0, SCRIPT_DIR)
|
||||
@ -284,6 +285,63 @@ class Automation(object):
|
||||
permDB.commit()
|
||||
cursor.close()
|
||||
|
||||
def setupTestApps(self, profileDir, apps):
|
||||
webappJSONTemplate = Template(""""$name": {
|
||||
"origin": "$origin",
|
||||
"installOrigin": "$origin",
|
||||
"receipt": null,
|
||||
"installTime": 132333986000,
|
||||
"manifestURL": "$manifestURL",
|
||||
"localId": $localId
|
||||
}""")
|
||||
|
||||
manifestTemplate = Template("""{
|
||||
"name": "$name",
|
||||
"description": "$description",
|
||||
"launch_path": "/",
|
||||
"developer": {
|
||||
"name": "Mozilla",
|
||||
"url": "https://mozilla.org/"
|
||||
},
|
||||
"permissions": [
|
||||
],
|
||||
"locales": {
|
||||
"en-US": {
|
||||
"name": "$name",
|
||||
"description": "$description"
|
||||
}
|
||||
},
|
||||
"default_locale": "en-US",
|
||||
"icons": {
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
# Create webapps/webapps.json
|
||||
webappsDir = os.path.join(profileDir, "webapps")
|
||||
os.mkdir(webappsDir);
|
||||
|
||||
webappsJSON = []
|
||||
for localId, app in enumerate(apps):
|
||||
app['localId'] = localId + 1 # Has to be 1..n
|
||||
webappsJSON.append(webappJSONTemplate.substitute(app))
|
||||
webappsJSON = '{\n' + ',\n'.join(webappsJSON) + '\n}\n'
|
||||
|
||||
webappsJSONFile = open(os.path.join(webappsDir, "webapps.json"), "a")
|
||||
webappsJSONFile.write(webappsJSON)
|
||||
webappsJSONFile.close()
|
||||
|
||||
# Create manifest file for each app.
|
||||
for app in apps:
|
||||
manifest = manifestTemplate.substitute(app)
|
||||
|
||||
manifestDir = os.path.join(webappsDir, app['name'])
|
||||
os.mkdir(manifestDir)
|
||||
|
||||
manifestFile = open(os.path.join(manifestDir, "manifest.webapp"), "a")
|
||||
manifestFile.write(manifest)
|
||||
manifestFile.close()
|
||||
|
||||
def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False):
|
||||
" Sets up the standard testing profile."
|
||||
|
||||
@ -463,6 +521,40 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
prefsFile.write("".join(prefs))
|
||||
prefsFile.close()
|
||||
|
||||
apps = [
|
||||
{
|
||||
'name': 'http_example_org',
|
||||
'origin': 'http://example.org',
|
||||
'manifestURL': 'http://example.org/manifest.webapp',
|
||||
'description': 'http://example.org App'
|
||||
},
|
||||
{
|
||||
'name': 'https_example_com',
|
||||
'origin': 'https://example.com',
|
||||
'manifestURL': 'https://example.com/manifest.webapp',
|
||||
'description': 'https://example.com App'
|
||||
},
|
||||
{
|
||||
'name': 'http_test1_example_org',
|
||||
'origin': 'http://test1.example.org',
|
||||
'manifestURL': 'http://test1.example.org/manifest.webapp',
|
||||
'description': 'http://test1.example.org App'
|
||||
},
|
||||
{
|
||||
'name': 'http_test1_example_org_8000',
|
||||
'origin': 'http://test1.example.org:8000',
|
||||
'manifestURL': 'http://test1.example.org:8000/manifest.webapp',
|
||||
'description': 'http://test1.example.org:8000 App'
|
||||
},
|
||||
{
|
||||
'name': 'http_sub1_test1_example_org',
|
||||
'origin': 'http://sub1.test1.example.org',
|
||||
'manifestURL': 'http://sub1.test1.example.org/manifest.webapp',
|
||||
'description': 'http://sub1.test1.example.org App'
|
||||
},
|
||||
];
|
||||
self.setupTestApps(profileDir, apps)
|
||||
|
||||
def addCommonOptions(self, parser):
|
||||
"Adds command-line options which are common to mochitest and reftest."
|
||||
|
||||
|
@ -1,4 +1,11 @@
|
||||
export CC=$topsrcdir/clang/bin/clang
|
||||
export CXX=$topsrcdir/clang/bin/clang++
|
||||
if [ -d "$topsrcdir/clang" ]; then
|
||||
# mozilla-central based build
|
||||
export CC=$topsrcdir/clang/bin/clang
|
||||
export CXX=$topsrcdir/clang/bin/clang++
|
||||
elif [ -d "$topsrcdir/../clang" ]; then
|
||||
# comm-central based build
|
||||
export CC=$topsrcdir/../clang/bin/clang
|
||||
export CXX=$topsrcdir/../clang/bin/clang++
|
||||
fi
|
||||
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
80
build/mobile/b2gemulator.py
Normal file
80
build/mobile/b2gemulator.py
Normal file
@ -0,0 +1,80 @@
|
||||
# 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/.
|
||||
|
||||
|
||||
import os
|
||||
import platform
|
||||
|
||||
from emulator import Emulator
|
||||
|
||||
|
||||
class B2GEmulator(Emulator):
|
||||
|
||||
def __init__(self, homedir=None, noWindow=False, logcat_dir=None, arch="x86",
|
||||
emulatorBinary=None, res='480x800', userdata=None,
|
||||
memory='512', partition_size='512'):
|
||||
super(B2GEmulator, self).__init__(noWindow=noWindow, logcat_dir=logcat_dir,
|
||||
arch=arch, emulatorBinary=emulatorBinary,
|
||||
res=res, userdata=userdata,
|
||||
memory=memory, partition_size=partition_size)
|
||||
self.homedir = homedir
|
||||
if self.homedir is not None:
|
||||
self.homedir = os.path.expanduser(homedir)
|
||||
|
||||
def _check_file(self, filePath):
|
||||
if not os.path.exists(filePath):
|
||||
raise Exception(('File not found: %s; did you pass the B2G home '
|
||||
'directory as the homedir parameter, or set '
|
||||
'B2G_HOME correctly?') % filePath)
|
||||
|
||||
def _check_for_adb(self, host_dir):
|
||||
self.adb = os.path.join(self.homedir, 'out', 'host', host_dir, 'bin', 'adb')
|
||||
if not os.path.exists(self.adb):
|
||||
self.adb = os.path.join(self.homedir, 'bin/adb')
|
||||
super(B2GEmulator, self)._check_for_adb()
|
||||
|
||||
def _locate_files(self):
|
||||
if self.homedir is None:
|
||||
self.homedir = os.getenv('B2G_HOME')
|
||||
if self.homedir is None:
|
||||
raise Exception('Must define B2G_HOME or pass the homedir parameter')
|
||||
self._check_file(self.homedir)
|
||||
|
||||
if self.arch not in ("x86", "arm"):
|
||||
raise Exception("Emulator architecture must be one of x86, arm, got: %s" %
|
||||
self.arch)
|
||||
|
||||
host_dir = "linux-x86"
|
||||
if platform.system() == "Darwin":
|
||||
host_dir = "darwin-x86"
|
||||
|
||||
host_bin_dir = os.path.join("out", "host", host_dir, "bin")
|
||||
|
||||
if self.arch == "x86":
|
||||
binary = os.path.join(host_bin_dir, "emulator-x86")
|
||||
kernel = "prebuilts/qemu-kernel/x86/kernel-qemu"
|
||||
sysdir = "out/target/product/generic_x86"
|
||||
self.tail_args = []
|
||||
else:
|
||||
binary = os.path.join(host_bin_dir, "emulator")
|
||||
kernel = "prebuilts/qemu-kernel/arm/kernel-qemu-armv7"
|
||||
sysdir = "out/target/product/generic"
|
||||
self.tail_args = ["-cpu", "cortex-a8"]
|
||||
|
||||
self._check_for_adb(host_dir)
|
||||
|
||||
if not self.binary:
|
||||
self.binary = os.path.join(self.homedir, binary)
|
||||
|
||||
self._check_file(self.binary)
|
||||
|
||||
self.kernelImg = os.path.join(self.homedir, kernel)
|
||||
self._check_file(self.kernelImg)
|
||||
|
||||
self.sysDir = os.path.join(self.homedir, sysdir)
|
||||
self._check_file(self.sysDir)
|
||||
|
||||
if not self.dataImg:
|
||||
self.dataImg = os.path.join(self.sysDir, 'userdata.img')
|
||||
self._check_file(self.dataImg)
|
295
build/mobile/emulator.py
Normal file
295
build/mobile/emulator.py
Normal file
@ -0,0 +1,295 @@
|
||||
# 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/.
|
||||
|
||||
from abc import abstractmethod
|
||||
import datetime
|
||||
from mozprocess import ProcessHandlerMixin
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import socket
|
||||
import subprocess
|
||||
from telnetlib import Telnet
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from emulator_battery import EmulatorBattery
|
||||
|
||||
|
||||
class LogcatProc(ProcessHandlerMixin):
|
||||
"""Process handler for logcat which saves all output to a logfile.
|
||||
"""
|
||||
|
||||
def __init__(self, logfile, cmd, **kwargs):
|
||||
self.logfile = logfile
|
||||
kwargs.setdefault('processOutputLine', []).append(self.log_output)
|
||||
ProcessHandlerMixin.__init__(self, cmd, **kwargs)
|
||||
|
||||
def log_output(self, line):
|
||||
f = open(self.logfile, 'a')
|
||||
f.write(line + "\n")
|
||||
f.flush()
|
||||
|
||||
|
||||
class Emulator(object):
|
||||
|
||||
deviceRe = re.compile(r"^emulator-(\d+)(\s*)(.*)$")
|
||||
|
||||
def __init__(self, noWindow=False, logcat_dir=None, arch="x86",
|
||||
emulatorBinary=None, res='480x800', userdata=None,
|
||||
memory='512', partition_size='512'):
|
||||
self.port = None
|
||||
self._emulator_launched = False
|
||||
self.proc = None
|
||||
self.local_port = None
|
||||
self.telnet = None
|
||||
self._tmp_userdata = None
|
||||
self._adb_started = False
|
||||
self.logcat_dir = logcat_dir
|
||||
self.logcat_proc = None
|
||||
self.arch = arch
|
||||
self.binary = emulatorBinary
|
||||
self.memory = str(memory)
|
||||
self.partition_size = str(partition_size)
|
||||
self.res = res
|
||||
self.battery = EmulatorBattery(self)
|
||||
self.noWindow = noWindow
|
||||
self.dataImg = userdata
|
||||
self.copy_userdata = self.dataImg is None
|
||||
|
||||
def __del__(self):
|
||||
if self.telnet:
|
||||
self.telnet.write('exit\n')
|
||||
self.telnet.read_all()
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
qemuArgs = [self.binary,
|
||||
'-kernel', self.kernelImg,
|
||||
'-sysdir', self.sysDir,
|
||||
'-data', self.dataImg]
|
||||
if self.noWindow:
|
||||
qemuArgs.append('-no-window')
|
||||
qemuArgs.extend(['-memory', self.memory,
|
||||
'-partition-size', self.partition_size,
|
||||
'-verbose',
|
||||
'-skin', self.res,
|
||||
'-gpu', 'on',
|
||||
'-qemu'] + self.tail_args)
|
||||
return qemuArgs
|
||||
|
||||
@property
|
||||
def is_running(self):
|
||||
if self._emulator_launched:
|
||||
return self.proc is not None and self.proc.poll() is None
|
||||
else:
|
||||
return self.port is not None
|
||||
|
||||
def _check_for_adb(self):
|
||||
if not os.path.exists(self.adb):
|
||||
adb = subprocess.Popen(['which', 'adb'],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
retcode = adb.wait()
|
||||
if retcode:
|
||||
raise Exception('adb not found!')
|
||||
out = adb.stdout.read().strip()
|
||||
if len(out) and out.find('/') > -1:
|
||||
self.adb = out
|
||||
|
||||
def _run_adb(self, args):
|
||||
args.insert(0, self.adb)
|
||||
adb = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
retcode = adb.wait()
|
||||
if retcode:
|
||||
raise Exception('adb terminated with exit code %d: %s'
|
||||
% (retcode, adb.stdout.read()))
|
||||
return adb.stdout.read()
|
||||
|
||||
def _get_telnet_response(self, command=None):
|
||||
output = []
|
||||
assert(self.telnet)
|
||||
if command is not None:
|
||||
self.telnet.write('%s\n' % command)
|
||||
while True:
|
||||
line = self.telnet.read_until('\n')
|
||||
output.append(line.rstrip())
|
||||
if line.startswith('OK'):
|
||||
return output
|
||||
elif line.startswith('KO:'):
|
||||
raise Exception('bad telnet response: %s' % line)
|
||||
|
||||
def _run_telnet(self, command):
|
||||
if not self.telnet:
|
||||
self.telnet = Telnet('localhost', self.port)
|
||||
self._get_telnet_response()
|
||||
return self._get_telnet_response(command)
|
||||
|
||||
def close(self):
|
||||
if self.is_running and self._emulator_launched:
|
||||
self.proc.terminate()
|
||||
self.proc.wait()
|
||||
if self._adb_started:
|
||||
self._run_adb(['kill-server'])
|
||||
self._adb_started = False
|
||||
if self.proc:
|
||||
retcode = self.proc.poll()
|
||||
self.proc = None
|
||||
if self._tmp_userdata:
|
||||
os.remove(self._tmp_userdata)
|
||||
self._tmp_userdata = None
|
||||
return retcode
|
||||
if self.logcat_proc:
|
||||
self.logcat_proc.kill()
|
||||
return 0
|
||||
|
||||
def _get_adb_devices(self):
|
||||
offline = set()
|
||||
online = set()
|
||||
output = self._run_adb(['devices'])
|
||||
for line in output.split('\n'):
|
||||
m = self.deviceRe.match(line)
|
||||
if m:
|
||||
if m.group(3) == 'offline':
|
||||
offline.add(m.group(1))
|
||||
else:
|
||||
online.add(m.group(1))
|
||||
return (online, offline)
|
||||
|
||||
def restart(self):
|
||||
if not self._emulator_launched:
|
||||
return
|
||||
self.close()
|
||||
self.start()
|
||||
|
||||
def start_adb(self):
|
||||
result = self._run_adb(['start-server'])
|
||||
# We keep track of whether we've started adb or not, so we know
|
||||
# if we need to kill it.
|
||||
if 'daemon started successfully' in result:
|
||||
self._adb_started = True
|
||||
else:
|
||||
self._adb_started = False
|
||||
|
||||
def connect(self):
|
||||
self._check_for_adb()
|
||||
self.start_adb()
|
||||
|
||||
online, offline = self._get_adb_devices()
|
||||
now = datetime.datetime.now()
|
||||
while online == set([]):
|
||||
time.sleep(1)
|
||||
if datetime.datetime.now() - now > datetime.timedelta(seconds=60):
|
||||
raise Exception('timed out waiting for emulator to be available')
|
||||
online, offline = self._get_adb_devices()
|
||||
self.port = int(list(online)[0])
|
||||
|
||||
@abstractmethod
|
||||
def _locate_files(self):
|
||||
pass
|
||||
|
||||
def start(self):
|
||||
self._locate_files()
|
||||
self.start_adb()
|
||||
|
||||
qemu_args = self.args[:]
|
||||
if self.copy_userdata:
|
||||
# Make a copy of the userdata.img for this instance of the emulator
|
||||
# to use.
|
||||
self._tmp_userdata = tempfile.mktemp(prefix='emulator')
|
||||
shutil.copyfile(self.dataImg, self._tmp_userdata)
|
||||
qemu_args[qemu_args.index('-data') + 1] = self._tmp_userdata
|
||||
|
||||
original_online, original_offline = self._get_adb_devices()
|
||||
|
||||
self.proc = subprocess.Popen(qemu_args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
online, offline = self._get_adb_devices()
|
||||
now = datetime.datetime.now()
|
||||
while online - original_online == set([]):
|
||||
time.sleep(1)
|
||||
if datetime.datetime.now() - now > datetime.timedelta(seconds=60):
|
||||
raise Exception('timed out waiting for emulator to start')
|
||||
online, offline = self._get_adb_devices()
|
||||
self.port = int(list(online - original_online)[0])
|
||||
self._emulator_launched = True
|
||||
|
||||
if self.logcat_dir:
|
||||
self.save_logcat()
|
||||
|
||||
# setup DNS fix for networking
|
||||
self._run_adb(['-s', 'emulator-%d' % self.port,
|
||||
'shell', 'setprop', 'net.dns1', '10.0.2.3'])
|
||||
|
||||
def _save_logcat_proc(self, filename, cmd):
|
||||
self.logcat_proc = LogcatProc(filename, cmd)
|
||||
self.logcat_proc.run()
|
||||
self.logcat_proc.waitForFinish()
|
||||
self.logcat_proc = None
|
||||
|
||||
def rotate_log(self, srclog, index=1):
|
||||
""" Rotate a logfile, by recursively rotating logs further in the sequence,
|
||||
deleting the last file if necessary.
|
||||
"""
|
||||
destlog = os.path.join(self.logcat_dir, 'emulator-%d.%d.log' % (self.port, index))
|
||||
if os.path.exists(destlog):
|
||||
if index == 3:
|
||||
os.remove(destlog)
|
||||
else:
|
||||
self.rotate_log(destlog, index + 1)
|
||||
shutil.move(srclog, destlog)
|
||||
|
||||
def save_logcat(self):
|
||||
""" Save the output of logcat to a file.
|
||||
"""
|
||||
filename = os.path.join(self.logcat_dir, "emulator-%d.log" % self.port)
|
||||
if os.path.exists(filename):
|
||||
self.rotate_log(filename)
|
||||
cmd = [self.adb, '-s', 'emulator-%d' % self.port, 'logcat']
|
||||
|
||||
# We do this in a separate process because we call mozprocess's
|
||||
# waitForFinish method to process logcat's output, and this method
|
||||
# blocks.
|
||||
proc = multiprocessing.Process(target=self._save_logcat_proc, args=(filename, cmd))
|
||||
proc.daemon = True
|
||||
proc.start()
|
||||
|
||||
def setup_port_forwarding(self, remote_port):
|
||||
""" Set up TCP port forwarding to the specified port on the device,
|
||||
using any availble local port, and return the local port.
|
||||
"""
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind(("", 0))
|
||||
local_port = s.getsockname()[1]
|
||||
s.close()
|
||||
|
||||
output = self._run_adb(['-s', 'emulator-%d' % self.port,
|
||||
'forward',
|
||||
'tcp:%d' % local_port,
|
||||
'tcp:%d' % remote_port])
|
||||
|
||||
self.local_port = local_port
|
||||
|
||||
return local_port
|
||||
|
||||
def wait_for_port(self, timeout=300):
|
||||
assert(self.local_port)
|
||||
starttime = datetime.datetime.now()
|
||||
while datetime.datetime.now() - starttime < datetime.timedelta(seconds=timeout):
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect(('localhost', self.local_port))
|
||||
data = sock.recv(16)
|
||||
sock.close()
|
||||
if '"from"' in data:
|
||||
return True
|
||||
except:
|
||||
import traceback
|
||||
print traceback.format_exc()
|
||||
time.sleep(1)
|
||||
return False
|
52
build/mobile/emulator_battery.py
Normal file
52
build/mobile/emulator_battery.py
Normal file
@ -0,0 +1,52 @@
|
||||
# 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/.
|
||||
|
||||
class EmulatorBattery(object):
|
||||
|
||||
def __init__(self, emulator):
|
||||
self.emulator = emulator
|
||||
|
||||
def get_state(self):
|
||||
status = {}
|
||||
state = {}
|
||||
|
||||
response = self.emulator._run_telnet('power display')
|
||||
for line in response:
|
||||
if ':' in line:
|
||||
field, value = line.split(':')
|
||||
value = value.strip()
|
||||
if value == 'true':
|
||||
value = True
|
||||
elif value == 'false':
|
||||
value = False
|
||||
elif field == 'capacity':
|
||||
value = float(value)
|
||||
status[field] = value
|
||||
|
||||
state['level'] = status.get('capacity', 0.0) / 100
|
||||
if status.get('AC') == 'online':
|
||||
state['charging'] = True
|
||||
else:
|
||||
state['charging'] = False
|
||||
|
||||
return state
|
||||
|
||||
def get_charging(self):
|
||||
return self.get_state()['charging']
|
||||
|
||||
def get_level(self):
|
||||
return self.get_state()['level']
|
||||
|
||||
def set_level(self, level):
|
||||
self.emulator._run_telnet('power capacity %d' % (level * 100))
|
||||
|
||||
def set_charging(self, charging):
|
||||
if charging:
|
||||
cmd = 'power ac on'
|
||||
else:
|
||||
cmd = 'power ac off'
|
||||
self.emulator._run_telnet(cmd)
|
||||
|
||||
charging = property(get_charging, set_charging)
|
||||
level = property(get_level, set_level)
|
@ -33,19 +33,39 @@ public class FennecTalosAssert implements Assert {
|
||||
|
||||
public void finalize() { }
|
||||
|
||||
public void ok(boolean condition, String name, String diag) { }
|
||||
public void ok(boolean condition, String name, String diag) {
|
||||
if (!condition) {
|
||||
dumpLog("__FAIL" + name + ": " + diag + "__FAIL");
|
||||
}
|
||||
}
|
||||
|
||||
public void is(Object a, Object b, String name) { }
|
||||
public void is(Object a, Object b, String name) {
|
||||
boolean pass = (a == null ? b == null : a.equals(b));
|
||||
ok(pass, name, "got " + a + ", expected " + b);
|
||||
}
|
||||
|
||||
public void isnot(Object a, Object b, String name) { }
|
||||
public void isnot(Object a, Object b, String name) {
|
||||
boolean fail = (a == null ? b == null : a.equals(b));
|
||||
ok(!fail, name, "got " + a + ", expected not " + b);
|
||||
}
|
||||
|
||||
public void ispixel(int actual, int r, int g, int b, String name) { }
|
||||
public void ispixel(int actual, int r, int g, int b, String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void todo(boolean condition, String name, String diag) { }
|
||||
public void todo(boolean condition, String name, String diag) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void todo_is(Object a, Object b, String name) { }
|
||||
public void todo_is(Object a, Object b, String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void todo_isnot(Object a, Object b, String name) { }
|
||||
public void todo_isnot(Object a, Object b, String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void info(String name, String message) { }
|
||||
public void info(String name, String message) {
|
||||
dumpLog(name + ": " + message);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ interface nsIContentSecurityPolicy;
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
|
||||
|
||||
[scriptable, uuid(42ba6a38-d619-49ab-8248-3d247e959d5e)]
|
||||
[scriptable, uuid(fbb93cc7-9a94-4743-8e89-9e6939cac083)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
@ -212,6 +212,39 @@ interface nsIPrincipal : nsISerializable
|
||||
* A Content Security Policy associated with this principal.
|
||||
*/
|
||||
[noscript] attribute nsIContentSecurityPolicy csp;
|
||||
|
||||
/**
|
||||
* Returns the extended origin of the principal.
|
||||
* The extended origin is a string that has more information than the origin
|
||||
* and can be used to isolate data or permissions between different
|
||||
* principals while taking into account parameters like the app id or the
|
||||
* fact that the principal is embedded in a mozbrowser.
|
||||
* Some principals will return the origin for extendedOrigin.
|
||||
* Some principals will assert if you try to access the extendedOrigin.
|
||||
*
|
||||
* The extendedOrigin is intended to be an opaque identifier. It is
|
||||
* currently "human-readable" but no callers should assume it will stay
|
||||
* as is and it might be crypto-hashed at some point.
|
||||
*/
|
||||
readonly attribute AUTF8String extendedOrigin;
|
||||
|
||||
const short APP_STATUS_NOT_INSTALLED = 0;
|
||||
const short APP_STATUS_INSTALLED = 1;
|
||||
const short APP_STATUS_TRUSTED = 2;
|
||||
const short APP_STATUS_CERTIFIED = 3;
|
||||
|
||||
/**
|
||||
* Shows the status of the app.
|
||||
* Can be: APP_STATUS_NOT_INSTALLED, APP_STATUS_INSTALLED,
|
||||
* APP_STATUS_TRUSTED or APP_STATUS_CERTIFIED.
|
||||
*/
|
||||
readonly attribute unsigned short appStatus;
|
||||
|
||||
/**
|
||||
* Returns the app id the principal is in.
|
||||
* Returns nsIAppsService::NO_APP_ID if this principal isn't part of an app.
|
||||
*/
|
||||
readonly attribute unsigned long appId;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -234,4 +267,4 @@ interface nsIExpandedPrincipal : nsISupports
|
||||
* should not be changed and should only be used ephemerally.
|
||||
*/
|
||||
[notxpcom] readonly attribute PrincipalArray whiteList;
|
||||
};
|
||||
};
|
||||
|
@ -8,8 +8,9 @@
|
||||
#include "nsIXPCSecurityManager.idl"
|
||||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
interface nsIDocShell;
|
||||
|
||||
[scriptable, uuid(cdb27711-492b-4973-938b-de81ac124658)]
|
||||
[scriptable, uuid(75a7afe3-d7c9-46fe-b305-ae686457bc7f)]
|
||||
interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
{
|
||||
///////////////// Security Checks //////////////////
|
||||
@ -84,21 +85,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
in nsIURI uri,
|
||||
in unsigned long flags);
|
||||
|
||||
/**
|
||||
* Check that content from "from" can load "uri".
|
||||
*
|
||||
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
|
||||
* should be denied.
|
||||
*
|
||||
* @param from the URI causing the load
|
||||
* @param uri the URI that is being loaded
|
||||
* @param flags the permission set, see above
|
||||
*
|
||||
* @deprecated Use checkLoadURIWithPrincipal instead of this function.
|
||||
*/
|
||||
[deprecated] void checkLoadURI(in nsIURI from, in nsIURI uri,
|
||||
in unsigned long flags);
|
||||
|
||||
/**
|
||||
* Similar to checkLoadURIWithPrincipal but there are two differences:
|
||||
*
|
||||
@ -112,15 +98,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
in AUTF8String uri,
|
||||
in unsigned long flags);
|
||||
|
||||
/**
|
||||
* Same as CheckLoadURI but takes string arguments for ease of use
|
||||
* by scripts
|
||||
*
|
||||
* @deprecated Use checkLoadURIStrWithPrincipal instead of this function.
|
||||
*/
|
||||
[deprecated] void checkLoadURIStr(in AUTF8String from, in AUTF8String uri,
|
||||
in unsigned long flags);
|
||||
|
||||
/**
|
||||
* Check that the function 'funObj' is allowed to run on 'targetObj'
|
||||
*
|
||||
@ -171,9 +148,36 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
|
||||
/**
|
||||
* Return a principal that has the same origin as aURI.
|
||||
* This principals should not be used for any data/permission check, it will
|
||||
* have appId = UNKNOWN_APP_ID.
|
||||
*/
|
||||
nsIPrincipal getCodebasePrincipal(in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* Returns a principal that has the given information.
|
||||
* @param appId is the app id of the principal. It can't be UNKNOWN_APP_ID.
|
||||
* @param inMozBrowser is true if the principal has to be considered as
|
||||
* inside a mozbrowser frame.
|
||||
*/
|
||||
nsIPrincipal getAppCodebasePrincipal(in nsIURI uri,
|
||||
in unsigned long appId,
|
||||
in boolean inMozBrowser);
|
||||
|
||||
/**
|
||||
* Returns a principal that has the appId and inMozBrowser of the docshell
|
||||
* inside a mozbrowser frame.
|
||||
* @param docShell to get appId/inMozBrowser from.
|
||||
*/
|
||||
nsIPrincipal getDocShellCodebasePrincipal(in nsIURI uri,
|
||||
in nsIDocShell docShell);
|
||||
|
||||
/**
|
||||
* Returns a principal with that has the same origin as uri and is not part
|
||||
* of an appliction.
|
||||
* The returned principal will have appId = NO_APP_ID.
|
||||
*/
|
||||
nsIPrincipal getNoAppCodebasePrincipal(in nsIURI uri);
|
||||
|
||||
///////////////// Capabilities API /////////////////////
|
||||
/**
|
||||
* Request that 'capability' can be enabled by scripts or applets
|
||||
@ -260,6 +264,19 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
[noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
|
||||
[noscript,notxpcom] nsIPrincipal getCxSubjectPrincipalAndFrame(in JSContextPtr cx,
|
||||
out JSStackFramePtr fp);
|
||||
|
||||
|
||||
const unsigned long NO_APP_ID = 0;
|
||||
const unsigned long UNKNOWN_APP_ID = 4294967295; // PR_UINT32_MAX
|
||||
|
||||
/**
|
||||
* Returns the extended origin for the uri.
|
||||
* appId can be NO_APP_ID or a valid app id. appId should not be
|
||||
* UNKNOWN_APP_ID.
|
||||
* inMozBrowser has to be true if the uri is inside a mozbrowser iframe.
|
||||
*/
|
||||
AUTF8String getExtendedOrigin(in nsIURI uri, in unsigned long appId,
|
||||
in boolean inMozBrowser);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -111,12 +111,6 @@ protected:
|
||||
|
||||
class nsPrincipal : public nsBasePrincipal
|
||||
{
|
||||
public:
|
||||
nsPrincipal();
|
||||
|
||||
protected:
|
||||
virtual ~nsPrincipal();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
@ -130,16 +124,24 @@ public:
|
||||
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
|
||||
NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
|
||||
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
|
||||
NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
|
||||
NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
|
||||
NS_IMETHOD GetAppId(PRUint32* aAppStatus);
|
||||
#ifdef DEBUG
|
||||
virtual void dumpImpl();
|
||||
#endif
|
||||
|
||||
nsPrincipal();
|
||||
|
||||
// Either Init() or InitFromPersistent() must be called before
|
||||
// the principal is in a usable state.
|
||||
nsresult Init(const nsACString& aCertFingerprint,
|
||||
const nsACString& aSubjectName,
|
||||
const nsACString& aPrettyName,
|
||||
nsISupports* aCert,
|
||||
nsIURI* aCodebase);
|
||||
nsIURI* aCodebase,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser);
|
||||
nsresult InitFromPersistent(const char* aPrefName,
|
||||
const nsCString& aFingerprint,
|
||||
const nsCString& aSubjectName,
|
||||
@ -148,17 +150,34 @@ public:
|
||||
const char* aDeniedList,
|
||||
nsISupports* aCert,
|
||||
bool aIsCert,
|
||||
bool aTrusted);
|
||||
bool aTrusted,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser);
|
||||
|
||||
virtual void GetScriptLocation(nsACString& aStr) MOZ_OVERRIDE;
|
||||
void SetURI(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Computes the puny-encoded origin of aURI.
|
||||
*/
|
||||
static nsresult GetOriginForURI(nsIURI* aURI, char **aOrigin);
|
||||
|
||||
nsCOMPtr<nsIURI> mDomain;
|
||||
nsCOMPtr<nsIURI> mCodebase;
|
||||
PRUint32 mAppId;
|
||||
bool mInMozBrowser;
|
||||
// If mCodebaseImmutable is true, mCodebase is non-null and immutable
|
||||
bool mCodebaseImmutable;
|
||||
bool mDomainImmutable;
|
||||
bool mInitialized;
|
||||
|
||||
protected:
|
||||
virtual ~nsPrincipal();
|
||||
|
||||
/**
|
||||
* Returns the app status of the principal based on mAppId and mInMozBrowser.
|
||||
*/
|
||||
PRUint16 GetAppStatus();
|
||||
};
|
||||
|
||||
class nsExpandedPrincipal : public nsIExpandedPrincipal, public nsBasePrincipal
|
||||
@ -183,6 +202,9 @@ public:
|
||||
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
|
||||
NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
|
||||
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
|
||||
NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
|
||||
NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
|
||||
NS_IMETHOD GetAppId(PRUint32* aAppStatus);
|
||||
#ifdef DEBUG
|
||||
virtual void dumpImpl();
|
||||
#endif
|
||||
|
@ -436,7 +436,12 @@ private:
|
||||
SecurityLevel* result);
|
||||
|
||||
nsresult
|
||||
CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result);
|
||||
GetCodebasePrincipalInternal(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
|
||||
nsIPrincipal** result);
|
||||
|
||||
nsresult
|
||||
CreateCodebasePrincipal(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
|
||||
nsIPrincipal** result);
|
||||
|
||||
// This is just like the API method, but it doesn't check that the subject
|
||||
// name is non-empty or aCertificate is non-null, and it doesn't change the
|
||||
@ -596,4 +601,13 @@ public:
|
||||
NS_IMETHOD InitializeNameSet(nsIScriptContext* aScriptContext);
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
GetExtendedOrigin(nsIURI* aURI, PRUint32 aAppid,
|
||||
bool aInMozBrowser,
|
||||
nsACString& aExtendedOrigin);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // nsScriptSecurityManager_h__
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -314,6 +315,26 @@ nsNullPrincipal::GetCertificate(nsISupports** aCertificate)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
|
||||
{
|
||||
return GetOrigin(getter_Copies(aExtendedOrigin));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetAppStatus(PRUint16* aAppStatus)
|
||||
{
|
||||
*aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetAppId(PRUint32* aAppId)
|
||||
{
|
||||
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* nsISerializable implementation
|
||||
*/
|
||||
|
@ -601,7 +601,7 @@ void nsPrincipal::dumpImpl()
|
||||
{
|
||||
nsCAutoString str;
|
||||
GetScriptLocation(str);
|
||||
fprintf(stderr, "nsPrincipal (%p) = %s\n", this, str.get());
|
||||
fprintf(stderr, "nsPrincipal (%p) = %s\n", static_cast<void*>(this), str.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -617,7 +617,9 @@ NS_IMPL_ADDREF_INHERITED(nsPrincipal, nsBasePrincipal)
|
||||
NS_IMPL_RELEASE_INHERITED(nsPrincipal, nsBasePrincipal)
|
||||
|
||||
nsPrincipal::nsPrincipal()
|
||||
: mCodebaseImmutable(false)
|
||||
: mAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
|
||||
, mInMozBrowser(false)
|
||||
, mCodebaseImmutable(false)
|
||||
, mDomainImmutable(false)
|
||||
, mInitialized(false)
|
||||
{ }
|
||||
@ -630,7 +632,9 @@ nsPrincipal::Init(const nsACString& aCertFingerprint,
|
||||
const nsACString& aSubjectName,
|
||||
const nsACString& aPrettyName,
|
||||
nsISupports* aCert,
|
||||
nsIURI *aCodebase)
|
||||
nsIURI *aCodebase,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser)
|
||||
{
|
||||
NS_ENSURE_STATE(!mInitialized);
|
||||
NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() || aCodebase); // better have one of these.
|
||||
@ -640,6 +644,9 @@ nsPrincipal::Init(const nsACString& aCertFingerprint,
|
||||
mCodebase = NS_TryToMakeImmutable(aCodebase);
|
||||
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
||||
|
||||
mAppId = aAppId;
|
||||
mInMozBrowser = aInMozBrowser;
|
||||
|
||||
if (aCertFingerprint.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
@ -656,18 +663,17 @@ nsPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetOrigin(char **aOrigin)
|
||||
/* static */ nsresult
|
||||
nsPrincipal::GetOriginForURI(nsIURI* aURI, char **aOrigin)
|
||||
{
|
||||
if (!aURI) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aOrigin = nsnull;
|
||||
|
||||
nsCOMPtr<nsIURI> origin;
|
||||
if (mCodebase) {
|
||||
origin = NS_GetInnermostURI(mCodebase);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI);
|
||||
if (!origin) {
|
||||
NS_ASSERTION(mCert, "No Domain or Codebase for a non-cert principal");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -683,8 +689,9 @@ nsPrincipal::GetOrigin(char **aOrigin)
|
||||
rv = origin->GetAsciiHost(hostPort);
|
||||
// Some implementations return an empty string, treat it as no support
|
||||
// for asciiHost by that implementation.
|
||||
if (hostPort.IsEmpty())
|
||||
if (hostPort.IsEmpty()) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 port;
|
||||
@ -701,6 +708,7 @@ nsPrincipal::GetOrigin(char **aOrigin)
|
||||
nsCAutoString scheme;
|
||||
rv = origin->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
|
||||
}
|
||||
else {
|
||||
@ -711,12 +719,19 @@ nsPrincipal::GetOrigin(char **aOrigin)
|
||||
// both fall back to GetSpec. That needs to be fixed.
|
||||
rv = origin->GetAsciiSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aOrigin = ToNewCString(spec);
|
||||
}
|
||||
|
||||
return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetOrigin(char **aOrigin)
|
||||
{
|
||||
return GetOriginForURI(mCodebase, aOrigin);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
|
||||
{
|
||||
@ -922,8 +937,6 @@ nsPrincipal::SetURI(nsIURI* aURI)
|
||||
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetHashValue(PRUint32* aValue)
|
||||
{
|
||||
@ -989,7 +1002,9 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
|
||||
const char* aDeniedList,
|
||||
nsISupports* aCert,
|
||||
bool aIsCert,
|
||||
bool aTrusted)
|
||||
bool aTrusted,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser)
|
||||
{
|
||||
NS_PRECONDITION(!mCapabilities || mCapabilities->Count() == 0,
|
||||
"mCapabilities was already initialized?");
|
||||
@ -999,6 +1014,9 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
|
||||
|
||||
mInitialized = true;
|
||||
|
||||
mAppId = aAppId;
|
||||
mInMozBrowser = aInMozBrowser;
|
||||
|
||||
nsresult rv;
|
||||
if (aIsCert) {
|
||||
rv = SetCertificate(aToken, aSubjectName, aPrettyName, aCert);
|
||||
@ -1044,6 +1062,37 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
|
||||
{
|
||||
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
mozilla::GetExtendedOrigin(mCodebase, mAppId, mInMozBrowser, aExtendedOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetAppStatus(PRUint16* aAppStatus)
|
||||
{
|
||||
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
*aAppStatus = GetAppStatus();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetAppId(PRUint32* aAppId)
|
||||
{
|
||||
if (mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
MOZ_ASSERT(false);
|
||||
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aAppId = mAppId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
@ -1110,7 +1159,15 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Init(fingerprint, subjectName, prettyName, cert, codebase);
|
||||
PRUint32 appId;
|
||||
rv = aStream->Read32(&appId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool inMozBrowser;
|
||||
rv = aStream->ReadBoolean(&inMozBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = Init(fingerprint, subjectName, prettyName, cert, codebase, appId, inMozBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> domain;
|
||||
@ -1206,6 +1263,9 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
aStream->Write32(mAppId);
|
||||
aStream->WriteBoolean(mInMozBrowser);
|
||||
|
||||
rv = aStream->Write8(mTrusted);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
@ -1217,6 +1277,18 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint16
|
||||
nsPrincipal::GetAppStatus()
|
||||
{
|
||||
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
// Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
|
||||
// and they are not inside a mozbrowser.
|
||||
return mAppId != nsIScriptSecurityManager::NO_APP_ID &&
|
||||
mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID && !mInMozBrowser
|
||||
? nsIPrincipal::APP_STATUS_INSTALLED
|
||||
: nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
@ -1386,6 +1458,24 @@ nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetAppStatus(PRUint16* aAppStatus)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetAppId(PRUint32* aAppId)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
void
|
||||
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
||||
{
|
||||
@ -1400,7 +1490,7 @@ nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
||||
#ifdef DEBUG
|
||||
void nsExpandedPrincipal::dumpImpl()
|
||||
{
|
||||
fprintf(stderr, "nsExpandedPrincipal (%p)\n", this);
|
||||
fprintf(stderr, "nsExpandedPrincipal (%p)\n", static_cast<void*>(this));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -328,7 +328,19 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel,
|
||||
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return GetCodebasePrincipal(uri, aPrincipal);
|
||||
PRUint32 appId = UNKNOWN_APP_ID;
|
||||
bool isInBrowserElement = false;
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
NS_QueryNotificationCallbacks(aChannel, docShell);
|
||||
|
||||
if (docShell) {
|
||||
docShell->GetAppId(&appId);
|
||||
docShell->GetIsInBrowserElement(&isInBrowserElement);
|
||||
}
|
||||
|
||||
return GetCodebasePrincipalInternal(uri, appId, isInBrowserElement,
|
||||
aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1262,25 +1274,6 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI)
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
// FIXME: bug 327244 -- this function should really die... Really truly.
|
||||
NS_PRECONDITION(aSourceURI, "CheckLoadURI called with null source URI");
|
||||
NS_ENSURE_ARG_POINTER(aSourceURI);
|
||||
|
||||
// Note: this is not _quite_ right if aSourceURI has
|
||||
// NS_NULLPRINCIPAL_SCHEME, but we'll just extract the scheme in
|
||||
// CheckLoadURIWithPrincipal anyway, so this is good enough. This method
|
||||
// really needs to go away....
|
||||
nsCOMPtr<nsIPrincipal> sourcePrincipal;
|
||||
nsresult rv = CreateCodebasePrincipal(aSourceURI,
|
||||
getter_AddRefs(sourcePrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return CheckLoadURIWithPrincipal(sourcePrincipal, aTargetURI, aFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to handle cases where a flag passed to
|
||||
* CheckLoadURIWithPrincipal means denying loading if the given URI has certain
|
||||
@ -1587,30 +1580,6 @@ nsScriptSecurityManager::ReportError(JSContext* cx, const nsAString& messageTag,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckLoadURIStr(const nsACString& aSourceURIStr,
|
||||
const nsACString& aTargetURIStr,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
// FIXME: bug 327244 -- this function should really die... Really truly.
|
||||
nsCOMPtr<nsIURI> source;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(source), aSourceURIStr,
|
||||
nsnull, nsnull, sIOService);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Note: this is not _quite_ right if aSourceURI has
|
||||
// NS_NULLPRINCIPAL_SCHEME, but we'll just extract the scheme in
|
||||
// CheckLoadURIWithPrincipal anyway, so this is good enough. This method
|
||||
// really needs to go away....
|
||||
nsCOMPtr<nsIPrincipal> sourcePrincipal;
|
||||
rv = CreateCodebasePrincipal(source,
|
||||
getter_AddRefs(sourcePrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CheckLoadURIStrWithPrincipal(sourcePrincipal, aTargetURIStr,
|
||||
aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckLoadURIStrWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aTargetURIStr,
|
||||
@ -1906,7 +1875,8 @@ nsScriptSecurityManager::DoGetCertificatePrincipal(const nsACString& aCertFinger
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = certificate->Init(aCertFingerprint, aSubjectName,
|
||||
aPrettyName, aCertificate, aURI);
|
||||
aPrettyName, aCertificate, aURI,
|
||||
UNKNOWN_APP_ID, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Check to see if we already have this principal.
|
||||
@ -1967,7 +1937,8 @@ nsScriptSecurityManager::DoGetCertificatePrincipal(const nsACString& aCertFinger
|
||||
subjectName, aPrettyName,
|
||||
granted, denied,
|
||||
aCertificate,
|
||||
true, false);
|
||||
true, false,
|
||||
UNKNOWN_APP_ID, false);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -1982,7 +1953,9 @@ nsScriptSecurityManager::DoGetCertificatePrincipal(const nsACString& aCertFinger
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **result)
|
||||
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, PRUint32 aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
// I _think_ it's safe to not create null principals here based on aURI.
|
||||
// At least all the callers would do the right thing in those cases, as far
|
||||
@ -2006,7 +1979,8 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **re
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = codebase->Init(EmptyCString(), EmptyCString(),
|
||||
EmptyCString(), nsnull, aURI);
|
||||
EmptyCString(), nsnull, aURI, aAppId,
|
||||
aInMozBrowser);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -2016,11 +1990,57 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **re
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
|
||||
nsScriptSecurityManager::GetCodebasePrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
return GetCodebasePrincipalInternal(aURI, nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
false, aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetNoAppCodebasePrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
return GetCodebasePrincipalInternal(aURI, nsIScriptSecurityManager::NO_APP_ID,
|
||||
false, aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
return GetCodebasePrincipalInternal(aURI, aAppId, aInMozBrowser, aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
|
||||
nsIDocShell* aDocShell,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aDocShell);
|
||||
|
||||
PRUint32 appId;
|
||||
bool isInBrowserElement;
|
||||
aDocShell->GetAppId(&appId);
|
||||
aDocShell->GetIsInBrowserElement(&isInBrowserElement);
|
||||
|
||||
return GetCodebasePrincipalInternal(aURI, appId, isInBrowserElement,
|
||||
aPrincipal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::GetCodebasePrincipalInternal(nsIURI *aURI,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
NS_ENSURE_ARG(aURI);
|
||||
|
||||
|
||||
bool inheritsPrincipal;
|
||||
nsresult rv =
|
||||
NS_URIChainHasFlags(aURI,
|
||||
@ -2029,10 +2049,11 @@ nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
|
||||
if (NS_FAILED(rv) || inheritsPrincipal) {
|
||||
return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result);
|
||||
}
|
||||
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = CreateCodebasePrincipal(aURI, getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = CreateCodebasePrincipal(aURI, aAppId, aInMozBrowser,
|
||||
getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mPrincipals.Count() > 0)
|
||||
{
|
||||
@ -2067,10 +2088,11 @@ nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
|
||||
subjectName, EmptyCString(),
|
||||
granted, denied,
|
||||
nsnull, false,
|
||||
isTrusted);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
isTrusted,
|
||||
aAppId,
|
||||
aInMozBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
codebase->SetURI(aURI);
|
||||
principal = codebase;
|
||||
}
|
||||
@ -3536,7 +3558,8 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
|
||||
rv = newPrincipal->InitFromPersistent(aPrefNames[c], id, subjectName,
|
||||
EmptyCString(),
|
||||
grantedList, deniedList, nsnull,
|
||||
isCert, isTrusted);
|
||||
isCert, isTrusted, UNKNOWN_APP_ID,
|
||||
false);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mPrincipals.Put(newPrincipal, newPrincipal);
|
||||
}
|
||||
@ -3594,6 +3617,51 @@ nsScriptSecurityManager::InitPrefs()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
GetExtendedOrigin(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
|
||||
nsACString& aExtendedOrigin)
|
||||
{
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
if (aAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
}
|
||||
|
||||
nsCAutoString origin;
|
||||
nsPrincipal::GetOriginForURI(aURI, getter_Copies(origin));
|
||||
|
||||
// Fallback.
|
||||
if (aAppId == nsIScriptSecurityManager::NO_APP_ID && !aInMozBrowser) {
|
||||
aExtendedOrigin.Assign(origin);
|
||||
return;
|
||||
}
|
||||
|
||||
// aExtendedOrigin = origin + "@" + aAppId + { 't', 'f' }
|
||||
aExtendedOrigin.Assign(origin + NS_LITERAL_CSTRING("@"));
|
||||
aExtendedOrigin.AppendInt(aAppId);
|
||||
aExtendedOrigin.Append(aInMozBrowser ? NS_LITERAL_CSTRING("t")
|
||||
: NS_LITERAL_CSTRING("f"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetExtendedOrigin(nsIURI* aURI,
|
||||
PRUint32 aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsACString& aExtendedOrigin)
|
||||
{
|
||||
MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
mozilla::GetExtendedOrigin(aURI, aAppId, aInMozBrowser, aExtendedOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The following code prints the contents of the policy DB to the console.
|
||||
#ifdef DEBUG_CAPS_HACKER
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
NS_IMPL_CLASSINFO(nsSystemPrincipal, NULL,
|
||||
nsIClassInfo::SINGLETON | nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
@ -237,6 +238,25 @@ nsSystemPrincipal::SetSecurityPolicy(void* aSecurityPolicy)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
|
||||
{
|
||||
return GetOrigin(getter_Copies(aExtendedOrigin));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetAppStatus(PRUint16* aAppStatus)
|
||||
{
|
||||
*aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetAppId(PRUint32* aAppId)
|
||||
{
|
||||
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Methods implementing nsISerializable //
|
||||
|
@ -18,6 +18,10 @@ MOCHITEST_FILES = test_bug423375.html \
|
||||
test_disallowInheritPrincipal.html \
|
||||
$(NULL)
|
||||
|
||||
# Temporarily disabled for orange
|
||||
# MOCHITEST_CHROME_FILES = test_principal_extendedorigin_appid_appstatus.html \
|
||||
# $(NULL)
|
||||
|
||||
test_bug292789.html : % : %.in
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
|
||||
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
|
||||
|
@ -0,0 +1,241 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=758258
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for nsIPrincipal extendedOrigin, appStatus and appId</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=758258">Mozilla Bug 758258</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 758258 **/
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/*
|
||||
* gData is an array of objects. Each object represents a test case.
|
||||
* - app: gives the app manifest URL, will set mozapp to it on the iframe;
|
||||
* - origin: gives the origin of the iframe. This is the URL thas is going to
|
||||
* to be passed as iframe.src but also the expected principal's
|
||||
* origin.
|
||||
* - isapp: tells if the iframe is really a mozapp. If the manifest url isn't
|
||||
* valid, the iframe will not be considered as a mozapp.
|
||||
* - browser: say if the iframe should be a mozbrowser. This is implicit when
|
||||
* app is set.
|
||||
* - test: an array of tests to run for this test case:
|
||||
* - eo-unique: the extendedOrigin of the prinicpal must be unique in the
|
||||
* current list.
|
||||
* - eo-as-last: the extendedOrigin of the principal must be the same as the
|
||||
* last added to the list.
|
||||
*/
|
||||
var gData = [
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "https://example.com/manifest.webapp",
|
||||
src: "https://example.com/",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "http://test1.example.org/manifest.webapp",
|
||||
src: "http://test1.example.org/",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "http://test1.example.org:8000/manifest.webapp",
|
||||
src: "http://test1.example.org:8000/",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "http://sub1.test1.example.org/manifest.webapp",
|
||||
src: "http://sub1.test1.example.org/",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
// WebApps implementation doesn't allow apps with the same origin. Sad...
|
||||
// {
|
||||
// app: "http://example.org/foo/manifest.webapp",
|
||||
// src: "http://example.org/",
|
||||
// isapp: true,
|
||||
// test: [ "eo-unique" ],
|
||||
// },
|
||||
// {
|
||||
// app: "http://example.org/bar/manifest.webapp",
|
||||
// src: "http://example.org/",
|
||||
// isapp: true,
|
||||
// test: [ "eo-unique" ],
|
||||
// },
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
browser: true,
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "http://example.org/wedonthaveanyappinthatdirectory/manifest.webapp",
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
// TODO: this is a browser because we need apps to be browser and it's not
|
||||
// an app because the manifest is invalid. Ideally, it should not be a
|
||||
// browser.
|
||||
browser: true,
|
||||
test: [ "eo-as-last" ],
|
||||
},
|
||||
/*
|
||||
// {
|
||||
// app: "http://example.org/manifest.webapp",
|
||||
// src: "data:text/html,foobar",
|
||||
// test: [ "todo-src" ],
|
||||
// },
|
||||
// {
|
||||
// app: "http://example.org/manifest.webapp",
|
||||
// src: "data:text/html,foobar2",
|
||||
// test: [ "todo-src" ],
|
||||
// },
|
||||
*/
|
||||
{
|
||||
src: "file:///",
|
||||
isapp: false,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
src: "file:///tmp",
|
||||
isapp: false,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "file:///",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "file:///tmp",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
];
|
||||
|
||||
// The list of all data ids generated by this test.
|
||||
var eoList = [];
|
||||
|
||||
var content = document.getElementById('content');
|
||||
var checkedCount = 0;
|
||||
var checksTodo = gData.length;
|
||||
|
||||
function checkPrincipalForIFrame(aFrame, data) {
|
||||
var principal = aFrame.contentDocument.nodePrincipal;
|
||||
|
||||
if (!data.test) {
|
||||
data.test = [];
|
||||
}
|
||||
|
||||
// Temporarily disable that check.
|
||||
// is(principal.URI.spec, data.src,
|
||||
// 'the correct URL should have been loaded');
|
||||
|
||||
if (data.isapp) {
|
||||
is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED,
|
||||
'this should be an installed app');
|
||||
isnot(principal.appId, Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
"installed app should have a valid appId");
|
||||
isnot(principal.appId, Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID,
|
||||
"installed app should have a valid appId");
|
||||
} else {
|
||||
is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED,
|
||||
'this should not be an installed app');
|
||||
is(principal.appId, Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
"principals from non-installed app should have NO_APP_ID");
|
||||
}
|
||||
|
||||
if (!data.isapp && !data.browser) {
|
||||
is(principal.extendedOrigin, principal.origin,
|
||||
'extendedOrigin should return the origin for non-app and non-browsers principals');
|
||||
} else {
|
||||
isnot(principal.extendedOrigin, principal.origin,
|
||||
'extendedOrigin should not return the origin for apps or mozbrowsers');
|
||||
}
|
||||
|
||||
if (data.test.indexOf("eo-unique") != -1) {
|
||||
is(eoList.indexOf(principal.extendedOrigin), -1,
|
||||
"extendedOrigin should be unique");
|
||||
}
|
||||
if (data.test.indexOf("eo-as-last") != -1) {
|
||||
is(principal.extendedOrigin, eoList[eoList.length-1],
|
||||
"extendedOrigin should be the same as the last inserted one");
|
||||
}
|
||||
|
||||
eoList.push(principal.extendedOrigin);
|
||||
|
||||
checkedCount++;
|
||||
if (checkedCount == checksTodo) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
is('appStatus' in document.nodePrincipal, true,
|
||||
'appStatus should be present in nsIPrincipal');
|
||||
is('extendedOrigin' in document.nodePrincipal, true,
|
||||
'extendedOrigin should be present in nsIPrincipal');
|
||||
is('appId' in document.nodePrincipal, true,
|
||||
'appId should be present in nsIPrincipal');
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true]]}, function() {
|
||||
|
||||
// For some unknown reasons, this test this to always timeout on Windows.
|
||||
if (navigator.platform.indexOf("Win") != -1) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
gData.forEach(function(data) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.checkPrincipal = function() {
|
||||
checkPrincipalForIFrame(this, data);
|
||||
};
|
||||
|
||||
if (data.app) {
|
||||
iframe.setAttribute('mozapp', data.app);
|
||||
iframe.setAttribute('mozbrowser', '');
|
||||
} else if (data.browser) {
|
||||
iframe.setAttribute('mozbrowser', '');
|
||||
}
|
||||
|
||||
iframe.src = data.src;
|
||||
|
||||
iframe.addEventListener('load', iframe.checkPrincipal.bind(iframe));
|
||||
|
||||
content.appendChild(iframe);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -84,6 +84,8 @@ MOZ_ETW = @MOZ_ETW@
|
||||
MOZ_TRACE_JSCALLS = @MOZ_TRACE_JSCALLS@
|
||||
DEHYDRA_PATH = @DEHYDRA_PATH@
|
||||
|
||||
MOZ_USING_CCACHE = @MOZ_USING_CCACHE@
|
||||
CLANG_CXX = @CLANG_CXX@
|
||||
MOZ_LINKER = @MOZ_LINKER@
|
||||
MOZ_OLD_LINKER = @MOZ_OLD_LINKER@
|
||||
MOZ_ENABLE_SZIP = @MOZ_ENABLE_SZIP@
|
||||
|
@ -562,6 +562,13 @@ ifdef MACOSX_DEPLOYMENT_TARGET
|
||||
export MACOSX_DEPLOYMENT_TARGET
|
||||
PBBUILD_SETTINGS += MACOSX_DEPLOYMENT_TARGET="$(MACOSX_DEPLOYMENT_TARGET)"
|
||||
endif # MACOSX_DEPLOYMENT_TARGET
|
||||
|
||||
ifdef MOZ_USING_CCACHE
|
||||
ifdef CLANG_CXX
|
||||
export CCACHE_CPP2=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_OPTIMIZE
|
||||
ifeq (2,$(MOZ_OPTIMIZE))
|
||||
# Only override project defaults if the config specified explicit settings
|
||||
|
@ -15,7 +15,7 @@ endif
|
||||
|
||||
define mochitest-libs-rule-template
|
||||
libs:: $$($(1))
|
||||
$$(INSTALL) $$(foreach f,$$^,"$$(f)") $$(call mochitestdir,$(2))
|
||||
$$(call install_cmd,$$(foreach f,$$^,"$$(f)") $$(call mochitestdir,$(2)))
|
||||
endef
|
||||
|
||||
# Provide support for modules with such a large number of tests that
|
||||
|
96
configure.in
96
configure.in
@ -363,60 +363,7 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
GNU_AS=
|
||||
GNU_LD=
|
||||
GNU_CC=
|
||||
GNU_CXX=
|
||||
CC_VERSION='N/A'
|
||||
CXX_VERSION='N/A'
|
||||
if test "$GCC" = "yes"; then
|
||||
GNU_CC=1
|
||||
CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
|
||||
fi
|
||||
if test "$GXX" = "yes"; then
|
||||
GNU_CXX=1
|
||||
CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
|
||||
fi
|
||||
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_AS=1
|
||||
fi
|
||||
rm -f conftest.out
|
||||
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_LD=1
|
||||
fi
|
||||
if test "$GNU_CC"; then
|
||||
if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
|
||||
GCC_USE_GNU_LD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
INTEL_CC=
|
||||
INTEL_CXX=
|
||||
if test "$GCC" = yes; then
|
||||
if test "`$CC -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
|
||||
INTEL_CC=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$GXX" = yes; then
|
||||
if test "`$CXX -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
|
||||
INTEL_CXX=1
|
||||
fi
|
||||
fi
|
||||
|
||||
CLANG_CC=
|
||||
CLANG_CXX=
|
||||
if test "$GCC" = yes; then
|
||||
if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
|
||||
CLANG_CC=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$GXX" = yes; then
|
||||
if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
|
||||
CLANG_CXX=1
|
||||
fi
|
||||
fi
|
||||
MOZ_TOOL_VARIABLES
|
||||
|
||||
dnl ========================================================
|
||||
dnl Special win32 checks
|
||||
@ -7167,32 +7114,7 @@ if test -n "$JS_CRASH_DIAGNOSTICS"; then
|
||||
AC_DEFINE(JS_CRASH_DIAGNOSTICS)
|
||||
fi
|
||||
|
||||
dnl ======================================================
|
||||
dnl = Enable compiling with ccache
|
||||
dnl ======================================================
|
||||
MOZ_ARG_WITH_STRING(ccache,
|
||||
[ --with-ccache[=path/to/ccache]
|
||||
Enable compiling with ccache],
|
||||
CCACHE=$withval, CCACHE="no")
|
||||
|
||||
if test "$CCACHE" != "no"; then
|
||||
if test -z "$CCACHE" -o "$CCACHE" = "yes"; then
|
||||
CCACHE=
|
||||
else
|
||||
if test ! -e "$CCACHE"; then
|
||||
AC_MSG_ERROR([$CCACHE not found])
|
||||
fi
|
||||
fi
|
||||
MOZ_PATH_PROGS(CCACHE, $CCACHE ccache)
|
||||
if test -z "$CCACHE" -o "$CCACHE" = ":"; then
|
||||
AC_MSG_ERROR([ccache not found])
|
||||
elif test -x "$CCACHE"; then
|
||||
CC="$CCACHE $CC"
|
||||
CXX="$CCACHE $CXX"
|
||||
else
|
||||
AC_MSG_ERROR([$CCACHE is not executable])
|
||||
fi
|
||||
fi
|
||||
MOZ_CHECK_CCACHE
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable static checking using gcc-dehydra
|
||||
@ -8752,14 +8674,16 @@ xpcom/xpcom-config.h
|
||||
xpcom/xpcom-private.h
|
||||
)
|
||||
|
||||
# Hack around an Apple bug that effects the egrep that comes with OS X 10.7.
|
||||
# "arch -arch i386 egrep" always uses the 32-bit Intel part of the egrep fat
|
||||
# binary, even on 64-bit systems. We (apparently) only need this hack when
|
||||
# egrep's "pattern" is particularly long (as in the following code).
|
||||
# See bug 655339.
|
||||
# Hack around an Apple bug that affects the egrep that comes with OS X 10.7.
|
||||
# "env ARCHPREFERENCE=i386,x86_64 arch egrep" first tries to use the 32-bit
|
||||
# Intel part of the egrep fat binary, even on 64-bit systems, and falls back on
|
||||
# the 64-bit part if it's not a fat binary, as can happen with MacPorts. We
|
||||
# (apparently) only need this hack when egrep's "pattern" is particularly long
|
||||
# (as in the following code) and the first egrep on our $PATH is Apple's. See
|
||||
# bug 655339.
|
||||
case "$host" in
|
||||
*-apple-darwin11*)
|
||||
FIXED_EGREP="arch -arch i386 egrep"
|
||||
FIXED_EGREP="env ARCHPREFERENCE=i386,x86_64 arch egrep"
|
||||
;;
|
||||
*)
|
||||
FIXED_EGREP="egrep"
|
||||
|
@ -66,12 +66,12 @@ ContentAreaDropListener.prototype =
|
||||
uriString = uriString.replace(/^\s*|\s*$/g, '');
|
||||
|
||||
let uri;
|
||||
let ioService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
try {
|
||||
// Check that the uri is valid first and return an empty string if not.
|
||||
// It may just be plain text and should be ignored here
|
||||
uri = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Components.interfaces.nsIIOService).
|
||||
newURI(uriString, null, null);
|
||||
uri = ioService.newURI(uriString, null, null);
|
||||
} catch (ex) { }
|
||||
if (!uri)
|
||||
return uriString;
|
||||
@ -85,10 +85,10 @@ ContentAreaDropListener.prototype =
|
||||
flags |= secMan.DISALLOW_INHERIT_PRINCIPAL;
|
||||
|
||||
// Use file:/// as the default uri so that drops of file URIs are always allowed
|
||||
if (sourceNode)
|
||||
secMan.checkLoadURIStrWithPrincipal(sourceNode.nodePrincipal, uriString, flags);
|
||||
else
|
||||
secMan.checkLoadURIStr("file:///", uriString, flags);
|
||||
let principal = sourceNode ? sourceNode.nodePrincipal
|
||||
: secMan.getCodebasePrincipal(ioService.newURI("file:///", null, null));
|
||||
|
||||
secMan.checkLoadURIStrWithPrincipal(principal, uriString, flags);
|
||||
|
||||
return uriString;
|
||||
},
|
||||
|
@ -2191,10 +2191,21 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
if (securityManager) {
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
|
||||
|
||||
if (!docShell && aLoadGroup) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> cbs;
|
||||
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
|
||||
docShell = do_GetInterface(cbs);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(docShell,
|
||||
"must be in a docshell or pass in an explicit principal");
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv =
|
||||
securityManager->GetCodebasePrincipal(mDocumentURI,
|
||||
getter_AddRefs(principal));
|
||||
nsresult rv = securityManager->
|
||||
GetDocShellCodebasePrincipal(mDocumentURI, docShell,
|
||||
getter_AddRefs(principal));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetPrincipal(principal);
|
||||
}
|
||||
@ -3087,7 +3098,7 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
|
||||
// should really be the same thing). Note that this code can run
|
||||
// before the current URI of the webnavigation has been updated, so we
|
||||
// can't assert equality here.
|
||||
refresher->SetupRefreshURIFromHeader(mDocumentURI,
|
||||
refresher->SetupRefreshURIFromHeader(mDocumentURI, NodePrincipal(),
|
||||
NS_ConvertUTF16toUTF8(aData));
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,7 @@
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "nsIAppsService.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
@ -1109,14 +1110,29 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
bool weAreBrowserFrame = false;
|
||||
bool otherIsBrowserFrame = false;
|
||||
ourDocshell->GetIsBrowserFrame(&weAreBrowserFrame);
|
||||
otherDocshell->GetIsBrowserFrame(&otherIsBrowserFrame);
|
||||
if (weAreBrowserFrame != otherIsBrowserFrame) {
|
||||
bool ourContentBoundary, otherContentBoundary;
|
||||
ourDocshell->GetIsContentBoundary(&ourContentBoundary);
|
||||
otherDocshell->GetIsContentBoundary(&otherContentBoundary);
|
||||
if (ourContentBoundary != otherContentBoundary) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (ourContentBoundary) {
|
||||
bool ourIsBrowser, otherIsBrowser;
|
||||
ourDocshell->GetIsBrowserElement(&ourIsBrowser);
|
||||
otherDocshell->GetIsBrowserElement(&otherIsBrowser);
|
||||
if (ourIsBrowser != otherIsBrowser) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
bool ourIsApp, otherIsApp;
|
||||
ourDocshell->GetIsApp(&ourIsApp);
|
||||
otherDocshell->GetIsApp(&otherIsApp);
|
||||
if (ourIsApp != otherIsApp) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (mInSwap || aOther->mInSwap) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -1461,6 +1477,24 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
|
||||
if (OwnerIsBrowserFrame() &&
|
||||
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)) {
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
if (!appsService) {
|
||||
NS_ERROR("Apps Service is not available!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString manifest;
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, manifest);
|
||||
|
||||
PRUint32 appId;
|
||||
appsService->GetAppLocalIdByManifestURL(manifest, &appId);
|
||||
|
||||
mDocShell->SetAppId(appId);
|
||||
}
|
||||
|
||||
if (!mNetworkCreated) {
|
||||
nsCOMPtr<nsIDocShellHistory> history = do_QueryInterface(mDocShell);
|
||||
if (history) {
|
||||
@ -1563,7 +1597,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
EnsureMessageManager();
|
||||
|
||||
if (OwnerIsBrowserFrame()) {
|
||||
mDocShell->SetIsBrowserFrame(true);
|
||||
mDocShell->SetIsBrowser();
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
|
@ -1744,6 +1744,7 @@ nsEventStateManager::HandleCrossProcessEvent(nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus *aStatus) {
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
aEvent->flags & NS_EVENT_FLAG_DONT_FORWARD_CROSS_PROCESS ||
|
||||
!CrossProcessSafeEvent(*aEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ MOCHITEST_FILES = \
|
||||
test_dom_keyboard_event.html \
|
||||
test_dom_mouse_event.html \
|
||||
test_bug742376.html \
|
||||
test_bug603008.html \
|
||||
$(NULL)
|
||||
|
||||
#bug 585630
|
||||
@ -101,12 +102,6 @@ MOCHITEST_FILES += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
||||
MOCHITEST_FILES += \
|
||||
test_bug603008.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
test_bug336682_2.xul \
|
||||
test_bug336682.js \
|
||||
|
@ -221,7 +221,7 @@ public:
|
||||
private:
|
||||
// Holds global instance of StateMachineTracker.
|
||||
// Writable on main thread only.
|
||||
static StateMachineTracker* mInstance;
|
||||
static StateMachineTracker* sInstance;
|
||||
|
||||
// Reentrant monitor that must be obtained to access
|
||||
// the decode thread count member and methods.
|
||||
@ -247,15 +247,15 @@ private:
|
||||
nsDeque mPending;
|
||||
};
|
||||
|
||||
StateMachineTracker* StateMachineTracker::mInstance = nsnull;
|
||||
StateMachineTracker* StateMachineTracker::sInstance = nsnull;
|
||||
|
||||
StateMachineTracker& StateMachineTracker::Instance()
|
||||
{
|
||||
if (!mInstance) {
|
||||
if (!sInstance) {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
mInstance = new StateMachineTracker();
|
||||
sInstance = new StateMachineTracker();
|
||||
}
|
||||
return *mInstance;
|
||||
return *sInstance;
|
||||
}
|
||||
|
||||
void StateMachineTracker::EnsureGlobalStateMachine()
|
||||
@ -303,7 +303,7 @@ void StateMachineTracker::CleanupGlobalStateMachine()
|
||||
NS_DispatchToMainThread(event);
|
||||
|
||||
NS_ASSERTION(mDecodeThreadCount == 0, "Decode thread count must be zero.");
|
||||
mInstance = nsnull;
|
||||
sInstance = nsnull;
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
@ -11,6 +11,13 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
|
||||
// GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
|
||||
// currentTime getter.
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DOM wrapper for MediaStreams.
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@ using namespace mozilla::dom;
|
||||
|
||||
// Helper function
|
||||
static bool
|
||||
GetCSSComputedValue(nsIContent* aElem,
|
||||
GetCSSComputedValue(Element* aElem,
|
||||
nsCSSProperty aPropID,
|
||||
nsAString& aResult)
|
||||
{
|
||||
@ -40,16 +40,11 @@ GetCSSComputedValue(nsIContent* aElem,
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<nsComputedDOMStyle> computedStyle;
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(aElem));
|
||||
nsresult rv = NS_NewComputedDOMStyle(domElement, EmptyString(), shell,
|
||||
getter_AddRefs(computedStyle));
|
||||
nsRefPtr<nsComputedDOMStyle> computedStyle =
|
||||
NS_NewComputedDOMStyle(aElem, EmptyString(), shell);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
computedStyle->GetPropertyValue(aPropID, aResult);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
computedStyle->GetPropertyValue(aPropID, aResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Class Methods
|
||||
|
@ -241,6 +241,7 @@ txMozillaXMLOutput::endDocument(nsresult aResult)
|
||||
do_QueryInterface(win->GetDocShell());
|
||||
if (refURI) {
|
||||
refURI->SetupRefreshURIFromHeader(mDocument->GetDocBaseURI(),
|
||||
mDocument->NodePrincipal(),
|
||||
mRefreshString);
|
||||
}
|
||||
}
|
||||
|
@ -311,9 +311,9 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
|
||||
parentDocShellItem) {
|
||||
|
||||
nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
|
||||
bool browserFrame = false;
|
||||
curDocShell->GetIsBrowserFrame(&browserFrame);
|
||||
if (browserFrame) {
|
||||
bool isContentBoundary;
|
||||
curDocShell->GetIsContentBoundary(&isContentBoundary);
|
||||
if (isContentBoundary) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
@ -201,6 +202,7 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// Number of documents currently loading
|
||||
static PRInt32 gNumberOfDocumentsLoading = 0;
|
||||
@ -763,6 +765,7 @@ nsDocShell::nsDocShell():
|
||||
#ifdef DEBUG
|
||||
mInEnsureScriptEnv(false),
|
||||
#endif
|
||||
mAppId(nsIScriptSecurityManager::NO_APP_ID),
|
||||
mParentCharsetSource(0)
|
||||
{
|
||||
mHistoryID = ++gDocshellIDCounter;
|
||||
@ -5528,6 +5531,7 @@ nsDocShell::ForceRefreshURI(nsIURI * aURI,
|
||||
|
||||
nsresult
|
||||
nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsACString & aHeader)
|
||||
{
|
||||
// Refresh headers are parsed with the following format in mind
|
||||
@ -5569,6 +5573,8 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
|
||||
|
||||
// when done, seconds is 0 or the given number of seconds
|
||||
// uriAttrib is empty or the URI specified
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
nsCAutoString uriAttrib;
|
||||
PRInt32 seconds = 0;
|
||||
bool specifiesSeconds = false;
|
||||
@ -5733,9 +5739,8 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
|
||||
(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = securityManager->
|
||||
CheckLoadURI(aBaseURI, uri,
|
||||
nsIScriptSecurityManager::
|
||||
LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT);
|
||||
CheckLoadURIWithPrincipal(aPrincipal, uri,
|
||||
nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
bool isjs = true;
|
||||
@ -5771,8 +5776,16 @@ NS_IMETHODIMP nsDocShell::SetupRefreshURI(nsIChannel * aChannel)
|
||||
refreshHeader);
|
||||
|
||||
if (!refreshHeader.IsEmpty()) {
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = secMan->GetChannelPrincipal(aChannel, getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SetupReferrerFromChannel(aChannel);
|
||||
rv = SetupRefreshURIFromHeader(mCurrentURI, refreshHeader);
|
||||
rv = SetupRefreshURIFromHeader(mCurrentURI, principal, refreshHeader);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return NS_REFRESHURI_HEADER_FOUND;
|
||||
}
|
||||
@ -12013,52 +12026,156 @@ nsDocShell::GetCanExecuteScripts(bool *aResult)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsBrowserFrame(bool *aOut)
|
||||
nsDocShell::SetIsBrowser()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOut);
|
||||
*aOut = mIsBrowserFrame;
|
||||
return NS_OK;
|
||||
}
|
||||
if (mIsBrowserFrame) {
|
||||
NS_ERROR("You should not call SetIsBrowser() more than once.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetIsBrowserFrame(bool aValue)
|
||||
{
|
||||
// Disallow transitions from browser frame to not-browser-frame. Once a
|
||||
// browser frame, always a browser frame. (Otherwise, observers of
|
||||
// docshell-marked-as-browser-frame would have to distinguish between
|
||||
// newly-created browser frames and frames which went from true to false back
|
||||
// to true.)
|
||||
NS_ENSURE_STATE(!mIsBrowserFrame || aValue);
|
||||
mIsBrowserFrame = true;
|
||||
|
||||
bool wasBrowserFrame = mIsBrowserFrame;
|
||||
mIsBrowserFrame = aValue;
|
||||
if (aValue && !wasBrowserFrame) {
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
os->NotifyObservers(GetAsSupports(this),
|
||||
"docshell-marked-as-browser-frame", NULL);
|
||||
os->NotifyObservers(GetAsSupports(this),
|
||||
"docshell-marked-as-browser-frame", NULL);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetContainedInBrowserFrame(bool *aOut)
|
||||
nsDocShell::FrameType
|
||||
nsDocShell::GetInheritedFrameType()
|
||||
{
|
||||
*aOut = false;
|
||||
FrameType type = GetFrameType();
|
||||
|
||||
if (mIsBrowserFrame) {
|
||||
*aOut = true;
|
||||
return NS_OK;
|
||||
if (type != eFrameTypeRegular) {
|
||||
return type;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
|
||||
GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
|
||||
nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
|
||||
if (parent) {
|
||||
return parent->GetContainedInBrowserFrame(aOut);
|
||||
if (!parent) {
|
||||
return eFrameTypeRegular;
|
||||
}
|
||||
|
||||
return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
|
||||
}
|
||||
|
||||
nsDocShell::FrameType
|
||||
nsDocShell::GetFrameType()
|
||||
{
|
||||
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
return eFrameTypeApp;
|
||||
}
|
||||
|
||||
return mIsBrowserFrame ? eFrameTypeBrowser : eFrameTypeRegular;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
|
||||
{
|
||||
*aIsBrowser = (GetFrameType() == eFrameTypeBrowser);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsApp(bool* aIsApp)
|
||||
{
|
||||
*aIsApp = (GetFrameType() == eFrameTypeApp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
|
||||
{
|
||||
switch (GetFrameType()) {
|
||||
case eFrameTypeRegular:
|
||||
*aIsContentBoundary = false;
|
||||
break;
|
||||
case eFrameTypeBrowser:
|
||||
case eFrameTypeApp:
|
||||
*aIsContentBoundary = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
|
||||
{
|
||||
*aIsInBrowserElement = (GetInheritedFrameType() == eFrameTypeBrowser);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsInApp(bool* aIsInApp)
|
||||
{
|
||||
*aIsInApp = (GetInheritedFrameType() == eFrameTypeApp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary)
|
||||
{
|
||||
switch (GetInheritedFrameType()) {
|
||||
case eFrameTypeRegular:
|
||||
*aIsInContentBoundary = false;
|
||||
break;
|
||||
case eFrameTypeBrowser:
|
||||
case eFrameTypeApp:
|
||||
*aIsInContentBoundary = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetAppId(PRUint32 aAppId)
|
||||
{
|
||||
MOZ_ASSERT(mAppId == nsIScriptSecurityManager::NO_APP_ID);
|
||||
MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
mAppId = aAppId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetAppId(PRUint32* aAppId)
|
||||
{
|
||||
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
MOZ_ASSERT(GetFrameType() == eFrameTypeApp);
|
||||
|
||||
*aAppId = mAppId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(GetFrameType() != eFrameTypeApp);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
|
||||
GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
|
||||
nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
|
||||
if (!parent) {
|
||||
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return parent->GetAppId(aAppId);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetAsyncPanZoomEnabled(bool* aOut)
|
||||
{
|
||||
if (TabChild* tabChild = GetTabChildFrom(this)) {
|
||||
*aOut = tabChild->IsAsyncPanZoomEnabled();
|
||||
return NS_OK;
|
||||
}
|
||||
*aOut = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -664,6 +664,15 @@ protected:
|
||||
|
||||
bool JustStartedNetworkLoad();
|
||||
|
||||
enum FrameType {
|
||||
eFrameTypeRegular = 0x0, // 0000
|
||||
eFrameTypeBrowser = 0x1, // 0001
|
||||
eFrameTypeApp = 0x2 // 0010
|
||||
};
|
||||
|
||||
FrameType GetInheritedFrameType();
|
||||
FrameType GetFrameType();
|
||||
|
||||
// hash of session storages, keyed by domain
|
||||
nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
|
||||
|
||||
@ -815,6 +824,8 @@ protected:
|
||||
|
||||
nsRefPtr<nsDOMNavigationTiming> mTiming;
|
||||
|
||||
PRUint32 mAppId;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIAtom> mForcedCharset;
|
||||
nsCOMPtr<nsIAtom> mParentCharset;
|
||||
|
@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
|
||||
interface nsIVariant;
|
||||
interface nsIPrivacyTransitionObserver;
|
||||
|
||||
[scriptable, builtinclass, uuid(89ea9f32-18ec-413b-9e2c-ce9a4c851b1c)]
|
||||
[scriptable, builtinclass, uuid(05802c0d-3315-4245-b72e-cf92eb3118a3)]
|
||||
interface nsIDocShell : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -589,21 +589,70 @@ interface nsIDocShell : nsISupports
|
||||
*/
|
||||
void addWeakPrivacyTransitionObserver(in nsIPrivacyTransitionObserver obs);
|
||||
|
||||
/*
|
||||
* Is this docshell a browser frame (i.e., does it correspond to an <iframe
|
||||
* mozbrowser>)? The frameloader is responsible for setting this property
|
||||
* when it initializes the docshell.
|
||||
/**
|
||||
* Mark the docshell as a browser frame.
|
||||
* This should be used for <iframe mozbrowser> but not for <iframe mozapp>.
|
||||
*
|
||||
* If so, this docshell should act like a chrome/content boundary for the
|
||||
* purposes of window.top and window.parent.
|
||||
*
|
||||
* See also nsIMozBrowserFrame.
|
||||
* This method should not be called more than once.
|
||||
*/
|
||||
attribute bool isBrowserFrame;
|
||||
void setIsBrowser();
|
||||
|
||||
/*
|
||||
* Is this docshell contained in an <iframe mozbrowser>, either directly or
|
||||
* indirectly?
|
||||
/**
|
||||
* Returns true iff the docshell is marked as a browser frame.
|
||||
*/
|
||||
readonly attribute bool containedInBrowserFrame;
|
||||
readonly attribute boolean isBrowserElement;
|
||||
|
||||
/**
|
||||
* Returns true iif the docshell is marked as an app frame.
|
||||
*/
|
||||
readonly attribute boolean isApp;
|
||||
|
||||
/**
|
||||
* Returns true iif the docshell is marked as a type that behaves like a
|
||||
* content boundary.
|
||||
*/
|
||||
readonly attribute boolean isContentBoundary;
|
||||
|
||||
/**
|
||||
* Returns true iif the docshell is inside a browser element.
|
||||
*/
|
||||
readonly attribute boolean isInBrowserElement;
|
||||
|
||||
/**
|
||||
* Returns true iif the docshell is inside an application.
|
||||
* However, it will return false if the docshell is inside a browser element
|
||||
* that is inside an application.
|
||||
*/
|
||||
readonly attribute boolean isInApp;
|
||||
|
||||
/**
|
||||
* Returns if the docshell has a docshell that behaves as a content boundary
|
||||
* in his parent hierarchy.
|
||||
*/
|
||||
readonly attribute boolean isBelowContentBoundary;
|
||||
|
||||
/**
|
||||
* Set the app id this docshell is associated with. The id has to be a valid
|
||||
* app id. If the docshell isn't associated with any app, the value should be
|
||||
* nsIScriptSecurityManager::NO_APP_ID. However, this is the default value if
|
||||
* nothing is et.
|
||||
*
|
||||
* This method is [noscript] to reduce the scope. It should be used at very
|
||||
* specific moments.
|
||||
*
|
||||
* Calling setAppId() will mark the frame as an app frame.
|
||||
*/
|
||||
[noscript] void setAppId(in unsigned long appId);
|
||||
|
||||
/**
|
||||
* Returns the app id of the app the docshell is in. Returns
|
||||
* nsIScriptSecurityManager::NO_APP_ID if the docshell is not in an app.
|
||||
*/
|
||||
readonly attribute unsigned long appId;
|
||||
|
||||
/**
|
||||
* True iff asynchronous panning and zooming is enabled for this
|
||||
* docshell.
|
||||
*/
|
||||
readonly attribute bool asyncPanZoomEnabled;
|
||||
};
|
||||
|
@ -7,8 +7,9 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIURI.idl"
|
||||
interface nsIChannel;
|
||||
interface nsIPrincipal;
|
||||
|
||||
[scriptable, uuid(cb0ad623-6b46-4c09-a473-c1d6ca63d3c7)]
|
||||
[scriptable, uuid(a5e61a3c-51bd-45be-ac0c-e87b71860656)]
|
||||
interface nsIRefreshURI : nsISupports {
|
||||
/**
|
||||
* Load a uri after waiting for aMillis milliseconds. If the docshell
|
||||
@ -55,10 +56,11 @@ interface nsIRefreshURI : nsISupports {
|
||||
* the current page finishes loading.
|
||||
*
|
||||
* @param aBaseURI base URI to resolve refresh uri with.
|
||||
* @param principal the associated principal
|
||||
* @param aHeader The meta refresh header string.
|
||||
*/
|
||||
void setupRefreshURIFromHeader(in nsIURI aBaseURI, in ACString aHeader);
|
||||
|
||||
void setupRefreshURIFromHeader(in nsIURI aBaseURI, in nsIPrincipal principal, in ACString aHeader);
|
||||
|
||||
/**
|
||||
* Cancels all timer loads.
|
||||
*/
|
||||
|
@ -317,7 +317,8 @@ let DOMApplicationRegistry = {
|
||||
},
|
||||
|
||||
_nextLocalId: function() {
|
||||
let maxLocalId = 0;
|
||||
let maxLocalId = Ci.nsIScriptSecurityManager.NO_APP_ID;
|
||||
|
||||
for (let id in this.webapps) {
|
||||
if (this.webapps[id].localId > maxLocalId) {
|
||||
maxLocalId = this.webapps[id].localId;
|
||||
@ -635,7 +636,7 @@ let DOMApplicationRegistry = {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return Ci.nsIScriptSecurityManager.NO_APP_ID;
|
||||
},
|
||||
|
||||
getAllWithoutManifests: function(aCallback) {
|
||||
|
@ -2965,9 +2965,9 @@ nsGlobalWindow::GetScriptableParent(nsIDOMWindow** aParent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool isMozBrowser = false;
|
||||
mDocShell->GetIsBrowserFrame(&isMozBrowser);
|
||||
if (isMozBrowser) {
|
||||
bool isContentBoundary = false;
|
||||
mDocShell->GetIsContentBoundary(&isContentBoundary);
|
||||
if (isContentBoundary) {
|
||||
nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this);
|
||||
parent.swap(*aParent);
|
||||
return NS_OK;
|
||||
@ -4567,6 +4567,11 @@ nsGlobalWindow::Dump(const nsAString& aStr)
|
||||
#endif
|
||||
|
||||
if (cstr) {
|
||||
#ifdef XP_WIN
|
||||
if (IsDebuggerPresent()) {
|
||||
OutputDebugStringA(cstr);
|
||||
}
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
__android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr);
|
||||
#endif
|
||||
@ -6446,12 +6451,13 @@ nsGlobalWindow::Close()
|
||||
{
|
||||
FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
bool isMozBrowser = false;
|
||||
bool isContentBoundary = false;
|
||||
if (mDocShell) {
|
||||
mDocShell->GetIsBrowserFrame(&isMozBrowser);
|
||||
mDocShell->GetIsContentBoundary(&isContentBoundary);
|
||||
}
|
||||
|
||||
if ((!isMozBrowser && IsFrame()) || !mDocShell || IsInModalState()) {
|
||||
if ((!isContentBoundary && IsFrame()) ||
|
||||
!mDocShell || IsInModalState()) {
|
||||
// window.close() is called on a frame in a frameset, on a window
|
||||
// that's already closed, or on a window for which there's
|
||||
// currently a modal dialog open. Ignore such calls.
|
||||
@ -6980,9 +6986,9 @@ nsGlobalWindow::GetScriptableFrameElement(nsIDOMElement** aFrameElement)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool isMozBrowser = false;
|
||||
mDocShell->GetIsBrowserFrame(&isMozBrowser);
|
||||
if (isMozBrowser) {
|
||||
bool isContentBoundary = false;
|
||||
mDocShell->GetIsContentBoundary(&isContentBoundary);
|
||||
if (isContentBoundary) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -8176,10 +8182,10 @@ nsGlobalWindow::GetComputedStyle(nsIDOMElement* aElt,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsComputedDOMStyle> compStyle;
|
||||
nsresult rv = NS_NewComputedDOMStyle(aElt, aPseudoElt, presShell,
|
||||
getter_AddRefs(compStyle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<dom::Element> element = do_QueryInterface(aElt);
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
nsRefPtr<nsComputedDOMStyle> compStyle =
|
||||
NS_NewComputedDOMStyle(element, aPseudoElt, presShell);
|
||||
|
||||
*aReturn = compStyle.forget().get();
|
||||
|
||||
|
@ -3755,7 +3755,7 @@ SetMemoryGCPrefChangedCallback(const char* aPrefName, void* aClosure)
|
||||
PRInt32 pref = Preferences::GetInt(aPrefName, -1);
|
||||
// handle overflow and negative pref values
|
||||
if (pref > 0 && pref < 10000)
|
||||
JS_SetGCParameter(nsJSRuntime::sRuntime, (JSGCParamKey)(long)aClosure, pref);
|
||||
JS_SetGCParameter(nsJSRuntime::sRuntime, (JSGCParamKey)(intptr_t)aClosure, pref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,14 @@
|
||||
# to an educated guess).
|
||||
# * castable - Indicates whether the value in the wrapper can be cast to
|
||||
# nativeType, or whether it needs to be QI-ed (defaults to True
|
||||
# for everything but callback interfaces).
|
||||
# for everything but callback interfaces and external interfaces,
|
||||
# for which it defaults to false and is not allowed to be set
|
||||
# at all).
|
||||
# * concrete - Indicates whether there exist objects with this interface as
|
||||
# their primary interface (defaults to True).
|
||||
# * prefable - Indicates whether this binding is subject to the about:config
|
||||
# pref, or whether it's always enabled (defaults to False).
|
||||
# Cannot be set on external interfaces.
|
||||
# * workers - Indicates whether the descriptor is intended to be used for
|
||||
# worker threads (defaults to false).
|
||||
# * customTrace - The native class will use a custom trace hook (defaults to
|
||||
@ -55,14 +58,11 @@ DOMInterfaces = {
|
||||
{
|
||||
'nativeType': 'nsIDOMBlob',
|
||||
'headerFile': 'nsIDOMFile.h',
|
||||
'prefable': True,
|
||||
'castable': False
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'CanvasRenderingContext2D': [
|
||||
@ -85,27 +85,21 @@ DOMInterfaces = {
|
||||
'Document': [
|
||||
{
|
||||
'nativeType': 'nsIDocument',
|
||||
'prefable': True,
|
||||
'castable': False
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'Event': [
|
||||
{
|
||||
'nativeType': 'nsIDOMEvent',
|
||||
'prefable': True,
|
||||
'castable': False
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'EventListener': [
|
||||
@ -136,56 +130,44 @@ DOMInterfaces = {
|
||||
'FormData': [
|
||||
{
|
||||
'nativeType': 'nsIDOMFormData',
|
||||
'prefable': True,
|
||||
'castable': False
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'IID': [
|
||||
{
|
||||
'nativeType': 'nsIJSIID',
|
||||
'headerFile': 'xpcjsid.h',
|
||||
'prefable': True,
|
||||
'castable': False
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'InputStream': [
|
||||
{
|
||||
'nativeType': 'nsIInputStream',
|
||||
'prefable': True,
|
||||
'castable': False,
|
||||
'notflattened': True
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'MozChannel': [
|
||||
{
|
||||
'nativeType': 'nsIChannel',
|
||||
'prefable': True,
|
||||
'castable': False,
|
||||
'notflattened': True
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'nativeType': 'JSObject',
|
||||
'headerFile': 'jsapi.h',
|
||||
'castable': False
|
||||
}],
|
||||
|
||||
'Performance': {
|
||||
@ -266,6 +248,10 @@ DOMInterfaces = {
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
'resultNotAddRefed': [ 'receiveWeakSelf', 'receiveWeakNullableSelf',
|
||||
'receiveWeakOther', 'receiveWeakNullableOther',
|
||||
'receiveWeakExternal', 'receiveWeakNullableExternal',
|
||||
'ReceiveWeakCallbackInterface',
|
||||
'ReceiveWeakNullableCallbackInterface',
|
||||
'receiveWeakCastableObjectSequence',
|
||||
'receiveWeakNullableCastableObjectSequence',
|
||||
'receiveWeakCastableObjectNullableSequence',
|
||||
@ -285,8 +271,7 @@ DOMInterfaces = {
|
||||
'TestExternalInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestExternalInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
'castable': False
|
||||
'register': False
|
||||
},
|
||||
|
||||
'TestNonWrapperCacheInterface' : {
|
||||
@ -295,6 +280,20 @@ DOMInterfaces = {
|
||||
'register': False,
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'TestCallbackInterface': {
|
||||
'nativeType': 'mozilla::dom::TestCallbackInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
},
|
||||
|
||||
'IndirectlyImplementedInterface': {
|
||||
'nativeType': 'mozilla::dom::IndirectlyImplementedInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
'castable': False,
|
||||
'concrete': False
|
||||
},
|
||||
}
|
||||
|
||||
# These are temporary, until they've been converted to use new DOM bindings
|
||||
@ -303,8 +302,7 @@ def addExternalIface(iface, nativeType=None, headerFile=None):
|
||||
nativeType = 'nsIDOM' + iface
|
||||
domInterface = {
|
||||
'nativeType': nativeType,
|
||||
'concrete': False,
|
||||
'castable': False
|
||||
'concrete': False
|
||||
}
|
||||
if not headerFile is None:
|
||||
domInterface['headerFile'] = headerFile
|
||||
|
@ -1836,6 +1836,10 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
"arguments (like %s), because we don't know "
|
||||
"how to handle them being preffed off" %
|
||||
descriptor.interface.identifier.name)
|
||||
if descriptor.interface.isConsequential():
|
||||
raise TypeError("Consequential interface %s being used as an "
|
||||
"argument but flagged as castable" %
|
||||
descriptor.interface.identifier.name)
|
||||
if failureCode is not None:
|
||||
templateBody += str(CastableObjectUnwrapper(
|
||||
descriptor,
|
||||
@ -2364,7 +2368,8 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
"}\n")
|
||||
else:
|
||||
wrappingCode = ""
|
||||
if descriptor.castable and not type.unroll().inner.isExternal():
|
||||
if (not descriptor.interface.isExternal() and
|
||||
not descriptor.interface.isCallback()):
|
||||
if descriptor.wrapperCache:
|
||||
wrapMethod = "WrapNewBindingObject"
|
||||
else:
|
||||
@ -2381,6 +2386,10 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
|
||||
"return false;")
|
||||
else:
|
||||
if descriptor.notflattened:
|
||||
raise TypeError("%s is prefable but not flattened; "
|
||||
"fallback won't work correctly" %
|
||||
descriptor.interface.identifier.name)
|
||||
# Try old-style wrapping for bindings which might be preffed off.
|
||||
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
|
||||
wrappingCode += wrapAndSetPtr(wrap, failed)
|
||||
@ -3063,6 +3072,13 @@ class CGSetterCall(CGGetterSetterCall):
|
||||
# We just get our stuff from vp
|
||||
return ""
|
||||
|
||||
class FakeCastableDescriptor():
|
||||
def __init__(self, descriptor):
|
||||
self.castable = True
|
||||
self.workers = descriptor.workers
|
||||
self.nativeType = descriptor.nativeType
|
||||
self.name = descriptor.name
|
||||
|
||||
class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
||||
"""
|
||||
Common class to generate the JSNatives for all our methods, getters, and
|
||||
@ -3075,9 +3091,14 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
||||
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
|
||||
|
||||
def definition_body(self):
|
||||
# Our descriptor might claim that we're not castable, simply because
|
||||
# we're someone's consequential interface. But for this-unwrapping, we
|
||||
# know that we're the real deal. So fake a descriptor here for
|
||||
# consumption by FailureFatalCastableObjectUnwrapper.
|
||||
unwrapThis = CGIndenter(CGGeneric(
|
||||
str(FailureFatalCastableObjectUnwrapper(self.descriptor,
|
||||
"obj", "self"))))
|
||||
str(FailureFatalCastableObjectUnwrapper(
|
||||
FakeCastableDescriptor(self.descriptor),
|
||||
"obj", "self"))))
|
||||
return CGList([ self.getThis(), unwrapThis,
|
||||
self.generate_code() ], "\n").define()
|
||||
|
||||
@ -3925,7 +3946,7 @@ class CGDescriptor(CGThing):
|
||||
if (descriptor.customTrace):
|
||||
cgThings.append(CGClassTraceHook(descriptor))
|
||||
|
||||
if descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject():
|
||||
if descriptor.interface.hasInterfacePrototypeObject():
|
||||
cgThings.append(CGNativePropertyHooks(descriptor))
|
||||
if descriptor.concrete:
|
||||
cgThings.append(CGDOMJSClass(descriptor))
|
||||
@ -3948,8 +3969,7 @@ class CGDescriptor(CGThing):
|
||||
|
||||
# Set up our Xray callbacks as needed. Note that we don't need to do
|
||||
# it in workers.
|
||||
if ((descriptor.concrete or
|
||||
descriptor.interface.hasInterfacePrototypeObject()) and
|
||||
if (descriptor.interface.hasInterfacePrototypeObject() and
|
||||
not descriptor.workers):
|
||||
cgThings.append(CGResolveProperty(descriptor, properties))
|
||||
cgThings.append(CGEnumerateProperties(descriptor, properties))
|
||||
|
@ -134,8 +134,13 @@ class Descriptor(DescriptorProvider):
|
||||
headerDefault = headerDefault.replace("::", "/") + ".h"
|
||||
self.headerFile = desc.get('headerFile', headerDefault)
|
||||
|
||||
castableDefault = not self.interface.isCallback()
|
||||
self.castable = desc.get('castable', castableDefault)
|
||||
if self.interface.isCallback() or self.interface.isExternal():
|
||||
if 'castable' in desc:
|
||||
raise TypeError("%s is external or callback but has a castable "
|
||||
"setting" % self.interface.identifier.name)
|
||||
self.castable = False
|
||||
else:
|
||||
self.castable = desc.get('castable', True)
|
||||
|
||||
self.notflattened = desc.get('notflattened', False)
|
||||
self.register = desc.get('register', True)
|
||||
@ -149,6 +154,9 @@ class Descriptor(DescriptorProvider):
|
||||
iface.setUserData('hasConcreteDescendant', True)
|
||||
iface = iface.parent
|
||||
|
||||
if self.interface.isExternal() and 'prefable' in desc:
|
||||
raise TypeError("%s is external but has a prefable setting" %
|
||||
self.interface.identifier.name)
|
||||
self.prefable = desc.get('prefable', False)
|
||||
|
||||
self.nativeIsISupports = not self.workers
|
||||
|
@ -577,7 +577,7 @@ class IDLInterface(IDLObjectWithScope):
|
||||
return not hasattr(self, "_noInterfaceObject")
|
||||
|
||||
def hasInterfacePrototypeObject(self):
|
||||
return not self.isCallback()
|
||||
return not self.isCallback() and self.getUserData('hasConcreteDescendant', False)
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
self._extendedAttrDict = {}
|
||||
|
@ -49,6 +49,10 @@ bindinggen_dependencies := \
|
||||
$(GLOBAL_DEPS) \
|
||||
$(NULL)
|
||||
|
||||
# Include rules.mk before any of our targets so our first target is coming from
|
||||
# rules.mk and running make with no target in this dir does the right thing.
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
$(CPPSRCS): ../%Binding.cpp: $(bindinggen_dependencies) \
|
||||
../%.webidl \
|
||||
$(NULL)
|
||||
@ -62,11 +66,11 @@ MOCHITEST_FILES = \
|
||||
test_lookupGetter.html \
|
||||
test_InstanceOf.html \
|
||||
test_traceProtos.html \
|
||||
test_forOf.html \
|
||||
forOf_iframe.html \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
check::
|
||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) $(srcdir)/../parser/runtests.py
|
||||
|
@ -35,6 +35,26 @@ public:
|
||||
virtual nsISupports* GetParentObject();
|
||||
};
|
||||
|
||||
// IID for the IndirectlyImplementedInterface
|
||||
#define NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID \
|
||||
{ 0xfed55b69, 0x7012, 0x4849, \
|
||||
{ 0xaf, 0x56, 0x4b, 0xa9, 0xee, 0x41, 0x30, 0x89 } }
|
||||
|
||||
class IndirectlyImplementedInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID)
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
bool GetIndirectlyImplementedProperty(ErrorResult&);
|
||||
void SetIndirectlyImplementedProperty(bool, ErrorResult&);
|
||||
void IndirectlyImplementedMethod(ErrorResult&);
|
||||
};
|
||||
|
||||
// IID for the TestExternalInterface
|
||||
#define NS_TEST_EXTERNAL_INTERFACE_IID \
|
||||
{ 0xd5ba0c99, 0x9b1d, 0x4e71, \
|
||||
@ -46,6 +66,17 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
// IID for the TestCallbackInterface
|
||||
#define NS_TEST_CALLBACK_INTERFACE_IID \
|
||||
{ 0xbf711ba4, 0xc8f6, 0x46cf, \
|
||||
{ 0xba, 0x5b, 0xaa, 0xe2, 0x78, 0x18, 0xe6, 0x4a } }
|
||||
class TestCallbackInterface : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_CALLBACK_INTERFACE_IID)
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
class TestNonWrapperCacheInterface : public nsISupports
|
||||
{
|
||||
public:
|
||||
@ -202,6 +233,24 @@ public:
|
||||
void PassOptionalNonNullExternal(const Optional<TestExternalInterface*>&, ErrorResult&);
|
||||
void PassOptionalExternalWithDefault(TestExternalInterface*, ErrorResult&);
|
||||
|
||||
already_AddRefed<TestCallbackInterface> ReceiveCallbackInterface(ErrorResult&);
|
||||
already_AddRefed<TestCallbackInterface> ReceiveNullableCallbackInterface(ErrorResult&);
|
||||
TestCallbackInterface* ReceiveWeakCallbackInterface(ErrorResult&);
|
||||
TestCallbackInterface* ReceiveWeakNullableCallbackInterface(ErrorResult&);
|
||||
void PassCallbackInterface(TestCallbackInterface&, ErrorResult&);
|
||||
void PassCallbackInterface2(OwningNonNull<TestCallbackInterface>, ErrorResult&);
|
||||
void PassNullableCallbackInterface(TestCallbackInterface*, ErrorResult&);
|
||||
already_AddRefed<TestCallbackInterface> GetNonNullCallbackInterface(ErrorResult&);
|
||||
void SetNonNullCallbackInterface(TestCallbackInterface&, ErrorResult&);
|
||||
already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface(ErrorResult&);
|
||||
void SetNullableCallbackInterface(TestCallbackInterface*, ErrorResult&);
|
||||
void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterface> >&, ErrorResult&);
|
||||
void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterface> >&, ErrorResult&);
|
||||
void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*, ErrorResult&);
|
||||
|
||||
already_AddRefed<IndirectlyImplementedInterface> ReceiveConsequentialInterface(ErrorResult&);
|
||||
void PassConsequentialInterface(IndirectlyImplementedInterface&, ErrorResult&);
|
||||
|
||||
// Sequence types
|
||||
void ReceiveSequence(nsTArray<int32_t>&, ErrorResult&);
|
||||
void ReceiveNullableSequence(Nullable< nsTArray<int32_t> >&, ErrorResult&);
|
||||
@ -220,8 +269,6 @@ public:
|
||||
ErrorResult&);
|
||||
void ReceiveCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&,
|
||||
ErrorResult&);
|
||||
void ReceiveWeakNullableCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&,
|
||||
ErrorResult&);
|
||||
void ReceiveNullableCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&,
|
||||
ErrorResult&);
|
||||
void ReceiveWeakCastableObjectSequence(nsTArray<TestInterface*> &,
|
||||
|
@ -9,6 +9,11 @@ interface TestExternalInterface;
|
||||
interface TestNonCastableInterface {
|
||||
};
|
||||
|
||||
callback interface TestCallbackInterface {
|
||||
readonly attribute long foo;
|
||||
void doSomething();
|
||||
};
|
||||
|
||||
enum TestEnum {
|
||||
"a",
|
||||
"b"
|
||||
@ -150,6 +155,27 @@ interface TestInterface {
|
||||
void passOptionalNonNullExternal(optional TestExternalInterface arg);
|
||||
void passOptionalExternalWithDefault(optional TestExternalInterface? arg = null);
|
||||
|
||||
// Callback interface types
|
||||
TestCallbackInterface receiveCallbackInterface();
|
||||
TestCallbackInterface? receiveNullableCallbackInterface();
|
||||
TestCallbackInterface receiveWeakCallbackInterface();
|
||||
TestCallbackInterface? receiveWeakNullableCallbackInterface();
|
||||
// A verstion to test for casting to TestCallbackInterface&
|
||||
void passCallbackInterface(TestCallbackInterface arg);
|
||||
// A version we can use to test for the exact type passed in
|
||||
void passCallbackInterface2(TestCallbackInterface arg);
|
||||
void passNullableCallbackInterface(TestCallbackInterface? arg);
|
||||
attribute TestCallbackInterface nonNullCallbackInterface;
|
||||
attribute TestCallbackInterface? nullableCallbackInterface;
|
||||
// Optional arguments
|
||||
void passOptionalCallbackInterface(optional TestCallbackInterface? arg);
|
||||
void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
|
||||
void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
|
||||
|
||||
// Miscellaneous interface tests
|
||||
IndirectlyImplementedInterface receiveConsequentialInterface();
|
||||
void passConsequentialInterface(IndirectlyImplementedInterface arg);
|
||||
|
||||
// Sequence types
|
||||
sequence<long> receiveSequence();
|
||||
sequence<long>? receiveNullableSequence();
|
||||
@ -280,6 +306,7 @@ interface ImplementedInterfaceParent {
|
||||
|
||||
ImplementedInterfaceParent implements IndirectlyImplementedInterface;
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface IndirectlyImplementedInterface {
|
||||
void indirectlyImplementedMethod();
|
||||
attribute boolean indirectlyImplementedProperty;
|
||||
|
13
dom/bindings/test/forOf_iframe.html
Normal file
13
dom/bindings/test/forOf_iframe.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>iframe content for test_forOf_iframe.html</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="basket">
|
||||
<span id="egg0"></span>
|
||||
<span id="egg1"><span id="duckling1"></span></span>
|
||||
<span id="egg2"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
94
dom/bindings/test/test_forOf.html
Normal file
94
dom/bindings/test/test_forOf.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=725907
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 725907</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=725907">Mozilla Bug 725907</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<div id="basket">
|
||||
<span id="egg0"></span>
|
||||
<span id="egg1"><span id="duckling1"></span></span>
|
||||
<span id="egg2"></span>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 725907 **/
|
||||
|
||||
function runTestsForDocument(document, msgSuffix) {
|
||||
function is(a, b, msg) { SimpleTest.is(a, b, msg + msgSuffix); }
|
||||
function isnot(a, b, msg) { SimpleTest.isnot(a, b, msg + msgSuffix); }
|
||||
|
||||
var basket = document.getElementById("basket");
|
||||
var egg3 = document.createElement("span");
|
||||
egg3.id = "egg3";
|
||||
|
||||
var log = '';
|
||||
for (var x of basket.childNodes) {
|
||||
if (x.nodeType != x.TEXT_NODE)
|
||||
log += x.id + ";";
|
||||
}
|
||||
is(log, "egg0;egg1;egg2;", "'for (x of div.childNodes)' should iterate over child nodes");
|
||||
|
||||
log = '';
|
||||
for (var x of basket.childNodes) {
|
||||
if (x.nodeType != x.TEXT_NODE) {
|
||||
log += x.id + ";";
|
||||
if (x.id == "egg1")
|
||||
basket.appendChild(egg3);
|
||||
}
|
||||
}
|
||||
is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.childNodes)' should see elements added during iteration");
|
||||
|
||||
var iter1 = basket.childNodes.iterator();
|
||||
var iter2 = basket.childNodes.iterator();
|
||||
isnot(iter1, iter2, "nodelist.iterator() returns a new iterator each time");
|
||||
|
||||
log = '';
|
||||
basket.appendChild(document.createTextNode("some text"));
|
||||
for (var x of basket.children)
|
||||
log += x.id + ";";
|
||||
is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.children)' should iterate over child elements");
|
||||
|
||||
var iter1 = basket.children.iterator();
|
||||
var iter2 = basket.children.iterator();
|
||||
isnot(iter1, iter2, ".iterator() returns a new iterator each time");
|
||||
|
||||
var count = 0;
|
||||
for (var x of document.getElementsByClassName("hazardous-materials"))
|
||||
count++;
|
||||
is(count, 0, "'for (x of emptyNodeList)' loop should run zero times");
|
||||
|
||||
var log = '';
|
||||
for (var x of document.querySelectorAll("span"))
|
||||
log += x.id + ";";
|
||||
is(log, "egg0;egg1;duckling1;egg2;egg3;", "for-of loop should work with a querySelectorAll() NodeList");
|
||||
}
|
||||
|
||||
/* All the tests run twice. First, in this document, so without any wrappers. */
|
||||
runTestsForDocument(document, "");
|
||||
|
||||
/* And once using the document of an iframe, so working with cross-compartment wrappers. */
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function iframeLoaded(iframe) {
|
||||
runTestsForDocument(iframe.contentWindow.document, " (in iframe)");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<iframe src="forOf_iframe.html" onload="iframeLoaded(this)"></iframe>
|
||||
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,6 +1,16 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
# Copyright 2012 Mozilla Foundation and Mozilla contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
|
@ -1,8 +1,19 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=40: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "BluetoothGonkService.h"
|
||||
#include "BluetoothDBusService.h"
|
||||
|
@ -1,8 +1,19 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=40: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_dom_bluetooth_bluetoothgonkservice_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothgonkservice_h__
|
||||
|
@ -1,8 +1,19 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=40: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "BluetoothGonkService.h"
|
||||
|
||||
|
@ -4,13 +4,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let Cu = Components.utils;
|
||||
let Ci = Components.interfaces;
|
||||
let Cc = Components.classes;
|
||||
let Cr = Components.results;
|
||||
|
||||
let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Geometry.jsm");
|
||||
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
|
||||
|
||||
// Event whitelisted for bubbling.
|
||||
@ -62,7 +59,7 @@ BrowserElementChild.prototype = {
|
||||
|
||||
BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
|
||||
|
||||
docShell.isBrowserFrame = true;
|
||||
docShell.setIsBrowser();
|
||||
docShell.QueryInterface(Ci.nsIWebProgress)
|
||||
.addProgressListener(this._progressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_LOCATION |
|
||||
@ -575,3 +572,10 @@ BrowserElementChild.prototype = {
|
||||
};
|
||||
|
||||
var api = new BrowserElementChild();
|
||||
|
||||
// FIXME/bug 775438: use a JSM?
|
||||
//
|
||||
// The code in this included file depends on the |addEventListener|,
|
||||
// |addMessageListener|, |content|, |Geometry| and |Services| symbols
|
||||
// being "exported" from here.
|
||||
#include BrowserElementScrolling.js
|
||||
|
@ -136,7 +136,12 @@ function BrowserElementParent(frameLoader) {
|
||||
|
||||
let self = this;
|
||||
function addMessageListener(msg, handler) {
|
||||
self._mm.addMessageListener('browser-element-api:' + msg, handler.bind(self));
|
||||
function checkedHandler() {
|
||||
if (self._isAlive()) {
|
||||
handler.apply(self, arguments);
|
||||
}
|
||||
}
|
||||
self._mm.addMessageListener('browser-element-api:' + msg, checkedHandler);
|
||||
}
|
||||
|
||||
addMessageListener("hello", this._recvHello);
|
||||
@ -157,11 +162,19 @@ function BrowserElementParent(frameLoader) {
|
||||
addMessageListener('got-can-go-forward', this._gotDOMRequestResult);
|
||||
|
||||
function defineMethod(name, fn) {
|
||||
XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
|
||||
XPCNativeWrapper.unwrap(self._frameElement)[name] = function() {
|
||||
if (self._isAlive()) {
|
||||
return fn.apply(self, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function defineDOMRequestMethod(domName, msgName) {
|
||||
XPCNativeWrapper.unwrap(self._frameElement)[domName] = self._sendDOMRequest.bind(self, msgName);
|
||||
XPCNativeWrapper.unwrap(self._frameElement)[domName] = function() {
|
||||
if (self._isAlive()) {
|
||||
return self._sendDOMRequest(msgName);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Define methods on the frame element.
|
||||
@ -176,6 +189,16 @@ function BrowserElementParent(frameLoader) {
|
||||
}
|
||||
|
||||
BrowserElementParent.prototype = {
|
||||
/**
|
||||
* You shouldn't touch this._frameElement or this._window if _isAlive is
|
||||
* false. (You'll likely get an exception if you do.)
|
||||
*/
|
||||
_isAlive: function() {
|
||||
return !Cu.isDeadWrapper(this._frameElement) &&
|
||||
!Cu.isDeadWrapper(this._frameElement.ownerDocument) &&
|
||||
!Cu.isDeadWrapper(this._frameElement.ownerDocument.defaultView);
|
||||
},
|
||||
|
||||
get _window() {
|
||||
return this._frameElement.ownerDocument.defaultView;
|
||||
},
|
||||
|
@ -1,23 +1,14 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* 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';
|
||||
|
||||
dump('======================= webapi.js ======================= \n');
|
||||
|
||||
let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/Geometry.jsm');
|
||||
|
||||
const ContentPanning = {
|
||||
init: function cp_init() {
|
||||
['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
|
||||
addEventListener(type, ContentPanning, true);
|
||||
});
|
||||
|
||||
addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
|
||||
},
|
||||
|
||||
handleEvent: function cp_handleEvent(evt) {
|
||||
@ -124,9 +115,9 @@ const ContentPanning = {
|
||||
if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
|
||||
return [null, null];
|
||||
|
||||
let content = node.ownerDocument.defaultView;
|
||||
let nodeContent = node.ownerDocument.defaultView;
|
||||
while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
|
||||
let style = content.getComputedStyle(node, null);
|
||||
let style = nodeContent.getComputedStyle(node, null);
|
||||
|
||||
let overflow = [style.getPropertyValue('overflow'),
|
||||
style.getPropertyValue('overflow-x'),
|
||||
@ -144,7 +135,13 @@ const ContentPanning = {
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
return [content, this._generateCallback(content)];
|
||||
if (ContentPanning._asyncPanZoomForViewportFrame &&
|
||||
nodeContent === content)
|
||||
// The parent context is asynchronously panning and zooming our
|
||||
// root scrollable frame, so don't use our synchronous fallback.
|
||||
return [null, null];
|
||||
|
||||
return [nodeContent, this._generateCallback(nodeContent)];
|
||||
},
|
||||
|
||||
_generateCallback: function cp_generateCallback(content) {
|
||||
@ -176,6 +173,39 @@ const ContentPanning = {
|
||||
|
||||
const kStateActive = 0x00000001;
|
||||
this._domUtils.setContentState(root.documentElement, kStateActive);
|
||||
},
|
||||
|
||||
get _asyncPanZoomForViewportFrame() {
|
||||
return docShell.asyncPanZoomEnabled;
|
||||
},
|
||||
|
||||
_recvViewportChange: function(data) {
|
||||
let viewport = data.json;
|
||||
let displayPort = viewport.displayPort;
|
||||
|
||||
let screenWidth = viewport.screenSize.width;
|
||||
let screenHeight = viewport.screenSize.height;
|
||||
|
||||
let x = viewport.x;
|
||||
let y = viewport.y;
|
||||
|
||||
let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
cwu.setCSSViewport(screenWidth, screenHeight);
|
||||
|
||||
// Set scroll position
|
||||
cwu.setScrollPositionClampingScrollPortSize(
|
||||
screenWidth / viewport.zoom, screenHeight / viewport.zoom);
|
||||
content.scrollTo(x, y);
|
||||
cwu.setResolution(displayPort.resolution, displayPort.resolution);
|
||||
|
||||
let element = null;
|
||||
if (content.document && (element = content.document.documentElement)) {
|
||||
cwu.setDisplayPortForElement(displayPort.left,
|
||||
displayPort.top,
|
||||
displayPort.width,
|
||||
displayPort.height,
|
||||
element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -349,4 +379,3 @@ const KineticPanning = {
|
||||
content.mozRequestAnimationFrame(callback);
|
||||
}
|
||||
};
|
||||
|
@ -17,15 +17,13 @@ DIRS = \\
|
||||
${dirs}
|
||||
|
||||
include $$(DEPTH)/config/autoconf.mk
|
||||
include $$(topsrcdir)/config/rules.mk
|
||||
"""
|
||||
|
||||
filesTemplate = """
|
||||
_FILES = \\
|
||||
MOCHITEST_FILES := \\
|
||||
${files}
|
||||
|
||||
libs:: $$(_FILES)
|
||||
\t$$(INSTALL) $$(foreach f,$$^,"$$f") $$(DEPTH)/_tests/testing/mochitest/tests/$$(relativesrcdir)
|
||||
include $$(topsrcdir)/config/rules.mk
|
||||
"""
|
||||
|
||||
def makefileString(entries):
|
||||
|
@ -15,9 +15,16 @@ interface mozIDOMApplication;
|
||||
* This service allows accessing some DOMApplicationRegistry methods from
|
||||
* non-javascript code.
|
||||
*/
|
||||
[scriptable, uuid(40e580e7-8891-4eb8-b514-0b5796af4df1)]
|
||||
[scriptable, uuid(1210a0f3-add3-4381-b892-9c102e3afc42)]
|
||||
interface nsIAppsService : nsISupports
|
||||
{
|
||||
mozIDOMApplication getAppByManifestURL(in DOMString manifestURL);
|
||||
|
||||
/**
|
||||
* Returns the |localId| of the app associated with the |manifestURL| passed
|
||||
* in parameter.
|
||||
* Returns nsIScriptSecurityManager::NO_APP_ID if |manifestURL| isn't a valid
|
||||
* installed manifest URL.
|
||||
*/
|
||||
unsigned long getAppLocalIdByManifestURL(in DOMString manifestURL);
|
||||
};
|
||||
|
@ -13,18 +13,23 @@ include protocol PRenderFrame;
|
||||
include protocol POfflineCacheUpdate;
|
||||
include protocol PIndexedDB;
|
||||
|
||||
include "mozilla/dom/TabMessageUtils.h";
|
||||
include "gfxMatrix.h";
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
include "IPC/nsGUIEventIPC.h";
|
||||
include "mozilla/dom/TabMessageUtils.h";
|
||||
include "mozilla/layout/RenderFrameUtils.h";
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
|
||||
using IPC::URI;
|
||||
using gfxMatrix;
|
||||
using gfxSize;
|
||||
using mozilla::layers::LayersBackend;
|
||||
using mozilla::layout::ScrollingBehavior;
|
||||
using mozilla::WindowsHandle;
|
||||
using nscolor;
|
||||
using nsCompositionEvent;
|
||||
using nsIMEUpdatePreference;
|
||||
using nsIntPoint;
|
||||
using nsIntRect;
|
||||
using nsIntSize;
|
||||
using nsKeyEvent;
|
||||
using nsMouseEvent;
|
||||
@ -176,7 +181,8 @@ parent:
|
||||
* the page that is currently loaded in the <browser>.
|
||||
*/
|
||||
sync PRenderFrame()
|
||||
returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
|
||||
returns (ScrollingBehavior scrolling,
|
||||
LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
|
||||
|
||||
/**
|
||||
* Starts an offline application cache update.
|
||||
@ -241,6 +247,11 @@ child:
|
||||
|
||||
UpdateDimensions(nsRect rect, nsIntSize size);
|
||||
|
||||
UpdateFrame(nsIntRect displayPort,
|
||||
nsIntPoint scrollOffset,
|
||||
gfxSize resolution,
|
||||
nsIntRect screenSize);
|
||||
|
||||
/**
|
||||
* Sending an activate message moves focus to the child.
|
||||
*/
|
||||
|
@ -12,7 +12,7 @@
|
||||
/*
|
||||
PContentPermissionRequestChild implementations also are
|
||||
XPCOM objects. Addref() is called on their implementation
|
||||
before SendPCOntentPermissionRequestConstructor is called.
|
||||
before SendPContentPermissionRequestConstructor is called.
|
||||
When Dealloc is called, IPDLRelease() is called.
|
||||
Implementations of this method are expected to call
|
||||
Release() on themselves. See Bug 594261 for more
|
||||
@ -21,6 +21,15 @@
|
||||
class PCOMContentPermissionRequestChild : public mozilla::dom::PContentPermissionRequestChild {
|
||||
public:
|
||||
virtual void IPDLRelease() = 0;
|
||||
#ifdef DEBUG
|
||||
PCOMContentPermissionRequestChild() : mIPCOpen(false) {}
|
||||
virtual ~PCOMContentPermissionRequestChild() {
|
||||
// mIPCOpen is set to true in TabChild::SendPContentPermissionRequestConstructor
|
||||
// and set to false in TabChild::DeallocPContentPermissionRequest
|
||||
MOZ_ASSERT(!mIPCOpen, "Protocol must not be open when PCOMContentPermissionRequestChild is destroyed.");
|
||||
}
|
||||
bool mIPCOpen;
|
||||
#endif /* DEBUG */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsScriptLoader.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -337,12 +338,12 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags,
|
||||
// open a modal-type window, we're going to create a new <iframe mozbrowser>
|
||||
// and return its window here.
|
||||
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
|
||||
bool inBrowserFrame = false;
|
||||
bool isInContentBoundary = false;
|
||||
if (docshell) {
|
||||
docshell->GetContainedInBrowserFrame(&inBrowserFrame);
|
||||
docshell->GetIsBelowContentBoundary(&isInContentBoundary);
|
||||
}
|
||||
|
||||
if (inBrowserFrame &&
|
||||
if (isInContentBoundary &&
|
||||
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
|
||||
@ -625,6 +626,37 @@ TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvUpdateFrame(const nsIntRect& aDisplayPort,
|
||||
const nsIntPoint& aScrollOffset,
|
||||
const gfxSize& aResolution,
|
||||
const nsIntRect& aScreenSize)
|
||||
{
|
||||
nsCString data;
|
||||
data += nsPrintfCString("{ \"x\" : %d", aScrollOffset.x);
|
||||
data += nsPrintfCString(", \"y\" : %d", aScrollOffset.y);
|
||||
// We don't treat the x and y scales any differently for this
|
||||
// semi-platform-specific code.
|
||||
data += nsPrintfCString(", \"zoom\" : %f", aResolution.width);
|
||||
data += nsPrintfCString(", \"displayPort\" : ");
|
||||
data += nsPrintfCString("{ \"left\" : %d", aDisplayPort.X());
|
||||
data += nsPrintfCString(", \"top\" : %d", aDisplayPort.Y());
|
||||
data += nsPrintfCString(", \"width\" : %d", aDisplayPort.Width());
|
||||
data += nsPrintfCString(", \"height\" : %d", aDisplayPort.Height());
|
||||
data += nsPrintfCString(", \"resolution\" : %f", aResolution.width);
|
||||
data += nsPrintfCString(" }");
|
||||
data += nsPrintfCString(", \"screenSize\" : ");
|
||||
data += nsPrintfCString("{ \"width\" : %d", aScreenSize.width);
|
||||
data += nsPrintfCString(", \"height\" : %d", aScreenSize.height);
|
||||
data += nsPrintfCString(" }");
|
||||
data += nsPrintfCString(" }");
|
||||
|
||||
// Let the BrowserElementScrolling helper (if it exists) for this
|
||||
// content manipulate the frame state.
|
||||
return RecvAsyncMessage(NS_LITERAL_STRING("Viewport:Change"),
|
||||
NS_ConvertUTF8toUTF16(data));
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvActivate()
|
||||
{
|
||||
@ -857,7 +889,12 @@ TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI&
|
||||
bool
|
||||
TabChild::DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor)
|
||||
{
|
||||
static_cast<PCOMContentPermissionRequestChild*>(actor)->IPDLRelease();
|
||||
PCOMContentPermissionRequestChild* child =
|
||||
static_cast<PCOMContentPermissionRequestChild*>(actor);
|
||||
#ifdef DEBUG
|
||||
child->mIPCOpen = false;
|
||||
#endif /* DEBUG */
|
||||
child->IPDLRelease();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -962,7 +999,8 @@ TabChild::RecvDestroy()
|
||||
}
|
||||
|
||||
PRenderFrameChild*
|
||||
TabChild::AllocPRenderFrame(LayersBackend* aBackend,
|
||||
TabChild::AllocPRenderFrame(ScrollingBehavior* aScrolling,
|
||||
LayersBackend* aBackend,
|
||||
int32_t* aMaxTextureSize,
|
||||
uint64_t* aLayersId)
|
||||
{
|
||||
@ -1035,7 +1073,7 @@ TabChild::InitWidget(const nsIntSize& size)
|
||||
int32_t maxTextureSize;
|
||||
RenderFrameChild* remoteFrame =
|
||||
static_cast<RenderFrameChild*>(SendPRenderFrameConstructor(
|
||||
&be, &maxTextureSize, &id));
|
||||
&mScrolling, &be, &maxTextureSize, &id));
|
||||
if (!remoteFrame) {
|
||||
NS_WARNING("failed to construct RenderFrame");
|
||||
return false;
|
||||
@ -1098,6 +1136,12 @@ TabChild::NotifyPainted()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::IsAsyncPanZoomEnabled()
|
||||
{
|
||||
return mScrolling == ASYNC_PAN_ZOOM;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user