From d77e73ca8f6a9eed6e8f58d8a778424e986aaf9f Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 11 Aug 2012 11:28:49 -0400 Subject: [PATCH] files recovered from dead machine... from now on I will commit every day --- bootstrap.coffee | 40 ++++++++----- packages/commands.coffee | 69 ++++++++++++++++++++++ packages/event-handlers.coffee | 65 +++++++++++++++++++++ packages/link-hints.coffee | 6 ++ packages/utils.coffee | 101 +++++++++++++++++++++++++++++++++ packages/vim.coffee | 46 +++++++++++++++ tests/test-event-utils.coffee | 18 ++++++ tests/test-window-utils.coffee | 15 +++-- 8 files changed, 342 insertions(+), 18 deletions(-) create mode 100755 packages/commands.coffee create mode 100755 packages/event-handlers.coffee create mode 100755 packages/link-hints.coffee create mode 100755 packages/utils.coffee create mode 100755 packages/vim.coffee create mode 100755 tests/test-event-utils.coffee diff --git a/bootstrap.coffee b/bootstrap.coffee index 788161d..8b98fbe 100644 --- a/bootstrap.coffee +++ b/bootstrap.coffee @@ -8,33 +8,47 @@ Cu.import "resource://gre/modules/Services.jsm", tools baseURI = tools.Services.io.newURI __SCRIPT_URI_SPEC__, null, null + include = (src, scope = {}) -> + try + uri = tools.Services.io.newURI "packages/#{ src }.js", null, baseURI + tools.Services.scriptloader.loadSubScript uri.spec, scope + catch error + uri = tools.Services.io.newURI src, null, baseURI + tools.Services.scriptloader.loadSubScript uri.spec, scope + + return scope + + modules = {} - global.require = (src) -> + require = (src) -> if modules[src] return modules[src] else scope = - require: global.require, + require: require + include: include exports: {} - try - uri = tools.Services.io.newURI "packages/" + src + ".js", null, baseURI - tools.Services.scriptloader.loadSubScript uri.spec, scope - catch error - uri = tools.Services.io.newURI src, null, baseURI - tools.Services.scriptloader.loadSubScript uri.spec, scope + include src, scope return modules[src] = scope.exports; - global.include = (src) -> - uri = tools.Services.io.newURI src, null, baseUri - tools.Services.scriptloader.loadSubScript uri.spec, global - - Console = global.require("console").Console + Console = require("console").Console global.console = new Console "vimroll" + global.include = include + global.require = require )(this); +{ WindowEventTracker } = require 'utils' +{ handlers } = require 'event-handlers' + +tracker = new WindowEventTracker handlers + + + startup = (data, reason) -> + tracker.start() shutdown = (data, reason) -> + tracker.stop() diff --git a/packages/commands.coffee b/packages/commands.coffee new file mode 100755 index 0000000..6cc675f --- /dev/null +++ b/packages/commands.coffee @@ -0,0 +1,69 @@ +SCROLL_AMOUNT = 60 + +{ classes: Cc, interfaces: Ci, utils: Cu } = Components + +utils = require 'utils' + +commands = + 'g,g': (window) -> + window.scrollTo(0, 0) + + 'G': (window) -> + window.scrollTo(0, window.document.body.scrollHeight) + + 'j': (window) -> + window.scrollBy(0, SCROLL_AMOUNT) + + 'k': (window) -> + window.scrollBy(0, -SCROLL_AMOUNT) + + 'd': (window) -> + window.scrollBy(0, window.innerHeight) + + 'u': (window) -> + window.scrollBy(0, -window.innerHeight) + + 'J': (window) -> + if rootWindow = utils.getRootWindow window + rootWindow.gBrowser.tabContainer.advanceSelectedTab(1, true); + + 'K': (window) -> + if rootWindow = utils.getRootWindow window + rootWindow.gBrowser.tabContainer.advanceSelectedTab(-1, true); + + 'x': (window) -> + if rootWindow = utils.getRootWindow window + rootWindow.gBrowser.removeCurrentTab() + + 'X': (window) -> + if rootWindow = utils.getRootWindow window + ss = utils.getSessionStore() + if ss and ss.getClosedTabCount(rootWindow) > 0 + ss.undoCloseTab rootWindow, 0 + + 'Esc': (window) -> + window.document.activeElement?.blur() + + +getCommand = (keys) -> + sequence = [key.toString() for key in keys].join(',') + if command = commands[sequence] + return command + else if keys.length > 0 + return getCommand keys.slice(1) + else + undefined + +maybeCommand = (keys) -> + if keys.length == 0 + return false + else + sequence = [key.toString() for key in keys].join(',') + for s in Object.keys(commands) + if s.search(sequence) == 0 + return true + + return maybeCommand keys.slice(1) + +exports.getCommand = getCommand +exports.maybeCommand = maybeCommand diff --git a/packages/event-handlers.coffee b/packages/event-handlers.coffee new file mode 100755 index 0000000..482f170 --- /dev/null +++ b/packages/event-handlers.coffee @@ -0,0 +1,65 @@ +utils = require 'utils' +{ getCommand } = require 'commands' +{ VimBucket } = require 'vim' + +{ interfaces: Ci } = Components + +KeyboardEvent = Ci.nsIDOMKeyEvent + +vimBucket = new VimBucket + +class KeyInfo + constructor: (event) -> + if event.charCode > 0 + @key = String.fromCharCode(event.charCode) + else + switch event.keyCode + when KeyboardEvent.DOM_VK_ESCAPE then @key = 'Esc' + + @shift = event.shiftKey + @alt = event.altKey + @ctrl = event.ctrlKey + @meta = event.metaKey + + toString: -> + k = (a, b) -> if a then b else '' + if @at or @ctrl or @meta + "<#{ k(@ctrl, 'c') }#{ k(@alt, 'a') }#{ k(@meta, 'm') }-#{ @key }>" + else + @key + +suppressEvent = (event) -> + event.preventDefault() + event.stopPropagation() + +handlers = + 'keypress': (event) -> + isEditable = utils.isElementEditable event.originalTarget + if event.keyCode == KeyboardEvent.DOM_VK_ESCAPE or not isEditable + if window = utils.getEventTabWindow event + keyInfo = new KeyInfo event + console.log event.keyCode, event.which, event.charCode + if vimBucket.get(window)?.keypress keyInfo + suppressEvent event + + + 'focus': (event) -> + if window = utils.getEventTabWindow event + vimBucket.get(window)?.focus event.originalTarget + + 'blur': (event) -> + if window = utils.getEventTabWindow event + vimBucket.get(window)?.blur event.originalTarget + + 'TabClose': (event) -> + if gBrowser = utils.getEventTabBrowser event + if browser = gBrowser.getBrowserForTab event.originalTarget + vimBucket.forget browser.contentWindow.wrappedJSObject + + 'DOMWindowClose': (event) -> + if gBrowser = event.originalTarget.gBrowser + for tab in gBrowser.tabs + if browser = gBrowser.getBrowserForTab tab + vimBucket.forget browser.contentWindow.wrappedJSObject + +exports.handlers = handlers diff --git a/packages/link-hints.coffee b/packages/link-hints.coffee new file mode 100755 index 0000000..bc444c3 --- /dev/null +++ b/packages/link-hints.coffee @@ -0,0 +1,6 @@ +HINTCHARS = 'asdfghjkl;' + +class Marker + constructor: (@element) -> + +hintDocument = (document, cb) -> diff --git a/packages/utils.coffee b/packages/utils.coffee new file mode 100755 index 0000000..b90b73b --- /dev/null +++ b/packages/utils.coffee @@ -0,0 +1,101 @@ +{ WindowTracker, isBrowserWindow } = require 'window-utils' + +class WindowEventTracker + constructor: (events, eventFilter = null) -> + + handlerFilter = (handler) -> + return (event) -> + if !eventFilter or eventFilter event + handler event + + addEventListeners = (window) -> + for name, handler of events + window.addEventListener name, handlerFilter(handler), true + + removeEventListeners = (window) -> + for name, handler of events + window.removeEventListener name, handlerFilter(handler), true + + @windowTracker = new WindowTracker + track: (window) -> + if isBrowserWindow window + addEventListeners window + + untrack: (window) -> + if isBrowserWindow window + removeEventListeners window + + start: -> @windowTracker.start() + stop: -> @windowTracker.stop() + +{ interfaces: Ci } = Components + +HTMLInputElement = Ci.nsIDOMHTMLInputElement +HTMLTextAreaElement = Ci.nsIDOMHTMLTextAreaElement +HTMLSelectElement = Ci.nsIDOMHTMLSelectElement +XULDocument = Ci.nsIDOMXULDocument +XULElement = Ci.nsIDOMXULElement +HTMLDocument = Ci.nsIDOMHTMLDocument +HTMLElement = Ci.nsIDOMHTMLElement +Window = Ci.nsIDOMWindow +ChromeWindow = Ci.nsIDOMChromeWindow + +isRootWindow = (window) -> + window.location == "chrome://browser/content/browser.xul" + +getEventWindow = (event) -> + if event.originalTarget instanceof Window + return event.originalTarget + else + doc = event.originalTarget.ownerDocument or event.originalTarget + if doc instanceof HTMLDocument or doc instanceof XULDocument + return doc.defaultView + +getEventTabWindow = (event) -> + if window = getEventWindow event + if isRootWindow window + return window.gBrowser.tabs.selectedItem?.contentWindow.wrappedJSObject + else + return window + +getEventRootWindow = (event) -> + if window = getEventWindow event + return getRootWindow window + +getEventTabBrowser = (event) -> + cw.gBrowser if cw = getEventRootWindow event + + +getRootWindow = (window) -> + return window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Window); + +isElementEditable = (element) -> + return element.isContentEditable or \ + element instanceof HTMLInputElement or \ + element instanceof HTMLTextAreaElement or \ + element instanceof HTMLSelectElement + +getWindowId = (window) -> + return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils) + .outerWindowID + +getSessionStore = -> + Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); + +exports.WindowEventTracker = WindowEventTracker +exports.isRootWindow = isRootWindow +exports.getEventWindow = getEventWindow +exports.getEventTabWindow = getEventTabWindow +exports.getEventRootWindow = getEventRootWindow +exports.getEventTabBrowser = getEventTabBrowser + +exports.getWindowId = getWindowId +exports.getRootWindow = getRootWindow +exports.isElementEditable = isElementEditable +exports.getSessionStore = getSessionStore diff --git a/packages/vim.coffee b/packages/vim.coffee new file mode 100755 index 0000000..132d84e --- /dev/null +++ b/packages/vim.coffee @@ -0,0 +1,46 @@ +{ getCommand, maybeCommand } = require 'commands' +{ getWindowId } = require 'utils' + +MODE_NORMAL = 1 + + +class Vim + constructor: (@window) -> + @mode = MODE_NORMAL + @keys = [] + + keypress: (keyInfo) -> + @keys.push keyInfo + if command = getCommand @keys + command @window + @keys = [] + true + else if maybeCommand @keys + true + else + false + + focus: (element) -> + @activeElement = element + console.log 'focus', @activeElement + + blur: (element) -> + console.log 'blur', @activeElement + delete @activeElement if @activeElement == element + + + + +class VimBucket + constructor: -> + @vims = {} + + get: (window) -> + id = getWindowId window + @vims[id] or @vims[id] = new Vim window + + forget: (window) -> + id = getWindowId window + delete @vims[id] if id + +exports.VimBucket = VimBucket diff --git a/tests/test-event-utils.coffee b/tests/test-event-utils.coffee new file mode 100755 index 0000000..d7d5801 --- /dev/null +++ b/tests/test-event-utils.coffee @@ -0,0 +1,18 @@ +{ WindowEventTracker } = require '../packages/event-utils' + +setupModule = (module) -> + module.controller = mozmill.getBrowserController() + +testWindowEventTracker = () -> + + count = 0 + tracker = new WindowEventTracker + keypress: (event) -> count += 1 + + tracker.start() + + controller.rootElement.keypress("k"); + + expect.equal count, 1, 'WindowEventTracker keypress failed' + + diff --git a/tests/test-window-utils.coffee b/tests/test-window-utils.coffee index 1366347..428fa94 100644 --- a/tests/test-window-utils.coffee +++ b/tests/test-window-utils.coffee @@ -2,19 +2,24 @@ setupModule = (module) -> module.controller = mozmill.getBrowserController() - tabBrowser = new TabbedBrowsingAPI.tabBrowser(controller); testWindowTracker = () -> controller.open 'http://www.google.com' - count = 0 + countTrack = 0 + countUntrack = 0 tracker = new WindowTracker - track: (window) -> count += 1 - untrack: (window) -> count += 1 + track: (window) -> countTrack += 1 + untrack: (window) -> countUntrack += 1 tracker.start() + + mozmill.newBrowserController() + tracker.stop() - expect.equal count, 2, 'WindowTracker failed' + expect.equal countTrack, 2, 'WindowTracker track failed' + expect.equal countUntrack, 2, 'WindowTracker untrack failed' + -- 2.39.3