• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5'use strict';
6
7base.require('base.utils');
8
9base.exportTo('base', function() {
10  // Setting this to true will cause stack traces to get dumped into the
11  // tasks. When an exception happens the original stack will be printed.
12  //
13  // NOTE: This should never be set committed as true.
14  var recordRAFStacks = false;
15
16  var pendingPreAFs = [];
17  var pendingRAFs = [];
18  var currentRAFDispatchList = undefined;
19
20  var rafScheduled = false;
21
22  function scheduleRAF() {
23    if (rafScheduled)
24      return;
25    rafScheduled = true;
26    window.webkitRequestAnimationFrame(processRequests);
27  }
28
29  function onAnimationFrameError(e, opt_stack) {
30    if (opt_stack)
31      console.log(opt_stack);
32
33    if (e.message)
34      console.error(e.message, e.stack);
35    else
36      console.error(e);
37  }
38
39  function runTask(task) {
40    try {
41      task.callback.call(task.context);
42    } catch (e) {
43      base.onAnimationFrameError(e, task.stack);
44    }
45  }
46
47  function processRequests() {
48    rafScheduled = false;
49
50    var currentPreAFs = pendingPreAFs;
51    currentRAFDispatchList = pendingRAFs;
52    pendingPreAFs = [];
53    pendingRAFs = [];
54
55    for (var i = 0; i < currentPreAFs.length; i++)
56      runTask(currentPreAFs[i]);
57
58    while (currentRAFDispatchList.length > 0)
59      runTask(currentRAFDispatchList.shift());
60    currentRAFDispatchList = undefined;
61  }
62
63  function getStack_() {
64    if (!recordRAFStacks)
65      return '';
66
67    var stackLines = base.stackTrace();
68    // Strip off getStack_.
69    stackLines.shift();
70    return stackLines.join('\n');
71  }
72
73  function requestPreAnimationFrame(callback, opt_this) {
74    pendingPreAFs.push({
75      callback: callback,
76      context: opt_this || window,
77      stack: getStack_()});
78    scheduleRAF();
79  }
80
81  function requestAnimationFrameInThisFrameIfPossible(callback, opt_this) {
82    if (!currentRAFDispatchList) {
83      requestAnimationFrame(callback, opt_this);
84      return;
85    }
86    currentRAFDispatchList.push({
87      callback: callback,
88      context: opt_this || window,
89      stack: getStack_()});
90    return;
91  }
92
93  function requestAnimationFrame(callback, opt_this) {
94    pendingRAFs.push({
95      callback: callback,
96      context: opt_this || window,
97      stack: getStack_()});
98    scheduleRAF();
99  }
100  return {
101    onAnimationFrameError: onAnimationFrameError,
102    requestPreAnimationFrame: requestPreAnimationFrame,
103    requestAnimationFrame: requestAnimationFrame,
104    requestAnimationFrameInThisFrameIfPossible:
105        requestAnimationFrameInThisFrameIfPossible
106  };
107});
108