-
Notifications
You must be signed in to change notification settings - Fork 0
/
document.js
136 lines (124 loc) · 3.65 KB
/
document.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
127
128
129
130
131
132
133
134
135
136
/* Room class. Pass settings object in the form: {
max_clients: int, //10
anyone_write: bool, //false
anyone_join: bool, //false
}
*/
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function isInteger(n) {
return !isNaN(parseInt(n, 10)) && isFinite(n);
}
function validate_position(pos) {
for (const key in pos) {
if (!(key === "x" || key === "y")) return false;
if (!isInteger(pos[key])) return false;
}
return true;
}
function validate_points(points) {
return points.every(validate_position);
}
class Layer {
constructor(name) {
this.name = name;
}
}
class Document {
constructor() {
this.history = [];
this.layers = [];
}
validate(dict, name, checktype) {
const v = dict[name];
let err = "";
checktype.split(" ").forEach(function (t) {
switch (t) {
case "positive":
if (v < 0) err = "value is not positive";
break;
case "number":
if (!isNumber(v)) err = "value is not a number";
break;
case "integer":
if (!isInteger(v)) err = "value is not an integer";
break;
case "layerid":
if (this.layers[v] == null) err = "a layer with id does not exist";
break;
case "position":
if (!validate_position(v)) err = "this value is an invalid position";
break;
case "points":
if (!validate_points(v)) err = "this value is an invalid point list";
break;
}
});
if (err.length > 0) {
throw new Error(
`Invalid data ${v.toString()} for ${name}. \
Expecting a "${checktype}" value, but ${err}`
);
}
}
DoCommand(command) {
switch (command.cmd) {
case "new_layer":
{
const name =
command.params.name || "Layer_" + (this.layers.length + 1);
command.params.name = name;
const l = new Layer(name);
this.layers.push(l);
}
break;
case "image":
//Image URL/key has already been validated
this.validate(command, "layerid", "layerid");
this.validate(command, "pos", "position");
break;
case "tool":
if (this.layers[command.layerid] == null) throw "Invalid layerid";
switch (command.name) {
case "Brush":
this.validate(command.data, "pos", "position");
this.validate(command.data, "points", "points");
this.validate(command.data, "lineWidth", "positive integer");
break;
case "Eraser":
this.validate(command.data, "pos", "position");
this.validate(command.data, "points", "points");
this.validate(command.data, "lineWidth", "positive integer");
this.validate(command.data, "alpha", "positive number");
break;
case "Line":
this.validate(command.data, "pos", "position");
this.validate(command.data, "pos2", "position");
this.validate(command.data, "lineWidth", "positive integer");
break;
case "Shape":
this.validate(command.data, "pos", "position");
this.validate(command.data, "pos2", "position");
this.validate(command.data, "strokeWidth", "positive integer");
break;
default:
throw "Unidentified tool " + command.name;
}
break;
default:
return false;
}
command.id = this.history.length;
this.history.push(command);
return true;
}
getHistory() {
return this.history;
}
Free() {
this.history = null;
this.layers = null;
}
}
exports.Document = Document;