diff --git a/content/bindings.xml b/content/bindings.xml index 9c87bdc3..6d9ecb2b 100644 --- a/content/bindings.xml +++ b/content/bindings.xml @@ -6,13 +6,14 @@ ]> -
+ diff --git a/content/bookmarks.js b/content/bookmarks.js index 4fbfcb4d..288809b9 100644 --- a/content/bookmarks.js +++ b/content/bookmarks.js @@ -50,8 +50,8 @@ function Bookmarks() //{{{ const Keyword = new Struct("keyword", "title", "icon", "url"); Bookmark.defaultValue("icon", function () getFavicon(this.url)); Bookmark.prototype.__defineGetter__("extra", function () [ - ['keyword', this.keyword, "hl-Keyword"], - ['tags', this.tags.join(', '), "hl-Tag"] + ['keyword', this.keyword, "Keyword"], + ['tags', this.tags.join(', '), "Tag"] ].filter(function (item) item[1])); const storage = modules.storage; @@ -742,6 +742,8 @@ function History() //{{{ let query = historyService.getNewQuery(); let options = historyService.getNewQueryOptions(); + if (typeof filter == "string") + filter = { searchTerms: filter }; for (let [k, v] in Iterator(filter)) query[k] = v; options.sortingMode = options.SORT_BY_DATE_DESCENDING; diff --git a/content/buffer.js b/content/buffer.js index 4956bcd9..c44bbc21 100644 --- a/content/buffer.js +++ b/content/buffer.js @@ -871,6 +871,8 @@ function Buffer() //{{{ { case "xhtml": return "http://www.w3.org/1999/xhtml"; + case "liberator": + return NS.uri; default: return null; } @@ -1243,12 +1245,15 @@ function Buffer() //{{{ frames[next].frameElement.scrollIntoView(false); // add the frame indicator - var doc = frames[next].document; - var indicator = util.xmlToDom(
, doc); + let doc = frames[next].document; + var indicator = util.xmlToDom(
, doc); doc.body.appendChild(indicator); - // remove the frame indicator setTimeout(function () { doc.body.removeChild(indicator); }, 500); + + // Doesn't unattach + //doc.body.setAttributeNS(NS.uri, "activeframe", "true"); + //setTimeout(function () { doc.body.removeAttributeNS(NS.uri, "activeframe"); }, 500); }, // similar to pageInfo diff --git a/content/completion.js b/content/completion.js index 9efd85bd..134236ab 100644 --- a/content/completion.js +++ b/content/completion.js @@ -150,6 +150,9 @@ CompletionContext.prototype = { get caret() (this.editor ? this.editor.selection.getRangeAt(0).startOffset : this.value.length) - this.offset, + get compare() this._compare || function () 0, + set compare(val) this._compare = val, + get completions() this._completions || [], set completions(items) { @@ -1066,8 +1069,8 @@ function Completion() //{{{ liberator.threadYield(true, true); let list = template.generic( -
- { template.completionRow(context.title, "hl-CompTitle") } +
+ { template.completionRow(context.title, "CompTitle") } { template.map(context.items, function (item) context.createRow(item)) }
); commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE); @@ -1099,7 +1102,7 @@ function Completion() //{{{ context.keys = { text: "text", description: "url", icon: "icon" }; let process = context.process[0]; context.process = [function ({ text: text, item: item }) <> - {item.indicator} + {item.indicator} { process.call(this, { item: item, text: text }) } ]; @@ -1275,9 +1278,10 @@ function Completion() //{{{ { context.format = history.format; context.title = ["History"] + context.compare = null; context.background = true; context.regenerate = true; - context.generate = function () history.get({ searchTerms: context.filter }); + context.generate = function () history.get(context.filter); }, get javascriptCompleter() javascript, @@ -1293,6 +1297,7 @@ function Completion() //{{{ context.incomplete = true; context.hasItems = context.completions.length > 0; // XXX context.filterFunc = null; + context.compare = null; let timer = new util.Timer(50, 100, function (result) { context.completions = [ [result.getValueAt(i), result.getCommentAt(i), result.getImageAt(i)] @@ -1331,9 +1336,9 @@ function Completion() //{{{ let engines = bookmarks.getSearchEngines(); context.title = ["Search Keywords"]; - context.keys = { text: 0, description: 1, icon: 2 }; - context.completions = keywords.concat(engines); context.anchored = true; + context.completions = keywords.concat(engines); + context.keys = { text: 0, description: 1, icon: 2 }; if (!space || noSuggest) return; @@ -1346,8 +1351,9 @@ function Completion() //{{{ context.fork("keyword/" + keyword, keyword.length + space.length, null, function (context) { context.format = history.format; context.title = [keyword + " Quick Search"]; - context.background = true; context.anchored = true; + context.background = true; + context.compare = null; context.generate = function () { let [begin, end] = item.url.split("%s"); @@ -1384,8 +1390,9 @@ function Completion() //{{{ let ctxt = context.fork(name, 0); ctxt.title = [engine.description + " Suggestions"]; - ctxt.regenerate = true; ctxt.background = true; + ctxt.compare = null; + ctxt.regenerate = true; ctxt.generate = function () bookmarks.getSuggestions(name, this.filter); }); }, diff --git a/content/events.js b/content/events.js index 6f20c60d..de4116d7 100644 --- a/content/events.js +++ b/content/events.js @@ -218,12 +218,12 @@ function AutoCommands() //{{{ var list = template.generic( - + { template.map(cmds, function ([event, items]) - + + diff --git a/content/find.js b/content/find.js index 5b3033cd..983f3b70 100644 --- a/content/find.js +++ b/content/find.js @@ -157,10 +157,10 @@ function Search() //{{{ if (!aWord) { - let elems = doc.getElementsByClassName("liberator-search"); - for (let i = elems.length; --i >= 0;) + let elems = highlightObj.getSpans(doc); + for (let i = elems.snapshotLength; --i >= 0;) { - let elem = elems[i]; + let elem = elems.snapshotItem(i); let docfrag = doc.createDocumentFragment(); let next = elem.nextSibling; let parent = elem.parentNode; @@ -176,7 +176,7 @@ function Search() //{{{ return; } - var baseNode = + var baseNode = baseNode = util.xmlToDom(baseNode, window.content.document); var body = doc.body; @@ -221,7 +221,9 @@ function Search() //{{{ aNode.appendChild(docfrag); parent.insertBefore(aNode, before); return aNode; - } + }, + + getSpans: function (doc) buffer.evaluateXPath("//*[liberator:highlight='Search']", doc) }; /////////////////////////////////////////////////////////////////////////////}}} @@ -442,7 +444,7 @@ function Search() //{{{ return; // already highlighted? - if (window.content.document.getElementsByClassName("liberator-search").length > 0) + if (highlightObj.getSpans(content.document).snapshotLength > 0) return; if (!text) diff --git a/content/hints.js b/content/hints.js index 2935ec0d..113d0a34 100644 --- a/content/hints.js +++ b/content/hints.js @@ -32,7 +32,7 @@ function Hints() //{{{ ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ - const ELEM = 0, TEXT = 1, SPAN = 2, IMGSPAN = 3, BGCOLOR = 4, COLOR = 5; + const ELEM = 0, TEXT = 1, SPAN = 2, IMGSPAN = 3; var myModes = config.browserModes; @@ -112,13 +112,12 @@ function Hints() //{{{ var scrollX = doc.defaultView.scrollX; var scrollY = doc.defaultView.scrollY; - var baseNodeAbsolute = util.xmlToDom( - , doc); + var baseNodeAbsolute = util.xmlToDom(, doc); var elem, tagname, text, span, rect; var res = buffer.evaluateXPath(hintMode.tags(), doc, null, true); - var fragment = doc.createDocumentFragment(); + var fragment = util.xmlToDom(
, doc); var start = pageHints.length; for (let elem in res) { @@ -171,19 +170,24 @@ function Hints() //{{{ { var oldElem = validHints[oldID - 1]; if (oldElem) - oldElem.style.backgroundColor = options["linkbgcolor"]; + setClass(newElem, false); var newElem = validHints[newID - 1]; if (newElem) - newElem.style.backgroundColor = options["activelinkbgcolor"]; + setClass(newElem, true); + } + + function setClass(elem, active) + { + let prefix = (elem.getAttributeNS(NS.uri, "class") || "") + " "; + if (active) + elem.setAttributeNS(NS.uri, "highlight", prefix + "HintActive"); + else + elem.setAttributeNS(NS.uri, "highlight", prefix + "HintElem"); } function showHints() { - var linkfgcolor = options["linkfgcolor"]; - var linkbgcolor = options["linkbgcolor"]; - var activelinkfgcolor = options["activelinkfgcolor"]; - var activelinkbgcolor = options["activelinkbgcolor"]; let elem, tagname, text, rect, span, imgspan; let hintnum = 1; @@ -208,9 +212,7 @@ function Hints() //{{{ if (imgspan) imgspan.style.display = "none"; - // reset background color - elem.style.backgroundColor = hint[BGCOLOR]; - elem.style.color = hint[COLOR]; + elem.removeAttributeNS(NS.uri, "highlight"); continue inner; } @@ -222,61 +224,58 @@ function Hints() //{{{ if (!rect) continue; - imgspan = doc.createElementNS("http://www.w3.org/1999/xhtml", "span"); - imgspan.style.position = "absolute"; - imgspan.style.opacity = 0.5; - imgspan.style.zIndex = "10000000"; + imgspan = util.xmlToDom(, doc); + imgspan.setAttributeNS(NS.uri, "class", "HintImage"); imgspan.style.left = (rect.left + scrollX) + "px"; imgspan.style.top = (rect.top + scrollY) + "px"; imgspan.style.width = (rect.right - rect.left) + "px"; imgspan.style.height = (rect.bottom - rect.top) + "px"; - imgspan.className = "liberator-hint"; hint[IMGSPAN] = imgspan; - doc.body.appendChild(imgspan); + span.parentNode.appendChild(imgspan); } - imgspan.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor; - imgspan.style.display = "inline"; + setClass(imgspan, activeHint == hintnum) } - if (!imgspan) - elem.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor; - elem.style.color = (activeHint == hintnum) ? activelinkfgcolor : linkfgcolor; - span.textContent = String(hintnum++); - span.style.display = "inline"; + span.setAttribute("number", hintnum++); + if (imgspan) + imgspan.setAttribute("number", hintnum++); + else + setClass(elem, activeHint == hintnum); validHints.push(elem); } } + if (options.usermode) + { + let css = []; + // FIXME: Broken for imgspans. + for (let [,{ doc: doc }] in Iterator(docs)) + { + for (let elem in buffer.evaluateXPath("//*[@liberator:highlight and @number]", doc)) + { + let group = elem.getAttributeNS(NS.uri, "highlight"); + css.push(highlight.selector(group) + "[number='" + elem.getAttribute("number") + "'] { " + elem.style.cssText + " }"); + } + } + styles.addSheet("hint-positions", "*", css.join("\n"), true, true); + } + return true; } function removeHints(timeout) { var firstElem = validHints[0] || null; - var firstElemBgColor = ""; - var firstElemColor = ""; for (let [,{ doc: doc, start: start, end: end }] in Iterator(docs)) { + for (let elem in buffer.evaluateXPath("//*[@liberator:highlight='hints']", doc)) + elem.parentNode.removeChild(elem); for (let i in util.range(start, end + 1)) { let hint = pageHints[i]; - // remove the span for the numeric display part - doc.body.removeChild(hint[SPAN]); - if (hint[IMGSPAN]) // a transparent span for images - doc.body.removeChild(hint[IMGSPAN]); - - if (timeout && firstElem == hint[ELEM]) - { - firstElemBgColor = hint[BGCOLOR]; - firstElemColor = hint[COLOR]; - } - else - { - // restore colors - var elem = hint[ELEM]; - elem.style.backgroundColor = hint[BGCOLOR]; - elem.style.color = hint[COLOR]; } + if (!timeout || hint[ELEM] != firstHint) + hint[ELEM].removeAttributeNS(NS.uri, "highlight"); } // animate the disappearance of the first hint @@ -305,12 +304,10 @@ function Hints() //{{{ // clearTimeout(id); // } // }, 100); - setTimeout(function () { - firstElem.style.backgroundColor = firstElemBgColor; - firstElem.style.color = firstElemColor; - }, timeout); + setTimeout(function () { firstElem.removeAttributeNS(NS.uri, "highlight") }, timeout); } } + styles.removeSheet("hint-positions", null, null, null, true); reset(); } @@ -560,22 +557,6 @@ function Hints() //{{{ "number", 0, { validator: function (value) value >= 0 && value < 3 }); - options.add(["linkfgcolor", "lfc"], - "Foreground color of a link during hint mode", - "string", "black"); - - options.add(["linkbgcolor", "lbc"], - "Background color of a link during hint mode", - "string", "yellow"); - - options.add(["activelinkfgcolor", "alfc"], - "Foreground color of the current active link during hint mode", - "string", "black"); - - options.add(["activelinkbgcolor", "albc"], - "Background color of the current active link during hint mode", - "string", "#88FF00"); - options.add(["hintmatching", "hm"], "How links are matched", "string", "contains", diff --git a/content/liberator-overlay.js b/content/liberator-overlay.js index 3dae5c79..fc999ee6 100644 --- a/content/liberator-overlay.js +++ b/content/liberator-overlay.js @@ -26,9 +26,9 @@ Components.utils.import("resource://liberator/storage.jsm", modules); ["liberator.js", + "config.js", "util.js", "style.js", - "config.js", "buffer.js", "commands.js", "completion.js", diff --git a/content/liberator.js b/content/liberator.js index 9b15db4d..d5d940e0 100644 --- a/content/liberator.js +++ b/content/liberator.js @@ -74,8 +74,8 @@ const liberator = (function () //{{{ "boolean", false); const tabopts = [ - ["n", "Tab number", null, ".hl-TabNumber"], - ["N", "Tab number over icon", null, ".hl-TabIconNumber"] + ["n", "Tab number", null, highlight.selector("TabNumber")], + ["N", "Tab number over icon", null, highlight.selector("TabIconNumber")] ]; options.add(["guioptions", "go"], "Show or hide certain GUI elements like the menu or toolbar", @@ -433,7 +433,7 @@ const liberator = (function () //{{{ var str = template.generic(
----- Auto Commands -----
{event}
- + diff --git a/content/liberator.xul b/content/liberator.xul index 948271bb..fe7c63a7 100644 --- a/content/liberator.xul +++ b/content/liberator.xul @@ -34,6 +34,7 @@ the terms of any one of the MPL, the GPL or the LGPL. ]> - + -
  • {text} 
  • -
  • {desc} 
  • +
  • {text} 
  • +
  • {desc} 
  • ; }, @@ -62,7 +62,7 @@ const template = { { let extra = this.getKey(item, "extra"); return <> - {text}  + {text}  { !(extra && extra.length) ? "" : @@ -79,10 +79,10 @@ const template = { icon: function (item, text) { let icon = this.getKey(item, "icon"); - return <>{icon ? : <>}{text} + return <>{icon ? : <>}{text} }, - filter: function (str) {str}, + filter: function (str) {str}, // if "processStrings" is true, any passed strings will be surrounded by " and // any line breaks are displayed as \n @@ -95,29 +95,29 @@ const template = { switch (arg == null ? "undefined" : typeof arg) { case "number": - return {str}; + return {str}; case "string": if (processStrings) str = str.quote(); - return {str}; + return {str}; case "boolean": - return {str}; + return {str}; case "function": // Vim generally doesn't like /foo*/, because */ looks like a comment terminator. // Using /foo*(:?)/ instead. if (processStrings) - return {str.replace(/\{(.|\n)*(?:)/g, "{ ... }")}; + return {str.replace(/\{(.|\n)*(?:)/g, "{ ... }")}; return <>{arg}; case "undefined": - return {arg}; + return {arg}; case "object": // for java packages value.toString() would crash so badly // that we cannot even try/catch it if (/^\[JavaPackage.*\]$/.test(arg)) return <>[JavaPackage]; if (processStrings && false) - str = template.highlightFilter(str, "\n", function () ^J); - return {str}; + str = template.highlightFilter(str, "\n", function () ^J); + return {str}; case "xml": return arg; default: @@ -179,7 +179,7 @@ const template = { highlightURL: function highlightURL(str, force) { if (force || /^[a-zA-Z]+:\/\//.test(str)) - return {str}; + return {str}; else return str; }, @@ -205,7 +205,7 @@ const template = { { return this.generic(
    Code execution summary
      Executed:{count}times
    - + { @@ -214,7 +214,7 @@ const template = { - + ) }
    jumptitleURI
    {idx == index ? ">" : ""} {Math.abs(idx - index)} {val.title}{val.URI.spec}{val.URI.spec}
    ); @@ -224,7 +224,7 @@ const template = { { return this.generic( - + { @@ -243,7 +243,7 @@ const template = { { let table =
    --- {title} ---
    - + { @@ -263,7 +263,7 @@ const template = { /* This might be mind-bogglingly slow. We'll see. */ return this.generic(
    {title}
    - + { this.map(headings, function (h) ) @@ -288,7 +288,7 @@ const template = { { this.map(iter, function (item) - + ) } diff --git a/content/ui.js b/content/ui.js index de0de3e7..c9b799c9 100644 --- a/content/ui.js +++ b/content/ui.js @@ -284,7 +284,7 @@ function CommandLine() //{{{ function setHighlightGroup(group) { - commandlineWidget.setAttribute("class", group); + commandlineWidget.setAttributeNS(NS.uri, "highlight", group); } // sets the prompt - for example, : or / @@ -301,7 +301,7 @@ function CommandLine() //{{{ { promptWidget.collapsed = true; } - promptWidget.setAttribute("class", highlightGroup || commandline.HL_NORMAL); + promptWidget.setAttributeNS(NS.uri, "highlight", highlightGroup || commandline.HL_NORMAL); } // sets the command - e.g. 'tabopen', 'open http://example.com/' @@ -320,7 +320,7 @@ function CommandLine() //{{{ .scrollWidth > commandWidget.inputField.scrollWidth) { setCommand(""); - setMultiline({str}, highlightGroup); + setMultiline({str}, highlightGroup); } } @@ -616,7 +616,7 @@ function CommandLine() //{{{ let list = <>; for (let [,message] in Iterator(messageHistory.messages)) - list +=
    {message.str}
    ; + list +=
    {message.str}
    ; liberator.echo(list, commandline.FORCE_MULTILINE); } @@ -629,14 +629,14 @@ function CommandLine() //{{{ return { - HL_NORMAL : "hl-Normal", - HL_ERRORMSG : "hl-ErrorMsg", - HL_MODEMSG : "hl-ModeMsg", - HL_MOREMSG : "hl-MoreMsg", - HL_QUESTION : "hl-Question", - HL_INFOMSG : "hl-InfoMsg", - HL_WARNINGMSG : "hl-WarningMsg", - HL_LINENR : "hl-LineNr", + HL_NORMAL : "Normal", + HL_ERRORMSG : "ErrorMsg", + HL_MODEMSG : "ModeMsg", + HL_MOREMSG : "MoreMsg", + HL_QUESTION : "Question", + HL_INFOMSG : "InfoMsg", + HL_WARNINGMSG : "WarningMsg", + HL_LINENR : "LineNr", FORCE_MULTILINE : 1 << 0, FORCE_SINGLELINE : 1 << 1, @@ -1047,7 +1047,7 @@ function CommandLine() //{{{ // TODO: on the prompt line should scroll one page case "": - if (event.originalTarget.className == "hl-URL buffer-list") + if (event.originalTarget.getAttributeNS(NS.uri, "highlight") == "URL buffer-list") { tabs.select(parseInt(event.originalTarget.parentNode.parentNode.firstChild.textContent, 10) - 1); closeWindow = true; @@ -1315,13 +1315,13 @@ function ItemList(id) //{{{ function init() { div = dom( -
    -
    No Completions
    +
    +
    No Completions
    -
    +
    { template.map(util.range(0, maxItems), function (i) -
    • ~
    ) +
    • ~
    ) }
    , divNodes); @@ -1333,12 +1333,12 @@ function ItemList(id) //{{{ return; context.cache.nodes = []; dom(
    -
    - {context.createRow(context.title || [], "hl-CompTitle")} +
    + {context.createRow(context.title || [], "CompTitle")}
    -
    -
    -
    +
    +
    +
    , context.cache.nodes); divNodes.completions.appendChild(context.cache.nodes.root); }); @@ -1400,7 +1400,7 @@ function ItemList(id) //{{{ divNodes.noCompletions.style.display = (off > 0) ? "none" : "block"; - completionElements = buffer.evaluateXPath("//*[@class='hl-CompItem' and not(contains(@style, 'none'))]", doc); + completionElements = buffer.evaluateXPath("//*[@liberator:highlight='CompItem' and not(contains(@style, 'none'))]", doc); autoSize(); return true; @@ -1549,7 +1549,7 @@ function StatusLine() //{{{ insecure: "StatusLine" }; - statusBar.setAttribute("class", "chromeclass-status hl-" + highlightGroup[type]); + statusBar.setAttributeNS(NS.uri, "highlight", highlightGroup[type]); }, // update all fields of the statusline diff --git a/content/util.js b/content/util.js index 574c1975..05bc3a89 100644 --- a/content/util.js +++ b/content/util.js @@ -26,6 +26,10 @@ 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 *****/ +const XHTML = "http://www.w3.org/1999/xhtml"; +const NS = Namespace("liberator", "http://vimperator.org/namespaces/liberator"); +default xml namespace = XHTML; + const util = { //{{{ Array: { @@ -331,8 +335,8 @@ const util = { //{{{ { obj = "[Object]"; } - obj = template.highlightFilter(util.clip(obj, 150), "\n", !color ? function () "^J" : function () ^J); - let string = <>{obj}::
    ; + obj = template.highlightFilter(util.clip(obj, 150), "\n", !color ? function () "^J" : function () ^J); + let string = <>{obj}::
    ; let keys = []; try // window.content often does not want to be queried with "var i in object" @@ -504,10 +508,9 @@ const util = { //{{{ case "text": return doc.createTextNode(node); case "element": - // Should use the node's namespace, in the future. - let domnode = doc.createElementNS("http://www.w3.org/1999/xhtml", node.localName()); + let domnode = doc.createElementNS(node.namespace(), node.localName()); for each (let attr in node.@*) - domnode.setAttribute(attr.name(), String(attr)); + domnode.setAttributeNS(attr.name() == "highlight" ? NS.uri : attr.namespace(), attr.name(), String(attr)); for each (let child in node.*) domnode.appendChild(arguments.callee(child, doc, nodes)); if (nodes && node.@key)
    {h}
    {item.name || item.names[0]}{item.name || item.names[0]} {item.description}