JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
events don't reach editable content, no selecting
authorJason Woofenden <jason@jasonwoof.com>
Tue, 8 Mar 2016 17:26:59 +0000 (12:26 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Tue, 8 Mar 2016 17:26:59 +0000 (12:26 -0500)
editor.coffee

index d93f1ed..ceffb9a 100644 (file)
@@ -56,6 +56,15 @@ is_display_block = (el) ->
        else
                return window.getComputedStyle(el, null).getPropertyValue('display') is 'block'
 
+# Pass return value from dom event handlers to this.
+# If they return false, this will addinionally stop propagation and default.
+event_return = (e, bool) ->
+       if bool is false
+               if e.stopPropagation?
+                       e.stopPropagation()
+               if e.preventDefault?
+                       e.preventDefault()
+       return bool
 # Warning: currently assumes you're asking about a single character
 # Note: chromium returns multiple bounding rects for a space at a line-break
 # Note: chromium's getBoundingClientRect() is broken (when zero-area client rects)
@@ -215,6 +224,10 @@ outer_css = (args) ->
        ret +=     'padding: 0;'
        ret +=     "width: #{w}px;"
        #ret +=     "height: #{h}px;" # height auto-set when content set/changed
+       ret +=     '-ms-user-select: none;'
+       ret +=     '-webkit-user-select: none;'
+       ret +=     '-moz-user-select: none;'
+       ret +=     'user-select: none;'
        ret += '}'
        ret += '#overlay {'
        ret +=     'position: absolute;'
@@ -549,11 +562,12 @@ tree_dedup_space = (tree) ->
 class PeachHTML5Editor
        # Options: (all optional)
        #   editor_id: "id" attribute for outer-most element created by/for editor
+       #   on_init: callback for when the editable content is in place
        constructor: (in_el, options) ->
                @options = options ? {}
                @in_el = in_el
                @tree = []
-               @initialized = false # when iframes have loaded
+               @inited = false # when iframes have loaded
                @outer_iframe # iframe to hold editor
                @outer_idoc # "document" object for @outer_iframe
                @iframe = null # iframe to hold editable content
@@ -579,7 +593,7 @@ class PeachHTML5Editor
                        @iframe = domify @outer_idoc, iframe: {}
                        @iframe.onload = =>
                                @init()
-                       setTimeout (=> @init()), 200 # firefox never fires this onload
+                       setTimeout (=> @init() unless @inited), 200 # firefox never fires this onload
                        @outer_idoc.body.appendChild(
                                domify @outer_idoc, div: id: 'wrap1', children: [
                                        domify @outer_idoc, div: id: 'wrap2', children: [
@@ -602,29 +616,33 @@ class PeachHTML5Editor
                css = outer_css w: outer_bounds.w, h: outer_bounds.h
                outer_wrap.appendChild @outer_iframe
        init: -> # called by @iframe's onload (or timeout on firefox)
-               return if @initialized # ignore timeout for non-broken browsers
                @idoc = @iframe.contentDocument
                @overlay.onclick = (e) =>
-                       return @onclick e
+                       return event_return @onclick e
+               @overlay.ondoubleclick = (e) =>
+                       return event_return @ondoubleclick e
                @outer_idoc.body.onkeyup = (e) =>
-                       return @onkeyup e
+                       return event_return @onkeyup e
                @outer_idoc.body.onkeydown = (e) =>
-                       return @onkeydown e
+                       return event_return @onkeydown e
                @outer_idoc.body.onkeypress = (e) =>
-                       return @onkeypress e
+                       return event_return @onkeypress e
                if @options.stylesheet
                        # TODO test this
                        @idoc.head.appendChild domify @idoc, style: src: @options.stylesheet
                @load_html @in_el.value
-               @initialized = true
-               if @options.initialized_cb?
-                       @options.initialized_cb()
+               @inited = true
+               if @options.on_init?
+                       @options.on_init()
        onclick: (e) ->
                x = (e.offsetX ? e.layerX) - overlay_padding
                y = (e.offsetY ? e.layerY) - overlay_padding
                new_cursor = find_loc_cursor_position @tree, x: x, y: y
                if new_cursor?
                        @move_cursor new_cursor
+               return false
+       ondoubleclick: (e) ->
+               return false
        onkeyup: (e) ->
                return if e.ctrlKey
                return false if ignore_key_codes[e.keyCode]?