diff --git a/controller/Html_cleaner.py b/controller/Html_cleaner.py index bb5f4b1..5b2153e 100644 --- a/controller/Html_cleaner.py +++ b/controller/Html_cleaner.py @@ -53,7 +53,7 @@ class Html_cleaner(HTMLParser): # "on" tags, like "onhover," would not be smart. Also be very careful # of "background" and "style." self.allowed_attributes = { - 'a': [ 'href' ], + 'a': [ 'href', 'target' ], } # The only schemes allowed in URLs (for href and src attributes). diff --git a/static/js/Editor.js b/static/js/Editor.js index 686f87d..e1fac85 100644 --- a/static/js/Editor.js +++ b/static/js/Editor.js @@ -276,11 +276,19 @@ Editor.prototype.mouse_clicked = function ( event ) { if ( !link ) return; } + if ( !link.href ) return; - // ignore external links pointing outside of this wiki (indicated by the presence of a link - // target), and let the browser handle them normally - if ( !link.href || link.target ) + // links with targets are considered to be external links pointing outside of this wiki + if ( link.target ) { + // if this is a read-only editor, bail and let the browser handle the link normally + if ( !this.read_write ) return; + + // otherwise, this is a read-write editor, so we've got to launch the external link ourselves. + // note that this ignores what the link target actually contains and assumes it's "_new" + window.open( link.href ); + event.stop(); return; + } event.stop(); @@ -317,13 +325,6 @@ Editor.prototype.empty = function () { return ( scrapeText( this.document.body ).length == 0 ); } -Editor.prototype.contents = function () { - if ( !this.document.body ) - return "" - - return scrapeText( this.document.body ); -} - Editor.prototype.start_link = function () { // get the current selection, which is the link title if ( this.iframe.contentWindow && this.iframe.contentWindow.getSelection ) { // browsers such as Firefox diff --git a/static/js/Wiki.js b/static/js/Wiki.js index 0df367b..12cf5a8 100644 --- a/static/js/Wiki.js +++ b/static/js/Wiki.js @@ -189,6 +189,15 @@ Wiki.prototype.load_editor = function ( note_title, from_iframe_id, note_id, rev } } + // if the title looks like a URL, then make it a link to an external site + if ( /^\w+:\/\//.test( note_title ) ) { + link.target = "_new"; + link.href = note_title; + window.open( link.href ); + return + } + link.removeAttribute( "target" ); + // if the note corresponding to the link's id is already open, highlight it and bail, but only if // we didn't pull a title from an open link pulldown if ( !pulldown_title ) { @@ -210,7 +219,7 @@ Wiki.prototype.load_editor = function ( note_title, from_iframe_id, note_id, rev // if there's not a valid destination note id, then load by title instead of by id var self = this; - if ( note_id == "new" || note_id == "null" ) { + if ( note_id == undefined || note_id == "new" || note_id == "null" ) { this.invoker.invoke( "/notebooks/load_note_by_title", "GET", { "notebook_id": this.notebook_id, @@ -233,11 +242,19 @@ Wiki.prototype.load_editor = function ( note_title, from_iframe_id, note_id, rev } Wiki.prototype.resolve_link = function ( note_title, link, callback ) { + // if the title looks like a URL, then make it a link to an external site + if ( /^\w+:\/\//.test( note_title ) ) { + link.target = "_new"; + link.href = note_title; + if ( callback ) callback( "web link" ); + return + } + link.removeAttribute( "target" ); + var id = parse_query( link ).note_id; - if ( !id ) return; // if the link already has a valid-looking id, it's already resolved, so bail - if ( !callback && id != "new" && id != "null" ) + if ( !callback && id != undefined && id != "new" && id != "null" ) return; if ( note_title.length == 0 ) @@ -920,7 +937,7 @@ function Link_pulldown( wiki, notebook_id, invoker, editor, link ) { this.invoker = invoker; this.editor = editor; - this.title_field = createDOM( "input", { "class": "text_field", "size": "25", "maxlength": "256" } ); + this.title_field = createDOM( "input", { "class": "text_field", "size": "30", "maxlength": "256" } ); this.note_preview = createDOM( "span", {} ); this.previous_title = ""; @@ -934,11 +951,18 @@ function Link_pulldown( wiki, notebook_id, invoker, editor, link ) { appendChildNodes( this.div, this.title_field ); appendChildNodes( this.div, this.note_preview ); + // links with targets are considered links to external sites + if ( link.target ) { + self.title_field.value = link.href; + replaceChildNodes( self.note_preview, "web link" ); + return; + } + // if the note has no destination note id set, try loading the note from the server by title var query = parse_query( link ); var title = link_title( link, query ); var id = query.note_id; - if ( ( id == "new" || id == "null" ) && title.length > 0 ) { + if ( ( id == undefined || id == "new" || id == "null" ) && title.length > 0 ) { this.invoker.invoke( "/notebooks/load_note_by_title", "GET", { "notebook_id": this.notebook_id,