Navigable url is now a real anchor when mode=view. Some fixes in click and enter events.

This commit is contained in:
josdejong 2013-05-02 21:42:39 +02:00
parent 77291ac62b
commit ac7a5afe37
5 changed files with 53 additions and 46 deletions

View File

@ -5,6 +5,7 @@ http://jsoneditoronline.org
## not yet released, version 2.2.0 ## not yet released, version 2.2.0
- Unified JSONFormatter and JSONEditor in one editor with a switchable mode. - Unified JSONFormatter and JSONEditor in one editor with a switchable mode.
- Urls are navigable now.
## 2013-03-11, version 2.1.1 ## 2013-03-11, version 2.1.1

View File

@ -43,8 +43,13 @@
} }
.jsoneditor .value.url { .jsoneditor .value.url {
color: green;
text-decoration: underline; text-decoration: underline;
cursor: pointer; }
.jsoneditor a.value.url:hover,
.jsoneditor a.value.url:focus {
color: red;
} }
.jsoneditor .separator { .jsoneditor .separator {

View File

@ -973,8 +973,12 @@ Node.prototype._updateDomValue = function () {
// TODO: put colors in css // TODO: put colors in css
var v = this.value; var v = this.value;
var t = (this.type == 'auto') ? typeof(v) : this.type; var t = (this.type == 'auto') ? typeof(v) : this.type;
var isUrl = (t == 'string' && util.isUrl(v));
var color = ''; var color = '';
if (t == 'string') { if (isUrl && !this.editor.mode.edit) {
color = '';
}
else if (t == 'string') {
color = 'green'; color = 'green';
} }
else if (t == 'number') { else if (t == 'number') {
@ -1006,7 +1010,7 @@ Node.prototype._updateDomValue = function () {
} }
// underline url // underline url
if (t == 'string' && util.isUrl(v)) { if (isUrl) {
util.addClassName(domValue, 'url'); util.addClassName(domValue, 'url');
} }
else { else {
@ -1019,10 +1023,7 @@ Node.prototype._updateDomValue = function () {
domValue.title = this.type + ' containing ' + count + ' items'; domValue.title = this.type + ' containing ' + count + ' items';
} }
else if (t == 'string' && util.isUrl(v)) { else if (t == 'string' && util.isUrl(v)) {
if (this.editor.mode.view) { if (this.editor.mode.edit) {
domValue.title = 'Click to open url in new window';
}
else {
domValue.title = 'Ctrl+Click or Ctrl+Enter to open url in new window'; 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.className = 'readonly';
domValue.innerHTML = '{...}'; 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 { else {
domValue = document.createElement('div'); if (!this.editor.mode.edit && util.isUrl(this.value)) {
domValue.contentEditable = !this.editor.mode.view; // create a link in case of read-only editor and value containing an url
domValue.spellcheck = false; domValue = document.createElement('a');
domValue.className = 'value'; domValue.className = 'value';
domValue.innerHTML = this._escapeHTML(this.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; return domValue;
}; };
@ -1780,7 +1782,11 @@ Node.prototype.onEvent = function (event) {
break; break;
case 'click': case 'click':
this._onOpenUrl(event); if (event.ctrlKey && this.editor.mode.edit) {
if (util.isUrl(this.value)) {
window.open(this.value, '_blank');
}
}
break; break;
case 'keyup': case 'keyup':
@ -1897,9 +1903,13 @@ Node.prototype.onKeyDown = function (event) {
// console.log(ctrlKey, keynum, event.charCode); // TODO: cleanup // console.log(ctrlKey, keynum, event.charCode); // TODO: cleanup
if (keynum == 13) { // Enter if (keynum == 13) { // Enter
if (target == this.dom.value && (ctrlKey || this.editor.mode.view)) { if (target == this.dom.value) {
this._onOpenUrl(event); if (!this.editor.mode.edit || event.ctrlKey) {
handled = true; if (util.isUrl(this.value)) {
window.open(this.value, '_blank');
handled = true;
}
}
} }
} }
else if (keynum == 68) { // D 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 * Handle the expand event, when clicked on the expand button
* @param {boolean} recurse If true, child nodes will be expanded too * @param {boolean} recurse If true, child nodes will be expanded too

View File

@ -492,10 +492,16 @@ TreeEditor.prototype._createFrame = function () {
editor._onEvent(event); editor._onEvent(event);
}; };
this.frame.onclick = function (event) { this.frame.onclick = function (event) {
event = event || window.event;
var target = event.target || event.srcElement;
onEvent(event); onEvent(event);
// prevent default submit action when TreeEditor is located inside a form // prevent default submit action of buttons when TreeEditor is located
util.preventDefault(event); // inside a form
if (target.nodeName == 'BUTTON') {
util.preventDefault(event);
}
}; };
this.frame.oninput = onEvent; this.frame.oninput = onEvent;
this.frame.onchange = onEvent; this.frame.onchange = onEvent;

View File

@ -113,11 +113,11 @@ util.clear = function (a) {
}; };
/** /**
* Test whether a text contains a url (matches true when a string starts with * Test whether a text contains a url (matches when a string starts
* 'http://*' or 'https://*' * with 'http://*' or 'https://*' and has no whitespace characters)
* @param {String} text * @param {String} text
*/ */
var isUrlRegex = /^https?:\/\/(?!$)/; var isUrlRegex = /^https?:\/\/\S+$/;
util.isUrl = function (text) { util.isUrl = function (text) {
return (typeof text == 'string' || text instanceof String) && return (typeof text == 'string' || text instanceof String) &&
isUrlRegex.test(text); isUrlRegex.test(text);