code: function (event) {
      var symbolName = symbolNames[event.type];
      if (!symbolName) {
          return;
      }
      var taskDatas = this[symbolName];
      if (!taskDatas) {
          return;
      }
      var args = [event];
      if (taskDatas.length === 1) {
          // if taskDatas only have one element, just invoke it
          var taskData = taskDatas[0];
          if (taskData.zone !== Zone.current) {
              // only use Zone.run when Zone.current not equals to stored zone
              return taskData.zone.run(taskData.handler, this, args);
          }
          else {
              return taskData.handler.apply(this, args);
          }
      }
      else {
          // copy tasks as a snapshot to avoid event handlers remove
          // itself or others
          var copiedTasks = taskDatas.slice();
          for (var i = 0; i < copiedTasks.length; i++) {
              // if other listener call event.stopImmediatePropagation
              // just break
              if (event[stopSymbol] === true) {
                  break;
              }
              var taskData = copiedTasks[i];
              if (taskData.zone !== Zone.current) {
                  // only use Zone.run when Zone.current not equals to stored zone
                  taskData.zone.run(taskData.handler, this, args);
              }
              else {
                  taskData.handler.apply(this, args);
              }
          }
      }
  }
docs: a global listener to handle all dom event, so we do not need to create a closure every time