| Index: chrome/renderer/resources/extensions/event.js | 
| diff --git a/chrome/renderer/resources/extensions/event.js b/chrome/renderer/resources/extensions/event.js | 
| deleted file mode 100644 | 
| index 74f3ee0688fa5a736f1cfd30fa630c0ed1f6e2f8..0000000000000000000000000000000000000000 | 
| --- a/chrome/renderer/resources/extensions/event.js | 
| +++ /dev/null | 
| @@ -1,528 +0,0 @@ | 
| -// Copyright (c) 2012 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. | 
| - | 
| -  var eventNatives = requireNative('event_natives'); | 
| -  var handleUncaughtException = require('uncaught_exception_handler').handle; | 
| -  var logging = requireNative('logging'); | 
| -  var schemaRegistry = requireNative('schema_registry'); | 
| -  var sendRequest = require('sendRequest').sendRequest; | 
| -  var utils = require('utils'); | 
| -  var validate = require('schemaUtils').validate; | 
| -  var unloadEvent = require('unload_event'); | 
| - | 
| -  // Schemas for the rule-style functions on the events API that | 
| -  // only need to be generated occasionally, so populate them lazily. | 
| -  var ruleFunctionSchemas = { | 
| -    // These values are set lazily: | 
| -    // addRules: {}, | 
| -    // getRules: {}, | 
| -    // removeRules: {} | 
| -  }; | 
| - | 
| -  // This function ensures that |ruleFunctionSchemas| is populated. | 
| -  function ensureRuleSchemasLoaded() { | 
| -    if (ruleFunctionSchemas.addRules) | 
| -      return; | 
| -    var eventsSchema = schemaRegistry.GetSchema("events"); | 
| -    var eventType = utils.lookup(eventsSchema.types, 'id', 'events.Event'); | 
| - | 
| -    ruleFunctionSchemas.addRules = | 
| -        utils.lookup(eventType.functions, 'name', 'addRules'); | 
| -    ruleFunctionSchemas.getRules = | 
| -        utils.lookup(eventType.functions, 'name', 'getRules'); | 
| -    ruleFunctionSchemas.removeRules = | 
| -        utils.lookup(eventType.functions, 'name', 'removeRules'); | 
| -  } | 
| - | 
| -  // A map of event names to the event object that is registered to that name. | 
| -  var attachedNamedEvents = {}; | 
| - | 
| -  // An array of all attached event objects, used for detaching on unload. | 
| -  var allAttachedEvents = []; | 
| - | 
| -  // A map of functions that massage event arguments before they are dispatched. | 
| -  // Key is event name, value is function. | 
| -  var eventArgumentMassagers = {}; | 
| - | 
| -  // An attachment strategy for events that aren't attached to the browser. | 
| -  // This applies to events with the "unmanaged" option and events without | 
| -  // names. | 
| -  var NullAttachmentStrategy = function(event) { | 
| -    this.event_ = event; | 
| -  }; | 
| -  NullAttachmentStrategy.prototype.onAddedListener = | 
| -      function(listener) { | 
| -  }; | 
| -  NullAttachmentStrategy.prototype.onRemovedListener = | 
| -      function(listener) { | 
| -  }; | 
| -  NullAttachmentStrategy.prototype.detach = function(manual) { | 
| -  }; | 
| -  NullAttachmentStrategy.prototype.getListenersByIDs = function(ids) { | 
| -    // |ids| is for filtered events only. | 
| -    return this.event_.listeners; | 
| -  }; | 
| - | 
| -  // Handles adding/removing/dispatching listeners for unfiltered events. | 
| -  var UnfilteredAttachmentStrategy = function(event) { | 
| -    this.event_ = event; | 
| -  }; | 
| - | 
| -  UnfilteredAttachmentStrategy.prototype.onAddedListener = | 
| -      function(listener) { | 
| -    // Only attach / detach on the first / last listener removed. | 
| -    if (this.event_.listeners.length == 0) | 
| -      eventNatives.AttachEvent(this.event_.eventName); | 
| -  }; | 
| - | 
| -  UnfilteredAttachmentStrategy.prototype.onRemovedListener = | 
| -      function(listener) { | 
| -    if (this.event_.listeners.length == 0) | 
| -      this.detach(true); | 
| -  }; | 
| - | 
| -  UnfilteredAttachmentStrategy.prototype.detach = function(manual) { | 
| -    eventNatives.DetachEvent(this.event_.eventName, manual); | 
| -  }; | 
| - | 
| -  UnfilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { | 
| -    // |ids| is for filtered events only. | 
| -    return this.event_.listeners; | 
| -  }; | 
| - | 
| -  var FilteredAttachmentStrategy = function(event) { | 
| -    this.event_ = event; | 
| -    this.listenerMap_ = {}; | 
| -  }; | 
| - | 
| -  FilteredAttachmentStrategy.idToEventMap = {}; | 
| - | 
| -  FilteredAttachmentStrategy.prototype.onAddedListener = function(listener) { | 
| -    var id = eventNatives.AttachFilteredEvent(this.event_.eventName, | 
| -                                              listener.filters || {}); | 
| -    if (id == -1) | 
| -      throw new Error("Can't add listener"); | 
| -    listener.id = id; | 
| -    this.listenerMap_[id] = listener; | 
| -    FilteredAttachmentStrategy.idToEventMap[id] = this.event_; | 
| -  }; | 
| - | 
| -  FilteredAttachmentStrategy.prototype.onRemovedListener = function(listener) { | 
| -    this.detachListener(listener, true); | 
| -  }; | 
| - | 
| -  FilteredAttachmentStrategy.prototype.detachListener = | 
| -      function(listener, manual) { | 
| -    if (listener.id == undefined) | 
| -      throw new Error("listener.id undefined - '" + listener + "'"); | 
| -    var id = listener.id; | 
| -    delete this.listenerMap_[id]; | 
| -    delete FilteredAttachmentStrategy.idToEventMap[id]; | 
| -    eventNatives.DetachFilteredEvent(id, manual); | 
| -  }; | 
| - | 
| -  FilteredAttachmentStrategy.prototype.detach = function(manual) { | 
| -    for (var i in this.listenerMap_) | 
| -      this.detachListener(this.listenerMap_[i], manual); | 
| -  }; | 
| - | 
| -  FilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { | 
| -    var result = []; | 
| -    for (var i = 0; i < ids.length; i++) | 
| -      $Array.push(result, this.listenerMap_[ids[i]]); | 
| -    return result; | 
| -  }; | 
| - | 
| -  function parseEventOptions(opt_eventOptions) { | 
| -    function merge(dest, src) { | 
| -      for (var k in src) { | 
| -        if (!$Object.hasOwnProperty(dest, k)) { | 
| -          dest[k] = src[k]; | 
| -        } | 
| -      } | 
| -    } | 
| - | 
| -    var options = opt_eventOptions || {}; | 
| -    merge(options, { | 
| -      // Event supports adding listeners with filters ("filtered events"), for | 
| -      // example as used in the webNavigation API. | 
| -      // | 
| -      // event.addListener(listener, [filter1, filter2]); | 
| -      supportsFilters: false, | 
| - | 
| -      // Events supports vanilla events. Most APIs use these. | 
| -      // | 
| -      // event.addListener(listener); | 
| -      supportsListeners: true, | 
| - | 
| -      // Event supports adding rules ("declarative events") rather than | 
| -      // listeners, for example as used in the declarativeWebRequest API. | 
| -      // | 
| -      // event.addRules([rule1, rule2]); | 
| -      supportsRules: false, | 
| - | 
| -      // Event is unmanaged in that the browser has no knowledge of its | 
| -      // existence; it's never invoked, doesn't keep the renderer alive, and | 
| -      // the bindings system has no knowledge of it. | 
| -      // | 
| -      // Both events created by user code (new chrome.Event()) and messaging | 
| -      // events are unmanaged, though in the latter case the browser *does* | 
| -      // interact indirectly with them via IPCs written by hand. | 
| -      unmanaged: false, | 
| -    }); | 
| -    return options; | 
| -  }; | 
| - | 
| -  // Event object.  If opt_eventName is provided, this object represents | 
| -  // the unique instance of that named event, and dispatching an event | 
| -  // with that name will route through this object's listeners. Note that | 
| -  // opt_eventName is required for events that support rules. | 
| -  // | 
| -  // Example: | 
| -  //   var Event = require('event_bindings').Event; | 
| -  //   chrome.tabs.onChanged = new Event("tab-changed"); | 
| -  //   chrome.tabs.onChanged.addListener(function(data) { alert(data); }); | 
| -  //   Event.dispatch("tab-changed", "hi"); | 
| -  // will result in an alert dialog that says 'hi'. | 
| -  // | 
| -  // If opt_eventOptions exists, it is a dictionary that contains the boolean | 
| -  // entries "supportsListeners" and "supportsRules". | 
| -  // If opt_webViewInstanceId exists, it is an integer uniquely identifying a | 
| -  // <webview> tag within the embedder. If it does not exist, then this is an | 
| -  // extension event rather than a <webview> event. | 
| -  var EventImpl = function(opt_eventName, opt_argSchemas, opt_eventOptions, | 
| -                           opt_webViewInstanceId) { | 
| -    this.eventName = opt_eventName; | 
| -    this.argSchemas = opt_argSchemas; | 
| -    this.listeners = []; | 
| -    this.eventOptions = parseEventOptions(opt_eventOptions); | 
| -    this.webViewInstanceId = opt_webViewInstanceId || 0; | 
| - | 
| -    if (!this.eventName) { | 
| -      if (this.eventOptions.supportsRules) | 
| -        throw new Error("Events that support rules require an event name."); | 
| -      // Events without names cannot be managed by the browser by definition | 
| -      // (the browser has no way of identifying them). | 
| -      this.eventOptions.unmanaged = true; | 
| -    } | 
| - | 
| -    // Track whether the event has been destroyed to help track down the cause | 
| -    // of http://crbug.com/258526. | 
| -    // This variable will eventually hold the stack trace of the destroy call. | 
| -    // TODO(kalman): Delete this and replace with more sound logic that catches | 
| -    // when events are used without being *attached*. | 
| -    this.destroyed = null; | 
| - | 
| -    if (this.eventOptions.unmanaged) | 
| -      this.attachmentStrategy = new NullAttachmentStrategy(this); | 
| -    else if (this.eventOptions.supportsFilters) | 
| -      this.attachmentStrategy = new FilteredAttachmentStrategy(this); | 
| -    else | 
| -      this.attachmentStrategy = new UnfilteredAttachmentStrategy(this); | 
| -  }; | 
| - | 
| -  // callback is a function(args, dispatch). args are the args we receive from | 
| -  // dispatchEvent(), and dispatch is a function(args) that dispatches args to | 
| -  // its listeners. | 
| -  function registerArgumentMassager(name, callback) { | 
| -    if (eventArgumentMassagers[name]) | 
| -      throw new Error("Massager already registered for event: " + name); | 
| -    eventArgumentMassagers[name] = callback; | 
| -  } | 
| - | 
| -  // Dispatches a named event with the given argument array. The args array is | 
| -  // the list of arguments that will be sent to the event callback. | 
| -  function dispatchEvent(name, args, filteringInfo) { | 
| -    var listenerIDs = []; | 
| - | 
| -    if (filteringInfo) | 
| -      listenerIDs = eventNatives.MatchAgainstEventFilter(name, filteringInfo); | 
| - | 
| -    var event = attachedNamedEvents[name]; | 
| -    if (!event) | 
| -      return; | 
| - | 
| -    var dispatchArgs = function(args) { | 
| -      var result = event.dispatch_(args, listenerIDs); | 
| -      if (result) | 
| -        logging.DCHECK(!result.validationErrors, result.validationErrors); | 
| -      return result; | 
| -    }; | 
| - | 
| -    if (eventArgumentMassagers[name]) | 
| -      eventArgumentMassagers[name](args, dispatchArgs); | 
| -    else | 
| -      dispatchArgs(args); | 
| -  } | 
| - | 
| -  // Registers a callback to be called when this event is dispatched. | 
| -  EventImpl.prototype.addListener = function(cb, filters) { | 
| -    if (!this.eventOptions.supportsListeners) | 
| -      throw new Error("This event does not support listeners."); | 
| -    if (this.eventOptions.maxListeners && | 
| -        this.getListenerCount_() >= this.eventOptions.maxListeners) { | 
| -      throw new Error("Too many listeners for " + this.eventName); | 
| -    } | 
| -    if (filters) { | 
| -      if (!this.eventOptions.supportsFilters) | 
| -        throw new Error("This event does not support filters."); | 
| -      if (filters.url && !(filters.url instanceof Array)) | 
| -        throw new Error("filters.url should be an array."); | 
| -      if (filters.serviceType && | 
| -          !(typeof filters.serviceType === 'string')) { | 
| -        throw new Error("filters.serviceType should be a string.") | 
| -      } | 
| -    } | 
| -    var listener = {callback: cb, filters: filters}; | 
| -    this.attach_(listener); | 
| -    $Array.push(this.listeners, listener); | 
| -  }; | 
| - | 
| -  EventImpl.prototype.attach_ = function(listener) { | 
| -    this.attachmentStrategy.onAddedListener(listener); | 
| - | 
| -    if (this.listeners.length == 0) { | 
| -      allAttachedEvents[allAttachedEvents.length] = this; | 
| -      if (this.eventName) { | 
| -        if (attachedNamedEvents[this.eventName]) { | 
| -          throw new Error("Event '" + this.eventName + | 
| -                          "' is already attached."); | 
| -        } | 
| -        attachedNamedEvents[this.eventName] = this; | 
| -      } | 
| -    } | 
| -  }; | 
| - | 
| -  // Unregisters a callback. | 
| -  EventImpl.prototype.removeListener = function(cb) { | 
| -    if (!this.eventOptions.supportsListeners) | 
| -      throw new Error("This event does not support listeners."); | 
| - | 
| -    var idx = this.findListener_(cb); | 
| -    if (idx == -1) | 
| -      return; | 
| - | 
| -    var removedListener = $Array.splice(this.listeners, idx, 1)[0]; | 
| -    this.attachmentStrategy.onRemovedListener(removedListener); | 
| - | 
| -    if (this.listeners.length == 0) { | 
| -      var i = $Array.indexOf(allAttachedEvents, this); | 
| -      if (i >= 0) | 
| -        delete allAttachedEvents[i]; | 
| -      if (this.eventName) { | 
| -        if (!attachedNamedEvents[this.eventName]) { | 
| -          throw new Error( | 
| -              "Event '" + this.eventName + "' is not attached."); | 
| -        } | 
| -        delete attachedNamedEvents[this.eventName]; | 
| -      } | 
| -    } | 
| -  }; | 
| - | 
| -  // Test if the given callback is registered for this event. | 
| -  EventImpl.prototype.hasListener = function(cb) { | 
| -    if (!this.eventOptions.supportsListeners) | 
| -      throw new Error("This event does not support listeners."); | 
| -    return this.findListener_(cb) > -1; | 
| -  }; | 
| - | 
| -  // Test if any callbacks are registered for this event. | 
| -  EventImpl.prototype.hasListeners = function() { | 
| -    return this.getListenerCount_() > 0; | 
| -  }; | 
| - | 
| -  // Returns the number of listeners on this event. | 
| -  EventImpl.prototype.getListenerCount_ = function() { | 
| -    if (!this.eventOptions.supportsListeners) | 
| -      throw new Error("This event does not support listeners."); | 
| -    return this.listeners.length; | 
| -  }; | 
| - | 
| -  // Returns the index of the given callback if registered, or -1 if not | 
| -  // found. | 
| -  EventImpl.prototype.findListener_ = function(cb) { | 
| -    for (var i = 0; i < this.listeners.length; i++) { | 
| -      if (this.listeners[i].callback == cb) { | 
| -        return i; | 
| -      } | 
| -    } | 
| - | 
| -    return -1; | 
| -  }; | 
| - | 
| -  EventImpl.prototype.dispatch_ = function(args, listenerIDs) { | 
| -    if (this.destroyed) { | 
| -      throw new Error(this.eventName + ' was already destroyed at: ' + | 
| -                      this.destroyed); | 
| -    } | 
| -    if (!this.eventOptions.supportsListeners) | 
| -      throw new Error("This event does not support listeners."); | 
| - | 
| -    if (this.argSchemas && logging.DCHECK_IS_ON()) { | 
| -      try { | 
| -        validate(args, this.argSchemas); | 
| -      } catch (e) { | 
| -        e.message += ' in ' + this.eventName; | 
| -        throw e; | 
| -      } | 
| -    } | 
| - | 
| -    // Make a copy of the listeners in case the listener list is modified | 
| -    // while dispatching the event. | 
| -    var listeners = $Array.slice( | 
| -        this.attachmentStrategy.getListenersByIDs(listenerIDs)); | 
| - | 
| -    var results = []; | 
| -    for (var i = 0; i < listeners.length; i++) { | 
| -      try { | 
| -        var result = this.wrapper.dispatchToListener(listeners[i].callback, | 
| -                                                     args); | 
| -        if (result !== undefined) | 
| -          $Array.push(results, result); | 
| -      } catch (e) { | 
| -        handleUncaughtException( | 
| -          'Error in event handler for ' + | 
| -              (this.eventName ? this.eventName : '(unknown)') + | 
| -              ': ' + e.message + '\nStack trace: ' + e.stack, | 
| -          e); | 
| -      } | 
| -    } | 
| -    if (results.length) | 
| -      return {results: results}; | 
| -  } | 
| - | 
| -  // Can be overridden to support custom dispatching. | 
| -  EventImpl.prototype.dispatchToListener = function(callback, args) { | 
| -    return $Function.apply(callback, null, args); | 
| -  } | 
| - | 
| -  // Dispatches this event object to all listeners, passing all supplied | 
| -  // arguments to this function each listener. | 
| -  EventImpl.prototype.dispatch = function(varargs) { | 
| -    return this.dispatch_($Array.slice(arguments), undefined); | 
| -  }; | 
| - | 
| -  // Detaches this event object from its name. | 
| -  EventImpl.prototype.detach_ = function() { | 
| -    this.attachmentStrategy.detach(false); | 
| -  }; | 
| - | 
| -  EventImpl.prototype.destroy_ = function() { | 
| -    this.listeners.length = 0; | 
| -    this.detach_(); | 
| -    this.destroyed = new Error().stack; | 
| -  }; | 
| - | 
| -  EventImpl.prototype.addRules = function(rules, opt_cb) { | 
| -    if (!this.eventOptions.supportsRules) | 
| -      throw new Error("This event does not support rules."); | 
| - | 
| -    // Takes a list of JSON datatype identifiers and returns a schema fragment | 
| -    // that verifies that a JSON object corresponds to an array of only these | 
| -    // data types. | 
| -    function buildArrayOfChoicesSchema(typesList) { | 
| -      return { | 
| -        'type': 'array', | 
| -        'items': { | 
| -          'choices': typesList.map(function(el) {return {'$ref': el};}) | 
| -        } | 
| -      }; | 
| -    }; | 
| - | 
| -    // Validate conditions and actions against specific schemas of this | 
| -    // event object type. | 
| -    // |rules| is an array of JSON objects that follow the Rule type of the | 
| -    // declarative extension APIs. |conditions| is an array of JSON type | 
| -    // identifiers that are allowed to occur in the conditions attribute of each | 
| -    // rule. Likewise, |actions| is an array of JSON type identifiers that are | 
| -    // allowed to occur in the actions attribute of each rule. | 
| -    function validateRules(rules, conditions, actions) { | 
| -      var conditionsSchema = buildArrayOfChoicesSchema(conditions); | 
| -      var actionsSchema = buildArrayOfChoicesSchema(actions); | 
| -      $Array.forEach(rules, function(rule) { | 
| -        validate([rule.conditions], [conditionsSchema]); | 
| -        validate([rule.actions], [actionsSchema]); | 
| -      }); | 
| -    }; | 
| - | 
| -    if (!this.eventOptions.conditions || !this.eventOptions.actions) { | 
| -      throw new Error('Event ' + this.eventName + ' misses ' + | 
| -                      'conditions or actions in the API specification.'); | 
| -    } | 
| - | 
| -    validateRules(rules, | 
| -                  this.eventOptions.conditions, | 
| -                  this.eventOptions.actions); | 
| - | 
| -    ensureRuleSchemasLoaded(); | 
| -    // We remove the first parameter from the validation to give the user more | 
| -    // meaningful error messages. | 
| -    validate([this.webViewInstanceId, rules, opt_cb], | 
| -             $Array.splice( | 
| -                 $Array.slice(ruleFunctionSchemas.addRules.parameters), 1)); | 
| -    sendRequest( | 
| -      "events.addRules", | 
| -      [this.eventName, this.webViewInstanceId, rules,  opt_cb], | 
| -      ruleFunctionSchemas.addRules.parameters); | 
| -  } | 
| - | 
| -  EventImpl.prototype.removeRules = function(ruleIdentifiers, opt_cb) { | 
| -    if (!this.eventOptions.supportsRules) | 
| -      throw new Error("This event does not support rules."); | 
| -    ensureRuleSchemasLoaded(); | 
| -    // We remove the first parameter from the validation to give the user more | 
| -    // meaningful error messages. | 
| -    validate([this.webViewInstanceId, ruleIdentifiers, opt_cb], | 
| -             $Array.splice( | 
| -                 $Array.slice(ruleFunctionSchemas.removeRules.parameters), 1)); | 
| -    sendRequest("events.removeRules", | 
| -                [this.eventName, | 
| -                 this.webViewInstanceId, | 
| -                 ruleIdentifiers, | 
| -                 opt_cb], | 
| -                ruleFunctionSchemas.removeRules.parameters); | 
| -  } | 
| - | 
| -  EventImpl.prototype.getRules = function(ruleIdentifiers, cb) { | 
| -    if (!this.eventOptions.supportsRules) | 
| -      throw new Error("This event does not support rules."); | 
| -    ensureRuleSchemasLoaded(); | 
| -    // We remove the first parameter from the validation to give the user more | 
| -    // meaningful error messages. | 
| -    validate([this.webViewInstanceId, ruleIdentifiers, cb], | 
| -             $Array.splice( | 
| -                 $Array.slice(ruleFunctionSchemas.getRules.parameters), 1)); | 
| - | 
| -    sendRequest( | 
| -      "events.getRules", | 
| -      [this.eventName, this.webViewInstanceId, ruleIdentifiers, cb], | 
| -      ruleFunctionSchemas.getRules.parameters); | 
| -  } | 
| - | 
| -  unloadEvent.addListener(function() { | 
| -    for (var i = 0; i < allAttachedEvents.length; ++i) { | 
| -      var event = allAttachedEvents[i]; | 
| -      if (event) | 
| -        event.detach_(); | 
| -    } | 
| -  }); | 
| - | 
| -  var Event = utils.expose('Event', EventImpl, { functions: [ | 
| -    'addListener', | 
| -    'removeListener', | 
| -    'hasListener', | 
| -    'hasListeners', | 
| -    'dispatchToListener', | 
| -    'dispatch', | 
| -    'addRules', | 
| -    'removeRules', | 
| -    'getRules' | 
| -  ] }); | 
| - | 
| -  // NOTE: Event is (lazily) exposed as chrome.Event from dispatcher.cc. | 
| -  exports.Event = Event; | 
| - | 
| -  exports.dispatchEvent = dispatchEvent; | 
| -  exports.parseEventOptions = parseEventOptions; | 
| -  exports.registerArgumentMassager = registerArgumentMassager; | 
|  |