text: 'use strict';
  
  var crossvent = require('crossvent');
  var dom = require('./dom');
  var text = require('./text');
  var props = [
    'fontFamily',
    'fontSize',
    'fontWeight',
    'fontStyle',
    'letterSpacing',
    'textTransform',
    'wordSpacing',
    'textIndent',
    'webkitBoxSizing',
    'mozBoxSizing',
    'boxSizing',
    'padding',
    'border'
  ];
  var offset = 20;
  
  module.exports = function factory (el) {
    var mirror = dom('span');
  
    document.body.appendChild(mirror);
    remap();
    bind();
  
    return {
      remap: remap,
      refresh: refresh,
      destroy: destroy
    };
  
    function remap () {
      var c = computed();
      var value;
      var i;
      for (i = 0; i < props.length; i++) {
        value = c[props[i]];
        if (value !== void 0 && value !== null) { // otherwise IE blows up
          mirror.style[props[i]] = value;
        }
      }
      mirror.disabled = 'disabled';
      mirror.style.whiteSpace = 'pre';
      mirror.style.position = 'absolute';
      mirror.style.top = mirror.style.left = '-9999em';
    }
  
    function refresh () {
      var value = el.value;
      if (value === mirror.value) {
        return;
      }
  
      text(mirror, value);
  
      var width = mirror.offsetWidth + offset;
  
      el.style.width = width + 'px';
    }
  
    function bind (remove) {
      var op = remove ? 'remove' : 'add';
      crossvent[op](el, 'keydown', refresh);
      crossvent[op](el, 'keyup', refresh);
      crossvent[op](el, 'input', refresh);
      crossvent[op](el, 'paste', refresh);
      crossvent[op](el, 'change', refresh);
    }
  
    function destroy () {
      bind(true);
      mirror.parentElement.removeChild(mirror);
      el.style.width = '';
    }
  
    function computed () {
      if (window.getComputedStyle) {
        return window.getComputedStyle(el);
      }
      return el.currentStyle;
    }
  };
  