/** * @class Ext.tip.QuickTip * @extends Ext.tip.ToolTip * A specialized tooltip class for tooltips that can be specified in markup and automatically managed by the global * {@link Ext.tip.QuickTipManager} instance. See the QuickTipManager class header for additional usage details and examples. * @xtype quicktip */ Ext.define('Ext.tip.QuickTip', { extend: 'Ext.tip.ToolTip', alternateClassName: 'Ext.QuickTip', /** * @cfg {Mixed} target The target HTMLElement, Ext.core.Element or id to associate with this Quicktip (defaults to the document). */ /** * @cfg {Boolean} interceptTitles True to automatically use the element's DOM title value if available (defaults to false). */ interceptTitles : false, // Force creation of header Component title: ' ', // private tagConfig : { namespace : "data-", attribute : "qtip", width : "qwidth", target : "target", title : "qtitle", hide : "hide", cls : "qclass", align : "qalign", anchor : "anchor" }, // private initComponent : function(){ var me = this; me.target = me.target || Ext.getDoc(); me.targets = me.targets || {}; me.callParent(); }, /** * Configures a new quick tip instance and assigns it to a target element. The following config values are * supported (for example usage, see the {@link Ext.tip.QuickTipManager} class header): * <div class="mdetail-params"><ul> * <li>autoHide</li> * <li>cls</li> * <li>dismissDelay (overrides the singleton value)</li> * <li>target (required)</li> * <li>text (required)</li> * <li>title</li> * <li>width</li></ul></div> * @param {Object} config The config object */ register : function(config){ var configs = Ext.isArray(config) ? config : arguments, i = 0, len = configs.length, target, j, targetLen; for (; i < len; i++) { config = configs[i]; target = config.target; if (target) { if (Ext.isArray(target)) { for (j = 0, targetLen = target.length; j < targetLen; j++) { this.targets[Ext.id(target[j])] = config; } } else{ this.targets[Ext.id(target)] = config; } } } }, /** * Removes this quick tip from its element and destroys it. * @param {String/HTMLElement/Element} el The element from which the quick tip is to be removed. */ unregister : function(el){ delete this.targets[Ext.id(el)]; }, /** * Hides a visible tip or cancels an impending show for a particular element. * @param {String/HTMLElement/Element} el The element that is the target of the tip. */ cancelShow: function(el){ var me = this, activeTarget = me.activeTarget; el = Ext.get(el).dom; if (me.isVisible()) { if (activeTarget && activeTarget.el == el) { me.hide(); } } else if (activeTarget && activeTarget.el == el) { me.clearTimer('show'); } }, getTipCfg: function(e) { var t = e.getTarget(), ttp, cfg; if(this.interceptTitles && t.title && Ext.isString(t.title)){ ttp = t.title; t.qtip = ttp; t.removeAttribute("title"); e.preventDefault(); } else { cfg = this.tagConfig; t = e.getTarget('[' + cfg.namespace + cfg.attribute + ']'); if (t) { ttp = t.getAttribute(cfg.namespace + cfg.attribute); } } return ttp; }, // private onTargetOver : function(e){ var me = this, target = e.getTarget(), elTarget, cfg, ns, ttp, autoHide; if (me.disabled) { return; } // TODO - this causes "e" to be recycled in IE6/7 (EXTJSIV-1608) so ToolTip#setTarget // was changed to include freezeEvent. The issue seems to be a nested 'resize' event // that smashed Ext.EventObject. me.targetXY = e.getXY(); if(!target || target.nodeType !== 1 || target == document || target == document.body){ return; } if (me.activeTarget && ((target == me.activeTarget.el) || Ext.fly(me.activeTarget.el).contains(target))) { me.clearTimer('hide'); me.show(); return; } if (target) { Ext.Object.each(me.targets, function(key, value) { var targetEl = Ext.fly(value.target); if (targetEl && (targetEl.dom === target || targetEl.contains(target))) { elTarget = targetEl.dom; return false; } }); if (elTarget) { me.activeTarget = me.targets[elTarget.id]; me.activeTarget.el = target; me.anchor = me.activeTarget.anchor; if (me.anchor) { me.anchorTarget = target; } me.delayShow(); return; } } elTarget = Ext.get(target); cfg = me.tagConfig; ns = cfg.namespace; ttp = me.getTipCfg(e); if (ttp) { autoHide = elTarget.getAttribute(ns + cfg.hide); me.activeTarget = { el: target, text: ttp, width: +elTarget.getAttribute(ns + cfg.width) || null, autoHide: autoHide != "user" && autoHide !== 'false', title: elTarget.getAttribute(ns + cfg.title), cls: elTarget.getAttribute(ns + cfg.cls), align: elTarget.getAttribute(ns + cfg.align) }; me.anchor = elTarget.getAttribute(ns + cfg.anchor); if (me.anchor) { me.anchorTarget = target; } me.delayShow(); } }, // private onTargetOut : function(e){ var me = this; // If moving within the current target, and it does not have a new tip, ignore the mouseout if (me.activeTarget && e.within(me.activeTarget.el) && !me.getTipCfg(e)) { return; } me.clearTimer('show'); if (me.autoHide !== false) { me.delayHide(); } }, // inherit docs showAt : function(xy){ var me = this, target = me.activeTarget; if (target) { if (!me.rendered) { me.render(Ext.getBody()); me.activeTarget = target; } if (target.title) { me.setTitle(target.title || ''); me.header.show(); } else { me.header.hide(); } me.body.update(target.text); me.autoHide = target.autoHide; me.dismissDelay = target.dismissDelay || me.dismissDelay; if (me.lastCls) { me.el.removeCls(me.lastCls); delete me.lastCls; } if (target.cls) { me.el.addCls(target.cls); me.lastCls = target.cls; } me.setWidth(target.width); if (me.anchor) { me.constrainPosition = false; } else if (target.align) { // TODO: this doesn't seem to work consistently xy = me.el.getAlignToXY(target.el, target.align); me.constrainPosition = false; }else{ me.constrainPosition = true; } } me.callParent([xy]); }, // inherit docs hide: function(){ delete this.activeTarget; this.callParent(); } });