Merge mozilla-central and mozilla-inbound

This commit is contained in:
Ed Morley 2011-10-26 01:04:58 +01:00
commit 41186fd050
69 changed files with 980 additions and 231 deletions

View File

@ -69,3 +69,4 @@ a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R15

View File

@ -4159,7 +4159,7 @@ var XULBrowserWindow = {
startTime: 0,
statusText: "",
isBusy: false,
inContentWhitelist: ["about:addons", "about:permissions"],
inContentWhitelist: ["about:addons", "about:permissions", "about:sync-progress"],
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIWebProgressListener) ||

View File

@ -0,0 +1,72 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Firefox Sync.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Allison Naaktgeboren <ally@mozilla.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-sync/main.js");
let gProgressBar;
let gCounter = 0;
function onLoad(event) {
Services.obs.addObserver(increaseProgressBar, "weave:engine:sync:finish", false);
Services.obs.addObserver(increaseProgressBar, "weave:engine:sync:error", false);
gProgressBar = document.getElementById('uploadProgressBar');
if (Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) {
gProgressBar.max = Weave.Engines.getEnabled().length;
gProgressBar.style.display = "inline";
}
else {
gProgressBar.style.display = "none";
}
}
function onUnload(event) {
Services.obs.removeObserver(increaseProgressBar, "weave:engine:sync:finish");
Services.obs.removeObserver(increaseProgressBar, "weave:engine:sync:error");
}
function increaseProgressBar(){
gCounter += 1;
gProgressBar.setAttribute("value", gCounter);
}
function closeTab() {
window.close();
}

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License
# Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Firefox Sync.
#
# The Initial Developer of the Original Code is the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Allison Naaktgeboren <ally@mozilla.com> (original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % syncProgressDTD
SYSTEM "chrome://browser/locale/syncProgress.dtd">
%syncProgressDTD;
<!ENTITY % syncSetupDTD
SYSTEM "chrome://browser/locale/syncSetup.dtd">
%syncSetupDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&syncProgress.pageTitle;</title>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://browser/skin/syncProgress.css"/>
<link rel="icon" type="image/png" id="favicon"
href="chrome://browser/skin/sync-16.png"/>
<script type="text/javascript;version=1.8"
src="chrome://browser/content/syncProgress.js"/>
</head>
<body onload="onLoad(event)" onunload="onUnload(event)">
<title>&setup.successPage.title;</title>
<div id="floatingBox" class="main-content">
<div id="title">
<h1>&setup.successPage.title;</h1>
</div>
<div id="successLogo">
<img id="brandSyncLogo" src="chrome://browser/skin/sync-128.png" alt="&syncProgress.logoAltText;" />
</div>
<div id="loadingText">
<p id="blurb">&syncProgress.textBlurb; </p>
</div>
<div id="progressBar">
<progress id="uploadProgressBar" value="0"/>
</div>
<div id="bottomRow">
<button id="closeButton" onclick="closeTab()">&syncProgress.closeButton; </button>
</div>
</div>
</body>
</html>

View File

@ -24,6 +24,7 @@
* Philipp von Weitershausen <philipp@weitershausen.de>
* Paul OShannessy <paul@oshannessy.com>
* Richard Newman <rnewman@mozilla.com>
* Allison Naaktgeboren <ally@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -53,7 +54,6 @@ const EXISTING_ACCOUNT_CONNECT_PAGE = 3;
const EXISTING_ACCOUNT_LOGIN_PAGE = 4;
const OPTIONS_PAGE = 5;
const OPTIONS_CONFIRM_PAGE = 6;
const SETUP_SUCCESS_PAGE = 7;
// Broader than we'd like, but after this changed from api-secure.recaptcha.net
// we had no choice. At least we only do this for the duration of setup.
@ -411,6 +411,7 @@ var gSyncSetup = {
this.checkFields();
break;
case EXISTING_ACCOUNT_CONNECT_PAGE:
Weave.Svc.Prefs.set("firstSync", "existingAccount");
this.wizard.getButton("next").hidden = false;
this.wizard.getButton("back").hidden = false;
this.wizard.getButton("extra1").hidden = false;
@ -425,18 +426,6 @@ var gSyncSetup = {
this.wizard.canRewind = true;
this.checkFields();
break;
case SETUP_SUCCESS_PAGE:
this.wizard.canRewind = false;
this.wizard.canAdvance = true;
this.wizard.getButton("back").hidden = true;
this.wizard.getButton("next").hidden = true;
this.wizard.getButton("cancel").hidden = true;
this.wizard.getButton("finish").hidden = false;
this._handleSuccess();
if (this.wizardType == "pair") {
this.completePairing();
}
break;
case OPTIONS_PAGE:
this.wizard.canRewind = false;
this.wizard.canAdvance = true;
@ -473,7 +462,7 @@ var gSyncSetup = {
!Weave.Utils.ensureMPUnlocked()) {
return false;
}
switch (this.wizard.pageIndex) {
case PAIR_PAGE:
this.startPairing();
@ -519,7 +508,8 @@ var gSyncSetup = {
Weave.Service.password = password;
Weave.Service.passphrase = Weave.Utils.generatePassphrase();
this._handleNoScript(false);
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
Weave.Svc.Prefs.set("firstSync", "newAccount");
this.wizardFinish();
return false;
}
@ -532,8 +522,9 @@ var gSyncSetup = {
Weave.Service.password = document.getElementById("existingPassword").value;
let pp = document.getElementById("existingPassphrase").value;
Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
if (Weave.Service.login())
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
if (Weave.Service.login()) {
this.wizardFinish();
}
return false;
case OPTIONS_PAGE:
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
@ -544,8 +535,7 @@ var gSyncSetup = {
return this._handleChoice();
case OPTIONS_CONFIRM_PAGE:
if (this._resettingSync) {
this.onWizardFinish();
window.close();
this.wizardFinish();
return false;
}
return this.returnFromOptions();
@ -580,9 +570,13 @@ var gSyncSetup = {
return true;
},
onWizardFinish: function () {
wizardFinish: function () {
this.setupInitialSync();
if (this.wizardType == "pair") {
this.completePairing();
}
if (!this._resettingSync) {
function isChecked(element) {
return document.getElementById(element).hasAttribute("checked");
@ -598,22 +592,17 @@ var gSyncSetup = {
Weave.Service.persistLogin();
Weave.Svc.Obs.notify("weave:service:setup-complete");
if (this._settingUpNew)
gSyncUtils.openFirstClientFirstrun();
else
gSyncUtils.openAddedClientFirstrun();
gSyncUtils.openFirstSyncProgressPage();
}
Weave.Utils.nextTick(Weave.Service.sync, Weave.Service);
window.close();
},
onWizardCancel: function () {
if (this._resettingSync)
return;
if (this.wizard.pageIndex == SETUP_SUCCESS_PAGE) {
this.onWizardFinish();
return;
}
this.abortEasySetup();
this._handleNoScript(false);
Weave.Service.startOver();
@ -714,7 +703,7 @@ var gSyncSetup = {
Weave.Service.password = credentials.password;
Weave.Service.passphrase = credentials.synckey;
Weave.Service.serverURL = credentials.serverURL;
self.wizard.pageIndex = SETUP_SUCCESS_PAGE;
gSyncSetup.wizardFinish();
},
onAbort: function onAbort(error) {
@ -906,25 +895,6 @@ var gSyncSetup = {
return valid;
},
_handleSuccess: function() {
let self = this;
function fill(id, string)
document.getElementById(id).firstChild.nodeValue =
string ? self._stringBundle.GetStringFromName(string) : "";
fill("firstSyncAction", "");
fill("firstSyncActionWarning", "");
if (this._settingUpNew) {
fill("firstSyncAction", "newAccount.action.label");
fill("firstSyncActionChange", "newAccount.change.label");
return;
}
fill("firstSyncActionChange", "existingAccount.change.label");
let action = document.getElementById("mergeChoiceRadio").selectedItem.id;
let id = action == "resetClient" ? "firstSyncAction" : "firstSyncActionWarning";
fill(id, action + ".change.label");
},
_handleChoice: function () {
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
document.getElementById("chosenActionDeck").selectedIndex = desc;

View File

@ -25,6 +25,7 @@
# Mike Connor <mconnor@mozilla.com>
# Paul OShannessy <paul@oshannessy.com>
# Philipp von Weitershausen <philipp@weitershausen.de>
# Allison Naaktgeboren <ally@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -60,7 +61,6 @@
xmlns:html="http://www.w3.org/1999/xhtml"
onwizardnext="return gSyncSetup.onWizardAdvance()"
onwizardback="return gSyncSetup.onWizardBack()"
onwizardfinish="gSyncSetup.onWizardFinish()"
onwizardcancel="gSyncSetup.onWizardCancel()"
onload="gSyncSetup.init()">
@ -511,24 +511,11 @@
</vbox>
</deck>
</wizardpage>
<wizardpage label="&setup.successPage.title;"
id="successfulSetup"
onextra1="gSyncSetup.onSyncOptions()"
onpageshow="gSyncSetup.onPageShow()">
<vbox align="center">
<image id="successPageIcon"/>
</vbox>
<separator/>
<description class="normal">
<html:span id="firstSyncAction">replace me</html:span>
<html:strong id="firstSyncActionWarning">replace me</html:strong>
<html:span id="firstSyncActionChange">replace me</html:span>
</description>
<description>
&continueUsing.label;
</description>
<separator flex="1"/>
# In terms of the wizard flow shown to the user, the 'syncOptionsConfirm'
# page above is not the last wizard page. To prevent the wizard binding from
# assuming that it is, we're inserting this dummy page here. This also means
# that the wizard needs to always be closed manually via wizardFinish().
<wizardpage>
</wizardpage>
</wizard>

View File

@ -109,17 +109,8 @@ let gSyncUtils = {
this._openLink(Weave.Svc.Prefs.get("privacyURL"));
},
// xxxmpc - fix domain before 1.3 final (bug 583652)
_baseURL: "http://www.mozilla.com/firefox/sync/",
openFirstClientFirstrun: function () {
let url = this._baseURL + "firstrun.html";
this._openLink(url);
},
openAddedClientFirstrun: function () {
let url = this._baseURL + "secondrun.html";
this._openLink(url);
openFirstSyncProgressPage: function () {
this._openLink("about:sync-progress");
},
/**

View File

@ -245,6 +245,7 @@ _BROWSER_FILES = \
test_wyciwyg_copying.html \
authenticate.sjs \
browser_minimize.js \
browser_aboutSyncProgress.js \
browser_middleMouse_inherit.js \
$(NULL)

View File

@ -0,0 +1,101 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-sync/main.js");
let gTests = [ {
desc: "Makes sure the progress bar appears if firstSync pref is set",
setup: function () {
Services.prefs.setCharPref("services.sync.firstSync", "newAccount");
},
run: function () {
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let progressBar = doc.getElementById("uploadProgressBar");
isnot(progressBar.style.display, "none", "progress bar should be visible");
executeSoon(runNextTest);
}
},
{
desc: "Makes sure the progress bar is hidden if firstSync pref is not set",
setup: function () {
Services.prefs.clearUserPref("services.sync.firstSync");
is(Services.prefs.getPrefType("services.sync.firstSync"),
Ci.nsIPrefBranch.PREF_INVALID, "pref DNE" );
},
run: function () {
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let progressBar = doc.getElementById("uploadProgressBar");
is(progressBar.style.display, "none",
"progress bar should not be visible");
executeSoon(runNextTest);
}
},
{
desc: "Makes sure the observer updates are reflected in the progress bar",
setup: function () {
},
run: function () {
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let progressBar = doc.getElementById("uploadProgressBar");
Services.obs.notifyObservers(null, "weave:engine:sync:finish", null);
Services.obs.notifyObservers(null, "weave:engine:sync:error", null);
let received = progressBar.getAttribute("value");
is(received, 2, "progress bar received correct notifications");
executeSoon(runNextTest);
}
},
{
desc: "Close button should close tab",
setup: function (){
},
run: function () {
function onTabClosed() {
ok(true, "received TabClose notification");
gBrowser.tabContainer.removeEventListener("TabClose", onTabClosed, false);
executeSoon(runNextTest);
}
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let button = doc.getElementById('closeButton');
let window = doc.defaultView;
gBrowser.tabContainer.addEventListener("TabClose", onTabClosed, false);
EventUtils.sendMouseEvent({type: "click"}, button, window);
}
},
];
function test () {
waitForExplicitFinish();
executeSoon(runNextTest);
}
function runNextTest()
{
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
if (gTests.length) {
let test = gTests.shift();
info(test.desc);
test.setup();
let tab = gBrowser.selectedTab = gBrowser.addTab("about:sync-progress");
tab.linkedBrowser.addEventListener("load", function (event) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
// Some part of the page is populated on load, so enqueue on it.
executeSoon(test.run);
}, true);
}
else {
finish();
}
}

View File

@ -71,6 +71,8 @@ browser.jar:
* content/browser/syncQuota.xul (content/syncQuota.xul)
content/browser/syncQuota.js (content/syncQuota.js)
content/browser/syncUtils.js (content/syncUtils.js)
content/browser/syncProgress.js (content/syncProgress.js)
* content/browser/syncProgress.xhtml (content/syncProgress.xhtml)
#endif
# XXX: We should exclude this one as well (bug 71895)
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)

View File

@ -97,6 +97,8 @@ static RedirEntry kRedirMap[] = {
{ "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
#ifdef MOZ_SERVICES_SYNC
{ "sync-progress", "chrome://browser/content/syncProgress.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
{ "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
nsIAboutModule::ALLOW_SCRIPT },
#endif

View File

@ -156,6 +156,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#ifdef MOZ_SERVICES_SYNC
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-progress", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },

View File

@ -0,0 +1,11 @@
<!ENTITY % brandDTD
SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!-- These strings are used in the sync progress upload page -->
<!ENTITY syncProgress.pageTitle "Your First Sync">
<!ENTITY syncProgress.textBlurb "Your data is now being encrypted and uploaded in the background. You can close this tab and continue using &brandShortName;.">
<!ENTITY syncProgress.closeButton "Close">
<!ENTITY syncProgress.logoAltText "&brandShortName; logo">
<!ENTITY syncProgress.diffText "&brandShortName; will now automatically sync in the background. You can close this tab and continue using &brandShortName;.">

View File

@ -9,6 +9,7 @@
locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
#ifdef MOZ_SERVICES_SYNC
locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd)
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
#endif
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)

View File

@ -93,10 +93,12 @@ browser.jar:
skin/classic/browser/sync-24-throbber.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-128.png
skin/classic/browser/sync-desktopIcon.png
skin/classic/browser/sync-mobileIcon.png
skin/classic/browser/sync-notification-24.png
skin/classic/browser/syncSetup.css
skin/classic/browser/syncCommon.css
skin/classic/browser/syncQuota.css
skin/classic/browser/syncProgress.css
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,79 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Firefox Sync.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Allison Naaktgeboren <ally@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
@import url(chrome://global/skin/inContentUI.css);
:root {
height: 100%;
width: 100%;
padding: 0;
}
body {
margin: 0;
padding: 0 2em;
}
#floatingBox {
margin: 4em auto;
max-width: 40em;
min-width: 23em;
padding: 1em 1.5em;
position: relative;
text-align: center;
}
#successLogo {
margin: 1em 2em;
}
#loadingText {
margin: 2em 6em;
}
#progressBar {
margin: 2em 10em;
}
#uploadProgressBar{
width: 100%;
}
#bottomRow {
margin-top: 2em;
padding: 0;
text-align: end;
}

View File

@ -131,12 +131,14 @@ browser.jar:
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-128.png
skin/classic/browser/sync-desktopIcon.png
skin/classic/browser/sync-mobileIcon.png
skin/classic/browser/sync-notification-24.png
skin/classic/browser/syncSetup.css
skin/classic/browser/syncCommon.css
skin/classic/browser/syncQuota.css
skin/classic/browser/syncProgress.css
#endif
skin/classic/browser/lion/keyhole-circle.png (keyhole-circle-lion.png)
skin/classic/browser/lion/Toolbar.png (Toolbar-lion.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,79 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Firefox Sync.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Allison Naaktgeboren <ally@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
@import url(chrome://global/skin/inContentUI.css);
:root {
height: 100%;
width: 100%;
padding: 0;
}
body {
margin: 0;
padding: 0 2em;
}
#floatingBox {
margin: 4em auto;
max-width: 40em;
min-width: 23em;
padding: 1em 1.5em;
position: relative;
text-align: center;
}
#successLogo {
margin: 1em 2em;
}
#loadingText {
margin: 2em 6em;
}
#progressBar {
margin: 2em 10em;
}
#uploadProgressBar{
width: 100%;
}
#bottomRow {
margin-top: 2em;
padding: 0;
text-align: end;
}

View File

@ -114,6 +114,7 @@ browser.jar:
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-128.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-desktopIcon.png
skin/classic/browser/sync-mobileIcon.png
@ -121,6 +122,7 @@ browser.jar:
skin/classic/browser/syncSetup.css
skin/classic/browser/syncCommon.css
skin/classic/browser/syncQuota.css
skin/classic/browser/syncProgress.css
#endif
#ifdef XP_WIN
@ -238,6 +240,7 @@ browser.jar:
skin/classic/aero/browser/sync-throbber.png
skin/classic/aero/browser/sync-16.png
skin/classic/aero/browser/sync-32.png
skin/classic/aero/browser/sync-128.png
skin/classic/aero/browser/sync-bg.png
skin/classic/aero/browser/sync-desktopIcon.png
skin/classic/aero/browser/sync-mobileIcon.png
@ -245,5 +248,6 @@ browser.jar:
skin/classic/aero/browser/syncSetup.css
skin/classic/aero/browser/syncCommon.css
skin/classic/aero/browser/syncQuota.css
skin/classic/aero/browser/syncProgress.css
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,79 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Firefox Sync.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Allison Naaktgeboren <ally@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
@import url(chrome://global/skin/inContentUI.css);
:root {
height: 100%;
width: 100%;
padding: 0;
}
body {
margin: 0;
padding: 0 2em;
}
#floatingBox {
margin: 4em auto;
max-width: 40em;
min-width: 23em;
padding: 1em 1.5em;
position: relative;
text-align: center;
}
#successLogo {
margin: 1em 2em;
}
#loadingText {
margin: 2em 6em;
}
#progressBar {
margin: 2em 10em;
}
#uploadProgressBar{
width: 100%;
}
#bottomRow {
margin-top: 2em;
padding: 0;
text-align: end;
}

View File

@ -560,8 +560,8 @@ TransactionPoolEventTarget::Dispatch(nsIRunnable* aRunnable,
NS_ASSERTION(aRunnable, "Null pointer!");
NS_ASSERTION(aFlags == NS_DISPATCH_NORMAL, "Unsupported!");
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE);
TransactionThreadPool* pool = TransactionThreadPool::Get();
NS_ASSERTION(pool, "This should never be null!");
return pool->Dispatch(mTransaction, aRunnable, false, nsnull);
}

View File

@ -125,6 +125,11 @@ public:
static IDBTransaction* GetCurrentTransaction();
bool HasTransaction()
{
return mTransaction;
}
nsISupports* GetSource()
{
return mRequest ? mRequest->Source() : nsnull;

View File

@ -85,7 +85,8 @@ EnumerateObjectStoreNames(const nsAString& aKey,
DatabaseInfo::DatabaseInfo()
: id(0),
nextObjectStoreId(1),
nextIndexId(1)
nextIndexId(1),
runningVersionChange(false)
{
MOZ_COUNT_CTOR(DatabaseInfo);
}

View File

@ -54,7 +54,8 @@ struct DatabaseInfo
~DatabaseInfo();
#else
DatabaseInfo()
: id(0), nextObjectStoreId(1), nextIndexId(1) { }
: id(0), nextObjectStoreId(1), nextIndexId(1), runningVersionChange(false)
{ }
#endif
static bool Get(PRUint32 aId,
@ -73,6 +74,7 @@ struct DatabaseInfo
nsString filePath;
PRInt64 nextObjectStoreId;
PRInt64 nextIndexId;
bool runningVersionChange;
nsAutoRefCnt referenceCount;
};

View File

@ -428,6 +428,34 @@ IDBDatabase::IsClosed()
return mClosed;
}
void
IDBDatabase::EnterSetVersionTransaction()
{
DatabaseInfo* dbInfo;
if (!DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
NS_ERROR("This should never fail!");
}
NS_ASSERTION(!dbInfo->runningVersionChange, "How did that happen?");
dbInfo->runningVersionChange = true;
}
void
IDBDatabase::ExitSetVersionTransaction()
{
DatabaseInfo* dbInfo;
if (!DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
NS_ERROR("This should never fail!");
}
NS_ASSERTION(dbInfo->runningVersionChange, "How did that happen?");
dbInfo->runningVersionChange = false;
IndexedDatabaseManager* manager = IndexedDatabaseManager::Get();
NS_ASSERTION(manager, "We should always have a manager here");
manager->UnblockSetVersionRunnable(this);
}
void
IDBDatabase::OnUnlink()
{
@ -710,6 +738,10 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
NS_ERROR("This should never fail!");
}
if (info->runningVersionChange) {
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
nsTArray<nsString> storesToOpen;
switch (type) {

View File

@ -135,6 +135,9 @@ public:
// Whether or not the database has had Close called on it.
bool IsClosed();
void EnterSetVersionTransaction();
void ExitSetVersionTransaction();
private:
IDBDatabase();
~IDBDatabase();

View File

@ -693,19 +693,15 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase)
// Now run the helper if there are no more live databases.
if (runnable->mHelper && runnable->mDatabases.IsEmpty()) {
// Don't hold the callback alive longer than necessary.
nsRefPtr<AsyncConnectionHelper> helper;
helper.swap(runnable->mHelper);
// At this point, all databases are closed, so no new transactions can
// be started. There may, however, still be outstanding transactions
// that have not completed. We need to wait for those before we
// dispatch the helper.
if (NS_FAILED(helper->DispatchToTransactionPool())) {
NS_WARNING("Failed to dispatch to thread pool!");
}
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
// Now wait for the transaction to complete. Completing the transaction
// will be our cue to remove the SetVersionRunnable from our list and
// therefore allow other SetVersion requests to begin.
TransactionThreadPool* pool = TransactionThreadPool::Get();
NS_ASSERTION(pool, "This should never be null!");
nsRefPtr<WaitForTransactionsToFinishRunnable> waitRunnable =
new WaitForTransactionsToFinishRunnable(runnable);
// All other databases should be closed, so we only need to wait on this
// one.
@ -714,8 +710,8 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase)
NS_ERROR("This should never fail!");
}
// Use the SetVersionRunnable as the callback.
if (!pool->WaitForAllDatabasesToComplete(array, runnable)) {
// Use the WaitForTransactionsToFinishRunnable as the callback.
if (!pool->WaitForAllDatabasesToComplete(array, waitRunnable)) {
NS_WARNING("Failed to wait for transaction to complete!");
}
}
@ -724,6 +720,27 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase)
}
}
void
IndexedDatabaseManager::UnblockSetVersionRunnable(IDBDatabase* aDatabase)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aDatabase, "Null pointer!");
// Check through the list of SetVersionRunnables to find the one we're seeking.
for (PRUint32 index = 0; index < mSetVersionRunnables.Length(); index++) {
nsRefPtr<SetVersionRunnable>& runnable = mSetVersionRunnables[index];
if (runnable->mRequestingDatabase->Id() == aDatabase->Id()) {
NS_ASSERTION(!runnable->mHelper,
"Why are we unblocking a runnable if the helper didn't run?");
NS_DispatchToCurrentThread(runnable);
return;
}
}
NS_NOTREACHED("How did we get here!");
}
// static
bool
IndexedDatabaseManager::SetCurrentDatabase(IDBDatabase* aDatabase)
@ -1283,3 +1300,39 @@ IndexedDatabaseManager::SetVersionRunnable::Run()
return NS_OK;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(IndexedDatabaseManager::WaitForTransactionsToFinishRunnable,
nsIRunnable)
NS_IMETHODIMP
IndexedDatabaseManager::WaitForTransactionsToFinishRunnable::Run()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
// Don't hold the callback alive longer than necessary.
nsRefPtr<AsyncConnectionHelper> helper;
helper.swap(mRunnable->mHelper);
nsRefPtr<SetVersionRunnable> runnable;
runnable.swap(mRunnable);
// If the helper has a transaction, dispatch it to the transaction
// threadpool.
if (helper->HasTransaction()) {
if (NS_FAILED(helper->DispatchToTransactionPool())) {
NS_WARNING("Failed to dispatch to thread pool!");
}
}
// Otherwise, dispatch it to the IO thread.
else {
IndexedDatabaseManager* manager = IndexedDatabaseManager::Get();
NS_ASSERTION(manager, "We should definitely have a manager here");
helper->Dispatch(manager->IOThread());
}
// The helper is responsible for calling
// IndexedDatabaseManager::UnblockSetVersionRunnable.
return NS_OK;
}

View File

@ -204,6 +204,8 @@ private:
// Called when AsyncUsageRunnable has finished its Run() method.
inline void OnUsageCheckComplete(AsyncUsageRunnable* aRunnable);
void UnblockSetVersionRunnable(IDBDatabase* aDatabase);
// Responsible for waiting until all databases have been closed before running
// the version change transaction. Created when
// IndexedDatabaseManager::SetDatabaseVersion is called. Runs only once on the
@ -227,6 +229,26 @@ private:
// Called when SetVersionRunnable has finished its Run() method.
inline void OnSetVersionRunnableComplete(SetVersionRunnable* aRunnable);
// A callback runnable used by the TransactionPool when it's safe to proceed
// with a SetVersion/DeleteDatabase/etc.
class WaitForTransactionsToFinishRunnable : public nsIRunnable
{
public:
WaitForTransactionsToFinishRunnable(SetVersionRunnable* aRunnable)
: mRunnable(aRunnable)
{
NS_ASSERTION(mRunnable, "Why don't we have a runnable?");
NS_ASSERTION(mRunnable->mDatabases.IsEmpty(), "We're here too early!");
}
NS_DECL_ISUPPORTS
NS_DECL_NSIRUNNABLE
private:
nsRefPtr<SetVersionRunnable> mRunnable;
};
// Maintains a list of live databases per origin.
nsClassHashtable<nsCStringHashKey, nsTArray<IDBDatabase*> > mLiveDatabases;

View File

@ -495,10 +495,13 @@ public:
NS_DECL_ISUPPORTS_INHERITED
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
protected:
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult Init();
// SetVersionHelper never fires an error event at the request. It hands that
// responsibility back to the OpenDatabaseHelper
void OnError() { }
@ -554,6 +557,8 @@ OpenDatabaseHelper::DoDatabaseWork()
}
#endif
mState = eFiringEvents; // In case we fail somewhere along the line.
if (IndexedDatabaseManager::IsShuttingDown()) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@ -646,9 +651,10 @@ OpenDatabaseHelper::DoDatabaseWork()
return NS_ERROR_DOM_INDEXEDDB_VERSION_ERR;
}
mState = mCurrentVersion != mRequestedVersion ?
eSetVersionPending :
eFiringEvents;
if (mCurrentVersion != mRequestedVersion) {
mState = eSetVersionPending;
}
return NS_OK;
}
@ -684,6 +690,7 @@ OpenDatabaseHelper::StartSetVersion()
// The SetVersionHelper is responsible for dispatching us back to the
// main thread again and changing the state to eSetVersionCompleted.
mState = eSetVersionPending;
return NS_OK;
}
@ -711,6 +718,12 @@ OpenDatabaseHelper::Run()
mState == eSetVersionCompleted, "Why are we here?");
if (mState == eSetVersionCompleted) {
// Allow transaction creation/other version change transactions to proceed
// before we fire events. Other version changes will be postd to the end
// of the event loop, and will be behind whatever the page does in
// its error/success event handlers.
mDatabase->ExitSetVersionTransaction();
mState = eFiringEvents;
} else {
// Notify the request that we're done, but only if we didn't just finish
@ -865,6 +878,15 @@ OpenDatabaseHelper::NotifySetVersionFinished()
return NS_DispatchToCurrentThread(this);
}
void
OpenDatabaseHelper::BlockDatabase()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(mDatabase, "This is going bad fast.");
mDatabase->EnterSetVersionTransaction();
}
void
OpenDatabaseHelper::DispatchSuccessEvent()
{
@ -916,6 +938,15 @@ OpenDatabaseHelper::ReleaseMainThreadObjects()
NS_IMPL_ISUPPORTS_INHERITED0(SetVersionHelper, AsyncConnectionHelper);
nsresult
SetVersionHelper::Init()
{
// Block transaction creation until we are done.
mOpenHelper->BlockDatabase();
return NS_OK;
}
nsresult
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{

View File

@ -82,6 +82,7 @@ public:
}
nsresult NotifySetVersionFinished();
void BlockDatabase();
protected:
// Methods only called on the main thread

View File

@ -238,7 +238,6 @@ TransactionThreadPool::FinishTransaction(IDBTransaction* aTransaction)
#ifdef DEBUG
if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) {
NS_ASSERTION(dbTransactionInfo->locked, "Should be locked!");
NS_ASSERTION(transactionCount == 1,
"More transactions running than should be!");
}
@ -344,10 +343,6 @@ TransactionThreadPool::TransactionCanRun(IDBTransaction* aTransaction,
PRUint32 transactionCount = transactionsInProgress.Length();
NS_ASSERTION(transactionCount, "Should never be 0!");
if (mode == IDBTransaction::VERSION_CHANGE) {
dbTransactionInfo->lockPending = true;
}
for (PRUint32 index = 0; index < transactionCount; index++) {
// See if this transaction is in out list of current transactions.
const TransactionInfo& info = transactionsInProgress[index];
@ -358,11 +353,7 @@ TransactionThreadPool::TransactionCanRun(IDBTransaction* aTransaction,
}
}
if (dbTransactionInfo->locked || dbTransactionInfo->lockPending) {
*aCanRun = false;
*aExistingQueue = nsnull;
return NS_OK;
}
NS_ASSERTION(mode != IDBTransaction::VERSION_CHANGE, "How did we get here?");
bool writeOverlap;
nsresult rv =
@ -448,11 +439,6 @@ TransactionThreadPool::Dispatch(IDBTransaction* aTransaction,
dbTransactionInfo = autoDBTransactionInfo;
}
if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) {
NS_ASSERTION(!dbTransactionInfo->locked, "Already locked?!");
dbTransactionInfo->locked = true;
}
const nsTArray<nsString>& objectStoreNames = aTransaction->mObjectStoreNames;
nsTArray<nsString>& storesInUse =

View File

@ -123,12 +123,6 @@ protected:
struct DatabaseTransactionInfo
{
DatabaseTransactionInfo()
: locked(false), lockPending(false)
{ }
bool locked;
bool lockPending;
nsTArray<TransactionInfo> transactions;
nsTArray<nsString> storesReading;
nsTArray<nsString> storesWriting;

View File

@ -98,6 +98,7 @@ TEST_FILES = \
test_setVersion.html \
test_setVersion_abort.html \
test_setVersion_events.html \
test_setVersion_exclusion.html \
test_writer_starvation.html \
third_party_iframe1.html \
third_party_iframe2.html \

View File

@ -69,6 +69,9 @@
db.createObjectStore("foo", { autoIncrement: true });
request.onsuccess = grabEventAndContinueHandler;
yield;
setTimeout(testFinishedCallback, 0, "ready");
yield;
}

View File

@ -104,7 +104,7 @@
db.onerror = errorEventCounter;
db.addEventListener("error", errorEventCounter, true);
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event.target.onsuccess = grabEventAndContinueHandler;
db.createObjectStore("foo", { autoIncrement: true });
yield;

View File

@ -12,7 +12,7 @@ function startDBWork() {
}
var store = db.createObjectStore("mystore");
store.add({ hello: "world" }, 42);
trans.oncomplete = madeMod;
e.target.onsuccess = madeMod;
};
}

View File

@ -33,6 +33,9 @@
let key = event.target.result;
ok(key, "Added entry");
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let objectStore = db.transaction("foo").objectStore("foo");
let first = objectStore.index("first");

View File

@ -25,7 +25,7 @@
let db = request.result;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
let objectStore = db.createObjectStore("foo", { autoIncrement: true });

View File

@ -23,7 +23,7 @@
let db = event.target.result;
db.onerror = errorHandler;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
// Make object store, add data.
let objectStore = db.createObjectStore("foo", { keyPath: "id" });
@ -39,7 +39,7 @@
let db2 = event.target.result;
db2.onerror = errorHandler;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
// Create index.
event.target.transaction.objectStore("foo").createIndex("foo", "num");

View File

@ -35,7 +35,7 @@
let event = yield;
let db = event.target.result;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
objectStore.createIndex("name", "name", { unique: true });

View File

@ -26,6 +26,7 @@
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
request.onsuccess = grabEventAndContinueHandler;
request = objectStore.getAll();
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
@ -46,6 +47,7 @@
}
}
yield;
yield;
request = db.transaction("foo").objectStore("foo").getAll();
request.onerror = errorHandler;

View File

@ -60,6 +60,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -78,7 +79,7 @@
}
}
}
event = yield;
yield;
ok(true, "1");
// Now create the indexes.
@ -88,7 +89,6 @@
}
is(objectStore.indexNames.length, indexData.length, "Good index count");
continueToNextStep();
yield;
ok(true, "2");

View File

@ -60,6 +60,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -87,7 +88,6 @@
}
is(objectStore.indexNames.length, indexData.length, "Good index count");
continueToNextStep();
yield;
objectStore = db.transaction(objectStoreName)

View File

@ -37,7 +37,7 @@
let db = event.target.result;
db.onerror = errorHandler;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
for (let objectStoreIndex in objectStoreData) {
const objectStoreInfo = objectStoreData[objectStoreIndex];

View File

@ -71,6 +71,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -97,7 +98,6 @@
indexData[i].options);
}
is(objectStore.indexNames.length, indexData.length, "Good index count");
continueToNextStep();
yield;
objectStore = db.transaction(objectStoreName)

View File

@ -51,6 +51,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -87,6 +88,7 @@
}
}
yield;
yield;
objectStore = db.transaction(objectStoreName)
.objectStore(objectStoreName);

View File

@ -28,7 +28,7 @@
let index2 = objectStore2.index("bar");
ok(index1 === index2, "Got same indexes");
transaction.oncomplete = continueToNextStep;
request.onsuccess = continueToNextStep;
yield;
transaction = db.transaction("foo");

View File

@ -29,7 +29,7 @@
autoIncrement: true });
let index = objectStore.createIndex("foo", "index");
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
yield;
objectStore = db.transaction("foo", IDBTransaction.READ_WRITE)

View File

@ -20,6 +20,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -31,7 +32,6 @@
is(db.objectStoreNames.length, 1, "Bad objectStores list");
is(db.objectStoreNames.item(0), objectStoreName, "Bad name");
continueToNextStep();
yield;
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);

View File

@ -26,7 +26,7 @@
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event.target.onsuccess = grabEventAndContinueHandler;
for (let i in objectStores) {
db.createObjectStore(objectStores[i], { autoIncrement: true });
}

View File

@ -22,6 +22,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -29,6 +30,8 @@
db.createObjectStore(osName, { autoIncrement: "true" });
yield;
let key1, key2;
request = db.transaction([osName], READ_WRITE)

View File

@ -0,0 +1,90 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = mozIndexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let request2 = mozIndexedDB.open(name, 2);
request2.onerror = errorHandler;
request2.onupgradeneeded = unexpectedSuccessHandler;
let event = yield;
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
is(event.target, request, "Event should be fired on the request");
ok(event.target.result instanceof IDBDatabase, "Expect a database here");
let db = event.target.result;
is(db.version, 1, "Database has correct version");
db.onupgradeneeded = function() {
ok(false, "our ongoing VERSION_CHANGE transaction should exclude any others!");
}
db.createObjectStore("foo");
try {
db.transaction("foo");
ok(false, "Transactions should be disallowed now!");
} catch (e) {
ok(e instanceof IDBDatabaseException, "Expect an IDBException");
is(e.code, IDBDatabaseException.NOT_ALLOWED_ERR, "Expect a NOT_ALLOWED_ERR");
}
request.transaction.oncomplete = grabEventAndContinueHandler;
yield;
// The database is still not fully open here.
try {
db.transaction("foo");
ok(false, "Transactions should be disallowed now!");
} catch (e) {
ok(e instanceof IDBDatabaseException, "Expect an IDBException");
is(e.code, IDBDatabaseException.NOT_ALLOWED_ERR, "Expect a NOT_ALLOWED_ERR");
}
request.onsuccess = grabEventAndContinueHandler;
yield;
db.onversionchange = function() {
ok(true, "next setVersion was unblocked appropriately");
db.close();
}
try {
db.transaction("foo");
ok(true, "Transactions should be allowed now!");
} catch (e) {
ok(false, "Transactions should be allowed now!");
}
request2.onupgradeneeded = null;
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -19,7 +19,7 @@
let db = event.target.result;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
let objectStore = db.createObjectStore("foo");
objectStore.add({}, 1).onerror = errorHandler;

View File

@ -29,6 +29,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -157,6 +158,8 @@
ok(true, "RemoveIndex threw");
}
yield;
request = db.transaction("foo", READ_WRITE).objectStore("foo").add({});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;

View File

@ -20,7 +20,7 @@
let db = event.target.result;
db.onerror = errorHandler;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
db.createObjectStore("foo", { autoIncrement: true });
yield;

View File

@ -20,7 +20,7 @@
let db = event.target.result;
db.onerror = errorHandler;
event.target.transaction.oncomplete = continueToNextStep;
event.target.onsuccess = continueToNextStep;
db.createObjectStore("foo");
yield;

View File

@ -23,6 +23,7 @@
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.target.result;
@ -39,7 +40,6 @@
let key = event.target.result;
ok(key, "Got a key");
SimpleTest.executeSoon(function() { testGenerator.next(); });
yield;
let continueReading = true;

View File

@ -6043,7 +6043,17 @@ PresShell::HandleEvent(nsIView *aView,
// still get sent to the window properly if nothing is focused or if a
// frame goes away while it is focused.
if (!eventTarget || !eventTarget->GetPrimaryFrame()) {
eventTarget = mDocument->GetRootElement();
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
if (htmlDoc) {
nsCOMPtr<nsIDOMHTMLElement> body;
htmlDoc->GetBody(getter_AddRefs(body));
eventTarget = do_QueryInterface(body);
if (!eventTarget) {
eventTarget = mDocument->GetRootElement();
}
} else {
eventTarget = mDocument->GetRootElement();
}
}
if (aEvent->message == NS_KEY_DOWN) {

View File

@ -346,6 +346,7 @@ _TEST_FILES += \
test_bug607529.html \
file_bug607529.html \
test_bug644768.html \
test_bug696020.html \
$(NULL)
endif

View File

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=696020
-->
<head>
<title>Test for Bug 696020</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696020">Mozilla Bug 696020</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 696020 **/
function startTest() {
var testFrame = document.getElementById("tf").contentWindow;
testFrame.focus();
var didHandleKeyEvent = false;
testFrame.addEventListener("keypress",
function(e) {
is(e.target, testFrame.document.body,
"Body element should be event target for key events!");
didHandleKeyEvent = true;
});
synthesizeKey("A", {}, testFrame);
ok(didHandleKeyEvent, "Should have handled a key event!");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(startTest)
</script>
</pre>
<iframe id="tf"></iframe>
</body>
</html>

View File

@ -103,7 +103,10 @@ class TPSTestRunner(object):
'services.sync.log.appender.console': 'Trace',
'services.sync.log.appender.debugLog.enabled': True,
'browser.dom.window.dump.enabled': True,
'extensions.checkCompatibility.4.0': False,
# Allow installing extensions dropped into the profile folder
'extensions.autoDisableScopes': 10,
# Don't open a dialog to show available add-on updates
'extensions.update.notifyUser' : False,
}
syncVerRe = re.compile(
r"Sync version: (?P<syncversion>.*)\n")

View File

@ -25,7 +25,7 @@ function test()
function onKey(aEvent)
{
if (aEvent.target != root) {
if (aEvent.target != root && aEvent.target != root.ownerDocument.body) {
ok(false, "unknown target: " + aEvent.target.tagName);
return;
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Blair McBride <bmcbride@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,11 +36,16 @@
*
* ***** END LICENSE BLOCK ***** */
/*
* The default namespace for this file is XUL. Be sure to prefix rules that
* are applicable to both XUL and HTML with '*|'.
*/
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
/* Page background */
:root {
*|*:root {
-moz-appearance: none;
padding: 18px;
background-color: Window;
@ -48,8 +54,12 @@
color: WindowText;
}
html|html {
font: message-box;
}
/* Content */
.main-content {
*|*.main-content {
/* Needed to allow the radius to clip the inner content, see bug 595656 */
/* Disabled because of bug 623615
overflow: hidden;

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Blair McBride <bmcbride@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,11 +38,15 @@
%include shared.inc
/*
* The default namespace for this file is XUL. Be sure to prefix rules that
* are applicable to both XUL and HTML with '*|'.
*/
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
/* Page background */
:root {
*|*:root {
-moz-appearance: none;
padding: 18px;
background-image: /* Texture */
@ -50,8 +55,12 @@
-moz-linear-gradient(top, #ADB5C2, #BFC6D1);
}
html|html {
font: message-box;
}
/* Content */
.main-content {
*|*.main-content {
/* Needed to allow the radius to clip the inner content, see bug 595656 */
/* Disabled because of bug 623615
overflow: hidden;
@ -62,7 +71,7 @@
}
/* Buttons */
button,
*|button,
menulist,
colorpicker[type="button"] {
-moz-appearance: none;
@ -84,6 +93,7 @@ colorpicker[type="button"]:-moz-focusring:not([open="true"]) > .colorpicker-butt
outline: 1px dotted #252F3B;
}
html|button[disabled],
button[disabled="true"],
menulist[disabled="true"],
colorpicker[type="button"][disabled="true"] {
@ -91,6 +101,7 @@ colorpicker[type="button"][disabled="true"] {
color: #505050;
}
html|button:not([disabled]):active:hover,
button:not([disabled="true"]):active:hover,
menulist[open="true"]:not([disabled="true"]),
colorpicker[type="button"][open="true"]:not([disabled="true"]) {

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Blair McBride <bmcbride@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,10 +36,15 @@
*
* ***** END LICENSE BLOCK ***** */
/*
* The default namespace for this file is XUL. Be sure to prefix rules that
* are applicable to both XUL and HTML with '*|'.
*/
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
/* Page background */
:root {
*|*:root {
-moz-appearance: none;
padding: 18px;
background-repeat: repeat;
@ -50,9 +56,13 @@
url("chrome://global/skin/inContentUI/background-texture.png");
}
html|html {
font: message-box;
}
%ifdef WINSTRIPE_AERO
@media all and (-moz-windows-default-theme) {
:root {
*|*:root {
color: #000;
background-color: #CCD9EA;
background-image: /* Fade-out texture at the top */
@ -63,7 +73,7 @@
}
@media all and (-moz-windows-compositor) {
:root {
*|*:root {
color: #000;
/* Blame shorlander for this monstrosity. */
background-image: /* Fade-out texture and light beams at the top */
@ -93,7 +103,7 @@
%endif
/* Content */
.main-content {
*|*.main-content {
/* Needed to allow the radius to clip the inner content, see bug 595656 */
/* Disabled because of bug 623615
overflow: hidden;
@ -109,7 +119,7 @@
%ifdef WINSTRIPE_AERO
@media all and (-moz-windows-compositor) {
/* Buttons */
button,
*|button,
menulist,
colorpicker[type="button"] {
-moz-appearance: none;
@ -133,6 +143,7 @@
outline: 1px dotted ThreeDDarkShadow;
}
html|button[disabled],
button[disabled="true"],
menulist[disabled="true"],
colorpicker[type="button"][disabled="true"] {
@ -144,6 +155,7 @@
color: #505050;
}
html|button:not([disabled]):active:hover,
button:not([disabled="true"]):active:hover,
menulist[open="true"]:not([disabled="true"]),
colorpicker[type="button"][open="true"]:not([disabled="true"]) {

View File

@ -148,59 +148,6 @@ typedef NTSTATUS (NTAPI *LdrLoadDll_func) (PWCHAR filePath, PULONG flags, PUNICO
static LdrLoadDll_func stub_LdrLoadDll = 0;
namespace {
template <class T>
struct RVAMap {
RVAMap(HANDLE map, unsigned offset) {
mMappedView = reinterpret_cast<T*>
(::MapViewOfFile(map, FILE_MAP_READ, 0, offset, sizeof(T)));
}
~RVAMap() {
if (mMappedView) {
::UnmapViewOfFile(mMappedView);
}
}
operator const T*() const { return mMappedView; }
const T* operator->() const { return mMappedView; }
private:
const T* mMappedView;
};
void
ForceASLR(const wchar_t* path)
{
HANDLE file = ::CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
if (file != INVALID_HANDLE_VALUE) {
HANDLE map = ::CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (map) {
RVAMap<IMAGE_DOS_HEADER> peHeader(map, 0);
if (peHeader) {
RVAMap<IMAGE_NT_HEADERS> ntHeader(map, peHeader->e_lfanew);
if (ntHeader) {
// If we're dealing with a DLL which has code inside it, but does not have the
// ASLR bit set, allocate a page at its base address.
if (((ntHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0) &&
(ntHeader->OptionalHeader.SizeOfCode > 0)) {
void* page = ::VirtualAlloc((LPVOID)ntHeader->OptionalHeader.ImageBase, 1,
MEM_RESERVE, PAGE_NOACCESS);
// Note that we will leak this page, but it's ok since it's just one page in
// the virtual address space, with no physical page backing it.
// We're done at this point!
}
}
}
::CloseHandle(map);
}
::CloseHandle(file);
}
}
}
static NTSTATUS NTAPI
patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle)
{
@ -210,32 +157,9 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
wchar_t *dll_part;
DllBlockInfo *info;
// In Windows 8, the first parameter seems to be used for more than just the
// path name. For example, its numerical value can be 1. Passing a non-valid
// pointer to SearchPathW will cause a crash, so we need to check to see if we
// are handed a valid pointer, and otherwise just pass NULL to SearchPathW.
PWCHAR sanitizedFilePath = (intptr_t(filePath) < 1024) ? NULL : filePath;
int len = moduleFileName->Length / 2;
wchar_t *fname = moduleFileName->Buffer;
// figure out the length of the string that we need
DWORD pathlen = SearchPathW(sanitizedFilePath, fname, L".dll", 0, NULL, NULL);
if (pathlen == 0) {
// uh, we couldn't find the DLL at all, so...
printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
return STATUS_DLL_NOT_FOUND;
}
nsAutoArrayPtr<wchar_t> full_fname(new wchar_t[pathlen+1]);
if (!full_fname) {
// couldn't allocate memory?
return STATUS_DLL_NOT_FOUND;
}
// now actually grab it
SearchPathW(sanitizedFilePath, fname, L".dll", pathlen+1, full_fname, NULL);
// The filename isn't guaranteed to be null terminated, but in practice
// it always will be; ensure that this is so, and bail if not.
// This is done instead of the more robust approach because of bug 527122,
@ -311,6 +235,29 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
#endif
if (info->maxVersion != ALL_VERSIONS) {
// In Windows 8, the first parameter seems to be used for more than just the
// path name. For example, its numerical value can be 1. Passing a non-valid
// pointer to SearchPathW will cause a crash, so we need to check to see if we
// are handed a valid pointer, and otherwise just pass NULL to SearchPathW.
PWCHAR sanitizedFilePath = (intptr_t(filePath) < 1024) ? NULL : filePath;
// figure out the length of the string that we need
DWORD pathlen = SearchPathW(sanitizedFilePath, fname, L".dll", 0, NULL, NULL);
if (pathlen == 0) {
// uh, we couldn't find the DLL at all, so...
printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
return STATUS_DLL_NOT_FOUND;
}
wchar_t *full_fname = (wchar_t*) malloc(sizeof(wchar_t)*(pathlen+1));
if (!full_fname) {
// couldn't allocate memory?
return STATUS_DLL_NOT_FOUND;
}
// now actually grab it
SearchPathW(sanitizedFilePath, fname, L".dll", pathlen+1, full_fname, NULL);
DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
@ -334,6 +281,8 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
load_ok = true;
}
}
free(full_fname);
}
if (!load_ok) {
@ -349,8 +298,6 @@ continue_loading:
NS_SetHasLoadedNewDLLs();
ForceASLR(full_fname);
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
}