-
Notifications
You must be signed in to change notification settings - Fork 1
/
event_stream.js
99 lines (83 loc) · 2.12 KB
/
event_stream.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
var copy = require('shallow-copy')
var xtend = require('xtend')
var Color = require('color')
module.exports = EventStream
EventStream.validEvent = validEvent
function EventStream () {
if (!(this instanceof EventStream)) return new EventStream()
this.events = []
}
EventStream.prototype.push = function push (event) {
var value = this.events.push(event)
return value
}
EventStream.prototype.pop = function pop () {
var value = this.events.pop()
return value
}
EventStream.prototype.toJSON = function toJSON () {
var self = this
var lastType
this.normalized = this.events.map(createEvent)
this.normalized.forEach(processPath)
return this.normalized.reduce(
reduce,
[]
)
function createEvent (event) {
var args = copy(event.args)
if (args) {
;['stroke', 'fill'].forEach(function setRgb (key) {
if (args[key]) args[key] = Color(args[key]).rgbaString()
})
}
return {
type: event.type,
id: event.id,
args: args,
layout: event.layout,
pathId: event.path ? event.path.id : undefined
}
}
function processPath (event) {
if (event.pathId) {
var path = self.normalized.filter(findById)[0]
if (path) {
event.deleted = true
path.args = xtend(path.args, event.args)
path.deleted = event.type === 'delete'
}
}
function findById (e) {
return e.id === event.pathId
}
}
function reduce (result, event) {
if (event.type === 'style' && lastType === 'style') result.pop()
if (validEvent(event)) {
lastType = event.type
result.push(
['type', 'args', 'layout'].reduce(copyEvent, {})
)
return result
}
function copyEvent (result, key) {
if (event[key]) {
result[key] = event[key]
}
return result
}
return result
}
}
function validEvent (event) {
if (event.deleted) return false
if (event.type === 'text') {
return !!event.args.value
}
if (event.type === 'path') {
return !!event.args.d.match(/a|l/i)
}
return Object.keys(event.args || {}).length +
Object.keys(event.layout || {}).length > 0
}