Ticket #139: remove_timeline.patch

File remove_timeline.patch, 21.8 KB (added by beelzy, on 05/20/2014 at 12:31:05 PM)

Apply to commit 972408582c2390594f1bda74b1d8fdde2f4e215b (should be the latest one at time of writing)

  • lib/contentPolicy.js

    From c1a4cfc2cdd97b25ae0c2731739891e213482352 Mon Sep 17 00:00:00 2001
    From: beelzy <beelzy@gmx.de>
    Date: Mon, 19 May 2014 12:52:43 +0200
    Subject: [PATCH] removed references to Timeline and timeline.js
    
    Updated author information
    ---
     lib/contentPolicy.js  |  10 ----
     lib/elemHide.js       |  19 -------
     lib/filterListener.js |   8 ---
     lib/filterStorage.js  |  21 -------
     lib/io.js             |  28 +--------
     lib/main.js           |  11 ----
     lib/notification.js   |   5 --
     lib/synchronizer.js   |   5 --
     lib/timeline.js       | 155 --------------------------------------------------
     9 files changed, 2 insertions(+), 260 deletions(-)
     delete mode 100644 lib/timeline.js
    
    diff --git a/lib/contentPolicy.js b/lib/contentPolicy.js
    index a06e6de..a63a6e3 100644
    a b  
    2222Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 
    2323Cu.import("resource://gre/modules/Services.jsm"); 
    2424 
    25 let {TimeLine} = require("timeline"); 
    2625let {Utils} = require("utils"); 
    2726let {Prefs} = require("prefs"); 
    2827let {FilterStorage} = require("filterStorage"); 
    let Policy = exports.Policy = 
    9089   */ 
    9190  init: function() 
    9291  { 
    93     TimeLine.enter("Entered content policy initialization"); 
    94  
    9592    // type constant by type description and type description by type constant 
    9693    let iface = Ci.nsIContentPolicy; 
    9794    for (let typeName of contentTypes) 
    let Policy = exports.Policy = 
    120117    for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" ")) 
    121118      this.whitelistSchemes[scheme] = true; 
    122119 
    123     TimeLine.log("done initializing types"); 
    124  
    125120    // Generate class identifier used to collapse node and register corresponding 
    126121    // stylesheet. 
    127     TimeLine.log("registering global stylesheet"); 
    128  
    129122    let offset = "a".charCodeAt(0); 
    130123    for (let i = 0; i < 20; i++) 
    131124      collapsedClass +=  String.fromCharCode(offset + Math.random() * 26); 
    let Policy = exports.Policy = 
    138131    { 
    139132      Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET); 
    140133    }) 
    141     TimeLine.log("done registering stylesheet"); 
    142  
    143     TimeLine.leave("Done initializing content policy"); 
    144134  }, 
    145135 
    146136  /** 
  • lib/elemHide.js

    diff --git a/lib/elemHide.js b/lib/elemHide.js
    index b5a1473..37aa3b2 100644
    a b let {Prefs} = require("prefs"); 
    2727let {ElemHideException} = require("filterClasses"); 
    2828let {FilterNotifier} = require("filterNotifier"); 
    2929let {AboutHandler} = require("elemHideHitRegistration"); 
    30 let {TimeLine} = require("timeline"); 
    3130 
    3231/** 
    3332 * Lookup table, filters by their associated key 
    let ElemHide = exports.ElemHide = 
    8281   */ 
    8382  init: function() 
    8483  { 
    85     TimeLine.enter("Entered ElemHide.init()"); 
    8684    Prefs.addListener(function(name) 
    8785    { 
    8886      if (name == "enabled") 
    let ElemHide = exports.ElemHide = 
    9391      ElemHide.unapply(); 
    9492    }); 
    9593 
    96     TimeLine.log("done adding prefs listener"); 
    97  
    9894    let styleFile = IO.resolveFilePath(Prefs.data_directory); 
    9995    styleFile.append("elemhide.css"); 
    10096    styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL); 
    101     TimeLine.log("done determining stylesheet URL"); 
    102  
    103     TimeLine.leave("ElemHide.init() done"); 
    10497  }, 
    10598 
    10699  /** 
    let ElemHide = exports.ElemHide = 
    220213      return; 
    221214    } 
    222215 
    223     TimeLine.enter("Entered ElemHide.apply()"); 
    224  
    225216    if (!ElemHide.isDirty || !Prefs.enabled) 
    226217    { 
    227218      // Nothing changed, looks like we merely got enabled/disabled 
    let ElemHide = exports.ElemHide = 
    236227        { 
    237228          Cu.reportError(e); 
    238229        } 
    239         TimeLine.log("Applying existing stylesheet finished"); 
    240230      } 
    241231      else if (!Prefs.enabled && ElemHide.applied) 
    242232      { 
    243233        ElemHide.unapply(); 
    244         TimeLine.log("ElemHide.unapply() finished"); 
    245234      } 
    246235 
    247       TimeLine.leave("ElemHide.apply() done (no file changes)"); 
    248236      return; 
    249237    } 
    250238 
    251239    IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e) 
    252240    { 
    253       TimeLine.enter("ElemHide.apply() write callback"); 
    254241      this._applying = false; 
    255242 
    256243      // _generateCSSContent is throwing NS_ERROR_NOT_AVAILABLE to indicate that 
    let ElemHide = exports.ElemHide = 
    275262        ElemHide.isDirty = false; 
    276263 
    277264        ElemHide.unapply(); 
    278         TimeLine.log("ElemHide.unapply() finished"); 
    279265 
    280266        if (!noFilters) 
    281267        { 
    let ElemHide = exports.ElemHide = 
    288274          { 
    289275            Cu.reportError(e); 
    290276          } 
    291           TimeLine.log("Applying stylesheet finished"); 
    292277        } 
    293278 
    294279        FilterNotifier.triggerListeners("elemhideupdate"); 
    295280      } 
    296       TimeLine.leave("ElemHide.apply() write callback done"); 
    297281    }.bind(this), "ElemHideWrite"); 
    298282 
    299283    this._applying = true; 
    300284 
    301     TimeLine.leave("ElemHide.apply() done", "ElemHideWrite"); 
    302285  }, 
    303286 
    304287  _generateCSSContent: function() 
    305288  { 
    306289    // Grouping selectors by domains 
    307     TimeLine.log("start grouping selectors"); 
    308290    let domains = {__proto__: null}; 
    309291    let hasFilters = false; 
    310292    for (let key in filterByKey) 
    let ElemHide = exports.ElemHide = 
    323305      list[filter.selector] = key; 
    324306      hasFilters = true; 
    325307    } 
    326     TimeLine.log("done grouping selectors"); 
    327308 
    328309    if (!hasFilters) 
    329310      throw Cr.NS_ERROR_NOT_AVAILABLE; 
  • lib/filterListener.js

    diff --git a/lib/filterListener.js b/lib/filterListener.js
    index 3b5a209..a9b75ea 100644
    a b  
    2222Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 
    2323Cu.import("resource://gre/modules/Services.jsm"); 
    2424 
    25 let {TimeLine} = require("timeline"); 
    2625let {FilterStorage} = require("filterStorage"); 
    2726let {FilterNotifier} = require("filterNotifier"); 
    2827let {ElemHide} = require("elemHide"); 
    let HistoryPurgeObserver = 
    103102 */ 
    104103function init() 
    105104{ 
    106   TimeLine.enter("Entered filter listener initialization()"); 
    107  
    108105  FilterNotifier.addListener(function(action, item, newValue, oldValue) 
    109106  { 
    110107    let match = /^(\w+)\.(.*)/.exec(action); 
    function init() 
    122119    flushElemHide = function() {};    // No global stylesheet in Chrome & Co. 
    123120  FilterStorage.loadFromDisk(); 
    124121 
    125   TimeLine.log("done initializing data structures"); 
    126  
    127122  Services.obs.addObserver(HistoryPurgeObserver, "browser:purge-session-history", true); 
    128123  onShutdown.add(function() 
    129124  { 
    130125    Services.obs.removeObserver(HistoryPurgeObserver, "browser:purge-session-history"); 
    131126  }); 
    132   TimeLine.log("done adding observers"); 
    133  
    134   TimeLine.leave("Filter listener initialization done"); 
    135127} 
    136128init(); 
    137129 
  • lib/filterStorage.js

    diff --git a/lib/filterStorage.js b/lib/filterStorage.js
    index 01b7328..1ff66f7 100644
    a b let {Filter, ActiveFilter} = require("filterClasses"); 
    2929let {Subscription, SpecialSubscription, ExternalSubscription} = require("subscriptionClasses"); 
    3030let {FilterNotifier} = require("filterNotifier"); 
    3131let {Utils} = require("utils"); 
    32 let {TimeLine} = require("timeline"); 
    3332 
    3433/** 
    3534 * Version number of the filter storage file format. 
    let FilterStorage = exports.FilterStorage = 
    365364    if (this._loading) 
    366365      return; 
    367366 
    368     TimeLine.enter("Entered FilterStorage.loadFromDisk()"); 
    369367    this._loading = true; 
    370368 
    371369    let readFile = function(sourceFile, backupIndex) 
    372370    { 
    373       TimeLine.enter("FilterStorage.loadFromDisk() -> readFile()"); 
    374371 
    375372      let parser = new INIParser(); 
    376373      IO.readFromFile(sourceFile, parser, function(e) 
    377374      { 
    378         TimeLine.enter("FilterStorage.loadFromDisk() read callback"); 
    379375        if (!e && parser.subscriptions.length == 0) 
    380376        { 
    381377          // No filter subscriptions in the file, this isn't right. 
    let FilterStorage = exports.FilterStorage = 
    403399              else 
    404400                doneReading(parser); 
    405401            }); 
    406             TimeLine.leave("FilterStorage.loadFromDisk() read callback done"); 
    407402            return; 
    408403          } 
    409404        } 
    410405        doneReading(parser); 
    411406      }.bind(this), "FilterStorageRead"); 
    412407 
    413       TimeLine.leave("FilterStorage.loadFromDisk() <- readFile()", "FilterStorageRead"); 
    414408    }.bind(this); 
    415409 
    416410    var doneReading = function(parser) 
    let FilterStorage = exports.FilterStorage = 
    441435          this.addFilter(filter, null, undefined, true); 
    442436        } 
    443437      } 
    444       TimeLine.log("Initializing data done, triggering observers") 
    445438 
    446439      this._loading = false; 
    447440      FilterNotifier.triggerListeners("load"); 
    let FilterStorage = exports.FilterStorage = 
    449442      if (sourceFile != this.sourceFile) 
    450443        this.saveToDisk(); 
    451444 
    452       TimeLine.leave("FilterStorage.loadFromDisk() read callback done"); 
    453445    }.bind(this); 
    454446 
    455447    let explicitFile; 
    let FilterStorage = exports.FilterStorage = 
    471463          this._loading = false; 
    472464          FilterNotifier.triggerListeners("load"); 
    473465 
    474           TimeLine.leave("FilterStorage.loadFromDisk() read callback done"); 
    475466        } 
    476467        else 
    477468          readFile(sourceFile, 0); 
    let FilterStorage = exports.FilterStorage = 
    483474        callback(true); 
    484475    } 
    485476 
    486     TimeLine.leave("FilterStorage.loadFromDisk() done"); 
    487477  }, 
    488478 
    489479  _generateFilterData: function(subscriptions) 
    let FilterStorage = exports.FilterStorage = 
    565555      return; 
    566556    } 
    567557 
    568     TimeLine.enter("Entered FilterStorage.saveToDisk()"); 
    569  
    570558    // Make sure the file's parent directory exists 
    571559    try { 
    572560      targetFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); 
    let FilterStorage = exports.FilterStorage = 
    574562 
    575563    let writeFilters = function() 
    576564    { 
    577       TimeLine.enter("FilterStorage.saveToDisk() -> writeFilters()"); 
    578565      IO.writeToFile(targetFile, this._generateFilterData(subscriptions), function(e) 
    579566      { 
    580         TimeLine.enter("FilterStorage.saveToDisk() write callback"); 
    581567        if (!explicitFile) 
    582568          this._saving = false; 
    583569 
    let FilterStorage = exports.FilterStorage = 
    591577        } 
    592578        else 
    593579          FilterNotifier.triggerListeners("save"); 
    594         TimeLine.leave("FilterStorage.saveToDisk() write callback done"); 
    595580      }.bind(this), "FilterStorageWrite"); 
    596       TimeLine.leave("FilterStorage.saveToDisk() -> writeFilters()", "FilterStorageWrite"); 
    597581    }.bind(this); 
    598582 
    599583    let checkBackupRequired = function(callbackNotRequired, callbackRequired) 
    let FilterStorage = exports.FilterStorage = 
    625609 
    626610    let removeLastBackup = function(part1, part2) 
    627611    { 
    628       TimeLine.enter("FilterStorage.saveToDisk() -> removeLastBackup()"); 
    629612      let file = targetFile.clone(); 
    630613      file.leafName = part1 + "-backup" + Prefs.patternsbackups + part2; 
    631614      IO.removeFile(file, function(e) renameBackup(part1, part2, Prefs.patternsbackups - 1)); 
    632       TimeLine.leave("FilterStorage.saveToDisk() <- removeLastBackup()"); 
    633615    }.bind(this); 
    634616 
    635617    let renameBackup = function(part1, part2, index) 
    636618    { 
    637       TimeLine.enter("FilterStorage.saveToDisk() -> renameBackup()"); 
    638619      if (index > 0) 
    639620      { 
    640621        let fromFile = targetFile.clone(); 
    let FilterStorage = exports.FilterStorage = 
    651632 
    652633        IO.copyFile(targetFile, toFile, writeFilters); 
    653634      } 
    654       TimeLine.leave("FilterStorage.saveToDisk() <- renameBackup()"); 
    655635    }.bind(this); 
    656636 
    657637    // Do not persist external subscriptions 
    let FilterStorage = exports.FilterStorage = 
    661641 
    662642    checkBackupRequired(writeFilters, removeLastBackup); 
    663643 
    664     TimeLine.leave("FilterStorage.saveToDisk() done"); 
    665644  }, 
    666645 
    667646  /** 
  • lib/io.js

    diff --git a/lib/io.js b/lib/io.js
    index aa2effc..5bdb2d7 100644
    a b let {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", null); 
    2424let {OS} = Cu.import("resource://gre/modules/osfile.jsm", null); 
    2525let {Task} = Cu.import("resource://gre/modules/Task.jsm", null); 
    2626 
    27 let {TimeLine} = require("timeline"); 
    2827let {Utils} = require("utils"); 
    2928 
    3029const BUFFER_SIZE = 0x8000;  // 32kB 
    let IO = exports.IO = 
    6968   * each line read and with a null parameter once the read operation is done. 
    7069   * The callback will be called when the operation is done. 
    7170   */ 
    72   readFromFile: function(/**nsIFile*/ file, /**Object*/ listener, /**Function*/ callback, /**String*/ timeLineID) 
     71  readFromFile: function(/**nsIFile*/ file, /**Object*/ listener, /**Function*/ callback) 
    7372  { 
    7473    try 
    7574    { 
    let IO = exports.IO = 
    8079 
    8180      let onProgress = function(data) 
    8281      { 
    83         if (timeLineID) 
    84         { 
    85           TimeLine.asyncStart(timeLineID); 
    86         } 
    8782 
    8883        let index = (processing ? -1 : Math.max(data.lastIndexOf("\n"), data.lastIndexOf("\r"))); 
    8984        if (index >= 0) 
    let IO = exports.IO = 
    125120        else 
    126121          buffer += data; 
    127122 
    128         if (timeLineID) 
    129         { 
    130           TimeLine.asyncEnd(timeLineID); 
    131         } 
    132123      }; 
    133124 
    134125      let onSuccess = function() 
    let IO = exports.IO = 
    140131          return; 
    141132        } 
    142133 
    143         if (timeLineID) 
    144         { 
    145           TimeLine.asyncStart(timeLineID); 
    146         } 
    147  
    148134        if (buffer !== "") 
    149135          listener.process(buffer); 
    150136        listener.process(null); 
    151137 
    152         if (timeLineID) 
    153         { 
    154           TimeLine.asyncEnd(timeLineID); 
    155           TimeLine.asyncDone(timeLineID); 
    156         } 
    157  
    158138        callback(null); 
    159139      }; 
    160140 
    let IO = exports.IO = 
    169149 
    170150        callback(e); 
    171151 
    172         if (timeLineID) 
    173         { 
    174           TimeLine.asyncDone(timeLineID); 
    175         } 
    176152      }; 
    177153 
    178154      let decoder = new TextDecoder(); 
    let IO = exports.IO = 
    206182   * Writes string data to a file in UTF-8 format asynchronously. The callback 
    207183   * will be called when the write operation is done. 
    208184   */ 
    209   writeToFile: function(/**nsIFile*/ file, /**Iterator*/ data, /**Function*/ callback, /**String*/ timeLineID) 
     185  writeToFile: function(/**nsIFile*/ file, /**Iterator*/ data, /**Function*/ callback) 
    210186  { 
    211187    try 
    212188    { 
  • lib/main.js

    diff --git a/lib/main.js b/lib/main.js
    index f18cc05..a065de0 100644
    a b  
    2222Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 
    2323Cu.import("resource://gre/modules/Services.jsm"); 
    2424 
    25 let {TimeLine} = require("timeline"); 
    26  
    27 TimeLine.enter("Adblock Plus startup"); 
    2825registerPublicAPI(); 
    29 TimeLine.log("Done registering public API"); 
    3026require("filterListener"); 
    31 TimeLine.log("Done loading filter listener"); 
    3227require("contentPolicy"); 
    33 TimeLine.log("Done loading content policy"); 
    3428require("synchronizer"); 
    35 TimeLine.log("Done loading subscription synchronizer"); 
    3629require("notification"); 
    37 TimeLine.log("Done loading notification downloader"); 
    3830require("sync"); 
    39 TimeLine.log("Done loading sync support"); 
    4031require("ui"); 
    41 TimeLine.log("Done loading UI integration code"); 
    42 TimeLine.leave("Started up"); 
    4332 
    4433function registerPublicAPI() 
    4534{ 
  • lib/notification.js

    diff --git a/lib/notification.js b/lib/notification.js
    index 06e949e..b00d24c 100644
    a b  
    2121 
    2222Cu.import("resource://gre/modules/Services.jsm"); 
    2323 
    24 let {TimeLine} = require("timeline"); 
    2524let {Prefs} = require("prefs"); 
    2625let {Downloader, Downloadable, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); 
    2726let {Utils} = require("utils"); 
    let Notification = exports.Notification = 
    8180   */ 
    8281  init: function() 
    8382  { 
    84     TimeLine.enter("Entered Notification.init()"); 
    85  
    8683    downloader = new Downloader(this._getDownloadables.bind(this), INITIAL_DELAY, CHECK_INTERVAL); 
    8784    onShutdown.add(function() 
    8885    { 
    let Notification = exports.Notification = 
    9289    downloader.onExpirationChange = this._onExpirationChange.bind(this); 
    9390    downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this); 
    9491    downloader.onDownloadError = this._onDownloadError.bind(this); 
    95  
    96     TimeLine.leave("Notification.init() done"); 
    9792  }, 
    9893 
    9994  /** 
  • lib/synchronizer.js

    diff --git a/lib/synchronizer.js b/lib/synchronizer.js
    index 590ad73..47e400e 100644
    a b  
    2222Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 
    2323Cu.import("resource://gre/modules/Services.jsm"); 
    2424 
    25 let {TimeLine} = require("timeline"); 
    2625let {Downloader, Downloadable, 
    2726    MILLIS_IN_SECOND, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); 
    2827let {Filter, CommentFilter} = require("filterClasses"); 
    let Synchronizer = exports.Synchronizer = 
    5453   */ 
    5554  init: function() 
    5655  { 
    57     TimeLine.enter("Entered Synchronizer.init()"); 
    58  
    5956    downloader = new Downloader(this._getDownloadables.bind(this), INITIAL_DELAY, CHECK_INTERVAL); 
    6057    onShutdown.add(function() 
    6158    { 
    let Synchronizer = exports.Synchronizer = 
    6663    downloader.onDownloadStarted = this._onDownloadStarted.bind(this); 
    6764    downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this); 
    6865    downloader.onDownloadError = this._onDownloadError.bind(this); 
    69  
    70     TimeLine.leave("Synchronizer.init() done"); 
    7166  }, 
    7267 
    7368  /** 
  • deleted file lib/timeline.js

    diff --git a/lib/timeline.js b/lib/timeline.js
    deleted file mode 100644
    index 18c10fb..0000000
    + -  
    1 /* 
    2  * This file is part of Adblock Plus <http://adblockplus.org/>, 
    3  * Copyright (C) 2006-2014 Eyeo GmbH 
    4  * 
    5  * Adblock Plus is free software: you can redistribute it and/or modify 
    6  * it under the terms of the GNU General Public License version 3 as 
    7  * published by the Free Software Foundation. 
    8  * 
    9  * Adblock Plus is distributed in the hope that it will be useful, 
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    12  * GNU General Public License for more details. 
    13  * 
    14  * You should have received a copy of the GNU General Public License 
    15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. 
    16  */ 
    17  
    18 /** 
    19  * @fileOverview Debugging module used for load time measurements. 
    20  */ 
    21  
    22 let nestingCounter = 0; 
    23 let firstTimeStamp = null; 
    24 let lastTimeStamp = null; 
    25  
    26 let asyncActions = {__proto__: null}; 
    27  
    28 /** 
    29  * Time logging module, used to measure startup time of Adblock Plus (development builds only). 
    30  * @class 
    31  */ 
    32 let TimeLine = exports.TimeLine = { 
    33   /** 
    34    * Logs an event to console together with the time it took to get there. 
    35    */ 
    36   log: function(/**String*/ message, /**Boolean*/ _forceDisplay) 
    37   { 
    38     if (!_forceDisplay && nestingCounter <= 0) 
    39       return; 
    40  
    41     let now = Date.now(); 
    42     let diff = lastTimeStamp ? Math.round(now - lastTimeStamp) : "first event"; 
    43     lastTimeStamp = now; 
    44  
    45     // Indent message depending on current nesting level 
    46     for (let i = 0; i < nestingCounter; i++) 
    47       message = "* " + message; 
    48  
    49     // Pad message with spaces 
    50     let padding = []; 
    51     for (let i = message.toString().length; i < 80; i++) 
    52       padding.push(" "); 
    53     dump("[" + now + "] ABP timeline: " + message + padding.join("") + "\t (" + diff + ")\n"); 
    54   }, 
    55  
    56   /** 
    57    * Called to indicate that application entered a block that needs to be timed. 
    58    */ 
    59   enter: function(/**String*/ message) 
    60   { 
    61     if (nestingCounter <= 0) 
    62       firstTimeStamp = Date.now(); 
    63  
    64     this.log(message, true); 
    65     nestingCounter = (nestingCounter <= 0 ? 1 : nestingCounter + 1); 
    66   }, 
    67  
    68   /** 
    69    * Called when application exited a block that TimeLine.enter() was called for. 
    70    * @param {String} message  message to be logged 
    71    * @param {String} [asyncAction]  identifier of a pending async action 
    72    */ 
    73   leave: function(message, asyncAction) 
    74   { 
    75     if (typeof asyncAction != "undefined") 
    76       message += " (async action pending)"; 
    77  
    78     nestingCounter--; 
    79     this.log(message, true); 
    80  
    81     if (nestingCounter <= 0) 
    82     { 
    83       if (firstTimeStamp !== null) 
    84         dump("ABP timeline: Total time elapsed: " + Math.round(Date.now() - firstTimeStamp) + "\n"); 
    85       firstTimeStamp = null; 
    86       lastTimeStamp = null; 
    87     } 
    88  
    89     if (typeof asyncAction != "undefined") 
    90     { 
    91       if (asyncAction in asyncActions) 
    92         dump("ABP timeline: Warning: Async action " + asyncAction + " already executing\n"); 
    93       asyncActions[asyncAction] = {start: Date.now(), total: 0}; 
    94     } 
    95   }, 
    96  
    97   /** 
    98    * Called when the application starts processing of an async action. 
    99    */ 
    100   asyncStart: function(/**String*/ asyncAction) 
    101   { 
    102     if (asyncAction in asyncActions) 
    103     { 
    104       let action = asyncActions[asyncAction]; 
    105       if ("currentStart" in action) 
    106         dump("ABP timeline: Warning: Processing reentered for async action " + asyncAction + "\n"); 
    107       action.currentStart = Date.now(); 
    108     } 
    109     else 
    110       dump("ABP timeline: Warning: Async action " + asyncAction + " is unknown\n"); 
    111   }, 
    112  
    113   /** 
    114    * Called when the application finishes processing of an async action. 
    115    */ 
    116   asyncEnd: function(/**String*/ asyncAction) 
    117   { 
    118     if (asyncAction in asyncActions) 
    119     { 
    120       let action = asyncActions[asyncAction]; 
    121       if ("currentStart" in action) 
    122       { 
    123         action.total += Date.now() - action.currentStart; 
    124         delete action.currentStart; 
    125       } 
    126       else 
    127         dump("ABP timeline: Warning: Processing not entered for async action " + asyncAction + "\n"); 
    128     } 
    129     else 
    130       dump("ABP timeline: Warning: Async action " + asyncAction + " is unknown\n"); 
    131   }, 
    132  
    133   /** 
    134    * Called when an async action is done and its time can be logged. 
    135    */ 
    136   asyncDone: function(/**String*/ asyncAction) 
    137   { 
    138     if (asyncAction in asyncActions) 
    139     { 
    140       let action = asyncActions[asyncAction]; 
    141       let now = Date.now(); 
    142       let diff = now - action.start; 
    143       if ("currentStart" in action) 
    144         dump("ABP timeline: Warning: Still processing for async action " + asyncAction + "\n"); 
    145  
    146       let message = "Async action " + asyncAction + " done"; 
    147       let padding = []; 
    148       for (let i = message.toString().length; i < 80; i++) 
    149         padding.push(" "); 
    150       dump("[" + now + "] ABP timeline: " + message + padding.join("") + "\t (" + action.total + "/" + diff + ")\n"); 
    151     } 
    152     else 
    153       dump("ABP timeline: Warning: Async action " + asyncAction + " is unknown\n"); 
    154   } 
    155 };