Merge m-c to b2g-inbound

This commit is contained in:
Wes Kocher 2014-05-14 16:34:15 -07:00
commit eee6cd4dda
128 changed files with 1437 additions and 338 deletions

View File

@ -1018,6 +1018,8 @@ pref("browser.sessionstore.restore_pinned_tabs_on_demand", false);
pref("browser.sessionstore.upgradeBackup.latestBuildID", ""); pref("browser.sessionstore.upgradeBackup.latestBuildID", "");
// End-users should not run sessionstore in debug mode // End-users should not run sessionstore in debug mode
pref("browser.sessionstore.debug", false); pref("browser.sessionstore.debug", false);
// Forget closed windows/tabs after two weeks
pref("browser.sessionstore.cleanup.forget_closed_after", 1209600000);
// allow META refresh by default // allow META refresh by default
pref("accessibility.blockautorefresh", false); pref("accessibility.blockautorefresh", false);

View File

@ -111,14 +111,20 @@ function restoreSession() {
// restore the session into a new window and close the current tab // restore the session into a new window and close the current tab
var newWindow = top.openDialog(top.location, "_blank", "chrome,dialog=no,all"); var newWindow = top.openDialog(top.location, "_blank", "chrome,dialog=no,all");
newWindow.addEventListener("load", function() {
newWindow.removeEventListener("load", arguments.callee, true); var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
obs.addObserver(function observe(win, topic) {
if (win != newWindow) {
return;
}
obs.removeObserver(observe, topic);
ss.setWindowState(newWindow, stateString, true); ss.setWindowState(newWindow, stateString, true);
var tabbrowser = top.gBrowser; var tabbrowser = top.gBrowser;
var tabIndex = tabbrowser.getBrowserIndexForDocument(document); var tabIndex = tabbrowser.getBrowserIndexForDocument(document);
tabbrowser.removeTab(tabbrowser.tabs[tabIndex]); tabbrowser.removeTab(tabbrowser.tabs[tabIndex]);
}, true); }, "browser-delayed-startup-finished", false);
} }
function startNewSession() { function startNewSession() {

View File

@ -36,6 +36,7 @@ const OBSERVING = [
"quit-application", "browser:purge-session-history", "quit-application", "browser:purge-session-history",
"browser:purge-domain-data", "browser:purge-domain-data",
"gather-telemetry", "gather-telemetry",
"idle-daily",
]; ];
// XUL Window properties to (re)store // XUL Window properties to (re)store
@ -384,15 +385,14 @@ let SessionStoreInternal = {
* Initialize the session using the state provided by SessionStartup * Initialize the session using the state provided by SessionStartup
*/ */
initSession: function () { initSession: function () {
TelemetryStopwatch.start("FX_SESSION_RESTORE_STARTUP_INIT_SESSION_MS");
let state; let state;
let ss = gSessionStartup; let ss = gSessionStartup;
try { if (ss.doRestore() ||
if (ss.doRestore() || ss.sessionType == Ci.nsISessionStartup.DEFER_SESSION) {
ss.sessionType == Ci.nsISessionStartup.DEFER_SESSION) state = ss.state;
state = ss.state;
} }
catch(ex) { dump(ex + "\n"); } // no state to restore, which is ok
if (state) { if (state) {
try { try {
@ -466,6 +466,7 @@ let SessionStoreInternal = {
this._performUpgradeBackup(); this._performUpgradeBackup();
TelemetryStopwatch.finish("FX_SESSION_RESTORE_STARTUP_INIT_SESSION_MS");
return state; return state;
}, },
@ -570,6 +571,9 @@ let SessionStoreInternal = {
case "gather-telemetry": case "gather-telemetry":
this.onGatherTelemetry(); this.onGatherTelemetry();
break; break;
case "idle-daily":
this.onIdleDaily();
break;
} }
}, },
@ -966,7 +970,10 @@ let SessionStoreInternal = {
} else { } else {
let initialState = this.initSession(); let initialState = this.initSession();
this._sessionInitialized = true; this._sessionInitialized = true;
TelemetryStopwatch.start("FX_SESSION_RESTORE_STARTUP_ONLOAD_INITIAL_WINDOW_MS");
this.onLoad(aWindow, initialState); this.onLoad(aWindow, initialState);
TelemetryStopwatch.finish("FX_SESSION_RESTORE_STARTUP_ONLOAD_INITIAL_WINDOW_MS");
// Let everyone know we're done. // Let everyone know we're done.
this._deferredInitialized.resolve(); this._deferredInitialized.resolve();
@ -1425,6 +1432,39 @@ let SessionStoreInternal = {
return SessionFile.gatherTelemetry(stateString); return SessionFile.gatherTelemetry(stateString);
}, },
// Clean up data that has been closed a long time ago.
// Do not reschedule a save. This will wait for the next regular
// save.
onIdleDaily: function() {
// Remove old closed windows
this._cleanupOldData([this._closedWindows]);
// Remove closed tabs of closed windows
this._cleanupOldData([winData._closedTabs for (winData of this._closedWindows)]);
// Remove closed tabs of open windows
this._cleanupOldData([this._windows[key]._closedTabs for (key of Object.keys(this._windows))]);
},
// Remove "old" data from an array
_cleanupOldData: function(targets) {
const TIME_TO_LIVE = this._prefBranch.getIntPref("sessionstore.cleanup.forget_closed_after");
const now = Date.now();
for (let array of targets) {
for (let i = array.length - 1; i >= 0; --i) {
let data = array[i];
// Make sure that we have a timestamp to tell us when the target
// has been closed. If we don't have a timestamp, default to a
// safe timestamp: just now.
data.closedAt = data.closedAt || now;
if (now - data.closedAt > TIME_TO_LIVE) {
array.splice(i, 1);
}
}
}
},
/* ........ nsISessionStore API .............. */ /* ........ nsISessionStore API .............. */
getBrowserState: function ssi_getBrowserState() { getBrowserState: function ssi_getBrowserState() {
@ -1668,6 +1708,8 @@ let SessionStoreInternal = {
// reopen the window // reopen the window
let state = { windows: this._closedWindows.splice(aIndex, 1) }; let state = { windows: this._closedWindows.splice(aIndex, 1) };
delete state.windows[0].closedAt; // Window is now open.
let window = this._openWindowWithState(state); let window = this._openWindowWithState(state);
this.windowToFocus = window; this.windowToFocus = window;
return window; return window;
@ -2469,6 +2511,7 @@ let SessionStoreInternal = {
} else { } else {
delete tab.__SS_extdata; delete tab.__SS_extdata;
} }
delete tabData.closedAt; // Tab is now open.
// Flush all data from the content script synchronously. This is done so // Flush all data from the content script synchronously. This is done so
// that all async messages that are still on their way to chrome will // that all async messages that are still on their way to chrome will

View File

@ -57,9 +57,11 @@ support-files =
#disabled-for-intermittent-failures--bug-766044, browser_459906_sample.html #disabled-for-intermittent-failures--bug-766044, browser_459906_sample.html
#disabled-for-intermittent-failures--bug-765389, browser_461743_sample.html #disabled-for-intermittent-failures--bug-765389, browser_461743_sample.html
[browser_aboutSessionRestore.js]
[browser_attributes.js] [browser_attributes.js]
[browser_broadcast.js] [browser_broadcast.js]
[browser_capabilities.js] [browser_capabilities.js]
[browser_cleaner.js]
[browser_dying_cache.js] [browser_dying_cache.js]
[browser_dynamic_frames.js] [browser_dynamic_frames.js]
[browser_form_restore_events.js] [browser_form_restore_events.js]

View File

@ -0,0 +1,46 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const CRASH_SHENTRY = {url: "about:mozilla"};
const CRASH_TAB = {entries: [CRASH_SHENTRY]};
const CRASH_STATE = {windows: [{tabs: [CRASH_TAB]}]};
const TAB_FORMDATA = {id: {sessionData: CRASH_STATE}};
const TAB_SHENTRY = {url: "about:sessionrestore", formdata: TAB_FORMDATA};
const TAB_STATE = {entries: [TAB_SHENTRY]};
const FRAME_SCRIPT = "data:," +
"content.document.getElementById('errorTryAgain').click()";
add_task(function* () {
// Prepare a blank tab.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Fake a post-crash tab.
ss.setTabState(tab, JSON.stringify(TAB_STATE));
yield promiseTabRestored(tab);
ok(gBrowser.tabs.length > 1, "we have more than one tab");
browser.messageManager.loadFrameScript(FRAME_SCRIPT, true);
// Wait until the new window was restored.
let win = yield waitForNewWindow();
yield promiseWindowClosed(win);
let [{tabs: [{entries: [{url}]}]}] = JSON.parse(ss.getClosedWindowData());
is(url, "about:mozilla", "session was restored correctly");
ss.forgetClosedWindow(0);
});
function waitForNewWindow() {
return new Promise(resolve => {
Services.obs.addObserver(function observe(win, topic) {
Services.obs.removeObserver(observe, topic);
resolve(win);
}, "browser-delayed-startup-finished", false);
});
}

View File

@ -0,0 +1,160 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* This test ensures that Session Restore eventually forgets about
* tabs and windows that have been closed a long time ago.
*/
"use strict";
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/osfile.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
const LONG_TIME_AGO = 1;
const URL_TAB1 = "http://example.com/browser_cleaner.js?newtab1=" + Math.random();
const URL_TAB2 = "http://example.com/browser_cleaner.js?newtab2=" + Math.random();
const URL_NEWWIN = "http://example.com/browser_cleaner.js?newwin=" + Math.random();
function isRecent(stamp) {
is(typeof stamp, "number", "This is a timestamp");
return Date.now() - stamp <= 60000;
}
function promiseCleanup () {
info("Cleaning up browser");
return promiseBrowserState(getClosedState());
};
function getClosedState() {
return Cu.cloneInto(CLOSED_STATE, {});
}
let CLOSED_STATE;
add_task(function* init() {
while (ss.getClosedWindowCount() > 0) {
ss.forgetClosedWindow(0);
}
while (ss.getClosedTabCount(window) > 0) {
ss.forgetClosedTab(window, 0);
}
});
add_task(function* test_open_and_close() {
let newTab1 = gBrowser.addTab(URL_TAB1);
yield promiseBrowserLoaded(newTab1.linkedBrowser);
let newTab2 = gBrowser.addTab(URL_TAB2);
yield promiseBrowserLoaded(newTab2.linkedBrowser);
let newWin = yield promiseNewWindowLoaded();
let tab = newWin.gBrowser.addTab(URL_NEWWIN);
yield promiseBrowserLoaded(tab.linkedBrowser);
info("1. Making sure that before closing, we don't have closedAt");
// For the moment, no "closedAt"
let state = JSON.parse(ss.getBrowserState());
is(state.windows[0].closedAt || false, false, "1. Main window doesn't have closedAt");
is(state.windows[1].closedAt || false, false, "1. Second window doesn't have closedAt");
is(state.windows[0].tabs[0].closedAt || false, false, "1. First tab doesn't have closedAt");
is(state.windows[0].tabs[1].closedAt || false, false, "1. Second tab doesn't have closedAt");
info("2. Making sure that after closing, we have closedAt");
// Now close stuff, this should add closeAt
yield promiseWindowClosed(newWin);
gBrowser.removeTab(newTab1);
gBrowser.removeTab(newTab2);
state = CLOSED_STATE = JSON.parse(ss.getBrowserState());
is(state.windows[0].closedAt || false, false, "2. Main window doesn't have closedAt");
ok(isRecent(state._closedWindows[0].closedAt), "2. Second window was closed recently");
ok(isRecent(state.windows[0]._closedTabs[0].closedAt), "2. First tab was closed recently");
ok(isRecent(state.windows[0]._closedTabs[1].closedAt), "2. Second tab was closed recently");
});
add_task(function* test_restore() {
info("3. Making sure that after restoring, we don't have closedAt");
yield promiseBrowserState(CLOSED_STATE);
let newWin = ss.undoCloseWindow(0);
yield promiseDelayedStartupFinished(newWin);
let newTab2 = ss.undoCloseTab(window, 0);
yield promiseTabRestored(newTab2);
let newTab1 = ss.undoCloseTab(window, 0);
yield promiseTabRestored(newTab1);
let state = JSON.parse(ss.getBrowserState());
is(state.windows[0].closedAt || false, false, "3. Main window doesn't have closedAt");
is(state.windows[1].closedAt || false, false, "3. Second window doesn't have closedAt");
is(state.windows[0].tabs[0].closedAt || false, false, "3. First tab doesn't have closedAt");
is(state.windows[0].tabs[1].closedAt || false, false, "3. Second tab doesn't have closedAt");
yield promiseWindowClosed(newWin);
gBrowser.removeTab(newTab1);
gBrowser.removeTab(newTab2);
});
add_task(function* test_old_data() {
info("4. Removing closedAt from the sessionstore, making sure that it is added upon idle-daily");
let state = getClosedState();
delete state._closedWindows[0].closedAt;
delete state.windows[0]._closedTabs[0].closedAt;
delete state.windows[0]._closedTabs[1].closedAt;
yield promiseBrowserState(state);
info("Sending idle-daily");
Services.obs.notifyObservers(null, "idle-daily", "");
info("Sent idle-daily");
state = JSON.parse(ss.getBrowserState());
is(state.windows[0].closedAt || false, false, "4. Main window doesn't have closedAt");
ok(isRecent(state._closedWindows[0].closedAt), "4. Second window was closed recently");
ok(isRecent(state.windows[0]._closedTabs[0].closedAt), "4. First tab was closed recently");
ok(isRecent(state.windows[0]._closedTabs[1].closedAt), "4. Second tab was closed recently");
yield promiseCleanup();
});
add_task(function* test_cleanup() {
info("5. Altering closedAt to an old date, making sure that stuff gets collected, eventually");
yield promiseCleanup();
let state = getClosedState();
state._closedWindows[0].closedAt = LONG_TIME_AGO;
state.windows[0]._closedTabs[0].closedAt = LONG_TIME_AGO;
state.windows[0]._closedTabs[1].closedAt = Date.now();
let url = state.windows[0]._closedTabs[1].state.entries[0].url;
yield promiseBrowserState(state);
info("Sending idle-daily");
Services.obs.notifyObservers(null, "idle-daily", "");
info("Sent idle-daily");
state = JSON.parse(ss.getBrowserState());
is(state._closedWindows[0], undefined, "5. Second window was forgotten");
is(state.windows[0]._closedTabs.length, 1, "5. Only one closed tab left");
is(state.windows[0]._closedTabs[0].state.entries[0].url, url, "5. The second tab is still here");
yield promiseCleanup();
});

View File

@ -88,6 +88,12 @@ function provideWindow(aCallback, aURL, aFeatures) {
// This assumes that tests will at least have some state/entries // This assumes that tests will at least have some state/entries
function waitForBrowserState(aState, aSetStateCallback) { function waitForBrowserState(aState, aSetStateCallback) {
if (typeof aState == "string") {
aState = JSON.parse(aState);
}
if (typeof aState != "object") {
throw new TypeError("Argument must be an object or a JSON representation of an object");
}
let windows = [window]; let windows = [window];
let tabsRestored = 0; let tabsRestored = 0;
let expectedTabsRestored = 0; let expectedTabsRestored = 0;
@ -172,6 +178,10 @@ function waitForBrowserState(aState, aSetStateCallback) {
ss.setBrowserState(JSON.stringify(aState)); ss.setBrowserState(JSON.stringify(aState));
} }
function promiseBrowserState(aState) {
return new Promise(resolve => waitForBrowserState(aState, resolve));
}
// Doesn't assume that the tab needs to be closed in a cleanup function. // Doesn't assume that the tab needs to be closed in a cleanup function.
// If that's the case, the test author should handle that in the test. // If that's the case, the test author should handle that in the test.
function waitForTabState(aTab, aState, aCallback) { function waitForTabState(aTab, aState, aCallback) {
@ -481,6 +491,9 @@ function whenDelayedStartupFinished(aWindow, aCallback) {
} }
}, "browser-delayed-startup-finished", false); }, "browser-delayed-startup-finished", false);
} }
function promiseDelayedStartupFinished(aWindow) {
return new Promise((resolve) => whenDelayedStartupFinished(aWindow, resolve));
}
/** /**
* The test runner that controls the execution flow of our tests. * The test runner that controls the execution flow of our tests.

View File

@ -26,6 +26,11 @@
min-height: 18px; min-height: 18px;
} }
#downloads-button[cui-areatype="toolbar"] > #downloads-indicator-anchor > #downloads-indicator-icon:-moz-lwtheme-brighttext {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
0, 198, 18, 180) center no-repeat;
}
#downloads-button[cui-areatype="toolbar"][attention] > #downloads-indicator-anchor > #downloads-indicator-icon { #downloads-button[cui-areatype="toolbar"][attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
background-image: url("chrome://browser/skin/downloads/download-glow.png"); background-image: url("chrome://browser/skin/downloads/download-glow.png");
} }
@ -44,6 +49,11 @@
background-size: 12px; background-size: 12px;
} }
#downloads-button:not([counter]) > #downloads-indicator-anchor >
#downloads-button-progress-area > #downloads-indicator-counter:-moz-lwtheme-brighttext {
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 198, 18, 180);
}
#downloads-button:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { #downloads-button:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
background-image: url("chrome://browser/skin/downloads/download-glow.png"); background-image: url("chrome://browser/skin/downloads/download-glow.png");
} }
@ -105,6 +115,12 @@
text-align: center; text-align: center;
} }
#downloads-indicator-counter:-moz-lwtheme-brighttext {
color: white;
text-shadow: 0 0 1px rgba(0,0,0,.7),
0 1px 1.5px rgba(0,0,0,.5);
}
#downloads-indicator-progress { #downloads-indicator-progress {
width: 18px; width: 18px;
height: 6px; height: 6px;

View File

@ -2547,7 +2547,7 @@ AC_LANG_C
dnl Check for .hidden assembler directive and visibility attribute. dnl Check for .hidden assembler directive and visibility attribute.
dnl Borrowed from glibc configure.in dnl Borrowed from glibc configure.in
dnl =============================================================== dnl ===============================================================
if test "$GNU_CC"; then if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
if test -n "$gonkdir"; then if test -n "$gonkdir"; then
@ -5806,6 +5806,11 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
MOZ_D3DCOMPILER_VISTA_DLL= MOZ_D3DCOMPILER_VISTA_DLL=
fi fi
# On mingw, check if headers are provided by toolchain.
if test -n "$GNU_CC"; then
MOZ_CHECK_HEADER(d3d10.h, MOZ_HAS_WINSDK_WITH_D3D=1)
fi
###################################### ######################################
# Find _43 for use by XP. # Find _43 for use by XP.

View File

@ -10,6 +10,7 @@
#include "mozilla/DOMEventTargetHelper.h" #include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/EventSourceBinding.h" #include "mozilla/dom/EventSourceBinding.h"
#include "mozilla/dom/MessageEvent.h" #include "mozilla/dom/MessageEvent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "js/OldDebugAPI.h" #include "js/OldDebugAPI.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
@ -29,7 +30,6 @@
#include "nsIChannelPolicy.h" #include "nsIChannelPolicy.h"
#include "nsIContentSecurityPolicy.h" #include "nsIContentSecurityPolicy.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "xpcpublic.h" #include "xpcpublic.h"
#include "nsCrossSiteListenerProxy.h" #include "nsCrossSiteListenerProxy.h"
@ -1236,15 +1236,15 @@ EventSource::DispatchAllMessageEvents()
return; return;
} }
// Let's play get the JSContext // We need a parent object so that we can enter its compartment.
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner()); nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
NS_ENSURE_TRUE_VOID(sgo); if (NS_WARN_IF(!parentObject)) {
return;
}
nsIScriptContext* scriptContext = sgo->GetContext(); AutoJSAPI jsapi;
NS_ENSURE_TRUE_VOID(scriptContext); JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, parentObject->GetGlobalJSObject());
AutoPushJSContext cx(scriptContext->GetNativeContext());
NS_ENSURE_TRUE_VOID(cx);
while (mMessagesToDispatch.GetSize() > 0) { while (mMessagesToDispatch.GetSize() > 0) {
nsAutoPtr<Message> nsAutoPtr<Message>

View File

@ -33,7 +33,6 @@
#include "nsIDOMApplicationRegistry.h" #include "nsIDOMApplicationRegistry.h"
#include "nsIBaseWindow.h" #include "nsIBaseWindow.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
@ -2423,12 +2422,6 @@ nsFrameLoader::EnsureMessageManager()
return NS_OK; return NS_OK;
} }
nsIScriptContext* sctx = mOwnerContent->GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(sctx);
AutoPushJSContext cx(sctx->GetNativeContext());
NS_ENSURE_STATE(cx);
nsCOMPtr<nsIDOMChromeWindow> chromeWindow = nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
do_QueryInterface(GetOwnerDoc()->GetWindow()); do_QueryInterface(GetOwnerDoc()->GetWindow());
nsCOMPtr<nsIMessageBroadcaster> parentManager; nsCOMPtr<nsIMessageBroadcaster> parentManager;

View File

@ -4286,16 +4286,18 @@ CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager *aManager)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CanvasPath) NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPath, mParent)
CanvasPath::CanvasPath(nsCOMPtr<nsISupports> aParent) : mParent(aParent) CanvasPath::CanvasPath(nsISupports* aParent)
: mParent(aParent)
{ {
SetIsDOMBinding(); SetIsDOMBinding();
mPathBuilder = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()->CreatePathBuilder(); mPathBuilder = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()->CreatePathBuilder();
} }
CanvasPath::CanvasPath(nsCOMPtr<nsISupports> aParent, RefPtr<PathBuilder> aPathBuilder): mParent(aParent), mPathBuilder(aPathBuilder) CanvasPath::CanvasPath(nsISupports* aParent, RefPtr<PathBuilder> aPathBuilder)
: mParent(aParent), mPathBuilder(aPathBuilder)
{ {
SetIsDOMBinding(); SetIsDOMBinding();

View File

@ -46,7 +46,7 @@ extern const mozilla::gfx::Float SIGMA_MAX;
template<typename T> class Optional; template<typename T> class Optional;
class CanvasPath : class CanvasPath MOZ_FINAL :
public nsWrapperCache public nsWrapperCache
{ {
public: public:
@ -88,8 +88,8 @@ public:
mozilla::RefPtr<mozilla::gfx::Path> GetPath(const CanvasWindingRule& winding, mozilla::RefPtr<mozilla::gfx::Path> GetPath(const CanvasWindingRule& winding,
const mozilla::RefPtr<mozilla::gfx::DrawTarget>& mTarget) const; const mozilla::RefPtr<mozilla::gfx::DrawTarget>& mTarget) const;
CanvasPath(nsCOMPtr<nsISupports> aParent); explicit CanvasPath(nsISupports* aParent);
CanvasPath(nsCOMPtr<nsISupports> aParent, RefPtr<gfx::PathBuilder> mPathBuilder); CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);
virtual ~CanvasPath() {} virtual ~CanvasPath() {}
private: private:

View File

@ -383,4 +383,8 @@ function runTests() {
addLoadEvent(runTests); addLoadEvent(runTests);
// Don't leak the world via the Path2D reference to its window.
document.all;
window.p = new Path2D();
</script> </script>

View File

@ -426,7 +426,7 @@ protected:
NS_IMETHOD Run() MOZ_OVERRIDE NS_IMETHOD Run() MOZ_OVERRIDE
{ {
static_cast<HTMLFormElement*>(mEventNode.get())->EventHandled(); static_cast<HTMLFormElement*>(mTarget.get())->EventHandled();
return AsyncEventDispatcher::Run(); return AsyncEventDispatcher::Run();
} }
}; };

View File

@ -166,8 +166,7 @@ AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
} }
void void
AudioBuffer::SetRawChannelContents(JSContext* aJSContext, uint32_t aChannel, AudioBuffer::SetRawChannelContents(uint32_t aChannel, float* aContents)
float* aContents)
{ {
PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannel]), aContents, mLength); PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannel]), aContents, mLength);
} }

View File

@ -97,9 +97,7 @@ public:
// This function needs to be called on an AudioBuffer which has not been // This function needs to be called on an AudioBuffer which has not been
// handed off to the content yet, and right after the object has been // handed off to the content yet, and right after the object has been
// initialized. // initialized.
void SetRawChannelContents(JSContext* aJSContext, void SetRawChannelContents(uint32_t aChannel, float* aContents);
uint32_t aChannel,
float* aContents);
protected: protected:
bool RestoreJSChannelData(JSContext* aJSContext); bool RestoreJSChannelData(JSContext* aJSContext);

View File

@ -590,21 +590,16 @@ AudioContext::UpdateNodeCount(int32_t aDelta)
} }
} }
JSContext* JSObject*
AudioContext::GetJSContext() const AudioContext::GetGlobalJSObject() const
{ {
MOZ_ASSERT(NS_IsMainThread()); nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
if (!parentObject) {
return nullptr;
}
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal = // This can also return null.
do_QueryInterface(GetParentObject()); return parentObject->GetGlobalJSObject();
if (!scriptGlobal) {
return nullptr;
}
nsIScriptContext* scriptContext = scriptGlobal->GetContext();
if (!scriptContext) {
return nullptr;
}
return scriptContext->GetNativeContext();
} }
void void

View File

@ -219,7 +219,7 @@ public:
void Mute() const; void Mute() const;
void Unmute() const; void Unmute() const;
JSContext* GetJSContext() const; JSObject* GetGlobalJSObject() const;
AudioChannel MozAudioChannelType() const; AudioChannel MozAudioChannelType() const;
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv); void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);

View File

@ -6,6 +6,7 @@
#include "AudioDestinationNode.h" #include "AudioDestinationNode.h"
#include "mozilla/dom/AudioDestinationNodeBinding.h" #include "mozilla/dom/AudioDestinationNodeBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "AudioChannelAgent.h" #include "AudioChannelAgent.h"
@ -125,11 +126,15 @@ public:
// which is strongly referenced by the runnable that called // which is strongly referenced by the runnable that called
// AudioDestinationNode::FireOfflineCompletionEvent. // AudioDestinationNode::FireOfflineCompletionEvent.
AutoPushJSContext cx(context->GetJSContext()); // We need the global for the context so that we can enter its compartment.
if (!cx) { JSObject* global = context->GetGlobalJSObject();
if (NS_WARN_IF(!global)) {
return; return;
} }
JSAutoRequest ar(cx);
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, global);
// Create the input buffer // Create the input buffer
nsRefPtr<AudioBuffer> renderedBuffer = new AudioBuffer(context, nsRefPtr<AudioBuffer> renderedBuffer = new AudioBuffer(context,
@ -139,7 +144,7 @@ public:
return; return;
} }
for (uint32_t i = 0; i < mInputChannels.Length(); ++i) { for (uint32_t i = 0; i < mInputChannels.Length(); ++i) {
renderedBuffer->SetRawChannelContents(cx, i, mInputChannels[i]); renderedBuffer->SetRawChannelContents(i, mInputChannels[i]);
} }
nsRefPtr<OfflineAudioCompletionEvent> event = nsRefPtr<OfflineAudioCompletionEvent> event =

View File

@ -6,6 +6,7 @@
#include "AudioProcessingEvent.h" #include "AudioProcessingEvent.h"
#include "mozilla/dom/AudioProcessingEventBinding.h" #include "mozilla/dom/AudioProcessingEventBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "AudioContext.h" #include "AudioContext.h"
namespace mozilla { namespace mozilla {
@ -40,7 +41,15 @@ void
AudioProcessingEvent::LazilyCreateBuffer(nsRefPtr<AudioBuffer>& aBuffer, AudioProcessingEvent::LazilyCreateBuffer(nsRefPtr<AudioBuffer>& aBuffer,
uint32_t aNumberOfChannels) uint32_t aNumberOfChannels)
{ {
AutoPushJSContext cx(mNode->Context()->GetJSContext()); // We need the global for the context so that we can enter its compartment.
JSObject* global = mNode->Context()->GetGlobalJSObject();
if (NS_WARN_IF(!global)) {
return;
}
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, global);
aBuffer = new AudioBuffer(mNode->Context(), mNode->BufferSize(), aBuffer = new AudioBuffer(mNode->Context(), mNode->BufferSize(),
mNode->Context()->SampleRate()); mNode->Context()->SampleRate());

View File

@ -7,6 +7,7 @@
#include "MediaBufferDecoder.h" #include "MediaBufferDecoder.h"
#include "BufferDecoder.h" #include "BufferDecoder.h"
#include "mozilla/dom/AudioContextBinding.h" #include "mozilla/dom/AudioContextBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include <speex/speex_resampler.h> #include <speex/speex_resampler.h>
#include "nsXPCOMCIDInternal.h" #include "nsXPCOMCIDInternal.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
@ -18,7 +19,6 @@
#include "nsIScriptObjectPrincipal.h" #include "nsIScriptObjectPrincipal.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "nsMimeTypes.h" #include "nsMimeTypes.h"
#include "nsCxPusher.h"
#include "WebAudioUtils.h" #include "WebAudioUtils.h"
namespace mozilla { namespace mozilla {
@ -402,12 +402,16 @@ WebAudioDecodeJob::AllocateBuffer()
MOZ_ASSERT(!mOutput); MOZ_ASSERT(!mOutput);
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
// First, get a JSContext // We need the global for the context so that we can enter its compartment.
AutoPushJSContext cx(mContext->GetJSContext()); JSObject* global = mContext->GetGlobalJSObject();
if (!cx) { if (NS_WARN_IF(!global)) {
return false; return false;
} }
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, global);
// Now create the AudioBuffer // Now create the AudioBuffer
mOutput = new AudioBuffer(mContext, mWriteIndex, mContext->SampleRate()); mOutput = new AudioBuffer(mContext, mWriteIndex, mContext->SampleRate());
if (!mOutput->InitializeBuffers(mChannelBuffers.Length(), cx)) { if (!mOutput->InitializeBuffers(mChannelBuffers.Length(), cx)) {
@ -415,7 +419,7 @@ WebAudioDecodeJob::AllocateBuffer()
} }
for (uint32_t i = 0; i < mChannelBuffers.Length(); ++i) { for (uint32_t i = 0; i < mChannelBuffers.Length(); ++i) {
mOutput->SetRawChannelContents(cx, i, mChannelBuffers[i]); mOutput->SetRawChannelContents(i, mChannelBuffers[i]);
} }
return true; return true;

View File

@ -12,7 +12,7 @@
#include "AudioNodeStream.h" #include "AudioNodeStream.h"
#include "AudioProcessingEvent.h" #include "AudioProcessingEvent.h"
#include "WebAudioUtils.h" #include "WebAudioUtils.h"
#include "nsCxPusher.h" #include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "mozilla/PodOperations.h" #include "mozilla/PodOperations.h"
#include <deque> #include <deque>
@ -402,44 +402,51 @@ private:
return NS_OK; return NS_OK;
} }
AutoPushJSContext cx(node->Context()->GetJSContext()); // Get the global for the context so that we can enter its compartment.
if (cx) { JSObject* global = node->Context()->GetGlobalJSObject();
if (NS_WARN_IF(!global)) {
// Create the input buffer return NS_OK;
nsRefPtr<AudioBuffer> inputBuffer;
if (!mNullInput) {
inputBuffer = new AudioBuffer(node->Context(),
node->BufferSize(),
node->Context()->SampleRate());
if (!inputBuffer->InitializeBuffers(mInputChannels.Length(), cx)) {
return NS_OK;
}
// Put the channel data inside it
for (uint32_t i = 0; i < mInputChannels.Length(); ++i) {
inputBuffer->SetRawChannelContents(cx, i, mInputChannels[i]);
}
}
// Ask content to produce data in the output buffer
// Note that we always avoid creating the output buffer here, and we try to
// avoid creating the input buffer as well. The AudioProcessingEvent class
// knows how to lazily create them if needed once the script tries to access
// them. Otherwise, we may be able to get away without creating them!
nsRefPtr<AudioProcessingEvent> event = new AudioProcessingEvent(node, nullptr, nullptr);
event->InitEvent(inputBuffer,
mInputChannels.Length(),
mPlaybackTime);
node->DispatchTrustedEvent(event);
// Steal the output buffers
nsRefPtr<ThreadSharedFloatArrayBufferList> output;
if (event->HasOutputBuffer()) {
output = event->OutputBuffer()->GetThreadSharedChannelsForRate(cx);
}
// Append it to our output buffer queue
node->GetSharedBuffers()->FinishProducingOutputBuffer(output, node->BufferSize());
} }
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, global);
// Create the input buffer
nsRefPtr<AudioBuffer> inputBuffer;
if (!mNullInput) {
inputBuffer = new AudioBuffer(node->Context(),
node->BufferSize(),
node->Context()->SampleRate());
if (!inputBuffer->InitializeBuffers(mInputChannels.Length(), cx)) {
return NS_OK;
}
// Put the channel data inside it
for (uint32_t i = 0; i < mInputChannels.Length(); ++i) {
inputBuffer->SetRawChannelContents(i, mInputChannels[i]);
}
}
// Ask content to produce data in the output buffer
// Note that we always avoid creating the output buffer here, and we try to
// avoid creating the input buffer as well. The AudioProcessingEvent class
// knows how to lazily create them if needed once the script tries to access
// them. Otherwise, we may be able to get away without creating them!
nsRefPtr<AudioProcessingEvent> event = new AudioProcessingEvent(node, nullptr, nullptr);
event->InitEvent(inputBuffer,
mInputChannels.Length(),
mPlaybackTime);
node->DispatchTrustedEvent(event);
// Steal the output buffers
nsRefPtr<ThreadSharedFloatArrayBufferList> output;
if (event->HasOutputBuffer()) {
output = event->OutputBuffer()->GetThreadSharedChannelsForRate(cx);
}
// Append it to our output buffer queue
node->GetSharedBuffers()->FinishProducingOutputBuffer(output, node->BufferSize());
return NS_OK; return NS_OK;
} }
private: private:

View File

@ -577,7 +577,7 @@ nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDOMWindowUtils::GetIsHistoryRestored(bool* aIsHistoryRestored) { nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) {
if (!nsContentUtils::IsCallerChrome()) { if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR; return NS_ERROR_DOM_SECURITY_ERR;
} }
@ -588,7 +588,7 @@ nsDOMWindowUtils::GetIsHistoryRestored(bool* aIsHistoryRestored) {
} }
const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
*aIsHistoryRestored = sf && sf->DidHistoryRestore(); *aIsResolutionSet = sf && sf->IsResolutionSet();
return NS_OK; return NS_OK;
} }

View File

@ -13452,12 +13452,6 @@ nsGlobalWindow::GetMessageManager(ErrorResult& aError)
MOZ_ASSERT(IsChromeWindow()); MOZ_ASSERT(IsChromeWindow());
nsGlobalChromeWindow* myself = static_cast<nsGlobalChromeWindow*>(this); nsGlobalChromeWindow* myself = static_cast<nsGlobalChromeWindow*>(this);
if (!myself->mMessageManager) { if (!myself->mMessageManager) {
nsIScriptContext* scx = GetContextInternal();
if (NS_WARN_IF(!scx || !(scx->GetNativeContext()))) {
aError.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsCOMPtr<nsIMessageBroadcaster> globalMM = nsCOMPtr<nsIMessageBroadcaster> globalMM =
do_GetService("@mozilla.org/globalmessagemanager;1"); do_GetService("@mozilla.org/globalmessagemanager;1");
myself->mMessageManager = myself->mMessageManager =

View File

@ -19,13 +19,13 @@ using namespace dom;
* mozilla::AsyncEventDispatcher * mozilla::AsyncEventDispatcher
******************************************************************************/ ******************************************************************************/
AsyncEventDispatcher::AsyncEventDispatcher(nsINode* aEventNode, AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget,
WidgetEvent& aEvent) WidgetEvent& aEvent)
: mEventNode(aEventNode) : mTarget(aTarget)
, mDispatchChromeOnly(false) , mDispatchChromeOnly(false)
{ {
MOZ_ASSERT(mEventNode); MOZ_ASSERT(mTarget);
EventDispatcher::CreateEvent(aEventNode, nullptr, &aEvent, EmptyString(), EventDispatcher::CreateEvent(aTarget, nullptr, &aEvent, EmptyString(),
getter_AddRefs(mEvent)); getter_AddRefs(mEvent));
NS_ASSERTION(mEvent, "Should never fail to create an event"); NS_ASSERTION(mEvent, "Should never fail to create an event");
mEvent->DuplicatePrivateData(); mEvent->DuplicatePrivateData();
@ -39,8 +39,9 @@ AsyncEventDispatcher::Run()
if (mDispatchChromeOnly) { if (mDispatchChromeOnly) {
MOZ_ASSERT(mEvent->InternalDOMEvent()->IsTrusted()); MOZ_ASSERT(mEvent->InternalDOMEvent()->IsTrusted());
nsCOMPtr<nsIDocument> ownerDoc = mEventNode->OwnerDoc(); nsCOMPtr<nsINode> node = do_QueryInterface(mTarget);
nsPIDOMWindow* window = ownerDoc->GetWindow(); MOZ_ASSERT(node, "ChromeOnly dispatch supported with Node targets only!");
nsPIDOMWindow* window = node->OwnerDoc()->GetWindow();
if (!window) { if (!window) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
@ -52,18 +53,23 @@ AsyncEventDispatcher::Run()
EventDispatcher::DispatchDOMEvent(target, nullptr, mEvent, EventDispatcher::DispatchDOMEvent(target, nullptr, mEvent,
nullptr, nullptr); nullptr, nullptr);
} else { } else {
nsCOMPtr<EventTarget> target = mEventNode.get();
bool defaultActionEnabled; // This is not used because the caller is async bool defaultActionEnabled; // This is not used because the caller is async
target->DispatchEvent(mEvent, &defaultActionEnabled); mTarget->DispatchEvent(mEvent, &defaultActionEnabled);
} }
} else { } else {
nsIDocument* doc = mEventNode->OwnerDoc();
if (mDispatchChromeOnly) { if (mDispatchChromeOnly) {
nsContentUtils::DispatchChromeEvent(doc, mEventNode, mEventType, nsCOMPtr<nsINode> node = do_QueryInterface(mTarget);
MOZ_ASSERT(node, "ChromeOnly dispatch supported with Node targets only!");
nsContentUtils::DispatchChromeEvent(node->OwnerDoc(), node, mEventType,
mBubbles, false); mBubbles, false);
} else { } else {
nsContentUtils::DispatchTrustedEvent(doc, mEventNode, mEventType, nsCOMPtr<nsIDOMEvent> event;
mBubbles, false); NS_NewDOMEvent(getter_AddRefs(event), mTarget, nullptr, nullptr);
nsresult rv = event->InitEvent(mEventType, mBubbles, false);
NS_ENSURE_SUCCESS(rv, rv);
event->SetTrusted(true);
bool dummy;
mTarget->DispatchEvent(event, &dummy);
} }
} }
@ -73,12 +79,14 @@ AsyncEventDispatcher::Run()
nsresult nsresult
AsyncEventDispatcher::PostDOMEvent() AsyncEventDispatcher::PostDOMEvent()
{ {
nsRefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
return NS_DispatchToCurrentThread(this); return NS_DispatchToCurrentThread(this);
} }
void void
AsyncEventDispatcher::RunDOMEventWhenSafe() AsyncEventDispatcher::RunDOMEventWhenSafe()
{ {
nsRefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
nsContentUtils::AddScriptRunner(this); nsContentUtils::AddScriptRunner(this);
} }

View File

@ -26,29 +26,38 @@ namespace mozilla {
class AsyncEventDispatcher : public nsRunnable class AsyncEventDispatcher : public nsRunnable
{ {
public: public:
AsyncEventDispatcher(nsINode* aEventNode, const nsAString& aEventType, AsyncEventDispatcher(nsINode* aTarget, const nsAString& aEventType,
bool aBubbles, bool aDispatchChromeOnly) bool aBubbles, bool aDispatchChromeOnly)
: mEventNode(aEventNode) : mTarget(aTarget)
, mEventType(aEventType) , mEventType(aEventType)
, mBubbles(aBubbles) , mBubbles(aBubbles)
, mDispatchChromeOnly(aDispatchChromeOnly) , mDispatchChromeOnly(aDispatchChromeOnly)
{ {
} }
AsyncEventDispatcher(nsINode* aEventNode, nsIDOMEvent* aEvent) AsyncEventDispatcher(dom::EventTarget* aTarget, const nsAString& aEventType,
: mEventNode(aEventNode) bool aBubbles)
: mTarget(aTarget)
, mEventType(aEventType)
, mBubbles(aBubbles)
, mDispatchChromeOnly(false)
{
}
AsyncEventDispatcher(dom::EventTarget* aTarget, nsIDOMEvent* aEvent)
: mTarget(aTarget)
, mEvent(aEvent) , mEvent(aEvent)
, mDispatchChromeOnly(false) , mDispatchChromeOnly(false)
{ {
} }
AsyncEventDispatcher(nsINode* aEventNode, WidgetEvent& aEvent); AsyncEventDispatcher(dom::EventTarget* aTarget, WidgetEvent& aEvent);
NS_IMETHOD Run() MOZ_OVERRIDE; NS_IMETHOD Run() MOZ_OVERRIDE;
nsresult PostDOMEvent(); nsresult PostDOMEvent();
void RunDOMEventWhenSafe(); void RunDOMEventWhenSafe();
nsCOMPtr<nsINode> mEventNode; nsCOMPtr<dom::EventTarget> mTarget;
nsCOMPtr<nsIDOMEvent> mEvent; nsCOMPtr<nsIDOMEvent> mEvent;
nsString mEventType; nsString mEventType;
bool mBubbles; bool mBubbles;

View File

@ -48,7 +48,7 @@ interface nsIRunnable;
interface nsICompositionStringSynthesizer; interface nsICompositionStringSynthesizer;
interface nsITranslationNodeList; interface nsITranslationNodeList;
[scriptable, uuid(8489681a-7407-457e-b889-53d1ae999b30)] [scriptable, uuid(aae2d993-366f-43e6-aa51-f2eb83935e7d)]
interface nsIDOMWindowUtils : nsISupports { interface nsIDOMWindowUtils : nsISupports {
/** /**
@ -231,13 +231,13 @@ interface nsIDOMWindowUtils : nsISupports {
void getResolution(out float aXResolution, out float aYResolution); void getResolution(out float aXResolution, out float aYResolution);
/** /**
* Whether the current window has been restored from session history. * Whether the resolution has been set by the user.
* This gives a way to check whether the provided resolution and scroll * This gives a way to check whether the provided resolution is the default
* position are default values or restored from a previous session. * value or restored from a previous session.
* *
* Can only be accessed with chrome privileges. * Can only be accessed with chrome privileges.
*/ */
readonly attribute boolean isHistoryRestored; readonly attribute boolean isResolutionSet;
/** /**
* Whether the next paint should be flagged as the first paint for a document. * Whether the next paint should be flagged as the first paint for a document.

View File

@ -501,6 +501,11 @@ nsTArray<ContentParent*>* ContentParent::sNonAppContentParents;
nsTArray<ContentParent*>* ContentParent::sPrivateContent; nsTArray<ContentParent*>* ContentParent::sPrivateContent;
StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents; StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
#ifdef MOZ_NUWA_PROCESS
// The pref updates sent to the Nuwa process.
static nsTArray<PrefSetting>* sNuwaPrefUpdates;
#endif
// This is true when subprocess launching is enabled. This is the // This is true when subprocess launching is enabled. This is the
// case between StartUp() and ShutDown() or JoinAllSubprocesses(). // case between StartUp() and ShutDown() or JoinAllSubprocesses().
static bool sCanLaunchSubprocesses; static bool sCanLaunchSubprocesses;
@ -1325,6 +1330,14 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
// remove the global remote preferences observers // remove the global remote preferences observers
Preferences::RemoveObserver(this, ""); Preferences::RemoveObserver(this, "");
#ifdef MOZ_NUWA_PROCESS
// Remove the pref update requests.
if (IsNuwaProcess() && sNuwaPrefUpdates) {
delete sNuwaPrefUpdates;
sNuwaPrefUpdates = nullptr;
}
#endif
RecvRemoveGeolocationListener(); RecvRemoveGeolocationListener();
mConsoleService = nullptr; mConsoleService = nullptr;
@ -2115,6 +2128,13 @@ ContentParent::RecvAddNewProcess(const uint32_t& aPid,
aPid, aPid,
aFds); aFds);
content->Init(); content->Init();
size_t numNuwaPrefUpdates = sNuwaPrefUpdates ?
sNuwaPrefUpdates->Length() : 0;
// Resend pref updates to the forked child.
for (int i = 0; i < numNuwaPrefUpdates; i++) {
content->SendPreferenceUpdate(sNuwaPrefUpdates->ElementAt(i));
}
PreallocatedProcessManager::PublishSpareProcess(content); PreallocatedProcessManager::PublishSpareProcess(content);
return true; return true;
#else #else
@ -2162,9 +2182,22 @@ ContentParent::Observe(nsISupports* aSubject,
PrefSetting pref(strData, null_t(), null_t()); PrefSetting pref(strData, null_t(), null_t());
Preferences::GetPreference(&pref); Preferences::GetPreference(&pref);
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess() && PreallocatedProcessManager::IsNuwaReady()) {
// Don't send the pref update to the Nuwa process. Save the update
// to send to the forked child.
if (!sNuwaPrefUpdates) {
sNuwaPrefUpdates = new nsTArray<PrefSetting>();
}
sNuwaPrefUpdates->AppendElement(pref);
} else if (!SendPreferenceUpdate(pref)) {
return NS_ERROR_NOT_AVAILABLE;
}
#else
if (!SendPreferenceUpdate(pref)) { if (!SendPreferenceUpdate(pref)) {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
#endif
} }
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) { else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
NS_ConvertUTF16toUTF8 dataStr(aData); NS_ConvertUTF16toUTF8 dataStr(aData);

View File

@ -54,6 +54,7 @@ public:
void DelayedNuwaFork(); void DelayedNuwaFork();
void PublishSpareProcess(ContentParent* aContent); void PublishSpareProcess(ContentParent* aContent);
void MaybeForgetSpare(ContentParent* aContent); void MaybeForgetSpare(ContentParent* aContent);
bool IsNuwaReady();
void OnNuwaReady(); void OnNuwaReady();
bool PreallocatedProcessReady(); bool PreallocatedProcessReady();
already_AddRefed<ContentParent> GetSpareProcess(); already_AddRefed<ContentParent> GetSpareProcess();
@ -340,6 +341,12 @@ PreallocatedProcessManagerImpl::MaybeForgetSpare(ContentParent* aContent)
} }
} }
bool
PreallocatedProcessManagerImpl::IsNuwaReady()
{
return mIsNuwaReady;
}
void void
PreallocatedProcessManagerImpl::OnNuwaReady() PreallocatedProcessManagerImpl::OnNuwaReady()
{ {
@ -482,6 +489,12 @@ PreallocatedProcessManager::OnNuwaReady()
GetPPMImpl()->OnNuwaReady(); GetPPMImpl()->OnNuwaReady();
} }
/* static */ bool
PreallocatedProcessManager::IsNuwaReady()
{
return GetPPMImpl()->IsNuwaReady();
}
/*static */ bool /*static */ bool
PreallocatedProcessManager::PreallocatedProcessReady() PreallocatedProcessManager::PreallocatedProcessReady()
{ {

View File

@ -83,6 +83,7 @@ public:
#ifdef MOZ_NUWA_PROCESS #ifdef MOZ_NUWA_PROCESS
static void PublishSpareProcess(ContentParent* aContent); static void PublishSpareProcess(ContentParent* aContent);
static void MaybeForgetSpare(ContentParent* aContent); static void MaybeForgetSpare(ContentParent* aContent);
static bool IsNuwaReady();
static void OnNuwaReady(); static void OnNuwaReady();
static bool PreallocatedProcessReady(); static bool PreallocatedProcessReady();
static void RunAfterPreallocatedProcessReady(nsIRunnable* aRunnable); static void RunAfterPreallocatedProcessReady(nsIRunnable* aRunnable);

View File

@ -2093,7 +2093,7 @@ MOZ_CXX11
dnl Check for .hidden assembler directive and visibility attribute. dnl Check for .hidden assembler directive and visibility attribute.
dnl Borrowed from glibc configure.in dnl Borrowed from glibc configure.in
dnl =============================================================== dnl ===============================================================
if test "$GNU_CC"; then if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
if test -n "$gonkdir"; then if test -n "$gonkdir"; then

View File

@ -2,7 +2,7 @@ Modifications to upstream libffi needed for the Mozilla build:
* Clear INFO_DEPS so that builds don't fail when makeinfo isn't present. * Clear INFO_DEPS so that builds don't fail when makeinfo isn't present.
- This can be removed if https://github.com/atgreen/libffi/issues/111 is fixed. - This can be removed if https://github.com/atgreen/libffi/issues/111 is fixed.
* Various workarounds for pymake bugs. * Various workarounds for pymake bugs.
- Once pymake support is fully deprecated, hunks 2 & 3 be safely removed. - Once pymake support is fully deprecated, hunks 2-4 be safely removed.
diff --git a/js/src/ctypes/libffi/Makefile.in b/js/src/ctypes/libffi/Makefile.in diff --git a/js/src/ctypes/libffi/Makefile.in b/js/src/ctypes/libffi/Makefile.in
--- a/js/src/ctypes/libffi/Makefile.in --- a/js/src/ctypes/libffi/Makefile.in
@ -26,7 +26,30 @@ diff --git a/js/src/ctypes/libffi/Makefile.in b/js/src/ctypes/libffi/Makefile.in
TEXINFOS = doc/libffi.texi TEXINFOS = doc/libffi.texi
TEXI2DVI = texi2dvi TEXI2DVI = texi2dvi
TEXI2PDF = $(TEXI2DVI) --pdf --batch TEXI2PDF = $(TEXI2DVI) --pdf --batch
@@ -1292,57 +1292,57 @@ distclean-compile: @@ -758,18 +758,20 @@ Makefile: $(srcdir)/Makefile.in $(top_bu
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
fficonfig.h: stamp-h1
- @test -f $@ || rm -f stamp-h1
- @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
stamp-h1: $(srcdir)/fficonfig.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status fficonfig.h
$(srcdir)/fficonfig.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
@@ -1292,57 +1294,57 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/freebsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/freebsd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/sysv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/unix64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/unix64.Plo@am__quote@
@ -90,7 +113,7 @@ diff --git a/js/src/ctypes/libffi/Makefile.in b/js/src/ctypes/libffi/Makefile.in
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool: mostlyclean-libtool:
@@ -1443,17 +1443,17 @@ doc/libffi.html: doc/libffi.texi $(srcdi @@ -1443,17 +1445,17 @@ doc/libffi.html: doc/libffi.texi $(srcdi
-@rm -f vti.tmp -@rm -f vti.tmp
@cp $(srcdir)/doc/version.texi $@ @cp $(srcdir)/doc/version.texi $@

View File

@ -763,8 +763,10 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps): $(am__aclocal_m4_deps):
fficonfig.h: stamp-h1 fficonfig.h: stamp-h1
@test -f $@ || rm -f stamp-h1 @if test ! -f $@; then \
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/fficonfig.h.in $(top_builddir)/config.status stamp-h1: $(srcdir)/fficonfig.h.in $(top_builddir)/config.status
@rm -f stamp-h1 @rm -f stamp-h1

View File

@ -237,7 +237,7 @@ if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
})(); })();
/* Implicit "use strict" context */ /* Implicit "use strict" context in modules */
(function() { (function() {
var funcHeader = 'function (glob, ffi, heap) {', var funcHeader = 'function (glob, ffi, heap) {',
@ -336,3 +336,33 @@ if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
} }
})(); })();
/* Implicit "use strict" context in functions */
(function () {
var funcCode = 'function g(x) {\n\
x=x|0;\n\
return x + 1 | 0;}';
var moduleCode = 'function () {\n\
"use asm";\n' + funcCode + '\n\
return g;\n\
}',
useStrict = '"use strict";';
var f5 = eval(useStrict + ";\n(" + moduleCode + "())");
var expectedToString = funcCode.replace('{', '{\n' + useStrict + '\n')
var expectedToSource = expectedToString
assertEq(f5.toString(), expectedToString);
assertEq(f5.toSource(), expectedToSource);
if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
var mf5 = eval("\"use strict\";\n(" + moduleCode + ")");
assertEq(isAsmJSModuleLoadedFromCache(mf5), true);
var f5 = mf5();
assertEq(f5.toString(), expectedToString);
assertEq(f5.toSource(), expectedToSource);
}
})();

View File

@ -585,6 +585,7 @@ HandleDynamicLinkFailure(JSContext *cx, CallArgs args, AsmJSModule &module, Hand
CompileOptions options(cx); CompileOptions options(cx);
options.setOriginPrincipals(module.scriptSource()->originPrincipals()) options.setOriginPrincipals(module.scriptSource()->originPrincipals())
.setFile(module.scriptSource()->filename())
.setCompileAndGo(false) .setCompileAndGo(false)
.setNoScriptRval(false); .setNoScriptRval(false);
@ -860,6 +861,28 @@ js::IsAsmJSModule(HandleFunction fun)
return fun->isNative() && fun->maybeNative() == LinkAsmJS; return fun->isNative() && fun->maybeNative() == LinkAsmJS;
} }
static bool
AppendUseStrictSource(JSContext *cx, HandleFunction fun, Handle<JSFlatString*> src, StringBuffer &out)
{
// We need to add "use strict" in the body right after the opening
// brace.
size_t bodyStart = 0, bodyEnd;
// No need to test for functions created with the Function ctor as
// these don't implicitly inherit the "use strict" context. Strict mode is
// enabled for functions created with the Function ctor only if they begin with
// the "use strict" directive, but these functions won't validate as asm.js
// modules.
ConstTwoByteChars chars(src->chars(), src->length());
if (!FindBody(cx, fun, chars, src->length(), &bodyStart, &bodyEnd))
return false;
return out.append(chars, bodyStart) &&
out.append("\n\"use strict\";\n") &&
out.append(chars + bodyStart, src->length() - bodyStart);
}
JSString * JSString *
js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda) js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda)
{ {
@ -909,26 +932,8 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
return nullptr; return nullptr;
if (module.strict()) { if (module.strict()) {
// We need to add "use strict" in the body right after the opening if (!AppendUseStrictSource(cx, fun, src, out))
// brace.
size_t bodyStart = 0, bodyEnd;
// No need to test for functions created with the Function ctor as
// these doesn't implicitly inherit the "use strict" context. Strict mode is
// enabled for functions created with the Function ctor only if they begin with
// the "use strict" directive, but these functions won't validate as asm.js
// modules.
ConstTwoByteChars chars(src->chars(), src->length());
if (!FindBody(cx, fun, chars, src->length(), &bodyStart, &bodyEnd))
return nullptr; return nullptr;
if (!out.append(chars, bodyStart) ||
!out.append("\n\"use strict\";\n") ||
!out.append(chars + bodyStart, src->length() - bodyStart))
{
return nullptr;
}
} else { } else {
if (!out.append(src->chars(), src->length())) if (!out.append(src->chars(), src->length()))
return nullptr; return nullptr;
@ -995,12 +1000,27 @@ js::AsmJSFunctionToString(JSContext *cx, HandleFunction fun)
if (!out.append("function ")) if (!out.append("function "))
return nullptr; return nullptr;
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end)); if (module.strict()) {
if (!src) // AppendUseStrictSource expects its input to start right after the
return nullptr; // function name, so split the source chars from the src into two parts:
// the function name and the rest (arguments + body).
if (!out.append(src->chars(), src->length())) // asm.js functions can't be anonymous
return nullptr; JS_ASSERT(fun->atom());
if (!out.append(fun->atom()))
return nullptr;
size_t nameEnd = begin + fun->atom()->length();
Rooted<JSFlatString*> src(cx, source->substring(cx, nameEnd, end));
if (!AppendUseStrictSource(cx, fun, src, out))
return nullptr;
} else {
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (!out.append(src->chars(), src->length()))
return nullptr;
}
return out.finishString(); return out.finishString();
} }

View File

@ -1567,71 +1567,71 @@ GenerateLIR(MIRGenerator *mir)
AllocationIntegrityState integrity(*lir); AllocationIntegrityState integrity(*lir);
TraceLogStartEvent(logger, TraceLogger::RegisterAllocation); {
AutoTraceLog log(logger, TraceLogger::RegisterAllocation);
switch (mir->optimizationInfo().registerAllocator()) { switch (mir->optimizationInfo().registerAllocator()) {
case RegisterAllocator_LSRA: { case RegisterAllocator_LSRA: {
#ifdef DEBUG #ifdef DEBUG
if (!integrity.record()) if (!integrity.record())
return nullptr; return nullptr;
#endif #endif
LinearScanAllocator regalloc(mir, &lirgen, *lir); LinearScanAllocator regalloc(mir, &lirgen, *lir);
if (!regalloc.go()) if (!regalloc.go())
return nullptr; return nullptr;
#ifdef DEBUG #ifdef DEBUG
if (!integrity.check(false)) if (!integrity.check(false))
return nullptr; return nullptr;
#endif #endif
IonSpewPass("Allocate Registers [LSRA]", &regalloc); IonSpewPass("Allocate Registers [LSRA]", &regalloc);
break; break;
} }
case RegisterAllocator_Backtracking: { case RegisterAllocator_Backtracking: {
#ifdef DEBUG #ifdef DEBUG
if (!integrity.record()) if (!integrity.record())
return nullptr; return nullptr;
#endif #endif
BacktrackingAllocator regalloc(mir, &lirgen, *lir); BacktrackingAllocator regalloc(mir, &lirgen, *lir);
if (!regalloc.go()) if (!regalloc.go())
return nullptr; return nullptr;
#ifdef DEBUG #ifdef DEBUG
if (!integrity.check(false)) if (!integrity.check(false))
return nullptr; return nullptr;
#endif #endif
IonSpewPass("Allocate Registers [Backtracking]"); IonSpewPass("Allocate Registers [Backtracking]");
break; break;
} }
case RegisterAllocator_Stupid: { case RegisterAllocator_Stupid: {
// Use the integrity checker to populate safepoint information, so // Use the integrity checker to populate safepoint information, so
// run it in all builds. // run it in all builds.
if (!integrity.record()) if (!integrity.record())
return nullptr; return nullptr;
StupidAllocator regalloc(mir, &lirgen, *lir); StupidAllocator regalloc(mir, &lirgen, *lir);
if (!regalloc.go()) if (!regalloc.go())
return nullptr; return nullptr;
if (!integrity.check(true)) if (!integrity.check(true))
return nullptr; return nullptr;
IonSpewPass("Allocate Registers [Stupid]"); IonSpewPass("Allocate Registers [Stupid]");
break; break;
} }
default: default:
MOZ_ASSUME_UNREACHABLE("Bad regalloc"); MOZ_ASSUME_UNREACHABLE("Bad regalloc");
}
if (mir->shouldCancel("Allocate Registers"))
return nullptr;
} }
if (mir->shouldCancel("Allocate Registers"))
return nullptr;
TraceLogStopEvent(logger, TraceLogger::RegisterAllocation);
{ {
AutoTraceLog log(logger, TraceLogger::UnsplitEdges); AutoTraceLog log(logger, TraceLogger::UnsplitEdges);
// Now that all optimization and register allocation is done, re-introduce // Now that all optimization and register allocation is done, re-introduce

View File

@ -87,7 +87,7 @@ JSString::validateLength(js::ThreadSafeContext *maybecx, size_t length)
MOZ_ALWAYS_INLINE void MOZ_ALWAYS_INLINE void
JSRope::init(js::ThreadSafeContext *cx, JSString *left, JSString *right, size_t length) JSRope::init(js::ThreadSafeContext *cx, JSString *left, JSString *right, size_t length)
{ {
d.lengthAndFlags = buildLengthAndFlags(length, ROPE_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length, ROPE_FLAGS);
d.u1.left = left; d.u1.left = left;
d.s.u2.right = right; d.s.u2.right = right;
js::StringWriteBarrierPost(cx, &d.u1.left); js::StringWriteBarrierPost(cx, &d.u1.left);
@ -122,7 +122,7 @@ JSDependentString::init(js::ThreadSafeContext *cx, JSLinearString *base, const j
size_t length) size_t length)
{ {
JS_ASSERT(!js::IsPoisonedPtr(base)); JS_ASSERT(!js::IsPoisonedPtr(base));
d.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_FLAGS);
d.u1.chars = chars; d.u1.chars = chars;
d.s.u2.base = base; d.s.u2.base = base;
js::StringWriteBarrierPost(cx, reinterpret_cast<JSString **>(&d.s.u2.base)); js::StringWriteBarrierPost(cx, reinterpret_cast<JSString **>(&d.s.u2.base));
@ -185,7 +185,7 @@ JSString::markBase(JSTracer *trc)
MOZ_ALWAYS_INLINE void MOZ_ALWAYS_INLINE void
JSFlatString::init(const jschar *chars, size_t length) JSFlatString::init(const jschar *chars, size_t length)
{ {
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
d.u1.chars = chars; d.u1.chars = chars;
} }
@ -229,7 +229,7 @@ JSInlineString::new_(js::ThreadSafeContext *cx)
MOZ_ALWAYS_INLINE jschar * MOZ_ALWAYS_INLINE jschar *
JSInlineString::init(size_t length) JSInlineString::init(size_t length)
{ {
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
d.u1.chars = d.inlineStorage; d.u1.chars = d.inlineStorage;
JS_ASSERT(lengthFits(length) || (isFatInline() && JSFatInlineString::lengthFits(length))); JS_ASSERT(lengthFits(length) || (isFatInline() && JSFatInlineString::lengthFits(length)));
return d.inlineStorage; return d.inlineStorage;
@ -238,7 +238,7 @@ JSInlineString::init(size_t length)
MOZ_ALWAYS_INLINE void MOZ_ALWAYS_INLINE void
JSInlineString::resetLength(size_t length) JSInlineString::resetLength(size_t length)
{ {
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
JS_ASSERT(lengthFits(length) || (isFatInline() && JSFatInlineString::lengthFits(length))); JS_ASSERT(lengthFits(length) || (isFatInline() && JSFatInlineString::lengthFits(length)));
} }
@ -254,7 +254,7 @@ JSExternalString::init(const jschar *chars, size_t length, const JSStringFinaliz
{ {
JS_ASSERT(fin); JS_ASSERT(fin);
JS_ASSERT(fin->finalize); JS_ASSERT(fin->finalize);
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
d.u1.chars = chars; d.u1.chars = chars;
d.s.u2.externalFinalizer = fin; d.s.u2.externalFinalizer = fin;
} }

View File

@ -231,8 +231,7 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
* To avoid maintaining a stack, tree nodes are mutated to indicate how many * To avoid maintaining a stack, tree nodes are mutated to indicate how many
* times they have been visited. Since ropes can be dags, a node may be * times they have been visited. Since ropes can be dags, a node may be
* encountered multiple times during traversal. However, step 3 above leaves * encountered multiple times during traversal. However, step 3 above leaves
* a valid dependent string, so everything works out. This algorithm is * a valid dependent string, so everything works out.
* homomorphic to marking code.
* *
* While ropes avoid all sorts of quadratic cases with string * While ropes avoid all sorts of quadratic cases with string
* concatenation, they can't help when ropes are immediately flattened. * concatenation, they can't help when ropes are immediately flattened.
@ -260,6 +259,14 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
JSString *str = this; JSString *str = this;
jschar *pos; jschar *pos;
/*
* JSString::flattenData is a tagged pointer to the parent node.
* The tag indicates what to do when we return to the parent.
*/
static const uintptr_t Tag_Mask = 0x3;
static const uintptr_t Tag_FinishNode = 0x0;
static const uintptr_t Tag_VisitRightChild = 0x1;
/* Find the left most string, containing the first string. */ /* Find the left most string, containing the first string. */
JSRope *leftMostRope = this; JSRope *leftMostRope = this;
while (leftMostRope->leftChild()->isRope()) while (leftMostRope->leftChild()->isRope())
@ -273,16 +280,16 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
* Simulate a left-most traversal from the root to leftMost->leftChild() * Simulate a left-most traversal from the root to leftMost->leftChild()
* via first_visit_node * via first_visit_node
*/ */
JS_ASSERT(str->isRope());
while (str != leftMostRope) { while (str != leftMostRope) {
JS_ASSERT(str->isRope());
if (b == WithIncrementalBarrier) { if (b == WithIncrementalBarrier) {
JSString::writeBarrierPre(str->d.u1.left); JSString::writeBarrierPre(str->d.u1.left);
JSString::writeBarrierPre(str->d.s.u2.right); JSString::writeBarrierPre(str->d.s.u2.right);
} }
JSString *child = str->d.u1.left; JSString *child = str->d.u1.left;
JS_ASSERT(child->isRope());
str->d.u1.chars = left.chars(); str->d.u1.chars = left.chars();
child->d.s.u3.parent = str; child->d.u0.flattenData = uintptr_t(str) | Tag_VisitRightChild;
child->d.lengthAndFlags = 0x200;
str = child; str = child;
} }
if (b == WithIncrementalBarrier) { if (b == WithIncrementalBarrier) {
@ -292,10 +299,10 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
str->d.u1.chars = left.chars(); str->d.u1.chars = left.chars();
wholeCapacity = capacity; wholeCapacity = capacity;
wholeChars = const_cast<jschar *>(left.chars()); wholeChars = const_cast<jschar *>(left.chars());
size_t bits = left.d.lengthAndFlags; size_t bits = left.d.u0.lengthAndFlags;
pos = wholeChars + (bits >> LENGTH_SHIFT); pos = wholeChars + (bits >> LENGTH_SHIFT);
JS_STATIC_ASSERT(!(EXTENSIBLE_FLAGS & DEPENDENT_FLAGS)); JS_STATIC_ASSERT(!(EXTENSIBLE_FLAGS & DEPENDENT_FLAGS));
left.d.lengthAndFlags = bits ^ (EXTENSIBLE_FLAGS | DEPENDENT_FLAGS); left.d.u0.lengthAndFlags = bits ^ (EXTENSIBLE_FLAGS | DEPENDENT_FLAGS);
left.d.s.u2.base = (JSLinearString *)this; /* will be true on exit */ left.d.s.u2.base = (JSLinearString *)this; /* will be true on exit */
StringWriteBarrierPostRemove(maybecx, &left.d.u1.left); StringWriteBarrierPostRemove(maybecx, &left.d.u1.left);
StringWriteBarrierPost(maybecx, (JSString **)&left.d.s.u2.base); StringWriteBarrierPost(maybecx, (JSString **)&left.d.s.u2.base);
@ -317,8 +324,8 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
str->d.u1.chars = pos; str->d.u1.chars = pos;
StringWriteBarrierPostRemove(maybecx, &str->d.u1.left); StringWriteBarrierPostRemove(maybecx, &str->d.u1.left);
if (left.isRope()) { if (left.isRope()) {
left.d.s.u3.parent = str; /* Return to this when 'left' done, */ /* Return to this node when 'left' done, then goto visit_right_child. */
left.d.lengthAndFlags = 0x200; /* but goto visit_right_child. */ left.d.u0.flattenData = uintptr_t(str) | Tag_VisitRightChild;
str = &left; str = &left;
goto first_visit_node; goto first_visit_node;
} }
@ -329,8 +336,8 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
visit_right_child: { visit_right_child: {
JSString &right = *str->d.s.u2.right; JSString &right = *str->d.s.u2.right;
if (right.isRope()) { if (right.isRope()) {
right.d.s.u3.parent = str; /* Return to this node when 'right' done, */ /* Return to this node when 'right' done, then goto finish_node. */
right.d.lengthAndFlags = 0x300; /* but goto finish_node. */ right.d.u0.flattenData = uintptr_t(str) | Tag_FinishNode;
str = &right; str = &right;
goto first_visit_node; goto first_visit_node;
} }
@ -342,21 +349,21 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
if (str == this) { if (str == this) {
JS_ASSERT(pos == wholeChars + wholeLength); JS_ASSERT(pos == wholeChars + wholeLength);
*pos = '\0'; *pos = '\0';
str->d.lengthAndFlags = buildLengthAndFlags(wholeLength, EXTENSIBLE_FLAGS); str->d.u0.lengthAndFlags = buildLengthAndFlags(wholeLength, EXTENSIBLE_FLAGS);
str->d.u1.chars = wholeChars; str->d.u1.chars = wholeChars;
str->d.s.u2.capacity = wholeCapacity; str->d.s.u2.capacity = wholeCapacity;
StringWriteBarrierPostRemove(maybecx, &str->d.u1.left); StringWriteBarrierPostRemove(maybecx, &str->d.u1.left);
StringWriteBarrierPostRemove(maybecx, &str->d.s.u2.right); StringWriteBarrierPostRemove(maybecx, &str->d.s.u2.right);
return &this->asFlat(); return &this->asFlat();
} }
size_t progress = str->d.lengthAndFlags; uintptr_t flattenData = str->d.u0.flattenData;
str->d.lengthAndFlags = buildLengthAndFlags(pos - str->d.u1.chars, DEPENDENT_FLAGS); str->d.u0.lengthAndFlags = buildLengthAndFlags(pos - str->d.u1.chars, DEPENDENT_FLAGS);
str->d.s.u2.base = (JSLinearString *)this; /* will be true on exit */ str->d.s.u2.base = (JSLinearString *)this; /* will be true on exit */
StringWriteBarrierPost(maybecx, (JSString **)&str->d.s.u2.base); StringWriteBarrierPost(maybecx, (JSString **)&str->d.s.u2.base);
str = str->d.s.u3.parent; str = (JSString *)(flattenData & ~Tag_Mask);
if (progress == 0x200) if ((flattenData & Tag_Mask) == Tag_VisitRightChild)
goto visit_right_child; goto visit_right_child;
JS_ASSERT(progress == 0x300); JS_ASSERT((flattenData & Tag_Mask) == Tag_FinishNode);
goto finish_node; goto finish_node;
} }
} }
@ -465,7 +472,7 @@ JSDependentString::undepend(ExclusiveContext *cx)
* Transform *this into an undepended string so 'base' will remain rooted * Transform *this into an undepended string so 'base' will remain rooted
* for the benefit of any other dependent string that depends on *this. * for the benefit of any other dependent string that depends on *this.
*/ */
d.lengthAndFlags = buildLengthAndFlags(n, UNDEPENDED_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(n, UNDEPENDED_FLAGS);
return &this->asFlat(); return &this->asFlat();
} }

View File

@ -136,7 +136,10 @@ class JSString : public js::gc::BarrieredCell<JSString>
/* Fields only apply to string types commented on the right. */ /* Fields only apply to string types commented on the right. */
struct Data struct Data
{ {
size_t lengthAndFlags; /* JSString */ union {
size_t lengthAndFlags; /* JSString */
uintptr_t flattenData; /* JSRope (temporary while flattening) */
} u0;
union { union {
const jschar *chars; /* JSLinearString */ const jschar *chars; /* JSLinearString */
JSString *left; /* JSRope */ JSString *left; /* JSRope */
@ -150,10 +153,6 @@ class JSString : public js::gc::BarrieredCell<JSString>
size_t capacity; /* JSFlatString (extensible) */ size_t capacity; /* JSFlatString (extensible) */
const JSStringFinalizer *externalFinalizer;/* JSExternalString */ const JSStringFinalizer *externalFinalizer;/* JSExternalString */
} u2; } u2;
union {
JSString *parent; /* JSRope (temporary) */
size_t reserved; /* may use for bug 615290 */
} u3;
} s; } s;
}; };
} d; } d;
@ -252,12 +251,12 @@ class JSString : public js::gc::BarrieredCell<JSString>
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
size_t length() const { size_t length() const {
return d.lengthAndFlags >> LENGTH_SHIFT; return d.u0.lengthAndFlags >> LENGTH_SHIFT;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool empty() const { bool empty() const {
return d.lengthAndFlags <= FLAGS_MASK; return d.u0.lengthAndFlags <= FLAGS_MASK;
} }
/* /*
@ -299,7 +298,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isRope() const { bool isRope() const {
return (d.lengthAndFlags & FLAGS_MASK) == ROPE_FLAGS; return (d.u0.lengthAndFlags & FLAGS_MASK) == ROPE_FLAGS;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
@ -321,7 +320,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isDependent() const { bool isDependent() const {
return (d.lengthAndFlags & FLAGS_MASK) == DEPENDENT_FLAGS; return (d.u0.lengthAndFlags & FLAGS_MASK) == DEPENDENT_FLAGS;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
@ -343,7 +342,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isExtensible() const { bool isExtensible() const {
return (d.lengthAndFlags & FLAGS_MASK) == EXTENSIBLE_FLAGS; return (d.u0.lengthAndFlags & FLAGS_MASK) == EXTENSIBLE_FLAGS;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
@ -376,17 +375,17 @@ class JSString : public js::gc::BarrieredCell<JSString>
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isUndepended() const { bool isUndepended() const {
return (d.lengthAndFlags & FLAGS_MASK) == UNDEPENDED_FLAGS; return (d.u0.lengthAndFlags & FLAGS_MASK) == UNDEPENDED_FLAGS;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isAtom() const { bool isAtom() const {
return d.lengthAndFlags & ATOM_BIT; return d.u0.lengthAndFlags & ATOM_BIT;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isPermanentAtom() const { bool isPermanentAtom() const {
return (d.lengthAndFlags & FLAGS_MASK) == PERMANENT_ATOM_FLAGS; return (d.u0.lengthAndFlags & FLAGS_MASK) == PERMANENT_ATOM_FLAGS;
} }
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
@ -399,7 +398,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
inline bool hasBase() const { inline bool hasBase() const {
JS_STATIC_ASSERT((DEPENDENT_FLAGS | JS_BIT(1)) == UNDEPENDED_FLAGS); JS_STATIC_ASSERT((DEPENDENT_FLAGS | JS_BIT(1)) == UNDEPENDED_FLAGS);
return d.lengthAndFlags & HAS_BASE_BIT; return d.u0.lengthAndFlags & HAS_BASE_BIT;
} }
inline JSLinearString *base() const; inline JSLinearString *base() const;
@ -417,7 +416,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
/* Offsets for direct field from jit code. */ /* Offsets for direct field from jit code. */
static size_t offsetOfLengthAndFlags() { static size_t offsetOfLengthAndFlags() {
return offsetof(JSString, d.lengthAndFlags); return offsetof(JSString, d.u0.lengthAndFlags);
} }
static size_t offsetOfChars() { static size_t offsetOfChars() {
@ -594,11 +593,11 @@ class JSFlatString : public JSLinearString
* operation changes the string to the JSAtom type, in place. * operation changes the string to the JSAtom type, in place.
*/ */
MOZ_ALWAYS_INLINE JSAtom *morphAtomizedStringIntoAtom() { MOZ_ALWAYS_INLINE JSAtom *morphAtomizedStringIntoAtom() {
d.lengthAndFlags = buildLengthAndFlags(length(), ATOM_BIT); d.u0.lengthAndFlags = buildLengthAndFlags(length(), ATOM_BIT);
return &asAtom(); return &asAtom();
} }
MOZ_ALWAYS_INLINE JSAtom *morphAtomizedStringIntoPermanentAtom() { MOZ_ALWAYS_INLINE JSAtom *morphAtomizedStringIntoPermanentAtom() {
d.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS);
return &asAtom(); return &asAtom();
} }
@ -740,13 +739,13 @@ class JSAtom : public JSFlatString
MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE
bool isPermanent() const { bool isPermanent() const {
return d.lengthAndFlags & PERMANENT_BIT; return d.u0.lengthAndFlags & PERMANENT_BIT;
} }
// Transform this atom into a permanent atom. This is only done during // Transform this atom into a permanent atom. This is only done during
// initialization of the runtime. // initialization of the runtime.
MOZ_ALWAYS_INLINE void morphIntoPermanentAtom() { MOZ_ALWAYS_INLINE void morphIntoPermanentAtom() {
d.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS); d.u0.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS);
} }
#ifdef DEBUG #ifdef DEBUG

View File

@ -1607,6 +1607,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
, mCollapsedResizer(false) , mCollapsedResizer(false)
, mShouldBuildScrollableLayer(false) , mShouldBuildScrollableLayer(false)
, mHasBeenScrolled(false) , mHasBeenScrolled(false)
, mIsResolutionSet(false)
{ {
mScrollingActive = IsAlwaysActive(); mScrollingActive = IsAlwaysActive();
@ -2795,6 +2796,7 @@ void
ScrollFrameHelper::SetResolution(const gfxSize& aResolution) ScrollFrameHelper::SetResolution(const gfxSize& aResolution)
{ {
mResolution = aResolution; mResolution = aResolution;
mIsResolutionSet = true;
} }
static void static void
@ -4538,6 +4540,7 @@ ScrollFrameHelper::RestoreState(nsPresState* aState)
mDidHistoryRestore = true; mDidHistoryRestore = true;
mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0); mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0);
mResolution = aState->GetResolution(); mResolution = aState->GetResolution();
mIsResolutionSet = true;
if (mIsRoot) { if (mIsRoot) {
mOuter->PresContext()->PresShell()->SetResolution(mResolution.width, mResolution.height); mOuter->PresContext()->PresShell()->SetResolution(mResolution.width, mResolution.height);

View File

@ -407,6 +407,10 @@ public:
// True if this frame has been scrolled at least once // True if this frame has been scrolled at least once
bool mHasBeenScrolled:1; bool mHasBeenScrolled:1;
// True if the frame's resolution has been set via SetResolution or restored
// via RestoreState.
bool mIsResolutionSet:1;
protected: protected:
/** /**
* @note This method might destroy the frame, pres shell and other objects. * @note This method might destroy the frame, pres shell and other objects.
@ -658,6 +662,9 @@ public:
virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE { virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
mHelper.ResetScrollPositionForLayerPixelAlignment(); mHelper.ResetScrollPositionForLayerPixelAlignment();
} }
virtual bool IsResolutionSet() const MOZ_OVERRIDE {
return mHelper.mIsResolutionSet;
}
virtual bool DidHistoryRestore() const MOZ_OVERRIDE { virtual bool DidHistoryRestore() const MOZ_OVERRIDE {
return mHelper.mDidHistoryRestore; return mHelper.mDidHistoryRestore;
} }
@ -972,6 +979,9 @@ public:
virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE { virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
mHelper.ResetScrollPositionForLayerPixelAlignment(); mHelper.ResetScrollPositionForLayerPixelAlignment();
} }
virtual bool IsResolutionSet() const MOZ_OVERRIDE {
return mHelper.mIsResolutionSet;
}
virtual bool DidHistoryRestore() const MOZ_OVERRIDE { virtual bool DidHistoryRestore() const MOZ_OVERRIDE {
return mHelper.mDidHistoryRestore; return mHelper.mDidHistoryRestore;
} }

View File

@ -271,6 +271,10 @@ public:
* Was the current presentation state for this frame restored from history? * Was the current presentation state for this frame restored from history?
*/ */
virtual bool DidHistoryRestore() const = 0; virtual bool DidHistoryRestore() const = 0;
/**
* Was the current resolution set by the user or just default initialized?
*/
virtual bool IsResolutionSet() const = 0;
/** /**
* Clear the flag so that DidHistoryRestore() returns false until the next * Clear the flag so that DidHistoryRestore() returns false until the next
* RestoreState call. * RestoreState call.

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: test button "disabled" text style</title>
<style>
button {
color: GrayText;
border-width: 0;
background: transparent;
}
</style>
</head>
<body>
<button>Some text</button>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: test button "disabled" text style</title>
<style>
button {
border-width: 0;
background: transparent;
}
</style>
</head>
<body>
<button disabled>Some text</button>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: test all types of buttons look similar when disabled</title>
</head>
<body>
<button>Some text</button>
<button>Some text</button>
<button>Reset</button>
<button>Submit Query</button>
<br>
<button disabled>Some text</button>
<button disabled>Some text</button>
<button disabled>Reset</button>
<button disabled>Submit Query</button>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: test all types of buttons look similar when disabled</title>
</head>
<body>
<button>Some text</button>
<input type="button" value="Some text">
<input type="reset">
<input type="submit">
<br>
<button disabled>Some text</button>
<input disabled type="button" value="Some text">
<input disabled type="reset">
<input disabled type="submit">
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<button disabled>Some text</button>
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<button>Some text</button>
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<input disabled type="button" value="Some text">
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<input type="button" value="Some text">
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<input disabled type="reset">
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<input type="reset">
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<input disabled type="submit">
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1007278: check disabled and non-disabled buttons look different</title>
</head>
<body>
<input type="submit">
</body>
</html>

View File

@ -17,3 +17,15 @@ fuzzy-if(B2G||Android,125,80) == percent-width-child-2.html percent-width-child
!= line-height-button-1.5.html line-height-button-1.0.html != line-height-button-1.5.html line-height-button-1.0.html
!= line-height-input-0.5.html line-height-input-1.0.html != line-height-input-0.5.html line-height-input-1.0.html
!= line-height-input-1.5.html line-height-input-1.0.html != line-height-input-1.5.html line-height-input-1.0.html
# Looks like Android and B2G change the text color, but to something slightly
# different from ColorGray
fails-if(Android||B2G) == disabled-1.html disabled-1-ref.html
# While disabled buttons don't look like non-disabled buttons, <button disabled>
# is different from other disabled buttons for B2G ICS Emulator (see bug 1009714)
fails-if(B2G) == disabled-2.html disabled-2-ref.html
!= disabled-3.html disabled-3-notref.html
!= disabled-4.html disabled-4-notref.html
!= disabled-5.html disabled-5-notref.html
!= disabled-6.html disabled-6-notref.html

View File

@ -664,6 +664,7 @@ input[type="submit"]:disabled {
cursor: inherit; cursor: inherit;
} }
button:disabled:active, button:disabled,
input[type="reset"]:disabled:active, input[type="reset"]:disabled:active,
input[type="reset"]:disabled, input[type="reset"]:disabled,
input[type="button"]:disabled:active, input[type="button"]:disabled:active,

2
mach
View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.

View File

@ -1,3 +1,3 @@
{ "title": "Firefox Marketplace", { "title": "Firefox Marketplace",
"url": "http://marketplace.firefox.com", "url": "https://marketplace.firefox.com/",
"bgcolor": "#0095dd" } "bgcolor": "#0095dd" }

View File

@ -1,3 +1,3 @@
{ "title": "Mozilla", { "title": "Mozilla",
"url": "http://mozilla.org", "url": "http://www.mozilla.org/en-US/",
"bgcolor": "#c13832" } "bgcolor": "#c13832" }

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/alert_app_animation_1" android:duration="150" />
<item android:drawable="@drawable/alert_app_animation_2" android:duration="150" />
<item android:drawable="@drawable/alert_app_animation_3" android:duration="150" />
<item android:drawable="@drawable/alert_app_animation_4" android:duration="150" />
<item android:drawable="@drawable/alert_app_animation_5" android:duration="150" />
<item android:drawable="@drawable/alert_app_animation_6" android:duration="150" />
<item android:drawable="@drawable/alert_app_animation_7" android:duration="150" />
</animation-list>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/alert_download_animation_1" android:duration="150" />
<item android:drawable="@drawable/alert_download_animation_2" android:duration="150" />
<item android:drawable="@drawable/alert_download_animation_3" android:duration="150" />
<item android:drawable="@drawable/alert_download_animation_4" android:duration="150" />
<item android:drawable="@drawable/alert_download_animation_5" android:duration="150" />
<item android:drawable="@drawable/alert_download_animation_6" android:duration="150" />
</animation-list>

View File

@ -4233,7 +4233,7 @@ Tab.prototype = {
restoredSessionZoom: function() { restoredSessionZoom: function() {
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
if (this._restoreZoom && cwu.isHistoryRestored) { if (this._restoreZoom && cwu.isResolutionSet) {
return this._getGeckoZoom(); return this._getGeckoZoom();
} }
return null; return null;

View File

@ -46,6 +46,7 @@ relativesrcdir toolkit/locales:
locale/@AB_CD@/browser/overrides/about.dtd (%chrome/global/about.dtd) locale/@AB_CD@/browser/overrides/about.dtd (%chrome/global/about.dtd)
locale/@AB_CD@/browser/overrides/aboutAbout.dtd (%chrome/global/aboutAbout.dtd) locale/@AB_CD@/browser/overrides/aboutAbout.dtd (%chrome/global/aboutAbout.dtd)
locale/@AB_CD@/browser/overrides/aboutRights.dtd (%chrome/global/aboutRights.dtd) locale/@AB_CD@/browser/overrides/aboutRights.dtd (%chrome/global/aboutRights.dtd)
locale/@AB_CD@/browser/overrides/charsetMenu.properties (%chrome/global/charsetMenu.properties)
locale/@AB_CD@/browser/overrides/commonDialogs.properties (%chrome/global/commonDialogs.properties) locale/@AB_CD@/browser/overrides/commonDialogs.properties (%chrome/global/commonDialogs.properties)
locale/@AB_CD@/browser/overrides/intl.properties (%chrome/global/intl.properties) locale/@AB_CD@/browser/overrides/intl.properties (%chrome/global/intl.properties)
locale/@AB_CD@/browser/overrides/intl.css (%chrome/global/intl.css) locale/@AB_CD@/browser/overrides/intl.css (%chrome/global/intl.css)
@ -70,6 +71,7 @@ relativesrcdir toolkit/locales:
% override chrome://global/locale/about.dtd chrome://browser/locale/overrides/about.dtd % override chrome://global/locale/about.dtd chrome://browser/locale/overrides/about.dtd
% override chrome://global/locale/aboutAbout.dtd chrome://browser/locale/overrides/aboutAbout.dtd % override chrome://global/locale/aboutAbout.dtd chrome://browser/locale/overrides/aboutAbout.dtd
% override chrome://global/locale/aboutRights.dtd chrome://browser/locale/overrides/aboutRights.dtd % override chrome://global/locale/aboutRights.dtd chrome://browser/locale/overrides/aboutRights.dtd
% override chrome://global/locale/charsetMenu.properties chrome://browser/locale/overrides/charsetMenu.properties
% override chrome://global/locale/commonDialogs.properties chrome://browser/locale/overrides/commonDialogs.properties % override chrome://global/locale/commonDialogs.properties chrome://browser/locale/overrides/commonDialogs.properties
% override chrome://mozapps/locale/handling/handling.properties chrome://browser/locale/handling.properties % override chrome://mozapps/locale/handling/handling.properties chrome://browser/locale/handling.properties
% override chrome://global/locale/intl.properties chrome://browser/locale/overrides/intl.properties % override chrome://global/locale/intl.properties chrome://browser/locale/overrides/intl.properties

View File

@ -351,8 +351,7 @@ this.WebappManager = {
notification = this._notify({ notification = this._notify({
title: Strings.GetStringFromName("checkingForUpdatesTitle"), title: Strings.GetStringFromName("checkingForUpdatesTitle"),
message: Strings.GetStringFromName("checkingForUpdatesMessage"), message: Strings.GetStringFromName("checkingForUpdatesMessage"),
// TODO: replace this with an animated icon. icon: "drawable://alert_app_animation",
icon: "drawable://alert_app",
progress: NaN, progress: NaN,
}); });
} }
@ -392,10 +391,7 @@ this.WebappManager = {
title: PluralForm.get(aApps.length, Strings.GetStringFromName("downloadingUpdateTitle")). title: PluralForm.get(aApps.length, Strings.GetStringFromName("downloadingUpdateTitle")).
replace("#1", aApps.length), replace("#1", aApps.length),
message: Strings.formatStringFromName("downloadingUpdateMessage", [downloadingNames], 1), message: Strings.formatStringFromName("downloadingUpdateMessage", [downloadingNames], 1),
// TODO: replace this with an animated icon. UpdateService uses icon: "drawable://alert_download_animation",
// android.R.drawable.stat_sys_download, but I don't think we can reference
// a system icon with a drawable: URL here, so we'll have to craft our own.
icon: "drawable://alert_download",
// TODO: make this a determinate progress indicator once we can determine // TODO: make this a determinate progress indicator once we can determine
// the sizes of the APKs and observe their progress. // the sizes of the APKs and observe their progress.
progress: NaN, progress: NaN,

View File

@ -126,6 +126,19 @@ Http2Session::Http2Session(nsAHttpTransaction *aHttpTransaction,
mPingThreshold = gHttpHandler->SpdyPingThreshold(); mPingThreshold = gHttpHandler->SpdyPingThreshold();
} }
// Copy the 32 bit number into the destination, using network byte order
// in the destination.
template<typename charType> static void
CopyAsNetwork32(charType dest, // where to store it
uint32_t number) // the 32 bit number in native format
{
number = PR_htonl(number);
memcpy(dest, &number, sizeof(number));
}
template void CopyAsNetwork32(char *dest, uint32_t number);
template void CopyAsNetwork32(uint8_t *dest, uint32_t number);
PLDHashOperator PLDHashOperator
Http2Session::ShutdownEnumerator(nsAHttpTransaction *key, Http2Session::ShutdownEnumerator(nsAHttpTransaction *key,
nsAutoPtr<Http2Stream> &stream, nsAutoPtr<Http2Stream> &stream,
@ -601,12 +614,11 @@ Http2Session::CreateFrameHeader(charType dest, uint16_t frameLength,
MOZ_ASSERT(!(streamID & 0x80000000)); MOZ_ASSERT(!(streamID & 0x80000000));
frameLength = PR_htons(frameLength); frameLength = PR_htons(frameLength);
streamID = PR_htonl(streamID);
memcpy(dest, &frameLength, 2); memcpy(dest, &frameLength, 2);
dest[2] = frameType; dest[2] = frameType;
dest[3] = frameFlags; dest[3] = frameFlags;
memcpy(dest + 4, &streamID, 4); CopyAsNetwork32(dest + 4, streamID);
} }
char * char *
@ -710,7 +722,7 @@ Http2Session::GeneratePriority(uint32_t aID, uint8_t aPriorityWeight)
mOutputQueueUsed += 13; mOutputQueueUsed += 13;
CreateFrameHeader(packet, 5, FRAME_TYPE_PRIORITY, 0, aID); CreateFrameHeader(packet, 5, FRAME_TYPE_PRIORITY, 0, aID);
memset(packet + 8, 0, 4); CopyAsNetwork32(packet + 8, 0);
memcpy(packet + 12, &aPriorityWeight, 1); memcpy(packet + 12, &aPriorityWeight, 1);
LogIO(this, nullptr, "Generate Priority", packet, 13); LogIO(this, nullptr, "Generate Priority", packet, 13);
FlushOutputQueue(); FlushOutputQueue();
@ -736,8 +748,7 @@ Http2Session::GenerateRstStream(uint32_t aStatusCode, uint32_t aID)
mOutputQueueUsed += 12; mOutputQueueUsed += 12;
CreateFrameHeader(packet, 4, FRAME_TYPE_RST_STREAM, 0, aID); CreateFrameHeader(packet, 4, FRAME_TYPE_RST_STREAM, 0, aID);
aStatusCode = PR_htonl(aStatusCode); CopyAsNetwork32(packet + 8, aStatusCode);
memcpy(packet + 8, &aStatusCode, 4);
LogIO(this, nullptr, "Generate Reset", packet, 12); LogIO(this, nullptr, "Generate Reset", packet, 12);
FlushOutputQueue(); FlushOutputQueue();
@ -755,12 +766,10 @@ Http2Session::GenerateGoAway(uint32_t aStatusCode)
CreateFrameHeader(packet, 8, FRAME_TYPE_GOAWAY, 0, 0); CreateFrameHeader(packet, 8, FRAME_TYPE_GOAWAY, 0, 0);
// last-good-stream-id are bytes 8-11 reflecting pushes // last-good-stream-id are bytes 8-11 reflecting pushes
uint32_t goAway = PR_htonl(mOutgoingGoAwayID); CopyAsNetwork32(packet + 8, mOutgoingGoAwayID);
memcpy(packet + 8, &goAway, 4);
// bytes 12-15 are the status code. // bytes 12-15 are the status code.
aStatusCode = PR_htonl(aStatusCode); CopyAsNetwork32(packet + 12, aStatusCode);
memcpy(packet + 12, &aStatusCode, 4);
LogIO(this, nullptr, "Generate GoAway", packet, 16); LogIO(this, nullptr, "Generate GoAway", packet, 16);
FlushOutputQueue(); FlushOutputQueue();
@ -812,8 +821,7 @@ Http2Session::SendHello()
// Advertise the Push RWIN for the session, and on each new pull stream // Advertise the Push RWIN for the session, and on each new pull stream
// send a window update with END_FLOW_CONTROL // send a window update with END_FLOW_CONTROL
packet[8 + 5 * numberOfEntries] = SETTINGS_TYPE_INITIAL_WINDOW; packet[8 + 5 * numberOfEntries] = SETTINGS_TYPE_INITIAL_WINDOW;
uint32_t rwin = PR_htonl(mPushAllowance); CopyAsNetwork32(packet + 9 + 5 * numberOfEntries, mPushAllowance);
memcpy(packet + 9 + 5 * numberOfEntries, &rwin, 4);
numberOfEntries++; numberOfEntries++;
// Explicitly signal that we do NOT support compressed data frames, even // Explicitly signal that we do NOT support compressed data frames, even
@ -835,16 +843,15 @@ Http2Session::SendHello()
goto sendHello_complete; goto sendHello_complete;
// send a window update for the session (Stream 0) for something large // send a window update for the session (Stream 0) for something large
sessionWindowBump = PR_htonl(sessionWindowBump);
mLocalSessionWindow = ASpdySession::kInitialRwin; mLocalSessionWindow = ASpdySession::kInitialRwin;
packet = mOutputQueueBuffer.get() + mOutputQueueUsed; packet = mOutputQueueBuffer.get() + mOutputQueueUsed;
CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0); CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0);
mOutputQueueUsed += 12; mOutputQueueUsed += 12;
memcpy(packet + 8, &sessionWindowBump, 4); CopyAsNetwork32(packet + 8, sessionWindowBump);
LOG3(("Session Window increase at start of session %p %u\n", LOG3(("Session Window increase at start of session %p %u\n",
this, PR_ntohl(sessionWindowBump))); this, sessionWindowBump));
LogIO(this, nullptr, "Session Window Bump ", packet, 12); LogIO(this, nullptr, "Session Window Bump ", packet, 12);
sendHello_complete: sendHello_complete:
@ -2480,8 +2487,7 @@ Http2Session::UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes)
MOZ_ASSERT(mOutputQueueUsed <= mOutputQueueSize); MOZ_ASSERT(mOutputQueueUsed <= mOutputQueueSize);
CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, stream->StreamID()); CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, stream->StreamID());
toack = PR_htonl(toack); CopyAsNetwork32(packet + 8, toack);
memcpy(packet + 8, &toack, 4);
LogIO(this, stream, "Stream Window Update", packet, 12); LogIO(this, stream, "Stream Window Update", packet, 12);
// dont flush here, this write can commonly be coalesced with a // dont flush here, this write can commonly be coalesced with a
@ -2519,8 +2525,7 @@ Http2Session::UpdateLocalSessionWindow(uint32_t bytes)
MOZ_ASSERT(mOutputQueueUsed <= mOutputQueueSize); MOZ_ASSERT(mOutputQueueUsed <= mOutputQueueSize);
CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0); CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0);
toack = PR_htonl(toack); CopyAsNetwork32(packet + 8, toack);
memcpy(packet + 8, &toack, 4);
LogIO(this, nullptr, "Session Window Update", packet, 12); LogIO(this, nullptr, "Session Window Update", packet, 12);
// dont flush here, this write can commonly be coalesced with others // dont flush here, this write can commonly be coalesced with others

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,6 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2012 Mozilla Foundation /* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2013 Mozilla Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More