1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 12:42:26 +01:00

Add :style and :delstyle commands. Need to write NEWS and :help entries, I suppose

This commit is contained in:
Kris Maglione
2008-10-03 23:14:30 +00:00
parent 268395a0fc
commit 1bb07747c4
5 changed files with 177 additions and 50 deletions

View File

@@ -26,22 +26,121 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
liberator.Buffer = function () //{{{
{
////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
function arrayIter(ary)
{
let length = ary.length;
for (let i = 0; i < length; i++)
yield ary[i];
}
const arrayIter = liberator.util.arrayIter;
var zoomLevels = [ 1, 10, 25, 50, 75, 90, 100,
120, 150, 200, 300, 500, 1000, 2000 ];
function Styles(name, store, serial)
{
const XHTML = "http://www.w3.org/1999/xhtml";
const ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
const sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
.getService(Components.interfaces.nsIStyleSheetService);
let cssUri = function (css) ios.newURI("data:text/css," + encodeURI(css), null, null);
let sheets = [];
this.__iterator__ = function () Iterator(sheets);
this.addSheet = function (filter, css)
{
let errors = checkSyntax(css);
if (errors.length)
return errors.map(function (e) "CSS: " + filter + ": " + e).join("\n");
let chrome = /^chrome:/.test(filter);
if (chrome)
return "Chrome styling not supported"; /* For now. */
if (sheets.some(function (s) s[0] == filter && s[1] == css))
return null;
sheets.push([filter, css]);
let uri = cssUri(wrapCSS(filter, css));
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
return null;
}
this.removeSheet = function (number)
{
if (number >= sheets.length)
return false;
let sheet = sheets.splice(number)[0];
let uri = cssUri(wrapCSS(sheet[0], sheet[1]));
sss.unregisterSheet(uri, sss.USER_SHEET);
return true;
}
function wrapCSS(filter, css)
{
if (filter == "*")
return css;
let selector = /[\/:]/.test(filter) ? "url" : "domain";
filter = filter.replace('"', "%22", "g");
return "@namespace url(" + XHTML + ");\n" +
"@-moz-document " + selector + '("' + filter + '") {\n' + css + "\n}\n";
/* } vim */
}
function checkSyntax(css)
{
let errors = [];
let listener = {
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIConsoleListener]),
observe: function (message)
{
try
{
message = message.QueryInterface(Components.interfaces.nsIScriptError);
if (message.sourceName.indexOf("data:text/css,") == 0)
errors.push(message.errorMessage);
}
catch (e) {}
}
};
var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
consoleService.registerListener(listener);
try
{
var doc = document.implementation.createDocument(XHTML, "doc", null);
doc.documentElement.appendChild(liberator.util.xmlToDom(
<html><head><link type="text/css" rel="stylesheet" href={cssUri(css).spec}/></head></html>, doc));
while (true)
{
try {
// Throws NS_ERROR_DOM_INVALID_ACCESS_ERR if not finished loading
doc.styleSheets[0].cssRules.length;
break;
} catch (e) {
if (e.name != "NS_ERROR_DOM_INVALID_ACCESS_ERR")
throw e;
liberator.sleep(10);
}
}
}
finally
{
consoleService.unregisterListener(listener);
}
return errors;
}
}
let styles = liberator.storage.newObject(styles, Styles, false);
function setZoom(value, fullZoom)
{
if (value < 1 || value > 2000)
@@ -181,10 +280,7 @@ liberator.Buffer = function () //{{{
liberator.options.add(["pageinfo", "pa"], "Desired info on :pa[geinfo]", "charlist", "gfm",
{
completer: function (filter)
{
return [[k, v[1]] for ([k, v] in Iterator(pageInfo))]
},
completer: function (filter) [0, [[k, v[1]] for ([k, v] in Iterator(pageInfo))]]
});
liberator.options.add(["scroll", "scr"],
@@ -198,14 +294,11 @@ liberator.Buffer = function () //{{{
"Show the destination of the link under the cursor in the status bar",
"number", 1,
{
completer: function (filter)
{
return [
completer: function (filter) [0, [
["0", "Don't show link destination"],
["1", "Show the link in the status line"],
["2", "Show the link in the command line"]
];
},
]],
validator: function (value) value >= 0 && value <= 2
});
@@ -567,6 +660,42 @@ liberator.Buffer = function () //{{{
},
{ argCount: "0" });
liberator.commands.add(["sty[le]"],
"Add or list user styles",
function (args, special)
{
let [, filter, css] = args.match(/([^\s]+)\s*(.*)/) || [];
if (!css)
{
let str = liberator.template.tabular(["", "Filter", "CSS"],
([i, style[0], style[1]] for ([i, style] in styles)
if (!filter || style[0] == filter)));
liberator.commandline.echo(str, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
}
else
{
// TODO: Accept here docs.
let err = styles.addSheet(filter, css);
if (err)
liberator.echoerr(err);
}
},
{
completer: function (filter) [0, [
[content.location.host, ""],
[content.location.href, ""]]
.concat([[s[0], ""] for ([i, s] in styles)])
],
});
liberator.commands.add(["dels[tyle]"],
"Remove a user stylesheet",
function (args, special) styles.removeSheet(parseInt(args.arguments[0])),
{
completer: function (filter) [0, [[i, s[0] + ": " + s[1].replace("\n", "\\n")] for ([i, s] in styles)]],
argCount: 1
});
liberator.commands.add(["vie[wsource]"],
"View source code of current document",
function (args, special) { liberator.buffer.viewSource(args, special); });
@@ -1243,8 +1372,6 @@ liberator.Buffer = function () //{{{
frames[next].frameElement.scrollIntoView(false);
// add the frame indicator
// TODO: make this an XBL element rather than messing with the content
// document
var doc = frames[next].document;
var indicator =
<div id="liberator-frame-indicator"
@@ -1859,7 +1986,30 @@ liberator.template = {
</table>;
if (table.tr.length() > 1)
return table;
}
},
tabular: function (headings, iter)
{
/* This might be mind-bogglingly slow. We'll see. */
return this.generic(
<table>
<tr class="hl-Title" align="left">
{
this.map(headings, function (h)
<th>{h}</th>)
}
</tr>
{
this.map(iter, function (row)
<tr>
{
liberator.template.map(row, function (d)
<td>{d}</td>)
}
</tr>)
}
</table>);
},
};
// vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -697,23 +697,9 @@ liberator.Commands = function () //{{{
var cmdlist = getMatchingUserCommands(cmd);
if (cmdlist.length > 0)
{
XML.prettyPrinting = false;
var str = liberator.template.generic(
<table>
<tr class="hl-Title" align="left">
<th>Name</th>
<th>Args</th>
<th>Definition</th>
</tr>
{
liberator.template.map(cmdlist, function (cmd)
<tr>
<td>{cmd.name}</td>
<td>*</td>
<td>{cmd.replacementText || "function () { ... }"}</td>
</tr>)
}
</table>);
var str = liberator.template.tabular(["Name", "Args", "Definition"],
([cmd.name, "*", cmd.replacementText || "function () { ... }"]
for each (cmd in cmdlist)));
liberator.commandline.echo(str, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
}
else

View File

@@ -666,16 +666,7 @@ liberator.Events = function () //{{{
function (args)
{
XML.prettyPrinting = false;
var str = <table>
{
liberator.template.map2(liberator.events.getMacros(args),
function (macro, keys)
<tr>
<td>{macro}</td>
<td>{keys}</td>
</tr>)
}
</table>.toXMLString();
var str = liberator.template.tabular(["Macro", "Keys"], liberator.events.getMacros(args));
liberator.echo(str, liberator.commandline.FORCE_MULTILINE);
},
{

View File

@@ -440,10 +440,10 @@ const liberator = (function () //{{{
<tr class="hl-Title" align="left">
<th colspan="3">Code execution summary</th>
</tr>
<tr><td> Executed:</td><td align="right"><span style="color: green">{count}</span></td><td>times</td></tr>
<tr><td> Average time:</td><td align="right"><span style="color: green">{each.toFixed(2)}</span></td><td>{eachUnits}</td></tr>
<tr><td> Total time:</td><td align="right"><span style="color: red">{total.toFixed(2)}</span></td><td>{totalUnits}</td></tr>
</table>);
<tr><td>  Executed:</td><td align="right"><span style="color: green">{count}</span></td><td>times</td></tr>
<tr><td>  Average time:</td><td align="right"><span style="color: green">{each.toFixed(2)}</span></td><td>{eachUnits}</td></tr>
<tr><td>  Total time:</td><td align="right"><span style="color: red">{total.toFixed(2)}</span></td><td>{totalUnits}</td></tr>
</table>);
liberator.commandline.echo(str, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
}

View File

@@ -504,7 +504,7 @@ liberator.CommandLine = function () //{{{
// TODO: color messages
// : are all messages single line? Some display an aggregation
// of single line messages at least. E.g. :source
let list = messageHistory.messages.join("<br/>");
let list = messageHistory.messages.join("\n");
liberator.commandline.echo(list);
}, { argCount: "0" });