1 /** 2 * Copyright (C) 2010-2014 KO GmbH <copyright@kogmbh.com> 3 * 4 * @licstart 5 * This file is part of WebODF. 6 * 7 * WebODF is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU Affero General Public License (GNU AGPL) 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * WebODF is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Affero General Public License for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public License 18 * along with WebODF. If not, see <http://www.gnu.org/licenses/>. 19 * @licend 20 * 21 * @source: http://www.webodf.org/ 22 * @source: https://github.com/kogmbh/WebODF/ 23 */ 24 25 /*global core, runtime*/ 26 27 (function() { 28 "use strict"; 29 /** @type {!RedrawTasks} */ 30 var redrawTasks; 31 32 /** 33 * FF doesn't execute requestAnimationFrame requests before it's next repaint, 34 * causing flickering when performing some types of updates (e.g., recomputing Style2CSS). 35 * To workaround this, sometimes we force animation callbacks to redraw ourselves 36 * at certain points. 37 * 38 * This object collects animation frame requests and provides 39 * a safe way of executing any outstanding requests 40 * 41 * @constructor 42 */ 43 function RedrawTasks() { 44 var callbacks = {}; 45 46 /** 47 * Schedule a callback to be invoked on the next animation frame, or 48 * when performRedraw is called. 49 * 50 * @param {!function():undefined} callback 51 * @return {!number} 52 */ 53 this.requestRedrawTask = function(callback) { 54 var id = runtime.requestAnimationFrame(function() { 55 callback(); 56 delete callbacks[id]; 57 }); 58 callbacks[id] = callback; 59 return id; 60 }; 61 62 /** 63 * Execute any pending animation frame callbacks and cancel their 64 * browser animation frame request. 65 * 66 * @return {undefined} 67 */ 68 this.performRedraw = function() { 69 Object.keys(callbacks).forEach(function(id) { 70 callbacks[id](); 71 runtime.cancelAnimationFrame(parseInt(id, 10)); 72 }); 73 callbacks = {}; 74 }; 75 76 /** 77 * Cancel a pending animation frame callback 78 * @param {!number} id 79 * @return {undefined} 80 */ 81 this.cancelRedrawTask = function(id) { 82 runtime.cancelAnimationFrame(id); 83 delete callbacks[id]; 84 }; 85 } 86 87 /** 88 * @type {!Object} 89 */ 90 core.Task = {}; 91 92 /** 93 * Disable manually processing of tasks when core.Task.processTasks is called. 94 * This is only used during benchmarks to prevent caret redraws from skewing 95 * the resulting numbers 96 * @type {!boolean} 97 */ 98 core.Task.SUPPRESS_MANUAL_PROCESSING = false; 99 100 /** 101 * Process any outstanding redraw tasks that may be queued up 102 * waiting for an animation frame 103 * 104 * @return {undefined} 105 */ 106 core.Task.processTasks = function() { 107 if (!core.Task.SUPPRESS_MANUAL_PROCESSING) { 108 redrawTasks.performRedraw(); 109 } 110 }; 111 112 /** 113 * Creates a new task that will execute the specified callback once 114 * when redrawing the next animation frame. Triggering the task multiple 115 * times before the execution occurs will still only result in a single 116 * call being made. 117 * 118 * @param {!Function} callback 119 * @return {!core.ScheduledTask} 120 */ 121 core.Task.createRedrawTask = function (callback) { 122 return new core.ScheduledTask(callback, 123 redrawTasks.requestRedrawTask, 124 redrawTasks.cancelRedrawTask 125 ); 126 }; 127 128 /** 129 * Creates a new task that will execute the specified callback once 130 * within the specified delay period. Triggering the task multiple 131 * times before the execution occurs will still only result in a single 132 * call being made. 133 * 134 * @param {!Function} callback 135 * @param {!number} delay 136 * @return {!core.ScheduledTask} 137 */ 138 core.Task.createTimeoutTask = function (callback, delay) { 139 return new core.ScheduledTask(callback, 140 function(callback) { 141 return runtime.setTimeout(callback, delay); 142 }, 143 runtime.clearTimeout 144 ); 145 }; 146 147 function init() { 148 redrawTasks = new RedrawTasks(); 149 } 150 init(); 151 }());