373 lines
10 KiB
JavaScript
373 lines
10 KiB
JavaScript
//@require @core
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
Ext.define('Ext.event.Dispatcher', {
|
|
|
|
requires: [
|
|
'Ext.event.ListenerStack',
|
|
'Ext.event.Controller'
|
|
],
|
|
|
|
statics: {
|
|
getInstance: function() {
|
|
if (!this.instance) {
|
|
this.instance = new this();
|
|
}
|
|
|
|
return this.instance;
|
|
},
|
|
|
|
setInstance: function(instance) {
|
|
this.instance = instance;
|
|
|
|
return this;
|
|
}
|
|
},
|
|
|
|
config: {
|
|
publishers: {}
|
|
},
|
|
|
|
wildcard: '*',
|
|
|
|
constructor: function(config) {
|
|
this.listenerStacks = {};
|
|
|
|
this.activePublishers = {};
|
|
|
|
this.publishersCache = {};
|
|
|
|
this.noActivePublishers = [];
|
|
|
|
this.controller = null;
|
|
|
|
this.initConfig(config);
|
|
|
|
return this;
|
|
},
|
|
|
|
getListenerStack: function(targetType, target, eventName, createIfNotExist) {
|
|
var listenerStacks = this.listenerStacks,
|
|
map = listenerStacks[targetType],
|
|
listenerStack;
|
|
|
|
createIfNotExist = Boolean(createIfNotExist);
|
|
|
|
if (!map) {
|
|
if (createIfNotExist) {
|
|
listenerStacks[targetType] = map = {};
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
map = map[target];
|
|
|
|
if (!map) {
|
|
if (createIfNotExist) {
|
|
listenerStacks[targetType][target] = map = {};
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
listenerStack = map[eventName];
|
|
|
|
if (!listenerStack) {
|
|
if (createIfNotExist) {
|
|
map[eventName] = listenerStack = new Ext.event.ListenerStack();
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return listenerStack;
|
|
},
|
|
|
|
getController: function(targetType, target, eventName, connectedController) {
|
|
var controller = this.controller,
|
|
info = {
|
|
targetType: targetType,
|
|
target: target,
|
|
eventName: eventName
|
|
};
|
|
|
|
if (!controller) {
|
|
this.controller = controller = new Ext.event.Controller();
|
|
}
|
|
|
|
if (controller.isFiring) {
|
|
controller = new Ext.event.Controller();
|
|
}
|
|
|
|
controller.setInfo(info);
|
|
|
|
if (connectedController && controller !== connectedController) {
|
|
controller.connect(connectedController);
|
|
}
|
|
|
|
return controller;
|
|
},
|
|
|
|
applyPublishers: function(publishers) {
|
|
var i, publisher;
|
|
|
|
this.publishersCache = {};
|
|
|
|
for (i in publishers) {
|
|
if (publishers.hasOwnProperty(i)) {
|
|
publisher = publishers[i];
|
|
|
|
this.registerPublisher(publisher);
|
|
}
|
|
}
|
|
|
|
return publishers;
|
|
},
|
|
|
|
registerPublisher: function(publisher) {
|
|
var activePublishers = this.activePublishers,
|
|
targetType = publisher.getTargetType(),
|
|
publishers = activePublishers[targetType];
|
|
|
|
if (!publishers) {
|
|
activePublishers[targetType] = publishers = [];
|
|
}
|
|
|
|
publishers.push(publisher);
|
|
|
|
publisher.setDispatcher(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
getCachedActivePublishers: function(targetType, eventName) {
|
|
var cache = this.publishersCache,
|
|
publishers;
|
|
|
|
if ((publishers = cache[targetType]) && (publishers = publishers[eventName])) {
|
|
return publishers;
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
cacheActivePublishers: function(targetType, eventName, publishers) {
|
|
var cache = this.publishersCache;
|
|
|
|
if (!cache[targetType]) {
|
|
cache[targetType] = {};
|
|
}
|
|
|
|
cache[targetType][eventName] = publishers;
|
|
|
|
return publishers;
|
|
},
|
|
|
|
getActivePublishers: function(targetType, eventName) {
|
|
var publishers, activePublishers,
|
|
i, ln, publisher;
|
|
|
|
if ((publishers = this.getCachedActivePublishers(targetType, eventName))) {
|
|
return publishers;
|
|
}
|
|
|
|
activePublishers = this.activePublishers[targetType];
|
|
|
|
if (activePublishers) {
|
|
publishers = [];
|
|
|
|
for (i = 0,ln = activePublishers.length; i < ln; i++) {
|
|
publisher = activePublishers[i];
|
|
|
|
if (publisher.handles(eventName)) {
|
|
publishers.push(publisher);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
publishers = this.noActivePublishers;
|
|
}
|
|
|
|
return this.cacheActivePublishers(targetType, eventName, publishers);
|
|
},
|
|
|
|
hasListener: function(targetType, target, eventName) {
|
|
var listenerStack = this.getListenerStack(targetType, target, eventName);
|
|
|
|
if (listenerStack) {
|
|
return listenerStack.count() > 0;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
addListener: function(targetType, target, eventName) {
|
|
var publishers = this.getActivePublishers(targetType, eventName),
|
|
ln = publishers.length,
|
|
i, result;
|
|
|
|
result = this.doAddListener.apply(this, arguments);
|
|
|
|
if (result && ln > 0) {
|
|
for (i = 0; i < ln; i++) {
|
|
publishers[i].subscribe(target, eventName);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
doAddListener: function(targetType, target, eventName, fn, scope, options, order) {
|
|
var listenerStack = this.getListenerStack(targetType, target, eventName, true);
|
|
|
|
return listenerStack.add(fn, scope, options, order);
|
|
},
|
|
|
|
removeListener: function(targetType, target, eventName) {
|
|
var publishers = this.getActivePublishers(targetType, eventName),
|
|
ln = publishers.length,
|
|
i, result;
|
|
|
|
result = this.doRemoveListener.apply(this, arguments);
|
|
|
|
if (result && ln > 0) {
|
|
for (i = 0; i < ln; i++) {
|
|
publishers[i].unsubscribe(target, eventName);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
doRemoveListener: function(targetType, target, eventName, fn, scope, order) {
|
|
var listenerStack = this.getListenerStack(targetType, target, eventName);
|
|
|
|
if (listenerStack === null) {
|
|
return false;
|
|
}
|
|
|
|
return listenerStack.remove(fn, scope, order);
|
|
},
|
|
|
|
clearListeners: function(targetType, target, eventName) {
|
|
var listenerStacks = this.listenerStacks,
|
|
ln = arguments.length,
|
|
stacks, publishers, i, publisherGroup;
|
|
|
|
if (ln === 3) {
|
|
if (listenerStacks[targetType] && listenerStacks[targetType][target]) {
|
|
this.removeListener(targetType, target, eventName);
|
|
delete listenerStacks[targetType][target][eventName];
|
|
}
|
|
}
|
|
else if (ln === 2) {
|
|
if (listenerStacks[targetType]) {
|
|
stacks = listenerStacks[targetType][target];
|
|
|
|
if (stacks) {
|
|
for (eventName in stacks) {
|
|
if (stacks.hasOwnProperty(eventName)) {
|
|
publishers = this.getActivePublishers(targetType, eventName);
|
|
|
|
for (i = 0,ln = publishers.length; i < ln; i++) {
|
|
publishers[i].unsubscribe(target, eventName, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
delete listenerStacks[targetType][target];
|
|
}
|
|
}
|
|
}
|
|
else if (ln === 1) {
|
|
publishers = this.activePublishers[targetType];
|
|
|
|
for (i = 0,ln = publishers.length; i < ln; i++) {
|
|
publishers[i].unsubscribeAll();
|
|
}
|
|
|
|
delete listenerStacks[targetType];
|
|
}
|
|
else {
|
|
publishers = this.activePublishers;
|
|
|
|
for (targetType in publishers) {
|
|
if (publishers.hasOwnProperty(targetType)) {
|
|
publisherGroup = publishers[targetType];
|
|
|
|
for (i = 0,ln = publisherGroup.length; i < ln; i++) {
|
|
publisherGroup[i].unsubscribeAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
delete this.listenerStacks;
|
|
this.listenerStacks = {};
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
dispatchEvent: function(targetType, target, eventName) {
|
|
var publishers = this.getActivePublishers(targetType, eventName),
|
|
ln = publishers.length,
|
|
i;
|
|
|
|
if (ln > 0) {
|
|
for (i = 0; i < ln; i++) {
|
|
publishers[i].notify(target, eventName);
|
|
}
|
|
}
|
|
|
|
return this.doDispatchEvent.apply(this, arguments);
|
|
},
|
|
|
|
doDispatchEvent: function(targetType, target, eventName, args, action, connectedController) {
|
|
var listenerStack = this.getListenerStack(targetType, target, eventName),
|
|
wildcardStacks = this.getWildcardListenerStacks(targetType, target, eventName),
|
|
controller;
|
|
|
|
if ((listenerStack === null || listenerStack.length == 0)) {
|
|
if (wildcardStacks.length == 0 && !action) {
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
wildcardStacks.push(listenerStack);
|
|
}
|
|
|
|
controller = this.getController(targetType, target, eventName, connectedController);
|
|
controller.setListenerStacks(wildcardStacks);
|
|
controller.fire(args, action);
|
|
|
|
return !controller.isInterrupted();
|
|
},
|
|
|
|
getWildcardListenerStacks: function(targetType, target, eventName) {
|
|
var stacks = [],
|
|
wildcard = this.wildcard,
|
|
isEventNameNotWildcard = eventName !== wildcard,
|
|
isTargetNotWildcard = target !== wildcard,
|
|
stack;
|
|
|
|
if (isEventNameNotWildcard && (stack = this.getListenerStack(targetType, target, wildcard))) {
|
|
stacks.push(stack);
|
|
}
|
|
|
|
if (isTargetNotWildcard && (stack = this.getListenerStack(targetType, wildcard, eventName))) {
|
|
stacks.push(stack);
|
|
}
|
|
|
|
return stacks;
|
|
},
|
|
|
|
getPublisher: function (name) {
|
|
return this.getPublishers()[name];
|
|
}
|
|
}); |