     arr.splice s, s - e, data
     # console.log 'inserted', narr
     @value = arr.join ''
+    @el.selectionStart = @el.selectionEnd = s + data.length
   ### public ###
   init: ->
     super()

    @on event: 'blur', handler: -> @placeholder = '_'
    # paste image
    @on event: 'paste', handler: (e) => @_onpaste e
    # auto save on exit
    @on el: window, event: 'unload', handler: =>
        sessionStorage.auto_save = @value or ''

  ### static ###
  @create: (cfg) -> super @, cfg
  ### private ###
  _image_mime_regex: /image\/(?:png|jpeg|qjpeg|gif|bmp)/
  _ondrop: (e) ->
    @_insertFiles [].slice.call e.dataTransfer.files
  _onpaste: (e) -> # paste images
    items = [].slice.call e.clipboardData.items
    files = items.filter((item) -> item.kind is 'file')
                 .map (item) -> item.getAsFile()
    return unless files.length
    # e.preventDefault() # alow file name pasted first
    @_insertFiles files
    return # alow file name pasted first
  _insertFiles: (files) ->
    return unless files
    files = [files] unless Array.isArray files
    files.forEach (file) =>
      if @_image_mime_regex.test file.type
        @_insertImage file
      else
        return # todo: support txt/src code files
    false
  _insertImage: (blob) ->
    if blob.size > 512 * 1024 # 512 K
      @channel.system 'The image you pasted is too large.' 
      return
    reader = new FileReader
    reader.onload = do (blob) => (e) =>
      fname = if blob.name then " alt=\"#{blob.name}\" title=\"#{blob.name}\"" else ''
      dataurl = e.target.result
      @_insertText "<img src=\"#{dataurl}\"#{fname}/>" # todo: match mode
      return
    reader.readAsDataURL blob
    return false
