diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/dom_utils.coffee | 131 | 
1 files changed, 41 insertions, 90 deletions
| diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee index 9360bb95..2ae9412e 100644 --- a/lib/dom_utils.coffee +++ b/lib/dom_utils.coffee @@ -250,99 +250,50 @@ DomUtils =      t = o || t?.parentNode      t -extend DomUtils, +  # This calculates the caret coordinates within an input element.  It is used by edit mode to calculate the +  # caret position for scrolling.  It creates a hidden div contain a mirror of element, and all of the text +  # from element up to position, then calculates the scroll position.    # 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. +    # The properties that we copy to the mirrored div.      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; -    } -    ` +      'direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', +      'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', +      'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', +      'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', +      'lineHeight', 'fontFamily', +      'textAlign', 'textTransform', 'textIndent', 'textDecoration', +      'letterSpacing', 'wordSpacing' ] + +    (element, position) -> +      div = document.createElement "div" +      div.id = "vimium-input-textarea-caret-position-mirror-div" +      document.body.appendChild div + +      style = div.style +      computed = getComputedStyle element + +      style.whiteSpace = "pre-wrap" +      style.wordWrap = "break-word" if element.nodeName.toLowerCase() != "input" +      style.position = "absolute" +      style.visibility = "hidden" +      style[prop] = computed[prop] for prop in properties +      style.overflow = "hidden" + +      div.textContent = element.value.substring 0, position +      if element.nodeName.toLowerCase() == "input" +        div.textContent = div.textContent.replace /\s/g, "\u00a0" + +      span = document.createElement "span" +      span.textContent = element.value.substring(position) || "." +      div.appendChild span + +      coordinates = +        top: span.offsetTop + parseInt computed["borderTopWidth"] +        left: span.offsetLeft + parseInt computed["borderLeftWidth"] + +      document.body.removeChild div +      coordinates  root = exports ? window  root.DomUtils = DomUtils | 
