Ext.define('Ext.event.publisher.ComponentPaint', {
extend: 'Ext.event.publisher.Publisher',
targetType: 'component',
handledEvents: ['painted', 'erased'],
idSelectorRegex: /^#([\w\-]+)$/i,
eventNames: {
painted: 'painted',
erased: 'erased'
},
constructor: function() {
this.callParent(arguments);
this.subscribers = {};
},
getSubscribers: function(eventName, createIfNotExist) {
var subscribers = this.subscribers;
if (!subscribers.hasOwnProperty(eventName)) {
if (!createIfNotExist) {
return null;
}
subscribers[eventName] = {
$length: 0
};
}
return subscribers[eventName];
},
setDispatcher: function(dispatcher) {
var targetType = this.targetType;
dispatcher.doAddListener(targetType, '*', 'renderedchange', 'onComponentRenderedChange', this);
dispatcher.doAddListener(targetType, '*', 'hiddenchange', 'onComponentHiddenChange', this);
return this.callParent(arguments);
},
subscribe: function(target, eventName) {
var match = target.match(this.idSelectorRegex),
subscribers;
if (!match) {
return false;
}
subscribers = this.getSubscribers(eventName, true);
subscribers[match[1]] = true;
subscribers.$length++;
return true;
},
unsubscribe: function(target, eventName) {
var match = target.match(this.idSelectorRegex),
subscribers;
if (!match || !(subscribers = this.getSubscribers(eventName))) {
return false;
}
delete subscribers[match[1]];
subscribers.$length--;
return true;
},
onComponentRenderedChange: function(component, rendered) {
var eventNames = this.eventNames,
eventName = rendered ? eventNames.painted : eventNames.erased,
subscribers = this.getSubscribers(eventName);
if (subscribers && subscribers.$length > 0) {
this.publish(subscribers, component, eventName);
}
},
onComponentHiddenChange: function(component, hidden) {
var eventNames = this.eventNames,
eventName = hidden ? eventNames.erased : eventNames.painted,
subscribers = this.getSubscribers(eventName);
if (subscribers && subscribers.$length > 0) {
this.publish(subscribers, component, eventName);
}
},
publish: function(subscribers, component, eventName) {
var id = component.getId(),
eventNames, items, i, ln, isPainted;
if (subscribers[id]) {
eventNames = this.eventNames;
isPainted = component.isPainted();
if ((eventName === eventNames.painted && isPainted) || eventName === eventNames.erased && !isPainted) {
this.dispatcher.doDispatchEvent(this.targetType, '#' + id, eventName, [component]);
}
else {
return this;
}
}
if (component.isContainer) {
items = component.getItems().items;
for (i = 0,ln = items.length; i < ln; i++) {
this.publish(subscribers, items[i], eventName);
}
}
}
});