Merge mozilla-central and mozilla-inbound
This commit is contained in:
1
.hgtags
1
.hgtags
@@ -69,3 +69,4 @@ a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
|
|||||||
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
|
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
|
||||||
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
|
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
|
||||||
c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
|
c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
|
||||||
|
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R15
|
||||||
|
|||||||
@@ -4159,7 +4159,7 @@ var XULBrowserWindow = {
|
|||||||
startTime: 0,
|
startTime: 0,
|
||||||
statusText: "",
|
statusText: "",
|
||||||
isBusy: false,
|
isBusy: false,
|
||||||
inContentWhitelist: ["about:addons", "about:permissions"],
|
inContentWhitelist: ["about:addons", "about:permissions", "about:sync-progress"],
|
||||||
|
|
||||||
QueryInterface: function (aIID) {
|
QueryInterface: function (aIID) {
|
||||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||||
|
|||||||
72
browser/base/content/syncProgress.js
Normal file
72
browser/base/content/syncProgress.js
Normal 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();
|
||||||
|
}
|
||||||
86
browser/base/content/syncProgress.xhtml
Normal file
86
browser/base/content/syncProgress.xhtml
Normal 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>
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
* Philipp von Weitershausen <philipp@weitershausen.de>
|
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||||
* Paul O’Shannessy <paul@oshannessy.com>
|
* Paul O’Shannessy <paul@oshannessy.com>
|
||||||
* Richard Newman <rnewman@mozilla.com>
|
* Richard Newman <rnewman@mozilla.com>
|
||||||
|
* Allison Naaktgeboren <ally@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* 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
|
* 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 EXISTING_ACCOUNT_LOGIN_PAGE = 4;
|
||||||
const OPTIONS_PAGE = 5;
|
const OPTIONS_PAGE = 5;
|
||||||
const OPTIONS_CONFIRM_PAGE = 6;
|
const OPTIONS_CONFIRM_PAGE = 6;
|
||||||
const SETUP_SUCCESS_PAGE = 7;
|
|
||||||
|
|
||||||
// Broader than we'd like, but after this changed from api-secure.recaptcha.net
|
// 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.
|
// we had no choice. At least we only do this for the duration of setup.
|
||||||
@@ -411,6 +411,7 @@ var gSyncSetup = {
|
|||||||
this.checkFields();
|
this.checkFields();
|
||||||
break;
|
break;
|
||||||
case EXISTING_ACCOUNT_CONNECT_PAGE:
|
case EXISTING_ACCOUNT_CONNECT_PAGE:
|
||||||
|
Weave.Svc.Prefs.set("firstSync", "existingAccount");
|
||||||
this.wizard.getButton("next").hidden = false;
|
this.wizard.getButton("next").hidden = false;
|
||||||
this.wizard.getButton("back").hidden = false;
|
this.wizard.getButton("back").hidden = false;
|
||||||
this.wizard.getButton("extra1").hidden = false;
|
this.wizard.getButton("extra1").hidden = false;
|
||||||
@@ -425,18 +426,6 @@ var gSyncSetup = {
|
|||||||
this.wizard.canRewind = true;
|
this.wizard.canRewind = true;
|
||||||
this.checkFields();
|
this.checkFields();
|
||||||
break;
|
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:
|
case OPTIONS_PAGE:
|
||||||
this.wizard.canRewind = false;
|
this.wizard.canRewind = false;
|
||||||
this.wizard.canAdvance = true;
|
this.wizard.canAdvance = true;
|
||||||
@@ -473,7 +462,7 @@ var gSyncSetup = {
|
|||||||
!Weave.Utils.ensureMPUnlocked()) {
|
!Weave.Utils.ensureMPUnlocked()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this.wizard.pageIndex) {
|
switch (this.wizard.pageIndex) {
|
||||||
case PAIR_PAGE:
|
case PAIR_PAGE:
|
||||||
this.startPairing();
|
this.startPairing();
|
||||||
@@ -519,7 +508,8 @@ var gSyncSetup = {
|
|||||||
Weave.Service.password = password;
|
Weave.Service.password = password;
|
||||||
Weave.Service.passphrase = Weave.Utils.generatePassphrase();
|
Weave.Service.passphrase = Weave.Utils.generatePassphrase();
|
||||||
this._handleNoScript(false);
|
this._handleNoScript(false);
|
||||||
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
|
Weave.Svc.Prefs.set("firstSync", "newAccount");
|
||||||
|
this.wizardFinish();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,8 +522,9 @@ var gSyncSetup = {
|
|||||||
Weave.Service.password = document.getElementById("existingPassword").value;
|
Weave.Service.password = document.getElementById("existingPassword").value;
|
||||||
let pp = document.getElementById("existingPassphrase").value;
|
let pp = document.getElementById("existingPassphrase").value;
|
||||||
Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
|
Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
|
||||||
if (Weave.Service.login())
|
if (Weave.Service.login()) {
|
||||||
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
|
this.wizardFinish();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
case OPTIONS_PAGE:
|
case OPTIONS_PAGE:
|
||||||
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
|
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
|
||||||
@@ -544,8 +535,7 @@ var gSyncSetup = {
|
|||||||
return this._handleChoice();
|
return this._handleChoice();
|
||||||
case OPTIONS_CONFIRM_PAGE:
|
case OPTIONS_CONFIRM_PAGE:
|
||||||
if (this._resettingSync) {
|
if (this._resettingSync) {
|
||||||
this.onWizardFinish();
|
this.wizardFinish();
|
||||||
window.close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.returnFromOptions();
|
return this.returnFromOptions();
|
||||||
@@ -580,9 +570,13 @@ var gSyncSetup = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
onWizardFinish: function () {
|
wizardFinish: function () {
|
||||||
this.setupInitialSync();
|
this.setupInitialSync();
|
||||||
|
|
||||||
|
if (this.wizardType == "pair") {
|
||||||
|
this.completePairing();
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._resettingSync) {
|
if (!this._resettingSync) {
|
||||||
function isChecked(element) {
|
function isChecked(element) {
|
||||||
return document.getElementById(element).hasAttribute("checked");
|
return document.getElementById(element).hasAttribute("checked");
|
||||||
@@ -598,22 +592,17 @@ var gSyncSetup = {
|
|||||||
|
|
||||||
Weave.Service.persistLogin();
|
Weave.Service.persistLogin();
|
||||||
Weave.Svc.Obs.notify("weave:service:setup-complete");
|
Weave.Svc.Obs.notify("weave:service:setup-complete");
|
||||||
if (this._settingUpNew)
|
|
||||||
gSyncUtils.openFirstClientFirstrun();
|
gSyncUtils.openFirstSyncProgressPage();
|
||||||
else
|
|
||||||
gSyncUtils.openAddedClientFirstrun();
|
|
||||||
}
|
}
|
||||||
Weave.Utils.nextTick(Weave.Service.sync, Weave.Service);
|
Weave.Utils.nextTick(Weave.Service.sync, Weave.Service);
|
||||||
|
window.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
onWizardCancel: function () {
|
onWizardCancel: function () {
|
||||||
if (this._resettingSync)
|
if (this._resettingSync)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.wizard.pageIndex == SETUP_SUCCESS_PAGE) {
|
|
||||||
this.onWizardFinish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.abortEasySetup();
|
this.abortEasySetup();
|
||||||
this._handleNoScript(false);
|
this._handleNoScript(false);
|
||||||
Weave.Service.startOver();
|
Weave.Service.startOver();
|
||||||
@@ -714,7 +703,7 @@ var gSyncSetup = {
|
|||||||
Weave.Service.password = credentials.password;
|
Weave.Service.password = credentials.password;
|
||||||
Weave.Service.passphrase = credentials.synckey;
|
Weave.Service.passphrase = credentials.synckey;
|
||||||
Weave.Service.serverURL = credentials.serverURL;
|
Weave.Service.serverURL = credentials.serverURL;
|
||||||
self.wizard.pageIndex = SETUP_SUCCESS_PAGE;
|
gSyncSetup.wizardFinish();
|
||||||
},
|
},
|
||||||
|
|
||||||
onAbort: function onAbort(error) {
|
onAbort: function onAbort(error) {
|
||||||
@@ -906,25 +895,6 @@ var gSyncSetup = {
|
|||||||
return valid;
|
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 () {
|
_handleChoice: function () {
|
||||||
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
|
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
|
||||||
document.getElementById("chosenActionDeck").selectedIndex = desc;
|
document.getElementById("chosenActionDeck").selectedIndex = desc;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
# Mike Connor <mconnor@mozilla.com>
|
# Mike Connor <mconnor@mozilla.com>
|
||||||
# Paul O’Shannessy <paul@oshannessy.com>
|
# Paul O’Shannessy <paul@oshannessy.com>
|
||||||
# Philipp von Weitershausen <philipp@weitershausen.de>
|
# Philipp von Weitershausen <philipp@weitershausen.de>
|
||||||
|
# Allison Naaktgeboren <ally@mozilla.com>
|
||||||
#
|
#
|
||||||
# Alternatively, the contents of this file may be used under the terms of
|
# 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
|
# 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"
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
onwizardnext="return gSyncSetup.onWizardAdvance()"
|
onwizardnext="return gSyncSetup.onWizardAdvance()"
|
||||||
onwizardback="return gSyncSetup.onWizardBack()"
|
onwizardback="return gSyncSetup.onWizardBack()"
|
||||||
onwizardfinish="gSyncSetup.onWizardFinish()"
|
|
||||||
onwizardcancel="gSyncSetup.onWizardCancel()"
|
onwizardcancel="gSyncSetup.onWizardCancel()"
|
||||||
onload="gSyncSetup.init()">
|
onload="gSyncSetup.init()">
|
||||||
|
|
||||||
@@ -511,24 +511,11 @@
|
|||||||
</vbox>
|
</vbox>
|
||||||
</deck>
|
</deck>
|
||||||
</wizardpage>
|
</wizardpage>
|
||||||
|
# In terms of the wizard flow shown to the user, the 'syncOptionsConfirm'
|
||||||
<wizardpage label="&setup.successPage.title;"
|
# page above is not the last wizard page. To prevent the wizard binding from
|
||||||
id="successfulSetup"
|
# assuming that it is, we're inserting this dummy page here. This also means
|
||||||
onextra1="gSyncSetup.onSyncOptions()"
|
# that the wizard needs to always be closed manually via wizardFinish().
|
||||||
onpageshow="gSyncSetup.onPageShow()">
|
<wizardpage>
|
||||||
<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"/>
|
|
||||||
</wizardpage>
|
</wizardpage>
|
||||||
</wizard>
|
</wizard>
|
||||||
|
|
||||||
|
|||||||
@@ -109,17 +109,8 @@ let gSyncUtils = {
|
|||||||
this._openLink(Weave.Svc.Prefs.get("privacyURL"));
|
this._openLink(Weave.Svc.Prefs.get("privacyURL"));
|
||||||
},
|
},
|
||||||
|
|
||||||
// xxxmpc - fix domain before 1.3 final (bug 583652)
|
openFirstSyncProgressPage: function () {
|
||||||
_baseURL: "http://www.mozilla.com/firefox/sync/",
|
this._openLink("about:sync-progress");
|
||||||
|
|
||||||
openFirstClientFirstrun: function () {
|
|
||||||
let url = this._baseURL + "firstrun.html";
|
|
||||||
this._openLink(url);
|
|
||||||
},
|
|
||||||
|
|
||||||
openAddedClientFirstrun: function () {
|
|
||||||
let url = this._baseURL + "secondrun.html";
|
|
||||||
this._openLink(url);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ _BROWSER_FILES = \
|
|||||||
test_wyciwyg_copying.html \
|
test_wyciwyg_copying.html \
|
||||||
authenticate.sjs \
|
authenticate.sjs \
|
||||||
browser_minimize.js \
|
browser_minimize.js \
|
||||||
|
browser_aboutSyncProgress.js \
|
||||||
browser_middleMouse_inherit.js \
|
browser_middleMouse_inherit.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|||||||
101
browser/base/content/test/browser_aboutSyncProgress.js
Normal file
101
browser/base/content/test/browser_aboutSyncProgress.js
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -71,6 +71,8 @@ browser.jar:
|
|||||||
* content/browser/syncQuota.xul (content/syncQuota.xul)
|
* content/browser/syncQuota.xul (content/syncQuota.xul)
|
||||||
content/browser/syncQuota.js (content/syncQuota.js)
|
content/browser/syncQuota.js (content/syncQuota.js)
|
||||||
content/browser/syncUtils.js (content/syncUtils.js)
|
content/browser/syncUtils.js (content/syncUtils.js)
|
||||||
|
content/browser/syncProgress.js (content/syncProgress.js)
|
||||||
|
* content/browser/syncProgress.xhtml (content/syncProgress.xhtml)
|
||||||
#endif
|
#endif
|
||||||
# XXX: We should exclude this one as well (bug 71895)
|
# XXX: We should exclude this one as well (bug 71895)
|
||||||
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
|
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ static RedirEntry kRedirMap[] = {
|
|||||||
{ "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
|
{ "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
|
||||||
nsIAboutModule::ALLOW_SCRIPT },
|
nsIAboutModule::ALLOW_SCRIPT },
|
||||||
#ifdef MOZ_SERVICES_SYNC
|
#ifdef MOZ_SERVICES_SYNC
|
||||||
|
{ "sync-progress", "chrome://browser/content/syncProgress.xhtml",
|
||||||
|
nsIAboutModule::ALLOW_SCRIPT },
|
||||||
{ "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
|
{ "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
|
||||||
nsIAboutModule::ALLOW_SCRIPT },
|
nsIAboutModule::ALLOW_SCRIPT },
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
|||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
#ifdef MOZ_SERVICES_SYNC
|
#ifdef MOZ_SERVICES_SYNC
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ 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
|
#endif
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||||
|
|||||||
11
browser/locales/en-US/chrome/browser/syncProgress.dtd
Normal file
11
browser/locales/en-US/chrome/browser/syncProgress.dtd
Normal 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;.">
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
|
locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
|
||||||
locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
|
locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
|
||||||
#ifdef MOZ_SERVICES_SYNC
|
#ifdef MOZ_SERVICES_SYNC
|
||||||
|
locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd)
|
||||||
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
|
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
|
||||||
#endif
|
#endif
|
||||||
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
|
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
|
||||||
|
|||||||
@@ -93,10 +93,12 @@ browser.jar:
|
|||||||
skin/classic/browser/sync-24-throbber.png
|
skin/classic/browser/sync-24-throbber.png
|
||||||
skin/classic/browser/sync-32.png
|
skin/classic/browser/sync-32.png
|
||||||
skin/classic/browser/sync-bg.png
|
skin/classic/browser/sync-bg.png
|
||||||
|
skin/classic/browser/sync-128.png
|
||||||
skin/classic/browser/sync-desktopIcon.png
|
skin/classic/browser/sync-desktopIcon.png
|
||||||
skin/classic/browser/sync-mobileIcon.png
|
skin/classic/browser/sync-mobileIcon.png
|
||||||
skin/classic/browser/sync-notification-24.png
|
skin/classic/browser/sync-notification-24.png
|
||||||
skin/classic/browser/syncSetup.css
|
skin/classic/browser/syncSetup.css
|
||||||
skin/classic/browser/syncCommon.css
|
skin/classic/browser/syncCommon.css
|
||||||
skin/classic/browser/syncQuota.css
|
skin/classic/browser/syncQuota.css
|
||||||
|
skin/classic/browser/syncProgress.css
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
BIN
browser/themes/gnomestripe/browser/sync-128.png
Normal file
BIN
browser/themes/gnomestripe/browser/sync-128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
79
browser/themes/gnomestripe/browser/syncProgress.css
Normal file
79
browser/themes/gnomestripe/browser/syncProgress.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -131,12 +131,14 @@ browser.jar:
|
|||||||
skin/classic/browser/sync-16.png
|
skin/classic/browser/sync-16.png
|
||||||
skin/classic/browser/sync-32.png
|
skin/classic/browser/sync-32.png
|
||||||
skin/classic/browser/sync-bg.png
|
skin/classic/browser/sync-bg.png
|
||||||
|
skin/classic/browser/sync-128.png
|
||||||
skin/classic/browser/sync-desktopIcon.png
|
skin/classic/browser/sync-desktopIcon.png
|
||||||
skin/classic/browser/sync-mobileIcon.png
|
skin/classic/browser/sync-mobileIcon.png
|
||||||
skin/classic/browser/sync-notification-24.png
|
skin/classic/browser/sync-notification-24.png
|
||||||
skin/classic/browser/syncSetup.css
|
skin/classic/browser/syncSetup.css
|
||||||
skin/classic/browser/syncCommon.css
|
skin/classic/browser/syncCommon.css
|
||||||
skin/classic/browser/syncQuota.css
|
skin/classic/browser/syncQuota.css
|
||||||
|
skin/classic/browser/syncProgress.css
|
||||||
#endif
|
#endif
|
||||||
skin/classic/browser/lion/keyhole-circle.png (keyhole-circle-lion.png)
|
skin/classic/browser/lion/keyhole-circle.png (keyhole-circle-lion.png)
|
||||||
skin/classic/browser/lion/Toolbar.png (Toolbar-lion.png)
|
skin/classic/browser/lion/Toolbar.png (Toolbar-lion.png)
|
||||||
|
|||||||
BIN
browser/themes/pinstripe/browser/sync-128.png
Normal file
BIN
browser/themes/pinstripe/browser/sync-128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
79
browser/themes/pinstripe/browser/syncProgress.css
Normal file
79
browser/themes/pinstripe/browser/syncProgress.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -114,6 +114,7 @@ browser.jar:
|
|||||||
skin/classic/browser/sync-throbber.png
|
skin/classic/browser/sync-throbber.png
|
||||||
skin/classic/browser/sync-16.png
|
skin/classic/browser/sync-16.png
|
||||||
skin/classic/browser/sync-32.png
|
skin/classic/browser/sync-32.png
|
||||||
|
skin/classic/browser/sync-128.png
|
||||||
skin/classic/browser/sync-bg.png
|
skin/classic/browser/sync-bg.png
|
||||||
skin/classic/browser/sync-desktopIcon.png
|
skin/classic/browser/sync-desktopIcon.png
|
||||||
skin/classic/browser/sync-mobileIcon.png
|
skin/classic/browser/sync-mobileIcon.png
|
||||||
@@ -121,6 +122,7 @@ browser.jar:
|
|||||||
skin/classic/browser/syncSetup.css
|
skin/classic/browser/syncSetup.css
|
||||||
skin/classic/browser/syncCommon.css
|
skin/classic/browser/syncCommon.css
|
||||||
skin/classic/browser/syncQuota.css
|
skin/classic/browser/syncQuota.css
|
||||||
|
skin/classic/browser/syncProgress.css
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
@@ -238,6 +240,7 @@ browser.jar:
|
|||||||
skin/classic/aero/browser/sync-throbber.png
|
skin/classic/aero/browser/sync-throbber.png
|
||||||
skin/classic/aero/browser/sync-16.png
|
skin/classic/aero/browser/sync-16.png
|
||||||
skin/classic/aero/browser/sync-32.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-bg.png
|
||||||
skin/classic/aero/browser/sync-desktopIcon.png
|
skin/classic/aero/browser/sync-desktopIcon.png
|
||||||
skin/classic/aero/browser/sync-mobileIcon.png
|
skin/classic/aero/browser/sync-mobileIcon.png
|
||||||
@@ -245,5 +248,6 @@ browser.jar:
|
|||||||
skin/classic/aero/browser/syncSetup.css
|
skin/classic/aero/browser/syncSetup.css
|
||||||
skin/classic/aero/browser/syncCommon.css
|
skin/classic/aero/browser/syncCommon.css
|
||||||
skin/classic/aero/browser/syncQuota.css
|
skin/classic/aero/browser/syncQuota.css
|
||||||
|
skin/classic/aero/browser/syncProgress.css
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
BIN
browser/themes/winstripe/browser/sync-128.png
Normal file
BIN
browser/themes/winstripe/browser/sync-128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
79
browser/themes/winstripe/browser/syncProgress.css
Normal file
79
browser/themes/winstripe/browser/syncProgress.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -560,8 +560,8 @@ TransactionPoolEventTarget::Dispatch(nsIRunnable* aRunnable,
|
|||||||
NS_ASSERTION(aRunnable, "Null pointer!");
|
NS_ASSERTION(aRunnable, "Null pointer!");
|
||||||
NS_ASSERTION(aFlags == NS_DISPATCH_NORMAL, "Unsupported!");
|
NS_ASSERTION(aFlags == NS_DISPATCH_NORMAL, "Unsupported!");
|
||||||
|
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
TransactionThreadPool* pool = TransactionThreadPool::Get();
|
||||||
NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE);
|
NS_ASSERTION(pool, "This should never be null!");
|
||||||
|
|
||||||
return pool->Dispatch(mTransaction, aRunnable, false, nsnull);
|
return pool->Dispatch(mTransaction, aRunnable, false, nsnull);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,11 @@ public:
|
|||||||
|
|
||||||
static IDBTransaction* GetCurrentTransaction();
|
static IDBTransaction* GetCurrentTransaction();
|
||||||
|
|
||||||
|
bool HasTransaction()
|
||||||
|
{
|
||||||
|
return mTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
nsISupports* GetSource()
|
nsISupports* GetSource()
|
||||||
{
|
{
|
||||||
return mRequest ? mRequest->Source() : nsnull;
|
return mRequest ? mRequest->Source() : nsnull;
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ EnumerateObjectStoreNames(const nsAString& aKey,
|
|||||||
DatabaseInfo::DatabaseInfo()
|
DatabaseInfo::DatabaseInfo()
|
||||||
: id(0),
|
: id(0),
|
||||||
nextObjectStoreId(1),
|
nextObjectStoreId(1),
|
||||||
nextIndexId(1)
|
nextIndexId(1),
|
||||||
|
runningVersionChange(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(DatabaseInfo);
|
MOZ_COUNT_CTOR(DatabaseInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ struct DatabaseInfo
|
|||||||
~DatabaseInfo();
|
~DatabaseInfo();
|
||||||
#else
|
#else
|
||||||
DatabaseInfo()
|
DatabaseInfo()
|
||||||
: id(0), nextObjectStoreId(1), nextIndexId(1) { }
|
: id(0), nextObjectStoreId(1), nextIndexId(1), runningVersionChange(false)
|
||||||
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool Get(PRUint32 aId,
|
static bool Get(PRUint32 aId,
|
||||||
@@ -73,6 +74,7 @@ struct DatabaseInfo
|
|||||||
nsString filePath;
|
nsString filePath;
|
||||||
PRInt64 nextObjectStoreId;
|
PRInt64 nextObjectStoreId;
|
||||||
PRInt64 nextIndexId;
|
PRInt64 nextIndexId;
|
||||||
|
bool runningVersionChange;
|
||||||
|
|
||||||
nsAutoRefCnt referenceCount;
|
nsAutoRefCnt referenceCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -428,6 +428,34 @@ IDBDatabase::IsClosed()
|
|||||||
return mClosed;
|
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
|
void
|
||||||
IDBDatabase::OnUnlink()
|
IDBDatabase::OnUnlink()
|
||||||
{
|
{
|
||||||
@@ -710,6 +738,10 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
|||||||
NS_ERROR("This should never fail!");
|
NS_ERROR("This should never fail!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info->runningVersionChange) {
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
nsTArray<nsString> storesToOpen;
|
nsTArray<nsString> storesToOpen;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@@ -135,6 +135,9 @@ public:
|
|||||||
// Whether or not the database has had Close called on it.
|
// Whether or not the database has had Close called on it.
|
||||||
bool IsClosed();
|
bool IsClosed();
|
||||||
|
|
||||||
|
void EnterSetVersionTransaction();
|
||||||
|
void ExitSetVersionTransaction();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IDBDatabase();
|
IDBDatabase();
|
||||||
~IDBDatabase();
|
~IDBDatabase();
|
||||||
|
|||||||
@@ -693,19 +693,15 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase)
|
|||||||
|
|
||||||
// Now run the helper if there are no more live databases.
|
// Now run the helper if there are no more live databases.
|
||||||
if (runnable->mHelper && runnable->mDatabases.IsEmpty()) {
|
if (runnable->mHelper && runnable->mDatabases.IsEmpty()) {
|
||||||
// Don't hold the callback alive longer than necessary.
|
// At this point, all databases are closed, so no new transactions can
|
||||||
nsRefPtr<AsyncConnectionHelper> helper;
|
// be started. There may, however, still be outstanding transactions
|
||||||
helper.swap(runnable->mHelper);
|
// that have not completed. We need to wait for those before we
|
||||||
|
// dispatch the helper.
|
||||||
|
|
||||||
if (NS_FAILED(helper->DispatchToTransactionPool())) {
|
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
||||||
NS_WARNING("Failed to dispatch to thread pool!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now wait for the transaction to complete. Completing the transaction
|
nsRefPtr<WaitForTransactionsToFinishRunnable> waitRunnable =
|
||||||
// will be our cue to remove the SetVersionRunnable from our list and
|
new WaitForTransactionsToFinishRunnable(runnable);
|
||||||
// therefore allow other SetVersion requests to begin.
|
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::Get();
|
|
||||||
NS_ASSERTION(pool, "This should never be null!");
|
|
||||||
|
|
||||||
// All other databases should be closed, so we only need to wait on this
|
// All other databases should be closed, so we only need to wait on this
|
||||||
// one.
|
// one.
|
||||||
@@ -714,8 +710,8 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase)
|
|||||||
NS_ERROR("This should never fail!");
|
NS_ERROR("This should never fail!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the SetVersionRunnable as the callback.
|
// Use the WaitForTransactionsToFinishRunnable as the callback.
|
||||||
if (!pool->WaitForAllDatabasesToComplete(array, runnable)) {
|
if (!pool->WaitForAllDatabasesToComplete(array, waitRunnable)) {
|
||||||
NS_WARNING("Failed to wait for transaction to complete!");
|
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
|
// static
|
||||||
bool
|
bool
|
||||||
IndexedDatabaseManager::SetCurrentDatabase(IDBDatabase* aDatabase)
|
IndexedDatabaseManager::SetCurrentDatabase(IDBDatabase* aDatabase)
|
||||||
@@ -1283,3 +1300,39 @@ IndexedDatabaseManager::SetVersionRunnable::Run()
|
|||||||
|
|
||||||
return NS_OK;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ private:
|
|||||||
// Called when AsyncUsageRunnable has finished its Run() method.
|
// Called when AsyncUsageRunnable has finished its Run() method.
|
||||||
inline void OnUsageCheckComplete(AsyncUsageRunnable* aRunnable);
|
inline void OnUsageCheckComplete(AsyncUsageRunnable* aRunnable);
|
||||||
|
|
||||||
|
void UnblockSetVersionRunnable(IDBDatabase* aDatabase);
|
||||||
|
|
||||||
// Responsible for waiting until all databases have been closed before running
|
// Responsible for waiting until all databases have been closed before running
|
||||||
// the version change transaction. Created when
|
// the version change transaction. Created when
|
||||||
// IndexedDatabaseManager::SetDatabaseVersion is called. Runs only once on the
|
// IndexedDatabaseManager::SetDatabaseVersion is called. Runs only once on the
|
||||||
@@ -227,6 +229,26 @@ private:
|
|||||||
// Called when SetVersionRunnable has finished its Run() method.
|
// Called when SetVersionRunnable has finished its Run() method.
|
||||||
inline void OnSetVersionRunnableComplete(SetVersionRunnable* aRunnable);
|
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.
|
// Maintains a list of live databases per origin.
|
||||||
nsClassHashtable<nsCStringHashKey, nsTArray<IDBDatabase*> > mLiveDatabases;
|
nsClassHashtable<nsCStringHashKey, nsTArray<IDBDatabase*> > mLiveDatabases;
|
||||||
|
|
||||||
|
|||||||
@@ -495,10 +495,13 @@ public:
|
|||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
|
|
||||||
nsresult GetSuccessResult(JSContext* aCx,
|
nsresult GetSuccessResult(JSContext* aCx,
|
||||||
jsval* aVal);
|
jsval* aVal);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
|
||||||
|
nsresult Init();
|
||||||
|
|
||||||
// SetVersionHelper never fires an error event at the request. It hands that
|
// SetVersionHelper never fires an error event at the request. It hands that
|
||||||
// responsibility back to the OpenDatabaseHelper
|
// responsibility back to the OpenDatabaseHelper
|
||||||
void OnError() { }
|
void OnError() { }
|
||||||
@@ -554,6 +557,8 @@ OpenDatabaseHelper::DoDatabaseWork()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mState = eFiringEvents; // In case we fail somewhere along the line.
|
||||||
|
|
||||||
if (IndexedDatabaseManager::IsShuttingDown()) {
|
if (IndexedDatabaseManager::IsShuttingDown()) {
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@@ -646,9 +651,10 @@ OpenDatabaseHelper::DoDatabaseWork()
|
|||||||
return NS_ERROR_DOM_INDEXEDDB_VERSION_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_VERSION_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mState = mCurrentVersion != mRequestedVersion ?
|
if (mCurrentVersion != mRequestedVersion) {
|
||||||
eSetVersionPending :
|
mState = eSetVersionPending;
|
||||||
eFiringEvents;
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,6 +690,7 @@ OpenDatabaseHelper::StartSetVersion()
|
|||||||
// The SetVersionHelper is responsible for dispatching us back to the
|
// The SetVersionHelper is responsible for dispatching us back to the
|
||||||
// main thread again and changing the state to eSetVersionCompleted.
|
// main thread again and changing the state to eSetVersionCompleted.
|
||||||
mState = eSetVersionPending;
|
mState = eSetVersionPending;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,6 +718,12 @@ OpenDatabaseHelper::Run()
|
|||||||
mState == eSetVersionCompleted, "Why are we here?");
|
mState == eSetVersionCompleted, "Why are we here?");
|
||||||
|
|
||||||
if (mState == eSetVersionCompleted) {
|
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;
|
mState = eFiringEvents;
|
||||||
} else {
|
} else {
|
||||||
// Notify the request that we're done, but only if we didn't just finish
|
// 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);
|
return NS_DispatchToCurrentThread(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenDatabaseHelper::BlockDatabase()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ASSERTION(mDatabase, "This is going bad fast.");
|
||||||
|
|
||||||
|
mDatabase->EnterSetVersionTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OpenDatabaseHelper::DispatchSuccessEvent()
|
OpenDatabaseHelper::DispatchSuccessEvent()
|
||||||
{
|
{
|
||||||
@@ -916,6 +938,15 @@ OpenDatabaseHelper::ReleaseMainThreadObjects()
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(SetVersionHelper, AsyncConnectionHelper);
|
NS_IMPL_ISUPPORTS_INHERITED0(SetVersionHelper, AsyncConnectionHelper);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
SetVersionHelper::Init()
|
||||||
|
{
|
||||||
|
// Block transaction creation until we are done.
|
||||||
|
mOpenHelper->BlockDatabase();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult NotifySetVersionFinished();
|
nsresult NotifySetVersionFinished();
|
||||||
|
void BlockDatabase();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Methods only called on the main thread
|
// Methods only called on the main thread
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ TransactionThreadPool::FinishTransaction(IDBTransaction* aTransaction)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) {
|
if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) {
|
||||||
NS_ASSERTION(dbTransactionInfo->locked, "Should be locked!");
|
|
||||||
NS_ASSERTION(transactionCount == 1,
|
NS_ASSERTION(transactionCount == 1,
|
||||||
"More transactions running than should be!");
|
"More transactions running than should be!");
|
||||||
}
|
}
|
||||||
@@ -344,10 +343,6 @@ TransactionThreadPool::TransactionCanRun(IDBTransaction* aTransaction,
|
|||||||
PRUint32 transactionCount = transactionsInProgress.Length();
|
PRUint32 transactionCount = transactionsInProgress.Length();
|
||||||
NS_ASSERTION(transactionCount, "Should never be 0!");
|
NS_ASSERTION(transactionCount, "Should never be 0!");
|
||||||
|
|
||||||
if (mode == IDBTransaction::VERSION_CHANGE) {
|
|
||||||
dbTransactionInfo->lockPending = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PRUint32 index = 0; index < transactionCount; index++) {
|
for (PRUint32 index = 0; index < transactionCount; index++) {
|
||||||
// See if this transaction is in out list of current transactions.
|
// See if this transaction is in out list of current transactions.
|
||||||
const TransactionInfo& info = transactionsInProgress[index];
|
const TransactionInfo& info = transactionsInProgress[index];
|
||||||
@@ -358,11 +353,7 @@ TransactionThreadPool::TransactionCanRun(IDBTransaction* aTransaction,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbTransactionInfo->locked || dbTransactionInfo->lockPending) {
|
NS_ASSERTION(mode != IDBTransaction::VERSION_CHANGE, "How did we get here?");
|
||||||
*aCanRun = false;
|
|
||||||
*aExistingQueue = nsnull;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool writeOverlap;
|
bool writeOverlap;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
@@ -448,11 +439,6 @@ TransactionThreadPool::Dispatch(IDBTransaction* aTransaction,
|
|||||||
dbTransactionInfo = autoDBTransactionInfo;
|
dbTransactionInfo = autoDBTransactionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) {
|
|
||||||
NS_ASSERTION(!dbTransactionInfo->locked, "Already locked?!");
|
|
||||||
dbTransactionInfo->locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsTArray<nsString>& objectStoreNames = aTransaction->mObjectStoreNames;
|
const nsTArray<nsString>& objectStoreNames = aTransaction->mObjectStoreNames;
|
||||||
|
|
||||||
nsTArray<nsString>& storesInUse =
|
nsTArray<nsString>& storesInUse =
|
||||||
|
|||||||
@@ -123,12 +123,6 @@ protected:
|
|||||||
|
|
||||||
struct DatabaseTransactionInfo
|
struct DatabaseTransactionInfo
|
||||||
{
|
{
|
||||||
DatabaseTransactionInfo()
|
|
||||||
: locked(false), lockPending(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool locked;
|
|
||||||
bool lockPending;
|
|
||||||
nsTArray<TransactionInfo> transactions;
|
nsTArray<TransactionInfo> transactions;
|
||||||
nsTArray<nsString> storesReading;
|
nsTArray<nsString> storesReading;
|
||||||
nsTArray<nsString> storesWriting;
|
nsTArray<nsString> storesWriting;
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ TEST_FILES = \
|
|||||||
test_setVersion.html \
|
test_setVersion.html \
|
||||||
test_setVersion_abort.html \
|
test_setVersion_abort.html \
|
||||||
test_setVersion_events.html \
|
test_setVersion_events.html \
|
||||||
|
test_setVersion_exclusion.html \
|
||||||
test_writer_starvation.html \
|
test_writer_starvation.html \
|
||||||
third_party_iframe1.html \
|
third_party_iframe1.html \
|
||||||
third_party_iframe2.html \
|
third_party_iframe2.html \
|
||||||
|
|||||||
@@ -69,6 +69,9 @@
|
|||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
yield;
|
||||||
|
|
||||||
setTimeout(testFinishedCallback, 0, "ready");
|
setTimeout(testFinishedCallback, 0, "ready");
|
||||||
yield;
|
yield;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
db.onerror = errorEventCounter;
|
db.onerror = errorEventCounter;
|
||||||
db.addEventListener("error", errorEventCounter, true);
|
db.addEventListener("error", errorEventCounter, true);
|
||||||
|
|
||||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
event.target.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
db.createObjectStore("foo", { autoIncrement: true });
|
||||||
yield;
|
yield;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function startDBWork() {
|
|||||||
}
|
}
|
||||||
var store = db.createObjectStore("mystore");
|
var store = db.createObjectStore("mystore");
|
||||||
store.add({ hello: "world" }, 42);
|
store.add({ hello: "world" }, 42);
|
||||||
trans.oncomplete = madeMod;
|
e.target.onsuccess = madeMod;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
|
|
||||||
let key = event.target.result;
|
let key = event.target.result;
|
||||||
ok(key, "Added entry");
|
ok(key, "Added entry");
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|
||||||
|
event = yield;
|
||||||
|
|
||||||
let objectStore = db.transaction("foo").objectStore("foo");
|
let objectStore = db.transaction("foo").objectStore("foo");
|
||||||
let first = objectStore.index("first");
|
let first = objectStore.index("first");
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
let db = request.result;
|
let db = request.result;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
// Make object store, add data.
|
// Make object store, add data.
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "id" });
|
let objectStore = db.createObjectStore("foo", { keyPath: "id" });
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
let db2 = event.target.result;
|
let db2 = event.target.result;
|
||||||
db2.onerror = errorHandler;
|
db2.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
// Create index.
|
// Create index.
|
||||||
event.target.transaction.objectStore("foo").createIndex("foo", "num");
|
event.target.transaction.objectStore("foo").createIndex("foo", "num");
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
|
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
|
||||||
objectStore.createIndex("name", "name", { unique: true });
|
objectStore.createIndex("name", "name", { unique: true });
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
request = objectStore.getAll();
|
request = objectStore.getAll();
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield;
|
yield;
|
||||||
|
yield;
|
||||||
|
|
||||||
request = db.transaction("foo").objectStore("foo").getAll();
|
request = db.transaction("foo").objectStore("foo").getAll();
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -78,7 +79,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event = yield;
|
yield;
|
||||||
ok(true, "1");
|
ok(true, "1");
|
||||||
|
|
||||||
// Now create the indexes.
|
// Now create the indexes.
|
||||||
@@ -88,7 +89,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||||
continueToNextStep();
|
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
ok(true, "2");
|
ok(true, "2");
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -87,7 +88,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||||
continueToNextStep();
|
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
objectStore = db.transaction(objectStoreName)
|
objectStore = db.transaction(objectStoreName)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
for (let objectStoreIndex in objectStoreData) {
|
for (let objectStoreIndex in objectStoreData) {
|
||||||
const objectStoreInfo = objectStoreData[objectStoreIndex];
|
const objectStoreInfo = objectStoreData[objectStoreIndex];
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -97,7 +98,6 @@
|
|||||||
indexData[i].options);
|
indexData[i].options);
|
||||||
}
|
}
|
||||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||||
continueToNextStep();
|
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
objectStore = db.transaction(objectStoreName)
|
objectStore = db.transaction(objectStoreName)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -87,6 +88,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield;
|
yield;
|
||||||
|
yield;
|
||||||
|
|
||||||
objectStore = db.transaction(objectStoreName)
|
objectStore = db.transaction(objectStoreName)
|
||||||
.objectStore(objectStoreName);
|
.objectStore(objectStoreName);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
let index2 = objectStore2.index("bar");
|
let index2 = objectStore2.index("bar");
|
||||||
ok(index1 === index2, "Got same indexes");
|
ok(index1 === index2, "Got same indexes");
|
||||||
|
|
||||||
transaction.oncomplete = continueToNextStep;
|
request.onsuccess = continueToNextStep;
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
transaction = db.transaction("foo");
|
transaction = db.transaction("foo");
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
autoIncrement: true });
|
autoIncrement: true });
|
||||||
let index = objectStore.createIndex("foo", "index");
|
let index = objectStore.createIndex("foo", "index");
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
objectStore = db.transaction("foo", IDBTransaction.READ_WRITE)
|
objectStore = db.transaction("foo", IDBTransaction.READ_WRITE)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -31,7 +32,6 @@
|
|||||||
is(db.objectStoreNames.length, 1, "Bad objectStores list");
|
is(db.objectStoreNames.length, 1, "Bad objectStores list");
|
||||||
is(db.objectStoreNames.item(0), objectStoreName, "Bad name");
|
is(db.objectStoreNames.item(0), objectStoreName, "Bad name");
|
||||||
|
|
||||||
continueToNextStep();
|
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||||
|
|
||||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
event.target.onsuccess = grabEventAndContinueHandler;
|
||||||
for (let i in objectStores) {
|
for (let i in objectStores) {
|
||||||
db.createObjectStore(objectStores[i], { autoIncrement: true });
|
db.createObjectStore(objectStores[i], { autoIncrement: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -29,6 +30,8 @@
|
|||||||
|
|
||||||
db.createObjectStore(osName, { autoIncrement: "true" });
|
db.createObjectStore(osName, { autoIncrement: "true" });
|
||||||
|
|
||||||
|
yield;
|
||||||
|
|
||||||
let key1, key2;
|
let key1, key2;
|
||||||
|
|
||||||
request = db.transaction([osName], READ_WRITE)
|
request = db.transaction([osName], READ_WRITE)
|
||||||
|
|||||||
90
dom/indexedDB/test/test_setVersion_exclusion.html
Normal file
90
dom/indexedDB/test/test_setVersion_exclusion.html
Normal 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>
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo");
|
let objectStore = db.createObjectStore("foo");
|
||||||
objectStore.add({}, 1).onerror = errorHandler;
|
objectStore.add({}, 1).onerror = errorHandler;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -157,6 +158,8 @@
|
|||||||
ok(true, "RemoveIndex threw");
|
ok(true, "RemoveIndex threw");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yield;
|
||||||
|
|
||||||
request = db.transaction("foo", READ_WRITE).objectStore("foo").add({});
|
request = db.transaction("foo", READ_WRITE).objectStore("foo").add({});
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
db.createObjectStore("foo", { autoIncrement: true });
|
||||||
yield;
|
yield;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.onsuccess = continueToNextStep;
|
||||||
db.createObjectStore("foo");
|
db.createObjectStore("foo");
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
let request = mozIndexedDB.open(name, 1, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
@@ -39,7 +40,6 @@
|
|||||||
let key = event.target.result;
|
let key = event.target.result;
|
||||||
ok(key, "Got a key");
|
ok(key, "Got a key");
|
||||||
|
|
||||||
SimpleTest.executeSoon(function() { testGenerator.next(); });
|
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
let continueReading = true;
|
let continueReading = true;
|
||||||
|
|||||||
@@ -6043,7 +6043,17 @@ PresShell::HandleEvent(nsIView *aView,
|
|||||||
// still get sent to the window properly if nothing is focused or if a
|
// still get sent to the window properly if nothing is focused or if a
|
||||||
// frame goes away while it is focused.
|
// frame goes away while it is focused.
|
||||||
if (!eventTarget || !eventTarget->GetPrimaryFrame()) {
|
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) {
|
if (aEvent->message == NS_KEY_DOWN) {
|
||||||
|
|||||||
@@ -346,6 +346,7 @@ _TEST_FILES += \
|
|||||||
test_bug607529.html \
|
test_bug607529.html \
|
||||||
file_bug607529.html \
|
file_bug607529.html \
|
||||||
test_bug644768.html \
|
test_bug644768.html \
|
||||||
|
test_bug696020.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
47
layout/base/tests/test_bug696020.html
Normal file
47
layout/base/tests/test_bug696020.html
Normal 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>
|
||||||
@@ -103,7 +103,10 @@ class TPSTestRunner(object):
|
|||||||
'services.sync.log.appender.console': 'Trace',
|
'services.sync.log.appender.console': 'Trace',
|
||||||
'services.sync.log.appender.debugLog.enabled': True,
|
'services.sync.log.appender.debugLog.enabled': True,
|
||||||
'browser.dom.window.dump.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(
|
syncVerRe = re.compile(
|
||||||
r"Sync version: (?P<syncversion>.*)\n")
|
r"Sync version: (?P<syncversion>.*)\n")
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function test()
|
|||||||
|
|
||||||
function onKey(aEvent)
|
function onKey(aEvent)
|
||||||
{
|
{
|
||||||
if (aEvent.target != root) {
|
if (aEvent.target != root && aEvent.target != root.ownerDocument.body) {
|
||||||
ok(false, "unknown target: " + aEvent.target.tagName);
|
ok(false, "unknown target: " + aEvent.target.tagName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Blair McBride <bmcbride@mozilla.com>
|
* Blair McBride <bmcbride@mozilla.com>
|
||||||
|
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* 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
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@@ -35,11 +36,16 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** 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 url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||||
|
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||||
|
|
||||||
|
|
||||||
/* Page background */
|
/* Page background */
|
||||||
:root {
|
*|*:root {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
background-color: Window;
|
background-color: Window;
|
||||||
@@ -48,8 +54,12 @@
|
|||||||
color: WindowText;
|
color: WindowText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|html {
|
||||||
|
font: message-box;
|
||||||
|
}
|
||||||
|
|
||||||
/* Content */
|
/* Content */
|
||||||
.main-content {
|
*|*.main-content {
|
||||||
/* Needed to allow the radius to clip the inner content, see bug 595656 */
|
/* Needed to allow the radius to clip the inner content, see bug 595656 */
|
||||||
/* Disabled because of bug 623615
|
/* Disabled because of bug 623615
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Blair McBride <bmcbride@mozilla.com>
|
* Blair McBride <bmcbride@mozilla.com>
|
||||||
|
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* 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
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@@ -37,11 +38,15 @@
|
|||||||
|
|
||||||
%include shared.inc
|
%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 url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||||
@namespace html url("http://www.w3.org/1999/xhtml");
|
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||||
|
|
||||||
/* Page background */
|
/* Page background */
|
||||||
:root {
|
*|*:root {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
background-image: /* Texture */
|
background-image: /* Texture */
|
||||||
@@ -50,8 +55,12 @@
|
|||||||
-moz-linear-gradient(top, #ADB5C2, #BFC6D1);
|
-moz-linear-gradient(top, #ADB5C2, #BFC6D1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|html {
|
||||||
|
font: message-box;
|
||||||
|
}
|
||||||
|
|
||||||
/* Content */
|
/* Content */
|
||||||
.main-content {
|
*|*.main-content {
|
||||||
/* Needed to allow the radius to clip the inner content, see bug 595656 */
|
/* Needed to allow the radius to clip the inner content, see bug 595656 */
|
||||||
/* Disabled because of bug 623615
|
/* Disabled because of bug 623615
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -62,7 +71,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
button,
|
*|button,
|
||||||
menulist,
|
menulist,
|
||||||
colorpicker[type="button"] {
|
colorpicker[type="button"] {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
@@ -84,6 +93,7 @@ colorpicker[type="button"]:-moz-focusring:not([open="true"]) > .colorpicker-butt
|
|||||||
outline: 1px dotted #252F3B;
|
outline: 1px dotted #252F3B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|button[disabled],
|
||||||
button[disabled="true"],
|
button[disabled="true"],
|
||||||
menulist[disabled="true"],
|
menulist[disabled="true"],
|
||||||
colorpicker[type="button"][disabled="true"] {
|
colorpicker[type="button"][disabled="true"] {
|
||||||
@@ -91,6 +101,7 @@ colorpicker[type="button"][disabled="true"] {
|
|||||||
color: #505050;
|
color: #505050;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|button:not([disabled]):active:hover,
|
||||||
button:not([disabled="true"]):active:hover,
|
button:not([disabled="true"]):active:hover,
|
||||||
menulist[open="true"]:not([disabled="true"]),
|
menulist[open="true"]:not([disabled="true"]),
|
||||||
colorpicker[type="button"][open="true"]:not([disabled="true"]) {
|
colorpicker[type="button"][open="true"]:not([disabled="true"]) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Blair McBride <bmcbride@mozilla.com>
|
* Blair McBride <bmcbride@mozilla.com>
|
||||||
|
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* 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
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@@ -35,10 +36,15 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** 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 url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||||
|
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||||
|
|
||||||
/* Page background */
|
/* Page background */
|
||||||
:root {
|
*|*:root {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
@@ -50,9 +56,13 @@
|
|||||||
url("chrome://global/skin/inContentUI/background-texture.png");
|
url("chrome://global/skin/inContentUI/background-texture.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|html {
|
||||||
|
font: message-box;
|
||||||
|
}
|
||||||
|
|
||||||
%ifdef WINSTRIPE_AERO
|
%ifdef WINSTRIPE_AERO
|
||||||
@media all and (-moz-windows-default-theme) {
|
@media all and (-moz-windows-default-theme) {
|
||||||
:root {
|
*|*:root {
|
||||||
color: #000;
|
color: #000;
|
||||||
background-color: #CCD9EA;
|
background-color: #CCD9EA;
|
||||||
background-image: /* Fade-out texture at the top */
|
background-image: /* Fade-out texture at the top */
|
||||||
@@ -63,7 +73,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media all and (-moz-windows-compositor) {
|
@media all and (-moz-windows-compositor) {
|
||||||
:root {
|
*|*:root {
|
||||||
color: #000;
|
color: #000;
|
||||||
/* Blame shorlander for this monstrosity. */
|
/* Blame shorlander for this monstrosity. */
|
||||||
background-image: /* Fade-out texture and light beams at the top */
|
background-image: /* Fade-out texture and light beams at the top */
|
||||||
@@ -93,7 +103,7 @@
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
/* Content */
|
/* Content */
|
||||||
.main-content {
|
*|*.main-content {
|
||||||
/* Needed to allow the radius to clip the inner content, see bug 595656 */
|
/* Needed to allow the radius to clip the inner content, see bug 595656 */
|
||||||
/* Disabled because of bug 623615
|
/* Disabled because of bug 623615
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -109,7 +119,7 @@
|
|||||||
%ifdef WINSTRIPE_AERO
|
%ifdef WINSTRIPE_AERO
|
||||||
@media all and (-moz-windows-compositor) {
|
@media all and (-moz-windows-compositor) {
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
button,
|
*|button,
|
||||||
menulist,
|
menulist,
|
||||||
colorpicker[type="button"] {
|
colorpicker[type="button"] {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
@@ -133,6 +143,7 @@
|
|||||||
outline: 1px dotted ThreeDDarkShadow;
|
outline: 1px dotted ThreeDDarkShadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|button[disabled],
|
||||||
button[disabled="true"],
|
button[disabled="true"],
|
||||||
menulist[disabled="true"],
|
menulist[disabled="true"],
|
||||||
colorpicker[type="button"][disabled="true"] {
|
colorpicker[type="button"][disabled="true"] {
|
||||||
@@ -144,6 +155,7 @@
|
|||||||
color: #505050;
|
color: #505050;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|button:not([disabled]):active:hover,
|
||||||
button:not([disabled="true"]):active:hover,
|
button:not([disabled="true"]):active:hover,
|
||||||
menulist[open="true"]:not([disabled="true"]),
|
menulist[open="true"]:not([disabled="true"]),
|
||||||
colorpicker[type="button"][open="true"]:not([disabled="true"]) {
|
colorpicker[type="button"][open="true"]:not([disabled="true"]) {
|
||||||
|
|||||||
@@ -148,59 +148,6 @@ typedef NTSTATUS (NTAPI *LdrLoadDll_func) (PWCHAR filePath, PULONG flags, PUNICO
|
|||||||
|
|
||||||
static LdrLoadDll_func stub_LdrLoadDll = 0;
|
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
|
static NTSTATUS NTAPI
|
||||||
patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle)
|
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;
|
wchar_t *dll_part;
|
||||||
DllBlockInfo *info;
|
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;
|
int len = moduleFileName->Length / 2;
|
||||||
wchar_t *fname = moduleFileName->Buffer;
|
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
|
// 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.
|
// 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,
|
// 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
|
#endif
|
||||||
|
|
||||||
if (info->maxVersion != ALL_VERSIONS) {
|
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 zero;
|
||||||
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
|
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
|
||||||
|
|
||||||
@@ -334,6 +281,8 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
|
|||||||
load_ok = true;
|
load_ok = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(full_fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!load_ok) {
|
if (!load_ok) {
|
||||||
@@ -349,8 +298,6 @@ continue_loading:
|
|||||||
|
|
||||||
NS_SetHasLoadedNewDLLs();
|
NS_SetHasLoadedNewDLLs();
|
||||||
|
|
||||||
ForceASLR(full_fname);
|
|
||||||
|
|
||||||
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
|
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user