Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: ui/accessibility/extensions/colorenhancer/src/cvd.js

Issue 1156303011: Fix Color Enhancer global scopes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | ui/accessibility/extensions/colorenhancer/src/popup.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ======= Global state =======
6
7 var curDelta = 0;
8 var curSeverity = 0;
9 var curType = 'PROTANOMALY';
10 var curSimulate = false;
11 var curEnable = false;
12 var curFilter = 0;
13
14
15 // ======= 3x3 matrix ops =======
16
17 /**
18 * The 3x3 identity matrix.
19 * @const {object}
20 */
21 var IDENTITY_MATRIX_3x3 = [
22 [1, 0, 0],
23 [0, 1, 0],
24 [0, 0, 1]
25 ];
26
27
28 /**
29 * Adds two matrices.
30 * @param {!object} m1 A 3x3 matrix.
31 * @param {!object} m2 A 3x3 matrix.
32 * @return {!object} The 3x3 matrix m1 + m2.
33 */
34 function add3x3(m1, m2) {
35 var result = [];
36 for (var i = 0; i < 3; i++) {
37 result[i] = [];
38 for (var j = 0; j < 3; j++) {
39 result[i].push(m1[i][j] + m2[i][j]);
40 }
41 }
42 return result;
43 }
44
45
46 /**
47 * Subtracts one matrix from another.
48 * @param {!object} m1 A 3x3 matrix.
49 * @param {!object} m2 A 3x3 matrix.
50 * @return {!object} The 3x3 matrix m1 - m2.
51 */
52 function sub3x3(m1, m2) {
53 var result = [];
54 for (var i = 0; i < 3; i++) {
55 result[i] = [];
56 for (var j = 0; j < 3; j++) {
57 result[i].push(m1[i][j] - m2[i][j]);
58 }
59 }
60 return result;
61 }
62
63
64 /**
65 * Multiplies one matrix with another.
66 * @param {!object} m1 A 3x3 matrix.
67 * @param {!object} m2 A 3x3 matrix.
68 * @return {!object} The 3x3 matrix m1 * m2.
69 */
70 function mul3x3(m1, m2) {
71 var result = [];
72 for (var i = 0; i < 3; i++) {
73 result[i] = [];
74 for (var j = 0; j < 3; j++) {
75 var sum = 0;
76 for (var k = 0; k < 3; k++) {
77 sum += m1[i][k] * m2[k][j];
78 }
79 result[i].push(sum);
80 }
81 }
82 return result;
83 }
84
85
86 /**
87 * Multiplies a matrix with a number.
88 * @param {!object} m A 3x3 matrix.
89 * @param {!number} k A scalar multiplier.
90 * @return {!object} The 3x3 matrix m * k.
91 */
92 function mul3x3Scalar(m, k) {
93 var result = [];
94 for (var i = 0; i < 3; i++) {
95 result[i] = [];
96 for (var j = 0; j < 3; j++) {
97 result[i].push(k * m[i][j]);
98 }
99 }
100 return result;
101 }
102
103
104 // ======= 3x3 matrix utils =======
105
106 /**
107 * Makes the SVG matrix string (of 20 values) for a given matrix.
108 * @param {!object} m A 3x3 matrix.
109 * @return {!string} The SVG matrix string for m.
110 */
111 function svgMatrixStringFrom3x3(m) {
112 var outputRows = [];
113 for (var i = 0; i < 3; i++) {
114 outputRows.push(m[i].join(' ') + ' 0 0');
115 }
116 // Add the alpha row
117 outputRows.push('0 0 0 1 0');
118 return outputRows.join(' ');
119 }
120
121
122 /**
123 * Makes a human readable string for a given matrix.
124 * @param {!object} m A 3x3 matrix.
125 * @return {!string} A human-readable string for m.
126 */
127 function humanReadbleStringFrom3x3(m) {
128 var result = '';
129 for (var i = 0; i < 3; i++) {
130 result += (i ? ', ' : '') + '[';
131 for (var j = 0; j < 3; j++) {
132 result += (j ? ', ' : '') + m[i][j].toFixed(2);
133 }
134 result += ']';
135 }
136 return result;
137 }
138
139
140 // ======= CVD parameters =======
141 /**
142 * Parameters for simulating color vision deficiency.
143 * Source:
144 * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulatio n.html
145 * Original Research Paper:
146 * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/Machado_Olive ira_Fernandes_CVD_Vis2009_final.pdf
147 *
148 * @enum {string}
149 */
150 var cvdSimulationParams = {
151 PROTANOMALY: [
152 [0.4720, -1.2946, 0.9857],
153 [-0.6128, 1.6326, 0.0187],
154 [0.1407, -0.3380, -0.0044],
155 [-0.1420, 0.2488, 0.0044],
156 [0.1872, -0.3908, 0.9942],
157 [-0.0451, 0.1420, 0.0013],
158 [0.0222, -0.0253, -0.0004],
159 [-0.0290, -0.0201, 0.0006],
160 [0.0068, 0.0454, 0.9990]
161 ],
162 DEUTERANOMALY: [
163 [0.5442, -1.1454, 0.9818],
164 [-0.7091, 1.5287, 0.0238],
165 [0.1650, -0.3833, -0.0055],
166 [-0.1664, 0.4368, 0.0056],
167 [0.2178, -0.5327, 0.9927],
168 [-0.0514, 0.0958, 0.0017],
169 [0.0180, -0.0288, -0.0006],
170 [-0.0232, -0.0649, 0.0007],
171 [0.0052, 0.0360, 0.9998]
172 ],
173 TRITANOMALY: [
174 [0.4275, -0.0181, 0.9307],
175 [-0.2454, 0.0013, 0.0827],
176 [-0.1821, 0.0168, -0.0134],
177 [-0.1280, 0.0047, 0.0202],
178 [0.0233, -0.0398, 0.9728],
179 [0.1048, 0.0352, 0.0070],
180 [-0.0156, 0.0061, 0.0071],
181 [0.3841, 0.2947, 0.0151],
182 [-0.3685, -0.3008, 0.9778]
183 ]
184 };
185
186
187 // TODO(mustaq): This should be nuked, see getCvdCorrectionMatrix().
188 var cvdCorrectionParams = {
189 PROTANOMALY: {
190 addendum: [
191 [0.0, 0.0, 0.0],
192 [0.7, 1.0, 0.0],
193 [0.7, 0.0, 1.0]
194 ],
195 delta_factor: [
196 [0.0, 0.0, 0.0],
197 [0.3, 0.0, 0.0],
198 [-0.3, 0.0, 0.0]
199 ]
200 },
201 DEUTERANOMALY: {
202 addendum: [
203 [0.0, 0.0, 0.0],
204 [0.7, 1.0, 0.0],
205 [0.7, 0.0, 1.0]
206 ],
207 delta_factor: [
208 [0.0, 0.0, 0.0],
209 [0.3, 0.0, 0.0],
210 [-0.3, 0.0, 0.0]
211 ]
212 },
213 TRITANOMALY: {
214 addendum: [
215 [1.0, 0.0, 0.7],
216 [0.0, 1.0, 0.7],
217 [0.0, 0.0, 0.0]
218 ],
219 delta_factor: [
220 [0.0, 0.0, 0.3],
221 [0.0, 0.0, -0.3],
222 [0.0, 0.0, 0.0]
223 ]
224 }
225 };
226
227
228 // ======= CVD matrix builders =======
229
230 /**
231 * Returns a 3x3 matrix for simulating the given type of CVD with the given
232 * severity.
233 * @param {string} cvdType Type of CVD, either "PROTANOMALY" or "DEUTERANOMALY"
234 * or "TRITANOMALY".
235 * @param {number} severity A real number in [0,1] denoting severity.
236 */
237 function getCvdSimulationMatrix(cvdType, severity) {
238 var cvdSimulationParam = cvdSimulationParams[cvdType];
239 var severity2 = severity * severity;
240 var matrix = [];
241 for (var i = 0; i < 3; i++) {
242 var row = [];
243 for (var j = 0; j < 3; j++) {
244 var paramRow = i*3+j;
245 var val = cvdSimulationParam[paramRow][0] * severity2
246 + cvdSimulationParam[paramRow][1] * severity
247 + cvdSimulationParam[paramRow][2];
248 row.push(val);
249 }
250 matrix.push(row);
251 }
252 return matrix;
253 }
254
255
256 /**
257 * Returns a 3x3 matrix for correcting the given type of CVD using the given
258 * color adjustment.
259 * @param {string} cvdType Type of CVD, either "PROTANOMALY" or "DEUTERANOMALY"
260 * or "TRITANOMALY".
261 * @param {number} delta A real number in [0,1] denoting color adjustment.
262 */
263 function getCvdCorrectionMatrix(cvdType, delta) {
264 cvdCorrectionParam = cvdCorrectionParams[cvdType];
265 // TODO(mustaq): Perhaps nuke full-matrix operations after experiment.
266 return add3x3(cvdCorrectionParam['addendum'],
267 mul3x3Scalar(cvdCorrectionParam['delta_factor'], delta));
268 }
269
270
271 /**
272 * Returns the 3x3 matrix to be used for the given settings.
273 * @param {string} cvdType Type of CVD, either "PROTANOMALY" or "DEUTERANOMALY"
274 * or "TRITANOMALY".
275 * @param {number} severity A real number in [0,1] denoting severity.
276 * @param {number} delta A real number in [0,1] denoting color adjustment.
277 * @param {boolean} simulate Whether to simulate the CVD type.
278 * @param {boolean} enable Whether to enable color filtering.
279 */
280 function getEffectiveCvdMatrix(cvdType, severity, delta, simulate, enable) {
281 if (!enable) {
282 //TODO(mustaq): we should remove matrices at the svg level
283 return IDENTITY_MATRIX_3x3;
284 }
285
286 var effectiveMatrix = getCvdSimulationMatrix(cvdType, severity);
287
288 if (!simulate) {
289 var cvdCorrectionMatrix = getCvdCorrectionMatrix(cvdType, delta);
290 var tmpProduct = mul3x3(cvdCorrectionMatrix, effectiveMatrix);
291
292 effectiveMatrix = sub3x3(
293 add3x3(IDENTITY_MATRIX_3x3, cvdCorrectionMatrix),
294 tmpProduct);
295 }
296
297 return effectiveMatrix;
298 }
299
300
301 // ======= Page linker =======
302
303 /** @const {string} */
304 var SVG_DEFAULT_MATRIX =
305 '1 0 0 0 0 ' +
306 '0 1 0 0 0 ' +
307 '0 0 1 0 0 ' +
308 '0 0 0 1 0';
309
310 var svgContent =
311 '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">' +
312 ' <defs>' +
313 ' <filter id="cvd_extension_0">' +
314 ' <feColorMatrix id="cvd_matrix_0" type="matrix" values="' +
315 SVG_DEFAULT_MATRIX + '"/>' +
316 ' </filter>' +
317 ' <filter id="cvd_extension_1">' +
318 ' <feColorMatrix id="cvd_matrix_1" type="matrix" values="' +
319 SVG_DEFAULT_MATRIX + '"/>' +
320 ' </filter>' +
321 ' </defs>' +
322 '</svg>';
323
324 /**
325 * Checks for svg filter matrix presence and append to DOM if not present.
326 */
327 function addSvgIfMissing() {
328 var wrap = document.getElementById('cvd_extension_svg_filter');
329 if (!wrap) {
330 wrap = document.createElement('span');
331 wrap.id = 'cvd_extension_svg_filter';
332 wrap.setAttribute('hidden', '');
333 wrap.innerHTML = svgContent;
334 document.body.appendChild(wrap);
335 }
336 }
337
338 /**
339 * Updates the SVG filter based on the RGB correction/simulation matrix.
340 * @param {!Object} matrix 3x3 RGB transformation matrix.
341 */
342 function setFilter(matrix) {
343 addSvgIfMissing();
344 var next = 1 - curFilter;
345
346 debugPrint('update: matrix#' + next + '=' +
347 humanReadbleStringFrom3x3(matrix));
348
349 var matrixElem = document.getElementById('cvd_matrix_' + next);
350 matrixElem.setAttribute('values', svgMatrixStringFrom3x3(matrix));
351
352 var html = document.documentElement;
353 html.classList.remove('filter' + curFilter);
354 html.classList.add('filter' + next);
355
356 curFilter = next;
357 }
358
359 /**
360 * Updates the SVG matrix using the current settings.
361 */
362 function update() {
363 if (!document.body) {
364 document.addEventListener('DOMContentLoaded', update);
365 return;
366 }
367
368 var effectiveMatrix = getEffectiveCvdMatrix(
369 curType, curSeverity, curDelta * 2 - 1, curSimulate, curEnable);
370
371 setFilter(effectiveMatrix);
372
373 // TODO(wnwen): Figure out whether this hack is still necessary.
374 // TODO(kevers): Check if a call to getComputedStyle is sufficient to force an
375 // update.
376 window.scrollBy(0, 1);
377 window.scrollBy(0, -1);
378 }
379
380
381 /**
382 * Process request from background page.
383 * @param {!object} request An object containing color filter parameters.
384 */
385 function onExtensionMessage(request) {
386 debugPrint('onExtensionMessage: ' + JSON.stringify(request));
387 var changed = false;
388
389 if (request['type'] !== undefined) {
390 var type = request.type;
391 if (curType != type) {
392 curType = type;
393 changed = true;
394 }
395 }
396
397 if (request['severity'] !== undefined) {
398 var severity = request.severity;
399 if (curSeverity != severity) {
400 curSeverity = severity;
401 changed = true;
402 }
403 }
404
405 if (request['delta'] !== undefined) {
406 var delta = request.delta;
407 if (curDelta != delta) {
408 curDelta = delta;
409 changed = true;
410 }
411 }
412
413 if (request['simulate'] !== undefined) {
414 var simulate = request.simulate;
415 if (curSimulate != simulate) {
416 curSimulate = simulate;
417 changed = true;
418 }
419 }
420
421 if (request['enable'] !== undefined) {
422 var enable = request.enable;
423 if (curEnable != enable) {
424 curEnable = enable;
425 changed = true;
426 }
427 }
428
429 if (changed)
430 update();
431 }
432
433
434 /**
435 * Prepare to process background messages and let it know to send initial
436 * values.
437 */
438 (function initialize() {
439 chrome.extension.onRequest.addListener(onExtensionMessage);
440 chrome.extension.sendRequest({'init': true}, onExtensionMessage);
441 })();
442 5
443 /** 6 /**
444 * Global exports. Used by popup to show effect of filter during setup. 7 * Global exports. Used by popup to show effect of filter during setup.
445 */ 8 */
446 (function(exports) { 9 (function(exports) {
10 var curDelta = 0;
11 var curSeverity = 0;
12 var curType = 'PROTANOMALY';
13 var curSimulate = false;
14 var curEnable = false;
15 var curFilter = 0;
16
17
18 // ======= 3x3 matrix ops =======
19
20 /**
21 * The 3x3 identity matrix.
22 * @const {object}
23 */
24 var IDENTITY_MATRIX_3x3 = [
25 [1, 0, 0],
26 [0, 1, 0],
27 [0, 0, 1]
28 ];
29
30
31 /**
32 * Adds two matrices.
33 * @param {!object} m1 A 3x3 matrix.
34 * @param {!object} m2 A 3x3 matrix.
35 * @return {!object} The 3x3 matrix m1 + m2.
36 */
37 function add3x3(m1, m2) {
38 var result = [];
39 for (var i = 0; i < 3; i++) {
40 result[i] = [];
41 for (var j = 0; j < 3; j++) {
42 result[i].push(m1[i][j] + m2[i][j]);
43 }
44 }
45 return result;
46 }
47
48
49 /**
50 * Subtracts one matrix from another.
51 * @param {!object} m1 A 3x3 matrix.
52 * @param {!object} m2 A 3x3 matrix.
53 * @return {!object} The 3x3 matrix m1 - m2.
54 */
55 function sub3x3(m1, m2) {
56 var result = [];
57 for (var i = 0; i < 3; i++) {
58 result[i] = [];
59 for (var j = 0; j < 3; j++) {
60 result[i].push(m1[i][j] - m2[i][j]);
61 }
62 }
63 return result;
64 }
65
66
67 /**
68 * Multiplies one matrix with another.
69 * @param {!object} m1 A 3x3 matrix.
70 * @param {!object} m2 A 3x3 matrix.
71 * @return {!object} The 3x3 matrix m1 * m2.
72 */
73 function mul3x3(m1, m2) {
74 var result = [];
75 for (var i = 0; i < 3; i++) {
76 result[i] = [];
77 for (var j = 0; j < 3; j++) {
78 var sum = 0;
79 for (var k = 0; k < 3; k++) {
80 sum += m1[i][k] * m2[k][j];
81 }
82 result[i].push(sum);
83 }
84 }
85 return result;
86 }
87
88
89 /**
90 * Multiplies a matrix with a number.
91 * @param {!object} m A 3x3 matrix.
92 * @param {!number} k A scalar multiplier.
93 * @return {!object} The 3x3 matrix m * k.
94 */
95 function mul3x3Scalar(m, k) {
96 var result = [];
97 for (var i = 0; i < 3; i++) {
98 result[i] = [];
99 for (var j = 0; j < 3; j++) {
100 result[i].push(k * m[i][j]);
101 }
102 }
103 return result;
104 }
105
106
107 // ======= 3x3 matrix utils =======
108
109 /**
110 * Makes the SVG matrix string (of 20 values) for a given matrix.
111 * @param {!object} m A 3x3 matrix.
112 * @return {!string} The SVG matrix string for m.
113 */
114 function svgMatrixStringFrom3x3(m) {
115 var outputRows = [];
116 for (var i = 0; i < 3; i++) {
117 outputRows.push(m[i].join(' ') + ' 0 0');
118 }
119 // Add the alpha row
120 outputRows.push('0 0 0 1 0');
121 return outputRows.join(' ');
122 }
123
124
125 /**
126 * Makes a human readable string for a given matrix.
127 * @param {!object} m A 3x3 matrix.
128 * @return {!string} A human-readable string for m.
129 */
130 function humanReadbleStringFrom3x3(m) {
131 var result = '';
132 for (var i = 0; i < 3; i++) {
133 result += (i ? ', ' : '') + '[';
134 for (var j = 0; j < 3; j++) {
135 result += (j ? ', ' : '') + m[i][j].toFixed(2);
136 }
137 result += ']';
138 }
139 return result;
140 }
141
142
143 // ======= CVD parameters =======
144 /**
145 * Parameters for simulating color vision deficiency.
146 * Source:
147 * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulat ion.html
148 * Original Research Paper:
149 * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/Machado_Oli veira_Fernandes_CVD_Vis2009_final.pdf
150 *
151 * @enum {string}
152 */
153 var cvdSimulationParams = {
154 PROTANOMALY: [
155 [0.4720, -1.2946, 0.9857],
156 [-0.6128, 1.6326, 0.0187],
157 [0.1407, -0.3380, -0.0044],
158 [-0.1420, 0.2488, 0.0044],
159 [0.1872, -0.3908, 0.9942],
160 [-0.0451, 0.1420, 0.0013],
161 [0.0222, -0.0253, -0.0004],
162 [-0.0290, -0.0201, 0.0006],
163 [0.0068, 0.0454, 0.9990]
164 ],
165 DEUTERANOMALY: [
166 [0.5442, -1.1454, 0.9818],
167 [-0.7091, 1.5287, 0.0238],
168 [0.1650, -0.3833, -0.0055],
169 [-0.1664, 0.4368, 0.0056],
170 [0.2178, -0.5327, 0.9927],
171 [-0.0514, 0.0958, 0.0017],
172 [0.0180, -0.0288, -0.0006],
173 [-0.0232, -0.0649, 0.0007],
174 [0.0052, 0.0360, 0.9998]
175 ],
176 TRITANOMALY: [
177 [0.4275, -0.0181, 0.9307],
178 [-0.2454, 0.0013, 0.0827],
179 [-0.1821, 0.0168, -0.0134],
180 [-0.1280, 0.0047, 0.0202],
181 [0.0233, -0.0398, 0.9728],
182 [0.1048, 0.0352, 0.0070],
183 [-0.0156, 0.0061, 0.0071],
184 [0.3841, 0.2947, 0.0151],
185 [-0.3685, -0.3008, 0.9778]
186 ]
187 };
188
189
190 // TODO(mustaq): This should be nuked, see getCvdCorrectionMatrix().
191 var cvdCorrectionParams = {
192 PROTANOMALY: {
193 addendum: [
194 [0.0, 0.0, 0.0],
195 [0.7, 1.0, 0.0],
196 [0.7, 0.0, 1.0]
197 ],
198 delta_factor: [
199 [0.0, 0.0, 0.0],
200 [0.3, 0.0, 0.0],
201 [-0.3, 0.0, 0.0]
202 ]
203 },
204 DEUTERANOMALY: {
205 addendum: [
206 [0.0, 0.0, 0.0],
207 [0.7, 1.0, 0.0],
208 [0.7, 0.0, 1.0]
209 ],
210 delta_factor: [
211 [0.0, 0.0, 0.0],
212 [0.3, 0.0, 0.0],
213 [-0.3, 0.0, 0.0]
214 ]
215 },
216 TRITANOMALY: {
217 addendum: [
218 [1.0, 0.0, 0.7],
219 [0.0, 1.0, 0.7],
220 [0.0, 0.0, 0.0]
221 ],
222 delta_factor: [
223 [0.0, 0.0, 0.3],
224 [0.0, 0.0, -0.3],
225 [0.0, 0.0, 0.0]
226 ]
227 }
228 };
229
230
231 // ======= CVD matrix builders =======
232
233 /**
234 * Returns a 3x3 matrix for simulating the given type of CVD with the given
235 * severity.
236 * @param {string} cvdType Type of CVD, either "PROTANOMALY" or
237 * "DEUTERANOMALY" or "TRITANOMALY".
238 * @param {number} severity A real number in [0,1] denoting severity.
239 */
240 function getCvdSimulationMatrix(cvdType, severity) {
241 var cvdSimulationParam = cvdSimulationParams[cvdType];
242 var severity2 = severity * severity;
243 var matrix = [];
244 for (var i = 0; i < 3; i++) {
245 var row = [];
246 for (var j = 0; j < 3; j++) {
247 var paramRow = i*3+j;
248 var val = cvdSimulationParam[paramRow][0] * severity2
249 + cvdSimulationParam[paramRow][1] * severity
250 + cvdSimulationParam[paramRow][2];
251 row.push(val);
252 }
253 matrix.push(row);
254 }
255 return matrix;
256 }
257
258
259 /**
260 * Returns a 3x3 matrix for correcting the given type of CVD using the given
261 * color adjustment.
262 * @param {string} cvdType Type of CVD, either "PROTANOMALY" or
263 * "DEUTERANOMALY" or "TRITANOMALY".
264 * @param {number} delta A real number in [0,1] denoting color adjustment.
265 */
266 function getCvdCorrectionMatrix(cvdType, delta) {
267 cvdCorrectionParam = cvdCorrectionParams[cvdType];
268 // TODO(mustaq): Perhaps nuke full-matrix operations after experiment.
269 return add3x3(cvdCorrectionParam['addendum'],
270 mul3x3Scalar(cvdCorrectionParam['delta_factor'], delta));
271 }
272
273
274 /**
275 * Returns the 3x3 matrix to be used for the given settings.
276 * @param {string} cvdType Type of CVD, either "PROTANOMALY" or
277 * "DEUTERANOMALY" or "TRITANOMALY".
278 * @param {number} severity A real number in [0,1] denoting severity.
279 * @param {number} delta A real number in [0,1] denoting color adjustment.
280 * @param {boolean} simulate Whether to simulate the CVD type.
281 * @param {boolean} enable Whether to enable color filtering.
282 */
283 function getEffectiveCvdMatrix(cvdType, severity, delta, simulate, enable) {
284 if (!enable) {
285 //TODO(mustaq): we should remove matrices at the svg level
286 return IDENTITY_MATRIX_3x3;
287 }
288
289 var effectiveMatrix = getCvdSimulationMatrix(cvdType, severity);
290
291 if (!simulate) {
292 var cvdCorrectionMatrix = getCvdCorrectionMatrix(cvdType, delta);
293 var tmpProduct = mul3x3(cvdCorrectionMatrix, effectiveMatrix);
294
295 effectiveMatrix = sub3x3(
296 add3x3(IDENTITY_MATRIX_3x3, cvdCorrectionMatrix),
297 tmpProduct);
298 }
299
300 return effectiveMatrix;
301 }
302
303
304 // ======= Page linker =======
305
306 /** @const {string} */
307 var SVG_DEFAULT_MATRIX =
308 '1 0 0 0 0 ' +
309 '0 1 0 0 0 ' +
310 '0 0 1 0 0 ' +
311 '0 0 0 1 0';
312
313 var svgContent =
314 '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">' +
315 ' <defs>' +
316 ' <filter id="cvd_extension_0">' +
317 ' <feColorMatrix id="cvd_matrix_0" type="matrix" values="' +
318 SVG_DEFAULT_MATRIX + '"/>' +
319 ' </filter>' +
320 ' <filter id="cvd_extension_1">' +
321 ' <feColorMatrix id="cvd_matrix_1" type="matrix" values="' +
322 SVG_DEFAULT_MATRIX + '"/>' +
323 ' </filter>' +
324 ' </defs>' +
325 '</svg>';
326
327 /**
328 * Checks for svg filter matrix presence and append to DOM if not present.
329 */
330 function addSvgIfMissing() {
331 var wrap = document.getElementById('cvd_extension_svg_filter');
332 if (!wrap) {
333 wrap = document.createElement('span');
334 wrap.id = 'cvd_extension_svg_filter';
335 wrap.setAttribute('hidden', '');
336 wrap.innerHTML = svgContent;
337 document.body.appendChild(wrap);
338 }
339 }
340
341 /**
342 * Updates the SVG filter based on the RGB correction/simulation matrix.
343 * @param {!Object} matrix 3x3 RGB transformation matrix.
344 */
345 function setFilter(matrix) {
346 addSvgIfMissing();
347 var next = 1 - curFilter;
348
349 debugPrint('update: matrix#' + next + '=' +
350 humanReadbleStringFrom3x3(matrix));
351
352 var matrixElem = document.getElementById('cvd_matrix_' + next);
353 matrixElem.setAttribute('values', svgMatrixStringFrom3x3(matrix));
354
355 var html = document.documentElement;
356 html.classList.remove('filter' + curFilter);
357 html.classList.add('filter' + next);
358
359 curFilter = next;
360 }
361
362 /**
363 * Updates the SVG matrix using the current settings.
364 */
365 function update() {
366 if (!document.body) {
367 document.addEventListener('DOMContentLoaded', update);
368 return;
369 }
370
371 var effectiveMatrix = getEffectiveCvdMatrix(
372 curType, curSeverity, curDelta * 2 - 1, curSimulate, curEnable);
373
374 setFilter(effectiveMatrix);
375
376 // TODO(kevers): Check if a call to getComputedStyle is sufficient to force
377 // an update.
378 window.scrollBy(0, 1);
379 window.scrollBy(0, -1);
380 }
381
382
383 /**
384 * Process request from background page.
385 * @param {!object} request An object containing color filter parameters.
386 */
387 function onExtensionMessage(request) {
388 debugPrint('onExtensionMessage: ' + JSON.stringify(request));
389 var changed = false;
390
391 if (request['type'] !== undefined) {
392 var type = request.type;
393 if (curType != type) {
394 curType = type;
395 changed = true;
396 }
397 }
398
399 if (request['severity'] !== undefined) {
400 var severity = request.severity;
401 if (curSeverity != severity) {
402 curSeverity = severity;
403 changed = true;
404 }
405 }
406
407 if (request['delta'] !== undefined) {
408 var delta = request.delta;
409 if (curDelta != delta) {
410 curDelta = delta;
411 changed = true;
412 }
413 }
414
415 if (request['simulate'] !== undefined) {
416 var simulate = request.simulate;
417 if (curSimulate != simulate) {
418 curSimulate = simulate;
419 changed = true;
420 }
421 }
422
423 if (request['enable'] !== undefined) {
424 var enable = request.enable;
425 if (curEnable != enable) {
426 curEnable = enable;
427 changed = true;
428 }
429 }
430
431 if (changed)
432 update();
433 }
434
435
436 /**
437 * Prepare to process background messages and let it know to send initial
438 * values.
439 */
440 exports.initializeExtension = function () {
441 chrome.extension.onRequest.addListener(onExtensionMessage);
442 chrome.extension.sendRequest({'init': true}, onExtensionMessage);
443 };
444
447 /** 445 /**
448 * Generate SVG filter for color enhancement based on type and severity using 446 * Generate SVG filter for color enhancement based on type and severity using
449 * default color adjustment. 447 * default color adjustment.
450 * @param {string} type Type type of color vision defficiency (CVD). 448 * @param {string} type Type type of color vision defficiency (CVD).
451 * @param {number} severity The degree of CVD ranging from 0 for normal 449 * @param {number} severity The degree of CVD ranging from 0 for normal
452 * vision to 1 for dichromats. 450 * vision to 1 for dichromats.
453 */ 451 */
454 exports.getDefaultCvdCorrectionFilter = function(type, severity) { 452 exports.getDefaultCvdCorrectionFilter = function(type, severity) {
455 return getEffectiveCvdMatrix(type, severity, 0, false, true); 453 return getEffectiveCvdMatrix(type, severity, 0, false, true);
456 }; 454 };
457 455
458 /** 456 /**
459 * Adds support for a color enhancement filter. 457 * Adds support for a color enhancement filter.
460 * @param {!Object} matrix 3x3 RGB transformation matrix. 458 * @param {!Object} matrix 3x3 RGB transformation matrix.
461 */ 459 */
462 exports.injectColorEnhancementFilter = function(matrix) { 460 exports.injectColorEnhancementFilter = function(matrix) {
463 setFilter(matrix); 461 setFilter(matrix);
464 }; 462 };
465 463
466 /** 464 /**
467 * Clears color correction filter. 465 * Clears color correction filter.
468 */ 466 */
469 exports.clearColorEnhancementFilter = function() { 467 exports.clearColorEnhancementFilter = function() {
470 var html = document.documentElement; 468 var html = document.documentElement;
471 html.classList.remove('filter0'); 469 html.classList.remove('filter0');
472 html.classList.remove('filter1'); 470 html.classList.remove('filter1');
473 }; 471 };
474 })(this); 472 })(this);
473
474 this.initializeExtension();
OLDNEW
« no previous file with comments | « no previous file | ui/accessibility/extensions/colorenhancer/src/popup.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698