mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-14 10:52:41 +01:00
137 lines
2.9 KiB
JavaScript
137 lines
2.9 KiB
JavaScript
|
/**
|
||
|
* Dumb HTML views. Mostly to demonstrate how the visitor pattern over these
|
||
|
* views works, as driven by validation. I'm not convinced it's actually a good
|
||
|
* idea to do validation.
|
||
|
*
|
||
|
* @provides javelin-view-html
|
||
|
* @requires javelin-install
|
||
|
* javelin-view
|
||
|
*/
|
||
|
|
||
|
JX.install('HTMLView', {
|
||
|
extend: 'View',
|
||
|
members : {
|
||
|
render: function(rendered_children) {
|
||
|
return JX.$N(this.getName(), this.getAllAttributes(), rendered_children);
|
||
|
},
|
||
|
validate: function() {
|
||
|
this.accept(JX.HTMLView.getValidatingVisitor());
|
||
|
}
|
||
|
},
|
||
|
|
||
|
statics: {
|
||
|
getValidatingVisitor: function() {
|
||
|
return new JX.ViewVisitor(JX.HTMLView.validate);
|
||
|
},
|
||
|
|
||
|
validate: function(view, children) {
|
||
|
var spec = this._getHTMLSpec();
|
||
|
if (!view.getName() in spec) {
|
||
|
throw new Error("invalid tag");
|
||
|
}
|
||
|
|
||
|
var tag_spec = spec[view.getName()];
|
||
|
|
||
|
var attrs = view.getAllAttributes();
|
||
|
for (var attr in attrs) {
|
||
|
if (!(attr in tag_spec)) {
|
||
|
throw new Error("invalid attr");
|
||
|
}
|
||
|
|
||
|
var validator = tag_spec[attr];
|
||
|
if (typeof validator === "function") {
|
||
|
return validator(attrs[attr]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
},
|
||
|
|
||
|
_validateRel: function(target) {
|
||
|
return target in {
|
||
|
"_blank": 1,
|
||
|
"_self": 1,
|
||
|
"_parent": 1,
|
||
|
"_top": 1
|
||
|
};
|
||
|
},
|
||
|
_getHTMLSpec: function() {
|
||
|
var attrs_any_can_have = {
|
||
|
className: 1,
|
||
|
id: 1,
|
||
|
sigil: 1
|
||
|
};
|
||
|
|
||
|
var form_elem_attrs = {
|
||
|
name: 1,
|
||
|
value: 1
|
||
|
};
|
||
|
|
||
|
var spec = {
|
||
|
a: { href: 1, target: JX.HTMLView._validateRel },
|
||
|
b: {},
|
||
|
blockquote: {},
|
||
|
br: {},
|
||
|
button: JX.copy({}, form_elem_attrs),
|
||
|
canvas: {},
|
||
|
code: {},
|
||
|
dd: {},
|
||
|
div: {},
|
||
|
dl: {},
|
||
|
dt: {},
|
||
|
em: {},
|
||
|
embed: {},
|
||
|
fieldset: {},
|
||
|
form: { type: 1 },
|
||
|
h1: {},
|
||
|
h2: {},
|
||
|
h3: {},
|
||
|
h4: {},
|
||
|
h5: {},
|
||
|
h6: {},
|
||
|
hr: {},
|
||
|
i: {},
|
||
|
iframe: { src: 1 },
|
||
|
img: { src: 1, alt: 1 },
|
||
|
input: JX.copy({}, form_elem_attrs),
|
||
|
label: {'for': 1},
|
||
|
li: {},
|
||
|
ol: {},
|
||
|
optgroup: {},
|
||
|
option: JX.copy({}, form_elem_attrs),
|
||
|
p: {},
|
||
|
pre: {},
|
||
|
q: {},
|
||
|
select: {},
|
||
|
span: {},
|
||
|
strong: {},
|
||
|
sub: {},
|
||
|
sup: {},
|
||
|
table: {},
|
||
|
tbody: {},
|
||
|
td: {},
|
||
|
textarea: {},
|
||
|
tfoot: {},
|
||
|
th: {},
|
||
|
thead: {},
|
||
|
tr: {},
|
||
|
ul: {}
|
||
|
};
|
||
|
|
||
|
for (var k in spec) {
|
||
|
JX.copy(spec[k], attrs_any_can_have);
|
||
|
}
|
||
|
|
||
|
return spec;
|
||
|
},
|
||
|
registerToInterpreter: function(view_interpreter) {
|
||
|
var spec = this._getHTMLSpec();
|
||
|
for (var tag in spec) {
|
||
|
view_interpreter.register(tag, JX.HTMLView);
|
||
|
}
|
||
|
return view_interpreter;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|