Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2016-02-29 11:44:03 +01:00
commit 63ee16b1e1
325 changed files with 5782 additions and 1848 deletions

View File

@ -64,7 +64,6 @@ browser/base/content/test/**
browser/base/content/newtab/**
browser/components/downloads/**
browser/components/feeds/**
browser/components/pocket/**
browser/components/preferences/**
browser/components/privatebrowsing/**
browser/components/sessionstore/**
@ -105,7 +104,6 @@ devtools/client/scratchpad/**
devtools/client/shadereditor/**
devtools/client/shared/**
devtools/client/sourceeditor/**
devtools/client/storage/**
devtools/client/tilt/**
devtools/client/webaudioeditor/**
devtools/client/webconsole/**
@ -182,7 +180,6 @@ toolkit/modules/tests/xpcshell/test_task.js
# Not yet updated
toolkit/components/osfile/**
toolkit/components/passwordmgr/**
# Uses preprocessing
toolkit/content/widgets/videocontrols.xml

View File

@ -4,15 +4,9 @@
<menu id="charsetMenu"
label="&charsetMenu2.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenu2.accesskey;"
#endif
oncommand="BrowserSetForcedCharacterSet(event.target.getAttribute('charset'));"
#ifdef OMIT_ACCESSKEYS
onpopupshowing="CharsetMenu.build(event.target, false);"
#else
onpopupshowing="CharsetMenu.build(event.target);"
#endif
onpopupshown="UpdateCurrentCharset(this);">
<menupopup>
</menupopup>

View File

@ -160,7 +160,7 @@ XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
XPCOMUtils.defineLazyGetter(this, "DeveloperToolbar", function() {
let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
let { DeveloperToolbar } = require("devtools/client/shared/developer-toolbar");
return new DeveloperToolbar(window, document.getElementById("developer-toolbar"));
return new DeveloperToolbar(window);
});
XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() {
@ -5492,9 +5492,9 @@ function BrowserCharsetReload()
}
function UpdateCurrentCharset(target) {
let selectedCharset = CharsetMenu.foldCharset(gBrowser.selectedBrowser.characterSet);
for (let menuItem of target.getElementsByTagName("menuitem")) {
let isSelected = menuItem.getAttribute("charset") ===
CharsetMenu.foldCharset(gBrowser.selectedBrowser.characterSet);
let isSelected = menuItem.getAttribute("charset") === selectedCharset;
menuItem.setAttribute("checked", isSelected);
}
}

View File

@ -1109,29 +1109,6 @@
<vbox id="browser-bottombox" layer="true">
<notificationbox id="global-notificationbox" notificationside="bottom"/>
<toolbar id="developer-toolbar"
hidden="true">
#ifdef XP_MACOSX
<toolbarbutton id="developer-toolbar-closebutton"
class="devtools-closebutton"
oncommand="DeveloperToolbar.hide();"
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
#endif
<stack class="gclitoolbar-stack-node" flex="1">
<textbox class="gclitoolbar-input-node" rows="1"/>
<hbox class="gclitoolbar-complete-node"/>
</stack>
<toolbarbutton id="developer-toolbar-toolbox-button"
class="developer-toolbar-button"
observes="devtoolsMenuBroadcaster_DevToolbox"
tooltiptext="&devToolbarToolsButton.tooltip;"/>
#ifndef XP_MACOSX
<toolbarbutton id="developer-toolbar-closebutton"
class="devtools-closebutton"
oncommand="DeveloperToolbar.hide();"
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
#endif
</toolbar>
</vbox>
<svg:svg height="0">

View File

@ -288,9 +288,8 @@ Sanitizer.prototype = {
}),
promiseClearPluginCookies: Task.async(function* (range) {
const phInterface = Ci.nsIPluginHost;
const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
const FLAG_CLEAR_ALL = Ci.nsIPluginHost.FLAG_CLEAR_ALL;
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
// Determine age range in seconds. (-1 means clear all.) We don't know
// that range[1] is actually now, so we compute age range based
@ -299,6 +298,13 @@ Sanitizer.prototype = {
if (!range || age >= 0) {
let tags = ph.getPluginTags();
for (let tag of tags) {
let refObj = {};
let probe = "";
if (/\bFlash\b/.test(tag.name)) {
probe = tag.loaded ? "FX_SANITIZE_LOADED_FLASH"
: "FX_SANITIZE_UNLOADED_FLASH";
TelemetryStopwatch.start(probe, refObj);
}
try {
let rv = yield new Promise(resolve =>
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, age, resolve)
@ -309,8 +315,14 @@ Sanitizer.prototype = {
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, -1, resolve)
);
}
if (probe) {
TelemetryStopwatch.finish(probe, refObj);
}
} catch (ex) {
// Ignore errors from plug-ins
if (probe) {
TelemetryStopwatch.cancel(probe, refObj);
}
}
}
}

View File

@ -142,7 +142,6 @@ skip-if = e10s # Bug 1093153 - no about:home support yet
[browser_alltabslistener.js]
[browser_audioTabIcon.js]
[browser_autocomplete_a11y_label.js]
skip-if = e10s # Bug 1101993 - times out for unknown reasons when run in the dir (works on its own)
[browser_autocomplete_cursor.js]
[browser_autocomplete_edit_completed.js]
[browser_autocomplete_enter_race.js]
@ -367,7 +366,7 @@ skip-if = buildapp == 'mulet'
[browser_popup_blocker.js]
skip-if = (os == 'linux') || (e10s && debug) # Frequent bug 1081925 and bug 1125520 failures
[browser_printpreview.js]
skip-if = buildapp == 'mulet' || e10s # Bug 1101973 - breaks the next test in e10s, and may be responsible for later timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
skip-if = buildapp == 'mulet'
[browser_private_browsing_window.js]
skip-if = buildapp == 'mulet'
[browser_private_no_prompt.js]
@ -393,11 +392,11 @@ skip-if = buildapp == 'mulet'
[browser_sanitizeDialog.js]
skip-if = buildapp == 'mulet'
[browser_save_link-perwindowpb.js]
skip-if = buildapp == 'mulet' || e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
skip-if = buildapp == 'mulet'
[browser_save_private_link_perwindowpb.js]
skip-if = buildapp == 'mulet' || e10s # e10s: Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
skip-if = buildapp == 'mulet'
[browser_save_link_when_window_navigates.js]
skip-if = buildapp == 'mulet' || e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
skip-if = buildapp == 'mulet'
[browser_save_video.js]
skip-if = buildapp == 'mulet'
[browser_save_video_frame.js]

View File

@ -51,6 +51,7 @@ function* test_bookmarks_popup({isNewBookmark, popupShowFn, popupEditFn,
if (!shouldAutoClose) {
yield new Promise(resolve => setTimeout(resolve, 400));
is(bookmarkPanel.state, "open", "Panel should still be 'open' for non-autoclose");
}
let hiddenPromise = promisePopupHidden(bookmarkPanel);
@ -144,7 +145,8 @@ add_task(function* panel_shown_for_new_bookmarks_mouseover_mouseout() {
yield new Promise(resolve => setTimeout(resolve, 400));
is(bookmarkPanel.state, "open", "Panel should still be open on mouseover");
},
*popupHideFn() {
let mouseOutPromise = new Promise(resolve => {
bookmarkPanel.addEventListener("mouseout", function onmouseout() {
bookmarkPanel.removeEventListener("mouseout", onmouseout);
@ -158,7 +160,7 @@ add_task(function* panel_shown_for_new_bookmarks_mouseover_mouseout() {
yield mouseOutPromise;
info("Got mouseout event, should autoclose now");
},
shouldAutoClose: true,
shouldAutoClose: false,
isBookmarkRemoved: false,
});
});
@ -208,7 +210,7 @@ add_task(function* panel_shown_for_new_bookmark_keypress_no_autoclose() {
});
});
add_task(function* contextmenu_new_bookmark_click_no_autoclose() {
add_task(function* contextmenu_new_bookmark_keypress_no_autoclose() {
yield test_bookmarks_popup({
isNewBookmark: true,
*popupShowFn(browser) {
@ -227,7 +229,7 @@ add_task(function* contextmenu_new_bookmark_click_no_autoclose() {
yield awaitPopupHidden;
},
popupEditFn() {
bookmarkPanelTitle.click();
EventUtils.sendChar("VK_TAB", window);
},
shouldAutoClose: false,
popupHideFn() {

View File

@ -1,14 +1,23 @@
let ourTab;
function test() {
waitForExplicitFinish();
ok(!gInPrintPreviewMode,
"Should NOT be in print preview mode at starting this tests");
// Skip access key test on platforms which don't support access key.
if (!/Win|Linux/.test(navigator.platform)) {
openPrintPreview(testClosePrintPreviewWithEscKey);
} else {
openPrintPreview(testClosePrintPreviewWithAccessKey);
}
BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", true).then(function(tab) {
ourTab = tab;
ok(!gInPrintPreviewMode,
"Should NOT be in print preview mode at starting this tests");
// Skip access key test on platforms which don't support access key.
if (!/Win|Linux/.test(navigator.platform)) {
openPrintPreview(testClosePrintPreviewWithEscKey);
} else {
openPrintPreview(testClosePrintPreviewWithAccessKey);
}
});
}
function tidyUp() {
BrowserTestUtils.removeTab(ourTab).then(finish);
}
function testClosePrintPreviewWithAccessKey() {
@ -34,7 +43,7 @@ function testClosePrintPreviewWithClosingWindowShortcutKey() {
checkPrintPreviewClosed(function (aSucceeded) {
ok(aSucceeded,
"print preview mode should be finished by closing window shortcut key");
finish();
tidyUp();
});
}

View File

@ -35,7 +35,7 @@ function triggerSave(aWindow, aCallback) {
{ type: "contextmenu", button: 2 },
testBrowser.contentWindow);
info("right clicked!");
}, testBrowser.contentWindow);
}, testBrowser);
}, false);
function contextMenuOpened(event) {

View File

@ -106,7 +106,7 @@ function test() {
EventUtils.synthesizeMouseAtCenter(img,
{ type: "contextmenu", button: 2 },
aWindow.gBrowser.contentWindow);
}, aWindow.gBrowser.selectedBrowser.contentWindow);
}, aWindow.gBrowser.selectedBrowser);
});
}

View File

@ -99,7 +99,6 @@ skip-if = os == "linux" # Intermittent failures
[browser_962884_opt_in_disable_hyphens.js]
[browser_963639_customizing_attribute_non_customizable_toolbar.js]
[browser_967000_button_charEncoding.js]
skip-if = e10s # Bug 1088710
[browser_967000_button_feeds.js]
[browser_967000_button_sync.js]
[browser_968447_bookmarks_toolbar_items_in_panel.js]
@ -127,7 +126,6 @@ skip-if = os == "linux"
[browser_987185_syncButton.js]
[browser_987492_window_api.js]
[browser_987640_charEncoding.js]
skip-if = e10s # Bug 1088710
[browser_988072_sidebar_events.js]
[browser_989338_saved_placements_not_resaved.js]
[browser_989751_subviewbutton_class.js]

View File

@ -6,9 +6,6 @@
const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test_967000_charEncoding_page.html";
var newTab;
var initialLocation = gBrowser.currentURI.spec;
add_task(function*() {
info("Check Character Encoding button functionality");
@ -28,14 +25,15 @@ add_task(function*() {
PanelUI.hide();
yield panelHidePromise;
newTab = gBrowser.selectedTab;
yield promiseTabLoadEvent(newTab, TEST_PAGE)
let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE, true, true);
yield PanelUI.show();
ok(!charEncodingButton.hasAttribute("disabled"), "The Character encoding button gets enabled");
charEncodingButton.click();
let characterEncodingView = document.getElementById("PanelUI-characterEncodingView");
let subviewShownPromise = subviewShown(characterEncodingView);
charEncodingButton.click();
yield subviewShownPromise;
ok(characterEncodingView.hasAttribute("current"), "The Character encoding panel is displayed");
let pinnedEncodings = document.getElementById("PanelUI-characterEncodingView-pinned");
@ -53,14 +51,12 @@ add_task(function*() {
panelHidePromise = promisePanelHidden(window);
PanelUI.hide();
yield panelHidePromise;
yield BrowserTestUtils.removeTab(newTab);
});
add_task(function* asyncCleanup() {
// reset the panel to the default state
yield resetCustomization();
ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
// restore the initial location
gBrowser.addTab(initialLocation);
gBrowser.removeTab(newTab);
});

View File

@ -5,7 +5,6 @@
"use strict";
const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test_967000_charEncoding_page.html";
var newTab = null;
add_task(function*() {
info("Check Character Encoding panel functionality");
@ -14,14 +13,15 @@ add_task(function*() {
CustomizableUI.addWidgetToArea("characterencoding-button",
CustomizableUI.AREA_PANEL);
newTab = gBrowser.addTab(TEST_PAGE);
yield promiseTabLoadEvent(gBrowser.selectedTab, TEST_PAGE);
let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE, true, true);
yield PanelUI.show();
let charEncodingButton = document.getElementById("characterencoding-button");
charEncodingButton.click();
let characterEncodingView = document.getElementById("PanelUI-characterEncodingView");
let subviewShownPromise = subviewShown(characterEncodingView);
charEncodingButton.click();
yield subviewShownPromise;
let checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
let initialEncoding = checkedButtons[0];
is(initialEncoding.getAttribute("label"), "Unicode", "The unicode encoding is initially selected");
@ -50,13 +50,11 @@ add_task(function*() {
charEncodingButton.click();
checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
is(checkedButtons[0].getAttribute("label"), "Unicode", "The encoding was reset to Unicode");
yield BrowserTestUtils.removeTab(newTab);
});
add_task(function* asyncCleanup() {
// reset the panel to the default state
yield resetCustomization();
ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
// remove the added tab
gBrowser.removeTab(newTab);
});

View File

@ -377,34 +377,50 @@ DistributionCustomizer.prototype = {
let localizedStr = Cc["@mozilla.org/pref-localizedstring;1"].
createInstance(Ci.nsIPrefLocalizedString);
if (sections["LocalizablePreferences"]) {
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences"))) {
var usedLocalizablePreferences = [];
if (sections["LocalizablePreferences-" + this._locale]) {
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
try {
let value = eval(this._ini.getString("LocalizablePreferences", key));
value = value.replace(/%LOCALE%/g, this._locale);
value = value.replace(/%LANGUAGE%/g, this._language);
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
if (value !== undefined) {
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
}
usedLocalizablePreferences.push(key);
} catch (e) { /* ignore bad prefs and move on */ }
}
}
if (sections["LocalizablePreferences-" + this._language]) {
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._language))) {
if (usedLocalizablePreferences.indexOf(key) > -1) {
continue;
}
try {
let value = eval(this._ini.getString("LocalizablePreferences-" + this._language, key));
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
if (value !== undefined) {
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
}
usedLocalizablePreferences.push(key);
} catch (e) { /* ignore bad prefs and move on */ }
}
}
if (sections["LocalizablePreferences-" + this._locale]) {
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
if (sections["LocalizablePreferences"]) {
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences"))) {
if (usedLocalizablePreferences.indexOf(key) > -1) {
continue;
}
try {
let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
let value = eval(this._ini.getString("LocalizablePreferences", key));
if (value !== undefined) {
value = value.replace(/%LOCALE%/g, this._locale);
value = value.replace(/%LANGUAGE%/g, this._language);
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
}
} catch (e) { /* ignore bad prefs and move on */ }
}
}

View File

@ -397,16 +397,20 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
}).api(),
create: function(createProperties) {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
function createInWindow(window) {
let url;
if (createProperties.url !== null) {
url = context.uri.resolve(createProperties.url);
} else {
url = window.BROWSER_NEW_TAB_URL;
if (!context.checkLoadURL(url, {dontReportErrors: true})) {
reject({message: `URL not allowed: ${url}`});
return;
}
}
let tab = window.gBrowser.addTab(url);
let tab = window.gBrowser.addTab(url || window.BROWSER_NEW_TAB_URL);
let active = true;
if (createProperties.active !== null) {
@ -460,10 +464,23 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
update: function(tabId, updateProperties) {
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
let tabbrowser = tab.ownerDocument.defaultView.gBrowser;
if (updateProperties.url !== null) {
tab.linkedBrowser.loadURI(updateProperties.url);
if (!tab) {
return Promise.reject({message: `No tab found with tabId: ${tabId}`});
}
let tabbrowser = tab.ownerDocument.defaultView.gBrowser;
if (updateProperties.url !== null) {
let url = context.uri.resolve(updateProperties.url);
if (!context.checkLoadURL(url, {dontReportErrors: true})) {
return Promise.reject({message: `URL not allowed: ${url}`});
}
tab.linkedBrowser.loadURI(url);
}
if (updateProperties.active !== null) {
if (updateProperties.active) {
tabbrowser.selectedTab = tab;
@ -626,7 +643,7 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
message, recipient);
},
_execute: function(tabId, details, kind) {
_execute: function(tabId, details, kind, method) {
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
let mm = tab.linkedBrowser.messageManager;
@ -635,6 +652,15 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
css: [],
};
// We require a `code` or a `file` property, but we can't accept both.
if ((details.code === null) == (details.file === null)) {
return Promise.reject({message: `${method} requires either a 'code' or a 'file' property, but not both`});
}
if (details.frameId !== null && details.allFrames) {
return Promise.reject({message: `'frameId' and 'allFrames' are mutually exclusive`});
}
let recipient = {
innerWindowID: tab.linkedBrowser.innerWindowID,
};
@ -660,22 +686,27 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
if (details.allFrames) {
options.all_frames = details.allFrames;
}
if (details.frameId !== null) {
options.frame_id = details.frameId;
}
if (details.matchAboutBlank) {
options.match_about_blank = details.matchAboutBlank;
}
if (details.runAt !== null) {
options.run_at = details.runAt;
} else {
options.run_at = "document_idle";
}
return context.sendMessage(mm, "Extension:Execute", {options}, recipient);
},
executeScript: function(tabId, details) {
return self.tabs._execute(tabId, details, "js");
return self.tabs._execute(tabId, details, "js", "executeScript");
},
insertCSS: function(tabId, details) {
return self.tabs._execute(tabId, details, "css");
return self.tabs._execute(tabId, details, "css", "insertCSS");
},
connect: function(tabId, connectInfo) {

View File

@ -7,6 +7,8 @@ support-files =
context_tabs_onUpdated_iframe.html
file_popup_api_injection_a.html
file_popup_api_injection_b.html
file_iframe_document.html
file_iframe_document.sjs
[browser_ext_simple.js]
[browser_ext_commands.js]
@ -29,12 +31,15 @@ support-files =
[browser_ext_tabs_executeScript.js]
[browser_ext_tabs_executeScript_good.js]
[browser_ext_tabs_executeScript_bad.js]
[browser_ext_tabs_executeScript_runAt.js]
[browser_ext_tabs_insertCSS.js]
[browser_ext_tabs_query.js]
[browser_ext_tabs_getCurrent.js]
[browser_ext_tabs_create.js]
[browser_ext_tabs_create_invalid_url.js]
[browser_ext_tabs_duplicate.js]
[browser_ext_tabs_update.js]
[browser_ext_tabs_update_url.js]
[browser_ext_tabs_onUpdated.js]
[browser_ext_tabs_sendMessage.js]
[browser_ext_tabs_move.js]
@ -43,4 +48,4 @@ support-files =
[browser_ext_windows_update.js]
[browser_ext_contentscript_connect.js]
[browser_ext_tab_runtimeConnect.js]
[browser_ext_webNavigation_getFrames.js]
[browser_ext_webNavigation_getFrames.js]

View File

@ -0,0 +1,66 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function* testTabsCreateInvalidURL(tabsCreateURL) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["tabs"],
},
background: function() {
browser.test.sendMessage("ready");
browser.test.onMessage.addListener((msg, tabsCreateURL) => {
browser.tabs.create({url: tabsCreateURL}, (tab) => {
browser.test.assertEq(undefined, tab, "on error tab should be undefined");
browser.test.assertTrue(/URL not allowed/.test(browser.runtime.lastError.message),
"runtime.lastError should report the expected error message");
// Remove the opened tab is any.
if (tab) {
browser.tabs.remove(tab.id);
}
browser.test.sendMessage("done");
});
});
},
});
yield extension.startup();
yield extension.awaitMessage("ready");
info(`test tab.create on invalid URL "${tabsCreateURL}"`);
extension.sendMessage("start", tabsCreateURL);
yield extension.awaitMessage("done");
yield extension.unload();
}
add_task(function* () {
info("Start testing tabs.create on invalid URLs");
let dataURLPage = `data:text/html,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>data url page</h1>
</body>
</html>`;
let testCases = [
{tabsCreateURL: "about:addons"},
{tabsCreateURL: "javascript:console.log('tabs.update execute javascript')"},
{tabsCreateURL: dataURLPage},
];
for (let {tabsCreateURL} of testCases) {
yield* testTabsCreateInvalidURL(tabsCreateURL);
}
info("done");
});

View File

@ -8,33 +8,134 @@ add_task(function* testExecuteScript() {
let messageManagersSize = MessageChannel.messageManagers.size;
let responseManagersSize = MessageChannel.responseManagers.size;
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/", true);
const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
const URL = BASE + "file_iframe_document.html";
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URL, true);
function background() {
browser.tabs.executeScript({
file: "script.js",
code: "42",
}, result => {
browser.test.assertEq(42, result, "Expected callback result");
browser.test.sendMessage("got result", result);
});
browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
return browser.webNavigation.getAllFrames({tabId: tabs[0].id});
}).then(frames => {
browser.test.log(`FRAMES: ${frames[1].frameId} ${JSON.stringify(frames)}\n`);
return Promise.all([
browser.tabs.executeScript({
code: "42",
}).then(result => {
browser.test.assertEq(42, result, "Expected callback result");
}),
browser.tabs.executeScript({
file: "script2.js",
}, result => {
browser.test.assertEq(27, result, "Expected callback result");
browser.test.sendMessage("got callback", result);
});
browser.tabs.executeScript({
file: "script.js",
code: "42",
}).then(result => {
browser.test.fail("Expected not to be able to execute a script with both file and code");
}, error => {
browser.test.assertTrue(/a 'code' or a 'file' property, but not both/.test(error.message),
"Got expected error");
}),
browser.runtime.onMessage.addListener(message => {
browser.test.assertEq("script ran", message, "Expected runtime message");
browser.test.sendMessage("got message", message);
browser.tabs.executeScript({
file: "script.js",
}).then(result => {
browser.test.assertEq(undefined, result, "Expected callback result");
}),
browser.tabs.executeScript({
file: "script2.js",
}).then(result => {
browser.test.assertEq(27, result, "Expected callback result");
}),
browser.tabs.executeScript({
code: "location.href;",
allFrames: true,
}).then(result => {
browser.test.assertTrue(Array.isArray(result), "Result is an array");
browser.test.assertEq(2, result.length, "Result has correct length");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
}),
browser.tabs.executeScript({
code: "location.href;",
runAt: "document_end",
}).then(result => {
browser.test.assertTrue(typeof(result) == "string", "Result is a string");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result), "Result is correct");
}),
browser.tabs.executeScript({
code: "window",
}).then(result => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
browser.test.assertEq("Script returned non-structured-clonable data",
error.message, "Got expected error");
}),
browser.tabs.executeScript({
code: "Promise.resolve(window)",
}).then(result => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
browser.test.assertEq("Script returned non-structured-clonable data",
error.message, "Got expected error");
}),
browser.tabs.executeScript({
code: "Promise.resolve(42)",
}).then(result => {
browser.test.assertEq(42, result, "Got expected promise resolution value as result");
}),
browser.tabs.executeScript({
code: "location.href;",
runAt: "document_end",
allFrames: true,
}).then(result => {
browser.test.assertTrue(Array.isArray(result), "Result is an array");
browser.test.assertEq(2, result.length, "Result has correct length");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
}),
browser.tabs.executeScript({
code: "location.href;",
frameId: frames[0].frameId,
}).then(result => {
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result), `Result for frameId[0] is correct: ${result}`);
}),
browser.tabs.executeScript({
code: "location.href;",
frameId: frames[1].frameId,
}).then(result => {
browser.test.assertEq("http://mochi.test:8888/", result, "Result for frameId[1] is correct");
}),
new Promise(resolve => {
browser.runtime.onMessage.addListener(message => {
browser.test.assertEq("script ran", message, "Expected runtime message");
resolve();
});
}),
]);
}).then(() => {
browser.test.notifyPass("executeScript");
}).catch(e => {
browser.test.fail(`Error: ${e} :: ${e.stack}`);
browser.test.notifyFail("executeScript");
});
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["http://mochi.test/"],
"permissions": ["http://mochi.test/", "webNavigation"],
},
background,
@ -50,9 +151,7 @@ add_task(function* testExecuteScript() {
yield extension.startup();
yield extension.awaitMessage("got result");
yield extension.awaitMessage("got callback");
yield extension.awaitMessage("got message");
yield extension.awaitFinish("executeScript");
yield extension.unload();

View File

@ -0,0 +1,110 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
/**
* These tests ensure that the runAt argument to tabs.executeScript delays
* script execution until the document has reached the correct state.
*
* Since tests of this nature are especially race-prone, it relies on a
* server-JS script to delay the completion of our test page's load cycle long
* enough for us to attempt to load our scripts in the earlies phase we support.
*
* And since we can't actually rely on that timing, it retries any attempts that
* fail to load as early as expected, but don't load at any illegal time.
*/
add_task(function* testExecuteScript() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true);
function background() {
let tab;
const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
const URL = BASE + "file_iframe_document.sjs";
const MAX_TRIES = 10;
let tries = 0;
function again() {
if (tries++ == MAX_TRIES) {
return Promise.reject(new Error("Max tries exceeded"));
}
let loadingPromise = new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId, changed, tab_) {
if (tabId == tab.id && changed.status == "loading" && tab_.url == URL) {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
});
});
// TODO: Test allFrames and frameId.
return browser.tabs.update({url: URL}).then(() => {
return loadingPromise;
}).then(() => {
return Promise.all([
// Send the executeScript requests in the reverse order that we expect
// them to execute in, to avoid them passing only because of timing
// races.
browser.tabs.executeScript({
code: "document.readyState",
runAt: "document_idle",
}),
browser.tabs.executeScript({
code: "document.readyState",
runAt: "document_end",
}),
browser.tabs.executeScript({
code: "document.readyState",
runAt: "document_start",
}),
].reverse());
}).then(states => {
browser.test.log(`Got states: ${states}`);
// Make sure that none of our scripts executed earlier than expected,
// regardless of retries.
browser.test.assertTrue(states[1] == "interactive" || states[1] == "complete",
`document_end state is valid: ${states[1]}`);
browser.test.assertTrue(states[2] == "complete",
`document_idle state is valid: ${states[2]}`);
// If we have the earliest valid states for each script, we're done.
// Otherwise, try again.
if (states[0] != "loading" || states[1] != "interactive" || states[2] != "complete") {
return again();
}
});
}
browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
tab = tabs[0];
return again();
}).then(() => {
browser.test.notifyPass("executeScript-runAt");
}).catch(e => {
browser.test.fail(`Error: ${e} :: ${e.stack}`);
browser.test.notifyFail("executeScript-runAt");
});
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["http://mochi.test/", "tabs"],
},
background,
});
yield extension.startup();
yield extension.awaitFinish("executeScript-runAt");
yield extension.unload();
yield BrowserTestUtils.removeTab(tab);
});

View File

@ -13,39 +13,20 @@ add_task(function* testExecuteScript() {
function background() {
let promises = [
{
background: "rgb(0, 0, 0)",
foreground: "rgb(255, 192, 203)",
promise: resolve => {
browser.tabs.insertCSS({
file: "file1.css",
code: "* { background: black }",
}, result => {
browser.test.assertEq(undefined, result, "Expected callback result");
resolve();
});
},
},
{
background: "rgb(0, 0, 0)",
background: "transparent",
foreground: "rgb(0, 113, 4)",
promise: resolve => {
browser.tabs.insertCSS({
promise: () => {
return browser.tabs.insertCSS({
file: "file2.css",
}, result => {
browser.test.assertEq(undefined, result, "Expected callback result");
resolve();
});
},
},
{
background: "rgb(42, 42, 42)",
foreground: "rgb(0, 113, 4)",
promise: resolve => {
browser.tabs.insertCSS({
promise: () => {
return browser.tabs.insertCSS({
code: "* { background: rgb(42, 42, 42) }",
}, result => {
browser.test.assertEq(undefined, result, "Expected callback result");
resolve();
});
},
},
@ -58,23 +39,29 @@ add_task(function* testExecuteScript() {
function next() {
if (!promises.length) {
browser.test.notifyPass("insertCSS");
return;
}
let {promise, background, foreground} = promises.shift();
new Promise(promise).then(() => {
browser.tabs.executeScript({
return promise().then(result => {
browser.test.assertEq(undefined, result, "Expected callback result");
return browser.tabs.executeScript({
code: `(${checkCSS})()`,
}, result => {
browser.test.assertEq(background, result[0], "Expected background color");
browser.test.assertEq(foreground, result[1], "Expected foreground color");
next();
});
}).then(result => {
browser.test.assertEq(background, result[0], "Expected background color");
browser.test.assertEq(foreground, result[1], "Expected foreground color");
return next();
});
}
next();
next().then(() => {
browser.test.notifyPass("insertCSS");
}).catch(e => {
browser.test.fail(`Error: ${e} :: ${e.stack}`);
browser.test.notifyFailure("insertCSS");
});
}
let extension = ExtensionTestUtils.loadExtension({
@ -85,7 +72,6 @@ add_task(function* testExecuteScript() {
background,
files: {
"file1.css": "* { color: pink }",
"file2.css": "* { color: rgb(0, 113, 4) }",
},
});

View File

@ -159,7 +159,7 @@ add_task(function* test_url() {
browser.test.assertEq(tabId, tab.id, "Check tab id");
browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
if ("url" in changeInfo) {
browser.test.assertEq("about:preferences", changeInfo.url,
browser.test.assertEq("about:blank", changeInfo.url,
"Check changeInfo.url");
browser.tabs.onUpdated.removeListener(onUpdated);
// Remove created tab.
@ -168,7 +168,7 @@ add_task(function* test_url() {
return;
}
});
browser.tabs.update(tab.id, {url: "about:preferences"});
browser.tabs.update(tab.id, {url: "about:blank"});
});
});
});

View File

@ -0,0 +1,120 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function* testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["tabs"],
},
files: {
"tab.html": `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>tab page</h1>
</body>
</html>
`.trim(),
},
background: function() {
browser.test.sendMessage("ready", browser.runtime.getURL("tab.html"));
browser.test.onMessage.addListener((msg, tabsUpdateURL, isErrorExpected) => {
let onTabsUpdated = (tab) => {
if (isErrorExpected) {
browser.test.fail(`tabs.update with URL ${tabsUpdateURL} should be rejected`);
} else {
browser.test.assertTrue(tab, "on success the tab should be defined");
}
};
let onTabsUpdateError = (error) => {
if (!isErrorExpected) {
browser.test.fails(`tabs.update with URL ${tabsUpdateURL} should not be rejected`);
} else {
browser.test.assertTrue(/^URL not allowed/.test(error.message),
"tabs.update should be rejected with the expected error message");
}
};
let onTabsUpdateDone = () => browser.test.sendMessage("done");
browser.tabs.query({lastFocusedWindow: true}, (tabs) => {
browser.tabs.update(tabs[1].id, {url: tabsUpdateURL})
.then(onTabsUpdated, onTabsUpdateError)
.then(onTabsUpdateDone);
});
});
},
});
yield extension.startup();
let mozExtTabURL = yield extension.awaitMessage("ready");
if (tabsUpdateURL == "self") {
tabsUpdateURL = mozExtTabURL;
}
info(`tab.update URL "${tabsUpdateURL}" on tab with URL "${existentTabURL}"`);
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, existentTabURL);
extension.sendMessage("start", tabsUpdateURL, isErrorExpected);
yield extension.awaitMessage("done");
yield BrowserTestUtils.removeTab(tab1);
yield extension.unload();
}
add_task(function* () {
info("Start testing tabs.update on javascript URLs");
let dataURLPage = `data:text/html,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>data url page</h1>
</body>
</html>`;
let checkList = [
{
tabsUpdateURL: "http://example.net",
isErrorExpected: false,
},
{
tabsUpdateURL: "self",
isErrorExpected: false,
},
{
tabsUpdateURL: "about:addons",
isErrorExpected: true,
},
{
tabsUpdateURL: "javascript:console.log('tabs.update execute javascript')",
isErrorExpected: true,
},
{
tabsUpdateURL: dataURLPage,
isErrorExpected: true,
},
];
let testCases = checkList
.map((check) => Object.assign({}, check, {existentTabURL: "about:blank"}));
for (let {existentTabURL, tabsUpdateURL, isErrorExpected} of testCases) {
yield* testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected);
}
info("done");
});

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<iframe src="/"></iframe>
</body>
</html>

View File

@ -0,0 +1,40 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */
"use strict";
// This script slows the load of an HTML document so that we can reliably test
// all phases of the load cycle supported by the extension API.
/* eslint-disable no-unused-vars */
const DELAY = 1 * 1000; // Delay one second before completing the request.
const Ci = Components.interfaces;
let nsTimer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
let timer;
function handleRequest(request, response) {
response.processAsync();
response.setHeader("Content-Type", "text/html", false);
response.write(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
`);
// Note: We need to store a reference to the timer to prevent it from being
// canceled when it's GCed.
timer = new nsTimer(() => {
response.write(`
<iframe src="/"></iframe>
</body>
</html>`);
response.finish();
}, DELAY, Ci.nsITimer.TYPE_ONE_SHOT);
}

View File

@ -972,7 +972,7 @@ PlacesController.prototype = {
PlacesUtils.bhistory.removePages(URIslice, URIslice.length);
Services.tm.mainThread.dispatch(() => gen.next(),
Ci.nsIThread.DISPATCH_NORMAL);
yield unefined;
yield undefined;
}
}
let gen = pagesChunkGenerator(URIs);

View File

@ -15,18 +15,21 @@ distribution.test.bool.false=false
[LocalizablePreferences]
distribution.test.locale="%LOCALE%"
distribution.test.reset="Set"
distribution.test.locale.set="First Set"
distribution.test.language.set="First Set"
distribution.test.language.reset="Preference Set"
distribution.test.locale.reset="Preference Set"
distribution.test.locale.set="Preference Set"
distribution.test.language.set="Preference Set"
[LocalizablePreferences-en]
distribution.test.language.en="en"
distribution.test.language.set="Second Set"
distribution.test.language.reset=
distribution.test.language.set="Language Set"
distribution.test.locale.set="Language Set"
[LocalizablePreferences-en-US]
distribution.test.locale.en-US="en-US"
distribution.test.reset=
distribution.test.locale.set="Second Set"
distribution.test.locale.reset=
distribution.test.locale.set="Locale Set"
[LocalizablePreferences-de]
distribution.test.locale.de="de"

View File

@ -71,11 +71,14 @@ add_task(function* () {
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.en", Ci.nsIPrefLocalizedString).data, "en");
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.en-US", Ci.nsIPrefLocalizedString).data, "en-US");
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.locale.de", Ci.nsIPrefLocalizedString));
// This value was never set because of the empty language specific pref
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.language.reset", Ci.nsIPrefLocalizedString));
// This value was never set because of the empty locale specific pref
// This testcase currently fails - the value is set to "undefined" - it should not be set at all (throw)
// Assert.throws(() => Services.prefs.getComplexValue("distribution.test.reset", Ci.nsIPrefLocalizedString));
// This value was overriden by a locale specific setting
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Second Set");
// This value was overriden by a language specific setting
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Second Set");
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.locale.reset", Ci.nsIPrefLocalizedString));
// This value was overridden by a locale specific setting
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Locale Set");
// This value was overridden by a language specific setting
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Language Set");
// Language should not override locale
Assert.notEqual(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Language Set");
});

View File

@ -1,3 +1,3 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.4.83
Current extension version is: 1.4.95

View File

@ -288,7 +288,7 @@ ChromeActions.prototype = {
try {
// contentDisposition/contentDispositionFilename is readonly before FF18
channel.contentDisposition = Ci.nsIChannel.DISPOSITION_ATTACHMENT;
if (self.contentDispositionFilename) {
if (self.contentDispositionFilename && !data.isAttachment) {
channel.contentDispositionFilename = self.contentDispositionFilename;
} else {
channel.contentDispositionFilename = filename;

View File

@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdf = {}));
// Use strict in our context only - users might not want it
'use strict';
var pdfjsVersion = '1.4.83';
var pdfjsBuild = '0629fd0';
var pdfjsVersion = '1.4.95';
var pdfjsBuild = '2b813c0';
var pdfjsFilePath =
typeof document !== 'undefined' && document.currentScript ?
@ -407,6 +407,17 @@ var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
font: 'font'
};
// Gets the file name from a given URL.
function getFilenameFromUrl(url) {
var anchor = url.indexOf('#');
var query = url.indexOf('?');
var end = Math.min(
anchor > 0 ? anchor : url.length,
query > 0 ? query : url.length);
return url.substring(url.lastIndexOf('/', end) + 1, end);
}
PDFJS.getFilenameFromUrl = getFilenameFromUrl;
// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
// absolute URL, it will be returned as is.
function combineUrl(baseUrl, url) {
@ -1537,6 +1548,7 @@ exports.combineUrl = combineUrl;
exports.createPromiseCapability = createPromiseCapability;
exports.deprecated = deprecated;
exports.error = error;
exports.getFilenameFromUrl = getFilenameFromUrl;
exports.getLookupTableFactory = getLookupTableFactory;
exports.info = info;
exports.isArray = isArray;
@ -1577,6 +1589,7 @@ var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType;
var AnnotationType = sharedUtil.AnnotationType;
var Util = sharedUtil.Util;
var addLinkAttributes = sharedUtil.addLinkAttributes;
var getFilenameFromUrl = sharedUtil.getFilenameFromUrl;
var warn = sharedUtil.warn;
var CustomStyle = displayDOMUtils.CustomStyle;
@ -1587,6 +1600,7 @@ var CustomStyle = displayDOMUtils.CustomStyle;
* @property {PDFPage} page
* @property {PageViewport} viewport
* @property {IPDFLinkService} linkService
* @property {DownloadManager} downloadManager
*/
/**
@ -1628,6 +1642,9 @@ AnnotationElementFactory.prototype =
case AnnotationType.STRIKEOUT:
return new StrikeOutAnnotationElement(parameters);
case AnnotationType.FILEATTACHMENT:
return new FileAttachmentAnnotationElement(parameters);
default:
return new AnnotationElement(parameters);
}
@ -1646,6 +1663,7 @@ var AnnotationElement = (function AnnotationElementClosure() {
this.page = parameters.page;
this.viewport = parameters.viewport;
this.linkService = parameters.linkService;
this.downloadManager = parameters.downloadManager;
if (isRenderable) {
this.container = this._createContainer();
@ -1744,6 +1762,43 @@ var AnnotationElement = (function AnnotationElementClosure() {
return container;
},
/**
* Create a popup for the annotation's HTML element. This is used for
* annotations that do not have a Popup entry in the dictionary, but
* are of a type that works with popups (such as Highlight annotations).
*
* @private
* @param {HTMLSectionElement} container
* @param {HTMLDivElement|HTMLImageElement|null} trigger
* @param {Object} data
* @memberof AnnotationElement
*/
_createPopup:
function AnnotationElement_createPopup(container, trigger, data) {
// If no trigger element is specified, create it.
if (!trigger) {
trigger = document.createElement('div');
trigger.style.height = container.style.height;
trigger.style.width = container.style.width;
container.appendChild(trigger);
}
var popupElement = new PopupElement({
container: container,
trigger: trigger,
color: data.color,
title: data.title,
contents: data.contents,
hideWrapper: true
});
var popup = popupElement.render();
// Position the popup next to the annotation's container.
popup.style.left = container.style.width;
container.appendChild(popup);
},
/**
* Render the annotation's HTML element in the empty container.
*
@ -1872,20 +1927,7 @@ var TextAnnotationElement = (function TextAnnotationElementClosure() {
image.dataset.l10nArgs = JSON.stringify({type: this.data.name});
if (!this.data.hasPopup) {
var popupElement = new PopupElement({
container: this.container,
trigger: image,
color: this.data.color,
title: this.data.title,
contents: this.data.contents,
hideWrapper: true
});
var popup = popupElement.render();
// Position the popup next to the Text annotation's container.
popup.style.left = image.style.width;
this.container.appendChild(popup);
this._createPopup(this.container, image, this.data);
}
this.container.appendChild(image);
@ -2162,7 +2204,9 @@ var PopupElement = (function PopupElementClosure() {
var HighlightAnnotationElement = (
function HighlightAnnotationElementClosure() {
function HighlightAnnotationElement(parameters) {
AnnotationElement.call(this, parameters, true);
var isRenderable = !!(parameters.data.hasPopup ||
parameters.data.title || parameters.data.contents);
AnnotationElement.call(this, parameters, isRenderable);
}
Util.inherit(HighlightAnnotationElement, AnnotationElement, {
@ -2175,6 +2219,11 @@ var HighlightAnnotationElement = (
*/
render: function HighlightAnnotationElement_render() {
this.container.className = 'highlightAnnotation';
if (!this.data.hasPopup) {
this._createPopup(this.container, null, this.data);
}
return this.container;
}
});
@ -2189,7 +2238,9 @@ var HighlightAnnotationElement = (
var UnderlineAnnotationElement = (
function UnderlineAnnotationElementClosure() {
function UnderlineAnnotationElement(parameters) {
AnnotationElement.call(this, parameters, true);
var isRenderable = !!(parameters.data.hasPopup ||
parameters.data.title || parameters.data.contents);
AnnotationElement.call(this, parameters, isRenderable);
}
Util.inherit(UnderlineAnnotationElement, AnnotationElement, {
@ -2202,6 +2253,11 @@ var UnderlineAnnotationElement = (
*/
render: function UnderlineAnnotationElement_render() {
this.container.className = 'underlineAnnotation';
if (!this.data.hasPopup) {
this._createPopup(this.container, null, this.data);
}
return this.container;
}
});
@ -2215,7 +2271,9 @@ var UnderlineAnnotationElement = (
*/
var SquigglyAnnotationElement = (function SquigglyAnnotationElementClosure() {
function SquigglyAnnotationElement(parameters) {
AnnotationElement.call(this, parameters, true);
var isRenderable = !!(parameters.data.hasPopup ||
parameters.data.title || parameters.data.contents);
AnnotationElement.call(this, parameters, isRenderable);
}
Util.inherit(SquigglyAnnotationElement, AnnotationElement, {
@ -2228,6 +2286,11 @@ var SquigglyAnnotationElement = (function SquigglyAnnotationElementClosure() {
*/
render: function SquigglyAnnotationElement_render() {
this.container.className = 'squigglyAnnotation';
if (!this.data.hasPopup) {
this._createPopup(this.container, null, this.data);
}
return this.container;
}
});
@ -2242,7 +2305,9 @@ var SquigglyAnnotationElement = (function SquigglyAnnotationElementClosure() {
var StrikeOutAnnotationElement = (
function StrikeOutAnnotationElementClosure() {
function StrikeOutAnnotationElement(parameters) {
AnnotationElement.call(this, parameters, true);
var isRenderable = !!(parameters.data.hasPopup ||
parameters.data.title || parameters.data.contents);
AnnotationElement.call(this, parameters, isRenderable);
}
Util.inherit(StrikeOutAnnotationElement, AnnotationElement, {
@ -2255,6 +2320,11 @@ var StrikeOutAnnotationElement = (
*/
render: function StrikeOutAnnotationElement_render() {
this.container.className = 'strikeoutAnnotation';
if (!this.data.hasPopup) {
this._createPopup(this.container, null, this.data);
}
return this.container;
}
});
@ -2262,6 +2332,62 @@ var StrikeOutAnnotationElement = (
return StrikeOutAnnotationElement;
})();
/**
* @class
* @alias FileAttachmentAnnotationElement
*/
var FileAttachmentAnnotationElement = (
function FileAttachmentAnnotationElementClosure() {
function FileAttachmentAnnotationElement(parameters) {
AnnotationElement.call(this, parameters, true);
this.filename = getFilenameFromUrl(parameters.data.file.filename);
this.content = parameters.data.file.content;
}
Util.inherit(FileAttachmentAnnotationElement, AnnotationElement, {
/**
* Render the file attachment annotation's HTML element in the empty
* container.
*
* @public
* @memberof FileAttachmentAnnotationElement
* @returns {HTMLSectionElement}
*/
render: function FileAttachmentAnnotationElement_render() {
this.container.className = 'fileAttachmentAnnotation';
var trigger = document.createElement('div');
trigger.style.height = this.container.style.height;
trigger.style.width = this.container.style.width;
trigger.addEventListener('dblclick', this._download.bind(this));
if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
this._createPopup(this.container, trigger, this.data);
}
this.container.appendChild(trigger);
return this.container;
},
/**
* Download the file attachment associated with this annotation.
*
* @private
* @memberof FileAttachmentAnnotationElement
*/
_download: function FileAttachmentAnnotationElement_download() {
if (!this.downloadManager) {
warn('Download cannot be started due to unavailable download manager');
return;
}
this.downloadManager.downloadData(this.content, this.filename, '');
}
});
return FileAttachmentAnnotationElement;
})();
/**
* @typedef {Object} AnnotationLayerParameters
* @property {PageViewport} viewport
@ -2298,7 +2424,8 @@ var AnnotationLayer = (function AnnotationLayerClosure() {
layer: parameters.div,
page: parameters.page,
viewport: parameters.viewport,
linkService: parameters.linkService
linkService: parameters.linkService,
downloadManager: parameters.downloadManager
};
var element = annotationElementFactory.create(properties);
if (element.isRenderable) {

View File

@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdfWorker = {}));
// Use strict in our context only - users might not want it
'use strict';
var pdfjsVersion = '1.4.83';
var pdfjsBuild = '0629fd0';
var pdfjsVersion = '1.4.95';
var pdfjsBuild = '2b813c0';
var pdfjsFilePath =
typeof document !== 'undefined' && document.currentScript ?
@ -2366,6 +2366,17 @@ var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
font: 'font'
};
// Gets the file name from a given URL.
function getFilenameFromUrl(url) {
var anchor = url.indexOf('#');
var query = url.indexOf('?');
var end = Math.min(
anchor > 0 ? anchor : url.length,
query > 0 ? query : url.length);
return url.substring(url.lastIndexOf('/', end) + 1, end);
}
PDFJS.getFilenameFromUrl = getFilenameFromUrl;
// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
// absolute URL, it will be returned as is.
function combineUrl(baseUrl, url) {
@ -3496,6 +3507,7 @@ exports.combineUrl = combineUrl;
exports.createPromiseCapability = createPromiseCapability;
exports.deprecated = deprecated;
exports.error = error;
exports.getFilenameFromUrl = getFilenameFromUrl;
exports.getLookupTableFactory = getLookupTableFactory;
exports.info = info;
exports.isArray = isArray;
@ -34982,6 +34994,7 @@ var ObjectLoader = (function() {
exports.Catalog = Catalog;
exports.ObjectLoader = ObjectLoader;
exports.XRef = XRef;
exports.FileSpec = FileSpec;
}));
@ -38792,6 +38805,7 @@ var isName = corePrimitives.isName;
var Stream = coreStream.Stream;
var ColorSpace = coreColorSpace.ColorSpace;
var ObjectLoader = coreObj.ObjectLoader;
var FileSpec = coreObj.FileSpec;
var OperatorList = coreEvaluator.OperatorList;
/**
@ -38817,6 +38831,7 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
// Return the right annotation object based on the subtype and field type.
var parameters = {
xref: xref,
dict: dict,
ref: ref
};
@ -38850,6 +38865,9 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
case 'StrikeOut':
return new StrikeOutAnnotation(parameters);
case 'FileAttachment':
return new FileAttachmentAnnotation(parameters);
default:
warn('Unimplemented annotation type "' + subtype + '", ' +
'falling back to base annotation');
@ -39083,6 +39101,24 @@ var Annotation = (function AnnotationClosure() {
}
},
/**
* Prepare the annotation for working with a popup in the display layer.
*
* @private
* @memberof Annotation
* @param {Dict} dict - The annotation's data dictionary
*/
_preparePopup: function Annotation_preparePopup(dict) {
if (!dict.has('C')) {
// Fall back to the default background color.
this.data.color = null;
}
this.data.hasPopup = dict.has('Popup');
this.data.title = stringToPDFString(dict.get('T') || '');
this.data.contents = stringToPDFString(dict.get('Contents') || '');
},
loadResources: function Annotation_loadResources(keys) {
return new Promise(function (resolve, reject) {
this.appearance.dict.getAsync('Resources').then(function (resources) {
@ -39400,27 +39436,15 @@ var TextAnnotation = (function TextAnnotationClosure() {
this.data.annotationType = AnnotationType.TEXT;
var dict = parameters.dict;
if (this.data.hasAppearance) {
this.data.name = 'NoIcon';
} else {
this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;
this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;
this.data.name = dict.has('Name') ? dict.get('Name').name : 'Note';
}
if (!dict.has('C')) {
// Fall back to the default background color.
this.data.color = null;
}
this.data.hasPopup = dict.has('Popup');
if (!this.data.hasPopup) {
// There is no associated Popup annotation, so the Text annotation
// must create its own popup.
this.data.title = stringToPDFString(dict.get('T') || '');
this.data.contents = stringToPDFString(dict.get('Contents') || '');
this.data.name = parameters.dict.has('Name') ?
parameters.dict.get('Name').name : 'Note';
}
this._preparePopup(parameters.dict);
}
Util.inherit(TextAnnotation, Annotation, {});
@ -39539,6 +39563,7 @@ var HighlightAnnotation = (function HighlightAnnotationClosure() {
Annotation.call(this, parameters);
this.data.annotationType = AnnotationType.HIGHLIGHT;
this._preparePopup(parameters.dict);
// PDF viewers completely ignore any border styles.
this.data.borderStyle.setWidth(0);
@ -39554,6 +39579,7 @@ var UnderlineAnnotation = (function UnderlineAnnotationClosure() {
Annotation.call(this, parameters);
this.data.annotationType = AnnotationType.UNDERLINE;
this._preparePopup(parameters.dict);
// PDF viewers completely ignore any border styles.
this.data.borderStyle.setWidth(0);
@ -39569,6 +39595,7 @@ var SquigglyAnnotation = (function SquigglyAnnotationClosure() {
Annotation.call(this, parameters);
this.data.annotationType = AnnotationType.SQUIGGLY;
this._preparePopup(parameters.dict);
// PDF viewers completely ignore any border styles.
this.data.borderStyle.setWidth(0);
@ -39584,6 +39611,7 @@ var StrikeOutAnnotation = (function StrikeOutAnnotationClosure() {
Annotation.call(this, parameters);
this.data.annotationType = AnnotationType.STRIKEOUT;
this._preparePopup(parameters.dict);
// PDF viewers completely ignore any border styles.
this.data.borderStyle.setWidth(0);
@ -39594,6 +39622,22 @@ var StrikeOutAnnotation = (function StrikeOutAnnotationClosure() {
return StrikeOutAnnotation;
})();
var FileAttachmentAnnotation = (function FileAttachmentAnnotationClosure() {
function FileAttachmentAnnotation(parameters) {
Annotation.call(this, parameters);
var file = new FileSpec(parameters.dict.get('FS'), parameters.xref);
this.data.annotationType = AnnotationType.FILEATTACHMENT;
this.data.file = file.serializable;
this._preparePopup(parameters.dict);
}
Util.inherit(FileAttachmentAnnotation, Annotation, {});
return FileAttachmentAnnotation;
})();
exports.Annotation = Annotation;
exports.AnnotationBorderStyle = AnnotationBorderStyle;
exports.AnnotationFactory = AnnotationFactory;

View File

@ -132,7 +132,8 @@
.annotationLayer .highlightAnnotation,
.annotationLayer .underlineAnnotation,
.annotationLayer .squigglyAnnotation,
.annotationLayer .strikeoutAnnotation {
.annotationLayer .strikeoutAnnotation,
.annotationLayer .fileAttachmentAnnotation {
cursor: pointer;
}

View File

@ -12,15 +12,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals PDFJS, PDFBug, FirefoxCom, Stats, ProgressBar,
DownloadManager, getFileName, getPDFFileNameFromURL,
PDFHistory, Preferences, SidebarView, ViewHistory, Stats,
PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar,
PasswordPrompt, PDFPresentationMode, PDFDocumentProperties, HandTool,
Promise, PDFLinkService, PDFOutlineView, PDFAttachmentView,
OverlayManager, PDFFindController, PDFFindBar, PDFViewer,
PDFRenderingQueue, PresentationModeState, parseQueryString,
RenderingStates, UNKNOWN_SCALE, DEFAULT_SCALE_VALUE,
/* globals PDFJS, PDFBug, FirefoxCom, Stats, ProgressBar, DownloadManager,
getPDFFileNameFromURL, PDFHistory, Preferences, SidebarView,
ViewHistory, Stats, PDFThumbnailViewer, URL, noContextMenuHandler,
SecondaryToolbar, PasswordPrompt, PDFPresentationMode,
PDFDocumentProperties, HandTool, Promise, PDFLinkService,
PDFOutlineView, PDFAttachmentView, OverlayManager,
PDFFindController, PDFFindBar, PDFViewer, PDFRenderingQueue,
PresentationModeState, parseQueryString, RenderingStates,
UNKNOWN_SCALE, DEFAULT_SCALE_VALUE,
IGNORE_CURRENT_POSITION_ON_ZOOM: true */
'use strict';
@ -52,15 +52,6 @@ var MAX_AUTO_SCALE = 1.25;
var SCROLLBAR_PADDING = 40;
var VERTICAL_PADDING = 5;
function getFileName(url) {
var anchor = url.indexOf('#');
var query = url.indexOf('?');
var end = Math.min(
anchor > 0 ? anchor : url.length,
query > 0 ? query : url.length);
return url.substring(url.lastIndexOf('/', end) + 1, end);
}
/**
* Returns scale factor for the canvas. It makes sense for the HiDPI displays.
* @return {Object} The object with horizontal (sx) and vertical (sy)
@ -4299,6 +4290,7 @@ DefaultTextLayerFactory.prototype = {
* @property {HTMLDivElement} pageDiv
* @property {PDFPage} pdfPage
* @property {IPDFLinkService} linkService
* @property {DownloadManager} downloadManager
*/
/**
@ -4313,6 +4305,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
this.pageDiv = options.pageDiv;
this.pdfPage = options.pdfPage;
this.linkService = options.linkService;
this.downloadManager = options.downloadManager;
this.div = null;
}
@ -4337,7 +4330,8 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
div: self.div,
annotations: annotations,
page: self.pdfPage,
linkService: self.linkService
linkService: self.linkService,
downloadManager: self.downloadManager
};
if (self.div) {
@ -4401,6 +4395,8 @@ DefaultAnnotationLayerFactory.prototype = {
* @property {HTMLDivElement} container - The container for the viewer element.
* @property {HTMLDivElement} viewer - (optional) The viewer element.
* @property {IPDFLinkService} linkService - The navigation/linking service.
* @property {DownloadManager} downloadManager - (optional) The download
* manager component.
* @property {PDFRenderingQueue} renderingQueue - (optional) The rendering
* queue object.
* @property {boolean} removePageBorders - (optional) Removes the border shadow
@ -4453,6 +4449,7 @@ var PDFViewer = (function pdfViewer() {
this.container = options.container;
this.viewer = options.viewer || options.container.firstElementChild;
this.linkService = options.linkService || new SimpleLinkService();
this.downloadManager = options.downloadManager || null;
this.removePageBorders = options.removePageBorders || false;
this.defaultRenderingQueue = !options.renderingQueue;
@ -5118,7 +5115,8 @@ var PDFViewer = (function pdfViewer() {
return new AnnotationLayerBuilder({
pageDiv: pageDiv,
pdfPage: pdfPage,
linkService: this.linkService
linkService: this.linkService,
downloadManager: this.downloadManager
});
},
@ -5242,7 +5240,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
this.linkService = linkService;
this.renderingQueue = renderingQueue;
this.hasImage = false;
this.resume = null;
this.renderingState = RenderingStates.INITIAL;
@ -5298,7 +5295,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
if (this.renderTask) {
this.renderTask.cancel();
}
this.hasImage = false;
this.resume = null;
this.renderingState = RenderingStates.INITIAL;
@ -5401,11 +5397,9 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
draw: function PDFThumbnailView_draw() {
if (this.renderingState !== RenderingStates.INITIAL) {
console.error('Must be in new state before drawing');
}
if (this.hasImage) {
return Promise.resolve(undefined);
}
this.hasImage = true;
this.renderingState = RenderingStates.RUNNING;
var resolveRenderPromise, rejectRenderPromise;
@ -5426,6 +5420,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
rejectRenderPromise(error);
return;
}
self.renderingState = RenderingStates.FINISHED;
self._convertCanvasToImage();
@ -5469,14 +5464,17 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
},
setImage: function PDFThumbnailView_setImage(pageView) {
if (this.renderingState !== RenderingStates.INITIAL) {
return;
}
var img = pageView.canvas;
if (this.hasImage || !img) {
if (!img) {
return;
}
if (!this.pdfPage) {
this.setPdfPage(pageView.pdfPage);
}
this.hasImage = true;
this.renderingState = RenderingStates.FINISHED;
var ctx = this._getPageDrawContext(true);
@ -5927,7 +5925,7 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() {
for (var i = 0; i < attachmentsCount; i++) {
var item = attachments[names[i]];
var filename = getFileName(item.filename);
var filename = PDFJS.getFilenameFromUrl(item.filename);
var div = document.createElement('div');
div.className = 'attachmentsItem';
var button = document.createElement('button');
@ -5993,7 +5991,8 @@ var PDFViewerApplication = {
container: container,
viewer: viewer,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService
linkService: pdfLinkService,
downloadManager: new DownloadManager()
});
pdfRenderingQueue.setViewer(this.pdfViewer);
pdfLinkService.setViewer(this.pdfViewer);
@ -6334,7 +6333,7 @@ var PDFViewerApplication = {
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
this.url = url;
try {
this.setTitle(decodeURIComponent(getFileName(url)) || url);
this.setTitle(decodeURIComponent(PDFJS.getFilenameFromUrl(url)) || url);
} catch (e) {
// decodeURIComponent may throw URIError,
// fall back to using the unprocessed url in that case

View File

@ -1,7 +1,7 @@
@import url("chrome://pocket-shared/skin/pocket.css");
#nav-bar #pocket-button > .toolbarbutton-icon {
padding: 2px 6px;
padding: calc(var(--toolbarbutton-vertical-inner-padding)) 6px;
}
:-moz-any(#TabsToolbar, .widget-overflow-list) #pocket-button > .toolbarbutton-icon {

View File

@ -1,4 +1,7 @@
{
"plugins": [
"react"
],
"globals": {
"Cc": true,
"Ci": true,
@ -30,6 +33,23 @@
"mozilla/reject-importGlobalProperties": 1,
"mozilla/var-only-at-top-level": 1,
// Rules from the React plugin
"react/display-name": 1,
"react/no-danger": 1,
"react/no-did-mount-set-state": 1,
"react/no-did-update-set-state": 1,
"react/no-direct-mutation-state": 1,
"react/no-unknown-property": 1,
"react/prefer-es6-class": 1,
"react/prop-types": 1,
"react/sort-comp": [1, {
order: [
"propTypes",
"everything-else",
"render"
]
}],
// Disallow using variables outside the blocks they are defined (especially
// since only let and const are used, see "no-var").
"block-scoped-var": 2,

View File

@ -8,26 +8,33 @@
const Services = require("Services");
const React = require("devtools/client/shared/vendor/react");
const { TabMenu } = require("./tab-menu");
const { createFactory, createClass, DOM: dom } =
require("devtools/client/shared/vendor/react");
loader.lazyRequireGetter(this, "AddonsTab", "./components/addons-tab", true);
loader.lazyRequireGetter(this, "WorkersTab", "./components/workers-tab", true);
const TabMenu = createFactory(require("./tab-menu"));
loader.lazyGetter(this, "AddonsTab",
() => createFactory(require("./addons-tab")));
loader.lazyGetter(this, "WorkersTab",
() => createFactory(require("./workers-tab")));
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
const tabs = [
{ id: "addons", name: Strings.GetStringFromName("addons"),
icon: "chrome://devtools/skin/images/debugging-addons.svg",
component: AddonsTab },
{ id: "workers", name: Strings.GetStringFromName("workers"),
icon: "chrome://devtools/skin/images/debugging-workers.svg",
component: WorkersTab },
];
const tabs = [{
id: "addons",
name: Strings.GetStringFromName("addons"),
icon: "chrome://devtools/skin/images/debugging-addons.svg",
component: AddonsTab
}, {
id: "workers",
name: Strings.GetStringFromName("workers"),
icon: "chrome://devtools/skin/images/debugging-workers.svg",
component: WorkersTab
}];
const defaultTabId = "addons";
exports.AboutDebuggingApp = React.createClass({
module.exports = createClass({
displayName: "AboutDebuggingApp",
getInitialState() {
@ -55,12 +62,11 @@ exports.AboutDebuggingApp = React.createClass({
let selectedTab = tabs.find(t => t.id == selectedTabId);
return React.createElement(
"div", { className: "app"},
React.createElement(TabMenu, { tabs, selectedTabId, selectTab }),
React.createElement("div", { className: "main-content" },
React.createElement(selectedTab.component, { client }))
);
return dom.div({ className: "app" },
TabMenu({ tabs, selectedTabId, selectTab }),
dom.div({ className: "main-content" },
selectedTab.component({ client }))
);
},
onHashChange() {

View File

@ -12,7 +12,7 @@ loader.lazyImporter(this, "AddonManager",
const { Cc, Ci } = require("chrome");
const Services = require("Services");
const React = require("devtools/client/shared/vendor/react");
const { createClass, DOM: dom } = require("devtools/client/shared/vendor/react");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
@ -20,32 +20,31 @@ const Strings = Services.strings.createBundle(
const MORE_INFO_URL = "https://developer.mozilla.org/docs/Tools" +
"/about:debugging#Enabling_add-on_debugging";
exports.AddonsControls = React.createClass({
module.exports = createClass({
displayName: "AddonsControls",
render() {
let { debugDisabled } = this.props;
return React.createElement(
"div", { className: "addons-controls" }, React.createElement(
"div", { className: "addons-options" },
React.createElement("input", {
return dom.div({ className: "addons-controls" },
dom.div({ className: "addons-options" },
dom.input({
id: "enable-addon-debugging",
type: "checkbox",
checked: !debugDisabled,
onChange: this.onEnableAddonDebuggingChange,
}),
React.createElement("label", {
dom.label({
className: "addons-debugging-label",
htmlFor: "enable-addon-debugging",
title: Strings.GetStringFromName("addonDebugging.tooltip")
}, Strings.GetStringFromName("addonDebugging.label")),
"(",
React.createElement("a", { href: MORE_INFO_URL, target: "_blank" },
dom.a({ href: MORE_INFO_URL, target: "_blank" },
Strings.GetStringFromName("addonDebugging.moreInfo")),
")"
),
React.createElement("button", {
dom.button({
id: "load-addon-from-file",
onClick: this.loadAddonFromFile,
}, Strings.GetStringFromName("loadTemporaryAddon"))

View File

@ -2,17 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global React */
"use strict";
const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
const Services = require("Services");
const React = require("devtools/client/shared/vendor/react");
const { AddonsControls } = require("./addons-controls");
const { TabHeader } = require("./tab-header");
const { TargetList } = require("./target-list");
const { createFactory, createClass, DOM: dom } =
require("devtools/client/shared/vendor/react");
const AddonsControls = createFactory(require("./addons-controls"));
const TabHeader = createFactory(require("./tab-header"));
const TargetList = createFactory(require("./target-list"));
const ExtensionIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
const Strings = Services.strings.createBundle(
@ -21,7 +20,7 @@ const Strings = Services.strings.createBundle(
const CHROME_ENABLED_PREF = "devtools.chrome.enabled";
const REMOTE_ENABLED_PREF = "devtools.debugger.remote-enabled";
exports.AddonsTab = React.createClass({
module.exports = createClass({
displayName: "AddonsTab",
getInitialState() {
@ -56,19 +55,17 @@ exports.AddonsTab = React.createClass({
let { debugDisabled, extensions: targets } = this.state;
let name = Strings.GetStringFromName("extensions");
return React.createElement(
"div", { id: "tab-addons", className: "tab", role: "tabpanel",
"aria-labelledby": "tab-addons-header-name" },
React.createElement(TabHeader, {
id: "tab-addons-header-name",
name: Strings.GetStringFromName("addons")}),
React.createElement(AddonsControls, { debugDisabled }),
React.createElement(
"div", { id: "addons" },
React.createElement(TargetList,
{ name, targets, client, debugDisabled })
)
);
return dom.div({
id: "tab-addons",
className: "tab",
role: "tabpanel",
"aria-labelledby": "tab-addons-header-name" },
TabHeader({
id: "tab-addons-header-name",
name: Strings.GetStringFromName("addons") }),
AddonsControls({ debugDisabled }),
dom.div({ id: "addons" },
TargetList({ name, targets, client, debugDisabled })));
},
updateDebugStatus() {

View File

@ -4,16 +4,16 @@
"use strict";
const React = require("devtools/client/shared/vendor/react");
const { createClass, DOM: dom } =
require("devtools/client/shared/vendor/react");
exports.TabHeader = React.createClass({
module.exports = createClass({
displayName: "TabHeader",
render() {
let { name, id } = this.props;
return React.createElement(
"div", { className: "header" }, React.createElement(
"h1", { id, className: "header-name" }, name));
return dom.div({ className: "header" },
dom.h1({ id, className: "header-name" }, name));
},
});

View File

@ -4,9 +4,10 @@
"use strict";
const React = require("devtools/client/shared/vendor/react");
const { createClass, DOM: dom } =
require("devtools/client/shared/vendor/react");
exports.TabMenuEntry = React.createClass({
module.exports = createClass({
displayName: "TabMenuEntry",
render() {
@ -15,13 +16,13 @@ exports.TabMenuEntry = React.createClass({
// Here .category, .category-icon, .category-name classnames are used to
// apply common styles defined.
let className = "category" + (selected ? " selected" : "");
return React.createElement(
"div", { className, onClick: this.onClick,
"aria-selected": selected, role: "tab" },
React.createElement("img", { className: "category-icon", src: icon,
role: "presentation" }),
React.createElement("div", { className: "category-name" }, name)
);
return dom.div({
"aria-selected": selected,
className,
onClick: this.onClick,
role: "tab" },
dom.img({ className: "category-icon", src: icon, role: "presentation" }),
dom.div({ className: "category-name" }, name));
},
onClick() {

View File

@ -2,25 +2,23 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global React */
"use strict";
const React = require("devtools/client/shared/vendor/react");
const { TabMenuEntry } = require("./tab-menu-entry");
const { createClass, createFactory, DOM: dom } =
require("devtools/client/shared/vendor/react");
const TabMenuEntry = createFactory(require("./tab-menu-entry"));
exports.TabMenu = React.createClass({
module.exports = createClass({
displayName: "TabMenu",
render() {
let { tabs, selectedTabId, selectTab } = this.props;
let tabLinks = tabs.map(({ id, name, icon }) => {
let selected = id == selectedTabId;
return React.createElement(TabMenuEntry,
{ tabId: id, name, icon, selected, selectTab });
return TabMenuEntry({ tabId: id, name, icon, selected, selectTab });
});
// "categories" id used for styling purposes
return React.createElement("div", { id: "categories" }, tabLinks);
return dom.div({ id: "categories" }, tabLinks);
},
});

View File

@ -2,14 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global React */
"use strict";
const Services = require("Services");
const React = require("devtools/client/shared/vendor/react");
const { Target } = require("./target");
const { createClass, createFactory, DOM: dom } =
require("devtools/client/shared/vendor/react");
const Target = createFactory(require("./target"));
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
@ -18,19 +17,21 @@ const LocaleCompare = (a, b) => {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
};
exports.TargetList = React.createClass({
module.exports = createClass({
displayName: "TargetList",
render() {
let { client, debugDisabled } = this.props;
let targets = this.props.targets.sort(LocaleCompare).map(target => {
return React.createElement(Target, { client, target, debugDisabled });
return Target({ client, target, debugDisabled });
});
return (
React.createElement("div", { id: this.props.id, className: "targets" },
React.createElement("h4", null, this.props.name),
targets.length > 0 ? targets :
React.createElement("p", null, Strings.GetStringFromName("nothing"))
dom.div({ id: this.props.id, className: "targets" },
dom.h4(null, this.props.name),
targets.length > 0 ?
targets :
dom.p(null, Strings.GetStringFromName("nothing"))
)
);
},

View File

@ -17,28 +17,29 @@ loader.lazyImporter(this, "BrowserToolboxProcess",
"resource://devtools/client/framework/ToolboxProcess.jsm");
const Services = require("Services");
const React = require("devtools/client/shared/vendor/react");
const { createClass, DOM: dom } =
require("devtools/client/shared/vendor/react");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
exports.Target = React.createClass({
module.exports = createClass({
displayName: "Target",
render() {
let { target, debugDisabled } = this.props;
let isServiceWorker = (target.type === "serviceworker");
let isRunning = (!isServiceWorker || target.workerActor);
return React.createElement("div", { className: "target" },
React.createElement("img", {
return dom.div({ className: "target" },
dom.img({
className: "target-icon",
role: "presentation",
src: target.icon }),
React.createElement("div", { className: "target-details" },
React.createElement("div", { className: "target-name" }, target.name)
dom.div({ className: "target-details" },
dom.div({ className: "target-name" }, target.name)
),
(isRunning ?
React.createElement("button", {
dom.button({
className: "debug-button",
onClick: this.debug,
disabled: debugDisabled,

View File

@ -8,15 +8,16 @@ const { Ci } = require("chrome");
const { Task } = require("resource://gre/modules/Task.jsm");
const Services = require("Services");
const React = require("devtools/client/shared/vendor/react");
const { TargetList } = require("./target-list");
const { TabHeader } = require("./tab-header");
const { createClass, createFactory, DOM: dom } =
require("devtools/client/shared/vendor/react");
const TabHeader = createFactory(require("./tab-header"));
const TargetList = createFactory(require("./target-list"));
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
exports.WorkersTab = React.createClass({
module.exports = createClass({
displayName: "WorkersTab",
getInitialState() {
@ -48,27 +49,30 @@ exports.WorkersTab = React.createClass({
let { client } = this.props;
let { workers } = this.state;
return React.createElement(
"div", { id: "tab-workers", className: "tab", role: "tabpanel",
"aria-labelledby": "tab-workers-header-name" },
React.createElement(TabHeader, {
id: "tab-workers-header-name",
name: Strings.GetStringFromName("workers")}),
React.createElement(
"div", { id: "workers", className: "inverted-icons" },
React.createElement(TargetList, {
id: "service-workers",
name: Strings.GetStringFromName("serviceWorkers"),
targets: workers.service, client }),
React.createElement(TargetList, {
id: "shared-workers",
name: Strings.GetStringFromName("sharedWorkers"),
targets: workers.shared, client }),
React.createElement(TargetList, {
id: "other-workers",
name: Strings.GetStringFromName("otherWorkers"),
targets: workers.other, client }))
);
return dom.div({
id: "tab-workers",
className: "tab",
role: "tabpanel",
"aria-labelledby": "tab-workers-header-name" },
TabHeader({
id: "tab-workers-header-name",
name: Strings.GetStringFromName("workers") }),
dom.div({ id: "workers", className: "inverted-icons" },
TargetList({
id: "service-workers",
name: Strings.GetStringFromName("serviceWorkers"),
targets: workers.service,
client }),
TargetList({
id: "shared-workers",
name: Strings.GetStringFromName("sharedWorkers"),
targets: workers.shared,
client }),
TargetList({
id: "other-workers",
name: Strings.GetStringFromName("otherWorkers"),
targets: workers.other,
client })));
},
update() {

View File

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env browser */
/* global DebuggerClient, DebuggerServer */
"use strict";
@ -22,8 +21,11 @@ const { BrowserLoader } = Components.utils.import(
const { require } =
BrowserLoader("resource://devtools/client/aboutdebugging/", window);
const React = require("devtools/client/shared/vendor/react");
const { AboutDebuggingApp } = require("./components/aboutdebugging");
const {
createFactory,
render,
unmountComponentAtNode } = require("devtools/client/shared/vendor/react");
const AboutDebuggingApp = createFactory(require("./components/aboutdebugging"));
var AboutDebugging = {
init() {
@ -38,13 +40,13 @@ var AboutDebugging = {
let client = this.client;
let telemetry = new Telemetry();
let app = React.createElement(AboutDebuggingApp, { client, telemetry });
React.render(app, document.querySelector("#body"));
render(AboutDebuggingApp({ client, telemetry }),
document.querySelector("#body"));
});
},
destroy() {
React.unmountComponentAtNode(document.querySelector("#body"));
unmountComponentAtNode(document.querySelector("#body"));
this.client.close();
this.client = null;

View File

@ -5,7 +5,6 @@
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
@ -13,6 +12,7 @@ Cu.import("resource://gre/modules/Console.jsm");
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const promise = require("promise");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
const { CallWatcherFront } = require("devtools/server/actors/call-watcher");
const { CanvasFront } = require("devtools/server/actors/canvas");

View File

@ -4,17 +4,11 @@
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
// Disable logging for all the tests. Both the debugger server and frontend will
// be affected by this pref.
var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
Services.prefs.setBoolPref("devtools.debugger.log", false);
var { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var Services = require("Services");
var promise = require("promise");
var { gDevTools } = require("devtools/client/framework/devtools");
var { DebuggerClient } = require("devtools/shared/client/main");
@ -43,6 +37,11 @@ const WEBGL_DRAW_ARRAYS = EXAMPLE_URL + "doc_webgl-drawArrays.html";
const WEBGL_DRAW_ELEMENTS = EXAMPLE_URL + "doc_webgl-drawElements.html";
const RAF_BEGIN_URL = EXAMPLE_URL + "doc_raf-begin.html";
// Disable logging for all the tests. Both the debugger server and frontend will
// be affected by this pref.
var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
Services.prefs.setBoolPref("devtools.debugger.log", false);
// All tests are asynchronous.
waitForExplicitFinish();

View File

@ -4,6 +4,7 @@
// Test various GCLI commands
const TEST_URI = "data:text/html;charset=utf-8,gcli-commands";
const HUDService = require("devtools/client/webconsole/hudservice");
function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);

View File

@ -93,7 +93,6 @@ const FRAME_TYPE = {
PUBLIC_CLIENT_EVAL: 3
};
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://devtools/shared/event-emitter.js");
Cu.import("resource://devtools/client/shared/widgets/SimpleListWidget.jsm");
@ -137,6 +136,7 @@ var services = {
WAIT_UNTIL: waitUntilService.NAME
};
var Services = require("Services");
var {TargetFactory} = require("devtools/client/framework/target");
var {Toolbox} = require("devtools/client/framework/toolbox");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");

View File

@ -4,7 +4,7 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="debugger.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/debugger/debugger.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/debugger.css" type="text/css"?>
<!DOCTYPE window [

View File

@ -5,8 +5,7 @@
"use strict";
const {Cc, Ci} = require("chrome");
const { Services } = require("resource://gre/modules/Services.jsm");
const Services = require("Services");
loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS);

View File

@ -7,10 +7,9 @@ const {rgbToHsl} = require("devtools/shared/css-color").colorUtils;
const Telemetry = require("devtools/client/shared/telemetry");
const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js");
const promise = require("promise");
const Services = require("Services");
const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
Cu.import("resource://gre/modules/Services.jsm");
loader.lazyGetter(this, "clipboardHelper", function() {
return Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper);

View File

@ -11,7 +11,6 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
const DBG_XUL = "chrome://devtools/content/framework/toolbox-process-window.xul";
const CHROME_DEBUGGER_PROFILE_NAME = "chrome_debugger_profile";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
const { require, DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
@ -22,6 +21,7 @@ XPCOMUtils.defineLazyGetter(this, "EventEmitter", function () {
return require("devtools/shared/event-emitter");
});
const promise = require("promise");
const Services = require("Services");
this.EXPORTED_SYMBOLS = ["BrowserToolboxProcess"];

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const {Cc, Ci, Cu} = require("chrome");
const Services = Cu.import("resource://gre/modules/Services.jsm", {}).Services;
const Services = require("Services");
const promise = require("promise");
function l10n(name) {

View File

@ -8,9 +8,9 @@
var Cu = Components.utils;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var Services = require("Services");
var {gDevTools} = require("devtools/client/framework/devtools");
var {TargetFactory} = require("devtools/client/framework/target");
var {Toolbox} = require("devtools/client/framework/toolbox")

View File

@ -7,9 +7,9 @@
const {Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
var Services = require("Services");
var EventEmitter = require("devtools/shared/event-emitter");
var Telemetry = require("devtools/client/shared/telemetry");

View File

@ -17,7 +17,6 @@ function scopedCuImport(path) {
return scope;
}
const {Services} = scopedCuImport("resource://gre/modules/Services.jsm");
const {console} = scopedCuImport("resource://gre/modules/Console.jsm");
const {ScratchpadManager} = scopedCuImport("resource://devtools/client/scratchpad/scratchpad-manager.jsm");
const {require} = scopedCuImport("resource://devtools/shared/Loader.jsm");
@ -26,6 +25,7 @@ const {gDevTools} = require("devtools/client/framework/devtools");
const {TargetFactory} = require("devtools/client/framework/target");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
let promise = require("promise");
const Services = require("Services");
const TEST_DIR = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
const CHROME_URL_ROOT = TEST_DIR + "/";

View File

@ -9,7 +9,7 @@
const {Cu} = require("chrome");
const EventEmitter = require("devtools/shared/event-emitter");
const promise = require("promise");
Cu.import("resource://gre/modules/Services.jsm");
const Services = require("Services");
Cu.import("resource://devtools/client/shared/DOMHelpers.jsm");
loader.lazyRequireGetter(this, "system", "devtools/shared/system");

View File

@ -16,7 +16,7 @@ require("devtools/client/framework/devtools-browser");
var { gDevTools } = require("devtools/client/framework/devtools");
var { TargetFactory } = require("devtools/client/framework/target");
var { Toolbox } = require("devtools/client/framework/toolbox");
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
var Services = require("Services");
var { DebuggerClient } = require("devtools/shared/client/main");
var { ViewHelpers } =
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm", {});

View File

@ -18,6 +18,7 @@ const SCREENSIZE_HISTOGRAM = "DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER";
var {Cc, Ci, Cu} = require("chrome");
var promise = require("promise");
var Services = require("Services");
var {gDevTools} = require("devtools/client/framework/devtools");
var EventEmitter = require("devtools/shared/event-emitter");
var Telemetry = require("devtools/client/shared/telemetry");
@ -25,7 +26,6 @@ var HUDService = require("devtools/client/webconsole/hudservice");
var viewSource = require("devtools/client/shared/view-source");
var { attachThread, detachThread } = require("./attach-thread");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm");
Cu.import("resource://devtools/client/shared/DOMHelpers.jsm");
Cu.import("resource://gre/modules/Task.jsm");
@ -563,11 +563,6 @@ Toolbox.prototype = {
let toggleKey = this.doc.getElementById("toolbox-toggle-host-key");
toggleKey.addEventListener("command", this.switchToPreviousHost.bind(this), true);
if (Services.prefs.prefHasUserValue("devtools.loader.srcdir")) {
let reloadKey = this.doc.getElementById("tools-reload-key");
reloadKey.addEventListener("command", this.reload.bind(this), true);
}
// Split console uses keypress instead of command so the event can be
// cancelled with stopPropagation on the keypress, and not preventDefault.
this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false);
@ -1702,11 +1697,6 @@ Toolbox.prototype = {
return newHost;
},
reload: function () {
const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
devtools.reload(true);
},
/**
* Switch to the last used host for the toolbox UI.
* This is determined by the devtools.toolbox.previousHost pref.

View File

@ -94,10 +94,6 @@
key="&toolboxToggle.key;"
oncommand="void(0);"
modifiers="accel shift"/>
<key id="tools-reload-key"
key="&toolboxReload.key;"
oncommand="void(0);"
modifiers="accel alt"/>
</keyset>
<popupset>

View File

@ -8,7 +8,7 @@
const {Cu, Ci} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const Services = require("Services");
const promise = require("promise");
const ENSURE_SELECTION_VISIBLE_DELAY = 50; // ms

View File

@ -14,6 +14,7 @@ const ToolDefinitions = require("devtools/client/main").Tools;
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/server/actors/styles");
const promise = require("promise");
const Services = require("Services");
const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
const {OutputParser} = require("devtools/client/shared/output-parser");
const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
@ -25,7 +26,6 @@ loader.lazyRequireGetter(this, "overlays",
loader.lazyRequireGetter(this, "StyleInspectorMenu",
"devtools/client/inspector/shared/style-inspector-menu");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",

View File

@ -8,8 +8,7 @@
const {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");
var Services = require("Services");
var promise = require("promise");
var EventEmitter = require("devtools/shared/event-emitter");
var clipboard = require("sdk/clipboard");

View File

@ -6,7 +6,7 @@
const {Cu} = require("chrome");
const Editor = require("devtools/client/sourceeditor/editor");
Cu.import("resource://gre/modules/Services.jsm");
const Services = require("Services");
Cu.import("resource://devtools/shared/event-emitter.js");
/**

View File

@ -42,7 +42,6 @@ const {scrollIntoViewIfNeeded} = require("devtools/shared/layout/utils");
const {PrefObserver} = require("devtools/client/styleeditor/utils");
Cu.import("resource://devtools/shared/gcli/Templater.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
loader.lazyRequireGetter(this, "CSS", "CSS");

View File

@ -13,8 +13,6 @@ const {promiseWarn} = require("devtools/client/inspector/shared/utils");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
loader.lazyGetter(this, "PSEUDO_ELEMENTS", () => {
return domUtils.getCSSPseudoElementNames();
});

View File

@ -9,6 +9,7 @@
const {Cc, Ci, Cu} = require("chrome");
const promise = require("promise");
const Services = require("Services");
const {Tools} = require("devtools/client/main");
const {setTimeout, clearTimeout} =
Cu.import("resource://gre/modules/Timer.jsm", {});
@ -34,7 +35,6 @@ loader.lazyRequireGetter(this, "EventEmitter",
"devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "StyleInspectorMenu",
"devtools/client/inspector/shared/style-inspector-menu");
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function() {
return Cc["@mozilla.org/widget/clipboardhelper;1"]

View File

@ -14,6 +14,8 @@ support-files =
doc_custom.html
doc_filter.html
doc_frame_script.js
doc_invalid_sourcemap.css
doc_invalid_sourcemap.html
doc_keyframeanimation.css
doc_keyframeanimation.html
doc_keyframeLineNumbers.html
@ -119,6 +121,7 @@ skip-if = (os == "win" && debug) # bug 963492: win.
[browser_rules_inherited-properties_01.js]
[browser_rules_inherited-properties_02.js]
[browser_rules_inherited-properties_03.js]
[browser_rules_invalid-source-map.js]
[browser_rules_keybindings.js]
[browser_rules_keyframes-rule_01.js]
[browser_rules_keyframes-rule_02.js]

View File

@ -25,10 +25,6 @@ add_task(function*() {
let swatch = getRuleViewProperty(view, "body", "color").valueSpan
.querySelector(".ruleview-colorswatch");
yield testColorPickerHidesWhenImageTooltipAppears(view, swatch);
});
function* testColorPickerHidesWhenImageTooltipAppears(view, swatch) {
let bgImageSpan = getRuleViewProperty(view, "body", "background-image")
.valueSpan;
let uriSpan = bgImageSpan.querySelector(".theme-link");
@ -41,8 +37,11 @@ function* testColorPickerHidesWhenImageTooltipAppears(view, swatch) {
info("Now showing the image preview tooltip to hide the color picker");
let onHidden = tooltip.once("hidden");
// Hiding the color picker refreshes the value.
let onRuleViewChanged = view.once("ruleview-changed");
yield assertHoverTooltipOn(view.tooltips.previewTooltip, uriSpan);
yield onHidden;
yield onRuleViewChanged;
ok(true, "The color picker closed when the image preview tooltip appeared");
}
});

View File

@ -13,27 +13,28 @@
// modifers,
// expected input box value after keypress,
// selectedIndex of the popup,
// total items in the popup
// total items in the popup,
// expect ruleview-changed
// ]
var testData = [
["b", {}, "beige", 0, 8],
["l", {}, "black", 0, 4],
["VK_DOWN", {}, "blanchedalmond", 1, 4],
["VK_DOWN", {}, "blue", 2, 4],
["VK_RIGHT", {}, "blue", -1, 0],
[" ", {}, "blue !important", 0, 10],
["!", {}, "blue !important", 0, 0],
["VK_BACK_SPACE", {}, "blue !", -1, 0],
["VK_BACK_SPACE", {}, "blue ", -1, 0],
["VK_BACK_SPACE", {}, "blue", -1, 0],
["VK_TAB", {shiftKey: true}, "color", -1, 0],
["VK_BACK_SPACE", {}, "", -1, 0],
["d", {}, "direction", 0, 3],
["i", {}, "direction", 0, 2],
["s", {}, "display", -1, 0],
["VK_TAB", {}, "blue", -1, 0],
["n", {}, "none", -1, 0],
["VK_RETURN", {}, null, -1, 0]
["b", {}, "beige", 0, 8, true],
["l", {}, "black", 0, 4, true],
["VK_DOWN", {}, "blanchedalmond", 1, 4, true],
["VK_DOWN", {}, "blue", 2, 4, true],
["VK_RIGHT", {}, "blue", -1, 0, false],
[" ", {}, "blue !important", 0, 10, true],
["!", {}, "blue !important", 0, 0, true],
["VK_BACK_SPACE", {}, "blue !", -1, 0, true],
["VK_BACK_SPACE", {}, "blue ", -1, 0, true],
["VK_BACK_SPACE", {}, "blue", -1, 0, true],
["VK_TAB", {shiftKey: true}, "color", -1, 0, true],
["VK_BACK_SPACE", {}, "", -1, 0, false],
["d", {}, "direction", 0, 3, false],
["i", {}, "direction", 0, 2, false],
["s", {}, "display", -1, 0, false],
["VK_TAB", {}, "blue", -1, 0, true],
["n", {}, "none", -1, 0, true],
["VK_RETURN", {}, null, -1, 0, true]
];
const TEST_URI = "<h1 style='color: red'>Header</h1>";
@ -54,9 +55,11 @@ function* runAutocompletionTest(toolbox, inspector, view) {
info("Selecting the test node");
yield selectNode("h1", inspector);
let rule = getRuleViewRuleEditor(view, 0).rule;
let prop = rule.textProps[0];
info("Focusing the css property editable value");
let value = view.styleDocument.querySelectorAll(".ruleview-propertyvalue")[0];
let editor = yield focusEditableField(view, value);
let editor = yield focusEditableField(view, prop.editor.valueSpan);
info("Starting to test for css property completion");
for (let i = 0; i < testData.length; i++) {
@ -67,30 +70,28 @@ function* runAutocompletionTest(toolbox, inspector, view) {
}
}
function* testCompletion([key, modifiers, completion, index, total], editor,
view) {
function* testCompletion([key, modifiers, completion, index, total, willChange],
editor, view) {
info("Pressing key " + key);
info("Expecting " + completion + ", " + index + ", " + total);
let onKeyPress;
if (/tab/ig.test(key)) {
info("Waiting for the new property or value editor to get focused");
let brace = view.styleDocument.querySelector(".ruleview-ruleclose");
onKeyPress = once(brace.parentNode, "focus", true);
} else if (/(right|return|back_space)/ig.test(key)) {
info("Adding event listener for right|return|back_space keys");
onKeyPress = once(editor.input, "keypress");
let onDone;
if (willChange) {
// If the key triggers a ruleview-changed, wait for that event, it will
// always be the last to be triggered and tells us when the preview has
// been done.
onDone = view.once("ruleview-changed");
} else {
info("Waiting for after-suggest event on the editor");
onKeyPress = editor.once("after-suggest");
// Otherwise, expect an after-suggest event (except if the popup gets
// closed).
onDone = key !== "VK_RIGHT" && key !== "VK_BACK_SPACE"
? editor.once("after-suggest")
: null;
}
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
yield onKeyPress;
yield waitForTick();
yield onDone;
// The key might have been a TAB or shift-TAB, in which case the editor will
// be a new one

View File

@ -13,30 +13,30 @@
// modifers,
// expected input box value after keypress,
// selectedIndex of the popup,
// total items in the popup
// total items in the popup,
// expect ruleview-changed
// ]
var testData = [
["a", {accelKey: true, ctrlKey: true}, "", -1, 0],
["d", {}, "direction", 0, 3],
["VK_DOWN", {}, "display", 1, 3],
["VK_TAB", {}, "", -1, 10],
["VK_DOWN", {}, "-moz-box", 0, 10],
["n", {}, "none", -1, 0],
["VK_TAB", {shiftKey: true}, "display", -1, 0],
["VK_BACK_SPACE", {}, "", -1, 0],
["c", {}, "caption-side", 0, 10],
["o", {}, "color", 0, 7],
["VK_TAB", {}, "none", -1, 0],
["r", {}, "rebeccapurple", 0, 6],
["VK_DOWN", {}, "red", 1, 6],
["VK_DOWN", {}, "rgb", 2, 6],
["VK_DOWN", {}, "rgba", 3, 6],
["VK_DOWN", {}, "rosybrown", 4, 6],
["VK_DOWN", {}, "royalblue", 5, 6],
["VK_RIGHT", {}, "royalblue", -1, 0],
[" ", {}, "royalblue !important", 0, 10],
["!", {}, "royalblue !important", 0, 0],
["VK_ESCAPE", {}, null, -1, 0]
["d", {}, "direction", 0, 3, false],
["VK_DOWN", {}, "display", 1, 3, false],
["VK_TAB", {}, "", -1, 10, true],
["VK_DOWN", {}, "-moz-box", 0, 10, true],
["n", {}, "none", -1, 0, true],
["VK_TAB", {shiftKey: true}, "display", -1, 0, true],
["VK_BACK_SPACE", {}, "", -1, 0, false],
["c", {}, "caption-side", 0, 10, false],
["o", {}, "color", 0, 7, false],
["VK_TAB", {}, "none", -1, 0, true],
["r", {}, "rebeccapurple", 0, 6, true],
["VK_DOWN", {}, "red", 1, 6, true],
["VK_DOWN", {}, "rgb", 2, 6, true],
["VK_DOWN", {}, "rgba", 3, 6, true],
["VK_DOWN", {}, "rosybrown", 4, 6, true],
["VK_DOWN", {}, "royalblue", 5, 6, true],
["VK_RIGHT", {}, "royalblue", -1, 0, false],
[" ", {}, "royalblue !important", 0, 10, true],
["!", {}, "royalblue !important", 0, 0, true],
["VK_ESCAPE", {}, null, -1, 0, true]
];
const TEST_URI = `
@ -77,31 +77,28 @@ function* runAutocompletionTest(toolbox, inspector, view) {
}
}
function* testCompletion([key, modifiers, completion, index, total], editor,
view) {
function* testCompletion([key, modifiers, completion, index, total, willChange],
editor, view) {
info("Pressing key " + key);
info("Expecting " + completion + ", " + index + ", " + total);
let onKeyPress;
if (/tab/ig.test(key)) {
info("Waiting for the new property or value editor to get focused");
let brace = view.styleDocument.querySelectorAll(".ruleview-ruleclose")[1];
onKeyPress = once(brace.parentNode, "focus", true);
} else if (/(right|back_space|escape|return)/ig.test(key) ||
(modifiers.accelKey || modifiers.ctrlKey)) {
info("Adding event listener for right|escape|back_space|return keys");
onKeyPress = once(editor.input, "keypress");
let onDone;
if (willChange) {
// If the key triggers a ruleview-changed, wait for that event, it will
// always be the last to be triggered and tells us when the preview has
// been done.
onDone = view.once("ruleview-changed");
} else {
info("Waiting for after-suggest event on the editor");
onKeyPress = editor.once("after-suggest");
// Otherwise, expect an after-suggest event (except if the popup gets
// closed).
onDone = key !== "VK_RIGHT" && key !== "VK_BACK_SPACE"
? editor.once("after-suggest")
: null;
}
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
yield onKeyPress;
yield waitForTick();
yield onDone;
info("Checking the state");
if (completion != null) {

View File

@ -10,8 +10,8 @@
// - press RETURN to move to the property value
// - blur the input to commit
const TEST_URI = "<style>.title {margin: 0;}</style>" +
"<h1 class=title style='color: red'>Header</h1>";
const TEST_URI = "<style>.title {color: red;}</style>" +
"<h1 class=title>Header</h1>";
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
@ -21,7 +21,7 @@ add_task(function*() {
yield selectNode("h1", inspector);
info("Focusing the new property editable field");
let ruleEditor = getRuleViewRuleEditor(view, 0);
let ruleEditor = getRuleViewRuleEditor(view, 1);
let editor = yield focusNewRuleViewProperty(ruleEditor);
info("Sending \"background\" to the editable field.");
@ -45,18 +45,17 @@ add_task(function*() {
is(editor.input.value, "background-color", "Correct value is autocompleted");
info("Press RETURN to move the focus to a property value editor.");
let onModifications = view.once("ruleview-changed");
let onModifications = waitForNEvents(view, "ruleview-changed", 2);
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onModifications;
// Getting the new value editor after focus
let elementRuleEditor = getRuleViewRuleEditor(view, 0);
editor = inplaceEditor(view.styleDocument.activeElement);
let textProp = elementRuleEditor.rule.textProps[1];
let textProp = ruleEditor.rule.textProps[1];
is(elementRuleEditor.rule.textProps.length, 2,
is(ruleEditor.rule.textProps.length, 2,
"Created a new text property.");
is(elementRuleEditor.propertyList.children.length, 2,
is(ruleEditor.propertyList.children.length, 2,
"Created a property editor.");
is(editor, inplaceEditor(textProp.editor.valueSpan),
"Editing the value span now.");

View File

@ -72,15 +72,13 @@ function* runTestData(view, {value, commitKey, modifiers, expected}) {
info("Entering test data " + value);
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.sendString(value, view.styleWindow);
info("Waiting for focus on the field");
let onBlur = once(editor.input, "blur");
yield onRuleViewChanged;
info("Entering the commit key " + commitKey + " " + modifiers);
onRuleViewChanged = view.once("ruleview-changed");
let onBlur = once(editor.input, "blur");
EventUtils.synthesizeKey(commitKey, modifiers);
yield onBlur;
// No matter if we escape or commit the change, the preview throttle is going
// to update the property value
yield onRuleViewChanged;
if (commitKey === "VK_ESCAPE") {

View File

@ -0,0 +1,43 @@
/* 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";
// Test that when a source map is missing/invalid, the rule view still loads
// correctly.
const TESTCASE_URI = URL_ROOT + "doc_invalid_sourcemap.html";
const PREF = "devtools.styleeditor.source-maps-enabled";
const CSS_LOC = "doc_invalid_sourcemap.css:1";
add_task(function*() {
Services.prefs.setBoolPref(PREF, true);
yield addTab(TESTCASE_URI);
let {inspector, view} = yield openRuleView();
yield selectNode("div", inspector);
let ruleEl = getRuleViewRule(view, "div");
ok(ruleEl, "The 'div' rule exists in the rule-view");
let prop = getRuleViewProperty(view, "div", "color");
ok(prop, "The 'color' property exists in this rule");
let value = getRuleViewPropertyValue(view, "div", "color");
is(value, "gold", "The 'color' property has the right value");
yield verifyLinkText(view, CSS_LOC);
Services.prefs.clearUserPref(PREF);
});
function verifyLinkText(view, text) {
info("Verifying that the rule-view stylesheet link is " + text);
let label = getRuleViewLinkByIndex(view, 1).querySelector("label");
return waitForSuccess(
() => label.getAttribute("value") == text,
"Link text changed to display correct location: " + text
);
}

View File

@ -13,12 +13,11 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("div", inspector);
yield testMultiValues(inspector, view);
});
function* testMultiValues(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 0);
let onDone = view.once("ruleview-changed");
yield createNewRuleViewProperty(ruleEditor, "width:");
yield onDone;
is(ruleEditor.rule.textProps.length, 1,
"Should have created a new text property.");
@ -26,11 +25,13 @@ function* testMultiValues(inspector, view) {
"Should have created a property editor.");
// Value is focused, lets add multiple rules here and make sure they get added
onDone = view.once("ruleview-changed");
let onMutation = inspector.once("markupmutation");
let valueEditor = ruleEditor.propertyList.children[0].querySelector("input");
valueEditor.value = "height: 10px;color:blue";
let input = view.styleDocument.activeElement;
input.value = "height: 10px;color:blue";
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onMutation;
yield onDone;
is(ruleEditor.rule.textProps.length, 2,
"Should have added the changed value.");
@ -50,4 +51,4 @@ function* testMultiValues(inspector, view) {
"Should have correct property name");
is(ruleEditor.rule.textProps[1].value, "blue",
"Should have correct property value");
}
});

View File

@ -0,0 +1,3 @@
div { color: gold; }
/*# sourceMappingURL=this-source-map-does-not-exist.css.map */

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Invalid source map</title>
<link rel="stylesheet" type="text/css" href="doc_invalid_sourcemap.css">
</head>
<body>
<div>invalid source map</div>
</body>
</html>

View File

@ -8,10 +8,10 @@
"use strict";
const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
const Services = require("Services");
loader.lazyRequireGetter(this, "overlays",
"devtools/client/inspector/shared/style-inspector-overlays");
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
loader.lazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
loader.lazyGetter(this, "_strings", () => {

View File

@ -23,7 +23,7 @@ const {
const EventEmitter = require("devtools/shared/event-emitter");
const promise = require("promise");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const Services = require("Services");
const PREF_IMAGE_TOOLTIP_SIZE = "devtools.inspector.imagePreviewTooltipSize";

View File

@ -7,6 +7,7 @@
"use strict";
const {Cu, Cc, Ci, components} = require("chrome");
const Services = require("Services");
const {Class} = require("sdk/core/heritage");
const {Unknown} = require("sdk/platform/xpcom");
const xpcom = require("sdk/platform/xpcom");
@ -18,7 +19,6 @@ loader.lazyRequireGetter(this, "NetworkHelper",
loader.lazyRequireGetter(this, "JsonViewUtils",
"devtools/client/jsonview/utils");
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
const childProcessMessageManager =
Cc["@mozilla.org/childprocessmessagemanager;1"].

View File

@ -7,9 +7,9 @@
"use strict";
const {Cu, Ci, Cc} = require("chrome");
const Services = require("Services");
const {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
XPCOMUtils.defineLazyGetter(this, "JsonViewService", function() {
return require("devtools/client/jsonview/utils");

View File

@ -75,9 +75,6 @@
<!ENTITY key_zoomin2 "=">
<!ENTITY key_zoomout "-">
<!ENTITY key_resetzoom "0">
<!-- reload WebIDE and devtools from local checkout -->
<!-- this binding is with accel+alt, whereas all others are just accel -->
<!ENTITY key_reload_devtools "R">
<!ENTITY projectPanel_myProjects "My Projects">
<!ENTITY projectPanel_runtimeApps "Runtime Apps">

View File

@ -4,8 +4,7 @@
"use strict";
const { Cu } = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");
const Services = require("Services");
const { gDevTools } = require("devtools/client/framework/devtools");
const { defaultTools, defaultThemes } = require("devtools/client/definitions");

View File

@ -6,10 +6,10 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://testing-common/Assert.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://devtools/client/shared/browser-loader.js");
var { require } = BrowserLoader("resource://devtools/client/memory/", this);
var Services = require("Services");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
DevToolsUtils.testing = true;

View File

@ -4,10 +4,10 @@
"use strict";
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
var { console } = Cu.import("resource://gre/modules/Console.jsm", {});
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var Services = require("Services");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
DevToolsUtils.testing = true;
DevToolsUtils.dumpn.wantLogging = true;

View File

@ -6,7 +6,7 @@
const { Cu, Ci, Cc } = require("chrome");
const { Class } = require("sdk/core/heritage");
const { defer, resolve } = require("promise");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const Services = require("Services");
Cu.import("resource://gre/modules/Task.jsm");

View File

@ -5,7 +5,7 @@
const { Cu, Ci, Cc } = require("chrome");
const { defer, all, resolve } = require("promise");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const Services = require("Services");
loader.lazyImporter(this, "ViewHelpers", "resource://devtools/client/shared/widgets/ViewHelpers.jsm");
loader.lazyRequireGetter(this, "NetworkHelper", "devtools/shared/webconsole/network-helper");

View File

@ -7,8 +7,7 @@ const { Cu, Ci, Cc } = require("chrome");
const { defer, all } = require("promise");
const { setTimeout, clearTimeout } = require("sdk/timers");
const { makeInfallible } = require("devtools/shared/DevToolsUtils");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const Services = require("Services");
// Helper tracer. Should be generic sharable by other modules (bug 1171927)
const trace = {

View File

@ -4,7 +4,7 @@
"use strict";
const { Cu, Cc, Ci } = require("chrome");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const Services = require("Services");
const { defer, resolve } = require("promise");
const { HarUtils } = require("./har-utils.js");
const { HarBuilder } = require("./har-builder.js");

View File

@ -4,7 +4,7 @@
"use strict";
const { Cu, Ci, Cc, CC } = require("chrome");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const Services = require("Services");
XPCOMUtils.defineLazyGetter(this, "dirService", function() {
return Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);

View File

@ -110,7 +110,6 @@ const ACTIVITY_TYPE = {
DISABLE_CACHE: 4
};
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
Cu.import("resource://devtools/client/shared/widgets/VariablesView.jsm");
@ -119,6 +118,7 @@ Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const promise = require("promise");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
const Editor = require("devtools/client/sourceeditor/editor");
const {Tooltip} = require("devtools/client/shared/widgets/Tooltip");

View File

@ -4,11 +4,11 @@
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var { gDevTools } = require("devtools/client/framework/devtools");
var { CurlUtils } = Cu.import("resource://devtools/client/shared/Curl.jsm", {});
var Services = require("Services");
var promise = require("promise");
var NetworkHelper = require("devtools/shared/webconsole/network-helper");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");

View File

@ -4,12 +4,12 @@
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
var { Preferences } = Cu.import("resource://gre/modules/Preferences.jsm", {});
var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var { gDevTools } = require("devtools/client/framework/devtools");
var { console } = require("resource://gre/modules/Console.jsm");
var Services = require("Services");
var { TargetFactory } = require("devtools/client/framework/target");
var Promise = require("promise");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");

View File

@ -5,7 +5,7 @@
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
var Services = require("Services");
var { console } = require("resource://gre/modules/Console.jsm");
const RecordingUtils = require("devtools/shared/performance/recording-utils");
const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";

Some files were not shown because too many files have changed in this diff Show More