This commit is contained in:
Ryan VanderMeulen 2015-05-22 11:11:20 -04:00
Родитель 6f209120d4 0b24acdc8b
Коммит 14cbd0dc83
218 изменённых файлов: 1480 добавлений и 6791 удалений

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

@ -307,11 +307,19 @@ function onSearchSubmit(aEvent)
if (engineName && searchTerms.length > 0) {
// Send an event that will perform a search and Firefox Health Report will
// record that a search from about:home has occurred.
let useNewTab = aEvent && aEvent.button == 1;
let eventData = {
engineName: engineName,
searchTerms: searchTerms,
useNewTab: useNewTab,
originalEvent: {
target: {
ownerDocument: null
},
shiftKey: aEvent.shiftKey,
ctrlKey: aEvent.ctrlKey,
metaKey: aEvent.metaKey,
altKey: aEvent.altKey,
button: aEvent.button,
},
};
if (searchText.hasAttribute("selection-index")) {

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

@ -192,7 +192,8 @@ let gIntro = {
for (let i = 1; i <= MAX_PARAGRAPH_ID; i++) {
try {
this._paragraphs.push(newTabString("intro.paragraph" + i, substringMappings[i]));
let name = "intro.paragraph" + i + (i == 4 ? ".2" : "");
this._paragraphs.push(newTabString(name, substringMappings[i]));
} catch (ex) {
// Paragraph with this ID doesn't exist so continue
}

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

@ -54,7 +54,16 @@ let gSearch = {
engineName: this.currentEngineName,
searchString: searchStr,
whence: "newtab",
useNewTab: useNewTab,
originalEvent: {
target: {
ownerDocument: null
},
shiftKey: event.shiftKey,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
altKey: event.altKey,
button: event.button,
},
}
if (searchText.hasAttribute("selection-index")) {

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

@ -19,9 +19,11 @@
"chai": false,
"console": false,
"jQuery": false,
"loop": false,
"loop": true,
"MozActivity": false,
"mozRTCSessionDescription": false,
"OT": false,
"performance": false,
"Promise": false,
"React": false,
"sinon": false
@ -35,9 +37,11 @@
// Eslint built-in rules are documented at <http://eslint.org/docs/rules/>
"camelcase": 0, // TODO: Remove (use default)
"consistent-return": 0, // TODO: Remove (use default)
dot-location: 0, // [2, property],
"eqeqeq": 0, // TBD. Might need to be separate for content & chrome
"global-strict": 0, // Leave as zero (this will be unsupported in eslint 1.0.0)
"key-spacing": 0, // TODO: Remove (use default)
"linebreak-style": [2, "unix"],
"new-cap": 0, // TODO: Remove (use default)
"no-catch-shadow": 0, // TODO: Remove (use default)
"no-console": 0, // Leave as 0. We use console logging in content code.
@ -50,8 +54,8 @@
"no-return-assign": 0, // TODO: Remove (use default)
"no-shadow": 0, // TODO: Remove (use default)
"no-spaced-func": 0, // TODO: Remove (use default)
"no-undef": 0, // TODO: Remove (use default)
"no-underscore-dangle": 0, // Leave as 0. Commonly used for private variables.
"no-unneeded-ternary": 2,
"no-unused-expressions": 0, // TODO: Remove (use default)
"no-unused-vars": 0, // TODO: Remove (use default)
"no-use-before-define": 0, // TODO: Remove (use default)

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

@ -0,0 +1,64 @@
// This file defines additional items and rules specific for gecko files.
// This is applied on top of the basic .eslintrc for gecko specific directories
// e.g. the modules directory.
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"globals": {
// Gecko + Loop Globals.
"CardDavImporter": true,
"Chat": false,
"ChromeWorker": false,
"CommonUtils": false,
"Components": false,
"convertToRTCStatsReport": false,
"CustomizableUI": false,
"deriveHawkCredentials": false,
"eventEmitter": false,
"FxAccountsOAuthClient": false,
"FxAccountsProfileClient": false,
"gBrowser": false,
"gDNSService": false,
"gLoopBundle": false,
"GoogleImporter": true,
"gWM": false,
"HawkClient": false,
"injectLoopAPI": true,
"Iterator": false,
"Log": false,
"log": true,
"LOOP_SESSION_TYPE": true,
"LoopCalls": true,
"LoopContacts": true,
"loopCrypto": false,
"LoopRooms": true,
"LoopRoomsCache": true,
"LoopStorage": true,
"MozLoopPushHandler": true,
"MozLoopService": true,
"OS": false,
"roomsPushNotification": true,
"Services": false,
"Social": false,
"SocialShare": false,
"Task": false,
"UITour": false,
"XPCOMUtils": false,
"uuidgen": true,
// Test Related
"Assert": false,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
}
}

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

@ -2,9 +2,6 @@
* 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/. */
/* jshint esnext:true */
/* global loop:true, hawk, deriveHawkCredentials */
var loop = loop || {};
loop.Client = (function($) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/*jshint newcap:false*/
/*global loop:true, React */
var loop = loop || {};
loop.contacts = (function(_, mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/*jshint newcap:false*/
/*global loop:true, React */
var loop = loop || {};
loop.contacts = (function(_, mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false, esnext:true */
/* global loop:true, React */
var loop = loop || {};
loop.conversation = (function(mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false, esnext:true */
/* global loop:true, React */
var loop = loop || {};
loop.conversation = (function(mozL10n) {
"use strict";

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -1,11 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* global loop:true, React */
var loop = loop || {};
loop.conversationViews = (function(mozL10n) {

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

@ -1,11 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* global loop:true, React */
var loop = loop || {};
loop.conversationViews = (function(mozL10n) {

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/*jshint newcap:false*/
/*global loop:true, React */
var loop = loop || {};
loop.panel = (function(_, mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/*jshint newcap:false*/
/*global loop:true, React */
var loop = loop || {};
loop.panel = (function(_, mozL10n) {
"use strict";

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
var loop = loop || {};
loop.roomViews = (function(mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
var loop = loop || {};
loop.roomViews = (function(mozL10n) {
"use strict";

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.actions = (function() {

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -2,7 +2,7 @@
* 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/. */
/* global loop:true */
/* global Components */
var loop = loop || {};
var inChrome = typeof Components != "undefined" && "utils" in Components;

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
/**
* The dispatcher for actions. This dispatches actions to stores registered
* for those actions.

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.FeedbackAPIClient = (function($, _) {
"use strict";

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -1,11 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.views = loop.shared.views || {};

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

@ -1,11 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.views = loop.shared.views || {};

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.mixins = (function() {

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.models = (function(l10n) {

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.OTSdkDriver = (function() {

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -2,7 +2,7 @@
* 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/. */
/* global loop:true */
/* global Components */
var loop = loop || {};
loop.shared = loop.shared || {};

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

@ -2,8 +2,6 @@
* 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/. */
/* jshint unused:false */
var loop = loop || {};
loop.validate = (function() {
"use strict";

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

@ -1,11 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.views = (function(_, l10n) {

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

@ -1,11 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
var loop = loop || {};
loop.shared = loop.shared || {};
loop.shared.views = (function(_, l10n) {

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.CallConnectionWebSocket = (function() {
"use strict";

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

@ -1,17 +1,3 @@
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
}
"extends": "../.eslintrc-gecko"
}

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

@ -190,7 +190,6 @@ let MozLoopServiceInternal = {
// Default to 5 seconds
return 5000;
}
return initialDelay;
},
/**

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

@ -1,4 +1,6 @@
/** @jsx React.DOM */
/* 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/. */
var loop = loop || {};
loop.fxOSMarketplaceViews = (function() {

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

@ -1,4 +1,6 @@
/** @jsx React.DOM */
/* 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/. */
var loop = loop || {};
loop.fxOSMarketplaceViews = (function() {

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

@ -2,7 +2,6 @@
* 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/. */
var loop = loop || {};
/**

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.store = loop.store || {};

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
var loop = loop || {};
loop.StandaloneClient = (function($) {
"use strict";

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

@ -2,8 +2,6 @@
* 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/. */
/* global loop:true */
/**
* The StandaloneMozLoop implementation reflects that of the mozLoop API for Loop
* in the desktop code. Not all functions are implemented.

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* global loop:true, React */
/* jshint newcap:false, maxlen:false */
var loop = loop || {};
loop.standaloneRoomViews = (function(mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* global loop:true, React */
/* jshint newcap:false, maxlen:false */
var loop = loop || {};
loop.standaloneRoomViews = (function(mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* global loop:true, React, MozActivity */
/* jshint newcap:false, maxlen:false */
var loop = loop || {};
loop.webapp = (function($, _, OT, mozL10n) {
"use strict";

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

@ -1,12 +1,7 @@
/** @jsx React.DOM */
/* 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/. */
/* global loop:true, React, MozActivity */
/* jshint newcap:false, maxlen:false */
var loop = loop || {};
loop.webapp = (function($, _, OT, mozL10n) {
"use strict";

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

@ -12,8 +12,8 @@
},
"dependencies": {},
"devDependencies": {
"eslint": "0.20.x",
"eslint-plugin-react": "2.2.x",
"eslint": "0.21.x",
"eslint-plugin-react": "2.3.x",
"express": "4.x"
},
"scripts": {

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

@ -2,13 +2,10 @@
* 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/. */
/*global loop, sinon, it, beforeEach, afterEach, describe */
var expect = chai.expect;
describe("loop.Client", function() {
"use strict";
var expect = chai.expect;
var sandbox,
callback,
client,

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

@ -2,15 +2,12 @@
* 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/. */
/*jshint newcap:false*/
/*global loop, sinon */
describe("loop.contacts", function() {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
describe("loop.contacts", function() {
"use strict";
var fakeAddContactButtonText = "Fake Add Contact";
var fakeEditContactButtonText = "Fake Edit Contact";
var fakeDoneButtonText = "Fake Done";

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

@ -1,10 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var expect = chai.expect;
describe("loop.store.ConversationAppStore", function () {
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var sandbox, dispatcher;

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

@ -1,11 +1,12 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var expect = chai.expect;
describe("loop.conversationViews", function () {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var sharedView = loop.shared.views;
var sandbox, view, dispatcher, contact, fakeAudioXHR;

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

@ -2,13 +2,11 @@
* 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/. */
/* global loop, sinon, React, TestUtils */
var expect = chai.expect;
describe("loop.conversation", function() {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
var sharedModels = loop.shared.models,
fakeWindow,
sandbox;

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

@ -82,7 +82,7 @@
describe("Uncaught Error Check", function() {
it("should load the tests without errors", function() {
expect(uncaughtError && uncaughtError.message).to.be.undefined;
chai.expect(uncaughtError && uncaughtError.message).to.be.undefined;
});
});

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

@ -2,17 +2,14 @@
* 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/. */
/*jshint newcap:false*/
/*global loop, sinon */
describe("loop.panel", function() {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
describe("loop.panel", function() {
"use strict";
var sandbox, notifications;
var fakeXHR, fakeWindow, fakeMozLoop;
var requests = [];
@ -925,8 +922,7 @@ describe("loop.panel", function() {
TestUtils.findRenderedDOMComponentWithClass(view, "terms-service");
});
it("should not render when the value of loop.seenToS is set to 'seen'",
function(done) {
it("should not render when the value of loop.seenToS is set to 'seen'", function() {
navigator.mozLoop.getLoopPref = function(key) {
return {
"gettingStarted.seen": true,
@ -934,11 +930,12 @@ describe("loop.panel", function() {
}[key];
};
try {
var view = TestUtils.renderIntoDocument(
React.createElement(loop.panel.ToSView));
expect(function() {
TestUtils.findRenderedDOMComponentWithClass(view, "terms-service");
} catch (err) {
done();
}
}).to.Throw(/not find/);
});
it("should render when the value of loop.gettingStarted.seen is false",

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

@ -1,10 +1,13 @@
var expect = chai.expect;
/* jshint newcap:false */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
describe("loop.roomViews", function () {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var ROOM_STATES = loop.store.ROOM_STATES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;

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

@ -1,17 +1,35 @@
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
"extends": "../../.eslintrc-gecko",
"globals": {
// General test items.
"add_task": false,
"Cc": true,
"Ci": true,
"Cr": true,
"Cu": true,
"is": false,
"info": false,
"ok": false,
"registerCleanupFunction": false,
// head.js items
"HAWK_TOKEN_LENGTH": true,
"checkLoggedOutState": false,
"checkFxAOAuthTokenData": false,
"loadLoopPanel": false,
"getLoopString": false,
"gMozLoopAPI": true,
"mockDb": true,
"mockPushHandler": true,
"promiseDeletedOAuthParams": false,
"promiseOAuthGetRegistration": false,
"promiseOAuthParamsSetup": false,
"promiseObserverNotified": false,
"promiseTabLoadEvent": false,
"promiseWaitForCondition": false,
"resetFxA": true,
// Loop specific items
"MozLoopServiceInternal": true,
"LoopRoomsInternal": true,
"LoopUI": false,
}
}

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

@ -351,7 +351,7 @@ const mockDb = {
callback(null);
},
promise: function(method, ...params) {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
this[method](...params, (err, res) => err ? reject(err) : resolve(res));
});
}

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

@ -1,11 +1,11 @@
/* global chai, loop */
var expect = chai.expect;
var sharedActions = loop.shared.actions;
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
describe("loop.store.ActiveRoomStore", function () {
"use strict";
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var REST_ERRNOS = loop.shared.utils.REST_ERRNOS;
var ROOM_STATES = loop.store.ROOM_STATES;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;

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

@ -1,11 +1,10 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var expect = chai.expect;
describe("loop.store.ConversationStore", function () {
"use strict";
var expect = chai.expect;
var CALL_STATES = loop.store.CALL_STATES;
var WS_STATES = loop.store.WS_STATES;
var CALL_TYPES = loop.shared.utils.CALL_TYPES;

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

@ -2,13 +2,10 @@
* 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/. */
/* global loop, sinon */
var expect = chai.expect;
describe("loop.crypto", function() {
"use strict";
var expect = chai.expect;
var sandbox, oldCrypto;
beforeEach(function() {

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

@ -1,11 +1,10 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var expect = chai.expect;
describe("loop.Dispatcher", function () {
"use strict";
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var dispatcher, sandbox;

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

@ -2,13 +2,10 @@
* 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/. */
/*global loop, sinon, it, beforeEach, afterEach, describe */
var expect = chai.expect;
describe("loop.FeedbackAPIClient", function() {
"use strict";
var expect = chai.expect;
var sandbox,
fakeXHR,
requests = [];

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

@ -1,11 +1,11 @@
/* global chai, loop */
var expect = chai.expect;
var sharedActions = loop.shared.actions;
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
describe("loop.store.FeedbackStore", function () {
"use strict";
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var FEEDBACK_STATES = loop.store.FEEDBACK_STATES;
var sandbox, dispatcher, store, feedbackClient;

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

@ -2,8 +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/. */
/*global loop, sinon, React */
/* jshint newcap:false */
describe("loop.shared.views.FeedbackView", function() {
"use strict";
var expect = chai.expect;
var l10n = navigator.mozL10n || document.mozL10n;
@ -12,10 +12,6 @@ var sharedActions = loop.shared.actions;
var sharedViews = loop.shared.views;
var FEEDBACK_STATES = loop.store.FEEDBACK_STATES;
describe("loop.shared.views.FeedbackView", function() {
"use strict";
var sandbox, comp, dispatcher, fakeFeedbackClient, feedbackStore;
beforeEach(function() {

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

@ -1,13 +1,12 @@
/* global chai, loop */
var expect = chai.expect;
var sharedActions = loop.shared.actions;
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
describe("loop.store.FxOSActiveRoomStore", function () {
"use strict";
var ROOM_STATES = loop.store.ROOM_STATES;
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var sandbox;
var dispatcher;
var fakeMozLoop;

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

@ -79,7 +79,7 @@
<script>
describe("Uncaught Error Check", function() {
it("should load the tests without errors", function() {
expect(uncaughtError && uncaughtError.message).to.be.undefined;
chai.expect(uncaughtError && uncaughtError.message).to.be.undefined;
});
});

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

@ -2,16 +2,13 @@
* 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/. */
/* global loop, sinon */
/* jshint newcap:false */
var expect = chai.expect;
describe("loop.shared.mixins", function() {
"use strict";
var expect = chai.expect;
var sandbox;
var sharedMixins = loop.shared.mixins;
var TestUtils = React.addons.TestUtils;
var ROOM_STATES = loop.store.ROOM_STATES;
beforeEach(function() {

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

@ -2,13 +2,11 @@
* 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/. */
/* global loop, sinon */
var expect = chai.expect;
describe("loop.shared.models", function() {
"use strict";
var expect = chai.expect;
var l10n = navigator.mozL10n || document.mozL10n;
var sharedModels = loop.shared.models, sandbox, fakeXHR,
requests = [], fakeSDK, fakeMozLoop, fakeSession, fakeSessionData;

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

@ -1,11 +1,10 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var expect = chai.expect;
describe("loop.OTSdkDriver", function () {
"use strict";
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var STREAM_PROPERTIES = loop.shared.utils.STREAM_PROPERTIES;

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

@ -2,14 +2,14 @@
* 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/. */
var expect = chai.expect;
describe("loop.store", function () {
"use strict";
var expect = chai.expect;
var dispatcher;
var sandbox;
var sharedActions = loop.shared.actions;
var TestUtils = React.addons.TestUtils;
beforeEach(function() {
sandbox = sinon.sandbox.create();

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

@ -2,14 +2,10 @@
* 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/. */
/* global loop, sinon */
/* jshint newcap:false */
var expect = chai.expect;
describe("loop.shared.utils", function() {
"use strict";
var expect = chai.expect;
var sandbox;
var sharedUtils = loop.shared.utils;

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

@ -1,13 +1,11 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*global chai, validate */
var expect = chai.expect;
describe("Validator", function() {
"use strict";
var expect = chai.expect;
// test helpers
function create(dependencies, values) {
var validator = new loop.validate.Validator(dependencies);

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

@ -2,16 +2,13 @@
* 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/. */
/*global loop, sinon, React */
/* jshint newcap:false */
describe("loop.shared.views", function() {
"use strict";
var expect = chai.expect;
var l10n = navigator.mozL10n || document.mozL10n;
var TestUtils = React.addons.TestUtils;
describe("loop.shared.views", function() {
"use strict";
var sharedActions = loop.shared.actions;
var sharedModels = loop.shared.models;
var sharedViews = loop.shared.views;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;

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

@ -2,14 +2,10 @@
* 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/. */
/*global loop, sinon, it, beforeEach, afterEach, describe */
var expect = chai.expect;
describe("loop.CallConnectionWebSocket", function() {
"use strict";
var expect = chai.expect;
var WEBSOCKET_REASONS = loop.shared.utils.WEBSOCKET_REASONS;
var sandbox,

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

@ -73,7 +73,7 @@
<script>
describe("Uncaught Error Check", function() {
it("should load the tests without errors", function() {
expect(uncaughtError && uncaughtError.message).to.be.undefined;
chai.expect(uncaughtError && uncaughtError.message).to.be.undefined;
});
});

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

@ -2,18 +2,15 @@
* 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/. */
/*global loop, sinon, it, beforeEach, afterEach, describe*/
var expect = chai.expect;
describe("loop.standaloneMedia._MultiplexGum", function() {
"use strict";
var expect = chai.expect;
var defaultGum =
navigator.getUserMedia ||
navigator.mozGetUserMedia ||
navigator.webkitGetUserMedia ||
(window.TBPlugin && TBPlugin.getUserMedia);
(window.TBPlugin && window.TBPlugin.getUserMedia);
var sandbox;
var multiplexGum;

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

@ -1,9 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var expect = chai.expect;
describe("loop.store.StandaloneAppStore", function () {
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var sandbox, dispatcher;

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

@ -2,11 +2,10 @@
* 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/. */
var expect = chai.expect;
describe("loop.store.StandaloneMetricsStore", function() {
"use strict";
var expect = chai.expect;
var sandbox, dispatcher, store, fakeActiveRoomStore;
var sharedActions = loop.shared.actions;

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

@ -2,11 +2,10 @@
* 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/. */
var expect = chai.expect;
describe("loop.StandaloneMozLoop", function() {
"use strict";
var expect = chai.expect;
var sandbox, fakeXHR, requests, callback, mozLoop;
var fakeToken, fakeBaseServerUrl, fakeServerErrorDescription;

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

@ -2,13 +2,12 @@
* 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/. */
/* global loop, sinon */
var expect = chai.expect;
describe("loop.standaloneRoomViews", function() {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
var ROOM_STATES = loop.store.ROOM_STATES;
var FEEDBACK_STATES = loop.store.FEEDBACK_STATES;
var ROOM_INFO_FAILURES = loop.shared.utils.ROOM_INFO_FAILURES;

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

@ -2,13 +2,10 @@
* 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/. */
/*global loop, sinon, it, beforeEach, afterEach, describe, hawk */
var expect = chai.expect;
describe("loop.StandaloneClient", function() {
"use strict";
var expect = chai.expect;
var sandbox,
fakeXHR,
requests = [],

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

@ -2,14 +2,11 @@
* 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/. */
/* global loop, sinon */
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
describe("loop.webapp", function() {
"use strict";
var expect = chai.expect;
var TestUtils = React.addons.TestUtils;
var sharedActions = loop.shared.actions;
var sharedModels = loop.shared.models,
sharedViews = loop.shared.views,

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

@ -1,17 +1,36 @@
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
"extends": "../../.eslintrc-gecko",
"globals": {
// General xpcshell-test functions
"HttpServer": false,
"add_task": false,
"add_test": false,
"Ci": true,
"Cu": true,
"do_check_true": false,
"do_check_false": false,
"do_check_eq": false,
"do_get_profile": false,
"do_print": false,
"do_register_cleanup": false,
"do_throw": false,
"do_timeout": false,
"run_next_test": false,
// head.js items.
"MockWebSocketChannel": false,
"extend": true,
"getLoopString": false,
"kServerPushUrl": true,
"kEndPointUrl": true,
"loopCrypto": true,
"loopServer": true,
"mockPushHandler": true,
"setupFakeFxAUserProfile": false,
"setupFakeLoopServer": false,
"timerHandlers",
"waitForCondition": true,
// Loop specific items
"MozLoopServiceInternal": true,
"LoopRoomsInternal": true,
}
}

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

@ -126,7 +126,9 @@ add_task(function* setup_server() {
});
function returnRoomDetails(res, roomName) {
roomDetail.roomName = roomName;
var roomDetail = {
roomName: roomName
};
res.setStatusLine(null, 200, "OK");
res.write(JSON.stringify(roomDetail));
res.processAsync();

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

@ -53,14 +53,6 @@ add_task(function* setup_server() {
res.finish();
});
function returnRoomDetails(res, roomName) {
roomDetail.roomName = roomName;
res.setStatusLine(null, 200, "OK");
res.write(JSON.stringify(roomDetail));
res.processAsync();
res.finish();
}
function getJSONData(body) {
return JSON.parse(CommonUtils.readBytesFromInputStream(body));
}

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

@ -1,6 +1,5 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* global Services, Assert */
"use strict";

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

@ -1,6 +1,5 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*global XPCOMUtils, Services, Assert */
"use strict";
@ -65,7 +64,7 @@ function test_setLoopPref_non_coercible_type()
{
MozLoopService.setLoopPref(fakeCharPrefName, true);
ok(true, "Setting non-coercible type should not fail");
Assert.ok(true, "Setting non-coercible type should not fail");
}

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

@ -1,11 +1,8 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
/* global uncaughtError:true */
(function() {
"use strict";

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

@ -1,11 +1,8 @@
/** @jsx React.DOM */
/* 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/. */
/* jshint newcap:false */
/* global loop:true, React */
/* global uncaughtError:true */
(function() {
"use strict";

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

@ -158,6 +158,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "TabState",
"resource:///modules/sessionstore/TabState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TabStateCache",
"resource:///modules/sessionstore/TabStateCache.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TabStateFlusher",
"resource:///modules/sessionstore/TabStateFlusher.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource:///modules/sessionstore/Utils.jsm");
@ -653,6 +655,19 @@ let SessionStoreInternal = {
TabState.update(browser, aMessage.data);
this.saveStateDelayed(win);
if (aMessage.data.isFinal) {
// If this the final message we need to resolve all pending flush
// requests for the given browser as they might have been sent too
// late and will never respond. If they have been sent shortly after
// switching a browser's remoteness there isn't too much data to skip.
TabStateFlusher.resolveAll(browser);
} else if (aMessage.data.flushID) {
// This is an update kicked off by an async flush request. Notify the
// TabStateFlusher so that it can finish the request and notify its
// consumer that's waiting for the flush to be done.
TabStateFlusher.resolve(browser, aMessage.data.flushID);
}
// Handle any updates sent by the child after the tab was closed. This
// might be the final update as sent by the "unload" handler but also
// any async update message that was sent before the child unloaded.
@ -661,7 +676,7 @@ let SessionStoreInternal = {
// Update the closed tab's state. This will be reflected in its
// window's list of closed tabs as that refers to the same object.
TabState.copyFromCache({linkedBrowser: browser}, tabData.state);
TabState.copyFromCache(browser, tabData.state);
// Is this the tab's final message?
if (aMessage.data.isFinal) {
@ -691,7 +706,7 @@ let SessionStoreInternal = {
break;
case "SessionStore:restoreHistoryComplete":
// Notify the tabbrowser that the tab chrome has been restored.
let tabData = browser.__SS_data;
let tabData = TabState.collect(tab);
// wall-paper fix for bug 439675: make sure that the URL to be loaded
// is always visible in the address bar
@ -713,6 +728,7 @@ let SessionStoreInternal = {
// Restore the tab icon.
if ("image" in tabData) {
win.gBrowser.setIcon(tab, tabData.image);
TabStateCache.update(browser, {image: null});
}
let event = win.document.createEvent("Events");
@ -729,11 +745,16 @@ let SessionStoreInternal = {
// enter yet, then we just need to write that value to the URL bar without
// loading anything. This must happen after the load, since it will clear
// userTypedValue.
let tabData = browser.__SS_data;
let tabData = TabState.collect(tab);
if (tabData.userTypedValue && !tabData.userTypedClear) {
browser.userTypedValue = tabData.userTypedValue;
win.URLBarSetURI();
}
// Remove state we don't need any longer.
TabStateCache.update(browser, {
userTypedValue: null, userTypedClear: null
});
}
break;
case "SessionStore:restoreTabContentComplete":
@ -743,8 +764,6 @@ let SessionStoreInternal = {
Services.obs.notifyObservers(browser, NOTIFY_TAB_RESTORED, null);
}
delete browser.__SS_data;
SessionStoreInternal._resetLocalTabRestoringState(tab);
SessionStoreInternal.restoreNextTab();
@ -1410,7 +1429,6 @@ let SessionStoreInternal = {
*/
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser;
delete browser.__SS_data;
browser.removeEventListener("SwapDocShells", this);
browser.removeEventListener("oop-browser-crashed", this);
@ -1619,6 +1637,10 @@ let SessionStoreInternal = {
let tab = aWindow.gBrowser.getTabForBrowser(aBrowser);
this._resetLocalTabRestoringState(tab);
}
// The browser crashed so we might never receive flush responses.
// Resolve all pending flush requests for the crashed browser.
TabStateFlusher.resolveAll(aBrowser);
},
// Clean up data that has been closed a long time ago.
@ -1783,24 +1805,43 @@ let SessionStoreInternal = {
throw Components.Exception("Invalid window object: no gBrowser", Cr.NS_ERROR_INVALID_ARG);
}
// Flush all data queued in the content script because we will need that
// state to properly duplicate the given tab.
TabState.flush(aTab.linkedBrowser);
// Create a new tab.
let newTab = aTab == aWindow.gBrowser.selectedTab ?
aWindow.gBrowser.addTab(null, {relatedToCurrent: true, ownerTab: aTab}) :
aWindow.gBrowser.addTab();
// Duplicate the tab state
// Set tab title to "Connecting..." and start the throbber to pretend we're
// doing something while actually waiting for data from the frame script.
aWindow.gBrowser.setTabTitleLoading(newTab);
newTab.setAttribute("busy", "true");
// Collect state before flushing.
let tabState = TabState.clone(aTab);
// Flush to get the latest tab state to duplicate.
let browser = aTab.linkedBrowser;
TabStateFlusher.flush(browser).then(() => {
// The new tab might have been closed in the meantime.
if (newTab.closing || !newTab.linkedBrowser) {
return;
}
// Update state with flushed data. We can't use TabState.clone() here as
// the tab to duplicate may have already been closed. In that case we
// only have access to the <xul:browser>.
let options = {includePrivateData: true};
TabState.copyFromCache(browser, tabState, options);
tabState.index += aDelta;
tabState.index = Math.max(1, Math.min(tabState.index, tabState.entries.length));
tabState.pinned = false;
let newTab = aTab == aWindow.gBrowser.selectedTab ?
aWindow.gBrowser.addTab(null, {relatedToCurrent: true, ownerTab: aTab}) :
aWindow.gBrowser.addTab();
// Restore the state into the new tab.
this.restoreTab(newTab, tabState, {
restoreImmediately: true /* Load this tab right away. */
});
});
return newTab;
},
@ -1948,15 +1989,7 @@ let SessionStoreInternal = {
},
getTabValue: function ssi_getTabValue(aTab, aKey) {
let data = {};
if (aTab.__SS_extdata) {
data = aTab.__SS_extdata;
}
else if (aTab.linkedBrowser.__SS_data && aTab.linkedBrowser.__SS_data.extData) {
// If the tab hasn't been fully restored, get the data from the to-be-restored data
data = aTab.linkedBrowser.__SS_data.extData;
}
return data[aKey] || "";
return (aTab.__SS_extdata || {})[aKey] || "";
},
setTabValue: function ssi_setTabValue(aTab, aKey, aStringValue) {
@ -1966,36 +1999,17 @@ let SessionStoreInternal = {
// If the tab hasn't been restored, then set the data there, otherwise we
// could lose newly added data.
let saveTo;
if (aTab.__SS_extdata) {
saveTo = aTab.__SS_extdata;
}
else if (aTab.linkedBrowser.__SS_data && aTab.linkedBrowser.__SS_data.extData) {
saveTo = aTab.linkedBrowser.__SS_data.extData;
}
else {
if (!aTab.__SS_extdata) {
aTab.__SS_extdata = {};
saveTo = aTab.__SS_extdata;
}
saveTo[aKey] = aStringValue;
aTab.__SS_extdata[aKey] = aStringValue;
this.saveStateDelayed(aTab.ownerDocument.defaultView);
},
deleteTabValue: function ssi_deleteTabValue(aTab, aKey) {
// We want to make sure that if data is accessed early, we attempt to delete
// that data from __SS_data as well. Otherwise we'll throw in cases where
// data can be set or read.
let deleteFrom;
if (aTab.__SS_extdata) {
deleteFrom = aTab.__SS_extdata;
}
else if (aTab.linkedBrowser.__SS_data && aTab.linkedBrowser.__SS_data.extData) {
deleteFrom = aTab.linkedBrowser.__SS_data.extData;
}
if (deleteFrom && aKey in deleteFrom) {
delete deleteFrom[aKey];
if (aTab.__SS_extdata && aKey in aTab.__SS_extdata) {
delete aTab.__SS_extdata[aKey];
this.saveStateDelayed(aTab.ownerDocument.defaultView);
}
},
@ -2819,7 +2833,6 @@ let SessionStoreInternal = {
// keep the data around to prevent dataloss in case
// a tab gets closed before it's been properly restored
browser.__SS_data = tabData;
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
browser.setAttribute("pending", "true");
tab.setAttribute("pending", "true");
@ -2831,7 +2844,14 @@ let SessionStoreInternal = {
storage: tabData.storage || null,
formdata: tabData.formdata || null,
disallow: tabData.disallow || null,
pageStyle: tabData.pageStyle || null
pageStyle: tabData.pageStyle || null,
// This information is only needed until the tab has finished restoring.
// When that's done it will be removed from the cache and we always
// collect it in TabState._collectBaseTabData().
image: tabData.image || "",
userTypedValue: tabData.userTypedValue || "",
userTypedClear: tabData.userTypedClear || 0
});
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory",

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

@ -55,8 +55,8 @@ this.TabState = Object.freeze({
return TabStateInternal.clone(tab);
},
copyFromCache: function (tab, tabData, options) {
TabStateInternal.copyFromCache(tab, tabData, options);
copyFromCache(browser, tabData, options) {
TabStateInternal.copyFromCache(browser, tabData, options);
}
});
@ -165,43 +165,6 @@ let TabStateInternal = {
let tabData = {entries: [], lastAccessed: tab.lastAccessed };
let browser = tab.linkedBrowser;
if (!browser || !browser.currentURI) {
// can happen when calling this function right after .addTab()
return tabData;
}
if (browser.__SS_data) {
// Use the data to be restored when the tab hasn't been
// completely loaded. We clone the data, since we're updating it
// here and the caller may update it further.
tabData = Utils.shallowCopy(browser.__SS_data);
if (tab.pinned)
tabData.pinned = true;
else
delete tabData.pinned;
tabData.hidden = tab.hidden;
// If __SS_extdata is set then we'll use that since it might be newer.
if (tab.__SS_extdata)
tabData.extData = tab.__SS_extdata;
// If it exists but is empty then a key was likely deleted. In that case just
// delete extData.
if (tabData.extData && !Object.keys(tabData.extData).length)
delete tabData.extData;
return tabData;
}
// If there is a userTypedValue set, then either the user has typed something
// in the URL bar, or a new tab was opened with a URI to load. userTypedClear
// is used to indicate whether the tab was in some sort of loading state with
// userTypedValue.
if (browser.userTypedValue) {
tabData.userTypedValue = browser.userTypedValue;
tabData.userTypedClear = browser.userTypedClear;
} else {
delete tabData.userTypedValue;
delete tabData.userTypedClear;
}
if (tab.pinned)
tabData.pinned = true;
else
@ -211,10 +174,6 @@ let TabStateInternal = {
// Save tab attributes.
tabData.attributes = TabAttributes.get(tab);
// Store the tab icon.
let tabbrowser = tab.ownerDocument.defaultView.gBrowser;
tabData.image = tabbrowser.getIcon(tab);
if (tab.__SS_extdata)
tabData.extData = tab.__SS_extdata;
else if (tabData.extData)
@ -222,29 +181,50 @@ let TabStateInternal = {
// Copy data from the tab state cache only if the tab has fully finished
// restoring. We don't want to overwrite data contained in __SS_data.
this.copyFromCache(tab, tabData, options);
this.copyFromCache(browser, tabData, options);
// After copyFromCache() was called we check for properties that are kept
// in the cache only while the tab is pending or restoring. Once that
// happened those properties will be removed from the cache and will
// be read from the tab/browser every time we collect data.
// Store the tab icon.
if (!("image" in tabData)) {
let tabbrowser = tab.ownerDocument.defaultView.gBrowser;
tabData.image = tabbrowser.getIcon(tab);
}
// If there is a userTypedValue set, then either the user has typed something
// in the URL bar, or a new tab was opened with a URI to load. userTypedClear
// is used to indicate whether the tab was in some sort of loading state with
// userTypedValue.
if (!("userTypedValue" in tabData) && browser.userTypedValue) {
tabData.userTypedValue = browser.userTypedValue;
tabData.userTypedClear = browser.userTypedClear;
}
return tabData;
},
/**
* Copy tab data for the given |tab| from the cache to |tabData|.
* Copy data for the given |browser| from the cache to |tabData|.
*
* @param tab (xul:tab)
* The tab belonging to the given |tabData| object.
* @param browser (xul:browser)
* The browser belonging to the given |tabData| object.
* @param tabData (object)
* The tab data belonging to the given |tab|.
* @param options (object)
* {includePrivateData: true} to always include private data
*/
copyFromCache: function (tab, tabData, options = {}) {
let data = TabStateCache.get(tab.linkedBrowser);
copyFromCache(browser, tabData, options = {}) {
let data = TabStateCache.get(browser);
if (!data) {
return;
}
// The caller may explicitly request to omit privacy checks.
let includePrivateData = options && options.includePrivateData;
let isPinned = tabData.pinned || false;
for (let key of Object.keys(data)) {
let value = data[key];
@ -252,9 +232,9 @@ let TabStateInternal = {
// Filter sensitive data according to the current privacy level.
if (!includePrivateData) {
if (key === "storage") {
value = PrivacyFilter.filterSessionStorageData(value, tab.pinned);
value = PrivacyFilter.filterSessionStorageData(value, isPinned);
} else if (key === "formdata") {
value = PrivacyFilter.filterFormData(value, tab.pinned);
value = PrivacyFilter.filterFormData(value, isPinned);
}
}

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

@ -0,0 +1,122 @@
/* 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";
this.EXPORTED_SYMBOLS = ["TabStateFlusher"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Promise.jsm", this);
/**
* A module that enables async flushes. Updates from frame scripts are
* throttled to be sent only once per second. If an action wants a tab's latest
* state without waiting for a second then it can request an async flush and
* wait until the frame scripts reported back. At this point the parent has the
* latest data and the action can continue.
*/
this.TabStateFlusher = Object.freeze({
/**
* Requests an async flush for the given browser. Returns a promise that will
* resolve when we heard back from the content process and the parent has
* all the latest data.
*/
flush(browser) {
return TabStateFlusherInternal.flush(browser);
},
/**
* Resolves the flush request with the given flush ID.
*/
resolve(browser, flushID) {
TabStateFlusherInternal.resolve(browser, flushID);
},
/**
* Resolves all active flush requests for a given browser. This should be
* used when the content process crashed or the final update message was
* seen. In those cases we can't guarantee to ever hear back from the frame
* script so we just resolve all requests instead of discarding them.
*/
resolveAll(browser) {
TabStateFlusherInternal.resolveAll(browser);
}
});
let TabStateFlusherInternal = {
// Stores the last request ID.
_lastRequestID: 0,
// A map storing all active requests per browser.
_requests: new WeakMap(),
/**
* Requests an async flush for the given browser. Returns a promise that will
* resolve when we heard back from the content process and the parent has
* all the latest data.
*/
flush(browser) {
let id = ++this._lastRequestID;
let mm = browser.messageManager;
mm.sendAsyncMessage("SessionStore:flush", {id});
// Retrieve active requests for given browser.
let permanentKey = browser.permanentKey;
let perBrowserRequests = this._requests.get(permanentKey) || new Map();
return new Promise(resolve => {
// Store resolve() so that we can resolve the promise later.
perBrowserRequests.set(id, resolve);
// Update the flush requests stored per browser.
this._requests.set(permanentKey, perBrowserRequests);
});
},
/**
* Resolves the flush request with the given flush ID.
*/
resolve(browser, flushID) {
// Nothing to do if there are no pending flushes for the given browser.
if (!this._requests.has(browser.permanentKey)) {
return;
}
// Retrieve active requests for given browser.
let perBrowserRequests = this._requests.get(browser.permanentKey);
if (!perBrowserRequests.has(flushID)) {
return;
}
// Resolve the request with the given id.
let resolve = perBrowserRequests.get(flushID);
perBrowserRequests.delete(flushID);
resolve();
},
/**
* Resolves all active flush requests for a given browser. This should be
* used when the content process crashed or the final update message was
* seen. In those cases we can't guarantee to ever hear back from the frame
* script so we just resolve all requests instead of discarding them.
*/
resolveAll(browser) {
// Nothing to do if there are no pending flushes for the given browser.
if (!this._requests.has(browser.permanentKey)) {
return;
}
// Retrieve active requests for given browser.
let perBrowserRequests = this._requests.get(browser.permanentKey);
// Resolve all requests.
for (let resolve of perBrowserRequests.values()) {
resolve();
}
// Clear active requests.
perBrowserRequests.clear();
}
};

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

@ -106,6 +106,7 @@ let MessageListener = {
"SessionStore:restoreHistory",
"SessionStore:restoreTabContent",
"SessionStore:resetRestore",
"SessionStore:flush",
],
init: function () {
@ -137,6 +138,9 @@ let MessageListener = {
case "SessionStore:resetRestore":
gContentRestore.resetRestore();
break;
case "SessionStore:flush":
this.flush(data);
break;
default:
debug("received unknown message '" + name + "'");
break;
@ -192,6 +196,11 @@ let MessageListener = {
// Pretend that the load succeeded so that event handlers fire correctly.
sendAsyncMessage("SessionStore:restoreTabContentComplete", {epoch});
}
},
flush({id}) {
// Flush the message queue, send the latest updates.
MessageQueue.send({flushID: id});
}
};
@ -651,6 +660,8 @@ let MessageQueue = {
* @param options (object)
* {id: 123} to override the update ID used to accumulate data to send.
* {sync: true} to send data to the parent process synchronously.
* {flushID: 123} to specify that this is a flush
* {isFinal: true} to signal this is the final message sent on unload
*/
send: function (options = {}) {
// Looks like we have been called off a timeout after the tab has been
@ -667,6 +678,7 @@ let MessageQueue = {
let sync = options && options.sync;
let startID = (options && options.id) || this._id;
let flushID = (options && options.flushID) || 0;
// We use sendRpcMessage in the sync case because we may have been called
// through a CPOW. RPC messages are the only synchronous messages that the
@ -702,7 +714,7 @@ let MessageQueue = {
// Send all data to the parent process.
sendMessage("SessionStore:update", {
id: this._id, data, telemetry,
id: this._id, data, telemetry, flushID,
isFinal: options.isFinal || false,
epoch: gCurrentEpoch
});

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

@ -44,6 +44,7 @@ EXTRA_JS_MODULES.sessionstore = [
'TabAttributes.jsm',
'TabState.jsm',
'TabStateCache.jsm',
'TabStateFlusher.jsm',
'Utils.jsm',
]

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

@ -65,6 +65,9 @@ support-files =
[browser_aboutPrivateBrowsing.js]
[browser_aboutSessionRestore.js]
[browser_async_duplicate_tab.js]
[browser_async_flushes.js]
run-if = e10s && crashreporter
[browser_async_remove_tab.js]
run-if = e10s
[browser_attributes.js]

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

@ -3,10 +3,6 @@
"use strict";
let tmp = {};
Cu.import("resource:///modules/sessionstore/SessionSaver.jsm", tmp);
let {SessionSaver} = tmp;
const URL = ROOT + "browser_454908_sample.html";
const PASS = "pwd-" + Math.random();

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