From 5bfd628b173f35a229bce33d62b76be9a92da500 Mon Sep 17 00:00:00 2001 From: Anton Khodakivskiy Date: Tue, 10 Dec 2013 12:17:15 +0700 Subject: [PATCH] Find refactoring --- extension/packages/commands.coffee | 32 ++--- extension/packages/find.coffee | 212 ----------------------------- extension/packages/modes.coffee | 17 ++- extension/packages/vim.coffee | 9 +- 4 files changed, 35 insertions(+), 235 deletions(-) delete mode 100644 extension/packages/find.coffee diff --git a/extension/packages/commands.coffee b/extension/packages/commands.coffee index 22df72b..4ff6c98 100644 --- a/extension/packages/commands.coffee +++ b/extension/packages/commands.coffee @@ -1,6 +1,5 @@ utils = require 'utils' help = require 'help' -find = require 'find' { _ } = require 'l10n' { getPref , setPref @@ -242,32 +241,25 @@ command_tab_move_right = (vim) -> command_help = (vim) -> help.injectHelp(vim.window.document, commands) -find.findStr = '' - # Switch into find mode command_find = (vim, storage) -> - find.injectFind vim.window.document, (findStr, startFindRng) -> - # Reset region and find string if new find stirng has arrived - if find.findStr != findStr - [find.findStr, storage.findRng] = [findStr, startFindRng] - # Perform forward find and store found region - return storage.findRng = find.find(vim.window, find.findStr, storage.findRng, find.DIRECTION_FORWARDS) + vim.enterMode('find') # Switch into find mode with highlighting command_find_hl = (vim, storage) -> - find.injectFind vim.window.document, (findStr) -> - # Reset region and find string if new find stirng has arrived - return find.highlight(vim.window, findStr) + vim.enterMode('find') # Search for the last pattern command_find_next = (vim, storage) -> - if find.findStr.length > 0 - storage.findRng = find.find(vim.window, find.findStr, storage.findRng, find.DIRECTION_FORWARDS, true) + if findBar = utils.getRootWindow(vim.window).gBrowser.getFindBar() + if findBar._findField.value.length > 0 + findBar.onFindAgainCommand(false) # Search for the last pattern backwards command_find_prev = (vim, storage) -> - if find.findStr.length > 0 - storage.findRng = find.find(vim.window, find.findStr, storage.findRng, find.DIRECTION_BACKWARDS, true) + if findBar = utils.getRootWindow(vim.window).gBrowser.getFindBar() + if findBar._findField.value.length > 0 + findBar.onFindAgainCommand(true) command_insert_mode = (vim) -> vim.enterMode('insert') @@ -279,13 +271,14 @@ command_Esc = (vim, storage, event) -> callback = -> event.originalTarget?.ownerDocument?.activeElement?.blur() vim.window.setTimeout(callback, 0) - find.removeFind(vim.window.document) - help.removeHelp(vim.window.document) if rootWindow = utils.getRootWindow(vim.window) rootWindow.DeveloperToolbar.hide() + if findBar = utils.getRootWindow(vim.window).gBrowser.getFindBar() + findBar.close() + class Command constructor: (@group, @name, @func, keys) -> @@ -374,6 +367,9 @@ searchForMatchingCommand = (keys) -> isEscCommandKey = (keyStr) -> keyStr in escapeCommand.keys() +isReturnCommandKey = (keyStr) -> keyStr.search('Return') > -1 + exports.commands = commands exports.searchForMatchingCommand = searchForMatchingCommand exports.isEscCommandKey = isEscCommandKey +exports.isReturnCommandKey = isReturnCommandKey diff --git a/extension/packages/find.coffee b/extension/packages/find.coffee deleted file mode 100644 index 8e6442e..0000000 --- a/extension/packages/find.coffee +++ /dev/null @@ -1,212 +0,0 @@ -{ classes: Cc, interfaces: Ci } = Components - -CONTAINER_ID = 'VimFxFindContainer' -DIRECTION_FORWARDS = 0 -DIRECTION_BACKWARDS = 1 - -HTMLDocument = Ci.nsIDOMHTMLDocument - -# Create and inserts into DOM find controls and handlers -injectFind = (document, cb) -> - # Find only works on HTML documents, not XUL documents - if document not instanceof HTMLDocument - return - - # First get starting range - it might begin where last search ended - startFindRng = getStartFindRng(document.defaultView) - - # Clean up just in case... - removeFind(document) - - # Create container div insert a text input into it - [div, input] = createFindContainer(document) - - # Call back in new input - input.addEventListener 'input', (event) -> - result = cb(input.value, startFindRng) - if result - input.classList.remove('VimFxNotFound') - else - input.classList.add('VimFxNotFound') - - # Call back on (Shift)-Enter with proper direction - input.addEventListener 'keypress', (event) -> - if event.keyCode == event.DOM_VK_RETURN - focusSelection(document, Ci.nsISelectionController.SELECTION_FIND) - removeFind(document, false) - - document.documentElement.appendChild(div) - input.focus() - -# Removes find controls from DOM -removeFind = (document, clear = true) -> - if div = document.getElementById(CONTAINER_ID) - document.documentElement.removeChild(div) - - if clear - clearSelection(document.defaultView) - -getStartFindRng = (window) -> - controller = getController(window) - for selectionType in [Ci.nsISelectionController.SELECTION_NORMAL, Ci.nsISelectionController.SELECTION_FIND] - selection = controller.getSelection(selectionType) - if selection.rangeCount > 0 - rng = selection.getRangeAt(0) - if rng.collapsed - rng.selectNode(rng.commonAncestorContainer) - if rng.commonAncestorContainer != window.document - return rng - - -focusSelection = (document, selectionType) -> - if controller = getController(document.defaultView) - if selection = controller.getSelection(selectionType) - if selection.rangeCount > 0 - # commonAncestorContainer is a Text node, we need to get the tag that wraps it - element = selection.getRangeAt(0).commonAncestorContainer?.parentNode - if element != document and element.focus - element.focus() - -createFindContainer = (document) -> - div = document.createElement('div') - div.className = 'VimFxReset' - div.id = CONTAINER_ID - - input = document.createElement('input') - input.type = 'text' - input.className = 'VimFxReset' - input.id = 'VimFxFindInput' - - div.appendChild(input) - - return [div, input] - -clearSelection = (window, selectionType = Ci.nsISelectionController.SELECTION_FIND) -> - for frame in window.frames - clearSelection(frame) - - if controller = getController(window) - controller.getSelection(selectionType).removeAllRanges() - -findFactory = (selectionType) -> - finder = Cc['@mozilla.org/embedcomp/rangefind;1'] - .createInstance() - .QueryInterface(Components.interfaces.nsIFind) - - return (window, findStr, findRng = null, direction = DIRECTION_FORWARDS, focus = false) -> - # `find` will also recursively search in all frames. `innerFind` does the work: - # searches, selects, scrolls, and optionally reaches into frames - innerFind = (window) -> - if controller = getController(window) - finder.findBackwards = (direction == DIRECTION_BACKWARDS) - finder.caseSensitive = (findStr != findStr.toLowerCase()) - - searchRange = window.document.createRange() - searchRange.selectNodeContents(window.document.body) - - if findRng and findRng.commonAncestorContainer.ownerDocument == window.document - if finder.findBackwards - searchRange.setEnd(findRng.startContainer, findRng.startOffset) - else - searchRange.setStart(findRng.endContainer, findRng.endOffset) - - (startPt = searchRange.cloneRange()).collapse(true) - (endPt = searchRange.cloneRange()).collapse(false) - - if finder.findBackwards - [startPt, endPt] = [endPt, startPt] - - if range = finder.Find(findStr, searchRange, startPt, endPt) - controller.getSelection(selectionType).addRange(range) - controller.scrollSelectionIntoView(selectionType, range, Ci.nsISelectionController.SCROLL_CENTER_VERTICALLY) - if focus - focusSelection(window.document, selectionType) - - return range - - clearSelection(window, selectionType) - - if findStr.length > 0 - # Get all embedded windows/frames including the passed window - wnds = getAllWindows(window) - # In backward searching reverse windows mode so that - # it starts off the deepest iframe - if finder.findBackwards - wnds.reverse() - - # First search in the same window to which current `findRng` belongs - if rngWindow = findRng?.commonAncestorContainer.ownerDocument.defaultView - wnds = cycleToItem(wnds, rngWindow) - - for w in wnds - if range = innerFind(w) - break - - return if findStr.length == 0 then true else range - -highlightFactory = (selectionType) -> - finder = Cc['@mozilla.org/embedcomp/rangefind;1'] - .createInstance() - .QueryInterface(Components.interfaces.nsIFind) - - return (window, findStr) -> - matchesCount = 0 - finder.findBackwards = false - finder.caseSensitive = (findStr != findStr.toLowerCase()) - - innerHighlight = (window) -> - if controller = getController(window) - searchRange = window.document.createRange() - searchRange.selectNodeContents(window.document.body) - - (startPt = searchRange.cloneRange()).collapse(true) - (endPt = searchRange.cloneRange()).collapse(false) - - selection = controller.getSelection(selectionType) - while range = finder.Find(findStr, searchRange, startPt, endPt) - selection.addRange(range) - matchesCount += 1 - (startPt = range.cloneRange()).collapse(false) - - # Highlight in iframes - for frame in window.frames - innerHighlight(frame) - - clearSelection(window, selectionType) - - if findStr.length > 0 - innerHighlight(window) - - return if findStr.length == 0 then true else matchesCount - -getController = (window) -> - if not window.innerWidth or not window.innerHeight - return null - - return window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsISelectionDisplay) - .QueryInterface(Ci.nsISelectionController) - -# Returns flat list of frmaes within provided window -getAllWindows = (window) -> - result = [window] - for frame in window.frames - result = result.concat(getAllWindows(frame)) - - return result - -cycleToItem = (array, item) -> - if item and array.indexOf(item) != -1 - while array[0] != item - array.push array.shift() - - return array - -exports.injectFind = injectFind -exports.removeFind = removeFind -exports.find = findFactory(Ci.nsISelectionController.SELECTION_FIND) -exports.highlight = highlightFactory(Ci.nsISelectionController.SELECTION_FIND) -exports.DIRECTION_FORWARDS = DIRECTION_FORWARDS -exports.DIRECTION_BACKWARDS = DIRECTION_BACKWARDS diff --git a/extension/packages/modes.coffee b/extension/packages/modes.coffee index 7edb0b2..6e73db9 100644 --- a/extension/packages/modes.coffee +++ b/extension/packages/modes.coffee @@ -2,7 +2,8 @@ utils = require 'utils' { mode_hints } = require 'mode-hints/mode-hints' { updateToolbarButton } = require 'button' { searchForMatchingCommand -, isEscCommandKey } = require 'commands' +, isEscCommandKey +, isReturnCommandKey } = require 'commands' modes = {} @@ -41,6 +42,20 @@ modes['insert'] = vim.enterMode('normal') return true +modes['find'] = + onEnter: (vim) -> + if findBar = utils.getRootWindow(vim.window)?.gBrowser.getFindBar() + findBar.open() + findBar._findField.focus() + findBar._findField.select() + onLeave: (vim) -> + if findBar = utils.getRootWindow(vim.window)?.gBrowser.getFindBar() + findBar.close() + onInput: (vim, storage, keyStr) -> + if isEscCommandKey(keyStr) or isReturnCommandKey(keyStr) > -1 + vim.enterMode('normal') + return true + modes['hints'] = mode_hints exports.modes = modes diff --git a/extension/packages/vim.coffee b/extension/packages/vim.coffee index c5efca5..5075986 100644 --- a/extension/packages/vim.coffee +++ b/extension/packages/vim.coffee @@ -1,6 +1,7 @@ -utils = require 'utils' -{ modes } = require 'modes' -{ isEscCommandKey } = require 'commands' +utils = require 'utils' +{ modes } = require 'modes' +{ isEscCommandKey +, isReturnCommandKey } = require 'commands' class Vim constructor: (@window) -> @@ -23,7 +24,7 @@ class Vim onInput: (keyStr, event) -> isEditable = utils.isElementEditable(event.originalTarget) - if isEditable and not isEscCommandKey(keyStr) + if isEditable and not (isEscCommandKey(keyStr) or isReturnCommandKey(keyStr)) return false oldMode = @mode -- 2.39.3