-
Notifications
You must be signed in to change notification settings - Fork 26
/
client.coffee
109 lines (84 loc) · 3.67 KB
/
client.coffee
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
propagateUIHooks = (parent, node) ->
return if not parent._uihooks or node._uihooks
node._uihooks = _.extend {}, parent._uihooks, parentNode: node
return unless node.hasChildNodes()
for childNode in node.childNodes when childNode.nodeType is Node.ELEMENT_NODE
propagateUIHooks node, childNode
# To optimize.
return
originalInsertNodeWithHooks = Blaze._DOMRange._insertNodeWithHooks
Blaze._DOMRange._insertNodeWithHooks = (node, parent, next) ->
propagateUIHooks parent, node
originalInsertNodeWithHooks node, parent, next
originalMoveNodeWithHooks = Blaze._DOMRange._moveNodeWithHooks
Blaze._DOMRange._moveNodeWithHooks = (node, parent, next) ->
propagateUIHooks parent, node
originalMoveNodeWithHooks node, parent, next
createUIHooks = (component, parentNode) ->
parentNode: parentNode
insertElement: (node, before) ->
component.insertDOMElement @parentNode, node, before
moveElement: (node, before) ->
component.moveDOMElement @parentNode, node, before
removeElement: (node) ->
component.removeDOMElement node.parentNode, node
originalDOMRangeAttach = Blaze._DOMRange::attach
Blaze._DOMRange::attach = (parentElement, nextNode, _isMove, _isReplace) ->
if component = @view?._templateInstance?.component
for member in @members when member not instanceof Blaze._DOMRange
member._uihooks = createUIHooks component, member
continue unless member.hasChildNodes()
for childNode in member.childNodes when childNode.nodeType is Node.ELEMENT_NODE
propagateUIHooks member, childNode
oldUIHooks = parentElement._uihooks
try
parentElement._uihooks = createUIHooks component, parentElement
return originalDOMRangeAttach.apply @, arguments
finally
if oldUIHooks
parentElement._uihooks = oldUIHooks
else
delete parentElement._uihooks
originalDOMRangeAttach.apply @, arguments
WHITESPACE_REGEX = /^\s+$/
EventHandler = Blaze._AttributeHandler.extend
update: (element, oldValue, value) ->
oldValue = [] unless oldValue
oldValue = [oldValue] unless _.isArray oldValue
value = [] unless value
value = [value] unless _.isArray value
assert _.every(oldValue, share.isEventHandler), oldValue
assert _.every(value, share.isEventHandler), value
$element = $(element)
eventName = @name.substr(2).toLowerCase()
$element.off eventName, fun for fun in oldValue
$element.on eventName, fun for fun in value
originalMakeAttributeHandler = Blaze._makeAttributeHandler
Blaze._makeAttributeHandler = (elem, name, value) ->
if share.EVENT_HANDLER_REGEX.test name
new EventHandler name, value
else
originalMakeAttributeHandler elem, name, value
originalToText = Blaze._toText
Blaze._toText = (htmljs, parentView, textMode) ->
# If it is an event handler function, we pass it as it is and do not try to convert it to text.
# Our EventHandler knows how to handle such attribute values - functions.
if share.isEventHandler htmljs
htmljs
else if _.isArray(htmljs) and _.some htmljs, share.isEventHandler
# Remove whitespace in onEvent="{{onEvent1}} {{onEvent2}}".
_.filter htmljs, (fun) ->
return true if share.isEventHandler fun
return false if WHITESPACE_REGEX.test fun
# We do not support anything fancy besides whitespace.
throw new Error "Invalid event handler: #{fun}"
else
originalToText htmljs, parentView, textMode
originalExpandAttributes = Blaze._expandAttributes
Blaze._expandAttributes = (attrs, parentView) ->
previousInExpandAttributes = share.inExpandAttributes
share.inExpandAttributes = true
try
originalExpandAttributes attrs, parentView
finally
share.inExpandAttributes = previousInExpandAttributes