1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-02-15 20:45:46 +01:00

Merge branch 'master' into vimperator-2.1

Conflicts:
	common/content/completion.js
	common/content/liberator.js
	vimperator/NEWS
This commit is contained in:
Doug Kearns
2009-03-29 11:18:10 +11:00
57 changed files with 448 additions and 128 deletions

View File

@@ -47,11 +47,9 @@
</xul:vbox>
</xul:stack>
<xul:stack class="tab-text-stack">
<xul:label xbl:inherits="value=ordinal" class="tab-text-shadow" liberator:highlight="TabNumber"/>
<xul:label xbl:inherits="value=ordinal" class="tab-text" liberator:highlight="TabNumber"/>
</xul:stack>
<xul:stack class="tab-text-stack" flex="1">
<xul:label flex="1" xbl:inherits="value=label,crop,accesskey" crop="right" class="tab-text-shadow"/>
<xul:label flex="1" xbl:inherits="value=label,crop,accesskey" crop="right" class="tab-text"/>
</xul:stack>
</xul:hbox>

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -147,13 +147,13 @@ function Buffer() //{{{
getter: function () window.fullScreen
});
options.add(["nextpattern"],
options.add(["nextpattern"], // \u00BB is » (>> in a single char)
"Patterns to use when guessing the 'next' page in a document sequence",
"stringlist", "\\bnext\\b,^>$,^(>>|»)$,^(>|»),(>|»)$,\\bmore\\b");
"stringlist", "\\bnext\\b,^>$,^(>>|\u00BB)$,^(>|\u00BB),(>|\u00BB)$,\\bmore\\b");
options.add(["previouspattern"],
options.add(["previouspattern"], // \u00AB is « (<< in a single char)
"Patterns to use when guessing the 'previous' page in a document sequence",
"stringlist", "\\bprev|previous\\b,^<$,^(<<|«)$,^(<|«),(<|«)$");
"stringlist", "\\bprev|previous\\b,^<$,^(<<|\u00AB)$,^(<|\u00AB),(<|\u00AB)$");
options.add(["pageinfo", "pa"], "Desired info on :pa[geinfo]", "charlist", "gfm",
{
@@ -1020,6 +1020,20 @@ function Buffer() //{{{
elem.contentWindow.focus();
return;
}
else if (elemTagName == "input" && elem.getAttribute('type').toLowerCase() == "file")
{
commandline.input("Upload file: ", function (path)
{
let file = io.getFile(path);
if (!file.exists())
return liberator.beep();
elem.value = file.path;
}
, {completer: completion.file, default: elem.value});
return;
}
elem.focus();
@@ -1125,6 +1139,20 @@ function Buffer() //{{{
offsetX = Number(coords[0]) + 1;
offsetY = Number(coords[1]) + 1;
}
else if (localName == "input" && elem.getAttribute('type').toLowerCase() == "file")
{
commandline.input("Upload file: ", function (path)
{
let file = io.getFile(path);
if (!file.exists())
return liberator.beep();
elem.value = file.path;
}
, {completer: completion.file, default: elem.value});
return;
}
let ctrlKey = false, shiftKey = false;
switch (where)

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -658,6 +658,11 @@ CompletionContext.prototype = {
this.tabPressed = false;
this.title = ["Completions"];
this.updateAsync = false;
try
{
this.waitingForTab = false;
}
catch (e) {}
this.cancelAll();
@@ -676,6 +681,11 @@ CompletionContext.prototype = {
for each (let context in this.contexts)
{
context.hasItems = false;
try
{
context.incomplete = false;
}
catch (e) {}
}
},
@@ -683,8 +693,9 @@ CompletionContext.prototype = {
* Wait for all subcontexts to complete.
*
* @param {boolean} interruptible When true, the call may be interrupted
* via <C-c>. In this case, "Interrupted" may be thrown.
* via <C-c>, in which case, "Interrupted" may be thrown.
* @param {number} timeout The maximum time, in milliseconds, to wait.
* If 0 or null, wait indefinately.
*/
wait: function wait(interruptable, timeout)
{
@@ -1415,15 +1426,17 @@ function Completion() //{{{
colorScheme: function colorScheme(context)
{
// TODO: use path for the description?
let colors = [];
io.getRuntimeDirectories("colors").forEach(function (dir) {
context.fork(dir.path, 0, null, function (context) {
context.filter = dir.path + IO.PATH_SEP + context.filter;
completion.file(context);
context.title = ["Color Scheme"];
context.quote = ["", function (text) text.replace(/\.vimp$/, ""), ""];
io.readDirectory(dir).forEach(function (file) {
if (/\.vimp$/.test(file.leafName) && !colors.some(function (c) c.leafName == file.leafName))
colors.push(file);
});
});
context.title = ["Color Scheme", "Runtime Path"];
context.completions = [[c.leafName.replace(/\.vimp$/, ""), c.parent.path] for ([,c] in Iterator(colors))]
},
command: function command(context)

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -623,12 +623,23 @@ function Editor() //{{{
pasteClipboard: function ()
{
if (liberator.has("Win32"))
{
this.executeCommand("cmd_paste");
return;
}
// FIXME: #93 (<s-insert> in the bottom of a long textarea bounces up)
let elem = window.document.commandDispatcher.focusedElement;
if (elem.setSelectionRange && util.readFromClipboard())
// readFromClipboard would return 'undefined' if not checked
// dunno about .setSelectionRange
{
// This is a hacky fix - but it works.
let curTop = elem.scrollTop;
let curLeft = elem.scrollLeft;
let rangeStart = elem.selectionStart; // caret position
let rangeEnd = elem.selectionEnd;
let tempStr1 = elem.value.substring(0, rangeStart);
@@ -637,6 +648,9 @@ function Editor() //{{{
elem.value = tempStr1 + tempStr2 + tempStr3;
elem.selectionStart = rangeStart + tempStr2.length;
elem.selectionEnd = elem.selectionStart;
elem.scrollTop = curTop;
elem.scrollLeft = curLeft;
}
},

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -898,6 +898,7 @@ function Events() //{{{
let wasFeeding = this.feedingKeys;
this.feedingKeys = true;
this.duringFeed = this.duringFeed || "";
let wasSilent = commandline.silent;
if (silent)
commandline.silent = silent;
@@ -993,6 +994,15 @@ function Events() //{{{
this.feedingKeys = wasFeeding;
if (silent)
commandline.silent = wasSilent;
if (this.duringFeed != "")
{
//Create a scalar constant for closure.
let duringFeed = this.duringFeed;
this.duringFeed = "";
setTimeout(function () events.feedkeys(duringFeed, false, false, true), 0);
}
}
return i == keys.length;
},
@@ -1370,13 +1380,23 @@ function Events() //{{{
// we can differentiate between a recorded <C-c>
// interrupting whatever it's started and a real <C-c>
// interrupting our playback.
if (events.feedingKeys)
if (events.feedingKeys && !event.isMacro)
{
if (key == "<C-c>" && !event.isMacro)
if (key == "<C-c>")
{
events.feedingKeys = false;
if (lastMacro)
if (modes.isReplaying)
{
modes.isReplaying = false;
setTimeout(function () { liberator.echomsg("Canceled playback of macro '" + lastMacro + "'"); }, 100);
}
event.preventDefault();
event.stopPropagation();
return true;
}
else
{
events.duringFeed += key;
event.preventDefault();
event.stopPropagation();
return true;
@@ -1664,13 +1684,16 @@ function Events() //{{{
}
},
// for notifying the user about secure web pages
onSecurityChange: function (webProgress, aRequest, aState)
onSecurityChange: function (webProgress, request, state)
{
if (aState & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
// TODO: do something useful with STATE_SECURE_MED and STATE_SECURE_LOW
if (state & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
statusline.setClass("insecure");
else if (aState & Ci.nsIWebProgressListener.STATE_IS_BROKEN)
else if (state & Ci.nsIWebProgressListener.STATE_IS_BROKEN)
statusline.setClass("broken");
else if (aState & Ci.nsIWebProgressListener.STATE_IS_SECURE)
else if (state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
statusline.setClass("extended");
else if (state & Ci.nsIWebProgressListener.STATE_SECURE_HIGH)
statusline.setClass("secure");
},
onStatusChange: function (webProgress, request, status, message)
@@ -1697,7 +1720,7 @@ function Events() //{{{
{
setTimeout(statusline.updateUrl, 100);
},
setOverLink : function (link, b)
setOverLink: function (link, b)
{
let ssli = options["showstatuslinks"];
if (link && ssli)
@@ -1761,11 +1784,12 @@ function Events() //{{{
window.XULBrowserWindow = self.progressListener;
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.XULBrowserWindow = window.XULBrowserWindow;
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.XULBrowserWindow = self.progressListener;
try
{
getBrowser().addProgressListener(self.progressListener, Ci.nsIWebProgress.NOTIFY_ALL);

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -165,8 +165,76 @@ function Hints() //{{{
text = elem.textContent.toLowerCase();
span = baseNodeAbsolute.cloneNode(true);
span.style.left = Math.max((rect.left + scrollX), scrollX) + "px";
span.style.top = Math.max((rect.top + scrollY), scrollY) + "px";
let leftpos = Math.max((rect.left + scrollX), scrollX);
let toppos = Math.max((rect.top + scrollY), scrollY);
if (tagname == "area")
{
// TODO: Maybe put the following into a seperate function
try
{
// Need to add the offset to the area element.
// Always try to find the top-left point, as per vimperator default.
let shape = elem.getAttribute("shape").toLowerCase();
let coordstr = elem.getAttribute("coords");
// Technically it should be only commas, but hey
coordstr = coordstr.replace(/\s+[;,]\s+/g, ",").replace(/\s+/g, ",");
let coords = coordstr.split(",").map(Number);
if ((shape == "rect" || shape == "rectangle") && coords.length == 4)
{
leftpos += coords[0];
toppos += coords[1];
}
else if (shape == "circle" && coords.length == 3)
{
leftpos += coords[0] - coords[2] / Math.sqrt(2);
toppos += coords[1] - coords[2] / Math.sqrt(2);
}
else if ((shape == "poly" || shape == "polygon") && coords.length % 2 == 0)
{
let leftbound = Infinity;
let topbound = Infinity;
// First find the top-left corner of the bounding rectangle (offset from image topleft can be noticably suboptimal)
for (let i = 0; i < coords.length; i += 2)
{
leftbound = Math.min(coords[i], leftbound);
topbound = Math.min(coords[i+1], topbound);
}
let curtop = null;
let curleft = null;
let curdist = Infinity;
// Then find the closest vertex. (we could generalise to nearest point on an edge, but I doubt there is a need)
for (let i = 0; i < coords.length; i += 2)
{
let leftoffset = coords[i] - leftbound;
let topoffset = coords[i+1] - topbound;
let dist = Math.sqrt(leftoffset * leftoffset + topoffset * topoffset);
if (dist < curdist)
{
curdist = dist;
curleft = coords[i];
curtop = coords[i+1];
}
}
// If we found a satisfactory offset, let's use it.
if (curdist < Infinity)
{
leftpos += curleft;
toppos += curtop;
}
}
}
catch (e) {} //badly formed document, or shape == "default" in which case we don't move the hint
}
span.style.left = leftpos + "px";
span.style.top = toppos + "px";
fragment.appendChild(span);
pageHints.push([elem, text, span, null, elem.style.backgroundColor, elem.style.color]);

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Code based on venkman
Alternatively, the contents of this file may be used under the terms of
@@ -547,6 +547,7 @@ function IO() //{{{
* @param {boolean} always When true, return a path whether
* the file exists or not.
* @default $HOME.
* @returns {nsIFile} The RC file or null if none is found.
*/
getRCFile: function (dir, always)
{

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -1225,7 +1225,12 @@ const liberator = (function () //{{{
config.features.push(getPlatformFeature());
config.defaults = config.defaults || {};
config.guioptions = config.guioptions || {};
config.browserModes = config.browserModes || [modes.NORMAL];
// -> we can't use this, since config.browserModes might already be defined as a getter-only
// TODO: also change the other config.* defaults?
// config.browserModes = config.browserModes || [modes.NORMAL];
if (!config.browserModes)
config.browserModes = [modes.NORMAL];
config.mailModes = config.mailModes || [modes.NORMAL];
// TODO: suitable defaults?
//config.mainWidget
@@ -1292,13 +1297,12 @@ const liberator = (function () //{{{
let extensionName = config.name.toUpperCase();
let init = services.get("environment").get(extensionName + "_INIT");
let rcFile = io.getRCFile("~");
if (init)
liberator.execute(init);
else
{
let rcFile = io.getRCFile("~");
if (rcFile)
{
io.source(rcFile.path, true);
@@ -1311,7 +1315,7 @@ const liberator = (function () //{{{
if (options["exrc"])
{
let localRCFile = io.getRCFile(io.getCurrentDirectory().path);
if (localRCFile)
if (localRCFile && !localRCFile.equals(rcFile))
io.source(localRCFile.path, true);
}

View File

@@ -13,7 +13,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -71,9 +71,10 @@ Highlights.prototype.CSS = <![CDATA[
LineNr color: orange; background: white;
Question color: green; background: white; font-weight: bold;
StatusLine color: white; background: black;
StatusLineBroken color: black; background: #FF6060 /* light-red */
StatusLineSecure color: black; background: #B0FF00 /* light-green */
StatusLine color: white; background: black;
StatusLineBroken color: black; background: #FFa0a0 /* light-red */
StatusLineSecure color: black; background: #a0a0FF /* light-blue */
StatusLineExtended color: black; background: #a0FFa0 /* light-green */
TabClose
TabIcon

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -623,6 +623,7 @@ function Tabs() //{{{
completer: function (context)
{
context.anchored = false;
context.compare = CompletionContext.Sort.unsorted;
context.keys = { text: function (item) item.state.entries[0].url, description: "title" };
context.completions = tabs.closedTabs;
},

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -1222,6 +1222,8 @@ function CommandLine() //{{{
* for the user's input.
* @... {string} promptHighlight - The HighlightGroup used for the
* prompt. @default "Question"
* @... {string} default - The initial value that will be returned
* if the user presses <CR> straightaway. @default ""
*/
input: function _input(prompt, callback, extra)
{
@@ -1303,20 +1305,17 @@ function CommandLine() //{{{
}
else if (event.type == "input")
{
//liberator.dump("input: " + command);
this.resetCompletions();
liberator.triggerCallback("change", currentExtendedMode, command);
}
else if (event.type == "keypress")
{
let key = events.toString(event);
if (completions)
completions.previewClear();
if (!currentExtendedMode)
return true;
let key = events.toString(event);
//liberator.log("command line handling key: " + key + "\n");
// user pressed ENTER to carry out a command
// user pressing ESCAPE is handled in the global onEscape
// FIXME: <Esc> should trigger "cancel" event
@@ -2040,16 +2039,18 @@ function StatusLine() //{{{
/**
* Update the status bar to indicate how secure the website is:
* extended - Secure connection with Extended Validation(EV) certificate.
* secure - Secure connection with valid certificate.
* broken - Secure connection with invalid certificate, or
* mixed content.
* insecure - Insecure connection.
*
* @param {'secure'|'broken'|'insecure'} type
* @param {'extended'|'secure'|'broken'|'insecure'} type
*/
setClass: function setClass(type)
{
const highlightGroup = {
extended: "StatusLineExtended",
secure: "StatusLineSecure",
broken: "StatusLineBroken",
insecure: "StatusLine"

View File

@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -249,6 +249,40 @@ const util = { //{{{
return delimiter + str.replace(/([\\'"])/g, "\\$1").replace("\n", "\\n", "g").replace("\t", "\\t", "g") + delimiter;
},
/**
* Split a string on literal occurances of a marker.
*
* Specifically this ignores occurences preceded by a backslash, or
* contained within 'single' or "double" quotes.
*
* It assumes backslash escaping on strings, and will thus not count quotes
* that are preceded by a backslash or within other quotes as starting or
* ending quoted sections of the string.
*
* @param {string} str
* @param {RegExp} marker
*/
splitLiteral: function splitLiteral(str, marker)
{
let results = [];
let resep = RegExp(/^(([^\\'"]|\\.|'([^\\']|\\.)*'|"([^\\"]|\\.)*")*?)/.source + marker.source);
let cont = true;
while (cont)
{
cont = false;
str = str.replace(resep, function (match, before)
{
results.push(before);
cont = true;
return "";
});
}
results.push(str);
return results;
},
/**
* Converts <b>bytes</b> to a pretty printed data size string.
*
@@ -618,7 +652,7 @@ const util = { //{{{
*/
stringToURLArray: function stringToURLArray(str)
{
let urls = str.split(RegExp("\\s*" + options["urlseparator"] + "\\s*"));
let urls = util.splitLiteral(str, RegExp("\\s*" + options["urlseparator"] + "\\s*"));
return urls.map(function (url) {
try
@@ -641,7 +675,7 @@ const util = { //{{{
// Ok, not a valid proto. If it looks like URL-ish (foo.com/bar),
// let Gecko figure it out.
if (/[.]/.test(url) && !/\s/.test(url) || /^[\w-.]+:\d+(?:\/|$)/.test(url))
if (/[.\/]/.test(url) && !/\s/.test(url) || /^[\w-.]+:\d+(?:\/|$)/.test(url))
return url;
// TODO: it would be clearer if the appropriate call to