mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge m-c to fx-team
This commit is contained in:
commit
3c154f8697
@ -48,6 +48,7 @@ if (Services.prefs.getBoolPref("browser.tabs.remote")) {
|
||||
});
|
||||
addEventListener("DOMFormHasPassword", function(event) {
|
||||
InsecurePasswordUtils.checkForInsecurePasswords(event.target);
|
||||
LoginManagerContent.onFormPassword(event);
|
||||
});
|
||||
addEventListener("DOMAutoComplete", function(event) {
|
||||
LoginManagerContent.onUsernameInput(event);
|
||||
|
@ -543,7 +543,7 @@ BrowserGlue.prototype = {
|
||||
label: win.gNavigatorBundle.getString("slowStartup.helpButton.label"),
|
||||
accessKey: win.gNavigatorBundle.getString("slowStartup.helpButton.accesskey"),
|
||||
callback: function () {
|
||||
win.openUILinkIn("https://support.mozilla.org/kb/firefox-takes-long-time-start-up", "tab");
|
||||
win.openUILinkIn("https://support.mozilla.org/kb/reset-firefox-easily-fix-most-problems", "tab");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -12,7 +12,7 @@ let Services = tempScope.Services;
|
||||
// Disable logging for faster test runs. Set this pref to true if you want to
|
||||
// debug a test in your try runs.
|
||||
let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope);
|
||||
|
@ -2,6 +2,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource:///modules/ContentUtil.jsm");
|
||||
|
||||
let Util = {
|
||||
/*
|
||||
* General purpose utilities
|
||||
@ -11,70 +13,12 @@ let Util = {
|
||||
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
},
|
||||
|
||||
// Recursively find all documents, including root document.
|
||||
getAllDocuments: function getAllDocuments(doc, resultSoFar) {
|
||||
resultSoFar = resultSoFar || [doc];
|
||||
if (!doc.defaultView)
|
||||
return resultSoFar;
|
||||
let frames = doc.defaultView.frames;
|
||||
if (!frames)
|
||||
return resultSoFar;
|
||||
|
||||
let i;
|
||||
let currentDoc;
|
||||
for (i = 0; i < frames.length; i++) {
|
||||
currentDoc = frames[i].document;
|
||||
resultSoFar.push(currentDoc);
|
||||
this.getAllDocuments(currentDoc, resultSoFar);
|
||||
}
|
||||
|
||||
return resultSoFar;
|
||||
},
|
||||
|
||||
// Put the Mozilla networking code into a state that will kick the
|
||||
// auto-connection process.
|
||||
forceOnline: function forceOnline() {
|
||||
Services.io.offline = false;
|
||||
},
|
||||
|
||||
// Pass several objects in and it will combine them all into the first object and return it.
|
||||
// NOTE: Deep copy is not supported
|
||||
extend: function extend() {
|
||||
// copy reference to target object
|
||||
let target = arguments[0] || {};
|
||||
let length = arguments.length;
|
||||
|
||||
if (length === 1) {
|
||||
return target;
|
||||
}
|
||||
|
||||
// Handle case when target is a string or something
|
||||
if (typeof target != "object" && typeof target != "function") {
|
||||
target = {};
|
||||
}
|
||||
|
||||
for (let i = 1; i < length; i++) {
|
||||
// Only deal with non-null/undefined values
|
||||
let options = arguments[i];
|
||||
if (options != null) {
|
||||
// Extend the base object
|
||||
for (let name in options) {
|
||||
let copy = options[name];
|
||||
|
||||
// Prevent never-ending loop
|
||||
if (target === copy)
|
||||
continue;
|
||||
|
||||
if (copy !== undefined)
|
||||
target[name] = copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the modified object
|
||||
return target;
|
||||
},
|
||||
|
||||
/*
|
||||
* Timing utilties
|
||||
*/
|
||||
@ -92,17 +36,6 @@ let Util = {
|
||||
* Console printing utilities
|
||||
*/
|
||||
|
||||
dumpf: function dumpf(str) {
|
||||
let args = arguments;
|
||||
let i = 1;
|
||||
dump(str.replace(/%s/g, function() {
|
||||
if (i >= args.length) {
|
||||
throw "dumps received too many placeholders and not enough arguments";
|
||||
}
|
||||
return args[i++].toString();
|
||||
}));
|
||||
},
|
||||
|
||||
// Like dump, but each arg is handled and there's an automatic newline
|
||||
dumpLn: function dumpLn() {
|
||||
for (let i = 0; i < arguments.length; i++)
|
||||
@ -110,30 +43,10 @@ let Util = {
|
||||
dump("\n");
|
||||
},
|
||||
|
||||
dumpElement: function dumpElement(aElement) {
|
||||
this.dumpLn(aElement.id);
|
||||
},
|
||||
|
||||
dumpElementTree: function dumpElementTree(aElement) {
|
||||
let node = aElement;
|
||||
while (node) {
|
||||
this.dumpLn("node:", node, "id:", node.id, "class:", node.classList);
|
||||
node = node.parentNode;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Element utilities
|
||||
*/
|
||||
|
||||
highlightElement: function highlightElement(aElement) {
|
||||
if (aElement == null) {
|
||||
this.dumpLn("aElement is null");
|
||||
return;
|
||||
}
|
||||
aElement.style.border = "2px solid red";
|
||||
},
|
||||
|
||||
transitionElementVisibility: function(aNodes, aVisible) {
|
||||
// accept single node or a collection of nodes
|
||||
aNodes = aNodes.length ? aNodes : [aNodes];
|
||||
@ -161,24 +74,6 @@ let Util = {
|
||||
return defd.promise;
|
||||
},
|
||||
|
||||
getHrefForElement: function getHrefForElement(target) {
|
||||
let link = null;
|
||||
while (target) {
|
||||
if (target instanceof Ci.nsIDOMHTMLAnchorElement ||
|
||||
target instanceof Ci.nsIDOMHTMLAreaElement ||
|
||||
target instanceof Ci.nsIDOMHTMLLinkElement) {
|
||||
if (target.hasAttribute("href"))
|
||||
link = target;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
|
||||
if (link && link.hasAttribute("href"))
|
||||
return link.href;
|
||||
else
|
||||
return null;
|
||||
},
|
||||
|
||||
isTextInput: function isTextInput(aElement) {
|
||||
return ((aElement instanceof Ci.nsIDOMHTMLInputElement &&
|
||||
aElement.mozIsTextField(false)) ||
|
||||
@ -308,16 +203,6 @@ let Util = {
|
||||
aURL.indexOf("chrome:") == 0);
|
||||
},
|
||||
|
||||
isOpenableScheme: function isShareableScheme(aProtocol) {
|
||||
let dontOpen = /^(mailto|javascript|news|snews)$/;
|
||||
return (aProtocol && !dontOpen.test(aProtocol));
|
||||
},
|
||||
|
||||
isShareableScheme: function isShareableScheme(aProtocol) {
|
||||
let dontShare = /^(chrome|about|file|javascript|resource)$/;
|
||||
return (aProtocol && !dontShare.test(aProtocol));
|
||||
},
|
||||
|
||||
// Don't display anything in the urlbar for these special URIs.
|
||||
isURLEmpty: function isURLEmpty(aURL) {
|
||||
return (!aURL ||
|
||||
@ -382,68 +267,6 @@ let Util = {
|
||||
return this.displayDPI = this.getWindowUtils(window).displayDPI;
|
||||
},
|
||||
|
||||
isPortrait: function isPortrait() {
|
||||
return (window.innerWidth <= window.innerHeight);
|
||||
},
|
||||
|
||||
LOCALE_DIR_RTL: -1,
|
||||
LOCALE_DIR_LTR: 1,
|
||||
get localeDir() {
|
||||
// determine browser dir first to know which direction to snap to
|
||||
let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
|
||||
return chromeReg.isLocaleRTL("global") ? this.LOCALE_DIR_RTL : this.LOCALE_DIR_LTR;
|
||||
},
|
||||
|
||||
/*
|
||||
* Process utilities
|
||||
*/
|
||||
|
||||
isParentProcess: function isInParentProcess() {
|
||||
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
|
||||
},
|
||||
|
||||
/*
|
||||
* Event utilities
|
||||
*/
|
||||
|
||||
modifierMaskFromEvent: function modifierMaskFromEvent(aEvent) {
|
||||
return (aEvent.altKey ? Ci.nsIDOMEvent.ALT_MASK : 0) |
|
||||
(aEvent.ctrlKey ? Ci.nsIDOMEvent.CONTROL_MASK : 0) |
|
||||
(aEvent.shiftKey ? Ci.nsIDOMEvent.SHIFT_MASK : 0) |
|
||||
(aEvent.metaKey ? Ci.nsIDOMEvent.META_MASK : 0);
|
||||
},
|
||||
|
||||
/*
|
||||
* Download utilities
|
||||
*/
|
||||
|
||||
insertDownload: function insertDownload(aSrcUri, aFile) {
|
||||
let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
|
||||
let db = dm.DBConnection;
|
||||
|
||||
let stmt = db.createStatement(
|
||||
"INSERT INTO moz_downloads (name, source, target, startTime, endTime, state, referrer) " +
|
||||
"VALUES (:name, :source, :target, :startTime, :endTime, :state, :referrer)"
|
||||
);
|
||||
|
||||
stmt.params.name = aFile.leafName;
|
||||
stmt.params.source = aSrcUri.spec;
|
||||
stmt.params.target = aFile.path;
|
||||
stmt.params.startTime = Date.now() * 1000;
|
||||
stmt.params.endTime = Date.now() * 1000;
|
||||
stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED;
|
||||
stmt.params.referrer = aSrcUri.spec;
|
||||
|
||||
stmt.execute();
|
||||
stmt.finalize();
|
||||
|
||||
let newItemId = db.lastInsertRowID;
|
||||
let download = dm.getDownload(newItemId);
|
||||
//dm.resumeDownload(download);
|
||||
//Services.obs.notifyObservers(download, "dl-start", null);
|
||||
},
|
||||
|
||||
/*
|
||||
* Local system utilities
|
||||
*/
|
||||
@ -540,3 +363,11 @@ Util.Timeout.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
// Mixin the ContentUtil module exports
|
||||
{
|
||||
for (let name in ContentUtil) {
|
||||
let copy = ContentUtil[name];
|
||||
if (copy !== undefined)
|
||||
Util[name] = copy;
|
||||
}
|
||||
}
|
||||
|
@ -1096,14 +1096,6 @@ var BrowserUI = {
|
||||
case "cmd_panel":
|
||||
PanelUI.toggle();
|
||||
break;
|
||||
case "cmd_volumeLeft":
|
||||
// Zoom in (portrait) or out (landscape)
|
||||
Browser.zoom(Util.isPortrait() ? -1 : 1);
|
||||
break;
|
||||
case "cmd_volumeRight":
|
||||
// Zoom out (portrait) or in (landscape)
|
||||
Browser.zoom(Util.isPortrait() ? 1 : -1);
|
||||
break;
|
||||
case "cmd_openFile":
|
||||
this.openFile();
|
||||
break;
|
||||
|
@ -95,12 +95,6 @@
|
||||
<command id="cmd_sanitize" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_contextUI" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- screen/display -->
|
||||
<command id="cmd_lockscreen" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<command id="cmd_volumeLeft" observes="bcast_contentShowing" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_volumeRight" observes="bcast_contentShowing" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- scrolling -->
|
||||
<command id="cmd_scrollPageUp" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_scrollPageDown" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
@ -140,6 +140,7 @@ let Content = {
|
||||
addEventListener("MozApplicationManifest", this, false);
|
||||
addEventListener("DOMContentLoaded", this, false);
|
||||
addEventListener("DOMAutoComplete", this, false);
|
||||
addEventListener("DOMFormHasPassword", this, false);
|
||||
addEventListener("blur", this, false);
|
||||
addEventListener("pagehide", this, false);
|
||||
// Attach a listener to watch for "click" events bubbling up from error
|
||||
@ -189,6 +190,10 @@ let Content = {
|
||||
this._onClickCapture(aEvent);
|
||||
break;
|
||||
|
||||
case "DOMFormHasPassword":
|
||||
LoginManagerContent.onFormPassword(aEvent);
|
||||
break;
|
||||
|
||||
case "DOMContentLoaded":
|
||||
LoginManagerContent.onContentLoaded(aEvent);
|
||||
this._maybeNotifyErrorPage();
|
||||
|
@ -140,13 +140,13 @@ var FindHelperUI = {
|
||||
this._container.removeEventListener("transitionend", onTransitionEnd, true);
|
||||
this._textbox.value = "";
|
||||
this.status = null;
|
||||
this._textbox.blur();
|
||||
this._open = false;
|
||||
|
||||
// Restore the scroll synchronisation
|
||||
Browser.selectedBrowser.scrollSync = true;
|
||||
};
|
||||
|
||||
this._textbox.blur();
|
||||
this._container.addEventListener("transitionend", onTransitionEnd, true);
|
||||
this._container.dismiss();
|
||||
Elements.browsers.removeAttribute("findbar");
|
||||
|
5
browser/metro/base/tests/unit/blank.xhtml
Normal file
5
browser/metro/base/tests/unit/blank.xhtml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" xml:lang="en">
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
load('Util.js');
|
||||
load("Util.js");
|
||||
|
||||
function run_test() {
|
||||
do_print("Testing Util.extend");
|
||||
|
||||
|
||||
do_print("Check if function is defined");
|
||||
do_check_true(!!Util.extend);
|
||||
|
||||
@ -14,7 +14,7 @@ function run_test() {
|
||||
|
||||
let nullRes = Util.extend(null);
|
||||
do_check_true(nullRes && typeof nullRes == "object");
|
||||
|
||||
|
||||
do_print("Simple extend");
|
||||
let simpleExtend = {a: 1, b: 2};
|
||||
let simpleExtendResult = Util.extend(simpleExtend, {b: 3, c: 4});
|
||||
|
@ -0,0 +1,90 @@
|
||||
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
let Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/ContentUtil.jsm");
|
||||
load("Util.js");
|
||||
|
||||
function empty_node(node) {
|
||||
let cnode;
|
||||
while((cnode = node.firstChild))
|
||||
node.removeChild(cnode);
|
||||
return node;
|
||||
}
|
||||
|
||||
function DOMSerializer() {
|
||||
return Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMSerializer);
|
||||
}
|
||||
|
||||
function serializeContents(node) {
|
||||
let str = DOMSerializer().serializeToString(node);
|
||||
return str.replace(/^<[^>]+>/, '')
|
||||
.replace(/<\/[^>]+>$/, '');
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
let doc, body, str, expectedResult, frag;
|
||||
|
||||
do_print("Testing Util.populateFragmentFromString");
|
||||
|
||||
do_check_true(!!Util.populateFragmentFromString);
|
||||
do_check_true(!!ContentUtil.populateFragmentFromString);
|
||||
do_check_eq(ContentUtil.populateFragmentFromString, Util.populateFragmentFromString);
|
||||
|
||||
do_print("Loading blank document");
|
||||
doc = do_parse_document("blank.xhtml", "application/xhtml+xml");
|
||||
|
||||
// sanity check
|
||||
do_check_eq(doc.nodeType, 9);
|
||||
do_check_true(doc.documentElement.localName != "parsererror");
|
||||
|
||||
body = doc.documentElement.getElementsByTagName("body")[0];
|
||||
do_check_eq(1, body.nodeType);
|
||||
|
||||
frag = doc.createDocumentFragment();
|
||||
|
||||
// test proper handling of leading and trailing text
|
||||
str = "Before, #2, #1. After";
|
||||
Util.populateFragmentFromString(
|
||||
frag, str,
|
||||
{ text: "One", className: "text-one"},
|
||||
{ text: "Two", className: "text-two"}
|
||||
);
|
||||
|
||||
empty_node(body);
|
||||
body.appendChild(frag);
|
||||
|
||||
expectedResult = 'Before, <span class="text-two">Two</span>, <span class="text-one">One</span>. After';
|
||||
do_check_eq(serializeContents(body), expectedResult);
|
||||
|
||||
// test proper handling of unspecified markers
|
||||
str = "#8080: #1. http://localhost/#bar";
|
||||
Util.populateFragmentFromString(
|
||||
frag, str,
|
||||
{ text: "One" }
|
||||
);
|
||||
|
||||
empty_node(body);
|
||||
body.appendChild(frag);
|
||||
|
||||
expectedResult = '#8080: <span>One</span>. http://localhost/#bar';
|
||||
do_check_eq(serializeContents(body), expectedResult);
|
||||
|
||||
// test proper handling of markup in strings
|
||||
str = "#1 <body> tag. © 2000 - Some Corp\u2122";
|
||||
Util.populateFragmentFromString(
|
||||
frag, str,
|
||||
{ text: "About the" }
|
||||
);
|
||||
|
||||
empty_node(body);
|
||||
body.appendChild(frag);
|
||||
expectedResult = "<span>About the</span> <body> tag. &copy; 2000 - Some Corp™"
|
||||
do_check_eq(serializeContents(body), expectedResult);
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
[DEFAULT]
|
||||
head =
|
||||
head =
|
||||
tail =
|
||||
firefox-appdir = metro
|
||||
|
||||
[test_util_extend.js]
|
||||
[test_util_populateFragmentFromString.js]
|
||||
|
||||
|
@ -14,6 +14,11 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ContentUtil", function() {
|
||||
Cu.import("resource:///modules/ContentUtil.jsm");
|
||||
return ContentUtil;
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// HelperApp Launcher Dialog
|
||||
// -----------------------------------------------------------------------
|
||||
@ -97,19 +102,35 @@ HelperAppLauncherDialog.prototype = {
|
||||
let window = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let chromeWin = this._getChromeWindow(window).wrappedJSObject;
|
||||
let notificationBox = chromeWin.Browser.getNotificationBox();
|
||||
let document = notificationBox.ownerDocument;
|
||||
downloadSize = this._getDownloadSize(aLauncher.contentLength);
|
||||
|
||||
let msg = browserBundle.GetStringFromName("alertDownloadSave")
|
||||
.replace("#1", aLauncher.suggestedFileName)
|
||||
.replace("#2", downloadSize)
|
||||
.replace("#3", aLauncher.source.host);
|
||||
let msg = browserBundle.GetStringFromName("alertDownloadSave");
|
||||
|
||||
let fragment = ContentUtil.populateFragmentFromString(
|
||||
document.createDocumentFragment(),
|
||||
msg,
|
||||
{
|
||||
text: aLauncher.suggestedFileName,
|
||||
className: "download-filename-text"
|
||||
},
|
||||
{
|
||||
text: aLauncher.suggestedFileName,
|
||||
className: "download-size-text"
|
||||
},
|
||||
{
|
||||
text: aLauncher.source.host,
|
||||
className: "download-host-text"
|
||||
}
|
||||
);
|
||||
notificationBox.notificationsHidden = false;
|
||||
let newBar = notificationBox.appendNotification(msg,
|
||||
let newBar = notificationBox.appendNotification("",
|
||||
"save-download",
|
||||
URI_GENERIC_ICON_DOWNLOAD,
|
||||
notificationBox.PRIORITY_WARNING_HIGH,
|
||||
buttons);
|
||||
let messageContainer = document.getAnonymousElementByAttribute(newBar, "anonid", "messageText");
|
||||
messageContainer.appendChild(fragment);
|
||||
},
|
||||
|
||||
promptForSaveToFile: function hald_promptForSaveToFile(aLauncher, aContext, aDefaultFile, aSuggestedFileExt, aForcePrompt) {
|
||||
|
92
browser/metro/modules/ContentUtil.jsm
Normal file
92
browser/metro/modules/ContentUtil.jsm
Normal file
@ -0,0 +1,92 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ContentUtil"];
|
||||
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
this.ContentUtil = {
|
||||
populateFragmentFromString: function populateFragmentFromString(fragment, str) {
|
||||
let re = /^([^#]*)#(\d+)\b([^#]*)/,
|
||||
document = fragment.ownerDocument,
|
||||
// the remaining arguments are our {text, className} values
|
||||
replacements = Array.slice(arguments, 2),
|
||||
match;
|
||||
|
||||
// walk over the string, building textNode/spans as nec. with replacement content
|
||||
// note that #1,#2 etc. may not appear in numerical order in the string
|
||||
while ((match = re.exec(str))) {
|
||||
let [mstring,pre,num,post] = match,
|
||||
replaceText = "",
|
||||
replaceClass,
|
||||
idx = num-1; // markers are 1-based, replacement indices 0 based
|
||||
|
||||
str = str.substring(re.lastIndex+mstring.length);
|
||||
|
||||
if (pre)
|
||||
fragment.appendChild(document.createTextNode(pre));
|
||||
|
||||
if (replacements[idx]) {
|
||||
replaceText = replacements[idx].text;
|
||||
let spanNode = document.createElementNS(XHTML_NS, "span");
|
||||
spanNode.appendChild(document.createTextNode(replaceText));
|
||||
// add class to the span when provided
|
||||
if(replacements[idx].className)
|
||||
spanNode.classList.add(replacements[idx].className);
|
||||
|
||||
fragment.appendChild(spanNode);
|
||||
} else {
|
||||
// put it back if no replacement was provided
|
||||
fragment.appendChild(document.createTextNode("#"+num));
|
||||
}
|
||||
|
||||
if(post)
|
||||
fragment.appendChild(document.createTextNode(post));
|
||||
}
|
||||
if(str)
|
||||
fragment.appendChild(document.createTextNode(str));
|
||||
|
||||
return fragment;
|
||||
},
|
||||
|
||||
// Pass several objects in and it will combine them all into the first object and return it.
|
||||
// NOTE: Deep copy is not supported
|
||||
extend: function extend() {
|
||||
// copy reference to target object
|
||||
let target = arguments[0] || {};
|
||||
let length = arguments.length;
|
||||
|
||||
if (length === 1) {
|
||||
return target;
|
||||
}
|
||||
|
||||
// Handle case when target is a string or something
|
||||
if (typeof target != "object" && typeof target != "function") {
|
||||
target = {};
|
||||
}
|
||||
|
||||
for (let i = 1; i < length; i++) {
|
||||
// Only deal with non-null/undefined values
|
||||
let options = arguments[i];
|
||||
if (options != null) {
|
||||
// Extend the base object
|
||||
for (let name in options) {
|
||||
let copy = options[name];
|
||||
|
||||
// Prevent never-ending loop
|
||||
if (target === copy)
|
||||
continue;
|
||||
|
||||
if (copy !== undefined)
|
||||
target[name] = copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the modified object
|
||||
return target;
|
||||
}
|
||||
|
||||
};
|
@ -5,6 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'ContentUtil.jsm',
|
||||
'CrossSlide.jsm',
|
||||
'View.jsm',
|
||||
'colorUtils.jsm',
|
||||
|
@ -696,7 +696,7 @@ documenttab[selected] .documenttab-selection {
|
||||
}
|
||||
|
||||
/* navbar edit button: one button out of three - when editing: go, when !editing,
|
||||
loading: stop, when !editing, !loading: reload */
|
||||
loading: stop, when !editing, !loading: reload */
|
||||
|
||||
#go-button, #reload-button, #stop-button {
|
||||
visibility: collapse;
|
||||
@ -1006,6 +1006,15 @@ documenttab[selected] .documenttab-selection {
|
||||
-moz-image-region: rect(80px, 560px, 120px, 520px) !important;
|
||||
}
|
||||
|
||||
/* Download notifications ======================================================= */
|
||||
|
||||
.download-filename-text {
|
||||
font-weight: bold;
|
||||
}
|
||||
.download-host-text {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Autoscroll popup ======================================================== */
|
||||
|
||||
.autoscroller {
|
||||
|
@ -37,7 +37,11 @@
|
||||
transition: opacity .15s ease 0s;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox > .checkbox-check {
|
||||
.side-menu-widget-item-checkbox > .checkbox-spacer-box {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox > .checkbox-spacer-box > .checkbox-check {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
background-image: url(itemToggle.png);
|
||||
@ -50,7 +54,7 @@
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox[checked] > .checkbox-check {
|
||||
.side-menu-widget-item-checkbox[checked] > .checkbox-spacer-box > .checkbox-check {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
|
@ -1664,12 +1664,11 @@ abstract public class GeckoApp
|
||||
protected int getSessionRestoreState(Bundle savedInstanceState) {
|
||||
final SharedPreferences prefs = GeckoApp.getAppSharedPreferences();
|
||||
int restoreMode = RESTORE_NONE;
|
||||
boolean allowCrashRestore = true;
|
||||
|
||||
// If the version has changed, the user has done an upgrade, so restore
|
||||
// previous tabs.
|
||||
final int versionCode = getVersionCode();
|
||||
if (prefs.getInt(PREFS_VERSION_CODE, 0) != versionCode) {
|
||||
// If the version has changed, the user has done an upgrade, so restore
|
||||
// previous tabs.
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -1680,19 +1679,12 @@ abstract public class GeckoApp
|
||||
});
|
||||
|
||||
restoreMode = RESTORE_NORMAL;
|
||||
} else if (savedInstanceState != null) {
|
||||
} else if (savedInstanceState != null || PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString(GeckoPreferences.PREFS_RESTORE_SESSION, "quit")
|
||||
.equals("always")) {
|
||||
// We're coming back from a background kill by the OS or the user
|
||||
// has chosen to always restore, so restore.
|
||||
restoreMode = RESTORE_NORMAL;
|
||||
} else {
|
||||
String restorePref = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString(GeckoPreferences.PREFS_RESTORE_SESSION, "crash");
|
||||
if ("always".equals(restorePref)) {
|
||||
restoreMode = RESTORE_NORMAL;
|
||||
} else {
|
||||
restoreMode = RESTORE_NONE;
|
||||
if ("never".equals(restorePref)) {
|
||||
allowCrashRestore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We record crashes in the crash reporter. If sessionstore.js
|
||||
@ -1709,9 +1701,7 @@ abstract public class GeckoApp
|
||||
}
|
||||
});
|
||||
|
||||
if (allowCrashRestore) {
|
||||
restoreMode = RESTORE_CRASH;
|
||||
}
|
||||
restoreMode = RESTORE_CRASH;
|
||||
}
|
||||
|
||||
return restoreMode;
|
||||
|
@ -77,7 +77,7 @@ public class GeckoPreferences
|
||||
private static String PREFS_HEALTHREPORT_LINK = NON_PREF_PREFIX + "healthreport.link";
|
||||
private static String PREFS_DEVTOOLS_REMOTE_ENABLED = "devtools.debugger.remote-enabled";
|
||||
|
||||
public static String PREFS_RESTORE_SESSION = NON_PREF_PREFIX + "restoreSession2";
|
||||
public static String PREFS_RESTORE_SESSION = NON_PREF_PREFIX + "restoreSession3";
|
||||
|
||||
// These values are chosen to be distinct from other Activity constants.
|
||||
private static int REQUEST_CODE_PREF_SCREEN = 5;
|
||||
|
@ -668,6 +668,7 @@ RES_DRAWABLE_MDPI = \
|
||||
res/drawable-mdpi/icon_most_recent_empty.png \
|
||||
res/drawable-mdpi/icon_most_visited.png \
|
||||
res/drawable-mdpi/icon_most_visited_empty.png \
|
||||
res/drawable-mdpi/icon_openinapp.png \
|
||||
res/drawable-mdpi/icon_pageaction.png \
|
||||
res/drawable-mdpi/icon_reading_list_empty.png \
|
||||
res/drawable-mdpi/progress_spinner.png \
|
||||
@ -780,6 +781,7 @@ RES_DRAWABLE_HDPI = \
|
||||
res/drawable-hdpi/icon_most_recent_empty.png \
|
||||
res/drawable-hdpi/icon_most_visited.png \
|
||||
res/drawable-hdpi/icon_most_visited_empty.png \
|
||||
res/drawable-hdpi/icon_openinapp.png \
|
||||
res/drawable-hdpi/icon_pageaction.png \
|
||||
res/drawable-hdpi/icon_reading_list_empty.png \
|
||||
res/drawable-hdpi/tab_indicator_divider.9.png \
|
||||
@ -878,6 +880,7 @@ RES_DRAWABLE_XHDPI = \
|
||||
res/drawable-xhdpi/icon_most_recent_empty.png \
|
||||
res/drawable-xhdpi/icon_most_visited.png \
|
||||
res/drawable-xhdpi/icon_most_visited_empty.png \
|
||||
res/drawable-xhdpi/icon_openinapp.png \
|
||||
res/drawable-xhdpi/icon_pageaction.png \
|
||||
res/drawable-xhdpi/icon_reading_list_empty.png \
|
||||
res/drawable-xhdpi/spinner_default.9.png \
|
||||
|
@ -407,11 +407,16 @@ public class BrowserDB {
|
||||
public boolean moveToPosition(int position) {
|
||||
mIndex = position;
|
||||
|
||||
// move the real cursor as if we were stepping through it to this position
|
||||
// be careful not to move it to far, and to account for any pinned sites
|
||||
// Move the real cursor as if we were stepping through it to this position.
|
||||
// Account for pinned sites, and be careful to update its position to the
|
||||
// minimum or maximum position, even if we're moving beyond its bounds.
|
||||
int before = getPinnedBefore(position);
|
||||
int p2 = position - before;
|
||||
if (p2 >= -1 && p2 <= mCursor.getCount()) {
|
||||
if (p2 <= -1) {
|
||||
super.moveToPosition(-1);
|
||||
} else if (p2 >= mCursor.getCount()) {
|
||||
super.moveToPosition(mCursor.getCount());
|
||||
} else {
|
||||
super.moveToPosition(p2);
|
||||
}
|
||||
|
||||
|
@ -112,8 +112,7 @@
|
||||
<!ENTITY pref_reflow_on_zoom4 "Text reflow">
|
||||
<!ENTITY pref_restore "Tabs">
|
||||
<!ENTITY pref_restore_always "Always restore">
|
||||
<!ENTITY pref_restore_crash "Restore after a crash">
|
||||
<!ENTITY pref_restore_never "Never restore">
|
||||
<!ENTITY pref_restore_quit "Don\'t restore after quitting &brandShortName;">
|
||||
<!ENTITY pref_font_size_tiny "Tiny">
|
||||
<!ENTITY pref_font_size_small "Small">
|
||||
<!ENTITY pref_font_size_medium "Medium">
|
||||
|
BIN
mobile/android/base/resources/drawable-hdpi/icon_openinapp.png
Normal file
BIN
mobile/android/base/resources/drawable-hdpi/icon_openinapp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 340 B |
BIN
mobile/android/base/resources/drawable-mdpi/icon_openinapp.png
Normal file
BIN
mobile/android/base/resources/drawable-mdpi/icon_openinapp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 249 B |
BIN
mobile/android/base/resources/drawable-xhdpi/icon_openinapp.png
Normal file
BIN
mobile/android/base/resources/drawable-xhdpi/icon_openinapp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 454 B |
@ -101,13 +101,11 @@
|
||||
</string-array>
|
||||
<string-array name="pref_restore_entries">
|
||||
<item>@string/pref_restore_always</item>
|
||||
<item>@string/pref_restore_crash</item>
|
||||
<item>@string/pref_restore_never</item>
|
||||
<item>@string/pref_restore_quit</item>
|
||||
</string-array>
|
||||
<string-array name="pref_restore_values">
|
||||
<item>always</item>
|
||||
<item>crash</item>
|
||||
<item>never</item>
|
||||
<item>quit</item>
|
||||
</string-array>
|
||||
<string-array name="pref_update_autodownload_entries">
|
||||
<item>@string/pref_update_autodownload_enabled</item>
|
||||
|
@ -25,9 +25,9 @@
|
||||
android:negativeButtonText="@string/button_cancel"
|
||||
android:persistent="false" />
|
||||
|
||||
<ListPreference android:key="android.not_a_preference.restoreSession2"
|
||||
<ListPreference android:key="android.not_a_preference.restoreSession3"
|
||||
android:title="@string/pref_restore"
|
||||
android:defaultValue="crash"
|
||||
android:defaultValue="quit"
|
||||
android:entries="@array/pref_restore_entries"
|
||||
android:entryValues="@array/pref_restore_values"
|
||||
android:persistent="true" />
|
||||
|
@ -31,9 +31,9 @@
|
||||
android:negativeButtonText="@string/button_cancel"
|
||||
android:persistent="false" />
|
||||
|
||||
<ListPreference android:key="android.not_a_preference.restoreSession2"
|
||||
<ListPreference android:key="android.not_a_preference.restoreSession3"
|
||||
android:title="@string/pref_restore"
|
||||
android:defaultValue="crash"
|
||||
android:defaultValue="quit"
|
||||
android:entries="@array/pref_restore_entries"
|
||||
android:entryValues="@array/pref_restore_values"
|
||||
android:persistent="true" />
|
||||
|
@ -27,9 +27,9 @@
|
||||
android:negativeButtonText="@string/button_cancel"
|
||||
android:persistent="false" />
|
||||
|
||||
<ListPreference android:key="android.not_a_preference.restoreSession2"
|
||||
<ListPreference android:key="android.not_a_preference.restoreSession3"
|
||||
android:title="@string/pref_restore"
|
||||
android:defaultValue="crash"
|
||||
android:defaultValue="quit"
|
||||
android:entries="@array/pref_restore_entries"
|
||||
android:entryValues="@array/pref_restore_values"
|
||||
android:persistent="true" />
|
||||
|
@ -129,8 +129,7 @@
|
||||
<string name="pref_reflow_on_zoom">&pref_reflow_on_zoom4;</string>
|
||||
<string name="pref_restore">&pref_restore;</string>
|
||||
<string name="pref_restore_always">&pref_restore_always;</string>
|
||||
<string name="pref_restore_crash">&pref_restore_crash;</string>
|
||||
<string name="pref_restore_never">&pref_restore_never;</string>
|
||||
<string name="pref_restore_quit">&pref_restore_quit;</string>
|
||||
<string name="pref_show_product_announcements">&pref_show_product_announcements;</string>
|
||||
<string name="pref_sync">&pref_sync;</string>
|
||||
<string name="pref_search_suggestions">&pref_search_suggestions;</string>
|
||||
|
@ -26,7 +26,7 @@ public class testSettingsMenuItems extends PixelTest {
|
||||
String[][] OPTIONS_CUSTOMIZE = {
|
||||
{ "Search settings", "", "Show search suggestions", "Installed search engines" },
|
||||
{ "Import from Android", "", "Bookmarks", "History", "Import" },
|
||||
{ "Tabs", "Restore after a crash", "Always restore", "Restore after a crash", "Never restore" },
|
||||
{ "Tabs", "Don't restore after quitting " + BRAND_NAME, "Always restore", "Don't restore after quitting " + BRAND_NAME },
|
||||
{ "Automatic updates", "Only over Wi-Fi", "Enabled", "Only over Wi-Fi", "Disabled" },
|
||||
};
|
||||
|
||||
|
@ -69,6 +69,54 @@ var HelperApps = {
|
||||
return found;
|
||||
},
|
||||
|
||||
updatePageAction: function setPageAction(uri) {
|
||||
let apps = this.getAppsForUri(uri);
|
||||
if (apps.length > 0)
|
||||
this._setPageActionFor(uri, apps);
|
||||
else
|
||||
this._removePageAction();
|
||||
},
|
||||
|
||||
_setPageActionFor: function setPageActionFor(uri, apps) {
|
||||
this._pageActionUri = uri;
|
||||
|
||||
// If the pageaction is already added, simply update the URI to be launched when 'onclick' is triggered.
|
||||
if (this._pageActionId != undefined)
|
||||
return;
|
||||
|
||||
this._pageActionId = NativeWindow.pageactions.add({
|
||||
title: Strings.browser.GetStringFromName("openInApp.pageAction"),
|
||||
icon: "drawable://icon_openinapp",
|
||||
clickCallback: function() {
|
||||
if (apps.length == 1)
|
||||
this._launchApp(apps[0], this._pageActionUri);
|
||||
else
|
||||
this.openUriInApp(this._pageActionUri);
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
_removePageAction: function removePageAction() {
|
||||
if(!this._pageActionId)
|
||||
return;
|
||||
|
||||
NativeWindow.pageactions.remove(this._pageActionId);
|
||||
delete this._pageActionId;
|
||||
},
|
||||
|
||||
_launchApp: function launchApp(appData, uri) {
|
||||
let mimeType = ContentAreaUtils.getMIMETypeForURI(uri) || "";
|
||||
let msg = {
|
||||
type: "Intent:Open",
|
||||
mime: mimeType,
|
||||
action: "android.intent.action.VIEW",
|
||||
url: uri.spec,
|
||||
packageName: appData.packageName,
|
||||
className: appData.activityName
|
||||
};
|
||||
sendMessageToJava(msg);
|
||||
},
|
||||
|
||||
openUriInApp: function openUriInApp(uri) {
|
||||
let mimeType = ContentAreaUtils.getMIMETypeForURI(uri) || "";
|
||||
let msg = {
|
||||
|
@ -2663,6 +2663,7 @@ Tab.prototype = {
|
||||
this.browser.sessionHistory.addSHistoryListener(this);
|
||||
|
||||
this.browser.addEventListener("DOMContentLoaded", this, true);
|
||||
this.browser.addEventListener("DOMFormHasPassword", this, true);
|
||||
this.browser.addEventListener("DOMLinkAdded", this, true);
|
||||
this.browser.addEventListener("DOMTitleChanged", this, true);
|
||||
this.browser.addEventListener("DOMWindowClose", this, true);
|
||||
@ -2811,6 +2812,7 @@ Tab.prototype = {
|
||||
this.browser.sessionHistory.removeSHistoryListener(this);
|
||||
|
||||
this.browser.removeEventListener("DOMContentLoaded", this, true);
|
||||
this.browser.removeEventListener("DOMFormHasPassword", this, true);
|
||||
this.browser.removeEventListener("DOMLinkAdded", this, true);
|
||||
this.browser.removeEventListener("DOMTitleChanged", this, true);
|
||||
this.browser.removeEventListener("DOMWindowClose", this, true);
|
||||
@ -3368,6 +3370,11 @@ Tab.prototype = {
|
||||
break;
|
||||
}
|
||||
|
||||
case "DOMFormHasPassword": {
|
||||
LoginManagerContent.onFormPassword(aEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case "DOMLinkAdded": {
|
||||
let target = aEvent.originalTarget;
|
||||
if (!target.href || target.disabled)
|
||||
@ -3540,6 +3547,9 @@ Tab.prototype = {
|
||||
this._linkifier.linkifyNumbers(this.browser.contentWindow.document);
|
||||
}
|
||||
|
||||
// Show page actions for helper apps.
|
||||
HelperApps.updatePageAction(this.browser.currentURI);
|
||||
|
||||
if (!Reader.isEnabledForParseOnLoad)
|
||||
return;
|
||||
|
||||
|
@ -288,3 +288,6 @@ getUserMedia.sharingCameraAndMicrophone.message2 = Camera and microphone are on
|
||||
#Reader mode
|
||||
readerMode.enter = Enter Reader Mode
|
||||
readerMode.exit = Exit Reader Mode
|
||||
|
||||
#Open in App
|
||||
openInApp.pageAction = Open in App
|
||||
|
@ -3909,6 +3909,7 @@ pref("signon.SignonFileName3", "signons3.txt"); // obsolete
|
||||
pref("signon.autofillForms", true);
|
||||
pref("signon.autologin.proxy", false);
|
||||
pref("signon.debug", false);
|
||||
pref("signon.useDOMFormHasPassword", true);
|
||||
|
||||
// Satchel (Form Manager) prefs
|
||||
pref("browser.formfill.debug", false);
|
||||
|
@ -184,7 +184,7 @@ interface nsIBrowserSearchInitObserver : nsISupports
|
||||
void onInitComplete(in nsresult aStatus);
|
||||
};
|
||||
|
||||
[scriptable, uuid(89beea9f-61a8-45d3-818d-b259f00195fe)]
|
||||
[scriptable, uuid(939d74a4-5b01-463c-80c7-4301f0c0f9ef)]
|
||||
interface nsIBrowserSearchService : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -13,7 +13,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
||||
var gEnabled = false, gDebug = false; // these mirror signon.* prefs
|
||||
var gEnabled = false, gDebug = false, gAutofillForms = true; // these mirror signon.* prefs
|
||||
var gUseDOMFormHasPassword = false; // use DOMFormHasPassword event for autofill
|
||||
|
||||
function log(...pieces) {
|
||||
function generateLogMessage(args) {
|
||||
@ -70,6 +71,8 @@ var observer = {
|
||||
onPrefChange : function() {
|
||||
gDebug = Services.prefs.getBoolPref("signon.debug");
|
||||
gEnabled = Services.prefs.getBoolPref("signon.rememberSignons");
|
||||
gAutofillForms = Services.prefs.getBoolPref("signon.autofillForms");
|
||||
gUseDOMFormHasPassword = Services.prefs.getBoolPref("signon.useDOMFormHasPassword");
|
||||
},
|
||||
};
|
||||
|
||||
@ -92,6 +95,10 @@ var LoginManagerContent = {
|
||||
},
|
||||
|
||||
onContentLoaded : function (event) {
|
||||
// If we're using the new DOMFormHasPassword event, don't fill at pageload.
|
||||
if (gUseDOMFormHasPassword)
|
||||
return;
|
||||
|
||||
if (!event.isTrusted)
|
||||
return;
|
||||
|
||||
@ -108,6 +115,64 @@ var LoginManagerContent = {
|
||||
},
|
||||
|
||||
|
||||
onFormPassword: function (event) {
|
||||
// If we're not using the new DOMFormHasPassword event, only fill at pageload.
|
||||
if (!gUseDOMFormHasPassword)
|
||||
return;
|
||||
|
||||
if (!event.isTrusted)
|
||||
return;
|
||||
|
||||
if (!gEnabled)
|
||||
return;
|
||||
|
||||
let form = event.target;
|
||||
let doc = form.ownerDocument;
|
||||
|
||||
log("onFormPassword for", doc.documentURI);
|
||||
|
||||
// If there are no logins for this site, bail out now.
|
||||
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
|
||||
if (!Services.logins.countLogins(formOrigin, "", null))
|
||||
return;
|
||||
|
||||
// If we're currently displaying a master password prompt, defer
|
||||
// processing this form until the user handles the prompt.
|
||||
if (Services.logins.uiBusy) {
|
||||
log("deferring onFormPassword for", doc.documentURI);
|
||||
let self = this;
|
||||
let observer = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
|
||||
observe: function (subject, topic, data) {
|
||||
log("Got deferred onFormPassword notification:", topic);
|
||||
// Only run observer once.
|
||||
Services.obs.removeObserver(this, "passwordmgr-crypto-login");
|
||||
Services.obs.removeObserver(this, "passwordmgr-crypto-loginCanceled");
|
||||
if (topic == "passwordmgr-crypto-loginCanceled")
|
||||
return;
|
||||
self.onFormPassword(event);
|
||||
},
|
||||
handleEvent : function (event) {
|
||||
// Not expected to be called
|
||||
}
|
||||
};
|
||||
// Trickyness follows: We want an observer, but don't want it to
|
||||
// cause leaks. So add the observer with a weak reference, and use
|
||||
// a dummy event listener (a strong reference) to keep it alive
|
||||
// until the form is destroyed.
|
||||
Services.obs.addObserver(observer, "passwordmgr-crypto-login", true);
|
||||
Services.obs.addObserver(observer, "passwordmgr-crypto-loginCanceled", true);
|
||||
form.addEventListener("mozCleverClosureHack", observer);
|
||||
return;
|
||||
}
|
||||
|
||||
let autofillForm = gAutofillForms && !PrivateBrowsingUtils.isWindowPrivate(doc.defaultView);
|
||||
|
||||
this._fillForm(form, autofillForm, false, false, null);
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* onUsernameInput
|
||||
*
|
||||
@ -537,8 +602,7 @@ var LoginManagerContent = {
|
||||
|
||||
log("fillDocument processing", forms.length, "forms on", doc.documentURI);
|
||||
|
||||
var autofillForm = !PrivateBrowsingUtils.isWindowPrivate(doc.defaultView) &&
|
||||
Services.prefs.getBoolPref("signon.autofillForms");
|
||||
var autofillForm = gAutofillForms && !PrivateBrowsingUtils.isWindowPrivate(doc.defaultView);
|
||||
var previousActionOrigin = null;
|
||||
var foundLogins = null;
|
||||
|
||||
|
@ -27,6 +27,7 @@ MOCHITEST_FILES = \
|
||||
test_basic_form_observer_autocomplete.html \
|
||||
test_basic_form_observer_foundLogins.html \
|
||||
test_basic_form_pwonly.html \
|
||||
test_basic_form_pwevent.html \
|
||||
test_bug_227640.html \
|
||||
test_bug_242956.html \
|
||||
test_bug_360493_1.html \
|
||||
|
@ -21,6 +21,36 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
// Assume that the pref starts out true, so set to false
|
||||
SpecialPowers.setBoolPref("signon.autofillForms", false);
|
||||
|
||||
var TestObserver = {
|
||||
receivedNotificationFoundForm : false,
|
||||
receivedNotificationFoundLogins : false,
|
||||
dataFoundForm : "",
|
||||
dataFoundLogins : null,
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
observe : function (subject, topic, data) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var pwmgr = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
if (topic == "passwordmgr-found-form") {
|
||||
info("got passwordmgr-found-form");
|
||||
this.receivedNotificationFoundForm = true;
|
||||
this.dataFoundForm = data;
|
||||
// Now fill the form
|
||||
pwmgr.fillForm(subject);
|
||||
} else if (topic == "passwordmgr-found-logins") {
|
||||
info("got passwordmgr-found-logins");
|
||||
this.receivedNotificationFoundLogins = true;
|
||||
this.dataFoundLogins = subject.QueryInterface(Ci.nsIPropertyBag2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add the observer
|
||||
var os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.addObserver(TestObserver, "passwordmgr-found-form", false);
|
||||
os.addObserver(TestObserver, "passwordmgr-found-logins", false);
|
||||
</script>
|
||||
|
||||
<p id="display"></p>
|
||||
@ -42,35 +72,6 @@ SpecialPowers.setBoolPref("signon.autofillForms", false);
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Login Manager: simple form with autofillForms disabled and notifying observers **/
|
||||
|
||||
var TestObserver = {
|
||||
receivedNotificationFoundForm : false,
|
||||
receivedNotificationFoundLogins : false,
|
||||
dataFoundForm : "",
|
||||
dataFoundLogins : null,
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
observe : function (subject, topic, data) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var pwmgr = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
if (topic == "passwordmgr-found-form") {
|
||||
this.receivedNotificationFoundForm = true;
|
||||
this.dataFoundForm = data;
|
||||
// Now fill the form
|
||||
pwmgr.fillForm(subject);
|
||||
} else if (topic == "passwordmgr-found-logins") {
|
||||
this.receivedNotificationFoundLogins = true;
|
||||
this.dataFoundLogins = subject.QueryInterface(Ci.nsIPropertyBag2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add the observer
|
||||
var os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.addObserver(TestObserver, "passwordmgr-found-form", false);
|
||||
os.addObserver(TestObserver, "passwordmgr-found-logins", false);
|
||||
|
||||
function startTest(){
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
// Test that found-form observer is notified & got correct data
|
||||
|
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=355063
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Test for Bug 355063</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript" src="pwmgr_common.js"></script>
|
||||
<script type="application/javascript">
|
||||
/** Test for Bug 355063 **/
|
||||
|
||||
function startTest() {
|
||||
info("startTest");
|
||||
addForm();
|
||||
}
|
||||
|
||||
function addForm() {
|
||||
info("addForm");
|
||||
var c = document.getElementById("content");
|
||||
c.innerHTML = "<form id=form1>form1: <input id=u1><input type=password id=p1></form><br>";
|
||||
}
|
||||
|
||||
function checkForm() {
|
||||
info("checkForm");
|
||||
var userField = document.getElementById("u1");
|
||||
var passField = document.getElementById("p1");
|
||||
is(userField.value, "testuser", "checking filled username");
|
||||
is(passField.value, "testpass", "checking filled password");
|
||||
|
||||
SpecialPowers.removeChromeEventListener("DOMFormHasPassword", checkForm);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) {
|
||||
commonInit();
|
||||
|
||||
// Password Manager's own listener should always have been added first, so
|
||||
// the test's listener should be called after the pwmgr's listener fills in
|
||||
// a login.
|
||||
//
|
||||
SpecialPowers.addChromeEventListener("DOMFormHasPassword", checkForm);
|
||||
window.addEventListener("load", startTest);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
} else {
|
||||
ok(true, "Skipping test when useDOMFormHasPassword is disabled");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=355063">Mozilla Bug 355063</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
forms go here!
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -52,7 +52,12 @@ function startTest() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.onload = startTest;
|
||||
if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) {
|
||||
info("skipping test when signon.useDOMFormHasPassword is enabled");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
window.onload = startTest;
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -52,7 +52,12 @@ function startTest() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.onload = startTest;
|
||||
if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) {
|
||||
info("skipping test when signon.useDOMFormHasPassword is enabled");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
window.onload = startTest;
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -52,7 +52,12 @@ function startTest() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.onload = startTest;
|
||||
if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) {
|
||||
info("skipping test when signon.useDOMFormHasPassword is enabled");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
window.onload = startTest;
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -146,17 +146,19 @@ const BackgroundPageThumbs = {
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("privatebrowsing", "true");
|
||||
|
||||
// Size the browser. Setting the width and height attributes doesn't
|
||||
// work -- the resulting thumbnails are blank and transparent -- but
|
||||
// setting the style does.
|
||||
let width = {};
|
||||
let height = {};
|
||||
// Size the browser. Make its aspect ratio the same as the canvases' that
|
||||
// the thumbnails are drawn into; the canvases' aspect ratio is the same as
|
||||
// the screen's, so use that. Aim for a size in the ballpark of 1024x768.
|
||||
let [swidth, sheight] = [{}, {}];
|
||||
Cc["@mozilla.org/gfx/screenmanager;1"].
|
||||
getService(Ci.nsIScreenManager).
|
||||
primaryScreen.
|
||||
GetRectDisplayPix({}, {}, width, height);
|
||||
browser.style.width = width.value + "px";
|
||||
browser.style.height = height.value + "px";
|
||||
GetRectDisplayPix({}, {}, swidth, sheight);
|
||||
let bwidth = Math.min(1024, swidth.value);
|
||||
// Setting the width and height attributes doesn't work -- the resulting
|
||||
// thumbnails are blank and transparent -- but setting the style does.
|
||||
browser.style.width = bwidth + "px";
|
||||
browser.style.height = (bwidth * sheight.value / swidth.value) + "px";
|
||||
|
||||
this._parentWin.document.documentElement.appendChild(browser);
|
||||
|
||||
|
@ -1993,8 +1993,9 @@ SourceClient.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let { contentType, source } = aResponse;
|
||||
let longString = this._client.activeThread.threadLongString(
|
||||
aResponse.source);
|
||||
source);
|
||||
longString.substring(0, longString.length, function (aResponse) {
|
||||
if (aResponse.error) {
|
||||
aCallback(aResponse);
|
||||
@ -2002,7 +2003,8 @@ SourceClient.prototype = {
|
||||
}
|
||||
|
||||
aCallback({
|
||||
source: aResponse.substring
|
||||
source: aResponse.substring,
|
||||
contentType: contentType
|
||||
});
|
||||
});
|
||||
}.bind(this));
|
||||
|
@ -692,8 +692,7 @@ ThreadActor.prototype = {
|
||||
}
|
||||
packet.why = aReason;
|
||||
|
||||
let { url, line, column } = packet.frame.where;
|
||||
this.sources.getOriginalLocation(url, line, column).then(aOrigPosition => {
|
||||
this.sources.getOriginalLocation(packet.frame.where).then(aOrigPosition => {
|
||||
packet.frame.where = aOrigPosition;
|
||||
resolve(onPacket(packet))
|
||||
.then(null, error => {
|
||||
@ -704,7 +703,7 @@ ThreadActor.prototype = {
|
||||
};
|
||||
})
|
||||
.then(packet => {
|
||||
this.conn.send(packet)
|
||||
this.conn.send(packet);
|
||||
});
|
||||
});
|
||||
|
||||
@ -772,10 +771,11 @@ ThreadActor.prototype = {
|
||||
// Define the JS hook functions for stepping.
|
||||
|
||||
let onEnterFrame = aFrame => {
|
||||
let { url } = this.synchronize(this.sources.getOriginalLocation(
|
||||
aFrame.script.url,
|
||||
aFrame.script.getOffsetLine(aFrame.offset),
|
||||
getOffsetColumn(aFrame.offset, aFrame.script)));
|
||||
let { url } = this.synchronize(this.sources.getOriginalLocation({
|
||||
url: aFrame.script.url,
|
||||
line: aFrame.script.getOffsetLine(aFrame.offset),
|
||||
column: getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
}));
|
||||
|
||||
return this.sources.isBlackBoxed(url)
|
||||
? undefined
|
||||
@ -787,10 +787,11 @@ ThreadActor.prototype = {
|
||||
let onPop = function TA_onPop(aCompletion) {
|
||||
// onPop is called with 'this' set to the current frame.
|
||||
|
||||
let { url } = thread.synchronize(thread.sources.getOriginalLocation(
|
||||
this.script.url,
|
||||
this.script.getOffsetLine(this.offset),
|
||||
getOffsetColumn(this.offset, this.script)));
|
||||
let { url } = thread.synchronize(thread.sources.getOriginalLocation({
|
||||
url: this.script.url,
|
||||
line: this.script.getOffsetLine(this.offset),
|
||||
column: getOffsetColumn(this.offset, this.script)
|
||||
}));
|
||||
|
||||
if (thread.sources.isBlackBoxed(url)) {
|
||||
return undefined;
|
||||
@ -818,10 +819,11 @@ ThreadActor.prototype = {
|
||||
let onStep = function TA_onStep() {
|
||||
// onStep is called with 'this' set to the current frame.
|
||||
|
||||
let { url } = thread.synchronize(thread.sources.getOriginalLocation(
|
||||
this.script.url,
|
||||
this.script.getOffsetLine(this.offset),
|
||||
getOffsetColumn(this.offset, this.script)));
|
||||
let { url } = thread.synchronize(thread.sources.getOriginalLocation({
|
||||
url: this.script.url,
|
||||
line: this.script.getOffsetLine(this.offset),
|
||||
column: getOffsetColumn(this.offset, this.script)
|
||||
}));
|
||||
|
||||
if (thread.sources.isBlackBoxed(url)) {
|
||||
return undefined;
|
||||
@ -1029,7 +1031,7 @@ ThreadActor.prototype = {
|
||||
if (this.state !== "paused") {
|
||||
return { error: "wrongState",
|
||||
message: "Debuggee must be paused to evaluate code." };
|
||||
};
|
||||
}
|
||||
|
||||
let frame = this._requestFrame(aRequest.frame);
|
||||
if (!frame) {
|
||||
@ -1040,7 +1042,7 @@ ThreadActor.prototype = {
|
||||
if (!frame.environment) {
|
||||
return { error: "notDebuggee",
|
||||
message: "cannot access the environment of this frame." };
|
||||
};
|
||||
}
|
||||
|
||||
// We'll clobber the youngest frame if the eval causes a pause, so
|
||||
// save our frame now to be restored after eval returns.
|
||||
@ -1091,8 +1093,7 @@ ThreadActor.prototype = {
|
||||
form.depth = i;
|
||||
frames.push(form);
|
||||
|
||||
let { url, line, column } = form.where;
|
||||
let promise = this.sources.getOriginalLocation(url, line, column)
|
||||
let promise = this.sources.getOriginalLocation(form.where)
|
||||
.then((aOrigLocation) => {
|
||||
form.where = aOrigLocation;
|
||||
let source = this.sources.source(form.where.url);
|
||||
@ -1142,9 +1143,7 @@ ThreadActor.prototype = {
|
||||
line: originalLine,
|
||||
column: originalColumn } = aRequest.location;
|
||||
|
||||
let locationPromise = this.sources.getGeneratedLocation(originalSource,
|
||||
originalLine,
|
||||
originalColumn);
|
||||
let locationPromise = this.sources.getGeneratedLocation(aRequest.location);
|
||||
return locationPromise.then(({url, line, column}) => {
|
||||
if (line == null ||
|
||||
line < 0 ||
|
||||
@ -1160,16 +1159,17 @@ ThreadActor.prototype = {
|
||||
// If the original location of our generated location is different from
|
||||
// the original location we attempted to set the breakpoint on, we will
|
||||
// need to know so that we can set actualLocation on the response.
|
||||
let originalLocation = this.sources.getOriginalLocation(url, line, column);
|
||||
let originalLocation = this.sources.getOriginalLocation({
|
||||
url: url,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
|
||||
return all([response, originalLocation])
|
||||
.then(([aResponse, {url, line}]) => {
|
||||
if (aResponse.actualLocation) {
|
||||
let actualOrigLocation = this.sources.getOriginalLocation(
|
||||
aResponse.actualLocation.url,
|
||||
aResponse.actualLocation.line,
|
||||
aResponse.actualLocation.column);
|
||||
return actualOrigLocation.then(function ({ url, line, column }) {
|
||||
let actualOrigLocation = this.sources.getOriginalLocation(aResponse.actualLocation);
|
||||
return actualOrigLocation.then(({ url, line, column }) => {
|
||||
if (url !== originalSource
|
||||
|| line !== originalLine
|
||||
|| column !== originalColumn) {
|
||||
@ -1505,7 +1505,7 @@ ThreadActor.prototype = {
|
||||
return {
|
||||
error: "notImplemented",
|
||||
message: "eventListeners request is only supported in content debugging"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
@ -1940,10 +1940,11 @@ ThreadActor.prototype = {
|
||||
onDebuggerStatement: function TA_onDebuggerStatement(aFrame) {
|
||||
// Don't pause if we are currently stepping (in or over) or the frame is
|
||||
// black-boxed.
|
||||
let { url } = this.synchronize(this.sources.getOriginalLocation(
|
||||
aFrame.script.url,
|
||||
aFrame.script.getOffsetLine(aFrame.offset),
|
||||
getOffsetColumn(aFrame.offset, aFrame.script)));
|
||||
let { url } = this.synchronize(this.sources.getOriginalLocation({
|
||||
url: aFrame.script.url,
|
||||
line: aFrame.script.getOffsetLine(aFrame.offset),
|
||||
column: getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
}));
|
||||
|
||||
return this.sources.isBlackBoxed(url) || aFrame.onStep
|
||||
? undefined
|
||||
@ -1960,10 +1961,11 @@ ThreadActor.prototype = {
|
||||
* The exception that was thrown.
|
||||
*/
|
||||
onExceptionUnwind: function TA_onExceptionUnwind(aFrame, aValue) {
|
||||
let { url } = this.synchronize(this.sources.getOriginalLocation(
|
||||
aFrame.script.url,
|
||||
aFrame.script.getOffsetLine(aFrame.offset),
|
||||
getOffsetColumn(aFrame.offset, aFrame.script)));
|
||||
let { url } = this.synchronize(this.sources.getOriginalLocation({
|
||||
url: aFrame.script.url,
|
||||
line: aFrame.script.getOffsetLine(aFrame.offset),
|
||||
column: getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
}));
|
||||
|
||||
if (this.sources.isBlackBoxed(url)) {
|
||||
return undefined;
|
||||
@ -2248,21 +2250,21 @@ SourceActor.prototype = {
|
||||
// source because we can't guarantee that the cache has the most up to date
|
||||
// content for this source like we can if it isn't source mapped.
|
||||
return fetch(this._url, { loadFromCache: !this._sourceMap })
|
||||
.then((aSource) => {
|
||||
return this.threadActor.createValueGrip(
|
||||
aSource, this.threadActor.threadLifetimePool);
|
||||
})
|
||||
.then((aSourceGrip) => {
|
||||
.then(({ content, contentType }) => {
|
||||
return {
|
||||
from: this.actorID,
|
||||
source: aSourceGrip
|
||||
source: this.threadActor.createValueGrip(
|
||||
content, this.threadActor.threadLifetimePool),
|
||||
contentType: contentType
|
||||
};
|
||||
}, (aError) => {
|
||||
})
|
||||
.then(null, (aError) => {
|
||||
reportError(aError, "Got an exception during SA_onSource: ");
|
||||
return {
|
||||
"from": this.actorID,
|
||||
"error": "loadSourceError",
|
||||
"message": "Could not load the source for " + this._url + "."
|
||||
"message": "Could not load the source for " + this._url + ".\n"
|
||||
+ safeErrorString(aError)
|
||||
};
|
||||
});
|
||||
},
|
||||
@ -3010,10 +3012,11 @@ BreakpointActor.prototype = {
|
||||
// Don't pause if we are currently stepping (in or over) or the frame is
|
||||
// black-boxed.
|
||||
let { url } = this.threadActor.synchronize(
|
||||
this.threadActor.sources.getOriginalLocation(
|
||||
this.location.url,
|
||||
this.location.line,
|
||||
this.location.column));
|
||||
this.threadActor.sources.getOriginalLocation({
|
||||
url: this.location.url,
|
||||
line: this.location.line,
|
||||
column: this.location.column
|
||||
}));
|
||||
|
||||
if (this.threadActor.sources.isBlackBoxed(url) || aFrame.onStep) {
|
||||
return undefined;
|
||||
@ -3483,8 +3486,8 @@ ThreadSources.prototype = {
|
||||
return this._sourceMaps[aAbsSourceMapURL];
|
||||
}
|
||||
|
||||
let promise = fetch(aAbsSourceMapURL).then(rawSourceMap => {
|
||||
let map = new SourceMapConsumer(rawSourceMap);
|
||||
let promise = fetch(aAbsSourceMapURL).then(({ content }) => {
|
||||
let map = new SourceMapConsumer(content);
|
||||
this._setSourceMapRoot(map, aAbsSourceMapURL, aScriptURL);
|
||||
return map;
|
||||
});
|
||||
@ -3515,28 +3518,27 @@ ThreadSources.prototype = {
|
||||
* Returns a promise of the location in the original source if the source is
|
||||
* source mapped, otherwise a promise of the same location.
|
||||
*/
|
||||
getOriginalLocation:
|
||||
function TS_getOriginalLocation(aSourceUrl, aLine, aColumn) {
|
||||
if (aSourceUrl in this._sourceMapsByGeneratedSource) {
|
||||
return this._sourceMapsByGeneratedSource[aSourceUrl]
|
||||
.then(function (aSourceMap) {
|
||||
let { source, line, column } = aSourceMap.originalPositionFor({
|
||||
line: aLine,
|
||||
column: aColumn
|
||||
});
|
||||
return {
|
||||
url: source,
|
||||
getOriginalLocation: function TS_getOriginalLocation({ url, line, column }) {
|
||||
if (url in this._sourceMapsByGeneratedSource) {
|
||||
return this._sourceMapsByGeneratedSource[url]
|
||||
.then((aSourceMap) => {
|
||||
let { source: aSourceURL, line: aLine, column: aColumn } = aSourceMap.originalPositionFor({
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
return {
|
||||
url: aSourceURL,
|
||||
line: aLine,
|
||||
column: aColumn
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// No source map
|
||||
return resolve({
|
||||
url: aSourceUrl,
|
||||
line: aLine,
|
||||
column: aColumn
|
||||
url: url,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
},
|
||||
|
||||
@ -3549,29 +3551,28 @@ ThreadSources.prototype = {
|
||||
* the tables this function uses; thus, it won't know that S's original
|
||||
* source URLs map to S until P is resolved.
|
||||
*/
|
||||
getGeneratedLocation:
|
||||
function TS_getGeneratedLocation(aSourceUrl, aLine, aColumn) {
|
||||
if (aSourceUrl in this._sourceMapsByOriginalSource) {
|
||||
return this._sourceMapsByOriginalSource[aSourceUrl]
|
||||
getGeneratedLocation: function TS_getGeneratedLocation({ url, line, column }) {
|
||||
if (url in this._sourceMapsByOriginalSource) {
|
||||
return this._sourceMapsByOriginalSource[url]
|
||||
.then((aSourceMap) => {
|
||||
let { line, column } = aSourceMap.generatedPositionFor({
|
||||
source: aSourceUrl,
|
||||
line: aLine,
|
||||
column: aColumn == null ? Infinity : aColumn
|
||||
let { line: aLine, column: aColumn } = aSourceMap.generatedPositionFor({
|
||||
source: url,
|
||||
line: line,
|
||||
column: column == null ? Infinity : column
|
||||
});
|
||||
return {
|
||||
url: this._generatedUrlsByOriginalUrl[aSourceUrl],
|
||||
line: line,
|
||||
column: column
|
||||
url: this._generatedUrlsByOriginalUrl[url],
|
||||
line: aLine,
|
||||
column: aColumn
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// No source map
|
||||
return resolve({
|
||||
url: aSourceUrl,
|
||||
line: aLine,
|
||||
column: aColumn
|
||||
url: url,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
},
|
||||
|
||||
@ -3698,6 +3699,7 @@ function fetch(aURL, aOptions={ loadFromCache: true }) {
|
||||
let scheme;
|
||||
let url = aURL.split(" -> ").pop();
|
||||
let charset;
|
||||
let contentType;
|
||||
|
||||
try {
|
||||
scheme = Services.io.extractScheme(url);
|
||||
@ -3714,13 +3716,14 @@ function fetch(aURL, aOptions={ loadFromCache: true }) {
|
||||
case "chrome":
|
||||
case "resource":
|
||||
try {
|
||||
NetUtil.asyncFetch(url, function onFetch(aStream, aStatus) {
|
||||
NetUtil.asyncFetch(url, function onFetch(aStream, aStatus, aRequest) {
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
deferred.reject(new Error("Request failed: " + url));
|
||||
return;
|
||||
}
|
||||
|
||||
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
|
||||
contentType = aRequest.contentType;
|
||||
deferred.resolve(source);
|
||||
aStream.close();
|
||||
});
|
||||
@ -3756,6 +3759,7 @@ function fetch(aURL, aOptions={ loadFromCache: true }) {
|
||||
}
|
||||
|
||||
charset = channel.contentCharset;
|
||||
contentType = channel.contentType;
|
||||
deferred.resolve(chunks.join(""));
|
||||
}
|
||||
};
|
||||
@ -3767,8 +3771,11 @@ function fetch(aURL, aOptions={ loadFromCache: true }) {
|
||||
break;
|
||||
}
|
||||
|
||||
return deferred.promise.then(function (source) {
|
||||
return convertToUnicode(source, charset);
|
||||
return deferred.promise.then(source => {
|
||||
return {
|
||||
content: convertToUnicode(source, charset),
|
||||
contentType: contentType
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -22,17 +22,12 @@ function run_test()
|
||||
gClient.connect(function() {
|
||||
attachTestTabAndResume(gClient, "test-grips", function(aResponse, aTabClient, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
gThreadClient.addListener("unsolicitedPause", unsolicitedPauseListener);
|
||||
test_source();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function unsolicitedPauseListener(aEvent, aPacket, aContinue) {
|
||||
gContinue = aContinue;
|
||||
}
|
||||
|
||||
function test_source()
|
||||
{
|
||||
DebuggerServer.LONG_STRING_LENGTH = 200;
|
||||
@ -43,7 +38,6 @@ function test_source()
|
||||
do_check_true(!!aResponse.sources);
|
||||
gClient.compat.supportsFeature("sources").then(function (supported) {
|
||||
do_check_true(supported);
|
||||
|
||||
});
|
||||
|
||||
let source = aResponse.sources.filter(function (s) {
|
||||
@ -57,6 +51,7 @@ function test_source()
|
||||
do_check_true(!!aResponse);
|
||||
do_check_true(!aResponse.error);
|
||||
do_check_true(!!aResponse.source);
|
||||
do_check_true(aResponse.contentType.contains("javascript"));
|
||||
|
||||
do_check_eq(readFile("test_source-01.js"),
|
||||
aResponse.source);
|
||||
|
@ -2543,6 +2543,24 @@ UpdateService.prototype = {
|
||||
* The timer that fired
|
||||
*/
|
||||
notify: function AUS_notify(timer) {
|
||||
// The telemetry below is specific to background notification.
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_ENABLED,
|
||||
"UPDATER_UPDATES_ENABLED");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_METRO_ENABLED,
|
||||
"UPDATER_UPDATES_METRO_ENABLED");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_AUTO,
|
||||
"UPDATER_UPDATES_AUTOMATIC");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGING_ENABLED,
|
||||
"UPDATER_STAGE_ENABLED");
|
||||
|
||||
#ifdef XP_WIN
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ENABLED,
|
||||
"UPDATER_SERVICE_ENABLED");
|
||||
this._sendIntPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ERRORS,
|
||||
"UPDATER_SERVICE_ERRORS");
|
||||
this._sendServiceInstalledTelemetryPing();
|
||||
#endif
|
||||
|
||||
this._checkForBackgroundUpdates(true);
|
||||
},
|
||||
|
||||
@ -2561,24 +2579,10 @@ UpdateService.prototype = {
|
||||
*/
|
||||
_checkForBackgroundUpdates: function AUS__checkForBackgroundUpdates(isNotify) {
|
||||
this._isNotify = isNotify;
|
||||
// This ensures that telemetry is gathered even if update is disabled.
|
||||
// From this point on, the telemetry reported differentiates between a call
|
||||
// to notify and a call to checkForBackgroundUpdates so they are reported
|
||||
// separately.
|
||||
this._sendLastNotifyIntervalPing();
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_ENABLED,
|
||||
"UPDATER_UPDATES_ENABLED");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_METRO_ENABLED,
|
||||
"UPDATER_UPDATES_METRO_ENABLED");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_AUTO,
|
||||
"UPDATER_UPDATES_AUTOMATIC");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGING_ENABLED,
|
||||
"UPDATER_STAGE_ENABLED");
|
||||
|
||||
#ifdef XP_WIN
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ENABLED,
|
||||
"UPDATER_SERVICE_ENABLED");
|
||||
this._sendIntPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ERRORS,
|
||||
"UPDATER_SERVICE_ERRORS");
|
||||
this._sendServiceInstalledTelemetryPing();
|
||||
#endif
|
||||
|
||||
// If a download is in progress or the patch has been staged do nothing.
|
||||
if (this.isDownloading) {
|
||||
|
@ -109,7 +109,7 @@ var gSwitchApp = false;
|
||||
var gDisableReplaceFallback = false;
|
||||
|
||||
// Time to wait for the test helper process before continuing the test
|
||||
const TEST_HELPER_TIMEOUT = 2000;
|
||||
const TEST_HELPER_TIMEOUT = 100;
|
||||
|
||||
// Use a copy of the main application executable for the test to avoid main
|
||||
// executable in use errors.
|
||||
@ -1057,7 +1057,7 @@ function waitForHelperSleep() {
|
||||
return;
|
||||
}
|
||||
output.remove(false);
|
||||
do_timeout(TEST_HELPER_TIMEOUT, doUpdate);
|
||||
doUpdate();
|
||||
}
|
||||
|
||||
function waitForHelperFinished() {
|
||||
@ -1070,7 +1070,7 @@ function waitForHelperFinished() {
|
||||
}
|
||||
// Give the lock file process time to unlock the file before deleting the
|
||||
// input and output files.
|
||||
do_timeout(TEST_HELPER_TIMEOUT, waitForHelperFinishFileUnlock);
|
||||
waitForHelperFinishFileUnlock();
|
||||
}
|
||||
|
||||
function waitForHelperFinishFileUnlock() {
|
||||
@ -1090,13 +1090,13 @@ function waitForHelperFinishFileUnlock() {
|
||||
do_timeout(TEST_HELPER_TIMEOUT, waitForHelperFinishFileUnlock);
|
||||
return;
|
||||
}
|
||||
do_timeout(TEST_HELPER_TIMEOUT, checkUpdate);
|
||||
checkUpdate();
|
||||
}
|
||||
|
||||
function setupHelperFinish() {
|
||||
let input = getApplyDirFile("a/b/input", true);
|
||||
writeFile(input, "finish\n");
|
||||
do_timeout(TEST_HELPER_TIMEOUT, waitForHelperFinished);
|
||||
waitForHelperFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1570,7 +1570,7 @@ function removeCallbackCopy() {
|
||||
}
|
||||
// Use a timeout to give any files that were in use additional
|
||||
// time to close. Same as updater.exe without service tests.
|
||||
do_timeout(TEST_HELPER_TIMEOUT, do_test_finished);
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
// Waits until files that are in use that break tests are no longer in use and
|
||||
|
Loading…
Reference in New Issue
Block a user