From ac7a5afe372ae7e61211d8d5368c972d6726c3c4 Mon Sep 17 00:00:00 2001 From: josdejong Date: Thu, 2 May 2013 21:42:39 +0200 Subject: [PATCH] Navigable url is now a real anchor when mode=view. Some fixes in click and enter events. --- changelog.txt | 1 + jsoneditor/css/jsoneditor.css | 7 +++- jsoneditor/js/node.js | 75 ++++++++++++++++------------------- jsoneditor/js/treeeditor.js | 10 ++++- jsoneditor/js/util.js | 6 +-- 5 files changed, 53 insertions(+), 46 deletions(-) diff --git a/changelog.txt b/changelog.txt index 09b6d7e..90e8f18 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,6 +5,7 @@ http://jsoneditoronline.org ## not yet released, version 2.2.0 - Unified JSONFormatter and JSONEditor in one editor with a switchable mode. +- Urls are navigable now. ## 2013-03-11, version 2.1.1 diff --git a/jsoneditor/css/jsoneditor.css b/jsoneditor/css/jsoneditor.css index c707c81..ba68494 100644 --- a/jsoneditor/css/jsoneditor.css +++ b/jsoneditor/css/jsoneditor.css @@ -43,8 +43,13 @@ } .jsoneditor .value.url { + color: green; text-decoration: underline; - cursor: pointer; +} + +.jsoneditor a.value.url:hover, +.jsoneditor a.value.url:focus { + color: red; } .jsoneditor .separator { diff --git a/jsoneditor/js/node.js b/jsoneditor/js/node.js index 0b595e9..52cc15f 100644 --- a/jsoneditor/js/node.js +++ b/jsoneditor/js/node.js @@ -973,8 +973,12 @@ Node.prototype._updateDomValue = function () { // TODO: put colors in css var v = this.value; var t = (this.type == 'auto') ? typeof(v) : this.type; + var isUrl = (t == 'string' && util.isUrl(v)); var color = ''; - if (t == 'string') { + if (isUrl && !this.editor.mode.edit) { + color = ''; + } + else if (t == 'string') { color = 'green'; } else if (t == 'number') { @@ -1006,7 +1010,7 @@ Node.prototype._updateDomValue = function () { } // underline url - if (t == 'string' && util.isUrl(v)) { + if (isUrl) { util.addClassName(domValue, 'url'); } else { @@ -1019,10 +1023,7 @@ Node.prototype._updateDomValue = function () { domValue.title = this.type + ' containing ' + count + ' items'; } else if (t == 'string' && util.isUrl(v)) { - if (this.editor.mode.view) { - domValue.title = 'Click to open url in new window'; - } - else { + if (this.editor.mode.edit) { domValue.title = 'Ctrl+Click or Ctrl+Enter to open url in new window'; } } @@ -1606,24 +1607,25 @@ Node.prototype._createDomValue = function () { domValue.className = 'readonly'; domValue.innerHTML = '{...}'; } - else if (this.type == 'string') { - domValue = document.createElement('div'); - domValue.contentEditable = !this.editor.mode.view; - domValue.spellcheck = false; - domValue.className = 'value'; - domValue.innerHTML = this._escapeHTML(this.value); - } else { - domValue = document.createElement('div'); - domValue.contentEditable = !this.editor.mode.view; - domValue.spellcheck = false; - domValue.className = 'value'; - domValue.innerHTML = this._escapeHTML(this.value); + if (!this.editor.mode.edit && util.isUrl(this.value)) { + // create a link in case of read-only editor and value containing an url + domValue = document.createElement('a'); + domValue.className = 'value'; + domValue.href = this.value; + domValue.target = '_blank'; + domValue.innerHTML = this._escapeHTML(this.value); + } + else { + // create and editable or read-only div + domValue = document.createElement('div'); + domValue.contentEditable = !this.editor.mode.view; + domValue.spellcheck = false; + domValue.className = 'value'; + domValue.innerHTML = this._escapeHTML(this.value); + } } - // TODO: in FF spel/check of editable divs is done via the body. quite ugly - // document.body.spellcheck = false; - return domValue; }; @@ -1780,7 +1782,11 @@ Node.prototype.onEvent = function (event) { break; case 'click': - this._onOpenUrl(event); + if (event.ctrlKey && this.editor.mode.edit) { + if (util.isUrl(this.value)) { + window.open(this.value, '_blank'); + } + } break; case 'keyup': @@ -1897,9 +1903,13 @@ Node.prototype.onKeyDown = function (event) { // console.log(ctrlKey, keynum, event.charCode); // TODO: cleanup if (keynum == 13) { // Enter - if (target == this.dom.value && (ctrlKey || this.editor.mode.view)) { - this._onOpenUrl(event); - handled = true; + if (target == this.dom.value) { + if (!this.editor.mode.edit || event.ctrlKey) { + if (util.isUrl(this.value)) { + window.open(this.value, '_blank'); + handled = true; + } + } } } else if (keynum == 68) { // D @@ -2069,21 +2079,6 @@ Node.prototype.onKeyDown = function (event) { } }; -/** - * Check whether to open an url on click - * @param {Event} event - * @private - */ -Node.prototype._onOpenUrl = function (event) { - event = event || window.event; - if (event.ctrlKey || this.editor.mode.view) { - if (util.isUrl(this.value)) { - // open url - window.open(this.value, '_blank'); - } - } -}; - /** * Handle the expand event, when clicked on the expand button * @param {boolean} recurse If true, child nodes will be expanded too diff --git a/jsoneditor/js/treeeditor.js b/jsoneditor/js/treeeditor.js index 16a4248..0ce0145 100644 --- a/jsoneditor/js/treeeditor.js +++ b/jsoneditor/js/treeeditor.js @@ -492,10 +492,16 @@ TreeEditor.prototype._createFrame = function () { editor._onEvent(event); }; this.frame.onclick = function (event) { + event = event || window.event; + var target = event.target || event.srcElement; + onEvent(event); - // prevent default submit action when TreeEditor is located inside a form - util.preventDefault(event); + // prevent default submit action of buttons when TreeEditor is located + // inside a form + if (target.nodeName == 'BUTTON') { + util.preventDefault(event); + } }; this.frame.oninput = onEvent; this.frame.onchange = onEvent; diff --git a/jsoneditor/js/util.js b/jsoneditor/js/util.js index 77bb40f..1b98d76 100644 --- a/jsoneditor/js/util.js +++ b/jsoneditor/js/util.js @@ -113,11 +113,11 @@ util.clear = function (a) { }; /** - * Test whether a text contains a url (matches true when a string starts with - * 'http://*' or 'https://*' + * Test whether a text contains a url (matches when a string starts + * with 'http://*' or 'https://*' and has no whitespace characters) * @param {String} text */ -var isUrlRegex = /^https?:\/\/(?!$)/; +var isUrlRegex = /^https?:\/\/\S+$/; util.isUrl = function (text) { return (typeof text == 'string' || text instanceof String) && isUrlRegex.test(text);