1 | "use strict";
|
2 | var utils = require('./utils');
|
3 |
|
4 | exports.property = function(attr) {
|
5 | if (Array.isArray(attr.type)) {
|
6 | var valid = Object.create(null);
|
7 | attr.type.forEach(function(val) {
|
8 | valid[val.value || val] = val.alias || val;
|
9 | });
|
10 | var missingValueDefault = attr.missing;
|
11 | if (missingValueDefault===undefined) { missingValueDefault = null; }
|
12 | var invalidValueDefault = attr.invalid;
|
13 | if (invalidValueDefault===undefined) { invalidValueDefault = missingValueDefault; }
|
14 | return {
|
15 | get: function() {
|
16 | var v = this._getattr(attr.name);
|
17 | if (v === null) return missingValueDefault;
|
18 |
|
19 | v = valid[v.toLowerCase()];
|
20 | if (v !== undefined) return v;
|
21 | if (invalidValueDefault !== null) return invalidValueDefault;
|
22 | return v;
|
23 | },
|
24 | set: function(v) {
|
25 | this._setattr(attr.name, v);
|
26 | }
|
27 | };
|
28 | }
|
29 | else if (attr.type === Boolean) {
|
30 | return {
|
31 | get: function() {
|
32 | return this.hasAttribute(attr.name);
|
33 | },
|
34 | set: function(v) {
|
35 | if (v) {
|
36 | this._setattr(attr.name, '');
|
37 | }
|
38 | else {
|
39 | this.removeAttribute(attr.name);
|
40 | }
|
41 | }
|
42 | };
|
43 | }
|
44 | else if (attr.type === Number ||
|
45 | attr.type === "long" ||
|
46 | attr.type === "unsigned long" ||
|
47 | attr.type === "limited unsigned long with fallback") {
|
48 | return numberPropDesc(attr);
|
49 | }
|
50 | else if (!attr.type || attr.type === String) {
|
51 | return {
|
52 | get: function() { return this._getattr(attr.name) || ''; },
|
53 | set: function(v) {
|
54 | if (attr.treatNullAsEmptyString && v === null) { v = ''; }
|
55 | this._setattr(attr.name, v);
|
56 | }
|
57 | };
|
58 | }
|
59 | else if (typeof attr.type === 'function') {
|
60 | return attr.type(attr.name, attr);
|
61 | }
|
62 | throw new Error('Invalid attribute definition');
|
63 | };
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | function numberPropDesc(a) {
|
81 | var def;
|
82 | if(typeof a.default === 'function') {
|
83 | def = a.default;
|
84 | }
|
85 | else if(typeof a.default === 'number') {
|
86 | def = function() { return a.default; };
|
87 | }
|
88 | else {
|
89 | def = function() { utils.assert(false, typeof a.default); };
|
90 | }
|
91 | var unsigned_long = (a.type === 'unsigned long');
|
92 | var signed_long = (a.type === 'long');
|
93 | var unsigned_fallback = (a.type === 'limited unsigned long with fallback');
|
94 | var min = a.min, max = a.max, setmin = a.setmin;
|
95 | if (min === undefined) {
|
96 | if (unsigned_long) min = 0;
|
97 | if (signed_long) min = -0x80000000;
|
98 | if (unsigned_fallback) min = 1;
|
99 | }
|
100 | if (max === undefined) {
|
101 | if (unsigned_long || signed_long || unsigned_fallback) max = 0x7FFFFFFF;
|
102 | }
|
103 |
|
104 | return {
|
105 | get: function() {
|
106 | var v = this._getattr(a.name);
|
107 | var n = a.float ? parseFloat(v) : parseInt(v, 10);
|
108 | if (v === null || !isFinite(n) || (min !== undefined && n < min) || (max !== undefined && n > max)) {
|
109 | return def.call(this);
|
110 | }
|
111 | if (unsigned_long || signed_long || unsigned_fallback) {
|
112 | if (!/^[ \t\n\f\r]*[-+]?[0-9]/.test(v)) { return def.call(this); }
|
113 | n = n|0;
|
114 | }
|
115 | return n;
|
116 | },
|
117 | set: function(v) {
|
118 | if (!a.float) { v = Math.floor(v); }
|
119 | if (setmin !== undefined && v < setmin) {
|
120 | utils.IndexSizeError(a.name + ' set to ' + v);
|
121 | }
|
122 | if (unsigned_long) {
|
123 | v = (v < 0 || v > 0x7FFFFFFF) ? def.call(this) :
|
124 | (v|0);
|
125 | } else if (unsigned_fallback) {
|
126 | v = (v < 1 || v > 0x7FFFFFFF) ? def.call(this) :
|
127 | (v|0);
|
128 | } else if (signed_long) {
|
129 | v = (v < -0x80000000 || v > 0x7FFFFFFF) ? def.call(this) :
|
130 | (v|0);
|
131 | }
|
132 | this._setattr(a.name, String(v));
|
133 | }
|
134 | };
|
135 | }
|
136 |
|
137 |
|
138 |
|
139 | exports.registerChangeHandler = function(c, name, handler) {
|
140 | var p = c.prototype;
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 | if (!Object.prototype.hasOwnProperty.call(p, '_attributeChangeHandlers')) {
|
147 | p._attributeChangeHandlers =
|
148 | Object.create(p._attributeChangeHandlers || null);
|
149 | }
|
150 |
|
151 | p._attributeChangeHandlers[name] = handler;
|
152 | };
|