diff --git a/static/css/style.css b/static/css/style.css index 674370a..aebb2e6 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -552,6 +552,10 @@ h1 { overflow-x: auto; } +.focused_note_frame { + border: 2px solid black; +} + .static_note_contents { font-size: 90%; line-height: 140%; diff --git a/static/js/Editor.js b/static/js/Editor.js index ed9b862..cf90083 100644 --- a/static/js/Editor.js +++ b/static/js/Editor.js @@ -130,13 +130,13 @@ Editor.prototype.create_iframe = function ( position_after ) { this.iframe = createDOM( "iframe", { // iframe src attribute is necessary in IE 6 on an HTTPS site to prevent annoying warnings - //"src": "/static/html/blank_note.html", + "src": "about:blank", "frameBorder": "0", "scrolling": "no", "id": iframe_id, "name": iframe_id, - "class": "note_frame", - "onresize": function () { setTimeout( function () { self.resize() }, 50 ); } + "class": "note_frame invisible", + "onresize": function () { setTimeout( function () { self.resize() }, 50 ); }, } ); this.iframe.editor = this; @@ -148,14 +148,33 @@ Editor.prototype.create_iframe = function ( position_after ) { this.connect_note_controls( true ); disconnectAll( this.div ); + addElementClass( static_note, "focused_note_frame" ); - swapDOM( static_note, this.iframe ); + var frame_height = elementDimensions( static_note ).h; + insertSiblingNodesAfter( static_note, this.iframe ); + + // give the invisible iframe the exact same position as the div it will replace + setStyle( this.iframe, { "position": "fixed" } ); + setElementPosition( this.iframe, getElementPosition( static_note ) ); + + // give the iframe the note's current contents and then resize it based on the size of the div + this.set_iframe_contents( this.contents() ); + this.resize( frame_height ); + + // make the completed iframe visible, and now remove the static div + removeElementClass( this.iframe, "invisible" ); + removeElement( static_note ); + + // set the iframe positioning back to standard static positioning and move the note controls + setStyle( this.iframe, { "position": "static" } ); insertSiblingNodesBefore( this.iframe, this.note_controls ); - this.init_iframe(); + // finally, turn on design mode so the iframe is editable + this.enable_design_mode(); this.div = null; } else { + // TODO: rewrite this portion of the function as above this.create_note_controls(); this.connect_note_controls(); @@ -169,12 +188,61 @@ Editor.prototype.create_iframe = function ( position_after ) { else appendChildNodes( "notes", note_holder ); - this.init_iframe(); + this.set_iframe_contents( this.contents() ); + this.enable_design_mode(); } this.finish_init(); } +Editor.prototype.set_iframe_contents = function ( contents_text ) { + if ( this.iframe.contentDocument ) { // browsers such as Firefox + this.document = this.iframe.contentDocument; + } else { // browsers such as IE + this.document = this.iframe.contentWindow.document; + } + + this.document.open(); + if ( !contents_text ) { + // hack: add a zero-width space to make the horizontal line under title show up in the + // correct position, even before there is a title + contents_text = "

​"; + } + + this.document.write( + '' + + '' + contents_text + '' + ); + this.document.close(); +} + +Editor.prototype.enable_design_mode = function () { + if ( this.iframe.contentDocument ) { // browsers such as Firefox + if ( this.edit_enabled ) + this.document.designMode = "On"; + } else { // browsers such as IE + if ( this.edit_enabled ) { + this.document.designMode = "On"; + // work-around for IE bug: reget the document after designMode is turned on + this.document = this.iframe.contentWindow.document; + } + } + + // move the text cursor to the end of the text + if ( this.iframe.contentWindow && this.iframe.contentWindow.getSelection ) { // browsers such as Firefox + var selection = this.iframe.contentWindow.getSelection(); + var last_node = this.document.body.lastChild; + if ( last_node.nodeValue == "\n" && last_node.previousSibling ) + last_node = last_node.previousSibling; + + selection.selectAllChildren( last_node ); + selection.collapseToEnd(); + } else if ( this.document.selection ) { // browsers such as IE + // TODO: finish this for IE + var range = this.document.selection.createRange(); + } +} + Editor.prototype.create_div = function ( position_after ) { var self = this; @@ -227,56 +295,6 @@ Editor.prototype.create_div = function ( position_after ) { signal( self, "init_complete" ); } -Editor.prototype.init_iframe = function () { - var self = this; // necessary so that the member functions of this editor object are used - - if ( this.iframe.contentDocument ) { // browsers such as Firefox - this.document = this.iframe.contentDocument; - - if ( this.edit_enabled ) - this.document.designMode = "On"; - -// setTimeout( function () { self.finish_init(); }, 1 ); - } else { // browsers such as IE - this.document = this.iframe.contentWindow.document; - - if ( this.edit_enabled ) { - this.document.designMode = "On"; - // work-around for IE bug: reget the document after designMode is turned on - this.document = this.iframe.contentWindow.document; - } -// setTimeout( function () { self.finish_init(); }, 100 ); - } - - this.document.open(); - var contents_text = this.contents(); - if ( !contents_text ) { - // hack: add a zero-width space to make the horizontal line under title show up in the - // correct position, even before there is a title - contents_text = "

​"; - } - - this.document.write( - '' + - '' + contents_text + '' - ); - this.document.close(); - - // move the text cursor to the end of the text - if ( this.iframe.contentWindow && this.iframe.contentWindow.getSelection ) { // browsers such as Firefox - var selection = this.iframe.contentWindow.getSelection(); - var last_node = this.document.body.lastChild; - if ( last_node.nodeValue == "\n" && last_node.previousSibling ) - last_node = last_node.previousSibling; - - selection.selectAllChildren( last_node ); - selection.collapseToEnd(); - } else if ( this.document.selection ) { // browsers such as IE - // TODO: finish this for IE - var range = this.document.selection.createRange(); - } -} - Editor.prototype.finish_init = function () { // since the browser may subtly tweak the html when it's inserted, save off the browser's version // of the html here. this yields more accurate comparisons within the dirty() method @@ -336,7 +354,6 @@ Editor.prototype.finish_init = function () { this.exec_command( "insertbronreturn", true ); } - this.resize(); if ( this.init_highlight ) self.highlight(); this.scrape_title(); @@ -420,21 +437,25 @@ Editor.prototype.query_command_value = function ( command ) { } // resize the editor's frame to fit the dimensions of its content -Editor.prototype.resize = function () { +Editor.prototype.resize = function ( height ) { if ( !this.document ) return; + var FRAME_BORDER_HEIGHT = 4; // 2 pixels at the top and 2 at the bottom - var height; - - if ( WEBKIT ) { - var self = this; - withDocument( this.document, function () { - var body = getFirstElementByTagAndClassName( "body" ); - height = elementDimensions( body ).h; - } ); - } else if ( this.iframe.contentDocument ) { // Gecko and other sane browsers - height = elementDimensions( this.document.documentElement ).h; - } else { // IE - height = this.document.body.scrollHeight; + if ( height ) { + height -= FRAME_BORDER_HEIGHT; + // if no height is given, get the height from this editor's document body + } else { + if ( WEBKIT ) { + var self = this; + withDocument( this.document, function () { + var body = getFirstElementByTagAndClassName( "body" ); + height = elementDimensions( body ).h; + } ); + } else if ( this.iframe.contentDocument ) { // Gecko and other sane browsers + height = elementDimensions( this.document.documentElement ).h; + } else { // IE + height = this.document.body.scrollHeight; + } } setElementDimensions( this.iframe, { "h": height } );