blob: c3074447522966364e7f88225206dd6745daf152 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
base.require('base.utils');
base.exportTo('base', function() {
// Setting this to true will cause stack traces to get dumped into the
// tasks. When an exception happens the original stack will be printed.
//
// NOTE: This should never be set committed as true.
var recordRAFStacks = false;
var pendingPreAFs = [];
var pendingRAFs = [];
var currentRAFDispatchList = undefined;
var rafScheduled = false;
function scheduleRAF() {
if (rafScheduled)
return;
rafScheduled = true;
window.webkitRequestAnimationFrame(processRequests);
}
function onAnimationFrameError(e, opt_stack) {
if (opt_stack)
console.log(opt_stack);
if (e.message)
console.error(e.message, e.stack);
else
console.error(e);
}
function runTask(task) {
try {
task.callback.call(task.context);
} catch (e) {
base.onAnimationFrameError(e, task.stack);
}
}
function processRequests() {
rafScheduled = false;
var currentPreAFs = pendingPreAFs;
currentRAFDispatchList = pendingRAFs;
pendingPreAFs = [];
pendingRAFs = [];
for (var i = 0; i < currentPreAFs.length; i++)
runTask(currentPreAFs[i]);
while (currentRAFDispatchList.length > 0)
runTask(currentRAFDispatchList.shift());
currentRAFDispatchList = undefined;
}
function getStack_() {
if (!recordRAFStacks)
return '';
var stackLines = base.stackTrace();
// Strip off getStack_.
stackLines.shift();
return stackLines.join('\n');
}
function requestPreAnimationFrame(callback, opt_this) {
pendingPreAFs.push({
callback: callback,
context: opt_this || window,
stack: getStack_()});
scheduleRAF();
}
function requestAnimationFrameInThisFrameIfPossible(callback, opt_this) {
if (!currentRAFDispatchList) {
requestAnimationFrame(callback, opt_this);
return;
}
currentRAFDispatchList.push({
callback: callback,
context: opt_this || window,
stack: getStack_()});
return;
}
function requestAnimationFrame(callback, opt_this) {
pendingRAFs.push({
callback: callback,
context: opt_this || window,
stack: getStack_()});
scheduleRAF();
}
return {
onAnimationFrameError: onAnimationFrameError,
requestPreAnimationFrame: requestPreAnimationFrame,
requestAnimationFrame: requestAnimationFrame,
requestAnimationFrameInThisFrameIfPossible:
requestAnimationFrameInThisFrameIfPossible
};
});