MozReview-Commit-ID: 6JFx7MHUHgW
This commit is contained in:
Kartikaya Gupta 2017-03-15 08:55:17 -04:00
Родитель 8f6c141289 f807b332df
Коммит 5041aa0404
616 изменённых файлов: 9658 добавлений и 5615 удалений

Просмотреть файл

@ -61,7 +61,9 @@ browser/base/content/test/general/file_csp_block_all_mixedcontent.html
browser/base/content/test/urlbar/file_blank_but_not_blank.html
browser/base/content/newtab/**
browser/components/downloads/**
browser/components/sessionstore/**
# Test files that are really json not js, and don't need to be linted.
browser/components/sessionstore/test/unit/data/sessionstore_valid.js
browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
browser/components/tabview/**
# generated & special files in cld2
browser/components/translation/cld2/**

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1345336 - Crash in icu_58::TimeZoneFormat::initGMTOffsetPatterns
Bug 1346967 - Generate metadata for all three ISimpleDOM interfaces via a single combined run of MIDL

Просмотреть файл

@ -2,4 +2,4 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
1 typelib ISimpleDOMNode.tlb
1 typelib ISimpleDOM.tlb

Просмотреть файл

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// We use #include instead of import here so that MIDL treats these files as
// part of the current file, thus forcing MIDL to generate proxy info for them.
#include "ISimpleDOMNode.idl"
#include "ISimpleDOMDocument.idl"
#include "ISimpleDOMText.idl"
[
uuid(a6245497-9c0b-4449-85a5-bd6ad07df8ea),
helpstring("ISimpleDOM Type Library")
]
library ISimpleDOM
{
interface ISimpleDOMNode;
interface ISimpleDOMText;
interface ISimpleDOMDocument;
};

Просмотреть файл

@ -99,9 +99,6 @@ cpp_quote("")
import "objidl.idl";
import "oaidl.idl";
import "ISimpleDOMText.idl";
import "ISimpleDOMDocument.idl";
[object, uuid(1814ceeb-49e2-407f-af99-fa755a7d2607)]
interface ISimpleDOMNode : IUnknown
{
@ -174,15 +171,3 @@ interface ISimpleDOMNode : IUnknown
[propget] HRESULT language([out, retval] BSTR *language);
}
[
uuid(a6245497-9c0b-4449-85a5-bd6ad07df8ea),
helpstring("ISimpleDOM Type Library")
]
library ISimpleDOM
{
interface ISimpleDOMNode;
interface ISimpleDOMText;
interface ISimpleDOMDocument;
};

Просмотреть файл

@ -6,27 +6,20 @@ GARBAGE += $(MIDL_GENERATED_FILES) done_gen
MIDL_GENERATED_FILES = \
dlldata.c \
ISimpleDOMNode.h \
ISimpleDOMNode_p.c \
ISimpleDOMNode_i.c \
ISimpleDOMNode.tlb \
ISimpleDOMDocument.h \
ISimpleDOMDocument_p.c \
ISimpleDOMDocument_i.c \
ISimpleDOMText.h \
ISimpleDOMText_p.c \
ISimpleDOMText_i.c \
ISimpleDOM.h \
ISimpleDOM_i.c \
ISimpleDOM_p.c \
ISimpleDOM.tlb \
$(NULL)
$(MIDL_GENERATED_FILES): done_gen
done_gen: ISimpleDOMNode.idl \
done_gen: ISimpleDOM.idl \
ISimpleDOMNode.idl \
ISimpleDOMDocument.idl \
ISimpleDOMText.idl
$(MIDL) $(MIDL_FLAGS) -I $(srcdir) -Oicf $(srcdir)/ISimpleDOMNode.idl
$(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/ISimpleDOMDocument.idl
$(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/ISimpleDOMText.idl
$(MIDL) $(MIDL_FLAGS) -I $(srcdir) -robust -Oicf $(srcdir)/ISimpleDOM.idl
touch $@
export:: done_gen
@ -38,12 +31,8 @@ register::
EMBED_MANIFEST_AT = 2
midl_exports := \
ISimpleDOMDocument.h \
ISimpleDOMDocument_i.c \
ISimpleDOMNode.h \
ISimpleDOMNode_i.c \
ISimpleDOMText.h \
ISimpleDOMText_i.c \
ISimpleDOM.h \
ISimpleDOM_i.c \
$(NULL)
INSTALL_TARGETS += midl_exports

Просмотреть файл

@ -8,15 +8,14 @@ GeckoSharedLibrary('AccessibleMarshal', linkage=None)
SOURCES += [
'!dlldata.c',
'!ISimpleDOMDocument_i.c',
'!ISimpleDOMDocument_p.c',
'!ISimpleDOMNode_i.c',
'!ISimpleDOMNode_p.c',
'!ISimpleDOMText_i.c',
'!ISimpleDOMText_p.c',
'!ISimpleDOM_i.c',
'!ISimpleDOM_p.c',
]
DEFINES['REGISTER_PROXY_DLL'] = True
# The following line is required to preserve compatibility with older versions
# of AccessibleMarshal.dll.
DEFINES['PROXY_CLSID'] = 'IID_ISimpleDOMNode'
DEFFILE = SRCDIR + '/AccessibleMarshal.def'
@ -28,16 +27,10 @@ OS_LIBS += [
GENERATED_FILES += [
'dlldata.c',
'ISimpleDOMDocument.h',
'ISimpleDOMDocument_i.c',
'ISimpleDOMDocument_p.c',
'ISimpleDOMNode.h',
'ISimpleDOMNode.tlb',
'ISimpleDOMNode_i.c',
'ISimpleDOMNode_p.c',
'ISimpleDOMText.h',
'ISimpleDOMText_i.c',
'ISimpleDOMText_p.c',
'ISimpleDOM.h',
'ISimpleDOM.tlb',
'ISimpleDOM_i.c',
'ISimpleDOM_p.c',
]
RCINCLUDE = 'AccessibleMarshal.rc'

Просмотреть файл

@ -16,7 +16,7 @@
#include "mozilla/Preferences.h"
#include "nsIDocShell.h"
#include "ISimpleDOMNode_i.c"
#include "ISimpleDOM.h"
namespace mozilla {
namespace a11y {

Просмотреть файл

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "sdnAccessible-inl.h"
#include "ISimpleDOMNode_i.c"
#include "ISimpleDOM_i.c"
#include "DocAccessibleWrap.h"

Просмотреть файл

@ -7,7 +7,7 @@
#ifndef mozilla_a11y_sdnAccessible_h_
#define mozilla_a11y_sdnAccessible_h_
#include "ISimpleDOMNode.h"
#include "ISimpleDOM.h"
#include "AccessibleWrap.h"
#include "IUnknownImpl.h"

Просмотреть файл

@ -6,7 +6,7 @@
#include "sdnDocAccessible.h"
#include "ISimpleDOMDocument_i.c"
#include "ISimpleDOM.h"
#include "nsNameSpaceManager.h"

Просмотреть файл

@ -7,7 +7,7 @@
#ifndef mozilla_a11y_sdnDocAccessible_h_
#define mozilla_a11y_sdnDocAccessible_h_
#include "ISimpleDOMDocument.h"
#include "ISimpleDOM.h"
#include "IUnknownImpl.h"
#include "DocAccessibleWrap.h"

Просмотреть файл

@ -6,7 +6,7 @@
#include "sdnTextAccessible.h"
#include "ISimpleDOMText_i.c"
#include "ISimpleDOM.h"
#include "nsCoreUtils.h"
#include "DocAccessible.h"

Просмотреть файл

@ -7,7 +7,7 @@
#ifndef mozilla_a11y_sdnTextAccessible_h_
#define mozilla_a11y_sdnTextAccessible_h_
#include "ISimpleDOMText.h"
#include "ISimpleDOM.h"
#include "IUnknownImpl.h"
#include "AccessibleWrap.h"

Просмотреть файл

@ -4,16 +4,6 @@
'use strict'
const { Cc, Ci, Cu } = require('chrome');
const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1'].
getService(Ci.nsINavBookmarksService);
const hsrv = Cc['@mozilla.org/browser/nav-history-service;1'].
getService(Ci.nsINavHistoryService);
const brsrv = Cc["@mozilla.org/browser/nav-history-service;1"]
.getService(Ci.nsIBrowserHistory);
const tagsrv = Cc['@mozilla.org/browser/tagging-service;1'].
getService(Ci.nsITaggingService);
const asyncHistory = Cc['@mozilla.org/browser/history;1'].
getService(Ci.mozIAsyncHistory);
const { send } = require('sdk/addon/events');
const { setTimeout } = require('sdk/timers');
const { newURI } = require('sdk/url/utils');
@ -41,7 +31,7 @@ exports.invalidResolve = invalidResolve;
// Removes all children of group
function clearBookmarks (group) {
group
? bmsrv.removeFolderChildren(group.id)
? PlacesUtils.bookmarks.removeFolderChildren(group.id)
: clearAllBookmarks();
}
@ -65,12 +55,15 @@ exports.resetPlaces = resetPlaces;
function compareWithHost (assert, item) {
let id = item.id;
let type = item.type === 'group' ? bmsrv.TYPE_FOLDER : bmsrv['TYPE_' + item.type.toUpperCase()];
let type = item.type === 'group' ?
PlacesUtils.bookmarks.TYPE_FOLDER :
PlacesUtils.bookmarks['TYPE_' + item.type.toUpperCase()];
let url = item.url && !item.url.endsWith('/') ? item.url + '/' : item.url;
if (type === bmsrv.TYPE_BOOKMARK) {
assert.equal(url, bmsrv.getBookmarkURI(id).spec.toString(), 'Matches host url');
let tags = tagsrv.getTagsForURI(newURI(item.url));
if (type === PlacesUtils.bookmarks.TYPE_BOOKMARK) {
assert.equal(url, PlacesUtils.bookmarks.getBookmarkURI(id).spec.toString(),
'Matches host url');
let tags = PlacesUtils.tagging.getTagsForURI(newURI(item.url));
for (let tag of tags) {
// Handle both array for raw data and set for instances
if (Array.isArray(item.tags))
@ -82,45 +75,45 @@ function compareWithHost (assert, item) {
Array.isArray(item.tags) ? item.tags.length : item.tags.size,
'matches tag count');
}
if (type !== bmsrv.TYPE_SEPARATOR) {
assert.equal(item.title, bmsrv.getItemTitle(id), 'Matches host title');
if (type !== PlacesUtils.bookmarks.TYPE_SEPARATOR) {
assert.equal(item.title, PlacesUtils.bookmarks.getItemTitle(id),
'Matches host title');
}
assert.equal(item.index, bmsrv.getItemIndex(id), 'Matches host index');
assert.equal(item.group.id || item.group, bmsrv.getFolderIdForItem(id), 'Matches host group id');
assert.equal(type, bmsrv.getItemType(id), 'Matches host type');
assert.equal(item.index, PlacesUtils.bookmarks.getItemIndex(id),
'Matches host index');
assert.equal(item.group.id || item.group,
PlacesUtils.bookmarks.getFolderIdForItem(id),
'Matches host group id');
assert.equal(type, PlacesUtils.bookmarks.getItemType(id),
'Matches host type');
}
exports.compareWithHost = compareWithHost;
/**
* Adds visits to places.
*
* @param {Array|String} urls Either an array of urls to add, or a single url
* as a string.
*/
function addVisits (urls) {
var deferred = defer();
asyncHistory.updatePlaces([].concat(urls).map(createVisit), {
handleResult: function () {},
handleError: deferred.reject,
handleCompletion: deferred.resolve
});
return deferred.promise;
return PlacesUtils.history.insertMany([].concat(urls).map(createVisit));
}
exports.addVisits = addVisits;
function removeVisits (urls) {
[].concat(urls).map(url => {
hsrv.removePage(newURI(url));
});
PlacesUtils.history.remove(urls);
}
exports.removeVisits = removeVisits;
// Creates a mozIVisitInfo object
function createVisit (url) {
let place = {}
place.uri = newURI(url);
place.title = "Test visit for " + place.uri.spec;
place.visits = [{
transitionType: hsrv.TRANSITION_LINK,
visitDate: +(new Date()) * 1000,
referredURI: undefined
}];
return place;
return {
url,
title: "Test visit for " + url,
visits: [{
transition: PlacesUtils.history.TRANSITION_LINK
}]
};
}
function createBookmark (data) {
@ -141,7 +134,7 @@ function createBookmark (data) {
exports.createBookmark = createBookmark;
function historyBatch () {
hsrv.runInBatchMode(() => {}, null);
PlacesUtils.history.runInBatchMode(() => {}, null);
}
exports.historyBatch = historyBatch;

Просмотреть файл

@ -36,9 +36,9 @@ exports.testEmptyQuery = function*(assert) {
'matches url');
assert.equal(results[1].url, 'http://simplequery-2.com/',
'matches url');
assert.equal(results[0].title, 'Test visit for ' + results[0].url,
assert.equal(results[0].title, 'Test visit for ' + 'http://simplequery-1.com',
'title matches');
assert.equal(results[1].title, 'Test visit for ' + results[1].url,
assert.equal(results[1].title, 'Test visit for ' + 'http://simplequery-2.com',
'title matches');
assert.equal(results[0].visitCount, 1, 'matches access');
assert.equal(results[1].visitCount, 1, 'matches access');

Просмотреть файл

@ -155,9 +155,13 @@ XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function() {
try {
// Hide all notifications while the URL is being edited and the address bar
// has focus, including the virtual focus in the results popup.
// We also have to hide notifications explicitly when the window is
// minimized because of the effects of the "noautohide" attribute on Linux.
// This can be removed once bug 545265 and bug 1320361 are fixed.
let shouldSuppress = () => {
return gURLBar.getAttribute("pageproxystate") != "valid" &&
gURLBar.focused;
return window.windowState == window.STATE_MINIMIZED ||
(gURLBar.getAttribute("pageproxystate") != "valid" &&
gURLBar.focused);
};
return new tmp.PopupNotifications(gBrowser,
document.getElementById("notification-popup"),
@ -1500,6 +1504,15 @@ var gBrowserInit = {
gExtensionsNotifications.init();
let wasMinimized = window.windowState == window.STATE_MINIMIZED;
window.addEventListener("sizemodechange", () => {
let isMinimized = window.windowState == window.STATE_MINIMIZED;
if (wasMinimized != isMinimized) {
wasMinimized = isMinimized;
UpdatePopupNotificationsVisibility();
}
});
window.addEventListener("mousemove", MousePosTracker);
window.addEventListener("dragover", MousePosTracker);

Просмотреть файл

@ -6665,6 +6665,10 @@
// Set the cursor to an arrow during tab drags.
dt.mozCursor = "default";
// Set the tab as the source of the drag, which ensures we have a stable
// node to deliver the `dragend` event. See bug 1345473.
dt.addElement(tab);
// Create a canvas to which we capture the current tab.
// Until canvas is HiDPI-aware (bug 780362), we need to scale the desired
// canvas size (in CSS pixels) to the window's backing resolution in order

Просмотреть файл

@ -10,7 +10,7 @@ skip-if = (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_anim.js]
[browser_devices_get_user_media_in_frame.js]
[browser_devices_get_user_media_screen.js]
skip-if = (e10s && debug) || (os == "linux" && !debug) # bug 1320754 for e10s debug, and bug 1320994 for linux opt
skip-if = (e10s && debug) || (os == "linux") || (os == "win" && !debug) # bug 1320754 for e10s debug, and bug 1320994 for linux opt, bug 1338038 for windows and linux debug
[browser_devices_get_user_media_tear_off_tab.js]
[browser_devices_get_user_media_unprompted_access.js]
[browser_devices_get_user_media_unprompted_access_in_frame.js]

Просмотреть файл

@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPreferencesManager",
"resource://gre/modules/ExtensionPreferencesManager.jsm");
/* eslint-disable mozilla/balanced-listeners */
extensions.on("manifest_chrome_settings_overrides", (type, directive, extension, manifest) => {
if (manifest.chrome_settings_overrides.homepage) {
ExtensionPreferencesManager.setSetting(extension, "homepage_override",
manifest.chrome_settings_overrides.homepage);
}
});
/* eslint-enable mozilla/balanced-listeners */
ExtensionPreferencesManager.addSetting("homepage_override", {
prefNames: [
"browser.startup.homepage",
],
setCallback(value) {
return {
"browser.startup.homepage": value,
};
},
});

Просмотреть файл

@ -2,6 +2,7 @@
category webextension-scripts bookmarks chrome://browser/content/ext-bookmarks.js
category webextension-scripts browserAction chrome://browser/content/ext-browserAction.js
category webextension-scripts browsingData chrome://browser/content/ext-browsingData.js
category webextension-scripts chrome-settings-overrides chrome://browser/content/ext-chrome-settings-overrides.js
category webextension-scripts commands chrome://browser/content/ext-commands.js
category webextension-scripts contextMenus chrome://browser/content/ext-contextMenus.js
category webextension-scripts desktop-runtime chrome://browser/content/ext-desktop-runtime.js
@ -32,6 +33,7 @@ category webextension-scripts-addon tabs chrome://browser/content/ext-c-tabs.js
category webextension-schemas bookmarks chrome://browser/content/schemas/bookmarks.json
category webextension-schemas browser_action chrome://browser/content/schemas/browser_action.json
category webextension-schemas browsing_data chrome://browser/content/schemas/browsing_data.json
category webextension-schemas chrome_settings_overrides chrome://browser/content/schemas/chrome_settings_overrides.json
category webextension-schemas commands chrome://browser/content/schemas/commands.json
category webextension-schemas context_menus chrome://browser/content/schemas/context_menus.json
category webextension-schemas context_menus_internal chrome://browser/content/schemas/context_menus_internal.json

Просмотреть файл

@ -15,6 +15,7 @@ browser.jar:
content/browser/ext-bookmarks.js
content/browser/ext-browserAction.js
content/browser/ext-browsingData.js
content/browser/ext-chrome-settings-overrides.js
content/browser/ext-commands.js
content/browser/ext-contextMenus.js
content/browser/ext-desktop-runtime.js

Просмотреть файл

@ -0,0 +1,25 @@
[
{
"namespace": "manifest",
"types": [
{
"$extend": "WebExtensionManifest",
"properties": {
"chrome_settings_overrides": {
"type": "object",
"optional": true,
"additionalProperties": { "$ref": "UnrecognizedProperty" },
"properties": {
"homepage": {
"type": "string",
"format": "url",
"optional": true,
"preprocess": "localize"
}
}
}
}
}
]
}
]

Просмотреть файл

@ -6,6 +6,7 @@ browser.jar:
content/browser/schemas/bookmarks.json
content/browser/schemas/browser_action.json
content/browser/schemas/browsing_data.json
content/browser/schemas/chrome_settings_overrides.json
content/browser/schemas/commands.json
content/browser/schemas/context_menus.json
content/browser/schemas/context_menus_internal.json

Просмотреть файл

@ -120,6 +120,7 @@ support-files =
[browser_ext_themes_icons.js]
[browser_ext_topwindowid.js]
[browser_ext_url_overrides_newtab.js]
[browser_ext_url_overrides_home.js]
[browser_ext_webRequest.js]
[browser_ext_webNavigation_frameId0.js]
[browser_ext_webNavigation_getFrames.js]

Просмотреть файл

@ -0,0 +1,184 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
// Named this way so they correspond to the extensions
const HOME_URI_2 = "http://example.com/";
const HOME_URI_3 = "http://example.org/";
const HOME_URI_4 = "http://example.net/";
add_task(function* test_multiple_extensions_overriding_home_page() {
let defaultHomePage = Preferences.get("browser.startup.homepage");
let ext1 = ExtensionTestUtils.loadExtension({
manifest: {"chrome_settings_overrides": {}},
useAddonManager: "temporary",
});
let ext2 = ExtensionTestUtils.loadExtension({
manifest: {"chrome_settings_overrides": {homepage: HOME_URI_2}},
useAddonManager: "temporary",
});
let ext3 = ExtensionTestUtils.loadExtension({
manifest: {"chrome_settings_overrides": {homepage: HOME_URI_3}},
useAddonManager: "temporary",
});
let ext4 = ExtensionTestUtils.loadExtension({
manifest: {"chrome_settings_overrides": {homepage: HOME_URI_4}},
useAddonManager: "temporary",
});
yield ext1.startup();
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
"Home url should be the default");
// Because we are expecting the pref to change when we start or unload, we
// need to wait on a pref change. This is because the pref management is
// async and can happen after the startup/unload is finished.
let prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext2.startup();
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
"Home url should be overridden by the second extension.");
// Because we are unloading an earlier extension, browser.startup.homepage won't change
yield ext1.unload();
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
"Home url should be overridden by the second extension.");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext3.startup();
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
"Home url should be overridden by the third extension.");
// Because we are unloading an earlier extension, browser.startup.homepage won't change
yield ext2.unload();
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
"Home url should be overridden by the third extension.");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext4.startup();
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_4),
"Home url should be overridden by the third extension.");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext4.unload();
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
"Home url should be overridden by the third extension.");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext3.unload();
yield prefPromise;
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
"Home url should be reset to default");
});
const HOME_URI_1 = "http://example.com/";
const USER_URI = "http://example.edu/";
add_task(function* test_extension_setting_home_page_back() {
let defaultHomePage = Preferences.get("browser.startup.homepage");
Preferences.set("browser.startup.homepage", USER_URI);
is(Preferences.get("browser.startup.homepage"), USER_URI,
"Home url should be the user set value");
let ext1 = ExtensionTestUtils.loadExtension({
manifest: {"chrome_settings_overrides": {homepage: HOME_URI_1}},
useAddonManager: "temporary",
});
// Because we are expecting the pref to change when we start or unload, we
// need to wait on a pref change. This is because the pref management is
// async and can happen after the startup/unload is finished.
let prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext1.startup();
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
"Home url should be overridden by the second extension.");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext1.unload();
yield prefPromise;
is(Preferences.get("browser.startup.homepage"), USER_URI,
"Home url should be the user set value");
Preferences.reset("browser.startup.homepage");
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
"Home url should be the default");
});
add_task(function* test_disable() {
let defaultHomePage = Preferences.get("browser.startup.homepage");
const ID = "id@tests.mozilla.org";
let ext1 = ExtensionTestUtils.loadExtension({
manifest: {
applications: {
gecko: {
id: ID,
},
},
"chrome_settings_overrides": {
homepage: HOME_URI_1,
},
},
useAddonManager: "temporary",
});
let prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext1.startup();
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
"Home url should be overridden by the extension.");
let addon = yield AddonManager.getAddonByID(ID);
is(addon.id, ID);
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
addon.userDisabled = true;
yield prefPromise;
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
"Home url should be the default");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
addon.userDisabled = false;
yield prefPromise;
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
"Home url should be overridden by the extension.");
prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext1.unload();
yield prefPromise;
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
"Home url should be the default");
});

Просмотреть файл

@ -16,6 +16,7 @@
* getListStyleImage getPanelForNode
* awaitExtensionPanel awaitPopupResize
* promiseContentDimensions alterContent
* promisePrefChangeObserved
*/
const {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm", {});
@ -348,3 +349,11 @@ function closePageAction(extension, win = window) {
return Promise.resolve();
}
function promisePrefChangeObserved(pref) {
return new Promise((resolve, reject) =>
Preferences.observe(pref, function prefObserver() {
Preferences.ignore(pref, prefObserver);
resolve();
}));
}

Просмотреть файл

@ -33,6 +33,7 @@ tags = trackingprotection
[browser_privatebrowsing_downloadLastDir_toggle.js]
[browser_privatebrowsing_favicon.js]
[browser_privatebrowsing_geoprompt.js]
tags = geolocation
[browser_privatebrowsing_lastpbcontextexited.js]
[browser_privatebrowsing_localStorage.js]
[browser_privatebrowsing_localStorage_before_after.js]

Просмотреть файл

@ -175,7 +175,7 @@ ContentRestoreInternal.prototype = {
* Start loading the current page. When the data has finished loading from the
* network, finishCallback is called. Returns true if the load was successful.
*/
restoreTabContent: function (loadArguments, isRemotenessUpdate, finishCallback) {
restoreTabContent(loadArguments, isRemotenessUpdate, finishCallback) {
let tabData = this._tabData;
this._tabData = null;
@ -199,7 +199,7 @@ ContentRestoreInternal.prototype = {
// same state it was before the load started then trigger the load.
let referrer = loadArguments.referrer ?
Utils.makeURI(loadArguments.referrer) : null;
let referrerPolicy = ('referrerPolicy' in loadArguments
let referrerPolicy = ("referrerPolicy" in loadArguments
? loadArguments.referrerPolicy
: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET);
let postData = loadArguments.postData ?
@ -243,11 +243,14 @@ ContentRestoreInternal.prototype = {
}
return true;
} catch (ex if ex instanceof Ci.nsIException) {
// Ignore page load errors, but return false to signal that the load never
// happened.
return false;
} catch (ex) {
if (ex instanceof Ci.nsIException) {
// Ignore page load errors, but return false to signal that the load never
// happened.
return false;
}
}
return null;
},
/**
@ -281,11 +284,11 @@ ContentRestoreInternal.prototype = {
* position. The restore is complete when this function exits. It should be
* called when the "load" event fires for the restoring tab.
*/
restoreDocument: function () {
restoreDocument() {
if (!this._restoringDocument) {
return;
}
let {entry, pageStyle, formdata, scrollPositions} = this._restoringDocument;
let {pageStyle, formdata, scrollPositions} = this._restoringDocument;
this._restoringDocument = null;
let window = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
@ -305,7 +308,7 @@ ContentRestoreInternal.prototype = {
* case, it's called before restoreDocument, so it cannot clear
* _restoringDocument.
*/
resetRestore: function () {
resetRestore() {
this._tabData = null;
if (this._historyListener) {
@ -338,18 +341,18 @@ HistoryListener.prototype = {
Ci.nsISupportsWeakReference
]),
uninstall: function () {
uninstall() {
let shistory = this.webNavigation.sessionHistory;
if (shistory) {
shistory.removeSHistoryListener(this);
}
},
OnHistoryGoBack: function(backURI) { return true; },
OnHistoryGoForward: function(forwardURI) { return true; },
OnHistoryGotoIndex: function(index, gotoURI) { return true; },
OnHistoryPurge: function(numEntries) { return true; },
OnHistoryReplaceEntry: function(index) {},
OnHistoryGoBack(backURI) { return true; },
OnHistoryGoForward(forwardURI) { return true; },
OnHistoryGotoIndex(index, gotoURI) { return true; },
OnHistoryPurge(numEntries) { return true; },
OnHistoryReplaceEntry(index) {},
// This will be called for a pending tab when loadURI(uri) is called where
// the given |uri| only differs in the fragment.
@ -408,11 +411,11 @@ ProgressListener.prototype = {
Ci.nsISupportsWeakReference
]),
uninstall: function() {
uninstall() {
this.webProgress.removeProgressListener(this);
},
onStateChange: function(webProgress, request, stateFlags, status) {
onStateChange(webProgress, request, stateFlags, status) {
let {STATE_IS_WINDOW, STATE_STOP, STATE_START} = Ci.nsIWebProgressListener;
if (!webProgress.isTopLevel || !(stateFlags & STATE_IS_WINDOW)) {
return;
@ -427,8 +430,8 @@ ProgressListener.prototype = {
}
},
onLocationChange: function() {},
onProgressChange: function() {},
onStatusChange: function() {},
onSecurityChange: function() {},
onLocationChange() {},
onProgressChange() {},
onStatusChange() {},
onSecurityChange() {},
};

Просмотреть файл

@ -10,11 +10,11 @@ this.EXPORTED_SYMBOLS = ["DocShellCapabilities"];
* The external API exported by this module.
*/
this.DocShellCapabilities = Object.freeze({
collect: function (docShell) {
collect(docShell) {
return DocShellCapabilitiesInternal.collect(docShell);
},
restore: function (docShell, disallow) {
restore(docShell, disallow) {
return DocShellCapabilitiesInternal.restore(docShell, disallow);
},
});
@ -29,7 +29,7 @@ var DocShellCapabilitiesInternal = {
// properties.
caps: null,
allCapabilities: function (docShell) {
allCapabilities(docShell) {
if (!this.caps) {
let keys = Object.keys(docShell);
this.caps = keys.filter(k => k.startsWith("allow")).map(k => k.slice(5));
@ -37,12 +37,12 @@ var DocShellCapabilitiesInternal = {
return this.caps;
},
collect: function (docShell) {
collect(docShell) {
let caps = this.allCapabilities(docShell);
return caps.filter(cap => !docShell["allow" + cap]);
},
restore: function (docShell, disallow) {
restore(docShell, disallow) {
let caps = this.allCapabilities(docShell);
for (let cap of caps)
docShell["allow" + cap] = !disallow.has(cap);

Просмотреть файл

@ -80,7 +80,7 @@ FrameTreeInternal.prototype = {
*
* @param obs (object)
*/
addObserver: function (obs) {
addObserver(obs) {
this._observers.add(obs);
},
@ -89,7 +89,7 @@ FrameTreeInternal.prototype = {
*
* @param method (string)
*/
notifyObservers: function (method) {
notifyObservers(method) {
for (let obs of this._observers) {
if (obs.hasOwnProperty(method)) {
obs[method]();
@ -104,7 +104,7 @@ FrameTreeInternal.prototype = {
* @param frame (nsIDOMWindow)
* @return bool
*/
contains: function (frame) {
contains(frame) {
return this._frames.has(frame);
},
@ -124,7 +124,7 @@ FrameTreeInternal.prototype = {
* @param cb (function)
* @return object
*/
map: function (cb) {
map(cb) {
let frames = this._frames;
function walk(frame) {
@ -169,7 +169,7 @@ FrameTreeInternal.prototype = {
* @param cb (function)
* This callback receives the current frame as the only argument.
*/
forEach: function (cb) {
forEach(cb) {
let frames = this._frames;
function walk(frame) {
@ -196,7 +196,7 @@ FrameTreeInternal.prototype = {
* @param index (int)
* The index in the given frame's parent's child list.
*/
collect: function (frame, index = 0) {
collect(frame, index = 0) {
// Mark the given frame as contained in the frame tree.
this._frames.set(frame, index);
@ -211,7 +211,7 @@ FrameTreeInternal.prototype = {
* - new documents that start loading to clear the current frame tree;
* - completed document loads to recollect reachable frames.
*/
onStateChange: function (webProgress, request, stateFlags, status) {
onStateChange(webProgress, request, stateFlags, status) {
// Ignore state changes for subframes because we're only interested in the
// top-document starting or stopping its load. We thus only care about any
// changes to the root of the frame tree, not to any of its nodes/leafs.
@ -244,10 +244,10 @@ FrameTreeInternal.prototype = {
},
// Unused nsIWebProgressListener methods.
onLocationChange: function () {},
onProgressChange: function () {},
onSecurityChange: function () {},
onStatusChange: function () {},
onLocationChange() {},
onProgressChange() {},
onSecurityChange() {},
onStatusChange() {},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])

Просмотреть файл

@ -28,14 +28,14 @@ GlobalStateInternal.prototype = {
/**
* Get all value from the global state.
*/
getState: function() {
getState() {
return this.state;
},
/**
* Clear all currently stored global state.
*/
clear: function() {
clear() {
this.state = {};
},
@ -46,7 +46,7 @@ GlobalStateInternal.prototype = {
* A key the value is stored under.
* @return The value stored at aKey, or an empty string if no value is set.
*/
get: function(aKey) {
get(aKey) {
return this.state[aKey] || "";
},
@ -56,7 +56,7 @@ GlobalStateInternal.prototype = {
* @param aKey
* A key to store the value under.
*/
set: function(aKey, aStringValue) {
set(aKey, aStringValue) {
this.state[aKey] = aStringValue;
},
@ -66,7 +66,7 @@ GlobalStateInternal.prototype = {
* @param aKey
* A key to delete the value for.
*/
delete: function(aKey) {
delete(aKey) {
delete this.state[aKey];
},
@ -78,7 +78,7 @@ GlobalStateInternal.prototype = {
* @param aState
* A state object to extract global state from to be set.
*/
setFromState: function (aState) {
setFromState(aState) {
this.state = (aState && aState.global) || {};
}
};

Просмотреть файл

@ -12,11 +12,11 @@ const Ci = Components.interfaces;
* The external API exported by this module.
*/
this.PageStyle = Object.freeze({
collect: function (docShell, frameTree) {
collect(docShell, frameTree) {
return PageStyleInternal.collect(docShell, frameTree);
},
restoreTree: function (docShell, data) {
restoreTree(docShell, data) {
PageStyleInternal.restoreTree(docShell, data);
}
});
@ -28,7 +28,7 @@ var PageStyleInternal = {
/**
* Collects the selected style sheet sets for all reachable frames.
*/
collect: function (docShell, frameTree) {
collect(docShell, frameTree) {
let result = frameTree.map(({document: doc}) => {
let style;
@ -71,23 +71,23 @@ var PageStyleInternal = {
* ]
* }
*/
restoreTree: function (docShell, data) {
restoreTree(docShell, data) {
let disabled = data.disabled || false;
let markupDocumentViewer =
docShell.contentViewer;
markupDocumentViewer.authorStyleDisabled = disabled;
function restoreFrame(root, data) {
if (data.hasOwnProperty("pageStyle")) {
root.document.selectedStyleSheetSet = data.pageStyle;
function restoreFrame(root, frameData) {
if (frameData.hasOwnProperty("pageStyle")) {
root.document.selectedStyleSheetSet = frameData.pageStyle;
}
if (!data.hasOwnProperty("children")) {
if (!frameData.hasOwnProperty("children")) {
return;
}
let frames = root.frames;
data.children.forEach((child, index) => {
frameData.children.forEach((child, index) => {
if (child && index < frames.length) {
restoreFrame(frames[index], child);
}

Просмотреть файл

@ -26,7 +26,7 @@ this.PrivacyFilter = Object.freeze({
* @param data The session storage data as collected from a tab.
* @return object
*/
filterSessionStorageData: function (data) {
filterSessionStorageData(data) {
let retval = {};
for (let host of Object.keys(data)) {
@ -46,12 +46,12 @@ this.PrivacyFilter = Object.freeze({
* @param data The form data as collected from a tab.
* @return object
*/
filterFormData: function (data) {
filterFormData(data) {
// If the given form data object has an associated URL that we are not
// allowed to store data for, bail out. We explicitly discard data for any
// children as well even if storing data for those frames would be allowed.
if (data.url && !PrivacyLevel.check(data.url)) {
return;
return null;
}
let retval = {};
@ -81,7 +81,7 @@ this.PrivacyFilter = Object.freeze({
* The browser state for which we remove any private windows and tabs.
* The given object will be modified.
*/
filterPrivateWindowsAndTabs: function (browserState) {
filterPrivateWindowsAndTabs(browserState) {
// Remove private opened windows.
for (let i = browserState.windows.length - 1; i >= 0; i--) {
let win = browserState.windows[i];
@ -113,7 +113,7 @@ this.PrivacyFilter = Object.freeze({
* The window state for which we remove any private tabs.
* The given object will be modified.
*/
filterPrivateTabs: function (winState) {
filterPrivateTabs(winState) {
// Remove open private tabs.
for (let i = winState.tabs.length - 1; i >= 0 ; i--) {
let tab = winState.tabs[i];

Просмотреть файл

@ -37,8 +37,8 @@ this.RecentlyClosedTabsAndWindowsMenuUtils = {
* Which localizable string to use for the 'restore all tabs' item.
* @returns A document fragment with UI items for each recently closed tab.
*/
getTabsFragment: function(aWindow, aTagName, aPrefixRestoreAll=false,
aRestoreAllLabel="menuRestoreAllTabs.label") {
getTabsFragment(aWindow, aTagName, aPrefixRestoreAll = false,
aRestoreAllLabel = "menuRestoreAllTabs.label") {
let doc = aWindow.document;
let fragment = doc.createDocumentFragment();
if (SessionStore.getClosedTabCount(aWindow) != 0) {
@ -67,8 +67,8 @@ this.RecentlyClosedTabsAndWindowsMenuUtils = {
* Which localizable string to use for the 'restore all windows' item.
* @returns A document fragment with UI items for each recently closed window.
*/
getWindowsFragment: function(aWindow, aTagName, aPrefixRestoreAll=false,
aRestoreAllLabel="menuRestoreAllWindows.label") {
getWindowsFragment(aWindow, aTagName, aPrefixRestoreAll = false,
aRestoreAllLabel = "menuRestoreAllWindows.label") {
let closedWindowData = SessionStore.getClosedWindowData(false);
let doc = aWindow.document;
let fragment = doc.createDocumentFragment();
@ -104,7 +104,7 @@ this.RecentlyClosedTabsAndWindowsMenuUtils = {
* @param aEvent
* The event when the user clicks the menu item
*/
_undoCloseMiddleClick: function(aEvent) {
_undoCloseMiddleClick(aEvent) {
if (aEvent.button != 1)
return;
@ -172,7 +172,7 @@ function createEntry(aTagName, aIsWindowsFragment, aIndex, aClosedTab,
element.addEventListener("click", RecentlyClosedTabsAndWindowsMenuUtils._undoCloseMiddleClick);
}
if (aIndex == 0) {
element.setAttribute("key", "key_undoClose" + (aIsWindowsFragment? "Window" : "Tab"));
element.setAttribute("key", "key_undoClose" + (aIsWindowsFragment ? "Window" : "Tab"));
}
aFragment.appendChild(element);
@ -204,11 +204,11 @@ function createRestoreAllEntry(aDocument, aFragment, aPrefixRestoreAll,
restoreAllElements.setAttribute("label", navigatorBundle.GetStringFromName(aRestoreAllLabel));
restoreAllElements.setAttribute("oncommand",
"for (var i = 0; i < " + aEntryCount + "; i++) undoClose" +
(aIsWindowsFragment? "Window" : "Tab") + "();");
(aIsWindowsFragment ? "Window" : "Tab") + "();");
if (aPrefixRestoreAll) {
aFragment.insertBefore(restoreAllElements, aFragment.firstChild);
} else {
aFragment.appendChild(aDocument.createElementNS(kNSXUL, "menuseparator"));
aFragment.appendChild(restoreAllElements);
}
}
}

Просмотреть файл

@ -24,11 +24,11 @@ const MAX_EXPIRY = Math.pow(2, 62);
* The external API implemented by the SessionCookies module.
*/
this.SessionCookies = Object.freeze({
update: function (windows) {
update(windows) {
SessionCookiesInternal.update(windows);
},
getHostsForWindow: function (window, checkPrivacy = false) {
getHostsForWindow(window, checkPrivacy = false) {
return SessionCookiesInternal.getHostsForWindow(window, checkPrivacy);
},
@ -55,7 +55,7 @@ var SessionCookiesInternal = {
* Array of window state objects.
* [{ tabs: [...], cookies: [...] }, ...]
*/
update: function (windows) {
update(windows) {
this._ensureInitialized();
for (let window of windows) {
@ -71,7 +71,7 @@ var SessionCookiesInternal = {
// _getCookiesForHost() will only return hosts with the right privacy
// rules, so there is no need to do anything special with this call
// to PrivacyLevel.canSave().
if (PrivacyLevel.canSave({isHttps: cookie.secure, isPinned: isPinned})) {
if (PrivacyLevel.canSave({isHttps: cookie.secure, isPinned})) {
cookies.push(cookie);
}
}
@ -99,7 +99,7 @@ var SessionCookiesInternal = {
* whether we will use the deferred privacy level when
* checking how much data to save on quitting.
*/
getHostsForWindow: function (window, checkPrivacy = false) {
getHostsForWindow(window, checkPrivacy = false) {
let hosts = {};
for (let tab of window.tabs) {
@ -135,7 +135,7 @@ var SessionCookiesInternal = {
* Handles observers notifications that are sent whenever cookies are added,
* changed, or removed. Ensures that the storage is updated accordingly.
*/
observe: function (subject, topic, data) {
observe(subject, topic, data) {
switch (data) {
case "added":
case "changed":
@ -163,7 +163,7 @@ var SessionCookiesInternal = {
* If called for the first time in a session, iterates all cookies in the
* cookies service and puts them into the store if they're session cookies.
*/
_ensureInitialized: function () {
_ensureInitialized() {
if (!this._initialized) {
this._reloadCookies();
this._initialized = true;
@ -185,7 +185,7 @@ var SessionCookiesInternal = {
* is the entry we're evaluating for a pinned tab; used only if
* checkPrivacy
*/
_extractHostsFromEntry: function (entry, hosts, checkPrivacy, isPinned) {
_extractHostsFromEntry(entry, hosts, checkPrivacy, isPinned) {
let host = entry._host;
let scheme = entry._scheme;
@ -199,8 +199,7 @@ var SessionCookiesInternal = {
host = uri.host;
scheme = uri.scheme;
this._extractHostsFromHostScheme(host, scheme, hosts, checkPrivacy, isPinned);
}
catch (ex) { }
} catch (ex) { }
}
if (entry.children) {
@ -226,13 +225,12 @@ var SessionCookiesInternal = {
* is the entry we're evaluating for a pinned tab; used only if
* checkPrivacy
*/
_extractHostsFromHostScheme:
function (host, scheme, hosts, checkPrivacy, isPinned) {
_extractHostsFromHostScheme(host, scheme, hosts, checkPrivacy, isPinned) {
// host and scheme may not be set (for about: urls for example), in which
// case testing scheme will be sufficient.
if (/https?/.test(scheme) && !hosts[host] &&
(!checkPrivacy ||
PrivacyLevel.canSave({isHttps: scheme == "https", isPinned: isPinned}))) {
PrivacyLevel.canSave({isHttps: scheme == "https", isPinned}))) {
// By setting this to true or false, we can determine when looking at
// the host in update() if we should check for privacy.
hosts[host] = isPinned;
@ -244,7 +242,7 @@ var SessionCookiesInternal = {
/**
* Updates or adds a given cookie to the store.
*/
_updateCookie: function (cookie) {
_updateCookie(cookie) {
cookie.QueryInterface(Ci.nsICookie2);
if (cookie.isSession) {
@ -257,7 +255,7 @@ var SessionCookiesInternal = {
/**
* Removes a given cookie from the store.
*/
_removeCookie: function (cookie) {
_removeCookie(cookie) {
cookie.QueryInterface(Ci.nsICookie2);
if (cookie.isSession) {
@ -268,7 +266,7 @@ var SessionCookiesInternal = {
/**
* Removes a given list of cookies from the store.
*/
_removeCookies: function (cookies) {
_removeCookies(cookies) {
for (let i = 0; i < cookies.length; i++) {
this._removeCookie(cookies.queryElementAt(i, Ci.nsICookie2));
}
@ -278,7 +276,7 @@ var SessionCookiesInternal = {
* Iterates all cookies in the cookies service and puts them into the store
* if they're session cookies.
*/
_reloadCookies: function () {
_reloadCookies() {
let iter = Services.cookies.enumerator;
while (iter.hasMoreElements()) {
this._updateCookie(iter.getNext());
@ -358,10 +356,10 @@ var CookieStore = {
/**
* Returns the list of stored session cookies for a given host.
*
* @param host
* @param mainHost
* A string containing the host name we want to get cookies for.
*/
getCookiesForHost: function (host) {
getCookiesForHost(mainHost) {
let cookies = [];
let appendCookiesForHost = host => {
@ -383,7 +381,7 @@ var CookieStore = {
// <.example.com>. We will find those variants with a leading dot in the
// map if the Set-Cookie header had a domain= attribute, i.e. the cookie
// will be stored for a parent domain and we send it for any subdomain.
for (let variant of [host, ...getPossibleSubdomainVariants(host)]) {
for (let variant of [mainHost, ...getPossibleSubdomainVariants(mainHost)]) {
appendCookiesForHost(variant);
}
@ -396,7 +394,7 @@ var CookieStore = {
* @param cookie
* The nsICookie2 object to add to the storage.
*/
set: function (cookie) {
set(cookie) {
let jscookie = {host: cookie.host, value: cookie.value};
// Only add properties with non-default values to save a few bytes.
@ -433,14 +431,14 @@ var CookieStore = {
* @param cookie
* The nsICookie2 object to be removed from storage.
*/
delete: function (cookie) {
delete(cookie) {
this._ensureMap(cookie).delete(cookie.name);
},
/**
* Removes all cookies.
*/
clear: function () {
clear() {
this._hosts.clear();
},
@ -453,7 +451,7 @@ var CookieStore = {
* @return The newly created Map instance mapping cookie names to
* internal jscookies, in the given path of the given host.
*/
_ensureMap: function (cookie) {
_ensureMap(cookie) {
if (!this._hosts.has(cookie.host)) {
this._hosts.set(cookie.host, new Map());
}

Просмотреть файл

@ -66,19 +66,19 @@ this.SessionFile = {
/**
* Read the contents of the session file, asynchronously.
*/
read: function () {
read() {
return SessionFileInternal.read();
},
/**
* Write the contents of the session file, asynchronously.
*/
write: function (aData) {
write(aData) {
return SessionFileInternal.write(aData);
},
/**
* Wipe the contents of the session file, asynchronously.
*/
wipe: function () {
wipe() {
return SessionFileInternal.wipe();
},
@ -226,32 +226,34 @@ var SessionFileInternal = {
let source = yield OS.File.read(path, { encoding: "utf-8" });
let parsed = JSON.parse(source);
if (!SessionStore.isFormatVersionCompatible(parsed.version || ["sessionrestore", 0] /*fallback for old versions*/)) {
if (!SessionStore.isFormatVersionCompatible(parsed.version || ["sessionrestore", 0] /* fallback for old versions*/)) {
// Skip sessionstore files that we don't understand.
Cu.reportError("Cannot extract data from Session Restore file " + path + ". Wrong format/version: " + JSON.stringify(parsed.version) + ".");
continue;
}
result = {
origin: key,
source: source,
parsed: parsed
source,
parsed
};
Telemetry.getHistogramById("FX_SESSION_RESTORE_CORRUPT_FILE").
add(false);
Telemetry.getHistogramById("FX_SESSION_RESTORE_READ_FILE_MS").
add(Date.now() - startMs);
break;
} catch (ex if ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
exists = false;
} catch (ex if ex instanceof OS.File.Error) {
// The file might be inaccessible due to wrong permissions
// or similar failures. We'll just count it as "corrupted".
console.error("Could not read session file ", ex, ex.stack);
corrupted = true;
} catch (ex if ex instanceof SyntaxError) {
console.error("Corrupt session file (invalid JSON found) ", ex, ex.stack);
// File is corrupted, try next file
corrupted = true;
} catch (ex) {
if (ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
exists = false;
} else if (ex instanceof OS.File.Error) {
// The file might be inaccessible due to wrong permissions
// or similar failures. We'll just count it as "corrupted".
console.error("Could not read session file ", ex, ex.stack);
corrupted = true;
} else if (ex instanceof SyntaxError) {
console.error("Corrupt session file (invalid JSON found) ", ex, ex.stack);
// File is corrupted, try next file
corrupted = true;
}
} finally {
if (exists) {
noFilesFound = false;
@ -310,7 +312,7 @@ var SessionFileInternal = {
return SessionWorker.post(...args)
}),
write: function (aData) {
write(aData) {
if (RunState.isClosed) {
return Promise.reject(new Error("SessionFile is closed"));
}
@ -377,12 +379,12 @@ var SessionFileInternal = {
});
},
wipe: function () {
wipe() {
return this._postToWorker("wipe");
},
_recordTelemetry: function(telemetry) {
for (let id of Object.keys(telemetry)){
_recordTelemetry(telemetry) {
for (let id of Object.keys(telemetry)) {
let value = telemetry[id];
let samples = [];
if (Array.isArray(value)) {

Просмотреть файл

@ -15,12 +15,12 @@ XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource://gre/modules/sessionstore/Utils.jsm");
// An encoder to UTF-8.
XPCOMUtils.defineLazyGetter(this, "gEncoder", function () {
XPCOMUtils.defineLazyGetter(this, "gEncoder", function() {
return new TextEncoder();
});
// A decoder.
XPCOMUtils.defineLazyGetter(this, "gDecoder", function () {
XPCOMUtils.defineLazyGetter(this, "gDecoder", function() {
return new TextDecoder();
});
@ -39,7 +39,7 @@ var SessionMigrationInternal = {
* The complete state is then wrapped into the "about:welcomeback" page as
* form field info to be restored when restoring the state.
*/
convertState: function(aStateObj) {
convertState(aStateObj) {
let state = {
selectedWindow: aStateObj.selectedWindow,
_closedWindows: []
@ -71,7 +71,7 @@ var SessionMigrationInternal = {
/**
* Asynchronously read session restore state (JSON) from a path
*/
readState: function(aPath) {
readState(aPath) {
return Task.spawn(function*() {
let bytes = yield OS.File.read(aPath);
let text = gDecoder.decode(bytes);
@ -82,7 +82,7 @@ var SessionMigrationInternal = {
/**
* Asynchronously write session restore state as JSON to a path
*/
writeState: function(aPath, aState) {
writeState(aPath, aState) {
let bytes = gEncoder.encode(JSON.stringify(aState));
return OS.File.writeAtomic(aPath, bytes, {tmpPath: aPath + ".tmp"});
}
@ -92,7 +92,7 @@ var SessionMigration = {
/**
* Migrate a limited set of session data from one path to another.
*/
migrate: function(aFromPath, aToPath) {
migrate(aFromPath, aToPath) {
return Task.spawn(function*() {
let inState = yield SessionMigrationInternal.readState(aFromPath);
let outState = SessionMigrationInternal.convertState(inState);

Просмотреть файл

@ -31,7 +31,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
// Minimal interval between two save operations (in milliseconds).
XPCOMUtils.defineLazyGetter(this, "gInterval", function () {
XPCOMUtils.defineLazyGetter(this, "gInterval", function() {
const PREF = "browser.sessionstore.interval";
// Observer that updates the cached value when the preference changes.
@ -54,7 +54,7 @@ function notify(subject, topic) {
// TelemetryStopwatch helper functions.
function stopWatch(method) {
return function (...histograms) {
return function(...histograms) {
for (let hist of histograms) {
TelemetryStopwatch[method]("FX_SESSION_RESTORE_" + hist);
}
@ -72,7 +72,7 @@ this.SessionSaver = Object.freeze({
/**
* Immediately saves the current session to disk.
*/
run: function () {
run() {
return SessionSaverInternal.run();
},
@ -81,7 +81,7 @@ this.SessionSaver = Object.freeze({
* another delayed run be scheduled already, we will ignore the given delay
* and state saving may occur a little earlier.
*/
runDelayed: function () {
runDelayed() {
SessionSaverInternal.runDelayed();
},
@ -89,14 +89,14 @@ this.SessionSaver = Object.freeze({
* Sets the last save time to the current time. This will cause us to wait for
* at least the configured interval when runDelayed() is called next.
*/
updateLastSaveTime: function () {
updateLastSaveTime() {
SessionSaverInternal.updateLastSaveTime();
},
/**
* Cancels all pending session saves.
*/
cancel: function () {
cancel() {
SessionSaverInternal.cancel();
}
});
@ -121,7 +121,7 @@ var SessionSaverInternal = {
/**
* Immediately saves the current session to disk.
*/
run: function () {
run() {
return this._saveState(true /* force-update all windows */);
},
@ -134,7 +134,7 @@ var SessionSaverInternal = {
* The minimum delay in milliseconds to wait for until we collect and
* save the current session.
*/
runDelayed: function (delay = 2000) {
runDelayed(delay = 2000) {
// Bail out if there's a pending run.
if (this._timeoutID) {
return;
@ -151,14 +151,14 @@ var SessionSaverInternal = {
* Sets the last save time to the current time. This will cause us to wait for
* at least the configured interval when runDelayed() is called next.
*/
updateLastSaveTime: function () {
updateLastSaveTime() {
this._lastSaveTime = Date.now();
},
/**
* Cancels all pending session saves.
*/
cancel: function () {
cancel() {
clearTimeout(this._timeoutID);
this._timeoutID = null;
},
@ -170,7 +170,7 @@ var SessionSaverInternal = {
* Forces us to recollect data for all windows and will bypass and
* update the corresponding caches.
*/
_saveState: function (forceUpdateAllWindows = false) {
_saveState(forceUpdateAllWindows = false) {
// Cancel any pending timeouts.
this.cancel();
@ -241,7 +241,7 @@ var SessionSaverInternal = {
* _saveState() to collect data again (with a cache hit rate of hopefully
* 100%) and write to disk afterwards.
*/
_saveStateAsync: function () {
_saveStateAsync() {
// Allow scheduling delayed saves again.
this._timeoutID = null;
@ -252,7 +252,7 @@ var SessionSaverInternal = {
/**
* Write the given state object to disk.
*/
_writeState: function (state) {
_writeState(state) {
// We update the time stamp before writing so that we don't write again
// too soon, if saving is requested before the write completes. Without
// this update we may save repeatedly if actions cause a runDelayed

Просмотреть файл

@ -33,7 +33,7 @@ this.SessionStorage = Object.freeze({
* session storage data as strings. For example:
* {"example.com": {"key": "value", "my_number": "123"}}
*/
collect: function (docShell, frameTree) {
collect(docShell, frameTree) {
return SessionStorageInternal.collect(docShell, frameTree);
},
@ -46,7 +46,7 @@ this.SessionStorage = Object.freeze({
* keys and per-host session storage data as strings. For example:
* {"example.com": {"key": "value", "my_number": "123"}}
*/
restore: function (aDocShell, aStorageData) {
restore(aDocShell, aStorageData) {
SessionStorageInternal.restore(aDocShell, aStorageData);
},
});
@ -62,7 +62,7 @@ var SessionStorageInternal = {
* session storage data as strings. For example:
* {"example.com": {"key": "value", "my_number": "123"}}
*/
collect: function (docShell, frameTree) {
collect(docShell, frameTree) {
let data = {};
let visitedOrigins = new Set();
@ -108,7 +108,7 @@ var SessionStorageInternal = {
* keys and per-host session storage data as strings. For example:
* {"example.com": {"key": "value", "my_number": "123"}}
*/
restore: function (aDocShell, aStorageData) {
restore(aDocShell, aStorageData) {
for (let origin of Object.keys(aStorageData)) {
let data = aStorageData[origin];
@ -149,7 +149,7 @@ var SessionStorageInternal = {
* @param aDocShell
* A tab's docshell (containing the sessionStorage)
*/
_readEntry: function (aPrincipal, aDocShell) {
_readEntry(aPrincipal, aDocShell) {
let hostData = {};
let storage;

Просмотреть файл

@ -326,7 +326,7 @@ this.SessionStore = {
SessionStoreInternal.restoreLastSession();
},
getCurrentState: function (aUpdateAll) {
getCurrentState(aUpdateAll) {
return SessionStoreInternal.getCurrentState(aUpdateAll);
},
@ -383,7 +383,7 @@ this.SessionStore = {
* The browser state for which we remove worth-saving tabs.
* The given object will be modified.
*/
keepOnlyWorthSavingTabs: function (aState) {
keepOnlyWorthSavingTabs(aState) {
for (let i = aState.windows.length - 1; i >= 0; i--) {
let win = aState.windows[i];
for (let j = win.tabs.length - 1; j >= 0; j--) {
@ -502,7 +502,7 @@ var SessionStoreInternal = {
_closedObjectsChanged: false,
// A promise resolved once initialization is complete
_deferredInitialized: (function () {
_deferredInitialized: (function() {
let deferred = {};
deferred.promise = new Promise((resolve, reject) => {
@ -571,7 +571,7 @@ var SessionStoreInternal = {
/**
* Initialize the sessionstore service.
*/
init: function () {
init() {
if (this._initialized) {
throw new Error("SessionStore.init() must only be called once!");
}
@ -588,7 +588,7 @@ var SessionStoreInternal = {
/**
* Initialize the session using the state provided by SessionStartup
*/
initSession: function () {
initSession() {
TelemetryStopwatch.start("FX_SESSION_RESTORE_STARTUP_INIT_SESSION_MS");
let state;
let ss = gSessionStartup;
@ -614,8 +614,7 @@ var SessionStoreInternal = {
if (remainingState.windows.length) {
LastSession.setState(remainingState);
}
}
else {
} else {
// Get the last deferred session in case the user still wants to
// restore it
LastSession.setState(state.lastSessionState);
@ -655,8 +654,7 @@ var SessionStoreInternal = {
delete aWindow.__lastSessionWindowID;
});
}
}
catch (ex) { debug("The session file is invalid: " + ex); }
} catch (ex) { debug("The session file is invalid: " + ex); }
}
// at this point, we've as good as resumed the session, so we can
@ -669,7 +667,7 @@ var SessionStoreInternal = {
return state;
},
_initPrefs : function() {
_initPrefs() {
this._prefBranch = Services.prefs.getBranch("browser.");
gDebuggingEnabled = this._prefBranch.getBoolPref("sessionstore.debug");
@ -858,7 +856,7 @@ var SessionStoreInternal = {
}
}
break;
case "SessionStore:restoreHistoryComplete":
case "SessionStore:restoreHistoryComplete": {
// Notify the tabbrowser that the tab chrome has been restored.
let tabData = TabState.collect(tab);
@ -902,6 +900,7 @@ var SessionStoreInternal = {
event.initEvent("SSTabRestoring", true, false);
tab.dispatchEvent(event);
break;
}
case "SessionStore:restoreTabContentStarted":
if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) {
// If a load not initiated by sessionstore was started in a
@ -947,7 +946,6 @@ var SessionStoreInternal = {
break;
default:
throw new Error(`received unknown message '${aMessage.name}'`);
break;
}
},
@ -957,8 +955,8 @@ var SessionStoreInternal = {
* {histogramID: value, ...} An object mapping histogramIDs to the
* value to be recorded for that ID,
*/
recordTelemetry: function (telemetry) {
for (let histogramId in telemetry){
recordTelemetry(telemetry) {
for (let histogramId in telemetry) {
Telemetry.getHistogramById(histogramId).add(telemetry[histogramId]);
}
},
@ -1139,22 +1137,19 @@ var SessionStoreInternal = {
let options = {firstWindow: true, overwriteTabs: overwrite};
this.restoreWindows(aWindow, aInitialState, options);
}
}
else {
} else {
// Nothing to restore, notify observers things are complete.
Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
}
}
// this window was opened by _openWindowWithState
else if (!this._isWindowLoaded(aWindow)) {
} else if (!this._isWindowLoaded(aWindow)) {
let state = this._statesToRestore[aWindow.__SS_restoreID];
let options = {overwriteTabs: true, isFollowUp: state.windows.length == 1};
this.restoreWindow(aWindow, state.windows[0], options);
}
// The user opened another, non-private window after starting up with
// a single private one. Let's restore the session we actually wanted to
// restore at startup.
else if (this._deferredInitialState && !isPrivateWindow &&
} else if (this._deferredInitialState && !isPrivateWindow &&
aWindow.toolbar.visible) {
// global data must be restored before restoreWindow is called so that
@ -1165,8 +1160,7 @@ var SessionStoreInternal = {
this._deferredInitialState.windows.length : 0;
this.restoreWindows(aWindow, this._deferredInitialState, {firstWindow: true});
this._deferredInitialState = null;
}
else if (this._restoreLastWindow && aWindow.toolbar.visible &&
} else if (this._restoreLastWindow && aWindow.toolbar.visible &&
this._closedWindows.length && !isPrivateWindow) {
// default to the most-recently closed window
@ -1202,14 +1196,12 @@ var SessionStoreInternal = {
// In case there were no unpinned tabs, remove the window from _closedWindows
if (!normalTabsState.windows.length) {
this._removeClosedWindow(closedWindowIndex);
}
// Or update _closedWindows with the modified state
else {
} else {
delete normalTabsState.windows[0].__lastSessionWindowID;
this._closedWindows[closedWindowIndex] = normalTabsState.windows[0];
}
}
else {
} else {
// If we're just restoring the window, make sure it gets removed from
// _closedWindows.
this._removeClosedWindow(closedWindowIndex);
@ -1241,7 +1233,7 @@ var SessionStoreInternal = {
* @param aWindow
* Window reference
*/
onBeforeBrowserWindowShown: function (aWindow) {
onBeforeBrowserWindowShown(aWindow) {
// Register the window.
this.onLoad(aWindow);
@ -1547,7 +1539,7 @@ var SessionStoreInternal = {
/**
* On quit application granted
*/
onQuitApplicationGranted: function ssi_onQuitApplicationGranted(syncShutdown=false) {
onQuitApplicationGranted: function ssi_onQuitApplicationGranted(syncShutdown = false) {
// Collect an initial snapshot of window data before we do the flush
this._forEachBrowserWindow((win) => {
this._collectWindowData(win);
@ -1623,7 +1615,7 @@ var SessionStoreInternal = {
*
* @return Promise
*/
flushAllWindowsAsync: Task.async(function*(progress={}) {
flushAllWindowsAsync: Task.async(function*(progress = {}) {
let windowPromises = new Map();
// We collect flush promises and close each window immediately so that
// the user can't start changing any window state while we're waiting
@ -1651,7 +1643,7 @@ var SessionStoreInternal = {
yield promise;
this._collectWindowData(win);
progress.current++;
};
}
// We must cache this because _getMostRecentBrowserWindow will always
// return null by the time quit-application occurs.
@ -1782,8 +1774,7 @@ var SessionStoreInternal = {
}
if (openTabs.length == 0) {
this._closedWindows.splice(ix, 1);
}
else if (openTabs.length != openTabCount) {
} else if (openTabs.length != openTabCount) {
// Adjust the window's title if we removed an open tab
let selectedTab = openTabs[this._closedWindows[ix].selected - 1];
// some duplication from restoreHistory - make sure we get the correct title
@ -2078,7 +2069,7 @@ var SessionStoreInternal = {
* @param aBrowser
* The <xul:browser> that is now in the crashed state.
*/
onBrowserCrashed: function(aBrowser) {
onBrowserCrashed(aBrowser) {
NS_ASSERT(aBrowser.isRemoteBrowser,
"Only remote browsers should be able to crash");
@ -2114,7 +2105,7 @@ var SessionStoreInternal = {
// Clean up data that has been closed a long time ago.
// Do not reschedule a save. This will wait for the next regular
// save.
onIdleDaily: function() {
onIdleDaily() {
// Remove old closed windows
this._cleanupOldData([this._closedWindows]);
@ -2128,12 +2119,12 @@ var SessionStoreInternal = {
},
// Remove "old" data from an array
_cleanupOldData: function(targets) {
_cleanupOldData(targets) {
const TIME_TO_LIVE = this._prefBranch.getIntPref("sessionstore.cleanup.forget_closed_after");
const now = Date.now();
for (let array of targets) {
for (let i = array.length - 1; i >= 0; --i) {
for (let i = array.length - 1; i >= 0; --i) {
let data = array[i];
// Make sure that we have a timestamp to tell us when the target
// has been closed. If we don't have a timestamp, default to a
@ -2166,8 +2157,7 @@ var SessionStoreInternal = {
try {
var state = JSON.parse(aState);
}
catch (ex) { /* invalid state object - don't restore anything */ }
} catch (ex) { /* invalid state object - don't restore anything */ }
if (!state) {
throw Components.Exception("Invalid state string: not JSON", Cr.NS_ERROR_INVALID_ARG);
}
@ -2462,7 +2452,7 @@ var SessionStoreInternal = {
getWindowValue: function ssi_getWindowValue(aWindow, aKey) {
if ("__SSi" in aWindow) {
var data = this._windows[aWindow.__SSi].extData || {};
let data = this._windows[aWindow.__SSi].extData || {};
return data[aKey] || "";
}
@ -2658,12 +2648,11 @@ var SessionStoreInternal = {
// Restore into that window - pretend it's a followup since we'll already
// have a focused window.
//XXXzpao This is going to merge extData together (taking what was in
// XXXzpao This is going to merge extData together (taking what was in
// winState over what is in the window already.
let options = {overwriteTabs: canOverwriteTabs, isFollowUp: true};
this.restoreWindow(windowToUse, winState, options);
}
else {
} else {
this._openWindowWithState({ windows: [winState] });
}
}
@ -2794,10 +2783,10 @@ var SessionStoreInternal = {
return;
}
let window = tab.ownerGlobal;
let refreshedWindow = tab.ownerGlobal;
// The tab or its window might be gone.
if (!window || !window.__SSi || window.closed) {
if (!refreshedWindow || !refreshedWindow.__SSi || refreshedWindow.closed) {
return;
}
@ -2858,6 +2847,7 @@ var SessionStoreInternal = {
let tabState = TabState.collect(tab);
return { index: tabState.index - 1, entries: tabState.entries }
}
return null;
},
/**
@ -2886,7 +2876,6 @@ var SessionStoreInternal = {
let homePages = ["about:blank"];
let removableTabs = [];
let tabbrowser = aWindow.gBrowser;
let normalTabsLen = tabbrowser.tabs.length - tabbrowser._numPinnedTabs;
let startupPref = this._prefBranch.getIntPref("startup.page");
if (startupPref == 1)
homePages = homePages.concat(aWindow.gHomeButton.getHomePage().split("|"));
@ -2900,8 +2889,7 @@ var SessionStoreInternal = {
if (tabbrowser.tabs.length == removableTabs.length) {
canOverwriteTabs = true;
}
else {
} else {
// If we're not overwriting all of the tabs, then close the home tabs.
for (let i = removableTabs.length - 1; i >= 0; i--) {
tabbrowser.removeTab(removableTabs.pop(), { animate: false });
@ -2946,7 +2934,7 @@ var SessionStoreInternal = {
* Bool update all windows
* @returns object
*/
getCurrentState: function (aUpdateAll) {
getCurrentState(aUpdateAll) {
this._handleClosedWindows().then(() => {
this._notifyOfClosedObjectsChange();
});
@ -2961,8 +2949,7 @@ var SessionStoreInternal = {
return;
if (aUpdateAll || DirtyWindows.has(aWindow) || aWindow == activeWindow) {
this._collectWindowData(aWindow);
}
else { // always update the window features (whose change alone never triggers a save operation)
} else { // always update the window features (whose change alone never triggers a save operation)
this._updateWindowFeatures(aWindow);
}
});
@ -3008,7 +2995,7 @@ var SessionStoreInternal = {
// If no non-popup browser window remains open, return the state of the last
// closed window(s). We only want to do this when we're actually "ending"
// the session.
//XXXzpao We should do this for _restoreLastWindow == true, but that has
// XXXzpao We should do this for _restoreLastWindow == true, but that has
// its own check for popups. c.f. bug 597619
if (nonPopupCount == 0 && lastClosedWindowsCopy.length > 0 &&
RunState.isQuitting) {
@ -3040,7 +3027,7 @@ var SessionStoreInternal = {
windows: total,
selectedWindow: ix + 1,
_closedWindows: lastClosedWindowsCopy,
session: session,
session,
global: this._globalState.getState()
};
@ -3084,7 +3071,7 @@ var SessionStoreInternal = {
let windows = [this._windows[aWindow.__SSi]];
SessionCookies.update(windows);
return { windows: windows };
return { windows };
},
/**
@ -3163,11 +3150,9 @@ var SessionStoreInternal = {
if (!winData.tabs) {
winData.tabs = [];
}
// don't restore a single blank tab when we've had an external
// URL passed in for loading at startup (cf. bug 357419)
else if (firstWindow && !overwriteTabs && winData.tabs.length == 1 &&
} else if (firstWindow && !overwriteTabs && winData.tabs.length == 1 &&
(!winData.tabs[0].entries || winData.tabs[0].entries.length == 0)) {
winData.tabs = [];
}
@ -3233,8 +3218,7 @@ var SessionStoreInternal = {
if (winData.tabs[t].hidden) {
tabbrowser.hideTab(tabs[t]);
}
else {
} else {
tabbrowser.showTab(tabs[t]);
numVisibleTabs++;
}
@ -3366,8 +3350,7 @@ var SessionStoreInternal = {
let root;
try {
root = (typeof aState == "string") ? JSON.parse(aState) : aState;
}
catch (ex) { // invalid state object - don't restore anything
} catch (ex) { // invalid state object - don't restore anything
debug(ex);
this._sendRestoreCompletedNotifications();
return;
@ -3589,7 +3572,7 @@ var SessionStoreInternal = {
});
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory",
{tabData: tabData, epoch: epoch, loadArguments});
{tabData, epoch, loadArguments});
// Restore tab attributes.
if ("attributes" in tabData) {
@ -3618,7 +3601,7 @@ var SessionStoreInternal = {
* @param aReloadInFreshProcess
* true if we want to reload into a fresh process
*/
restoreTabContent: function (aTab, aLoadArguments = null, aReloadInFreshProcess = false) {
restoreTabContent(aTab, aLoadArguments = null, aReloadInFreshProcess = false) {
if (aTab.hasAttribute("customizemode") && !aLoadArguments) {
return;
}
@ -3651,7 +3634,7 @@ var SessionStoreInternal = {
let isRemotenessUpdate =
tabbrowser.updateBrowserRemotenessByURL(browser, uri, {
freshProcess: aReloadInFreshProcess,
newFrameloader: newFrameloader,
newFrameloader,
});
if (isRemotenessUpdate) {
@ -3663,8 +3646,8 @@ var SessionStoreInternal = {
let epoch = this.startNextEpoch(browser);
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory", {
tabData: tabData,
epoch: epoch,
tabData,
epoch,
loadArguments: aLoadArguments,
isRemotenessUpdate,
});
@ -3736,7 +3719,7 @@ var SessionStoreInternal = {
* Object containing session data for the window
*/
restoreWindowFeatures: function ssi_restoreWindowFeatures(aWindow, aWinData) {
var hidden = (aWinData.hidden)?aWinData.hidden.split(","):[];
var hidden = (aWinData.hidden) ? aWinData.hidden.split(",") : [];
WINDOW_HIDEABLE_FEATURES.forEach(function(aItem) {
aWindow[aItem].visible = hidden.indexOf(aItem) == -1;
});
@ -3747,8 +3730,7 @@ var SessionStoreInternal = {
aWindow.gURLBar.readOnly = true;
aWindow.gURLBar.setAttribute("enablehistory", "false");
}
}
else {
} else {
delete this._windows[aWindow.__SSi].isPopup;
if (aWindow.gURLBar) {
aWindow.gURLBar.readOnly = false;
@ -3756,14 +3738,13 @@ var SessionStoreInternal = {
}
}
var _this = this;
aWindow.setTimeout(function() {
_this.restoreDimensions.apply(_this, [aWindow,
aWindow.setTimeout(() => {
this.restoreDimensions(aWindow,
+(aWinData.width || 0),
+(aWinData.height || 0),
"screenX" in aWinData ? +aWinData.screenX : NaN,
"screenY" in aWinData ? +aWinData.screenY : NaN,
aWinData.sizemode || "", aWinData.sidebar || ""]);
aWinData.sizemode || "", aWinData.sidebar || "");
}, 0);
},
@ -3845,10 +3826,8 @@ var SessionStoreInternal = {
aWindow.resizeTo(aWidth, aHeight);
}
}
if (aSizeMode && win_("sizemode") != aSizeMode)
{
switch (aSizeMode)
{
if (aSizeMode && win_("sizemode") != aSizeMode) {
switch (aSizeMode) {
case "maximized":
aWindow.maximize();
break;
@ -3880,7 +3859,7 @@ var SessionStoreInternal = {
* Will mark the given window as dirty so that we will recollect its
* data before we start writing.
*/
saveStateDelayed: function (aWindow = null) {
saveStateDelayed(aWindow = null) {
if (aWindow) {
DirtyWindows.add(aWindow);
}
@ -4172,7 +4151,7 @@ var SessionStoreInternal = {
* @param aURL is the single URL we're looking for
* @returns whether the window data contains only the single URL passed
*/
_hasSingleTabWithURL: function(aWinData, aURL) {
_hasSingleTabWithURL(aWinData, aURL) {
if (aWinData &&
aWinData.length == 1 &&
aWinData[0].tabs &&
@ -4539,7 +4518,7 @@ var SessionStoreInternal = {
* @param aTab
* The tab that will be "reset"
*/
_resetLocalTabRestoringState: function (aTab) {
_resetLocalTabRestoringState(aTab) {
NS_ASSERT(aTab.linkedBrowser.__SS_restoreState,
"given tab is not restoring");
@ -4565,7 +4544,7 @@ var SessionStoreInternal = {
}
},
_resetTabRestoringState: function (tab) {
_resetTabRestoringState(tab) {
NS_ASSERT(tab.linkedBrowser.__SS_restoreState,
"given tab is not restoring");
@ -4609,7 +4588,7 @@ var SessionStoreInternal = {
* epoch. This function does that, and returns true if |epoch| is up-to-date
* with respect to |browser|.
*/
isCurrentEpoch: function (browser, epoch) {
isCurrentEpoch(browser, epoch) {
return this.getCurrentEpoch(browser) == epoch;
},
@ -4680,7 +4659,7 @@ var TabRestoreQueue = {
get restoreOnDemand() {
let updateValue = () => {
let value = Services.prefs.getBoolPref(PREF);
let definition = {value: value, configurable: true};
let definition = {value, configurable: true};
Object.defineProperty(this, "restoreOnDemand", definition);
return value;
}
@ -4694,7 +4673,7 @@ var TabRestoreQueue = {
get restorePinnedTabsOnDemand() {
let updateValue = () => {
let value = Services.prefs.getBoolPref(PREF);
let definition = {value: value, configurable: true};
let definition = {value, configurable: true};
Object.defineProperty(this, "restorePinnedTabsOnDemand", definition);
return value;
}
@ -4708,7 +4687,7 @@ var TabRestoreQueue = {
get restoreHiddenTabs() {
let updateValue = () => {
let value = Services.prefs.getBoolPref(PREF);
let definition = {value: value, configurable: true};
let definition = {value, configurable: true};
Object.defineProperty(this, "restoreHiddenTabs", definition);
return value;
}
@ -4720,12 +4699,12 @@ var TabRestoreQueue = {
},
// Resets the queue and removes all tabs.
reset: function () {
reset() {
this.tabs = {priority: [], visible: [], hidden: []};
},
// Adds a tab to the queue and determines its priority bucket.
add: function (tab) {
add(tab) {
let {priority, hidden, visible} = this.tabs;
if (tab.pinned) {
@ -4738,7 +4717,7 @@ var TabRestoreQueue = {
},
// Removes a given tab from the queue, if it's in there.
remove: function (tab) {
remove(tab) {
let {priority, hidden, visible} = this.tabs;
// We'll always check priority first since we don't
@ -4757,7 +4736,7 @@ var TabRestoreQueue = {
},
// Returns and removes the tab with the highest priority.
shift: function () {
shift() {
let set;
let {priority, hidden, visible} = this.tabs;
@ -4777,7 +4756,7 @@ var TabRestoreQueue = {
},
// Moves a given tab from the 'hidden' to the 'visible' bucket.
hiddenToVisible: function (tab) {
hiddenToVisible(tab) {
let {hidden, visible} = this.tabs;
let index = hidden.indexOf(tab);
@ -4788,7 +4767,7 @@ var TabRestoreQueue = {
},
// Moves a given tab from the 'visible' to the 'hidden' bucket.
visibleToHidden: function (tab) {
visibleToHidden(tab) {
let {visible, hidden} = this.tabs;
let index = visible.indexOf(tab);
@ -4806,7 +4785,7 @@ var TabRestoreQueue = {
* The tab to check
* @returns bool
*/
willRestoreSoon: function (tab) {
willRestoreSoon(tab) {
let { priority, hidden, visible } = this.tabs;
let { restoreOnDemand, restorePinnedTabsOnDemand,
restoreHiddenTabs } = this.prefs;
@ -4834,19 +4813,19 @@ var TabRestoreQueue = {
var DyingWindowCache = {
_data: new WeakMap(),
has: function (window) {
has(window) {
return this._data.has(window);
},
get: function (window) {
get(window) {
return this._data.get(window);
},
set: function (window, data) {
set(window, data) {
this._data.set(window, data);
},
remove: function (window) {
remove(window) {
this._data.delete(window);
}
};
@ -4856,19 +4835,19 @@ var DyingWindowCache = {
var DirtyWindows = {
_data: new WeakMap(),
has: function (window) {
has(window) {
return this._data.has(window);
},
add: function (window) {
add(window) {
return this._data.set(window, true);
},
remove: function (window) {
remove(window) {
this._data.delete(window);
},
clear: function (window) {
clear(window) {
this._data = new WeakMap();
}
};
@ -4884,15 +4863,15 @@ var LastSession = {
return !!this._state;
},
getState: function () {
getState() {
return this._state;
},
setState: function (state) {
setState(state) {
this._state = state;
},
clear: function () {
clear() {
if (this._state) {
this._state = null;
Services.obs.notifyObservers(null, NOTIFY_LAST_SESSION_CLEARED, null);

Просмотреть файл

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env worker */
/**
* A worker dedicated to handle I/O for Session Store.
*/
@ -124,7 +126,7 @@ var Agent = {
* - isFinalWrite If |true|, write to Paths.clean instead of
* Paths.recovery
*/
write: function (state, options = {}) {
write(state, options = {}) {
let exn;
let telemetry = {};
@ -227,7 +229,7 @@ var Agent = {
try {
iterator = new File.DirectoryIterator(this.Paths.backups);
iterator.forEach(function (file) {
iterator.forEach(function(file) {
if (file.path.startsWith(upgradeBackupPrefix)) {
backups.push(file.path);
}
@ -276,14 +278,14 @@ var Agent = {
result: {
upgradeBackup: upgradeBackupComplete
},
telemetry: telemetry,
telemetry,
};
},
/**
* Wipes all files holding session data from disk.
*/
wipe: function () {
wipe() {
// Don't stop immediately in case of error.
let exn = null;
@ -332,7 +334,7 @@ var Agent = {
* @param {string|null} prefix If provided, only remove files whose
* name starts with a specific prefix.
*/
_wipeFromDir: function(path, prefix) {
_wipeFromDir(path, prefix) {
// Sanity check
if (typeof prefix == "undefined" || prefix == "") {
throw new TypeError();

Просмотреть файл

@ -57,7 +57,7 @@ this.StartupPerformance = {
_totalNumberOfTabs: 0,
_totalNumberOfWindows: 0,
init: function() {
init() {
for (let topic of OBSERVED_TOPICS) {
Services.obs.addObserver(this, topic, false);
}
@ -83,7 +83,7 @@ this.StartupPerformance = {
// Called when restoration starts.
// Record the start timestamp, setup the timer and `this._promiseFinished`.
// Behavior is unspecified if there was already an ongoing measure.
_onRestorationStarts: function(isAutoRestore) {
_onRestorationStarts(isAutoRestore) {
this._latestRestoredTimeStamp = this._startTimeStamp = Date.now();
this._totalNumberOfEagerTabs = 0;
this._totalNumberOfTabs = 0;
@ -131,7 +131,7 @@ this.StartupPerformance = {
});
},
_startTimer: function() {
_startTimer() {
if (this._hasFired) {
return;
}
@ -153,7 +153,7 @@ this.StartupPerformance = {
}, COLLECT_RESULTS_AFTER_MS);
},
observe: function(subject, topic, details) {
observe(subject, topic, details) {
try {
switch (topic) {
case "sessionstore-restoring-on-startup":

Просмотреть файл

@ -20,15 +20,15 @@ const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "iconLoadingPri
// attributes when collecting tab data and will re-set those attributes when
// the given tab data is restored to a new tab.
this.TabAttributes = Object.freeze({
persist: function (name) {
persist(name) {
return TabAttributesInternal.persist(name);
},
get: function (tab) {
get(tab) {
return TabAttributesInternal.get(tab);
},
set: function (tab, data = {}) {
set(tab, data = {}) {
TabAttributesInternal.set(tab, data);
}
});
@ -36,7 +36,7 @@ this.TabAttributes = Object.freeze({
var TabAttributesInternal = {
_attrs: new Set(),
persist: function (name) {
persist(name) {
if (this._attrs.has(name) || ATTRIBUTES_TO_SKIP.has(name)) {
return false;
}
@ -45,7 +45,7 @@ var TabAttributesInternal = {
return true;
},
get: function (tab) {
get(tab) {
let data = {};
for (let name of this._attrs) {
@ -57,7 +57,7 @@ var TabAttributesInternal = {
return data;
},
set: function (tab, data = {}) {
set(tab, data = {}) {
// Clear attributes.
for (let name of this._attrs) {
tab.removeAttribute(name);

Просмотреть файл

@ -23,15 +23,15 @@ XPCOMUtils.defineLazyModuleGetter(this, "Utils",
* Module that contains tab state collection methods.
*/
this.TabState = Object.freeze({
update: function (browser, data) {
update(browser, data) {
TabStateInternal.update(browser, data);
},
collect: function (tab) {
collect(tab) {
return TabStateInternal.collect(tab);
},
clone: function (tab) {
clone(tab) {
return TabStateInternal.clone(tab);
},
@ -44,7 +44,7 @@ var TabStateInternal = {
/**
* Processes a data update sent by the content script.
*/
update: function (browser, {data}) {
update(browser, {data}) {
TabStateCache.update(browser, data);
},
@ -58,7 +58,7 @@ var TabStateInternal = {
* tab has not been invalidated since the last call to
* collect(aTab), the same object is returned.
*/
collect: function (tab) {
collect(tab) {
return this._collectBaseTabData(tab);
},
@ -73,7 +73,7 @@ var TabStateInternal = {
* cached, it will always be read from the tab and thus be
* up-to-date.
*/
clone: function (tab) {
clone(tab) {
return this._collectBaseTabData(tab, {includePrivateData: true});
},
@ -87,7 +87,7 @@ var TabStateInternal = {
*
* @returns {object} An object with the basic data for this tab.
*/
_collectBaseTabData: function (tab, options) {
_collectBaseTabData(tab, options) {
let tabData = { entries: [], lastAccessed: tab.lastAccessed };
let browser = tab.linkedBrowser;
@ -164,7 +164,6 @@ var TabStateInternal = {
// The caller may explicitly request to omit privacy checks.
let includePrivateData = options && options.includePrivateData;
let isPinned = !!tabData.pinned;
for (let key of Object.keys(data)) {
let value = data[key];

Просмотреть файл

@ -26,7 +26,7 @@ this.TabStateCache = Object.freeze({
* The cached data stored for the given |tab|
* or associated |browser|.
*/
get: function (browserOrTab) {
get(browserOrTab) {
return TabStateCacheInternal.get(browserOrTab);
},
@ -39,7 +39,7 @@ this.TabStateCache = Object.freeze({
* The new data to be stored for the given |tab|
* or associated |browser|.
*/
update: function (browserOrTab, newData) {
update(browserOrTab, newData) {
TabStateCacheInternal.update(browserOrTab, newData);
}
});
@ -56,7 +56,7 @@ var TabStateCacheInternal = {
* The cached data stored for the given |tab|
* or associated |browser|.
*/
get: function (browserOrTab) {
get(browserOrTab) {
return this._data.get(browserOrTab.permanentKey);
},
@ -70,7 +70,7 @@ var TabStateCacheInternal = {
* @param change (object)
* The actual changed values per domain.
*/
updatePartialStorageChange: function (data, change) {
updatePartialStorageChange(data, change) {
if (!data.storage) {
data.storage = {};
}
@ -105,7 +105,7 @@ var TabStateCacheInternal = {
* Object containing the tail of the history array, and
* some additional metadata.
*/
updatePartialHistoryChange: function (data, change) {
updatePartialHistoryChange(data, change) {
const kLastIndex = Number.MAX_SAFE_INTEGER - 1;
if (!data.history) {
@ -140,7 +140,7 @@ var TabStateCacheInternal = {
* The new data to be stored for the given |tab|
* or associated |browser|.
*/
update: function (browserOrTab, newData) {
update(browserOrTab, newData) {
let data = this._data.get(browserOrTab.permanentKey) || {};
for (let key of Object.keys(newData)) {

Просмотреть файл

@ -48,7 +48,7 @@ this.TabStateFlusher = Object.freeze({
* An error message that will be sent to the Console in the
* event that a flush failed.
*/
resolve(browser, flushID, success=true, message="") {
resolve(browser, flushID, success = true, message = "") {
TabStateFlusherInternal.resolve(browser, flushID, success, message);
},
@ -66,7 +66,7 @@ this.TabStateFlusher = Object.freeze({
* An error message that will be sent to the Console in the
* event that the flushes failed.
*/
resolveAll(browser, success=true, message="") {
resolveAll(browser, success = true, message = "") {
TabStateFlusherInternal.resolveAll(browser, success, message);
}
});
@ -124,7 +124,7 @@ var TabStateFlusherInternal = {
* An error message that will be sent to the Console in the
* event that a flush failed.
*/
resolve(browser, flushID, success=true, message="") {
resolve(browser, flushID, success = true, message = "") {
// Nothing to do if there are no pending flushes for the given browser.
if (!this._requests.has(browser.permanentKey)) {
return;
@ -160,7 +160,7 @@ var TabStateFlusherInternal = {
* An error message that will be sent to the Console in the
* event that the flushes failed.
*/
resolveAll(browser, success=true, message="") {
resolveAll(browser, success = true, message = "") {
// Nothing to do if there are no pending flushes for the given browser.
if (!this._requests.has(browser.permanentKey)) {
return;

Просмотреть файл

@ -194,15 +194,13 @@ function onListClick(aEvent) {
!treeView.isContainer(cell.row)) {
restoreSingleTab(cell.row, aEvent.shiftKey);
aEvent.stopPropagation();
}
else if (cell.col.id == "restore")
} else if (cell.col.id == "restore")
toggleRowChecked(cell.row);
}
}
function onListKeyDown(aEvent) {
switch (aEvent.keyCode)
{
switch (aEvent.keyCode) {
case KeyEvent.DOM_VK_SPACE:
toggleRowChecked(document.getElementById("tabList").currentIndex);
// Prevent page from scrolling on the space key.
@ -239,11 +237,16 @@ function toggleRowChecked(aIx) {
tab.checked = item.checked;
treeView.treeBox.invalidateRow(gTreeData.indexOf(tab));
}
}
else {
// update the window's checkmark as well (0 means "partially checked")
item.parent.checked = item.parent.tabs.every(isChecked) ? true :
item.parent.tabs.some(isChecked) ? 0 : false;
} else {
// Update the window's checkmark as well (0 means "partially checked").
let state = false;
if (item.parent.tabs.every(isChecked)) {
state = true;
} else if (item.parent.tabs.some(isChecked)) {
state = 0;
}
item.parent.checked = state;
treeView.treeBox.invalidateRow(gTreeData.indexOf(item.parent));
}
@ -277,20 +280,20 @@ var treeView = {
treeBox: null,
selection: null,
get rowCount() { return gTreeData.length; },
setTree: function(treeBox) { this.treeBox = treeBox; },
getCellText: function(idx, column) { return gTreeData[idx].label; },
isContainer: function(idx) { return "open" in gTreeData[idx]; },
getCellValue: function(idx, column){ return gTreeData[idx].checked; },
isContainerOpen: function(idx) { return gTreeData[idx].open; },
isContainerEmpty: function(idx) { return false; },
isSeparator: function(idx) { return false; },
isSorted: function() { return false; },
isEditable: function(idx, column) { return false; },
canDrop: function(idx, orientation, dt) { return false; },
getLevel: function(idx) { return this.isContainer(idx) ? 0 : 1; },
get rowCount() { return gTreeData.length; },
setTree(treeBox) { this.treeBox = treeBox; },
getCellText(idx, column) { return gTreeData[idx].label; },
isContainer(idx) { return "open" in gTreeData[idx]; },
getCellValue(idx, column) { return gTreeData[idx].checked; },
isContainerOpen(idx) { return gTreeData[idx].open; },
isContainerEmpty(idx) { return false; },
isSeparator(idx) { return false; },
isSorted() { return false; },
isEditable(idx, column) { return false; },
canDrop(idx, orientation, dt) { return false; },
getLevel(idx) { return this.isContainer(idx) ? 0 : 1; },
getParentIndex: function(idx) {
getParentIndex(idx) {
if (!this.isContainer(idx))
for (var t = idx - 1; t >= 0 ; t--)
if (this.isContainer(t))
@ -298,7 +301,7 @@ var treeView = {
return -1;
},
hasNextSibling: function(idx, after) {
hasNextSibling(idx, after) {
var thisLevel = this.getLevel(idx);
for (var t = after + 1; t < gTreeData.length; t++)
if (this.getLevel(t) <= thisLevel)
@ -306,7 +309,7 @@ var treeView = {
return false;
},
toggleOpenState: function(idx) {
toggleOpenState(idx) {
if (!this.isContainer(idx))
return;
var item = gTreeData[idx];
@ -317,8 +320,7 @@ var treeView = {
var deletecount = t - idx - 1;
gTreeData.splice(idx + 1, deletecount);
this.treeBox.rowCountChanged(idx + 1, -deletecount);
}
else {
} else {
// add this window's tab rows to the view
var toinsert = gTreeData[idx].tabs;
for (var i = 0; i < toinsert.length; i++)
@ -329,7 +331,7 @@ var treeView = {
this.treeBox.invalidateRow(idx);
},
getCellProperties: function(idx, column) {
getCellProperties(idx, column) {
if (column.id == "restore" && this.isContainer(idx) && gTreeData[idx].checked === 0)
return "partial";
if (column.id == "title")
@ -338,7 +340,7 @@ var treeView = {
return "";
},
getRowProperties: function(idx) {
getRowProperties(idx) {
var winState = gTreeData[idx].parent || gTreeData[idx];
if (winState.ix % 2 != 0)
return "alternate";
@ -346,17 +348,17 @@ var treeView = {
return "";
},
getImageSrc: function(idx, column) {
getImageSrc(idx, column) {
if (column.id == "title")
return gTreeData[idx].src || null;
return null;
},
getProgressMode : function(idx, column) { },
cycleHeader: function(column) { },
cycleCell: function(idx, column) { },
selectionChanged: function() { },
performAction: function(action) { },
performActionOnCell: function(action, index, column) { },
getColumnProperties: function(column) { return ""; }
getProgressMode(idx, column) { },
cycleHeader(column) { },
cycleCell(idx, column) { },
selectionChanged() { },
performAction(action) { },
performActionOnCell(action, index, column) { },
getColumnProperties(column) { return ""; }
};

Просмотреть файл

@ -2,11 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* eslint-env mozilla/frame-script */
function debug(msg) {
Services.console.logStringMessage("SessionStoreContent: " + msg);
}
"use strict";
var Cu = Components.utils;
var Cc = Components.classes;
@ -15,6 +13,11 @@ var Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
Cu.import("resource://gre/modules/Timer.jsm", this);
Cu.import("resource://gre/modules/Services.jsm", this);
function debug(msg) {
Services.console.logStringMessage("SessionStoreContent: " + msg);
}
XPCOMUtils.defineLazyModuleGetter(this, "FormData",
"resource://gre/modules/FormData.jsm");
@ -36,7 +39,7 @@ Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
var gFrameTree = new FrameTree(this);
Cu.import("resource:///modules/sessionstore/ContentRestore.jsm", this);
XPCOMUtils.defineLazyGetter(this, 'gContentRestore',
XPCOMUtils.defineLazyGetter(this, "gContentRestore",
() => { return new ContentRestore(this) });
// The current epoch.
@ -76,11 +79,11 @@ function createLazy(fn) {
*/
var EventListener = {
init: function () {
init() {
addEventListener("load", this, true);
},
handleEvent: function (event) {
handleEvent(event) {
// Ignore load events from subframes.
if (event.target != content.document) {
return;
@ -117,11 +120,11 @@ var MessageListener = {
"SessionStore:becomeActiveProcess",
],
init: function () {
init() {
this.MESSAGES.forEach(m => addMessageListener(m, this));
},
receiveMessage: function ({name, data}) {
receiveMessage({name, data}) {
// The docShell might be gone. Don't process messages,
// that will just lead to errors anyway.
if (!docShell) {
@ -230,7 +233,7 @@ var MessageListener = {
* {entries: [{url: "about:mozilla", ...}, ...], index: 1}
*/
var SessionHistoryListener = {
init: function () {
init() {
// The frame tree observer is needed to handle initial subframe loads.
// It will redundantly invalidate with the SHistoryListener in some cases
// but these invalidations are very cheap.
@ -260,14 +263,14 @@ var SessionHistoryListener = {
addEventListener("DOMTitleChanged", this);
},
uninit: function () {
uninit() {
let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
if (sessionHistory) {
sessionHistory.removeSHistoryListener(this);
}
},
collect: function () {
collect() {
// We want to send down a historychange even for full collects in case our
// session history is a partial session history, in which case we don't have
// enough information for a full update. collectFrom(-1) tells the collect
@ -286,7 +289,7 @@ var SessionHistoryListener = {
// and send the entire history. We always send the additional info like the current selected
// index (so for going back and forth between history entries we set the index to kLastIndex
// if nothing else changed send an empty array and the additonal info like the selected index)
collectFrom: function (idx) {
collectFrom(idx) {
if (this._fromIdx <= idx) {
// If we already know that we need to update history fromn index N we can ignore any changes
// tha happened with an element with index larger than N.
@ -312,44 +315,44 @@ var SessionHistoryListener = {
this.collect();
},
onFrameTreeCollected: function () {
onFrameTreeCollected() {
this.collect();
},
onFrameTreeReset: function () {
onFrameTreeReset() {
this.collect();
},
OnHistoryNewEntry: function (newURI, oldIndex) {
OnHistoryNewEntry(newURI, oldIndex) {
this.collectFrom(oldIndex);
},
OnHistoryGoBack: function (backURI) {
OnHistoryGoBack(backURI) {
this.collectFrom(kLastIndex);
return true;
},
OnHistoryGoForward: function (forwardURI) {
OnHistoryGoForward(forwardURI) {
this.collectFrom(kLastIndex);
return true;
},
OnHistoryGotoIndex: function (index, gotoURI) {
OnHistoryGotoIndex(index, gotoURI) {
this.collectFrom(kLastIndex);
return true;
},
OnHistoryPurge: function (numEntries) {
OnHistoryPurge(numEntries) {
this.collect();
return true;
},
OnHistoryReload: function (reloadURI, reloadFlags) {
OnHistoryReload(reloadURI, reloadFlags) {
this.collect();
return true;
},
OnHistoryReplaceEntry: function (index) {
OnHistoryReplaceEntry(index) {
this.collect();
},
@ -372,12 +375,12 @@ var SessionHistoryListener = {
* {scroll: "100,100", children: [null, null, {scroll: "200,200"}]}
*/
var ScrollPositionListener = {
init: function () {
init() {
addEventListener("scroll", this);
gFrameTree.addObserver(this);
},
handleEvent: function (event) {
handleEvent(event) {
let frame = event.target.defaultView;
// Don't collect scroll data for frames created at or after the load event
@ -387,15 +390,15 @@ var ScrollPositionListener = {
}
},
onFrameTreeCollected: function () {
onFrameTreeCollected() {
MessageQueue.push("scroll", () => this.collect());
},
onFrameTreeReset: function () {
onFrameTreeReset() {
MessageQueue.push("scroll", () => null);
},
collect: function () {
collect() {
return gFrameTree.map(ScrollPosition.collect);
}
};
@ -418,13 +421,13 @@ var ScrollPositionListener = {
* }
*/
var FormDataListener = {
init: function () {
init() {
addEventListener("input", this, true);
addEventListener("change", this, true);
gFrameTree.addObserver(this);
},
handleEvent: function (event) {
handleEvent(event) {
let frame = event.target.ownerGlobal;
// Don't collect form data for frames created at or after the load event
@ -434,11 +437,11 @@ var FormDataListener = {
}
},
onFrameTreeReset: function () {
onFrameTreeReset() {
MessageQueue.push("formdata", () => null);
},
collect: function () {
collect() {
return gFrameTree.map(FormData.collect);
}
};
@ -455,18 +458,18 @@ var FormDataListener = {
* {pageStyle: "Dusk", children: [null, {pageStyle: "Mozilla"}]}
*/
var PageStyleListener = {
init: function () {
init() {
Services.obs.addObserver(this, "author-style-disabled-changed", false);
Services.obs.addObserver(this, "style-sheet-applicable-state-changed", false);
gFrameTree.addObserver(this);
},
uninit: function () {
uninit() {
Services.obs.removeObserver(this, "author-style-disabled-changed");
Services.obs.removeObserver(this, "style-sheet-applicable-state-changed");
},
observe: function (subject, topic) {
observe(subject, topic) {
let frame = subject.defaultView;
if (frame && gFrameTree.contains(frame)) {
@ -474,15 +477,15 @@ var PageStyleListener = {
}
},
collect: function () {
collect() {
return PageStyle.collect(docShell, gFrameTree);
},
onFrameTreeCollected: function () {
onFrameTreeCollected() {
MessageQueue.push("pageStyle", () => this.collect());
},
onFrameTreeReset: function () {
onFrameTreeReset() {
MessageQueue.push("pageStyle", () => null);
}
};
@ -503,14 +506,14 @@ var DocShellCapabilitiesListener = {
*/
_latestCapabilities: "",
init: function () {
init() {
gFrameTree.addObserver(this);
},
/**
* onFrameTreeReset() is called as soon as we start loading a page.
*/
onFrameTreeReset: function() {
onFrameTreeReset() {
// The order of docShell capabilities cannot change while we're running
// so calling join() without sorting before is totally sufficient.
let caps = DocShellCapabilities.collect(docShell).join(",");
@ -533,23 +536,23 @@ var DocShellCapabilitiesListener = {
* as keys and per-host DOMSessionStorage data as values.
*/
var SessionStorageListener = {
init: function () {
init() {
addEventListener("MozSessionStorageChanged", this, true);
Services.obs.addObserver(this, "browser:purge-domain-data", false);
gFrameTree.addObserver(this);
},
uninit: function () {
uninit() {
Services.obs.removeObserver(this, "browser:purge-domain-data");
},
handleEvent: function (event) {
handleEvent(event) {
if (gFrameTree.contains(event.target)) {
this.collectFromEvent(event);
}
},
observe: function () {
observe() {
// Collect data on the next tick so that any other observer
// that needs to purge data can do its work first.
setTimeout(() => this.collect(), 0);
@ -567,7 +570,7 @@ var SessionStorageListener = {
// we also don't want to cause an OOM here, we use a quick and memory-
// efficient approximation: we compute the total sum of string lengths
// involved in this object.
estimateStorageSize: function(collected) {
estimateStorageSize(collected) {
if (!collected) {
return 0;
}
@ -593,11 +596,11 @@ var SessionStorageListener = {
// reset these changes.
_changes: undefined,
resetChanges: function () {
resetChanges() {
this._changes = undefined;
},
collectFromEvent: function (event) {
collectFromEvent(event) {
// TODO: we should take browser.sessionstore.dom_storage_limit into an account here.
if (docShell) {
let {url, key, newValue} = event;
@ -622,7 +625,7 @@ var SessionStorageListener = {
}
},
collect: function () {
collect() {
if (docShell) {
// We need the entire session storage, let's reset the pending individual change
// messages.
@ -649,11 +652,11 @@ var SessionStorageListener = {
}
},
onFrameTreeCollected: function () {
onFrameTreeCollected() {
this.collect();
},
onFrameTreeReset: function () {
onFrameTreeReset() {
this.collect();
}
};
@ -669,7 +672,7 @@ var SessionStorageListener = {
* not saved.
*/
var PrivacyListener = {
init: function() {
init() {
docShell.addWeakPrivacyTransitionObserver(this);
// Check that value at startup as it might have
@ -680,7 +683,7 @@ var PrivacyListener = {
},
// Ci.nsIPrivacyTransitionObserver
privateModeChanged: function(enabled) {
privateModeChanged(enabled) {
MessageQueue.push("isPrivate", () => enabled || null);
},
@ -774,7 +777,7 @@ var MessageQueue = {
* A function that returns the value that will be sent to the parent
* process.
*/
push: function (key, fn) {
push(key, fn) {
this._data.set(key, createLazy(fn));
if (!this._timeout && !this._timeoutDisabled) {
@ -790,7 +793,7 @@ var MessageQueue = {
* {flushID: 123} to specify that this is a flush
* {isFinal: true} to signal this is the final message sent on unload
*/
send: function (options = {}) {
send(options = {}) {
// Looks like we have been called off a timeout after the tab has been
// closed. The docShell is gone now and we can just return here as there
// is nothing to do.
@ -832,13 +835,14 @@ var MessageQueue = {
isFinal: options.isFinal || false,
epoch: gCurrentEpoch
});
} catch (ex if ex && ex.result == Cr.NS_ERROR_OUT_OF_MEMORY) {
let telemetry = {
FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM: 1
};
sendAsyncMessage("SessionStore:error", {
telemetry
});
} catch (ex) {
if (ex && ex.result == Cr.NS_ERROR_OUT_OF_MEMORY) {
sendAsyncMessage("SessionStore:error", {
telemetry: {
FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM: 1
}
});
}
}
},
};

Просмотреть файл

@ -65,7 +65,7 @@ consoleMsg.init(aMsg, aException.fileName, null, aException.lineNumber, 0, Ci.ns
Services.console.logMessage(consoleMsg);
}
var gOnceInitializedDeferred = (function () {
var gOnceInitializedDeferred = (function() {
let deferred = {};
deferred.promise = new Promise((resolve, reject) => {
@ -127,7 +127,7 @@ SessionStartup.prototype = {
* @param source The Session State string read from disk.
* @param parsed The object obtained by parsing |source| as JSON.
*/
_onSessionFileRead: function ({source, parsed, noFilesFound}) {
_onSessionFileRead({source, parsed, noFilesFound}) {
this._initialized = true;
// Let observers modify the state before it is used
@ -173,35 +173,30 @@ SessionStartup.prototype = {
// If the previous session finished writing the final state, we'll
// assume there was no crash.
this._previousSessionCrashed = !checkpoints["sessionstore-final-state-write-complete"];
} else {
} else if (noFilesFound) {
// If the Crash Monitor could not load a checkpoints file it will
// provide null. This could occur on the first run after updating to
// a version including the Crash Monitor, or if the checkpoints file
// was removed, or on first startup with this profile, or after Firefox Reset.
if (noFilesFound) {
// There was no checkpoints file and no sessionstore.js or its backups
// so we will assume that this was a fresh profile.
this._previousSessionCrashed = false;
// There was no checkpoints file and no sessionstore.js or its backups
// so we will assume that this was a fresh profile.
this._previousSessionCrashed = false;
} else {
// If this is the first run after an update, sessionstore.js should
// still contain the session.state flag to indicate if the session
// crashed. If it is not present, we will assume this was not the first
// run after update and the checkpoints file was somehow corrupted or
// removed by a crash.
//
// If the session.state flag is present, we will fallback to using it
// for crash detection - If the last write of sessionstore.js had it
// set to "running", we crashed.
let stateFlagPresent = (this._initialState.session &&
this._initialState.session.state);
} else {
// If this is the first run after an update, sessionstore.js should
// still contain the session.state flag to indicate if the session
// crashed. If it is not present, we will assume this was not the first
// run after update and the checkpoints file was somehow corrupted or
// removed by a crash.
//
// If the session.state flag is present, we will fallback to using it
// for crash detection - If the last write of sessionstore.js had it
// set to "running", we crashed.
let stateFlagPresent = (this._initialState.session &&
this._initialState.session.state);
this._previousSessionCrashed = !stateFlagPresent ||
(this._initialState.session.state == STATE_RUNNING_STR);
}
this._previousSessionCrashed = !stateFlagPresent ||
(this._initialState.session.state == STATE_RUNNING_STR);
}
// Report shutdown success via telemetry. Shortcoming here are
@ -293,7 +288,7 @@ SessionStartup.prototype = {
* crash, this method returns false.
* @returns bool
*/
isAutomaticRestoreEnabled: function () {
isAutomaticRestoreEnabled() {
return Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") ||
Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION;
},
@ -302,7 +297,7 @@ SessionStartup.prototype = {
* Determines whether there is a pending session restore.
* @returns bool
*/
_willRestore: function () {
_willRestore() {
return this._sessionType == Ci.nsISessionStartup.RECOVER_SESSION ||
this._sessionType == Ci.nsISessionStartup.RESUME_SESSION;
},

Просмотреть файл

@ -26,7 +26,7 @@ function SessionStoreService() {}
// The SessionStore module's object is frozen. We need to modify our prototype
// and add some properties so let's just copy the SessionStore object.
Object.keys(SessionStore).forEach(function (aName) {
Object.keys(SessionStore).forEach(function(aName) {
let desc = Object.getOwnPropertyDescriptor(SessionStore, aName);
Object.defineProperty(SessionStoreService.prototype, aName, desc);
});

Просмотреть файл

@ -1,15 +1,15 @@
"use strict";
const PREF = 'network.cookie.cookieBehavior';
const PAGE_URL = 'http://mochi.test:8888/browser/' +
'browser/components/sessionstore/test/browser_1234021_page.html';
const PREF = "network.cookie.cookieBehavior";
const PAGE_URL = "http://mochi.test:8888/browser/" +
"browser/components/sessionstore/test/browser_1234021_page.html";
const BEHAVIOR_REJECT = 2;
add_task(function* test() {
yield pushPrefs([PREF, BEHAVIOR_REJECT]);
yield BrowserTestUtils.withNewTab({
gBrowser: gBrowser,
gBrowser,
url: PAGE_URL
}, function* handler(aBrowser) {
yield TabStateFlusher.flush(aBrowser);

Просмотреть файл

@ -32,10 +32,10 @@ function test() {
}
});
function test(aLambda) {
function checkNoThrow(aLambda) {
try {
return aLambda() || true;
} catch(ex) { }
} catch (ex) { }
return false;
}
@ -73,9 +73,9 @@ function test() {
(aValue.indexOf(aIx) > -1) == aOpt.selected);
}
//////////////////////////////////////////////////////////////////
// Test (B) : Session data restoration between windows //
//////////////////////////////////////////////////////////////////
/**
* Test (B) : Session data restoration between windows
*/
let rootDir = getRootDirectory(gTestPath);
const testURL = rootDir + "browser_248970_b_sample.html";
@ -93,7 +93,6 @@ function test() {
"getClosedTabCount should return zero or at most max_tabs_undo");
// setup a state for tab (A) so we can check later that is restored
let key = "key";
let value = "Value " + Math.random();
let state = { entries: [{ url: testURL }], extData: { key: value } };
@ -117,15 +116,15 @@ function test() {
"getClosedTabCount has increased after closing a tab");
// verify tab: (A), in undo list
let tab_A_restored = test(() => ss.undoCloseTab(aWin, 0));
let tab_A_restored = checkNoThrow(() => ss.undoCloseTab(aWin, 0));
ok(tab_A_restored, "a tab is in undo list");
promiseTabRestored(tab_A_restored).then(() => {
is(testURL, tab_A_restored.linkedBrowser.currentURI.spec,
"it's the same tab that we expect");
aWin.gBrowser.removeTab(tab_A_restored);
whenNewWindowLoaded({ private: true }, function(aWin) {
windowsToClose.push(aWin);
whenNewWindowLoaded({ private: true }, function(win) {
windowsToClose.push(win);
// setup a state for tab (B) so we can check that its duplicated
// properly
@ -135,14 +134,14 @@ function test() {
entries: [{ url: testURL2 }], extData: { key1: value1 }
};
let tab_B = aWin.gBrowser.addTab(testURL2);
let tab_B = win.gBrowser.addTab(testURL2);
promiseTabState(tab_B, state1).then(() => {
// populate tab: (B) with different form data
for (let item in fieldList)
setFormValue(tab_B, item, fieldList[item]);
// duplicate tab: (B)
let tab_C = aWin.gBrowser.duplicateTab(tab_B);
let tab_C = win.gBrowser.duplicateTab(tab_B);
promiseTabRestored(tab_C).then(() => {
// verify the correctness of the duplicated tab
is(ss.getTabValue(tab_C, key1), value1,
@ -153,8 +152,8 @@ function test() {
"The value for \"" + item + "\" was correctly duplicated");
// private browsing session, close tab: (C) and (B)
aWin.gBrowser.removeTab(tab_C);
aWin.gBrowser.removeTab(tab_B);
win.gBrowser.removeTab(tab_C);
win.gBrowser.removeTab(tab_B);
finish();
});

Просмотреть файл

@ -5,40 +5,41 @@
function test() {
/** Test for Bug 345898 **/
function test(aLambda) {
try {
aLambda();
return false;
}
catch (ex) {
return ex.name == "NS_ERROR_ILLEGAL_VALUE" ||
ex.name == "NS_ERROR_FAILURE";
}
}
// all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
ok(test(() => ss.getWindowState({})),
"Invalid window for getWindowState throws");
ok(test(() => ss.setWindowState({}, "", false)),
"Invalid window for setWindowState throws");
ok(test(() => ss.getTabState({})),
"Invalid tab for getTabState throws");
ok(test(() => ss.setTabState({}, "{}")),
"Invalid tab state for setTabState throws");
ok(test(() => ss.setTabState({}, JSON.stringify({ entries: [] }))),
"Invalid tab for setTabState throws");
ok(test(() => ss.duplicateTab({}, {})),
"Invalid tab for duplicateTab throws");
ok(test(() => ss.duplicateTab({}, gBrowser.selectedTab)),
"Invalid window for duplicateTab throws");
ok(test(() => ss.getClosedTabData({})),
"Invalid window for getClosedTabData throws");
ok(test(() => ss.undoCloseTab({}, 0)),
"Invalid window for undoCloseTab throws");
ok(test(() => ss.undoCloseTab(window, -1)),
"Invalid index for undoCloseTab throws");
ok(test(() => ss.getWindowValue({}, "")),
"Invalid window for getWindowValue throws");
ok(test(() => ss.setWindowValue({}, "", "")),
"Invalid window for setWindowValue throws");
Assert.throws(() => ss.getWindowState({}),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for getWindowState throws");
Assert.throws(() => ss.setWindowState({}, "", false),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for setWindowState throws");
Assert.throws(() => ss.getTabState({}),
/NS_ERROR_FAILURE/,
"Invalid tab for getTabState throws");
Assert.throws(() => ss.setTabState({}, "{}"),
/NS_ERROR_FAILURE/,
"Invalid tab state for setTabState throws");
Assert.throws(() => ss.setTabState({}, JSON.stringify({ entries: [] })),
/NS_ERROR_FAILURE/,
"Invalid tab for setTabState throws");
Assert.throws(() => ss.duplicateTab({}, {}),
/NS_ERROR_FAILURE/,
"Invalid tab for duplicateTab throws");
Assert.throws(() => ss.duplicateTab({}, gBrowser.selectedTab),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for duplicateTab throws");
Assert.throws(() => ss.getClosedTabData({}),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for getClosedTabData throws");
Assert.throws(() => ss.undoCloseTab({}, 0),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for undoCloseTab throws");
Assert.throws(() => ss.undoCloseTab(window, -1),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid index for undoCloseTab throws");
Assert.throws(() => ss.getWindowValue({}, ""),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for getWindowValue throws");
Assert.throws(() => ss.setWindowValue({}, "", ""),
/NS_ERROR_ILLEGAL_VALUE/,
"Invalid window for setWindowValue throws");
}

Просмотреть файл

@ -12,14 +12,13 @@ add_task(function* () {
function test(aLambda) {
try {
return aLambda() || true;
}
catch (ex) { }
} catch (ex) { }
return false;
}
////////////////////////////
// setWindowValue, et al. //
////////////////////////////
/**
* setWindowValue, et al.
*/
let key = "Unique name: " + Date.now();
let value = "Unique value: " + Math.random();
@ -38,9 +37,9 @@ add_task(function* () {
// test deleting a non-existent value
ok(test(() => ss.deleteWindowValue(window, key)), "delete non-existent window value");
/////////////////////////
// setTabValue, et al. //
/////////////////////////
/**
* setTabValue, et al.
*/
key = "Unique name: " + Math.random();
value = "Unique value: " + Date.now();
let tab = gBrowser.addTab();
@ -64,9 +63,9 @@ add_task(function* () {
// clean up
yield promiseRemoveTab(tab);
/////////////////////////////////////
// getClosedTabCount, undoCloseTab //
/////////////////////////////////////
/**
* getClosedTabCount, undoCloseTab
*/
// get closed tab count
let count = ss.getClosedTabCount(window);

Просмотреть файл

@ -76,7 +76,7 @@ add_task(function* setup() {
document.documentElement.setAttribute("windowtype", "navigator:testrunner");
registerCleanupFunction(() => {
document.documentElement.setAttribute("windowtype", "navigator:browser");
document.documentElement.setAttribute("windowtype", oldWinType);
});
});
@ -154,7 +154,7 @@ let setupTest = Task.async(function*(options, testFunction) {
* The browser window to load the tabs in
*/
function injectTestTabs(win) {
TEST_URLS.forEach(function (url) {
TEST_URLS.forEach(function(url) {
win.gBrowser.addTab(url);
});
}
@ -471,4 +471,3 @@ add_task(function* test_mac_notifications() {
"Got expected browser-lastwindow-close-granted notifications");
});
});

Просмотреть файл

@ -35,6 +35,7 @@ add_task(function* () {
});
function promiseSHistoryCount(browser) {
/* eslint-env mozilla/frame-script */
return ContentTask.spawn(browser, null, function* () {
return docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory.count;
});

Просмотреть файл

@ -29,7 +29,7 @@ function test() {
// Mark the window with some unique data to be restored later on.
ss.setWindowValue(newWin, uniqueKey, uniqueValue);
let [txt, chk] = newWin.content.document.querySelectorAll("#txt, #chk");
let [txt] = newWin.content.document.querySelectorAll("#txt");
txt.value = uniqueText;
let browser = newWin.gBrowser.selectedBrowser;
@ -73,7 +73,8 @@ function test() {
is(newWin2.gBrowser.currentURI.spec, TEST_URL,
"The window correctly restored the URL");
let [txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
let chk;
[txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
ok(txt.value == uniqueText && chk.checked,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,

Просмотреть файл

@ -73,4 +73,4 @@ add_task(function* test_closed_window_states() {
other: {popup: 0, normal: 3}};
yield testWindows(windowsToOpen2, expectedResults2);
});
});

Просмотреть файл

@ -6,7 +6,7 @@ Components.utils.import("resource://gre/modules/ForgetAboutSite.jsm");
function waitForClearHistory(aCallback) {
let observer = {
observe: function(aSubject, aTopic, aData) {
observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "browser:purge-domain-data");
setTimeout(aCallback, 0);
}

Просмотреть файл

@ -12,7 +12,7 @@ function test() {
// Make sure the functionality added in bug 943339 doesn't affect the results
gPrefService.setIntPref("browser.sessionstore.max_serialize_back", -1);
gPrefService.setIntPref("browser.sessionstore.max_serialize_forward", -1);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
gPrefService.clearUserPref("browser.sessionstore.max_serialize_back");
gPrefService.clearUserPref("browser.sessionstore.max_serialize_forward");
});

Просмотреть файл

@ -41,7 +41,7 @@ add_task(function* test_restore_nonstandard_input_values() {
}
is(countGood, 4, "Saved text for non-standard input fields");
is(countBad, 0, "Didn't save text for ignored field types");
is(countBad, 0, "Didn't save text for ignored field types");
});
function setFormElementValues(browser, data) {

Просмотреть файл

@ -24,15 +24,15 @@ function test() {
frameCount = 0;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
tab2.linkedBrowser.addEventListener("load", function(eventTab2) {
// wait for all frames to load (and reload!) completely
if (frameCount++ < 2)
return;
tab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
let iframes = tab2.linkedBrowser.contentWindow.frames;
if (iframes[1].document.body.innerHTML !== uniqueValue) {
let iframesTab2 = tab2.linkedBrowser.contentWindow.frames;
if (iframesTab2[1].document.body.innerHTML !== uniqueValue) {
// Poll again the value, since we can't ensure to run
// after SessionStore has injected innerHTML value.
// See bug 521802.
@ -41,14 +41,13 @@ function test() {
return;
}
is(iframes[1].document.body.innerHTML, uniqueValue,
is(iframesTab2[1].document.body.innerHTML, uniqueValue,
"rich textarea's content correctly duplicated");
let innerDomain = null;
try {
innerDomain = iframes[0].document.domain;
}
catch (ex) { /* throws for chrome: documents */ }
innerDomain = iframesTab2[0].document.domain;
} catch (ex) { /* throws for chrome: documents */ }
is(innerDomain, "mochi.test", "XSS exploit prevented!");
// clean up

Просмотреть файл

@ -36,6 +36,6 @@
});
frames[1].document.designMode = "on";
};
}
</script>
</body>

Просмотреть файл

@ -26,8 +26,7 @@ function test() {
try {
aFunction();
return false;
}
catch (ex) {
} catch (ex) {
return ex.name == "NS_ERROR_ILLEGAL_VALUE";
}
}

Просмотреть файл

@ -18,7 +18,7 @@ function test() {
return;
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("461743", function(aEvent) {
tab2.linkedBrowser.addEventListener("461743", function(eventTab2) {
tab2.linkedBrowser.removeEventListener("461743", arguments.callee, true);
is(aEvent.data, "done", "XSS injection was attempted");

Просмотреть файл

@ -35,7 +35,7 @@
xhr.send(null);
}
function done() {
var event = new MessageEvent('461743', { bubbles: true, cancelable: false,
var event = new MessageEvent("461743", { bubbles: true, cancelable: false,
data: "done", origin: location.href,
source: window });
document.dispatchEvent(event);
@ -51,6 +51,6 @@
frames[0].document.addEventListener("DOMNodeInserted", done, true);
frames[0].document.designMode = "on";
};
}
</script>
</body>

Просмотреть файл

@ -35,6 +35,6 @@ add_task(function* test_check_urls_before_restoring() {
function getState(url) {
return JSON.stringify({
entries: [{url: URL, triggeringPrincipal_base64}],
formdata: {url: url, id: {text: "foobar"}}
formdata: {url, id: {text: "foobar"}}
});
}

Просмотреть файл

@ -41,7 +41,7 @@ add_task(function* () {
Assert.equal(content.frames[1].document.getElementById("out2").value,
"", "id prefixes can't be faked");
// Disabled for now, Bug 588077
//Assert.equal(content.frames[0].frames[1].document.getElementById("in1").value,
// Assert.equal(content.frames[0].frames[1].document.getElementById("in1").value,
// "", "id prefixes aren't mixed up");
Assert.equal(content.frames[1].frames[0].document.getElementById("in1").value,
"", "id prefixes aren't mixed up");

Просмотреть файл

@ -6,7 +6,7 @@ Components.utils.import("resource://gre/modules/ForgetAboutSite.jsm");
function waitForClearHistory(aCallback) {
let observer = {
observe: function(aSubject, aTopic, aData) {
observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "browser:purge-domain-data");
setTimeout(aCallback, 0);
}

Просмотреть файл

@ -44,7 +44,7 @@
}
document.getElementById("state").textContent = "done";
var event = new MessageEvent('464620_a', { bubbles: true, cancelable: false,
var event = new MessageEvent("464620_a", { bubbles: true, cancelable: false,
data: "done", origin: location.href,
source: window });
document.dispatchEvent(event);

Просмотреть файл

@ -21,7 +21,7 @@ function test() {
executeSoon(function() {
frameCount = 0;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("464620_a", function(aEvent) {
tab2.linkedBrowser.addEventListener("464620_a", function(eventTab2) {
tab2.linkedBrowser.removeEventListener("464620_a", arguments.callee, true);
is(aEvent.data, "done", "XSS injection was attempted");

Просмотреть файл

@ -47,7 +47,7 @@
}
document.getElementById("state").textContent = "done";
var event = new MessageEvent('464620_b', { bubbles: true, cancelable: false,
var event = new MessageEvent("464620_b", { bubbles: true, cancelable: false,
data: "done", origin: location.href,
source: window });
document.dispatchEvent(event);

Просмотреть файл

@ -21,7 +21,7 @@ function test() {
executeSoon(function() {
frameCount = 0;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("464620_b", function(aEvent) {
tab2.linkedBrowser.addEventListener("464620_b", function(eventTab2) {
tab2.linkedBrowser.removeEventListener("464620_b", arguments.callee, true);
is(aEvent.data, "done", "XSS injection was attempted");

Просмотреть файл

@ -12,8 +12,7 @@
window.addEventListener("DOMContentLoaded", function() {
if (!document.location.hash) {
document.location.hash = "#ready";
}
else {
} else {
document.getElementById("thief").type = "file";
document.getElementById("reverse_thief").type = "text";
}

Просмотреть файл

@ -26,7 +26,7 @@ const STATE3 = createEntries(JSON.stringify(CRASH_STATE));
function createEntries(sessionData) {
return {
entries: [{url: "about:sessionrestore", triggeringPrincipal_base64}],
formdata: {id: {sessionData: sessionData}, url: "about:sessionrestore"}
formdata: {id: {sessionData}, url: "about:sessionrestore"}
};
}

Просмотреть файл

@ -22,7 +22,7 @@ add_task(function* () {
yield TabStateFlusher.flush(browser);
let tabState = JSON.parse(ss.getTabState(tab));
is(tabState.entries[0].referrer, REFERRER1,
is(tabState.entries[0].referrer, REFERRER1,
"Referrer retrieved via getTabState matches referrer set via loadURI.");
tabState.entries[0].referrer = REFERRER2;

Просмотреть файл

@ -73,8 +73,7 @@ function test() {
try {
aFunction();
return false;
}
catch (ex) {
} catch (ex) {
return ex.name == "NS_ERROR_ILLEGAL_VALUE";
}
}

Просмотреть файл

@ -12,13 +12,13 @@ function checkState(tab) {
let popStateCount = 0;
tab.linkedBrowser.addEventListener('popstate', function(aEvent) {
tab.linkedBrowser.addEventListener("popstate", function(aEvent) {
let contentWindow = tab.linkedBrowser.contentWindow;
if (popStateCount == 0) {
popStateCount++;
is(tab.linkedBrowser.contentWindow.testState, 'foo',
'testState after going back');
is(tab.linkedBrowser.contentWindow.testState, "foo",
"testState after going back");
ok(aEvent.state, "Event should have a state property.");
is(JSON.stringify(tab.linkedBrowser.contentWindow.history.state), JSON.stringify({obj1:1}),
@ -33,8 +33,7 @@ function checkState(tab) {
doc.body.appendChild(elem);
tab.linkedBrowser.goForward();
}
else if (popStateCount == 1) {
} else if (popStateCount == 1) {
popStateCount++;
// When content fires a PopStateEvent and we observe it from a chrome event
// listener (as we do here, and, thankfully, nowhere else in the tree), the
@ -64,7 +63,7 @@ function checkState(tab) {
// Set some state in the page's window. When we go back(), the page should
// be retrieved from bfcache, and this state should still be there.
tab.linkedBrowser.contentWindow.testState = 'foo';
tab.linkedBrowser.contentWindow.testState = "foo";
// Now go back. This should trigger the popstate event handler above.
tab.linkedBrowser.goBack();

Просмотреть файл

@ -19,10 +19,10 @@ function test() {
}
function getSessionstorejsModificationTime() {
let file = getSessionstoreFile();
if (file.exists())
if (file.exists()) {
return file.lastModifiedTime;
else
return -1;
}
return -1;
}
// delete existing sessionstore.js, to make sure we're not reading
@ -49,7 +49,7 @@ function test() {
promiseBrowserLoaded(tab.linkedBrowser).then(() => {
// step1: the above has triggered some saveStateDelayed(), sleep until
// it's done, and get the initial sessionstore.js mtime
setTimeout(function step1(e) {
setTimeout(function step1() {
let mtime1 = getSessionstorejsModificationTime();
isnot(mtime1, mtime0, "initial sessionstore.js update");
@ -57,7 +57,7 @@ function test() {
// or content scrolling
gBrowser.selectedTab = tab;
tab.linkedBrowser.contentWindow.scrollTo(1100, 1200);
setTimeout(function step2(e) {
setTimeout(function step2() {
let mtime2 = getSessionstorejsModificationTime();
is(mtime2, mtime1,
"tab selection and scrolling: sessionstore.js not updated");

Просмотреть файл

@ -19,8 +19,8 @@ function test() {
};
var theWin = openDialog(location, "", "chrome,all,dialog=no");
theWin.addEventListener("load", function () {
executeSoon(function () {
theWin.addEventListener("load", function() {
executeSoon(function() {
var gotError = false;
try {
ss.setWindowState(theWin, JSON.stringify(state), true);

Просмотреть файл

@ -145,7 +145,7 @@ function test() {
// be in a non-userTypedValue case, while others should still have
// userTypedValue and userTypedClear set.
gBrowser.addTabsProgressListener({
onLocationChange: function (aBrowser) {
onLocationChange(aBrowser) {
if (uris.indexOf(aBrowser.currentURI.spec) > -1) {
gBrowser.removeTabsProgressListener(this);
firstLocationChange();
@ -194,9 +194,9 @@ function test() {
let inputText = "example.org";
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1) , {});
EventUtils.synthesizeKey(inputText.slice(-1), {});
executeSoon(function () {
executeSoon(function() {
is(browser.userTypedValue, "example.org",
"userTypedValue was set when changing URLBar value");
ok(!browser.didStartLoadSinceLastUserTyping(),

Просмотреть файл

@ -10,7 +10,7 @@ function test() {
waitForExplicitFinish();
whenNewWindowLoaded({ private: false }, function (window_B) {
whenNewWindowLoaded({ private: false }, function(window_B) {
waitForFocus(function() {
// Add identifying information to window_B
ss.setWindowValue(window_B, uniqKey, uniqVal);

Просмотреть файл

@ -53,12 +53,11 @@ function test() {
} else {
info("waiting for the current window to become active");
setTimeout(pollMostRecentWindow, 0);
window.focus(); //XXX Why is this needed?
window.focus(); // XXX Why is this needed?
}
}
pollMostRecentWindow();
}
else {
} else {
browserWindowsCount(1);
ok(!window.closed, "Restoring the old state should have left this window open");
Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");

Просмотреть файл

@ -55,13 +55,13 @@ function openWinWithCb(cb, argURIs, expectedURIs) {
var win = openDialog(getBrowserURL(), "_blank",
"chrome,all,dialog=no", argURIs.join("|"));
win.addEventListener("load", function () {
win.addEventListener("load", function() {
info("the window loaded");
var expectedLoads = expectedURIs.length;
win.gBrowser.addTabsProgressListener({
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
if (aRequest &&
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
@ -70,7 +70,7 @@ function openWinWithCb(cb, argURIs, expectedURIs) {
win.gBrowser.removeTabsProgressListener(this);
info("all tabs loaded");
is(win.gBrowser.tabs.length, expectedURIs.length, "didn't load any unexpected tabs");
executeSoon(function () {
executeSoon(function() {
cb(win);
});
}

Просмотреть файл

@ -8,7 +8,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -24,7 +24,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
loadCount++;
// We'll make sure that the loads we get come from pinned tabs or the

Просмотреть файл

@ -9,7 +9,7 @@ add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
Services.prefs.setBoolPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND, true);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
Services.prefs.clearUserPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND);
});
@ -25,7 +25,7 @@ add_task(function* test() {
], selected: 5 }] };
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
// get the tab
let tab;
for (let i = 0; i < window.gBrowser.tabs.length; i++) {

Просмотреть файл

@ -8,7 +8,7 @@ requestLongerTimeout(2);
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -63,7 +63,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
loadCount++;
if (aBrowser.currentURI.spec == state1.windows[0].tabs[2].entries[0].url)

Просмотреть файл

@ -6,7 +6,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -30,7 +30,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
loadCount++;
let expected = expectedCounts[loadCount - 1];

Просмотреть файл

@ -6,7 +6,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -35,7 +35,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
if (++loadCount == numTabs) {
// We don't actually care about load order in this test, just that they all
// do load.

Просмотреть файл

@ -6,7 +6,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});

Просмотреть файл

@ -6,7 +6,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -31,7 +31,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
loadCount++;
let expected = expectedCounts[loadCount - 1];

Просмотреть файл

@ -6,7 +6,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -30,7 +30,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
// When loadCount == 2, we'll also restore state2 into the window
if (++loadCount == 2) {
ss.setWindowState(window, JSON.stringify(state2), false);

Просмотреть файл

@ -6,7 +6,7 @@ const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
add_task(function* test() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
@ -30,7 +30,7 @@ add_task(function* test() {
let loadCount = 0;
let promiseRestoringTabs = new Promise(resolve => {
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
gProgressListener.setCallback(function(aBrowser, aNeedRestore, aRestoring, aRestored) {
// When loadCount == 2, we'll also restore state2 into the window
if (++loadCount == 2) {
executeSoon(() => ss.setWindowState(window, JSON.stringify(state2), true));

Просмотреть файл

@ -8,7 +8,7 @@ function observeOneRestore(callback) {
Services.obs.removeObserver(onRestore, topic);
callback();
}, topic, false);
};
}
function test() {
waitForExplicitFinish();
@ -37,10 +37,10 @@ function test() {
observeOneRestore(function() {
let testWindow = Services.wm.getEnumerator("navigator:browser").getNext();
is(testWindow.gBrowser.visibleTabs.length, 1, "only restored 1 visible tab");
let tabs = testWindow.gBrowser.tabs;
ok(!tabs[0].hidden, "first is still visible");
ok(tabs[1].hidden, "second tab is still hidden");
ok(tabs[2].hidden, "third tab is now hidden");
let restoredTabs = testWindow.gBrowser.tabs;
ok(!restoredTabs[0].hidden, "first is still visible");
ok(restoredTabs[1].hidden, "second tab is still hidden");
ok(restoredTabs[2].hidden, "third tab is now hidden");
// Restore the original state and clean up now that we're done
gBrowser.removeTab(hiddenTab);

Просмотреть файл

@ -9,7 +9,7 @@ function test() {
waitForExplicitFinish();
newWindowWithState(state, function (win) {
newWindowWithState(state, function(win) {
registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
is(win.gBrowser.tabs.length, 2, "two tabs were restored");
@ -27,7 +27,7 @@ function newWindowWithState(state, callback) {
let win = window.openDialog(getBrowserURL(), "_blank", opts);
win.addEventListener("load", function() {
executeSoon(function () {
executeSoon(function() {
win.addEventListener("SSWindowStateReady", function() {
promiseTabRestored(win.gBrowser.tabs[0]).then(() => callback(win));
}, {once: true});

Просмотреть файл

@ -58,7 +58,7 @@ tests.push({
extra: false,
close: false,
checkWinLin: checkNoWindowsGenerator(1),
checkOSX: function(aPreviousState, aCurState) {
checkOSX(aPreviousState, aCurState) {
is(aCurState, aPreviousState, "test #1: closed window state is unchanged");
}
});
@ -118,8 +118,7 @@ function test() {
function runNextTestOrFinish() {
if (tests.length) {
setupForTest(tests.shift())
}
else {
} else {
// some state is cleaned up at the end of each test, but not all
["browser.tabs.warnOnClose", "browser.startup.page"].forEach(function(p) {
if (gPrefService.prefHasUserValue(p))
@ -166,7 +165,7 @@ function onStateRestored(aSubject, aTopic, aData) {
if (shouldPinTab)
newWin.gBrowser.pinTab(newWin.gBrowser.selectedTab);
newWin.addEventListener("unload", function () {
newWin.addEventListener("unload", function() {
onWindowUnloaded();
}, {once: true});
// Open a new tab as well. On Windows/Linux this will be restored when the
@ -179,15 +178,13 @@ function onStateRestored(aSubject, aTopic, aData) {
newTab.linkedBrowser.addEventListener("load", function() {
if (shouldCloseTab == "one") {
newWin.gBrowser.removeTab(newTab2);
}
else if (shouldCloseTab == "both") {
} else if (shouldCloseTab == "both") {
newWin.gBrowser.removeTab(newTab);
newWin.gBrowser.removeTab(newTab2);
}
newWin.BrowserTryToCloseWindow();
}, {capture: true, once: true});
}
else {
} else {
newWin.BrowserTryToCloseWindow();
}
});
@ -214,7 +211,7 @@ function onWindowUnloaded() {
// Now we want to open a new window
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:mozilla");
newWin.addEventListener("load", function(aEvent) {
newWin.gBrowser.selectedBrowser.addEventListener("load", function () {
newWin.gBrowser.selectedBrowser.addEventListener("load", function() {
// Good enough for checking the state
afterTestCallback(previousClosedWindowData, ss.getClosedWindowData());
afterTestCleanup(newWin);

Просмотреть файл

@ -11,8 +11,6 @@ function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
let startedTest = false;
// wasLoaded will be used to keep track of tabs that have already had SSTabRestoring
// fired for them.
let wasLoaded = { };
@ -87,8 +85,7 @@ function test() {
// then the test is successful.
try {
ss.deleteTabValue(tab, "baz");
}
catch (e) {
} catch (e) {
ok(false, "no error calling deleteTabValue - " + e);
}

Просмотреть файл

@ -16,14 +16,14 @@ function test() {
waitForExplicitFinish();
newWindowWithState(state, function (win) {
newWindowWithState(state, function(win) {
registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
is(gBrowser.tabs.length, 1, "The total number of tabs should be 1");
is(gBrowser.visibleTabs.length, 1, "The total number of visible tabs should be 1");
executeSoon(function () {
waitForFocus(function () {
executeSoon(function() {
waitForFocus(function() {
middleClickTest(win);
finish();
}, win);
@ -64,7 +64,7 @@ function newWindowWithState(state, callback) {
callback(win);
}, {capture: true, once: true});
executeSoon(function () {
executeSoon(function() {
ss.setWindowState(win, JSON.stringify(state), true);
});
}, {once: true});

Просмотреть файл

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
var state = {windows:[{tabs:[
var windowState = {windows:[{tabs:[
{entries:[{url:"http://example.com#1", triggeringPrincipal_base64}]},
{entries:[{url:"http://example.com#2", triggeringPrincipal_base64}]},
{entries:[{url:"http://example.com#3", triggeringPrincipal_base64}]},
@ -16,13 +16,13 @@ function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
registerCleanupFunction(function () {
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
});
// First stage: restoreHiddenTabs = true
// Second stage: restoreHiddenTabs = false
test_loadTabs(true, function () {
test_loadTabs(true, function() {
test_loadTabs(false, finish);
});
}
@ -33,7 +33,7 @@ function test_loadTabs(restoreHiddenTabs, callback) {
let expectedTabs = restoreHiddenTabs ? 8 : 4;
let firstProgress = true;
newWindowWithState(state, function (win, needsRestore, isRestoring) {
newWindowWithState(windowState, function(win, needsRestore, isRestoring) {
if (firstProgress) {
firstProgress = false;
is(isRestoring, 3, "restoring 3 tabs concurrently");
@ -56,32 +56,32 @@ function test_loadTabs(restoreHiddenTabs, callback) {
}
var TabsProgressListener = {
init: function (win) {
init(win) {
this.window = win;
Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
},
uninit: function () {
uninit() {
Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
delete this.window;
delete this.callback;
},
setCallback: function (callback) {
setCallback(callback) {
this.callback = callback;
},
observe: function (browser) {
observe(browser) {
TabsProgressListener.onRestored(browser);
},
onRestored: function (browser) {
onRestored(browser) {
if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING)
this.callback.apply(null, [this.window].concat(this.countTabs()));
},
countTabs: function () {
countTabs() {
let needsRestore = 0, isRestoring = 0;
for (let i = 0; i < this.window.gBrowser.tabs.length; i++) {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше