X-Git-Url: https://jasonwoof.com/gitweb/?p=peach-html5-editor.git;a=blobdiff_plain;f=editor.js;h=f3c620432efe3c70b07a5f5aeba0f1aab572a1ab;hp=85c8f10707502443516e7201e588af017037ca1b;hb=HEAD;hpb=0424dbfeb5473d1305ab090a2cf2b6459f404e9a diff --git a/editor.js b/editor.js index 85c8f10..f3c6204 100644 --- a/editor.js +++ b/editor.js @@ -121,11 +121,10 @@ get_el_bounds = window.bounds = function(el) { } function is_display_block (el) { - if (el.currentStyle != null) { - return el.currentStyle.display === 'block' - } else { + if (el.nodeType === 1) { return window.getComputedStyle(el, null).getPropertyValue('display') === 'block' } + return false } // Pass return value from dom event handlers to this. @@ -428,12 +427,19 @@ function instantiate_tree (tree, parent) { break case 'tag': if (c.name === 'script' || c.name === 'object' || c.name === 'iframe' || c.name === 'link') { - // TODO put placeholders instead - remove.unshift(i) + // TODO make some placeholders visible + // problematic to have different type than c: c.el = parent.ownerDocument.createComment(c.name + ' tag here') + c.el = parent.ownerDocument.createElement(c.name) + // correct type, but empty and no attributes continue } - // TODO create in correct namespace - c.el = parent.ownerDocument.createElement(c.name) + if (c.namespace === 'svg') { + c.el = parent.ownerDocument.createElementNS('http://www.w3.org/2000/svg', c.name) + } else if (c.namespace === 'mathml') { + c.el = parent.ownerDocument.createElementNS('http://www.w3.org/1998/Math/MathML', c.name) + } else { + c.el = parent.ownerDocument.createElement(c.name) + } ref1 = c.attrs for (k in ref1) { v = ref1[k] @@ -450,13 +456,6 @@ function instantiate_tree (tree, parent) { } } } - results = [] - for (i = 0; i < remove.length; i++) { - // FIXME this deletes the wrong node when siblings are removed - index = remove[i] - results.push(tree.splice(index, 1)) - } - return results } function traverse_tree (tree, cb) { @@ -805,6 +804,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 +814,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 +824,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 +896,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) { - _this.have_focus() - return event_return(e, _this.onclick(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) { + var _this = this + var this_event_bind = function (cb) { + return function (e) { _this.have_focus() - return event_return(e, _this.onkeydown(e)) + event_return(e, _this[cb](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() @@ -1691,9 +1673,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('

', this.parser_opts) + this.tree = peach_parser.parse('

', this.parser_opts) } this.tree_parent = this.tree[0].parent this.tree_parent.el = this.idoc.body @@ -1880,7 +1862,7 @@ PeachHTML5Editor.prototype.collapse_whitespace = function(tree) { if (block) { cb(null) } - if (n.children.length > 0) { + if (n.children.length > 0 && plaintext_elements[n.name] == null) { iterate(n.children, cb) } if (block) { @@ -2385,21 +2367,12 @@ PeachHTML5Editor.prototype.pretty_html = function(tree, indent, parent_flags) { is_br = true } is_text = false - if (n.el.currentStyle != null) { - cs = n.el.currentStyle - whitespace = cs['white-space'] - display = cs['display'] - position = cs['position'] - float = cs['float'] - visibility = cs['visibility'] - } else { - cs = this.iframe.contentWindow.getComputedStyle(n.el, null) - whitespace = cs.getPropertyValue('white-space') - display = cs.getPropertyValue('display') - position = cs.getPropertyValue('position') - float = cs.getPropertyValue('float') - visibility = cs.getPropertyValue('visibility') - } + cs = this.iframe.contentWindow.getComputedStyle(n.el, null) + whitespace = cs.getPropertyValue('white-space') + display = cs.getPropertyValue('display') + position = cs.getPropertyValue('position') + float = cs.getPropertyValue('float') + visibility = cs.getPropertyValue('visibility') if (n.name === 'textarea') { inner_flags.pre_ish = true } else { @@ -2537,27 +2510,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() {