зеркало из https://github.com/mozilla/gecko-dev.git
merge fx-team to mozilla-central a=merge
This commit is contained in:
Коммит
c084656336
|
@ -50,6 +50,7 @@ DEFAULT_NO_CONNECTIONS_PREFS = {
|
|||
'media.gmp-manager.cert.requireBuiltIn' : False,
|
||||
'media.gmp-manager.url' : 'http://localhost/media-dummy/gmpmanager',
|
||||
'media.gmp-manager.url.override': 'http://localhost/dummy-gmp-manager.xml',
|
||||
'media.gmp-manager.updateEnabled': False,
|
||||
'browser.aboutHomeSnippets.updateUrl': 'https://localhost/snippet-dummy',
|
||||
'browser.newtab.url' : 'about:blank',
|
||||
'browser.search.update': False,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"media.gmp-manager.cert.requireBuiltIn": false,
|
||||
"media.gmp-manager.url": "http://localhost/media-dummy/gmpmanager",
|
||||
"media.gmp-manager.url.override": "http://localhost/dummy-gmp-manager.xml",
|
||||
"media.gmp-manager.updateEnabled": false,
|
||||
"browser.aboutHomeSnippets.updateUrl": "https://localhost/snippet-dummy",
|
||||
"browser.newtab.url": "about:blank",
|
||||
"browser.search.update": false,
|
||||
|
|
|
@ -332,6 +332,8 @@ DeveloperToolbar.prototype.createToolbar = function () {
|
|||
toolboxBtn.setAttribute("class", "developer-toolbar-button");
|
||||
let toolboxTooltip = L10N.getStr("toolbar.toolsButton.tooltip");
|
||||
toolboxBtn.setAttribute("tooltiptext", toolboxTooltip);
|
||||
let toolboxOpen = gDevToolsBrowser.hasToolboxOpened(this._chromeWindow);
|
||||
toolboxBtn.setAttribute("checked", toolboxOpen);
|
||||
toolboxBtn.addEventListener("command", function (event) {
|
||||
let window = event.target.ownerDocument.defaultView;
|
||||
gDevToolsBrowser.toggleToolboxCommand(window.gBrowser);
|
||||
|
@ -714,6 +716,8 @@ DeveloperToolbar.prototype.handleEvent = function (ev) {
|
|||
});
|
||||
|
||||
if (ev.type == "TabSelect") {
|
||||
let toolboxOpen = gDevToolsBrowser.hasToolboxOpened(this._chromeWindow);
|
||||
this._errorCounterButton.setAttribute("checked", toolboxOpen);
|
||||
this._initErrorsCount(ev.target);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,14 @@ const testCases = [
|
|||
{name: "c1.2", value: "Object"},
|
||||
{name: "c1.2.foo", value: "Bar"},
|
||||
], true],
|
||||
["c_encoded", [
|
||||
{name: "c_encoded", value: encodeURIComponent(JSON.stringify({foo: {foo1: "bar"}}))}
|
||||
]],
|
||||
[null, [
|
||||
{name: "c_encoded", value: "Object"},
|
||||
{name: "c_encoded.foo", value: "Object"},
|
||||
{name: "c_encoded.foo.foo1", value: "bar"}
|
||||
], true],
|
||||
[["localStorage", "http://test1.example.org"]],
|
||||
["ls2", [
|
||||
{name: "ls2", value: "foobar-2"}
|
||||
|
|
|
@ -19,6 +19,9 @@ document.cookie = "c1=" + JSON.stringify([
|
|||
}]) + "; expires=" + new Date(cookieExpiresTime).toGMTString() +
|
||||
"; path=/browser";
|
||||
document.cookie = "cs2=sessionCookie; path=/; domain=" + partialHostname;
|
||||
// URLEncoded cookie
|
||||
document.cookie = "c_encoded=" + encodeURIComponent(JSON.stringify({foo: {foo1: "bar"}}));
|
||||
|
||||
// ... and some local storage items ..
|
||||
const es6 = "for";
|
||||
localStorage.setItem("ls1", JSON.stringify({
|
||||
|
|
|
@ -645,7 +645,17 @@ StorageUI.prototype = {
|
|||
* @param {string} value
|
||||
* The string to be parsed into an object
|
||||
*/
|
||||
parseItemValue: function (name, value) {
|
||||
parseItemValue: function (name, originalValue) {
|
||||
// Find if value is URLEncoded ie
|
||||
let decodedValue = "";
|
||||
try {
|
||||
decodedValue = decodeURIComponent(originalValue);
|
||||
} catch (e) {
|
||||
// Unable to decode, nothing to do
|
||||
}
|
||||
let value = (decodedValue && decodedValue !== originalValue)
|
||||
? decodedValue : originalValue;
|
||||
|
||||
let json = null;
|
||||
try {
|
||||
json = JSOL.parse(value);
|
||||
|
|
|
@ -723,3 +723,39 @@ a.learn-more-link.webconsole-learn-more-link {
|
|||
.message.network .method {
|
||||
margin-inline-end: 5px;
|
||||
}
|
||||
|
||||
/* console.table() */
|
||||
.new-consoletable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
--consoletable-border: 1px solid var(--table-splitter-color);
|
||||
}
|
||||
|
||||
.new-consoletable thead,
|
||||
.new-consoletable tbody {
|
||||
background-color: var(--theme-body-background);
|
||||
}
|
||||
|
||||
.new-consoletable th {
|
||||
background-color: var(--theme-selection-background);
|
||||
color: var(--theme-selection-color);
|
||||
margin: 0;
|
||||
padding: 5px 0 0;
|
||||
font-weight: inherit;
|
||||
border-inline-end: var(--consoletable-border);
|
||||
border-bottom: var(--consoletable-border);
|
||||
}
|
||||
|
||||
.new-consoletable tr:nth-of-type(even) {
|
||||
background-color: var(--table-zebra-background);
|
||||
}
|
||||
|
||||
.new-consoletable td {
|
||||
padding: 3px 4px;
|
||||
min-width: 100px;
|
||||
-moz-user-focus: normal;
|
||||
color: var(--theme-body-color);
|
||||
border-inline-end: var(--consoletable-border);
|
||||
height: 1.25em;
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { BATCH_ACTIONS } = require("../constants");
|
||||
|
||||
function batchActions(batchedActions) {
|
||||
return {
|
||||
type: BATCH_ACTIONS,
|
||||
actions: batchedActions,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
batchActions
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const actionModules = [
|
||||
"enhancers",
|
||||
"filters",
|
||||
"messages",
|
||||
"ui",
|
||||
].map(filename => require(`./${filename}`));
|
||||
|
||||
const actions = Object.assign({}, ...actionModules);
|
||||
|
||||
module.exports = actions;
|
|
@ -10,33 +10,35 @@ const {
|
|||
prepareMessage
|
||||
} = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
|
||||
|
||||
const { batchActions } = require("devtools/client/webconsole/new-console-output/actions/enhancers");
|
||||
const {
|
||||
MESSAGE_ADD,
|
||||
MESSAGES_CLEAR,
|
||||
MESSAGE_OPEN,
|
||||
MESSAGE_CLOSE,
|
||||
MESSAGE_TYPE,
|
||||
MESSAGE_TABLE_RECEIVE,
|
||||
} = require("../constants");
|
||||
|
||||
const defaultIdGenerator = new IdGenerator();
|
||||
|
||||
function messageAdd(packet, idGenerator = null) {
|
||||
return (dispatch) => {
|
||||
if (idGenerator == null) {
|
||||
idGenerator = defaultIdGenerator;
|
||||
}
|
||||
let message = prepareMessage(packet, idGenerator);
|
||||
|
||||
if (message.type === MESSAGE_TYPE.CLEAR) {
|
||||
dispatch(messagesClear());
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: MESSAGE_ADD,
|
||||
message
|
||||
});
|
||||
if (idGenerator == null) {
|
||||
idGenerator = defaultIdGenerator;
|
||||
}
|
||||
let message = prepareMessage(packet, idGenerator);
|
||||
const addMessageAction = {
|
||||
type: MESSAGE_ADD,
|
||||
message
|
||||
};
|
||||
|
||||
if (message.type === MESSAGE_TYPE.CLEAR) {
|
||||
return batchActions([
|
||||
messagesClear(),
|
||||
addMessageAction,
|
||||
]);
|
||||
}
|
||||
return addMessageAction;
|
||||
}
|
||||
|
||||
function messagesClear() {
|
||||
|
@ -59,7 +61,39 @@ function messageClose(id) {
|
|||
};
|
||||
}
|
||||
|
||||
exports.messageAdd = messageAdd;
|
||||
exports.messagesClear = messagesClear;
|
||||
exports.messageOpen = messageOpen;
|
||||
exports.messageClose = messageClose;
|
||||
function messageTableDataGet(id, client, dataType) {
|
||||
return (dispatch) => {
|
||||
let fetchObjectActorData;
|
||||
if (["Map", "WeakMap", "Set", "WeakSet"].includes(dataType)) {
|
||||
fetchObjectActorData = (cb) => client.enumEntries(cb);
|
||||
} else {
|
||||
fetchObjectActorData = (cb) => client.enumProperties({
|
||||
ignoreNonIndexedProperties: dataType === "Array"
|
||||
}, cb);
|
||||
}
|
||||
|
||||
fetchObjectActorData(enumResponse => {
|
||||
const {iterator} = enumResponse;
|
||||
iterator.slice(0, iterator.count, sliceResponse => {
|
||||
let {ownProperties} = sliceResponse;
|
||||
dispatch(messageTableDataReceive(id, ownProperties));
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function messageTableDataReceive(id, data) {
|
||||
return {
|
||||
type: MESSAGE_TABLE_RECEIVE,
|
||||
id,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
messageAdd,
|
||||
messagesClear,
|
||||
messageOpen,
|
||||
messageClose,
|
||||
messageTableDataGet,
|
||||
};
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'enhancers.js',
|
||||
'filters.js',
|
||||
'index.js',
|
||||
'messages.js',
|
||||
'ui.js',
|
||||
)
|
||||
|
|
|
@ -12,13 +12,13 @@ const {
|
|||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const { getAllMessages, getAllMessagesUiById } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const { getAllMessages, getAllMessagesUiById, getAllMessagesTableDataById } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const MessageContainer = createFactory(require("devtools/client/webconsole/new-console-output/components/message-container").MessageContainer);
|
||||
|
||||
const ConsoleOutput = createClass({
|
||||
|
||||
propTypes: {
|
||||
jsterm: PropTypes.object.isRequired,
|
||||
hudProxyClient: PropTypes.object.isRequired,
|
||||
messages: PropTypes.object.isRequired,
|
||||
messagesUi: PropTypes.object.isRequired,
|
||||
sourceMapService: PropTypes.object,
|
||||
|
@ -46,8 +46,10 @@ const ConsoleOutput = createClass({
|
|||
render() {
|
||||
let {
|
||||
dispatch,
|
||||
hudProxyClient,
|
||||
messages,
|
||||
messagesUi,
|
||||
messagesTableData,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger,
|
||||
openNetworkPanel,
|
||||
|
@ -58,6 +60,7 @@ const ConsoleOutput = createClass({
|
|||
return (
|
||||
MessageContainer({
|
||||
dispatch,
|
||||
hudProxyClient,
|
||||
message,
|
||||
key: message.id,
|
||||
sourceMapService,
|
||||
|
@ -65,6 +68,7 @@ const ConsoleOutput = createClass({
|
|||
openNetworkPanel,
|
||||
openLink,
|
||||
open: messagesUi.includes(message.id),
|
||||
tableData: messagesTableData.get(message.id),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -85,6 +89,7 @@ function mapStateToProps(state) {
|
|||
return {
|
||||
messages: getAllMessages(state),
|
||||
messagesUi: getAllMessagesUiById(state),
|
||||
messagesTableData: getAllMessagesTableDataById(state),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/* 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 {
|
||||
createClass,
|
||||
createFactory,
|
||||
DOM: dom,
|
||||
PropTypes
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const { ObjectClient } = require("devtools/shared/client/main");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const {l10n} = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const GripMessageBody = createFactory(require("devtools/client/webconsole/new-console-output/components/grip-message-body").GripMessageBody);
|
||||
|
||||
const TABLE_ROW_MAX_ITEMS = 1000;
|
||||
const TABLE_COLUMN_MAX_ITEMS = 10;
|
||||
|
||||
const ConsoleTable = createClass({
|
||||
|
||||
displayName: "ConsoleTable",
|
||||
|
||||
propTypes: {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
parameters: PropTypes.array.isRequired,
|
||||
hudProxyClient: PropTypes.object.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
},
|
||||
|
||||
componentWillMount: function () {
|
||||
const {id, dispatch, hudProxyClient, parameters} = this.props;
|
||||
|
||||
if (!Array.isArray(parameters) || parameters.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const client = new ObjectClient(hudProxyClient, parameters[0]);
|
||||
let dataType = getParametersDataType(parameters);
|
||||
|
||||
// Get all the object properties.
|
||||
dispatch(actions.messageTableDataGet(id, client, dataType));
|
||||
},
|
||||
|
||||
getHeaders: function (columns) {
|
||||
let headerItems = [];
|
||||
columns.forEach((value, key) => headerItems.push(dom.th({}, value)));
|
||||
return headerItems;
|
||||
},
|
||||
|
||||
getRows: function (columns, items) {
|
||||
return items.map(item => {
|
||||
let cells = [];
|
||||
columns.forEach((value, key) => {
|
||||
cells.push(
|
||||
dom.td(
|
||||
{},
|
||||
GripMessageBody({
|
||||
grip: item[key]
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
return dom.tr({}, cells);
|
||||
});
|
||||
},
|
||||
|
||||
render: function () {
|
||||
const {parameters, tableData} = this.props;
|
||||
const headersGrip = parameters[1];
|
||||
const headers = headersGrip && headersGrip.preview ? headersGrip.preview.items : null;
|
||||
|
||||
// if tableData is nullable, we don't show anything.
|
||||
if (!tableData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {columns, items} = getTableItems(
|
||||
tableData,
|
||||
getParametersDataType(parameters),
|
||||
headers
|
||||
);
|
||||
|
||||
return (
|
||||
dom.table({className: "new-consoletable devtools-monospace"},
|
||||
dom.thead({}, this.getHeaders(columns)),
|
||||
dom.tbody({}, this.getRows(columns, items))
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function getParametersDataType(parameters = null) {
|
||||
if (!Array.isArray(parameters) || parameters.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return parameters[0].class;
|
||||
}
|
||||
|
||||
function getTableItems(data = {}, type, headers = null) {
|
||||
const INDEX_NAME = "_index";
|
||||
const VALUE_NAME = "_value";
|
||||
const namedIndexes = {
|
||||
[INDEX_NAME]: (
|
||||
["Object", "Array"].includes(type) ?
|
||||
l10n.getStr("table.index") : l10n.getStr("table.iterationIndex")
|
||||
),
|
||||
[VALUE_NAME]: l10n.getStr("table.value"),
|
||||
key: l10n.getStr("table.key")
|
||||
};
|
||||
|
||||
let columns = new Map();
|
||||
let items = [];
|
||||
|
||||
let addItem = function (item) {
|
||||
items.push(item);
|
||||
Object.keys(item).forEach(key => addColumn(key));
|
||||
};
|
||||
|
||||
let addColumn = function (columnIndex) {
|
||||
let columnExists = columns.has(columnIndex);
|
||||
let hasMaxColumns = columns.size == TABLE_COLUMN_MAX_ITEMS;
|
||||
let hasCustomHeaders = Array.isArray(headers);
|
||||
|
||||
if (
|
||||
!columnExists &&
|
||||
!hasMaxColumns && (
|
||||
!hasCustomHeaders ||
|
||||
headers.includes(columnIndex) ||
|
||||
columnIndex === INDEX_NAME
|
||||
)
|
||||
) {
|
||||
columns.set(columnIndex, namedIndexes[columnIndex] || columnIndex);
|
||||
}
|
||||
};
|
||||
|
||||
for (let index of Object.keys(data)) {
|
||||
if (type !== "Object" && index == parseInt(index, 10)) {
|
||||
index = parseInt(index, 10);
|
||||
}
|
||||
|
||||
let item = {
|
||||
[INDEX_NAME]: index
|
||||
};
|
||||
|
||||
let property = data[index].value;
|
||||
|
||||
if (property.preview) {
|
||||
let {preview} = property;
|
||||
let entries = preview.ownProperties || preview.items;
|
||||
if (entries) {
|
||||
for (let key of Object.keys(entries)) {
|
||||
let entry = entries[key];
|
||||
item[key] = entry.value || entry;
|
||||
}
|
||||
} else {
|
||||
if (preview.key) {
|
||||
item.key = preview.key;
|
||||
}
|
||||
|
||||
item[VALUE_NAME] = preview.value || property;
|
||||
}
|
||||
} else {
|
||||
item[VALUE_NAME] = property;
|
||||
}
|
||||
|
||||
addItem(item);
|
||||
|
||||
if (items.length === TABLE_ROW_MAX_ITEMS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Some headers might not be present in the items, so we make sure to
|
||||
// return all the headers set by the user.
|
||||
if (Array.isArray(headers)) {
|
||||
headers.forEach(header => addColumn(header));
|
||||
}
|
||||
|
||||
// We want to always have the index column first
|
||||
if (columns.has(INDEX_NAME)) {
|
||||
let index = columns.get(INDEX_NAME);
|
||||
columns.delete(INDEX_NAME);
|
||||
columns = new Map([[INDEX_NAME, index], ...columns.entries()]);
|
||||
}
|
||||
|
||||
// We want to always have the values column last
|
||||
if (columns.has(VALUE_NAME)) {
|
||||
let index = columns.get(VALUE_NAME);
|
||||
columns.delete(VALUE_NAME);
|
||||
columns.set(VALUE_NAME, index);
|
||||
}
|
||||
|
||||
return {
|
||||
columns,
|
||||
items
|
||||
};
|
||||
}
|
||||
|
||||
exports.ConsoleTable = ConsoleTable;
|
|
@ -12,9 +12,9 @@ const {
|
|||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
|
||||
const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui");
|
||||
const { filterTextSet, filtersClear } = require("devtools/client/webconsole/new-console-output/actions/filters");
|
||||
const { messagesClear } = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const uiActions = require("devtools/client/webconsole/new-console-output/actions/ui");
|
||||
const { filterTextSet, filtersClear } = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { messagesClear } = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const uiActions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const {
|
||||
MESSAGE_LEVEL
|
||||
} = require("../constants");
|
||||
|
|
|
@ -8,7 +8,7 @@ const {
|
|||
DOM: dom,
|
||||
PropTypes
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/filters");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
|
||||
const FilterButton = createClass({
|
||||
|
||||
|
|
|
@ -41,12 +41,14 @@ function GripMessageBody(props) {
|
|||
typeof grip === "string"
|
||||
? StringRep({
|
||||
object: grip,
|
||||
useQuotes: false
|
||||
useQuotes: false,
|
||||
mode: props.mode,
|
||||
})
|
||||
: Rep({
|
||||
object: grip,
|
||||
objectLink: VariablesViewLink,
|
||||
defaultRep: Grip
|
||||
defaultRep: Grip,
|
||||
mode: props.mode,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ const MessageContainer = createClass({
|
|||
openNetworkPanel: PropTypes.func.isRequired,
|
||||
openLink: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
hudProxyClient: PropTypes.object.isRequired,
|
||||
},
|
||||
|
||||
getDefaultProps: function () {
|
||||
|
@ -46,8 +47,10 @@ const MessageContainer = createClass({
|
|||
},
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return this.props.message.repeat !== nextProps.message.repeat
|
||||
|| this.props.open !== nextProps.open;
|
||||
const repeatChanged = this.props.message.repeat !== nextProps.message.repeat;
|
||||
const openChanged = this.props.open !== nextProps.open;
|
||||
const tableDataChanged = this.props.tableData !== nextProps.tableData;
|
||||
return repeatChanged || openChanged || tableDataChanged;
|
||||
},
|
||||
|
||||
render() {
|
||||
|
@ -59,6 +62,8 @@ const MessageContainer = createClass({
|
|||
openNetworkPanel,
|
||||
openLink,
|
||||
open,
|
||||
tableData,
|
||||
hudProxyClient,
|
||||
} = this.props;
|
||||
|
||||
let MessageComponent = createFactory(getMessageComponent(message));
|
||||
|
@ -70,6 +75,8 @@ const MessageContainer = createClass({
|
|||
openNetworkPanel,
|
||||
openLink,
|
||||
open,
|
||||
tableData,
|
||||
hudProxyClient,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,7 +18,8 @@ const GripMessageBody = createFactory(require("devtools/client/webconsole/new-co
|
|||
const MessageRepeat = createFactory(require("devtools/client/webconsole/new-console-output/components/message-repeat").MessageRepeat);
|
||||
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
|
||||
const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button").CollapseButton);
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const ConsoleTable = createFactory(require("devtools/client/webconsole/new-console-output/components/console-table").ConsoleTable);
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
|
||||
ConsoleApiCall.displayName = "ConsoleApiCall";
|
||||
|
||||
|
@ -27,6 +28,7 @@ ConsoleApiCall.propTypes = {
|
|||
sourceMapService: PropTypes.object,
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool,
|
||||
hudProxyClient: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
ConsoleApiCall.defaultProps = {
|
||||
|
@ -34,15 +36,26 @@ ConsoleApiCall.defaultProps = {
|
|||
};
|
||||
|
||||
function ConsoleApiCall(props) {
|
||||
const { dispatch, message, sourceMapService, onViewSourceInDebugger, open } = props;
|
||||
const { source, level, stacktrace, type, frame, parameters } = message;
|
||||
const {
|
||||
dispatch,
|
||||
message,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger,
|
||||
open,
|
||||
hudProxyClient,
|
||||
tableData
|
||||
} = props;
|
||||
const {source, level, stacktrace, type, frame, parameters } = message;
|
||||
|
||||
let messageBody;
|
||||
if (type === "trace") {
|
||||
messageBody = dom.span({ className: "cm-variable" }, "console.trace()");
|
||||
messageBody = dom.span({className: "cm-variable"}, "console.trace()");
|
||||
} else if (type === "assert") {
|
||||
let reps = formatReps(parameters);
|
||||
messageBody = dom.span({ className: "cm-variable" }, "Assertion failed: ", reps);
|
||||
} else if (type === "table") {
|
||||
// TODO: Chrome does not output anything, see if we want to keep this
|
||||
messageBody = dom.span({className: "cm-variable"}, "console.table()");
|
||||
} else if (parameters) {
|
||||
messageBody = formatReps(parameters);
|
||||
} else {
|
||||
|
@ -83,6 +96,14 @@ function ConsoleApiCall(props) {
|
|||
}
|
||||
},
|
||||
});
|
||||
} else if (type === "table") {
|
||||
attachment = ConsoleTable({
|
||||
dispatch,
|
||||
id: message.id,
|
||||
hudProxyClient,
|
||||
parameters: message.parameters,
|
||||
tableData
|
||||
});
|
||||
}
|
||||
|
||||
const classes = ["message", "cm-s-mozilla"];
|
||||
|
|
|
@ -15,7 +15,7 @@ const {
|
|||
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
|
||||
const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button").CollapseButton);
|
||||
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
|
||||
NetworkEventMessage.displayName = "NetworkEventMessage";
|
||||
|
||||
|
@ -60,17 +60,6 @@ function NetworkEventMessage(props) {
|
|||
// @TODO add timestamp
|
||||
// @TODO add indent if necessary
|
||||
MessageIcon({ level }),
|
||||
CollapseButton({
|
||||
open,
|
||||
title: l10n.getStr("messageToggleDetails"),
|
||||
onClick: () => {
|
||||
if (open) {
|
||||
dispatch(actions.messageClose(message.id));
|
||||
} else {
|
||||
dispatch(actions.messageOpen(message.id));
|
||||
}
|
||||
},
|
||||
}),
|
||||
dom.span({
|
||||
className: "message-body-wrapper message-body devtools-monospace",
|
||||
"aria-haspopup": "true"
|
||||
|
@ -78,8 +67,7 @@ function NetworkEventMessage(props) {
|
|||
dom.span({ className: "method" }, method),
|
||||
isXHR ? dom.span({ className: "xhr" }, xhr) : null,
|
||||
dom.a({ className: "url", title: url, onClick: onUrlClick },
|
||||
url.replace(/\?.+/, "")),
|
||||
dom.a({ className: "status" }, statusInfo)
|
||||
url.replace(/\?.+/, ""))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ const CollapseButton = createFactory(require("devtools/client/webconsole/new-con
|
|||
const MessageRepeat = createFactory(require("devtools/client/webconsole/new-console-output/components/message-repeat").MessageRepeat);
|
||||
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
|
||||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
|
||||
PageError.displayName = "PageError";
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ DIRS += [
|
|||
DevToolsModules(
|
||||
'collapse-button.js',
|
||||
'console-output.js',
|
||||
'console-table.js',
|
||||
'filter-bar.js',
|
||||
'filter-button.js',
|
||||
'grip-message-body.js',
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
"use strict";
|
||||
|
||||
const actionTypes = {
|
||||
BATCH_ACTIONS: "BATCH_ACTIONS",
|
||||
MESSAGE_ADD: "MESSAGE_ADD",
|
||||
MESSAGES_CLEAR: "MESSAGES_CLEAR",
|
||||
MESSAGE_OPEN: "MESSAGE_OPEN",
|
||||
MESSAGE_CLOSE: "MESSAGE_CLOSE",
|
||||
MESSAGE_TABLE_RECEIVE: "MESSAGE_TABLE_RECEIVE",
|
||||
FILTER_TOGGLE: "FILTER_TOGGLE",
|
||||
FILTER_TEXT_SET: "FILTER_TEXT_SET",
|
||||
FILTERS_CLEAR: "FILTERS_CLEAR",
|
||||
|
|
|
@ -8,7 +8,7 @@ const React = require("devtools/client/shared/vendor/react");
|
|||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { configureStore } = require("devtools/client/webconsole/new-console-output/store");
|
||||
|
||||
const ConsoleOutput = React.createFactory(require("devtools/client/webconsole/new-console-output/components/console-output"));
|
||||
|
@ -17,40 +17,54 @@ const FilterBar = React.createFactory(require("devtools/client/webconsole/new-co
|
|||
const store = configureStore();
|
||||
|
||||
function NewConsoleOutputWrapper(parentNode, jsterm, toolbox, owner) {
|
||||
const sourceMapService = toolbox ? toolbox._sourceMapService : null;
|
||||
let childComponent = ConsoleOutput({
|
||||
jsterm,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger: frame => toolbox.viewSourceInDebugger.call(
|
||||
toolbox,
|
||||
frame.url,
|
||||
frame.line
|
||||
),
|
||||
openNetworkPanel: (requestId) => {
|
||||
return toolbox.selectTool("netmonitor").then(panel => {
|
||||
return panel.panelWin.NetMonitorController.inspectRequest(requestId);
|
||||
});
|
||||
},
|
||||
openLink: (url) => {
|
||||
owner.openLink(url);
|
||||
},
|
||||
});
|
||||
let filterBar = FilterBar({});
|
||||
let provider = React.createElement(
|
||||
Provider,
|
||||
{ store },
|
||||
React.DOM.div(
|
||||
{className: "webconsole-output-wrapper"},
|
||||
filterBar,
|
||||
childComponent
|
||||
));
|
||||
this.body = ReactDOM.render(provider, parentNode);
|
||||
this.parentNode = parentNode;
|
||||
this.jsterm = jsterm;
|
||||
this.toolbox = toolbox;
|
||||
this.owner = owner;
|
||||
|
||||
this.init = this.init.bind(this);
|
||||
}
|
||||
|
||||
NewConsoleOutputWrapper.prototype = {
|
||||
init: function () {
|
||||
const sourceMapService = this.toolbox ? this.toolbox._sourceMapService : null;
|
||||
|
||||
let childComponent = ConsoleOutput({
|
||||
hudProxyClient: this.jsterm.hud.proxy.client,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger: frame => this.toolbox.viewSourceInDebugger.call(
|
||||
this.toolbox,
|
||||
frame.url,
|
||||
frame.line
|
||||
),
|
||||
openNetworkPanel: (requestId) => {
|
||||
return this.toolbox.selectTool("netmonitor").then(panel => {
|
||||
return panel.panelWin.NetMonitorController.inspectRequest(requestId);
|
||||
});
|
||||
},
|
||||
openLink: (url) => {
|
||||
this.owner.openLink(url);
|
||||
},
|
||||
});
|
||||
let filterBar = FilterBar({});
|
||||
let provider = React.createElement(
|
||||
Provider,
|
||||
{ store },
|
||||
React.DOM.div(
|
||||
{className: "webconsole-output-wrapper"},
|
||||
filterBar,
|
||||
childComponent
|
||||
));
|
||||
|
||||
this.body = ReactDOM.render(provider, this.parentNode);
|
||||
},
|
||||
dispatchMessageAdd: (message) => {
|
||||
store.dispatch(actions.messageAdd(message));
|
||||
},
|
||||
dispatchMessagesAdd: (messages) => {
|
||||
const batchedActions = messages.map(message => actions.messageAdd(message));
|
||||
store.dispatch(actions.batchActions(batchedActions));
|
||||
},
|
||||
dispatchMessagesClear: () => {
|
||||
store.dispatch(actions.messagesClear());
|
||||
},
|
||||
|
|
|
@ -11,11 +11,13 @@ const constants = require("devtools/client/webconsole/new-console-output/constan
|
|||
const MessageState = Immutable.Record({
|
||||
messagesById: Immutable.List(),
|
||||
messagesUiById: Immutable.List(),
|
||||
messagesTableDataById: Immutable.Map(),
|
||||
});
|
||||
|
||||
function messages(state = new MessageState(), action) {
|
||||
const messagesById = state.messagesById;
|
||||
const messagesUiById = state.messagesUiById;
|
||||
const messagesTableDataById = state.messagesTableDataById;
|
||||
|
||||
switch (action.type) {
|
||||
case constants.MESSAGE_ADD:
|
||||
|
@ -52,6 +54,9 @@ function messages(state = new MessageState(), action) {
|
|||
case constants.MESSAGE_CLOSE:
|
||||
let index = state.messagesUiById.indexOf(action.id);
|
||||
return state.deleteIn(["messagesUiById", index]);
|
||||
case constants.MESSAGE_TABLE_RECEIVE:
|
||||
const {id, data} = action;
|
||||
return state.set("messagesTableDataById", messagesTableDataById.set(id, data));
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -34,6 +34,10 @@ function getAllMessagesUiById(state) {
|
|||
return state.messages.messagesUiById;
|
||||
}
|
||||
|
||||
function getAllMessagesTableDataById(state) {
|
||||
return state.messages.messagesTableDataById;
|
||||
}
|
||||
|
||||
function filterLevel(messages, filters) {
|
||||
return messages.filter((message) => {
|
||||
return filters.get(message.level) === true
|
||||
|
@ -114,3 +118,4 @@ function prune(messages, logLimit) {
|
|||
|
||||
exports.getAllMessages = getAllMessages;
|
||||
exports.getAllMessagesUiById = getAllMessagesUiById;
|
||||
exports.getAllMessagesTableDataById = getAllMessagesTableDataById;
|
||||
|
|
|
@ -5,8 +5,14 @@
|
|||
|
||||
const {FilterState} = require("devtools/client/webconsole/new-console-output/reducers/filters");
|
||||
const {PrefState} = require("devtools/client/webconsole/new-console-output/reducers/prefs");
|
||||
const { applyMiddleware, combineReducers, createStore } = require("devtools/client/shared/vendor/redux");
|
||||
const {
|
||||
applyMiddleware,
|
||||
combineReducers,
|
||||
compose,
|
||||
createStore
|
||||
} = require("devtools/client/shared/vendor/redux");
|
||||
const { thunk } = require("devtools/client/shared/redux/middleware/thunk");
|
||||
const constants = require("devtools/client/webconsole/new-console-output/constants");
|
||||
const { reducers } = require("./reducers/index");
|
||||
const Services = require("Services");
|
||||
|
||||
|
@ -28,10 +34,33 @@ function configureStore() {
|
|||
return createStore(
|
||||
combineReducers(reducers),
|
||||
initialState,
|
||||
applyMiddleware(thunk)
|
||||
compose(applyMiddleware(thunk), enableBatching())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A enhancer for the store to handle batched actions.
|
||||
*/
|
||||
function enableBatching() {
|
||||
return next => (reducer, initialState, enhancer) => {
|
||||
function batchingReducer(state, action) {
|
||||
switch (action.type) {
|
||||
case constants.BATCH_ACTIONS:
|
||||
return action.actions.reduce(batchingReducer, state);
|
||||
default:
|
||||
return reducer(state, action);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof initialState === "function" && typeof enhancer === "undefined") {
|
||||
enhancer = initialState;
|
||||
initialState = undefined;
|
||||
}
|
||||
|
||||
return next(batchingReducer, initialState, enhancer);
|
||||
};
|
||||
}
|
||||
|
||||
// Provide the store factory for test code so that each test is working with
|
||||
// its own instance.
|
||||
module.exports.configureStore = configureStore;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/filters");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const {
|
||||
FILTER_TEXT_SET,
|
||||
FILTER_TOGGLE,
|
||||
|
|
|
@ -26,16 +26,16 @@ describe("Message actions:", () => {
|
|||
const store = mockStore({});
|
||||
store.dispatch(actions.messageAdd(packet));
|
||||
|
||||
const expectedActions = store.getActions();
|
||||
expect(expectedActions.length).toEqual(1);
|
||||
const actualActions = store.getActions();
|
||||
expect(actualActions.length).toEqual(1);
|
||||
|
||||
const addAction = expectedActions[0];
|
||||
const addAction = actualActions[0];
|
||||
const {message} = addAction;
|
||||
const expected = {
|
||||
const expectedAction = {
|
||||
type: constants.MESSAGE_ADD,
|
||||
message: stubPreparedMessages.get("console.log('foobar', 'test')")
|
||||
};
|
||||
expect(message.toJS()).toEqual(expected.message.toJS());
|
||||
expect(message.toJS()).toEqual(expectedAction.message.toJS());
|
||||
});
|
||||
|
||||
it("dispatches expected actions given a console.clear packet", () => {
|
||||
|
@ -43,18 +43,35 @@ describe("Message actions:", () => {
|
|||
const store = mockStore({});
|
||||
store.dispatch(actions.messageAdd(packet));
|
||||
|
||||
const expectedActions = store.getActions();
|
||||
expect(expectedActions.length).toEqual(2);
|
||||
const actualActions = store.getActions();
|
||||
expect(actualActions.length).toEqual(1);
|
||||
|
||||
const [clearAction, addAction] = expectedActions;
|
||||
const [clearAction, addAction] = actualActions[0].actions;
|
||||
expect(clearAction.type).toEqual(constants.MESSAGES_CLEAR);
|
||||
|
||||
const {message} = addAction;
|
||||
const expected = {
|
||||
const expectedAction = {
|
||||
type: constants.MESSAGE_ADD,
|
||||
message: stubPreparedMessages.get("console.clear()")
|
||||
};
|
||||
expect(addAction.type).toEqual(constants.MESSAGE_ADD);
|
||||
expect(message.toJS()).toEqual(expectedAction.message.toJS());
|
||||
});
|
||||
|
||||
it("dispatches expected action given a console.table packet", () => {
|
||||
const packet = stubPackets.get("console.table(['a', 'b', 'c'])");
|
||||
const store = mockStore({});
|
||||
store.dispatch(actions.messageAdd(packet));
|
||||
|
||||
const expectedActions = store.getActions();
|
||||
expect(expectedActions.length).toEqual(1);
|
||||
|
||||
const addAction = expectedActions[0];
|
||||
const {message} = addAction;
|
||||
const expected = {
|
||||
type: constants.MESSAGE_ADD,
|
||||
message: stubPreparedMessages.get("console.table(['a', 'b', 'c'])")
|
||||
};
|
||||
expect(message.toJS()).toEqual(expected.message.toJS());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/ui");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const {
|
||||
FILTER_BAR_TOGGLE
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
|
|
@ -58,7 +58,7 @@ function timeit(cb) {
|
|||
|
||||
window.onload = Task.async(function* () {
|
||||
const { configureStore } = browserRequire("devtools/client/webconsole/new-console-output/store");
|
||||
const { filterTextSet, filtersClear } = browserRequire("devtools/client/webconsole/new-console-output/actions/filters");
|
||||
const { filterTextSet, filtersClear } = browserRequire("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const NewConsoleOutputWrapper = browserRequire("devtools/client/webconsole/new-console-output/new-console-output-wrapper");
|
||||
const wrapper = new NewConsoleOutputWrapper(document.querySelector("#output"), {});
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ describe("NetworkEventMessage component:", () => {
|
|||
expect(wrapper.find(".message-body .xhr").length).toBe(0);
|
||||
expect(wrapper.find(".message-body .url").length).toBe(1);
|
||||
expect(wrapper.find(".message-body .url").text()).toBe(EXPECTED_URL);
|
||||
expect(wrapper.find(".message-body .status").length).toBe(1);
|
||||
expect(wrapper.find("div.message.cm-s-mozilla span.message-body.devtools-monospace").length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
@ -43,7 +42,6 @@ describe("NetworkEventMessage component:", () => {
|
|||
expect(wrapper.find(".message-body .xhr").length).toBe(1);
|
||||
expect(wrapper.find(".message-body .xhr").text()).toBe("XHR");
|
||||
expect(wrapper.find(".message-body .url").text()).toBe(EXPECTED_URL);
|
||||
expect(wrapper.find(".message-body .status").length).toBe(1);
|
||||
expect(wrapper.find("div.message.cm-s-mozilla span.message-body.devtools-monospace").length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
@ -58,7 +56,6 @@ describe("NetworkEventMessage component:", () => {
|
|||
expect(wrapper.find(".message-body .xhr").text()).toBe("XHR");
|
||||
expect(wrapper.find(".message-body .url").length).toBe(1);
|
||||
expect(wrapper.find(".message-body .url").text()).toBe(EXPECTED_URL);
|
||||
expect(wrapper.find(".message-body .status").length).toBe(1);
|
||||
expect(wrapper.find("div.message.cm-s-mozilla span.message-body.devtools-monospace").length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
9
devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient.js
поставляемый
Normal file
9
devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient.js
поставляемый
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
class ObjectClient {
|
||||
}
|
||||
|
||||
module.exports = ObjectClient;
|
|
@ -46,6 +46,17 @@ console.time("bar");
|
|||
console.timeEnd("bar");
|
||||
`});
|
||||
|
||||
consoleApi.set("console.table('bar')", {
|
||||
keys: ["console.table('bar')"],
|
||||
code: `
|
||||
console.table('bar');
|
||||
`});
|
||||
|
||||
consoleApi.set("console.table(['a', 'b', 'c'])", {
|
||||
keys: ["console.table(['a', 'b', 'c'])"],
|
||||
code: `
|
||||
console.table(['a', 'b', 'c']);
|
||||
`});
|
||||
// Evaluation Result
|
||||
|
||||
const evaluationResultCommands = [
|
||||
|
|
|
@ -331,10 +331,10 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({
|
|||
"source": "console-api",
|
||||
"type": "timeEnd",
|
||||
"level": "log",
|
||||
"messageText": "bar: 1.63ms",
|
||||
"messageText": "bar: 1.81ms",
|
||||
"parameters": null,
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.63ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1}}",
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.81ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)",
|
||||
|
@ -343,6 +343,63 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({
|
|||
}
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "log",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
"bar"
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)\",\"line\":2,\"column\":1}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)",
|
||||
"line": 2,
|
||||
"column": 1
|
||||
}
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "table",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn14.child1/obj31",
|
||||
"class": "Array",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 4,
|
||||
"preview": {
|
||||
"kind": "ArrayLike",
|
||||
"length": 3,
|
||||
"items": [
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"table\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn14.child1/obj31\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)\",\"line\":2,\"column\":1}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)",
|
||||
"line": 2,
|
||||
"column": 1
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
stubPackets.set("console.log('foobar', 'test')", {
|
||||
"from": "server1.conn0.child1/consoleActor2",
|
||||
|
@ -370,7 +427,7 @@ stubPackets.set("console.log('foobar', 'test')", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329261562,
|
||||
"timeStamp": 1474757913492,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -404,7 +461,7 @@ stubPackets.set("console.log(undefined)", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329262588,
|
||||
"timeStamp": 1474757916196,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -436,7 +493,7 @@ stubPackets.set("console.warn('danger, will robinson!')", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329263650,
|
||||
"timeStamp": 1474757918499,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -470,7 +527,7 @@ stubPackets.set("console.log(NaN)", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329264822,
|
||||
"timeStamp": 1474757920577,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -504,7 +561,7 @@ stubPackets.set("console.log(null)", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329265855,
|
||||
"timeStamp": 1474757922439,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -536,7 +593,7 @@ stubPackets.set("console.log('鼬')", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329266922,
|
||||
"timeStamp": 1474757924400,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -565,7 +622,7 @@ stubPackets.set("console.clear()", {
|
|||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474329267971,
|
||||
"timeStamp": 1474757926626,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
|
@ -600,7 +657,7 @@ stubPackets.set("console.count('bar')", {
|
|||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474329269084,
|
||||
"timeStamp": 1474757929281,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
|
@ -654,7 +711,7 @@ stubPackets.set("console.assert(false, {message: 'foobar'})", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329270125,
|
||||
"timeStamp": 1474757931800,
|
||||
"timer": null,
|
||||
"stacktrace": [
|
||||
{
|
||||
|
@ -695,7 +752,7 @@ stubPackets.set("console.log('hello \nfrom \rthe \"string world!')", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329271256,
|
||||
"timeStamp": 1474757936217,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -727,7 +784,7 @@ stubPackets.set("console.log('úṇĩçödê țĕșť')", {
|
|||
},
|
||||
"private": false,
|
||||
"styles": [],
|
||||
"timeStamp": 1474329272298,
|
||||
"timeStamp": 1474757938480,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"category": "webdev"
|
||||
|
@ -756,7 +813,7 @@ stubPackets.set("console.trace()", {
|
|||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474329273375,
|
||||
"timeStamp": 1474757940569,
|
||||
"timer": null,
|
||||
"stacktrace": [
|
||||
{
|
||||
|
@ -811,10 +868,10 @@ stubPackets.set("console.time('bar')", {
|
|||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474329274410,
|
||||
"timeStamp": 1474757942740,
|
||||
"timer": {
|
||||
"name": "bar",
|
||||
"started": 618.57
|
||||
"started": 1220.705
|
||||
},
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
|
@ -846,9 +903,9 @@ stubPackets.set("console.timeEnd('bar')", {
|
|||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474329274411,
|
||||
"timeStamp": 1474757942742,
|
||||
"timer": {
|
||||
"duration": 1.3249999999999318,
|
||||
"duration": 1.8100000000001728,
|
||||
"name": "bar"
|
||||
},
|
||||
"workerType": "none",
|
||||
|
@ -857,6 +914,87 @@ stubPackets.set("console.timeEnd('bar')", {
|
|||
}
|
||||
});
|
||||
|
||||
stubPackets.set("console.table('bar')", {
|
||||
"from": "server1.conn13.child1/consoleActor2",
|
||||
"type": "consoleAPICall",
|
||||
"message": {
|
||||
"arguments": [
|
||||
"bar"
|
||||
],
|
||||
"columnNumber": 1,
|
||||
"counter": null,
|
||||
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)",
|
||||
"functionName": "triggerPacket",
|
||||
"groupName": "",
|
||||
"level": "table",
|
||||
"lineNumber": 2,
|
||||
"originAttributes": {
|
||||
"addonId": "",
|
||||
"appId": 0,
|
||||
"firstPartyDomain": "",
|
||||
"inIsolatedMozBrowser": false,
|
||||
"privateBrowsingId": 0,
|
||||
"signedPkg": "",
|
||||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474757944789,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
"category": "webdev"
|
||||
}
|
||||
});
|
||||
|
||||
stubPackets.set("console.table(['a', 'b', 'c'])", {
|
||||
"from": "server1.conn14.child1/consoleActor2",
|
||||
"type": "consoleAPICall",
|
||||
"message": {
|
||||
"arguments": [
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn14.child1/obj31",
|
||||
"class": "Array",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 4,
|
||||
"preview": {
|
||||
"kind": "ArrayLike",
|
||||
"length": 3,
|
||||
"items": [
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"columnNumber": 1,
|
||||
"counter": null,
|
||||
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)",
|
||||
"functionName": "triggerPacket",
|
||||
"groupName": "",
|
||||
"level": "table",
|
||||
"lineNumber": 2,
|
||||
"originAttributes": {
|
||||
"addonId": "",
|
||||
"appId": 0,
|
||||
"firstPartyDomain": "",
|
||||
"inIsolatedMozBrowser": false,
|
||||
"privateBrowsingId": 0,
|
||||
"signedPkg": "",
|
||||
"userContextId": 0
|
||||
},
|
||||
"private": false,
|
||||
"timeStamp": 1474757946731,
|
||||
"timer": null,
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
"category": "webdev"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = {
|
||||
stubPreparedMessages,
|
||||
|
|
|
@ -7,7 +7,7 @@ let ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
|||
let React = require("devtools/client/shared/vendor/react");
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { configureStore } = require("devtools/client/webconsole/new-console-output/store");
|
||||
const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
|
||||
const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
|
|
@ -4,8 +4,10 @@ subsuite = devtools
|
|||
support-files =
|
||||
head.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
test-console-table.html
|
||||
test-console.html
|
||||
|
||||
[browser_webconsole_console_table.js]
|
||||
[browser_webconsole_init.js]
|
||||
[browser_webconsole_input_focus.js]
|
||||
[browser_webconsole_observer_notifications.js]
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Check console.table calls with all the test cases shown
|
||||
// in the MDN doc (https://developer.mozilla.org/en-US/docs/Web/API/Console/table)
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-console-table.html";
|
||||
|
||||
add_task(function* () {
|
||||
let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
|
||||
let hud = toolbox.getCurrentPanel().hud;
|
||||
|
||||
function Person(firstName, lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
const testCases = [{
|
||||
info: "Testing when data argument is an array",
|
||||
input: ["apples", "oranges", "bananas"],
|
||||
expected: {
|
||||
columns: ["(index)", "Values"],
|
||||
rows: [
|
||||
["0", "apples"],
|
||||
["1", "oranges"],
|
||||
["2", "bananas"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing when data argument is an object",
|
||||
input: new Person("John", "Smith"),
|
||||
expected: {
|
||||
columns: ["(index)", "Values"],
|
||||
rows: [
|
||||
["firstName", "John"],
|
||||
["lastName", "Smith"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing when data argument is an array of arrays",
|
||||
input: [["Jane", "Doe"], ["Emily", "Jones"]],
|
||||
expected: {
|
||||
columns: ["(index)", "0", "1"],
|
||||
rows: [
|
||||
["0", "Jane", "Doe"],
|
||||
["1", "Emily", "Jones"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing when data argument is an array of objects",
|
||||
input: [
|
||||
new Person("Jack", "Foo"),
|
||||
new Person("Emma", "Bar"),
|
||||
new Person("Michelle", "Rax"),
|
||||
],
|
||||
expected: {
|
||||
columns: ["(index)", "firstName", "lastName"],
|
||||
rows: [
|
||||
["0", "Jack", "Foo"],
|
||||
["1", "Emma", "Bar"],
|
||||
["2", "Michelle", "Rax"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing when data argument is an object whose properties are objects",
|
||||
input: {
|
||||
father: new Person("Darth", "Vader"),
|
||||
daughter: new Person("Leia", "Organa"),
|
||||
son: new Person("Luke", "Skywalker"),
|
||||
},
|
||||
expected: {
|
||||
columns: ["(index)", "firstName", "lastName"],
|
||||
rows: [
|
||||
["father", "Darth", "Vader"],
|
||||
["daughter", "Leia", "Organa"],
|
||||
["son", "Luke", "Skywalker"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing when data argument is a Set",
|
||||
input: new Set(["a", "b", "c"]),
|
||||
expected: {
|
||||
columns: ["(iteration index)", "Values"],
|
||||
rows: [
|
||||
["0", "a"],
|
||||
["1", "b"],
|
||||
["2", "c"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing when data argument is a Map",
|
||||
input: new Map([["key-a", "value-a"], ["key-b", "value-b"]]),
|
||||
expected: {
|
||||
columns: ["(iteration index)", "Key", "Values"],
|
||||
rows: [
|
||||
["0", "key-a", "value-a"],
|
||||
["1", "key-b", "value-b"],
|
||||
]
|
||||
}
|
||||
}, {
|
||||
info: "Testing restricting the columns displayed",
|
||||
input: [
|
||||
new Person("Sam", "Wright"),
|
||||
new Person("Elena", "Bartz"),
|
||||
],
|
||||
headers: ["firstName"],
|
||||
expected: {
|
||||
columns: ["(index)", "firstName"],
|
||||
rows: [
|
||||
["0", "Sam"],
|
||||
["1", "Elena"],
|
||||
]
|
||||
}
|
||||
}];
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, testCases, function (tests) {
|
||||
tests.forEach((test) => {
|
||||
content.wrappedJSObject.doConsoleTable(test.input, test.headers);
|
||||
});
|
||||
});
|
||||
|
||||
let nodes = [];
|
||||
for (let testCase of testCases) {
|
||||
let node = yield waitFor(
|
||||
() => findConsoleTable(hud.ui.experimentalOutputNode, testCases.indexOf(testCase))
|
||||
);
|
||||
nodes.push(node);
|
||||
}
|
||||
|
||||
let consoleTableNodes = hud.ui.experimentalOutputNode.querySelectorAll(
|
||||
".message .new-consoletable");
|
||||
|
||||
is(consoleTableNodes.length, testCases.length,
|
||||
"console has the expected number of consoleTable items");
|
||||
|
||||
testCases.forEach((testCase, index) => {
|
||||
info(testCase.info);
|
||||
|
||||
let node = nodes[index];
|
||||
let columns = Array.from(node.querySelectorAll("thead th"));
|
||||
let rows = Array.from(node.querySelectorAll("tbody tr"));
|
||||
|
||||
is(
|
||||
JSON.stringify(testCase.expected.columns),
|
||||
JSON.stringify(columns.map(column => column.textContent)),
|
||||
"table has the expected columns"
|
||||
);
|
||||
|
||||
is(testCase.expected.rows.length, rows.length,
|
||||
"table has the expected number of rows");
|
||||
|
||||
testCase.expected.rows.forEach((expectedRow, rowIndex) => {
|
||||
let row = rows[rowIndex];
|
||||
let cells = row.querySelectorAll("td");
|
||||
is(expectedRow.length, cells.length, "row has the expected number of cells");
|
||||
|
||||
expectedRow.forEach((expectedCell, cellIndex) => {
|
||||
let cell = cells[cellIndex];
|
||||
is(expectedCell, cell.textContent, "cell has the expected content");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function findConsoleTable(node, index) {
|
||||
let condition = node.querySelector(
|
||||
`.message:nth-of-type(${index + 1}) .new-consoletable`);
|
||||
return condition;
|
||||
}
|
|
@ -7,12 +7,51 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Test input focus";
|
||||
const TEST_URI =
|
||||
`data:text/html;charset=utf-8,Test input focused
|
||||
<script>
|
||||
console.log("console message 1");
|
||||
</script>`;
|
||||
|
||||
add_task(function* () {
|
||||
let hud = yield openNewTabAndConsole(TEST_URI);
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
let inputNode = hud.jsterm.inputNode;
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused");
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused after output is cleared");
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.console.log("console message 2");
|
||||
});
|
||||
let msg = yield waitFor(() => findMessage(hud, "console message 2"));
|
||||
let outputItem = msg.querySelector(".message-body");
|
||||
|
||||
inputNode = hud.jsterm.inputNode;
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused, first");
|
||||
|
||||
yield waitForBlurredInput(inputNode);
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused, second time");
|
||||
|
||||
yield waitForBlurredInput(inputNode);
|
||||
|
||||
info("Setting a text selection and making sure a click does not re-focus");
|
||||
let selection = hud.iframeWindow.getSelection();
|
||||
selection.selectAllChildren(outputItem);
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
|
||||
ok(!inputNode.getAttribute("focused"),
|
||||
"input node focused after text is selected");
|
||||
});
|
||||
|
||||
function waitForBlurredInput(inputNode) {
|
||||
return new Promise(resolve => {
|
||||
let lostFocus = () => {
|
||||
ok(!inputNode.getAttribute("focused"), "input node is not focused");
|
||||
resolve();
|
||||
};
|
||||
inputNode.addEventListener("blur", lostFocus, { once: true });
|
||||
document.getElementById("urlbar").click();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ function waitForMessages({ hud, messages }) {
|
|||
function* waitFor(condition, message = "waitFor", interval = 100, maxTries = 50) {
|
||||
return new Promise(resolve => {
|
||||
BrowserTestUtils.waitForCondition(condition, message, interval, maxTries)
|
||||
.then(resolve(condition()));
|
||||
.then(() => resolve(condition()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -110,5 +110,5 @@ function findMessage(hud, text, selector = ".message") {
|
|||
hud.ui.experimentalOutputNode.querySelectorAll(selector),
|
||||
(el) => el.textContent.includes(text)
|
||||
);
|
||||
return elements.pop();
|
||||
return elements.length > 0 ? elements.pop() : false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple webconsole test page</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>console.table() test page</p>
|
||||
<script>
|
||||
function doConsoleTable(data, constrainedHeaders = null) {
|
||||
if (constrainedHeaders) {
|
||||
console.table(data, constrainedHeaders);
|
||||
} else {
|
||||
console.table(data);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -30,5 +30,7 @@ requireHacker.global_hook("default", path => {
|
|||
case "Services":
|
||||
case "Services.default":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/Services")`;
|
||||
case "devtools/shared/client/main":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient")`;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
const expect = require("expect");
|
||||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/filters");
|
||||
const { messageAdd } = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { messageAdd } = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { ConsoleCommand } = require("devtools/client/webconsole/new-console-output/types");
|
||||
const { getAllMessages } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
|
||||
|
|
|
@ -11,6 +11,9 @@ const {
|
|||
setupStore
|
||||
} = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
const { stubPackets, stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
const {
|
||||
MESSAGE_TYPE,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
const expect = require("expect");
|
||||
|
||||
|
@ -117,6 +120,17 @@ describe("Message reducer:", () => {
|
|||
const messages = getAllMessages(getState());
|
||||
expect(messages.size).toBe(0);
|
||||
});
|
||||
|
||||
it("adds console.table call with unsupported type as console.log", () => {
|
||||
const { dispatch, getState } = setupStore([]);
|
||||
|
||||
const packet = stubPackets.get("console.table('bar')");
|
||||
dispatch(actions.messageAdd(packet));
|
||||
|
||||
const messages = getAllMessages(getState());
|
||||
const tableMessage = messages.last();
|
||||
expect(tableMessage.level).toEqual(MESSAGE_TYPE.LOG);
|
||||
});
|
||||
});
|
||||
|
||||
describe("messagesUiById", () => {
|
||||
|
|
|
@ -81,6 +81,19 @@ function transformPacket(packet) {
|
|||
type = MESSAGE_TYPE.NULL_MESSAGE;
|
||||
}
|
||||
break;
|
||||
case "table":
|
||||
const supportedClasses = [
|
||||
"Array", "Object", "Map", "Set", "WeakMap", "WeakSet"];
|
||||
if (
|
||||
!Array.isArray(parameters) ||
|
||||
parameters.length === 0 ||
|
||||
!supportedClasses.includes(parameters[0].class)
|
||||
) {
|
||||
// If the class of the first parameter is not supported,
|
||||
// we handle the call as a simple console.log
|
||||
type = "log";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
const frame = message.filename ? {
|
||||
|
|
|
@ -494,6 +494,10 @@ WebConsoleFrame.prototype = {
|
|||
};
|
||||
allReady.then(notifyObservers, notifyObservers);
|
||||
|
||||
if (this.NEW_CONSOLE_OUTPUT_ENABLED) {
|
||||
allReady.then(this.newConsoleOutput.init);
|
||||
}
|
||||
|
||||
return allReady;
|
||||
},
|
||||
|
||||
|
@ -3272,6 +3276,13 @@ WebConsoleConnectionProxy.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Batched dispatch of messages.
|
||||
*/
|
||||
dispatchMessagesAdd: function(packets) {
|
||||
this.webConsoleFrame.newConsoleOutput.dispatchMessagesAdd(packets);
|
||||
},
|
||||
|
||||
/**
|
||||
* The "cachedMessages" response handler.
|
||||
*
|
||||
|
@ -3301,9 +3312,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
// Filter out CSS page errors.
|
||||
messages = messages.filter(message => !(message._type == "PageError"
|
||||
&& Utils.categoryForScriptError(message) === CATEGORY_CSS));
|
||||
for (let packet of messages) {
|
||||
this.dispatchMessageAdd(packet);
|
||||
}
|
||||
this.dispatchMessagesAdd(messages);
|
||||
} else {
|
||||
this.webConsoleFrame.displayCachedMessages(messages);
|
||||
if (!this._hasNativeConsoleAPI) {
|
||||
|
|
|
@ -32,8 +32,11 @@
|
|||
|
||||
let packagedAppLocation = getTestFilePath("app");
|
||||
|
||||
let onValidated = waitForUpdate(win, "project-validated");
|
||||
let onDetails = waitForUpdate(win, "details");
|
||||
yield winProject.projectList.importPackagedApp(packagedAppLocation);
|
||||
yield waitForUpdate(win, "details");
|
||||
yield onValidated;
|
||||
yield onDetails;
|
||||
|
||||
let project = win.AppManager.selectedProject;
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ user_pref("startup.homepage_override_url", "");
|
|||
user_pref("browser.usedOnWindows10.introURL", "");
|
||||
|
||||
user_pref("media.gmp-manager.url.override", "http://localhost/dummy-gmp-manager.xml");
|
||||
user_pref("media.gmp-manager.updateEnabled", false);
|
||||
|
||||
// A fake bool pref for "@supports -moz-bool-pref" sanify test.
|
||||
user_pref("testing.supports.moz-bool-pref", true);
|
||||
|
|
|
@ -47,6 +47,7 @@ user_pref("app.update.staging.enabled", false);
|
|||
user_pref("app.update.url.android", "");
|
||||
// Make sure GMPInstallManager won't hit the network.
|
||||
user_pref("media.gmp-manager.url.override", "http://%(server)s/dummy-gmp-manager.xml");
|
||||
user_pref("media.gmp-manager.updateEnabled", false);
|
||||
user_pref("dom.w3c_touch_events.enabled", 1);
|
||||
user_pref("layout.accessiblecaret.enabled_on_touch", false);
|
||||
user_pref("dom.undo_manager.enabled", true);
|
||||
|
|
|
@ -140,6 +140,7 @@ DEFAULTS = dict(
|
|||
'http://127.0.0.1/extensions-dummy/repositorySearchURL',
|
||||
'media.gmp-manager.url':
|
||||
'http://127.0.0.1/gmpmanager-dummy/update.xml',
|
||||
'media.gmp-manager.updateEnabled': False,
|
||||
'extensions.systemAddon.update.url':
|
||||
'http://127.0.0.1/dummy-system-addons.xml',
|
||||
'media.navigator.enabled': True,
|
||||
|
|
|
@ -1616,6 +1616,7 @@ try {
|
|||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
prefs.setCharPref("media.gmp-manager.url.override", "http://%(server)s/dummy-gmp-manager.xml");
|
||||
prefs.setCharPref("media.gmp-manager.updateEnabled", false);
|
||||
prefs.setCharPref("extensions.systemAddon.update.url", "http://%(server)s/dummy-system-addons.xml");
|
||||
prefs.setCharPref("browser.selfsupport.url", "https://%(server)s/selfsupport-dummy/");
|
||||
prefs.setCharPref("toolkit.telemetry.server", "https://%(server)s/telemetry-dummy");
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"vendors": {
|
||||
"gmp-eme-adobe": {
|
||||
"platforms": {
|
||||
"WINNT_x86-msvc-x64": {
|
||||
"alias": "WINNT_x86-msvc"
|
||||
},
|
||||
"WINNT_x86-msvc": {
|
||||
"fileUrl": "https://cdmdownload.adobe.com/firefox/win/x86/primetime_gmp_win_x86_gmc_40673.zip",
|
||||
"hashValue": "8aad35fc13814b0f1daacddb0d599eedd685287d5afddc97c2f740c8aea270636ccd75b1d1a57364b84e8eb1b23c9f1c126c057d95f3d8217b331dc4b1d5340f",
|
||||
"filesize": 3694349
|
||||
},
|
||||
"WINNT_x86_64-msvc-x64": {
|
||||
"alias": "WINNT_x86_64-msvc"
|
||||
},
|
||||
"WINNT_x86-msvc-x86": {
|
||||
"alias": "WINNT_x86-msvc"
|
||||
},
|
||||
"WINNT_x86_64-msvc": {
|
||||
"fileUrl": "https://cdmdownload.adobe.com/firefox/win/x64/primetime_gmp_win_x64_gmc_40673.zip",
|
||||
"hashValue": "bd1e1a370c5f9dadc247c9f00dd203fab1a75ff3afed8439a0a0bfcc7e1767d0da68497140cbe48daa70e2535dde5f220dd7b344619cecd830a6b685efb9d5a0",
|
||||
"filesize": 4853103
|
||||
}
|
||||
},
|
||||
"version": "17"
|
||||
}
|
||||
},
|
||||
"hashFunction": "sha512",
|
||||
"name": "CDM-17",
|
||||
"schema_version": 1000
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"vendors": {
|
||||
"gmp-gmpopenh264": {
|
||||
"platforms": {
|
||||
"WINNT_x86-msvc-x64": {
|
||||
"alias": "WINNT_x86-msvc"
|
||||
},
|
||||
"Android_x86-gcc3": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-android-x86-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "8ce4d4318aa6ae9ac1376500d5fceecb3df38727aa920efd9f7829c139face4a069cab683d3902e7cdb89daad2a7e928ffba120812ae343f052a833812dad387",
|
||||
"filesize": 1640053
|
||||
},
|
||||
"WINNT_x86-msvc": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-win32-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "991e01c3b95fa13fac52e0512e1936f1edae42ecbbbcc55447a36915eb3ca8f836546cc780343751691e0188872e5bc56fe3ad5f23f3243e90b96a637561b89e",
|
||||
"filesize": 356940
|
||||
},
|
||||
"WINNT_x86-msvc-x86": {
|
||||
"alias": "WINNT_x86-msvc"
|
||||
},
|
||||
"Linux_x86_64-gcc3": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-linux64-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "e1086ee6e4fb60a1aa11b5626594b97695533a8e269d776877cebd5cf29088619e2c164e7bd1eba5486f772c943f2efec723f69cc48478ec84a11d7b61ca1865",
|
||||
"filesize": 515722
|
||||
},
|
||||
"Darwin_x86-gcc3-u-i386-x86_64": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-macosx32-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "64b0e13e6319b7a31ed35a46bea5abcfe6af04ba59a277db07677236cfb685813763731ff6b44b85e03e1489f3b15f8df0128a299a36720531b9f4ba6e1c1f58",
|
||||
"filesize": 382435
|
||||
},
|
||||
"Darwin_x86_64-gcc3": {
|
||||
"alias": "Darwin_x86_64-gcc3-u-i386-x86_64"
|
||||
},
|
||||
"Linux_x86-gcc3": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-linux32-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "19084f0230218c584715861f4723e072b1af02e26995762f368105f670f60ecb4082531bc4e33065a4675dd1296f6872a6cb101547ef2d19ef3e25e2e16d4dc0",
|
||||
"filesize": 515857
|
||||
},
|
||||
"Darwin_x86_64-gcc3-u-i386-x86_64": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-macosx64-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "3b52343070a2f75e91b7b0d3bb33935352237c7e1d2fdc6a467d039ffbbda6a72087f9e0a369fe95e6c4c789ff3052f0c134af721d7273db9ba66d077d85b327",
|
||||
"filesize": 390308
|
||||
},
|
||||
"Android_arm-eabi-gcc3": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-android-arm-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "7a15245c781f32df310ebb88cb8a783512eab934b38ffd889d6420473d40eddbe8a89c17cc60d4e7647c156b04d20030e1ae0081e3f90a0d8f94626ec5f4d817",
|
||||
"filesize": 1515895
|
||||
},
|
||||
"Darwin_x86-gcc3": {
|
||||
"alias": "Darwin_x86-gcc3-u-i386-x86_64"
|
||||
},
|
||||
"WINNT_x86_64-msvc-x64": {
|
||||
"alias": "WINNT_x86_64-msvc"
|
||||
},
|
||||
"WINNT_x86_64-msvc": {
|
||||
"fileUrl": "http://ciscobinary.openh264.org/openh264-win64-0410d336bb748149a4f560eb6108090f078254b1.zip",
|
||||
"hashValue": "5030b47065e817db5c40bca9c62ac27292bbf636e24698f45dc67f03fa6420b97bd2f792c1cb39df65776c1e7597c70122ac7abf36fb2ad0603734e9e8ec4ef3",
|
||||
"filesize": 404355
|
||||
}
|
||||
},
|
||||
"version": "1.6"
|
||||
}
|
||||
},
|
||||
"hashFunction": "sha512",
|
||||
"name": "OpenH264-1.6",
|
||||
"schema_version": 1000
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"vendors": {
|
||||
"gmp-widevinecdm": {
|
||||
"platforms": {
|
||||
"WINNT_x86-msvc-x64": {
|
||||
"alias": "WINNT_x86-msvc"
|
||||
},
|
||||
"WINNT_x86-msvc": {
|
||||
"fileUrl": "https://redirector.gvt1.com/edgedl/widevine-cdm/903-win-ia32.zip",
|
||||
"hashValue": "d7e10d09c87a157af865f8388ba70ae672bd9e38987bdd94077af52d6b1abaa745b3db92e9f93f607af6420c68210f7cfd518a9d2c99fecf79aed3385cbcbc0b",
|
||||
"filesize": 2884452
|
||||
},
|
||||
"WINNT_x86-msvc-x86": {
|
||||
"alias": "WINNT_x86-msvc"
|
||||
},
|
||||
"Linux_x86_64-gcc3": {
|
||||
"fileUrl": "https://redirector.gvt1.com/edgedl/widevine-cdm/903-linux-x64.zip",
|
||||
"hashValue": "1edfb58a44792d2a53694f46fcc698161edafb2a1fe0e5c31b50c1d52408b5e8918d9f33271c62a19a65017694ebeacb4f390fe914688ca7b1952cdb84ed55ec",
|
||||
"filesize": 2975492
|
||||
},
|
||||
"Darwin_x86_64-gcc3-u-i386-x86_64": {
|
||||
"fileUrl": "https://redirector.gvt1.com/edgedl/widevine-cdm/903-mac-x64.zip",
|
||||
"hashValue": "1916805e84a49e04748204f4e4c48ae52c8312f7c04afedacacd7dfab2de424412bc988a8c3e5bcb0865f8844b569c0eb9589dae51e74d9bdfe46792c9d1631f",
|
||||
"filesize": 2155607
|
||||
},
|
||||
"Darwin_x86_64-gcc3": {
|
||||
"alias": "Darwin_x86_64-gcc3-u-i386-x86_64"
|
||||
},
|
||||
"Linux_x86-gcc3": {
|
||||
"fileUrl": "https://redirector.gvt1.com/edgedl/widevine-cdm/903-linux-ia32.zip",
|
||||
"hashValue": "5c4beb72ea693740a013b60bc5491a042bb82fa5ca6845a2f450579e2e1e465263f19e7ab6d08d91deb8219b30f092ab6e6745300d5adda627f270c95e5a66e0",
|
||||
"filesize": 3084582
|
||||
},
|
||||
"WINNT_x86_64-msvc-x64": {
|
||||
"alias": "WINNT_x86_64-msvc"
|
||||
},
|
||||
"WINNT_x86_64-msvc": {
|
||||
"fileUrl": "https://redirector.gvt1.com/edgedl/widevine-cdm/903-win-x64.zip",
|
||||
"hashValue": "33497f3458846e11fa52413f6477bfe1a7f502da262c3a2ce9fe6d773a4a2d023c54228596eb162444b55c87fb126de01f60fa729d897ef5e6eec73b2dfbdc7a",
|
||||
"filesize": 2853777
|
||||
}
|
||||
},
|
||||
"version": "1.4.8.903"
|
||||
}
|
||||
},
|
||||
"hashFunction": "sha512",
|
||||
"name": "Widevine-1.4.8.903",
|
||||
"schema_version": 1000
|
||||
}
|
|
@ -109,3 +109,6 @@ toolkit.jar:
|
|||
content/global/macWindowMenu.js
|
||||
#endif
|
||||
content/global/svg/svgBindings.xml (/layout/svg/resources/content/svgBindings.xml)
|
||||
content/global/gmp-sources/eme-adobe.json (gmp-sources/eme-adobe.json)
|
||||
content/global/gmp-sources/openh264.json (gmp-sources/openh264.json)
|
||||
content/global/gmp-sources/widevinecdm.json (gmp-sources/widevinecdm.json)
|
|
@ -21,7 +21,8 @@ XPCOMUtils.defineLazyGetter(this, "kDebug", () => {
|
|||
|
||||
const kContentChangeThresholdPx = 5;
|
||||
const kBrightTextSampleSize = 5;
|
||||
const kModalHighlightRepaintFreqMs = 100;
|
||||
const kModalHighlightRepaintLoFreqMs = 100;
|
||||
const kModalHighlightRepaintHiFreqMs = 16;
|
||||
const kHighlightAllPref = "findbar.highlightAll";
|
||||
const kModalHighlightPref = "findbar.modalHighlight";
|
||||
const kFontPropsCSS = ["color", "font-family", "font-kerning", "font-size",
|
||||
|
@ -1113,7 +1114,9 @@ FinderHighlighter.prototype = {
|
|||
/**
|
||||
* Doing a full repaint each time a range is delivered by the highlight iterator
|
||||
* is way too costly, thus we pipe the frequency down to every
|
||||
* `kModalHighlightRepaintFreqMs` milliseconds.
|
||||
* `kModalHighlightRepaintLoFreqMs` milliseconds. If there are dynamic ranges
|
||||
* found (see `_isInDynamicContainer()` for the definition), the frequency
|
||||
* will be upscaled to `kModalHighlightRepaintHiFreqMs`.
|
||||
*
|
||||
* @param {nsIDOMWindow} window
|
||||
* @param {Object} options Dictionary of painter hints that contains the
|
||||
|
@ -1134,7 +1137,8 @@ FinderHighlighter.prototype = {
|
|||
|
||||
window = window.top;
|
||||
let dict = this.getForWindow(window);
|
||||
let repaintDynamicRanges = ((scrollOnly || contentChanged) && !!dict.dynamicRangesSet.size);
|
||||
let hasDynamicRanges = !!dict.dynamicRangesSet.size;
|
||||
let repaintDynamicRanges = ((scrollOnly || contentChanged) && hasDynamicRanges);
|
||||
|
||||
// When we request to repaint unconditionally, we mean to call
|
||||
// `_repaintHighlightAllMask()` right after the timeout.
|
||||
|
@ -1164,7 +1168,7 @@ FinderHighlighter.prototype = {
|
|||
dict.unconditionalRepaintRequested = false;
|
||||
this._repaintHighlightAllMask(window);
|
||||
}
|
||||
}, kModalHighlightRepaintFreqMs);
|
||||
}, hasDynamicRanges ? kModalHighlightRepaintHiFreqMs : kModalHighlightRepaintLoFreqMs);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,18 @@ XPCOMUtils.defineLazyGetter(this, "gCertUtils", function() {
|
|||
return temp;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "isXPOrVista64", function () {
|
||||
let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
||||
if (os != "WINNT") {
|
||||
return false;
|
||||
}
|
||||
let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
|
||||
if (parseFloat(sysInfo.getProperty("version")) < 6) {
|
||||
return true;
|
||||
}
|
||||
return Services.appinfo.is64Bit;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
|
||||
"resource://gre/modules/UpdateUtils.jsm");
|
||||
|
||||
|
@ -80,7 +92,10 @@ GMPInstallManager.prototype = {
|
|||
/**
|
||||
* Performs an addon check.
|
||||
* @return a promise which will be resolved or rejected.
|
||||
* The promise is resolved with an array of GMPAddons
|
||||
* The promise is resolved with an object with properties:
|
||||
* gmpAddons: array of GMPAddons
|
||||
* usedFallback: whether the data was collected from online or
|
||||
* from fallback data within the build
|
||||
* The promise is rejected with an object with properties:
|
||||
* target: The XHR request object
|
||||
* status: The HTTP status code
|
||||
|
@ -104,12 +119,16 @@ GMPInstallManager.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
ProductAddonChecker.getProductAddonList(url, allowNonBuiltIn, certs).then((addons) => {
|
||||
if (!addons) {
|
||||
this._deferred.resolve([]);
|
||||
let addonPromise = ProductAddonChecker
|
||||
.getProductAddonList(url, allowNonBuiltIn, certs);
|
||||
|
||||
addonPromise.then(res => {
|
||||
if (!res || !res.gmpAddons) {
|
||||
this._deferred.resolve({gmpAddons: []});
|
||||
}
|
||||
else {
|
||||
this._deferred.resolve(addons.map(a => new GMPAddon(a)));
|
||||
res.gmpAddons = res.gmpAddons.map(a => new GMPAddon(a));
|
||||
this._deferred.resolve(res);
|
||||
}
|
||||
delete this._deferred;
|
||||
}, (ex) => {
|
||||
|
@ -201,7 +220,7 @@ GMPInstallManager.prototype = {
|
|||
}
|
||||
|
||||
try {
|
||||
let gmpAddons = yield this.checkForAddons();
|
||||
let {usedFallback, gmpAddons} = yield this.checkForAddons();
|
||||
this._updateLastCheck();
|
||||
log.info("Found " + gmpAddons.length + " addons advertised.");
|
||||
let addonsToInstall = gmpAddons.filter(function(gmpAddon) {
|
||||
|
@ -222,6 +241,19 @@ GMPInstallManager.prototype = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (gmpAddon.isEME && isXPOrVista64) {
|
||||
log.info("Addon |" + gmpAddon.id + "| not supported on this platform.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not install from fallback if already installed as it
|
||||
// may be a downgrade
|
||||
if (usedFallback && gmpAddon.isUpdate) {
|
||||
log.info("Addon |" + gmpAddon.id + "| not installing updates based " +
|
||||
"on fallback.");
|
||||
return false;
|
||||
}
|
||||
|
||||
let addonUpdateEnabled = false;
|
||||
if (GMP_PLUGIN_IDS.indexOf(gmpAddon.id) >= 0) {
|
||||
if (!this._isAddonEnabled(gmpAddon.id)) {
|
||||
|
@ -341,6 +373,14 @@ GMPAddon.prototype = {
|
|||
get isEME() {
|
||||
return this.id == "gmp-widevinecdm" || this.id.indexOf("gmp-eme-") == 0;
|
||||
},
|
||||
/**
|
||||
* @return true if the addon has been previously installed and this is
|
||||
* a new version, if this is a fresh install return false
|
||||
*/
|
||||
get isUpdate() {
|
||||
return this.version &&
|
||||
GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VERSION, false, this.id);
|
||||
},
|
||||
};
|
||||
/**
|
||||
* Constructs a GMPExtractor object which is used to extract a GMP zip
|
||||
|
|
|
@ -134,6 +134,7 @@ this.GMPPrefs = {
|
|||
KEY_CERT_REQUIREBUILTIN: "media.gmp-manager.cert.requireBuiltIn",
|
||||
KEY_UPDATE_LAST_CHECK: "media.gmp-manager.lastCheck",
|
||||
KEY_SECONDS_BETWEEN_CHECKS: "media.gmp-manager.secondsBetweenChecks",
|
||||
KEY_UPDATE_ENABLED: "media.gmp-manager.updateEnabled",
|
||||
KEY_APP_DISTRIBUTION: "distribution.id",
|
||||
KEY_APP_DISTRIBUTION_VERSION: "distribution.version",
|
||||
KEY_BUILDID: "media.gmp-manager.buildID",
|
||||
|
|
|
@ -67,10 +67,8 @@ add_test(function test_checkForAddons_uninitWithoutInstall() {
|
|||
overrideXHR(200, "");
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("no response should reject");
|
||||
}, err => {
|
||||
do_check_true(!!err);
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -83,10 +81,8 @@ add_test(function test_checkForAddons_noResponse() {
|
|||
overrideXHR(200, "");
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("no response should reject");
|
||||
}, err => {
|
||||
do_check_true(!!err);
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -98,8 +94,8 @@ add_test(function test_checkForAddons_noResponse() {
|
|||
add_task(function* test_checkForAddons_noAddonsElement() {
|
||||
overrideXHR(200, "<updates></updates>");
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 0);
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 0);
|
||||
installManager.uninit();
|
||||
});
|
||||
|
||||
|
@ -109,8 +105,8 @@ add_task(function* test_checkForAddons_noAddonsElement() {
|
|||
add_task(function* test_checkForAddons_emptyAddonsElement() {
|
||||
overrideXHR(200, "<updates><addons/></updates>");
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 0);
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 0);
|
||||
installManager.uninit();
|
||||
});
|
||||
|
||||
|
@ -121,10 +117,8 @@ add_test(function test_checkForAddons_wrongResponseXML() {
|
|||
overrideXHR(200, "<digits_of_pi>3.141592653589793....</digits_of_pi>");
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("response with the wrong root element should reject");
|
||||
}, err => {
|
||||
do_check_true(!!err);
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -137,11 +131,8 @@ add_test(function test_checkForAddons_404Error() {
|
|||
overrideXHR(404, "");
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("404 response should reject");
|
||||
}, err => {
|
||||
do_check_true(!!err);
|
||||
do_check_eq(err.status, 404);
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -155,10 +146,8 @@ add_test(function test_checkForAddons_abort() {
|
|||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
xhr.abort();
|
||||
promise.then(() => {
|
||||
do_throw("abort() should reject");
|
||||
}, err => {
|
||||
do_check_eq(err.status, 0);
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -171,10 +160,8 @@ add_test(function test_checkForAddons_timeout() {
|
|||
overrideXHR(200, "", { dropRequest: true, timeout: true });
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("Defensive timeout should reject");
|
||||
}, err => {
|
||||
do_check_eq(err.status, 0);
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -200,11 +187,8 @@ add_test(function test_checkForAddons_bad_ssl() {
|
|||
overrideXHR(200, "");
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("Defensive timeout should reject");
|
||||
}, err => {
|
||||
do_check_true(err.message.includes("SSL is required and URI scheme is " +
|
||||
"not https."));
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
if (PREF_KEY_URL_OVERRIDE_BACKUP) {
|
||||
Preferences.set(GMPScope.GMPPrefs.KEY_URL_OVERRIDE,
|
||||
|
@ -225,10 +209,9 @@ add_test(function test_checkForAddons_notXML() {
|
|||
overrideXHR(200, "3.141592653589793....");
|
||||
let installManager = new GMPInstallManager();
|
||||
let promise = installManager.checkForAddons();
|
||||
promise.then(() => {
|
||||
do_throw("non XML response should reject");
|
||||
}, err => {
|
||||
do_check_true(!!err);
|
||||
|
||||
promise.then(res => {
|
||||
do_check_true(res.usedFallback);
|
||||
installManager.uninit();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -251,9 +234,9 @@ add_task(function* test_checkForAddons_singleAddon() {
|
|||
"</updates>"
|
||||
overrideXHR(200, responseXML);
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 1);
|
||||
let gmpAddon= gmpAddons[0];
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 1);
|
||||
let gmpAddon = res.gmpAddons[0];
|
||||
do_check_eq(gmpAddon.id, "gmp-gmpopenh264");
|
||||
do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
|
||||
do_check_eq(gmpAddon.hashFunction, "sha256");
|
||||
|
@ -284,9 +267,9 @@ add_task(function* test_checkForAddons_singleAddonWithSize() {
|
|||
"</updates>"
|
||||
overrideXHR(200, responseXML);
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 1);
|
||||
let gmpAddon = gmpAddons[0];
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 1);
|
||||
let gmpAddon = res.gmpAddons[0];
|
||||
do_check_eq(gmpAddon.id, "openh264-plugin-no-at-symbol");
|
||||
do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
|
||||
do_check_eq(gmpAddon.hashFunction, "sha256");
|
||||
|
@ -353,9 +336,9 @@ add_task(function* test_checkForAddons_multipleAddonNoUpdatesSomeInvalid() {
|
|||
"</updates>"
|
||||
overrideXHR(200, responseXML);
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 7);
|
||||
let gmpAddon= gmpAddons[0];
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 7);
|
||||
let gmpAddon = res.gmpAddons[0];
|
||||
do_check_eq(gmpAddon.id, "gmp-gmpopenh264");
|
||||
do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
|
||||
do_check_eq(gmpAddon.hashFunction, "sha256");
|
||||
|
@ -364,7 +347,7 @@ add_task(function* test_checkForAddons_multipleAddonNoUpdatesSomeInvalid() {
|
|||
do_check_true(gmpAddon.isValid);
|
||||
do_check_false(gmpAddon.isInstalled);
|
||||
|
||||
gmpAddon= gmpAddons[1];
|
||||
gmpAddon = res.gmpAddons[1];
|
||||
do_check_eq(gmpAddon.id, "NOT-gmp-gmpopenh264");
|
||||
do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip");
|
||||
do_check_eq(gmpAddon.hashFunction, "sha512");
|
||||
|
@ -373,9 +356,9 @@ add_task(function* test_checkForAddons_multipleAddonNoUpdatesSomeInvalid() {
|
|||
do_check_true(gmpAddon.isValid);
|
||||
do_check_false(gmpAddon.isInstalled);
|
||||
|
||||
for (let i = 2; i < gmpAddons.length; i++) {
|
||||
do_check_false(gmpAddons[i].isValid);
|
||||
do_check_false(gmpAddons[i].isInstalled);
|
||||
for (let i = 2; i < res.gmpAddons.length; i++) {
|
||||
do_check_false(res.gmpAddons[i].isValid);
|
||||
do_check_false(res.gmpAddons[i].isInstalled);
|
||||
}
|
||||
installManager.uninit();
|
||||
});
|
||||
|
@ -401,9 +384,9 @@ add_task(function* test_checkForAddons_updatesWithAddons() {
|
|||
"</updates>"
|
||||
overrideXHR(200, responseXML);
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 1);
|
||||
let gmpAddon= gmpAddons[0];
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 1);
|
||||
let gmpAddon = res.gmpAddons[0];
|
||||
do_check_eq(gmpAddon.id, "gmp-gmpopenh264");
|
||||
do_check_eq(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
|
||||
do_check_eq(gmpAddon.hashFunction, "sha256");
|
||||
|
@ -455,9 +438,9 @@ function* test_checkForAddons_installAddon(id, includeSize, wantInstallReject) {
|
|||
|
||||
overrideXHR(200, responseXML);
|
||||
let installManager = new GMPInstallManager();
|
||||
let gmpAddons = yield installManager.checkForAddons();
|
||||
do_check_eq(gmpAddons.length, 1);
|
||||
let gmpAddon = gmpAddons[0];
|
||||
let res = yield installManager.checkForAddons();
|
||||
do_check_eq(res.gmpAddons.length, 1);
|
||||
let gmpAddon = res.gmpAddons[0];
|
||||
do_check_false(gmpAddon.isInstalled);
|
||||
|
||||
try {
|
||||
|
@ -588,9 +571,9 @@ add_test(function test_installAddon_noServer() {
|
|||
overrideXHR(200, responseXML);
|
||||
let installManager = new GMPInstallManager();
|
||||
let checkPromise = installManager.checkForAddons();
|
||||
checkPromise.then(gmpAddons => {
|
||||
do_check_eq(gmpAddons.length, 1);
|
||||
let gmpAddon= gmpAddons[0];
|
||||
checkPromise.then(res => {
|
||||
do_check_eq(res.gmpAddons.length, 1);
|
||||
let gmpAddon = res.gmpAddons[0];
|
||||
|
||||
GMPInstallManager.overrideLeaveDownloadedZip = true;
|
||||
let installPromise = installManager.installAddon(gmpAddon);
|
||||
|
|
|
@ -6,8 +6,23 @@
|
|||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
const LOCAL_EME_SOURCES = [{
|
||||
"id": "gmp-eme-adobe",
|
||||
"src": "chrome://global/content/gmp-sources/eme-adobe.json"
|
||||
}, {
|
||||
"id": "gmp-gmpopenh264",
|
||||
"src": "chrome://global/content/gmp-sources/openh264.json"
|
||||
}, {
|
||||
"id": "gmp-widevinecdm",
|
||||
"src": "chrome://global/content/gmp-sources/widevinecdm.json"
|
||||
}];
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "ProductAddonChecker" ];
|
||||
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"]);
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
Cu.import("resource://gre/modules/CertUtils.jsm");
|
||||
|
@ -15,7 +30,15 @@ Cu.import("resource://gre/modules/CertUtils.jsm");
|
|||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
/*globals OS*/
|
||||
|
||||
/*globals GMPPrefs */
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "GMPPrefs",
|
||||
"resource://gre/modules/GMPUtils.jsm");
|
||||
|
||||
/*globals OS */
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
|
||||
"resource://gre/modules/UpdateUtils.jsm");
|
||||
|
||||
var logger = Log.repository.getLogger("addons.productaddons");
|
||||
|
||||
|
@ -139,13 +162,34 @@ function downloadXML(url, allowNonBuiltIn = false, allowedCerts = null) {
|
|||
});
|
||||
}
|
||||
|
||||
function downloadJSON(uri) {
|
||||
logger.info("fetching config from: " + uri);
|
||||
return new Promise((resolve, reject) => {
|
||||
let xmlHttp = new XMLHttpRequest({mozAnon: true});
|
||||
|
||||
xmlHttp.onload = function(aResponse) {
|
||||
resolve(JSON.parse(this.responseText));
|
||||
};
|
||||
|
||||
xmlHttp.onerror = function(e) {
|
||||
reject("Fetching " + uri + " results in error code: " + e.target.status);
|
||||
};
|
||||
|
||||
xmlHttp.open("GET", uri);
|
||||
xmlHttp.overrideMimeType("application/json");
|
||||
xmlHttp.send();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a list of add-ons from a DOM document.
|
||||
*
|
||||
* @param document
|
||||
* The DOM document to parse.
|
||||
* @return null if there is no <addons> element otherwise an array of the addons
|
||||
* listed.
|
||||
* @return null if there is no <addons> element otherwise an object containing
|
||||
* an array of the addons listed and a field notifying whether the
|
||||
* fallback was used.
|
||||
*/
|
||||
function parseXML(document) {
|
||||
// Check that the root element is correct
|
||||
|
@ -175,7 +219,67 @@ function parseXML(document) {
|
|||
results.push(addon);
|
||||
}
|
||||
|
||||
return results;
|
||||
return {
|
||||
usedFallback: false,
|
||||
gmpAddons: results
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* If downloading from the network fails (AUS server is down),
|
||||
* load the sources from local build configuration.
|
||||
*/
|
||||
function downloadLocalConfig() {
|
||||
|
||||
if (!GMPPrefs.get(GMPPrefs.KEY_UPDATE_ENABLED, true)) {
|
||||
logger.info("Updates are disabled via media.gmp-manager.updateEnabled");
|
||||
return Promise.resolve({usedFallback: true, gmpAddons: []});
|
||||
}
|
||||
|
||||
return Promise.all(LOCAL_EME_SOURCES.map(conf => {
|
||||
return downloadJSON(conf.src).then(addons => {
|
||||
|
||||
let platforms = addons.vendors[conf.id].platforms;
|
||||
let target = Services.appinfo.OS + "_" + UpdateUtils.ABI;
|
||||
let details = null;
|
||||
|
||||
while (!details) {
|
||||
if (!(target in platforms)) {
|
||||
// There was no matching platform so return false, this addon
|
||||
// will be filtered from the results below
|
||||
logger.info("no details found for: " + target);
|
||||
return false;
|
||||
}
|
||||
// Field either has the details of the binary or is an alias
|
||||
// to another build target key that does
|
||||
if (platforms[target].alias) {
|
||||
target = platforms[target].alias;
|
||||
} else {
|
||||
details = platforms[target];
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("found plugin: " + conf.id);
|
||||
return {
|
||||
"id": conf.id,
|
||||
"URL": details.fileUrl,
|
||||
"hashFunction": addons.hashFunction,
|
||||
"hashValue": details.hashValue,
|
||||
"version": addons.vendors[conf.id].version,
|
||||
"size": details.filesize
|
||||
};
|
||||
});
|
||||
})).then(addons => {
|
||||
|
||||
// Some filters may not match this platform so
|
||||
// filter those out
|
||||
addons = addons.filter(x => x !== false);
|
||||
|
||||
return {
|
||||
usedFallback: true,
|
||||
gmpAddons: addons
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -313,11 +417,14 @@ const ProductAddonChecker = {
|
|||
* @param allowedCerts
|
||||
* The list of certificate attributes to match the SSL certificate
|
||||
* against or null to skip checks.
|
||||
* @return a promise that resolves to the list of add-ons or rejects with a JS
|
||||
* @return a promise that resolves to an object containing the list of add-ons
|
||||
* and whether the local fallback was used, or rejects with a JS
|
||||
* exception in case of error.
|
||||
*/
|
||||
getProductAddonList: function(url, allowNonBuiltIn = false, allowedCerts = null) {
|
||||
return downloadXML(url, allowNonBuiltIn, allowedCerts).then(parseXML);
|
||||
return downloadXML(url, allowNonBuiltIn, allowedCerts)
|
||||
.then(parseXML)
|
||||
.catch(downloadLocalConfig);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -3083,17 +3083,17 @@ this.XPIProvider = {
|
|||
url = UpdateUtils.formatUpdateURL(url);
|
||||
|
||||
logger.info(`Starting system add-on update check from ${url}.`);
|
||||
let addonList = yield ProductAddonChecker.getProductAddonList(url);
|
||||
let res = yield ProductAddonChecker.getProductAddonList(url);
|
||||
|
||||
// If there was no list then do nothing.
|
||||
if (!addonList) {
|
||||
if (!res || !res.gmpAddons) {
|
||||
logger.info("No system add-ons list was returned.");
|
||||
yield systemAddonLocation.cleanDirectories();
|
||||
return;
|
||||
}
|
||||
|
||||
addonList = new Map(
|
||||
addonList.map(spec => [spec.id, { spec, path: null, addon: null }]));
|
||||
let addonList = new Map(
|
||||
res.gmpAddons.map(spec => [spec.id, { spec, path: null, addon: null }]));
|
||||
|
||||
let getAddonsInLocation = (location) => {
|
||||
return new Promise(resolve => {
|
||||
|
|
|
@ -62,43 +62,23 @@ function compareFiles(file1, file2) {
|
|||
}
|
||||
|
||||
add_task(function* test_404() {
|
||||
try {
|
||||
let addons = yield ProductAddonChecker.getProductAddonList(root + "404.xml");
|
||||
do_throw("Should not have returned anything");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_true(true, "Expected to throw for a missing update file");
|
||||
}
|
||||
let res = yield ProductAddonChecker.getProductAddonList(root + "404.xml");
|
||||
do_check_true(res.usedFallback);
|
||||
});
|
||||
|
||||
add_task(function* test_not_xml() {
|
||||
try {
|
||||
let addons = yield ProductAddonChecker.getProductAddonList(root + "bad.txt");
|
||||
do_throw("Should not have returned anything");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_true(true, "Expected to throw for a non XML result");
|
||||
}
|
||||
let res = yield ProductAddonChecker.getProductAddonList(root + "bad.txt");
|
||||
do_check_true(res.usedFallback);
|
||||
});
|
||||
|
||||
add_task(function* test_invalid_xml() {
|
||||
try {
|
||||
let addons = yield ProductAddonChecker.getProductAddonList(root + "bad.xml");
|
||||
do_throw("Should not have returned anything");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_true(true, "Expected to throw for invalid XML");
|
||||
}
|
||||
let res = yield ProductAddonChecker.getProductAddonList(root + "bad.xml");
|
||||
do_check_true(res.usedFallback);
|
||||
});
|
||||
|
||||
add_task(function* test_wrong_xml() {
|
||||
try {
|
||||
let addons = yield ProductAddonChecker.getProductAddonList(root + "bad2.xml");
|
||||
do_throw("Should not have returned anything");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_true(true, "Expected to throw for a missing <updates> tag");
|
||||
}
|
||||
let res = yield ProductAddonChecker.getProductAddonList(root + "bad2.xml");
|
||||
do_check_true(res.usedFallback);
|
||||
});
|
||||
|
||||
add_task(function* test_missing() {
|
||||
|
@ -107,19 +87,19 @@ add_task(function* test_missing() {
|
|||
});
|
||||
|
||||
add_task(function* test_empty() {
|
||||
let addons = yield ProductAddonChecker.getProductAddonList(root + "empty.xml");
|
||||
do_check_true(Array.isArray(addons));
|
||||
do_check_eq(addons.length, 0);
|
||||
let res = yield ProductAddonChecker.getProductAddonList(root + "empty.xml");
|
||||
do_check_true(Array.isArray(res.gmpAddons));
|
||||
do_check_eq(res.gmpAddons.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* test_good_xml() {
|
||||
let addons = yield ProductAddonChecker.getProductAddonList(root + "good.xml");
|
||||
do_check_true(Array.isArray(addons));
|
||||
let res = yield ProductAddonChecker.getProductAddonList(root + "good.xml");
|
||||
do_check_true(Array.isArray(res.gmpAddons));
|
||||
|
||||
// There are three valid entries in the XML
|
||||
do_check_eq(addons.length, 5);
|
||||
do_check_eq(res.gmpAddons.length, 5);
|
||||
|
||||
let addon = addons[0];
|
||||
let addon = res.gmpAddons[0];
|
||||
do_check_eq(addon.id, "test1");
|
||||
do_check_eq(addon.URL, "http://example.com/test1.xpi");
|
||||
do_check_eq(addon.hashFunction, undefined);
|
||||
|
@ -127,7 +107,7 @@ add_task(function* test_good_xml() {
|
|||
do_check_eq(addon.version, undefined);
|
||||
do_check_eq(addon.size, undefined);
|
||||
|
||||
addon = addons[1];
|
||||
addon = res.gmpAddons[1];
|
||||
do_check_eq(addon.id, "test2");
|
||||
do_check_eq(addon.URL, "http://example.com/test2.xpi");
|
||||
do_check_eq(addon.hashFunction, "md5");
|
||||
|
@ -135,7 +115,7 @@ add_task(function* test_good_xml() {
|
|||
do_check_eq(addon.version, undefined);
|
||||
do_check_eq(addon.size, undefined);
|
||||
|
||||
addon = addons[2];
|
||||
addon = res.gmpAddons[2];
|
||||
do_check_eq(addon.id, "test3");
|
||||
do_check_eq(addon.URL, "http://example.com/test3.xpi");
|
||||
do_check_eq(addon.hashFunction, undefined);
|
||||
|
@ -143,7 +123,7 @@ add_task(function* test_good_xml() {
|
|||
do_check_eq(addon.version, "1.0");
|
||||
do_check_eq(addon.size, 45);
|
||||
|
||||
addon = addons[3];
|
||||
addon = res.gmpAddons[3];
|
||||
do_check_eq(addon.id, "test4");
|
||||
do_check_eq(addon.URL, undefined);
|
||||
do_check_eq(addon.hashFunction, undefined);
|
||||
|
@ -151,7 +131,7 @@ add_task(function* test_good_xml() {
|
|||
do_check_eq(addon.version, undefined);
|
||||
do_check_eq(addon.size, undefined);
|
||||
|
||||
addon = addons[4];
|
||||
addon = res.gmpAddons[4];
|
||||
do_check_eq(addon.id, undefined);
|
||||
do_check_eq(addon.URL, "http://example.com/test5.xpi");
|
||||
do_check_eq(addon.hashFunction, undefined);
|
||||
|
|
|
@ -289,19 +289,6 @@ const TEST_CONDITIONS = {
|
|||
* if missing the test condition's initialState is used.
|
||||
*/
|
||||
const TESTS = {
|
||||
// Test that an error response does nothing
|
||||
error: {
|
||||
test: function*() {
|
||||
try {
|
||||
yield install_system_addons("foobar");
|
||||
do_throw("Expected to fail the update check");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_true(true, "Expected to fail the update check");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// Test that a blank response does nothing
|
||||
blank: {
|
||||
updateList: null,
|
||||
|
|
Загрузка…
Ссылка в новой задаче