JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
change parser api again
[peach-html5-editor.git] / editor.js
index 0c9cf46..977ca9e 100644 (file)
--- a/editor.js
+++ b/editor.js
@@ -274,7 +274,7 @@ void_elements = {
 }
 
 // contents are not html encoded
-plaintext_elements = {
+var plaintext_elements = {
        style: 1,
        script: 1,
        xmp: 1,
@@ -286,7 +286,7 @@ plaintext_elements = {
 }
 
 // parser deletes a starting newline inside:
-newline_eating_elements = {
+var newline_eating_elements = {
        pre: 1,
        textarea: 1,
        listing: 1
@@ -805,6 +805,7 @@ function PeachHTML5Editor (in_el, options) {
        this.init_1_called = false // when iframes have loaded
        this.outer_iframe // iframe to hold editor
        this.outer_idoc // "document" object for this.outer_iframe
+       this.input_el = null
        this.wrap2 = null // scrollbar is on this
        this.wrap2_offset = null
        this.wrap2_height = null // including padding
@@ -814,7 +815,6 @@ function PeachHTML5Editor (in_el, options) {
        this.cursor_el = null
        this.cursor_visible = false
        this.cursor_ideal_x = null
-       this.poll_for_blur_timeout = null
        opt_fragment = this.options.fragment != null ? this.options.fragment : true
        this.parser_opts = {}
        if (opt_fragment) {
@@ -825,39 +825,40 @@ function PeachHTML5Editor (in_el, options) {
        if (this.options.editor_id != null) {
                this.outer_iframe.setAttribute('id', this.options.editor_id)
        }
-       this.outer_iframe.onload = (function(_this) {
-               return function() {
-                       var icss
-                       _this.outer_idoc = _this.outer_iframe.contentDocument
-                       icss = domify(_this.outer_idoc, { style: { children: [
-                               domify(_this.outer_idoc, {text: css})
-                       ]}})
-                       _this.outer_idoc.head.appendChild(icss)
-                       _this.iframe = domify(_this.outer_idoc, {iframe: {sandbox: 'allow-same-origin allow-scripts'}})
-                       _this.iframe.onload = function() {
+       this.outer_iframe.onload = (function(_this) { return function() {
+               var icss
+               _this.outer_idoc = _this.outer_iframe.contentDocument
+               icss = domify(_this.outer_idoc, { style: { children: [
+                       domify(_this.outer_idoc, {text: css})
+               ]}})
+               _this.outer_idoc.head.appendChild(icss)
+               _this.input_el = domify(_this.outer_idoc, {textarea: {style: "position: relative; left: 100px"}}) // {style: "display: block; position: absolute; top: -1000px; left: 0; height: 500px; width 50em"}})
+               _this.input_el.onblur = _this.onblur.bind(_this)
+               _this.outer_idoc.body.appendChild(_this.input_el)
+               _this.iframe = domify(_this.outer_idoc, {iframe: {sandbox: 'allow-same-origin allow-scripts'}})
+               _this.iframe.onload = function() {
+                       return _this.init_1()
+               }
+               timeout(200, function() { // firefox never fires this onload
+                       if (!_this.init_1_called) {
                                return _this.init_1()
                        }
-                       timeout(200, function() { // firefox never fires this onload
-                               if (!_this.init_1_called) {
-                                       return _this.init_1()
-                               }
-                       })
-                       _this.outer_idoc.body.appendChild(
-                               domify(_this.outer_idoc, {div: {id: 'wrap1', children: [
-                                       domify(_this.outer_idoc, {div: {
-                                               style: "position: absolute; top: 0; left: 1px; font-size: 10px",
-                                               children: [domify(_this.outer_idoc, {text: "Peach HTML5 Editor"})]
-                                       }}),
-                                       _this.wrap2 = domify(_this.outer_idoc, {div: {id: 'wrap2', children: [
-                                               domify(_this.outer_idoc, {div: {id: 'wrap3', children: [
-                                                       _this.iframe,
-                                                       _this.overlay = domify(_this.outer_idoc, { div: { id: 'overlay' }})
-                                               ]}})
+               })
+               _this.outer_idoc.body.appendChild(
+                       domify(_this.outer_idoc, {div: {id: 'wrap1', children: [
+                               domify(_this.outer_idoc, {div: {
+                                       style: "position: absolute; top: 0; left: 1px; font-size: 10px",
+                                       children: [domify(_this.outer_idoc, {text: "Peach HTML5 Editor"})]
+                               }}),
+                               _this.wrap2 = domify(_this.outer_idoc, {div: {id: 'wrap2', children: [
+                                       domify(_this.outer_idoc, {div: {id: 'wrap3', children: [
+                                               _this.iframe,
+                                               _this.overlay = domify(_this.outer_idoc, { div: { id: 'overlay' }})
                                        ]}})
                                ]}})
-                       )
-               }
-       })(this)
+                       ]}})
+               )
+       }})(this)
        outer_wrap = domify(document, {div: {"class": 'peach_html5_editor' }})
        this.in_el.parentNode.appendChild(outer_wrap)
        outer_bounds = get_el_bounds(outer_wrap)
@@ -896,36 +897,18 @@ PeachHTML5Editor.prototype.init_1 = function() { // this.iframe has loaded (but
        }
 }
 PeachHTML5Editor.prototype.init_2 = function() { // this.iframe and it's css file(s) are ready
-       this.overlay.onclick = (function(_this) {
-               return function(e) {
+       var _this = this
+       var this_event_bind = function (cb) {
+               return function (e) {
                        _this.have_focus()
-                       return event_return(e, _this.onclick(e))
+                       event_return(e, _this[cb](e))
                }
-       })(this)
-       this.overlay.ondoubleclick = (function(_this) {
-               return function(e) {
-                       _this.have_focus()
-                       return event_return(e, _this.ondoubleclick(e))
-               }
-       })(this)
-       this.outer_idoc.body.onkeyup = (function(_this) {
-               return function(e) {
-                       _this.have_focus()
-                       return event_return(e, _this.onkeyup(e))
-               }
-       })(this)
-       this.outer_idoc.body.onkeydown = (function(_this) {
-               return function(e) {
-                       _this.have_focus()
-                       return event_return(e, _this.onkeydown(e))
-               }
-       })(this)
-       this.outer_idoc.body.onkeypress = (function(_this) {
-               return function(e) {
-                       _this.have_focus()
-                       return event_return(e, _this.onkeypress(e))
-               }
-       })(this)
+       }
+       this.overlay.onmousedown = this_event_bind('onclick')
+       this.overlay.ondoubleclick = this_event_bind('ondoubleclick')
+       this.outer_idoc.body.onkeyup = this_event_bind('onkeyup')
+       this.outer_idoc.body.onkeydown = this_event_bind('onkeydown')
+       this.outer_idoc.body.onkeypress = this_event_bind('onkeypress')
        this.load_html(this.in_el.value)
        if (this.options.on_init != null) {
                return this.options.on_init()
@@ -957,6 +940,7 @@ PeachHTML5Editor.prototype.generate_outer_css = function(args) {
        ret +=     'padding: 0;'
        ret +=     'color: black;'
        ret +=     'background: white;'
+       ret +=     'font-family: sans;'
        ret += '}'
        ret += '#wrap1 {'
        ret +=     "border: " + (occupy(1)) + "px solid black;"
@@ -1690,9 +1674,9 @@ PeachHTML5Editor.prototype.clear_dom = function() {
        this.kill_cursor()
 }
 PeachHTML5Editor.prototype.load_html = function(html) {
-       this.tree = peach_parser(html, this.parser_opts)
+       this.tree = peach_parser.parse(html, this.parser_opts)
        if (this.tree[0] == null ? true : this.tree[0].parent == null) {
-               this.tree = peach_parser('<p style="white-space: pre-wrap"> </p>', this.parser_opts)
+               this.tree = peach_parser.parse('<p style="white-space: pre-wrap"> </p>', this.parser_opts)
        }
        this.tree_parent = this.tree[0].parent
        this.tree_parent.el = this.idoc.body
@@ -1833,7 +1817,7 @@ PeachHTML5Editor.prototype.preserve_space = function(n, ideal_target) {
 PeachHTML5Editor.prototype.update_style_from_el = function(n) {
        var style
        style = n.el.getAttribute('style')
-       if (style != null) {
+       if (style != null && style != '') {
                return n.attrs.style = style
        } else {
                if (n.attrs.style != null) {
@@ -2156,7 +2140,7 @@ PeachHTML5Editor.prototype.text_cleanup = function(n) {
                        }
                        if (need_preserve) {
                                // do we have it already?
-                               ws = this.computed_style(n, 'white-space') // FIXME implement this
+                               ws = this.computed_style(n, 'white-space')
                                if (ws_props[ws] != null ? !ws_props[ws].space : true) {
                                        // 2nd arg is ideal target for css rule
                                        ws = this.preserve_space(n, block)
@@ -2164,7 +2148,7 @@ PeachHTML5Editor.prototype.text_cleanup = function(n) {
                                eats_start_sp = false
                        } else {
                                if (is_space_code(n.text.charCodeAt(n.text.length - 1))) {
-                                       ws = this.computed_style(n, 'white-space') // FIXME implement this
+                                       ws = this.computed_style(n, 'white-space')
                                        if ((ref1 = ws_props[ws]) != null ? ref1.space : void 0) {
                                                eats_start_sp = false
                                        } else {
@@ -2536,27 +2520,14 @@ PeachHTML5Editor.prototype.pretty_html = function(tree, indent, parent_flags) {
        return ret
 }
 PeachHTML5Editor.prototype.onblur = function() {
+       this.editor_is_focused = false
        this.kill_cursor()
 }
 PeachHTML5Editor.prototype.have_focus = function() {
-       this.editor_is_focused = true
-       this.poll_for_blur()
-}
-PeachHTML5Editor.prototype.poll_for_blur = function() {
-       if (this.poll_for_blur_timeout != null) {
-               return
+       if (!this.editor_is_focused) {
+               this.input_el.focus()
+               this.editor_is_focused = true
        }
-       this.poll_for_blur_timeout = timeout(150, (function(_this) { return function() {
-               next_frame(function() { // pause polling when browser knows we're not active/visible/etc.
-                       _this.poll_for_blur_timeout = null
-                       if (document.activeElement === _this.outer_iframe) {
-                               _this.poll_for_blur()
-                       } else {
-                               _this.editor_is_focused = false
-                               _this.onblur()
-                       }
-               })
-       }})(this))
 }
 
 window.peach_html5_editor = function() {