- @iframe.onload = =>
- @idoc = @iframe.contentDocument
-
- ignore_key_codes =
- '18': true # alt
- '20': true # capslock
- '17': true # ctrl
- '144': true # numlock
- '16': true # shift
- '91': true # windows "start" key
- control_key_codes = # we react to these, but they aren't typing
- '37': KEY_LEFT
- '38': KEY_UP
- '39': KEY_RIGHT
- '40': KEY_DOWN
- '35': KEY_END
- '8': KEY_BACKSPACE
- '46': KEY_DELETE
- '13': KEY_ENTER
- '27': KEY_ESCAPE
- '36': KEY_HOME
- '45': KEY_INSERT
- '33': KEY_PAGE_UP
- '34': KEY_PAGE_DOWN
- '9': KEY_TAB
-
- @overlay.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
- @idoc.body.onkeyup = (e) =>
- return if e.ctrlKey
- return false if ignore_key_codes[e.keyCode]?
- #return false if control_key_codes[e.keyCode]?
- @idoc.body.onkeydown = (e) =>
- return if e.ctrlKey
- return false if ignore_key_codes[e.keyCode]?
- #return false if control_key_codes[e.keyCode]?
- switch e.keyCode
- when KEY_LEFT
- if @cursor?
- new_cursor = find_prev_cursor_position @tree, @cursor...
- if new_cursor?
- @move_cursor new_cursor
- else
- for c in @tree
- new_cursor = find_next_cursor_position @tree, c, -1
- if new_cursor?
+ @outer_iframe = domify document, iframe: {}
+ outer_iframe_style = 'border: none !important; margin: 0 !important; padding: 0 !important; height: 100% !important; width: 100% !important;'
+ if @options.editor_id?
+ @outer_iframe.setAttribute 'id', @options.editor_id
+ @outer_iframe.onload = =>
+ @outer_idoc = @outer_iframe.contentDocument
+ icss = domify @outer_idoc, style: children: [
+ domify @outer_idoc, text: css
+ ]
+ @outer_idoc.head.appendChild icss
+ @iframe = domify @outer_idoc, iframe: sandbox: 'allow-same-origin allow-scripts'
+ @iframe.onload = =>
+ @init_1()
+ timeout 200, => # firefox never fires this onload
+ @init_1() unless @init_1_called
+ @outer_idoc.body.appendChild(
+ domify @outer_idoc, div: id: 'wrap1', children: [
+ domify @outer_idoc, div: style: "position: absolute; top: 0; left: 1px; font-size: 10px", children: [ domify @outer_idoc, text: "Peach HTML5 Editor" ]
+ @wrap2 = domify @outer_idoc, div: id: 'wrap2', children: [
+ domify @outer_idoc, div: id: 'wrap3', children: [
+ @iframe
+ @overlay = domify @outer_idoc, div: id: 'overlay'
+ ]
+ ]
+ ]
+ )
+ outer_wrap = domify document, div: class: 'peach_html5_editor'
+ @in_el.parentNode.appendChild outer_wrap
+ outer_bounds = get_el_bounds outer_wrap
+ if outer_bounds.w < 300
+ outer_bounds.w = 300
+ if outer_bounds.h < 300
+ outer_bounds.h = 300
+ outer_iframe_style += "width: #{outer_bounds.w}px; height: #{outer_bounds.h}px;"
+ @outer_iframe.setAttribute 'style', outer_iframe_style
+ css = outer_css w: outer_bounds.w, h: outer_bounds.h
+ outer_wrap.appendChild @outer_iframe
+ init_1: -> # @iframe has loaded (but not it's css)
+ @idoc = @iframe.contentDocument
+ @init_1_called = true
+ # chromium doesn't resolve relative urls as though they were at the same domain
+ # so add a <base> tag
+ @idoc.head.appendChild domify @idoc, base: href: this_url_sans_path()
+ # don't let @iframe have scrollbars
+ @idoc.head.appendChild domify @idoc, style: children: [domify @idoc, text: "body { overflow: hidden; }"]
+ # load css file
+ if @options.css_file
+ istyle = domify @idoc, link: rel: 'stylesheet', href: @options.css_file
+ istyle.onload = =>
+ @init_2()
+ @idoc.head.appendChild istyle
+ else
+ @init_2()
+ init_2: -> # @iframe and it's css file(s) are ready
+ @overlay.onclick = (e) =>
+ @have_focus()
+ return event_return e, @onclick e
+ @overlay.ondoubleclick = (e) =>
+ @have_focus()
+ return event_return e, @ondoubleclick e
+ @outer_idoc.body.onkeyup = (e) =>
+ @have_focus()
+ return event_return e, @onkeyup e
+ @outer_idoc.body.onkeydown = (e) =>
+ @have_focus()
+ return event_return e, @onkeydown e
+ @outer_idoc.body.onkeypress = (e) =>
+ @have_focus()
+ return event_return e, @onkeypress e
+ @load_html @in_el.value
+ if @options.on_init?
+ @options.on_init()
+ overlay_event_to_inner_xy: (e) ->
+ unless @wrap2_offset?
+ @wrap2_offset = get_el_bounds @wrap2
+ x = e.pageX - overlay_padding
+ y = e.pageY - overlay_padding + @wrap2.scrollTop
+ return x: x - @wrap2_offset.x, y: y - @wrap2_offset.y
+ onclick: (e) ->
+ xy = @overlay_event_to_inner_xy e
+ new_cursor = find_loc_cursor_position @tree, xy
+ if new_cursor?
+ @move_cursor new_cursor
+ else
+ @kill_cursor()
+ return false
+ ondoubleclick: (e) ->
+ return false
+ onkeyup: (e) ->
+ return if e.ctrlKey
+ return false if ignore_key_codes[e.keyCode]?
+ #return false if control_key_codes[e.keyCode]?
+ onkeydown: (e) ->
+ return if e.ctrlKey
+ return false if ignore_key_codes[e.keyCode]?
+ #return false if control_key_codes[e.keyCode]?
+ switch e.keyCode
+ when KEY_LEFT
+ if @cursor?
+ new_cursor = find_prev_cursor_position @tree, @cursor...
+ if new_cursor?
+ @move_cursor new_cursor
+ else
+ for c in @tree
+ new_cursor = find_next_cursor_position @tree, c, -1
+ if new_cursor?
+ @move_cursor new_cursor
+ break
+ return false
+ when KEY_UP
+ if @cursor?
+ new_cursor = @cursor
+ old_loc = cursor_to_xyh new_cursor[0], new_cursor[1]
+ new_loc = x: old_loc.x, y: old_loc.y
+ while new_loc.y >= old_loc.y
+ new_cursor = find_prev_cursor_position @tree, new_cursor[0], new_cursor[1]
+ return false unless new_cursor?
+ new_loc = cursor_to_xyh new_cursor[0], new_cursor[1]
+ if new_cursor?
+ # now we're above
+ if new_loc.x <= old_loc.x
+ @move_cursor new_cursor
+ return false
+ target_y = new_loc.y
+ # search leftward, until we find the closest position
+ while new_loc.x > old_loc.x and new_loc.y is target_y
+ prev_loc = new_loc
+ prev_cursor = new_cursor
+ new_cursor = find_prev_cursor_position @tree, new_cursor[0], new_cursor[1]
+ break unless new_cursor?
+ new_loc = cursor_to_xyh new_cursor[0], new_cursor[1]
+ # move cursor to prev_cursor or new_cursor
+ if new_cursor?
+ if new_loc.y is target_y
+ # both valid, and on the same line, use closest
+ if (old_loc.x - new_loc.x) < (prev_loc.x - old_loc.x)