-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackbone.vdomview.js
126 lines (115 loc) · 3.94 KB
/
backbone.vdomview.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*!
* Backbone.VDOMView
*
* MIT Licensed. Copyright (c) 2017, JC Brand <jc@opkode.com>
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([
"snabbdom",
"snabbdom-attributes",
"snabbdom-class",
"snabbdom-dataset",
"snabbdom-props",
"snabbdom-style",
"tovnode",
"underscore",
"backbone"
], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments
module.exports = factory(
require('snabbdom'),
require('snabbdom-attributes'),
require('snabbdom-class'),
require('snabbdom-dataset'),
require('snabbdom-props'),
require('snabbdom-style'),
require('tovnode'),
require('underscore'),
require('backbone')
);
}
}(this, function (
snabbdom,
snabbdom_attributes,
snabbdom_class,
snabbdom_dataset,
snabbdom_props,
snabbdom_style,
tovnode,
_,
Backbone) {
"use strict";
let domParser = new DOMParser();
const patch = snabbdom.init([
snabbdom_attributes.default,
snabbdom_class.default,
snabbdom_dataset.default,
snabbdom_props.default,
snabbdom_style.default
]);
const View = _.isUndefined(Backbone.NativeView) ? Backbone.View : Backbone.NativeView;
function parseHTMLToDOM (html_str) {
/* Parses a string with HTML and returns a DOM element.
*
* Forked from vdom_parser:
* https://github.com/bitinn/vdom-parser
*/
if (typeof html_str !== 'string') {
throw new Error('Invalid parameter type in parseHTMLToDOM');
}
if ( !('DOMParser' in window) ) {
throw new Error(
'DOMParser is not available, '+
'so parsing string to DOM node is not possible.');
}
if (!html_str) {
return document.createTextNode('');
}
domParser = domParser || new DOMParser();
const doc = domParser.parseFromString(html_str, 'text/html');
// most tags default to body
if (doc.body.firstChild) {
return doc.getElementsByTagName('body')[0].firstChild;
// some tags, like script and style, default to head
} else if (doc.head.firstChild && (doc.head.firstChild.tagName !== 'TITLE' || doc.title)) {
return doc.head.firstChild;
// special case for html comment, cdata, doctype
} else if (doc.firstChild && doc.firstChild.tagName !== 'HTML') {
return doc.firstChild;
// other element, such as whitespace, or html/body/head tag, fallback to empty text node
} else {
return document.createTextNode('');
}
}
Backbone.VDOMView = View.extend({
updateEventListeners (old_vnode, new_vnode) {
this.setElement(new_vnode.elm);
},
render () {
if (_.isFunction(this.beforeRender)) {
this.beforeRender();
}
let new_vnode;
if (!_.isNil(this.toHTML)) {
new_vnode = tovnode.toVNode(parseHTMLToDOM(this.toHTML()));
} else {
new_vnode = tovnode.toVNode(this.toDOM());
}
new_vnode.data.hook = _.extend({
create: this.updateEventListeners.bind(this),
update: this.updateEventListeners.bind(this)
});
const el = this.vnode ? this.vnode.elm : this.el;
if (el.outerHTML !== new_vnode.elm.outerHTML) {
this.vnode = patch(this.vnode || this.el, new_vnode);
}
if (_.isFunction(this.afterRender)) {
this.afterRender();
}
return this;
}
});
return Backbone.VDOMView;
}));