updates for html parsing, request handling, and editable elements

This commit is contained in:
rlx 2011-10-27 18:50:23 +00:00
parent a949ad2cf4
commit 62f8a907ea
6 changed files with 153 additions and 69 deletions

View file

@ -14,6 +14,9 @@ a:hover {
text-decoration: underline; text-decoration: underline;
cursor: pointer; cursor: pointer;
} }
blockquote {
margin: 0 1.5em 0 1.5em;
}
body { body {
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
@ -30,11 +33,26 @@ div, input, textarea {
font-family: Lucida Grande, Segoe UI, DejaVu Sans, Arial; font-family: Lucida Grande, Segoe UI, DejaVu Sans, Arial;
font-size: 11px; font-size: 11px;
} }
h1 {
margin: 0;
font-size: 16px;
font-weight: normal;
}
img { img {
-moz-user-drag: none; -moz-user-drag: none;
-o-user-drag: none; -o-user-drag: none;
-webkit-user-drag: none; -webkit-user-drag: none;
} }
ol, ul {
padding-left: 1.5em;
margin: 0;
}
p:first-child {
margin-top: 0;
}
p:last-child {
margin-bottom: 0;
}
td { td {
padding: 0; padding: 0;
} }

View file

@ -125,10 +125,9 @@ Ox.Request = function(options) {
} else { } else {
pending[options.id] = true; pending[options.id] = true;
$.ajax({ $.ajax({
complete: complete,
data: options.data, data: options.data,
dataType: 'json', //dataType: 'json',
error: error,
success: success,
timeout: options.timeout, timeout: options.timeout,
type: options.type, type: options.type,
url: options.url url: options.url
@ -172,37 +171,66 @@ Ox.Request = function(options) {
iframe.close(); iframe.close();
} }
function error(request, status, error) { function complete(request) {
var data; var data;
if (arguments.length == 1) { try {
data = arguments[0] data = JSON.parse(request.responseText);
} else { } catch (err) {
try { try {
data = JSON.parse(request.responseText); data = {
status: {
code: request.status,
text: request.statusText
}
};
} catch (err) { } catch (err) {
try { data = {
data = { status: {
status: { code: '500',
code: request.status, text: 'Unknown Error'
text: request.statusText }
} };
};
} catch (err) {
data = {
status: {
code: '500',
text: 'Unknown Error'
}
};
}
} }
} }
if (data.status.code && data.status.code < 500) { if (data.status.code == 200) {
// 0 is timeout cache[req] = {
data: data,
time: Ox.getTime()
};
callback(data); callback(data);
} else { } else if (data.status.code >= 400 && data.status.code < 500) {
var $dialog = Ox.Dialog({
buttons: [
Ox.Button({
id: 'close',
title: 'Close'
})
.bindEvent({
click: function() {
$dialog.close();
}
})
],
content: Ox.Element()
.append(
$('<img>')
.attr({src: Ox.UI.PATH + 'png/icon128.png'})
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
)
.append(
Ox.Element()
.css({position: 'absolute', left: '96px', top: '16px', width: '256px'})
.html('Sorry, you have made an unauthorized request.')
),
height: 192,
keys: {enter: 'close', escape: 'close'},
title: Ox.toTitleCase(data.status.text),
width: 368
})
.open();
} else {
// 0 (timeout) or 500 (error)
var $dialog = Ox.Dialog({ var $dialog = Ox.Dialog({
title: 'Application Error',
buttons: [ buttons: [
Ox.Button({ Ox.Button({
id: 'details', id: 'details',
@ -238,28 +266,15 @@ Ox.Request = function(options) {
), ),
height: 192, height: 192,
keys: {enter: 'close', escape: 'close'}, keys: {enter: 'close', escape: 'close'},
title: 'Application Error',
width: 368 width: 368
}) })
.open(); .open();
// fixme: change this to Send / Don't Send // fixme: change this to Send / Don't Send
/*Ox.print({
request: request,
status: status,
error: error
});*/
} }
pending[options.id] = false; pending[options.id] = false;
} }
function success(data) {
pending[options.id] = false;
cache[req] = {
data: data,
time: Ox.getTime()
};
callback(data);
}
// return dfd.promise(); // return dfd.promise();
return options.id; return options.id;

View file

@ -18,12 +18,11 @@ Ox.Editable = function(options, self) {
tooltip: options.tooltip tooltip: options.tooltip
}, self) }, self)
.defaults({ .defaults({
clickLink: function(e) { clickLink: null,
document.location.href = $(e.target).attr('href');
},
editable: true, editable: true,
editing: false, editing: false,
format: null, format: null,
height: 0,
placeholder: '', placeholder: '',
tooltip: '', tooltip: '',
value: '', value: '',
@ -33,16 +32,20 @@ Ox.Editable = function(options, self) {
.options(options || {}) .options(options || {})
.addClass('OxEditableElement') .addClass('OxEditableElement')
.bind({ .bind({
click: function(e) { click: function() {
if ($(e.target).is('a')) { return false;
return false;
}
} }
}) })
.bindEvent({ .bindEvent({
doubleclick: edit, doubleclick: edit,
singleclick: function(e) { singleclick: function(e) {
$(e.target).is('a') && self.options.clickLink(e); if ($(e.target).is('a')) {
if (self.options.clickLink) {
self.options.clickLink(e);
} else {
document.location.href = $(e.target).attr('href');
}
}
} }
}); });
@ -56,8 +59,9 @@ Ox.Editable = function(options, self) {
//border: '1px solid transparent' //border: '1px solid transparent'
} : { } : {
//padding: '0 4px 0 4px' //padding: '0 4px 0 4px'
width: self.options.width + 'px' //width: self.options.width + 'px'
}) })
//.css({background: 'red'})
.html(formatValue()) .html(formatValue())
//[self.options.editing ? 'hide' : 'show']() //[self.options.editing ? 'hide' : 'show']()
.appendTo(that); .appendTo(that);
@ -112,10 +116,11 @@ Ox.Editable = function(options, self) {
function change(event) { function change(event) {
var height, width; var height, width;
self.options.value = event.value; self.options.value = event.value;
self.$value.html(formatValue); self.$value.html(formatValue());
self.$test.html(formatTestValue()); self.$test.html(formatTestValue());
height = self.options.height || self.$test.height(); //height = self.options.height || Ox.limit(self.$test.height() + 2, self.minHeight, self.maxHeight);
width = self.options.width || Ox.limit(self.$test.width() + 2, self.minWidth, self.maxWidth) height = self.options.height || Math.max(self.$test.height() + 2, self.minHeight);
width = self.options.width || Ox.limit(self.$test.width() + 2, self.minWidth, self.maxWidth);
Ox.print(self.options.width, self.$test.width(), 'wxh', width, height) Ox.print(self.options.width, self.$test.width(), 'wxh', width, height)
if (self.options.type == 'input') { if (self.options.type == 'input') {
self.$input.options({ self.$input.options({
@ -146,14 +151,16 @@ Ox.Editable = function(options, self) {
var height, width; var height, width;
if (self.options.editable && !self.options.editing) { if (self.options.editable && !self.options.editing) {
self.originalValue = self.options.value; self.originalValue = self.options.value;
self.minWidth = 8 self.minWidth = 8;
self.maxWidth = that.parent().width(); self.maxWidth = that.parent().width();
Ox.print('MAX WIDTH', self.maxWidth); self.minHeight = 14;
self.maxHeight = that.parent().height();
height = self.options.height || self.$value.height(); height = self.options.height || self.$value.height();
width = self.$value.width(); width = self.options.width || self.$value.width();
self.$value.hide(); self.$value.hide();
//self.$test.show();
Ox.print('HEIGHT', height) Ox.print("H:::", self.options.height, self.maxHeight, height)
self.$input.options({ self.$input.options({
height: height, height: height,
width: width width: width
@ -179,9 +186,11 @@ Ox.Editable = function(options, self) {
} }
function formatInputValue() { function formatInputValue() {
return self.options.type == 'input' return Ox.decodeHTML(
? self.options.value self.options.type == 'input'
: self.options.value.replace(/<br\/?>/g, '\n'); ? self.options.value
: self.options.value.replace(/<br\/?><br\/?>/g, '\n\n')
);
} }
function formatTestValue() { function formatTestValue() {

View file

@ -288,11 +288,31 @@
'äbçdê' 'äbçdê'
> Ox.decodeHTML('&#x00E4;b&#x00E7;d&#x00EA;') > Ox.decodeHTML('&#x00E4;b&#x00E7;d&#x00EA;')
'äbçdê' 'äbçdê'
> Ox.decodeHTML('<b>bold</b>')
'<b>bold</b>'
@*/ @*/
Ox.decodeHTML = function(str) { Ox.decodeHTML = function(str) {
// relies on dom, but shorter than using this: // relies on dom, but shorter than using this:
// http://www.w3.org/TR/html5/named-character-references.html // http://www.w3.org/TR/html5/named-character-references.html
return Ox.element('<div>').html(str)[0].childNodes[0].nodeValue; return Ox.decodeHTMLEntities(Ox.element('<div>').html(str).html());
};
Ox.encodeHTMLEntities = function(str) {
return str.replace(
new RegExp('(' + Object.keys(Ox.HTML_ENTITIES).join('|') + ')', 'g'),
function(match) {
return Ox.HTML_ENTITIES[match];
}
);
};
Ox.decodeHTMLEntities = function(str) {
return str.replace(
new RegExp('(' + Ox.values(Ox.HTML_ENTITIES).join('|') + ')', 'g'),
function(match) {
return Ox.keyOf(Ox.HTML_ENTITIES, match);
}
);
}; };
/*@ /*@

View file

@ -37,15 +37,22 @@ Ox.parseHTML <f> Takes HTML from an untrusted source and returns something sane
Ox.parseHTML = (function() { Ox.parseHTML = (function() {
var defaultTags = [ var defaultTags = [
'a', 'b', 'blockquote', 'br', 'cite', 'code', // inline formatting
'del', 'em', 'i', 'img', 'ins', 'b', 'code', 'i', 'q', 's', 'sub', 'sup', 'u',
'li', 'ol', 'p', 'q', 'rtl', // block
's', 'strong', 'sub', 'sup', 'blockquote', 'h1', 'p', 'pre',
'table', 'tbody', 'td', 'th', 'tr', 'ul', '[]' // lists
'li', 'ol', 'ul',
// tables
'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr',
// other
'a', 'br', 'img',
// special
'rtl', '[]'
], ],
parse = { parse = {
a: { a: {
'<a [^<>]*?href="(https?:\/\/.+?)".*?>': '<a href="{1}" title="{1}">', '<a [^<>]*?href="((https?:\/\/|\/).+?)".*?>': '<a href="{1}" title="{1}">',
'<\/a>': '</a>' '<\/a>': '</a>'
}, },
img: { img: {
@ -90,7 +97,7 @@ Ox.parseHTML = (function() {
html = html.replace(new RegExp(tab + i + tab, 'gi'), match); html = html.replace(new RegExp(tab + i + tab, 'gi'), match);
}); });
//html = html.replace(/\n/g, '<br/>\n'); //html = html.replace(/\n/g, '<br/>\n');
html = html.replace(/\n/g, '<br/>'); html = html.replace(/\n\n/g, '<br/><br/>');
// close extra opening (and remove extra closing) tags // close extra opening (and remove extra closing) tags
// note: this converts '&quot;' to '"' // note: this converts '&quot;' to '"'
return Ox.element('<div>').html(html).html(); return Ox.element('<div>').html(html).html();

View file

@ -14,6 +14,21 @@ Ox.extend = function() {
return obj; return obj;
}; };
/*@
Ox.keyOf <f> undocumented
@*/
Ox.keyOf = function(obj, val) {
var key;
Ox.forEach(obj, function(v, k) {
if (v == val) {
key = k;
return false;
}
});
return key;
};
/*@ /*@
Ox.serialize <f> Parses an object into query parameters Ox.serialize <f> Parses an object into query parameters
> Ox.serialize({a: 1, b: 2, c: 3}) > Ox.serialize({a: 1, b: 2, c: 3})