diff options
| author | Stephen Blott | 2015-01-22 16:50:58 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2015-01-23 09:53:49 +0000 | 
| commit | 256beee031efef70f4ee750044d9e697d66868bd (patch) | |
| tree | 851b8aa8abdb3b5875d5caa52166d83f13ca89b8 /lib/dom_utils.coffee | |
| parent | eefe8c29b2410119412984301eba8c66dffda059 (diff) | |
| download | vimium-256beee031efef70f4ee750044d9e697d66868bd.tar.bz2 | |
Visual/edit modes: develop edit mode.
- implement "i", "a".
- fix "w" for edit mode.
- try out "e" for enter edit mode.
- initial implementation "o", "O"
- Suppress backspace and delete.
- Scroll in text areas.
Diffstat (limited to 'lib/dom_utils.coffee')
| -rw-r--r-- | lib/dom_utils.coffee | 94 | 
1 files changed, 94 insertions, 0 deletions
| diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee index 4f36e395..477abef2 100644 --- a/lib/dom_utils.coffee +++ b/lib/dom_utils.coffee @@ -231,5 +231,99 @@ DomUtils =          @remove()          false +extend DomUtils, +  # From: https://github.com/component/textarea-caret-position/blob/master/index.js +  getCaretCoordinates: do -> +    # The properties that we copy into a mirrored div. +    # Note that some browsers, such as Firefox, +    # do not concatenate properties, i.e. padding-top, bottom etc. -> padding, +    # so we have to do every single property specifically. +    properties = [ +      'direction',  # RTL support +      'boxSizing', +      'width',  # on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does +      'height', +      'overflowX', +      'overflowY',  # copy the scrollbar for IE + +      'borderTopWidth', +      'borderRightWidth', +      'borderBottomWidth', +      'borderLeftWidth', + +      'paddingTop', +      'paddingRight', +      'paddingBottom', +      'paddingLeft', + +      # https://developer.mozilla.org/en-US/docs/Web/CSS/font +      'fontStyle', +      'fontVariant', +      'fontWeight', +      'fontStretch', +      'fontSize', +      'fontSizeAdjust', +      'lineHeight', +      'fontFamily', + +      'textAlign', +      'textTransform', +      'textIndent', +      'textDecoration',  # might not make a difference, but better be safe + +      'letterSpacing', +      'wordSpacing' +    ] + +    `function (element, position, recalculate) { +      // mirrored div +      var div = document.createElement('div'); +      div.id = 'input-textarea-caret-position-mirror-div'; +      document.body.appendChild(div); + +      var style = div.style; +      var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle;  // currentStyle for IE < 9 + +      // default textarea styles +      style.whiteSpace = 'pre-wrap'; +      if (element.nodeName !== 'INPUT') +        style.wordWrap = 'break-word';  // only for textarea-s + +      // position off-screen +      style.position = 'absolute';  // required to return coordinates properly +      style.visibility = 'hidden';  // not 'display: none' because we want rendering + +      // transfer the element's properties to the div +      properties.forEach(function (prop) { +        style[prop] = computed[prop]; +      }); + +      style.overflow = 'hidden';  // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll' + +      div.textContent = element.value.substring(0, position); +      // the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037 +      if (element.nodeName === 'INPUT') +        div.textContent = div.textContent.replace(/\s/g, "\u00a0"); + +      var span = document.createElement('span'); +      // Wrapping must be replicated *exactly*, including when a long word gets +      // onto the next line, with whitespace at the end of the line before (#7). +      // The  *only* reliable way to do that is to copy the *entire* rest of the +      // textarea's content into the <span> created at the caret position. +      // for inputs, just '.' would be enough, but why bother? +      span.textContent = element.value.substring(position) || '.';  // || because a completely empty faux span doesn't render at all +      div.appendChild(span); + +      var coordinates = { +        top: span.offsetTop + parseInt(computed['borderTopWidth']), +        left: span.offsetLeft + parseInt(computed['borderLeftWidth']) +      }; + +      document.body.removeChild(div); + +      return coordinates; +    } +    ` +  root = exports ? window  root.DomUtils = DomUtils | 
