Merge from mozilla-central.

This commit is contained in:
David Anderson 2012-07-20 12:02:04 -07:00
commit 07f7d8e680
462 changed files with 9210 additions and 3355 deletions

View File

@ -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));
}
}
}

View File

@ -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
View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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;
}
}
},
};

View File

@ -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);

View File

@ -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 {

View File

@ -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">

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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">

View File

@ -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))

View File

@ -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);
});

View File

@ -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");

View 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

View File

@ -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");

View File

@ -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);
}
});
}

View File

@ -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 \

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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]

View File

@ -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 {

View File

@ -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();

View File

@ -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;

View File

@ -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 \

View File

@ -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();

View File

@ -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");

View File

@ -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");

View File

@ -113,7 +113,7 @@ function test()
executeSoon(function() {
contextMenu.hidePopup();
gDebugger.DebuggerController.activeThread.resume(finish);
closeDebuggerAndFinish();
});
}

View 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;
});
}

View File

@ -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,

View File

@ -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">

View File

@ -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.

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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
View 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)
])

View 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)
])

View File

@ -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."

View File

@ -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

View 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
View 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

View 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)

View File

@ -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);
}
}

View File

@ -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;
};
};

View File

@ -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++

View File

@ -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

View File

@ -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__

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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 //

View File

@ -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) $< > $@

View File

@ -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>

View File

@ -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@

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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;
},

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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 \

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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

View File

@ -241,6 +241,7 @@ txMozillaXMLOutput::endDocument(nsresult aResult)
do_QueryInterface(win->GetDocShell());
if (refURI) {
refURI->SetupRefreshURIFromHeader(mDocument->GetDocBaseURI(),
mDocument->NodePrincipal(),
mRefreshString);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
};

View File

@ -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.
*/

View File

@ -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) {

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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 = {}

View File

@ -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

View File

@ -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*> &,

View File

@ -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;

View 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>

View 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>

View File

@ -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@

View File

@ -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"

View File

@ -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__

View File

@ -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"

View File

@ -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

View File

@ -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;
},

View File

@ -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);
}
};

View File

@ -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):

View File

@ -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);
};

View File

@ -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.
*/

View File

@ -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

View File

@ -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