365
361
Y.extend(Widget, Y.Base, {
368
* Returns a class name prefixed with the the value of the
369
* <code>YUI.config.classNamePrefix</code> attribute + the instances <code>NAME</code> property.
370
* Uses <code>YUI.config.classNameDelimiter</code> attribute to delimit the provided strings.
374
* // returns "yui-slider-foo-bar", for a slider instance
375
* var scn = slider.getClassName('foo','bar');
377
* // returns "yui-overlay-foo-bar", for an overlay instance
378
* var ocn = overlay.getClassName('foo','bar');
382
* @method getClassName
383
* @param {String}+ One or more classname bits to be joined and prefixed
385
getClassName: function () {
364
* Returns a class name prefixed with the the value of the
365
* <code>YUI.config.classNamePrefix</code> attribute + the instances <code>NAME</code> property.
366
* Uses <code>YUI.config.classNameDelimiter</code> attribute to delimit the provided strings.
370
* // returns "yui-slider-foo-bar", for a slider instance
371
* var scn = slider.getClassName('foo','bar');
373
* // returns "yui-overlay-foo-bar", for an overlay instance
374
* var ocn = overlay.getClassName('foo','bar');
378
* @method getClassName
379
* @param {String}+ One or more classname bits to be joined and prefixed
381
getClassName: function () {
386
382
return _getClassName.apply(ClassNameManager, [this._cssPrefix].concat(Y.Array(arguments), true));
390
* Returns the name of the skin that's currently applied to the widget.
391
* This is only really useful after the widget's DOM structure is in the
392
* document, either by render or by progressive enhancement. Searches up
393
* the Widget's ancestor axis for a class yui3-skin-(name), and returns the
394
* (name) portion. Otherwise, returns null.
396
* @method getSkinName
397
* @return {String} the name of the skin, or null (yui3-skin-sam => sam)
399
getSkinName: function () {
400
var root = this.get( CONTENT_BOX ) || this.get( BOUNDING_BOX ),
401
search = new RegExp( '\\b' + _getClassName( 'skin' ) + '-(\\S+)' ),
405
root.ancestor( function ( node ) {
406
match = node.get( 'className' ).match( search );
411
return ( match ) ? match[1] : null;
454
424
Y.log('destructor called', 'life', 'widget');
456
426
var boundingBox = this.get(BOUNDING_BOX),
457
bbGuid = Y.stamp(boundingBox, TRUE),
458
widgetGuid = Y.stamp(this, TRUE);
427
contentBox = this.get(CONTENT_BOX),
428
bbGuid = Y.stamp(boundingBox, TRUE);
460
430
if (bbGuid in _instances) {
461
431
delete _instances[bbGuid];
464
Y.each(_delegates, function (info, key) {
465
if (info.instances[widgetGuid]) {
466
// Unregister this Widget instance as needing this delegated
468
delete info.instances[widgetGuid];
470
// There are no more Widget instances using this delegated
471
// event listener, so detach it.
473
if (Y.Object.isEmpty(info.instances)) {
474
info.handle.detach();
476
if (_delegates[key]) {
477
delete _delegates[key];
434
if (this.UI_EVENTS) {
435
this._destroyUIEvents();
483
438
this._unbindUI(boundingBox);
440
if (contentBox) { // Just to be safe because it's a last minute change. Really shouldn't be required.
441
contentBox.remove(TRUE);
484
443
boundingBox.remove(TRUE);
675
637
* @param {boolean} expand
677
639
_uiSizeCB : function(expand) {
679
var bb = this.get(BOUNDING_BOX),
680
cb = this.get(CONTENT_BOX),
682
bbTempExpanding = _getWidgetClassName("tmp", "forcesize"),
684
borderBoxSupported = this._bbs,
685
heightReallyMinHeight = IE && IE < 7;
687
if (borderBoxSupported) {
688
cb.toggleClass(_getWidgetClassName(CONTENT, "expanded"), expand);
691
if (heightReallyMinHeight) {
692
bb.addClass(bbTempExpanding);
695
cb.set(OFFSET_HEIGHT, bb.get(OFFSET_HEIGHT));
697
if (heightReallyMinHeight) {
698
bb.removeClass(bbTempExpanding);
701
cb.setStyle(HEIGHT, EMPTY_STR);
640
this.get(CONTENT_BOX).toggleClass(_getWidgetClassName(CONTENT, "expanded"), expand);
718
655
_renderBox: function(parentNode) {
720
657
// TODO: Performance Optimization [ More effective algo to reduce Node refs, compares, replaces? ]
722
var contentBox = this.get(CONTENT_BOX),
723
boundingBox = this.get(BOUNDING_BOX),
724
srcNode = this.get(SRC_NODE),
725
defParentNode = this.DEF_PARENT_NODE,
659
var widget = this, // kweight
660
contentBox = widget.get(CONTENT_BOX),
661
boundingBox = widget.get(BOUNDING_BOX),
662
srcNode = widget.get(SRC_NODE),
663
defParentNode = widget.DEF_PARENT_NODE,
727
665
doc = (srcNode && srcNode.get(OWNER_DOCUMENT)) || boundingBox.get(OWNER_DOCUMENT) || contentBox.get(OWNER_DOCUMENT);
891
827
_bindDOM : function() {
892
var oDocument = this.get(BOUNDING_BOX).get(OWNER_DOCUMENT);
828
var oDocument = this.get(BOUNDING_BOX).get(OWNER_DOCUMENT);
894
830
// TODO: Perf Optimization: Use Widget.getByNode delegation, to get by
895
831
// with just one _onDocFocus subscription per sandbox, instead of one per widget
896
this._hDocFocus = oDocument.on("focus", this._onDocFocus, this);
832
this._hDocFocus = oDocument.on("focus", this._onDocFocus, this);
899
// Document doesn't receive focus in Webkit when the user mouses
900
// down on it, so the "focused" attribute won't get set to the
903
this._hDocMouseDown = oDocument.on("mousedown", this._onDocMouseDown, this);
835
// Document doesn't receive focus in Webkit when the user mouses
836
// down on it, so the "focused" attribute won't get set to the
839
this._hDocMouseDown = oDocument.on("mousedown", this._onDocMouseDown, this);
1013
949
_uiSetTabIndex: function(index) {
1014
var boundingBox = this.get(BOUNDING_BOX);
950
var boundingBox = this.get(BOUNDING_BOX);
1016
if (L.isNumber(index)) {
1017
boundingBox.set(TAB_INDEX, index);
1019
boundingBox.removeAttribute(TAB_INDEX);
952
if (L.isNumber(index)) {
953
boundingBox.set(TAB_INDEX, index);
955
boundingBox.removeAttribute(TAB_INDEX);
1024
* @method _onDocMouseDown
1025
* @description "mousedown" event handler for the owner document of the
1026
* widget's bounding box.
960
* @method _onDocMouseDown
961
* @description "mousedown" event handler for the owner document of the
962
* widget's bounding box.
1028
964
* @param {EventFacade} evt The event facade for the DOM focus event
1030
_onDocMouseDown: function (evt) {
1031
if (this._hasDOMFocus) {
1032
this._onDocFocus(evt);
966
_onDocMouseDown: function (evt) {
967
if (this._domFocus) {
968
this._onDocFocus(evt);
1037
973
* DOM focus event handler, used to sync the state of the Widget with the DOM
1190
* The list of UI attributes to bind for Widget's _bindUI implementation
1192
* @property _BIND_UI_ATTRS
1196
_BIND_UI_ATTRS : UI_ATTRS,
1199
* The list of UI attributes to sync for Widget's _syncUI implementation
1201
* @property _SYNC_UI_ATTRS
1205
_SYNC_UI_ATTRS : UI_ATTRS.concat(TAB_INDEX),
1208
* Map of DOM events that should be fired as Custom Events by the
1211
* @property UI_EVENTS
1125
* The lists of UI attributes to bind and sync for widget's _bindUI and _syncUI implementations
1127
* @property _UI_ATTRS
1214
UI_EVENTS: Y.Node.DOM_EVENTS,
1217
* Returns the node on which to bind delegate listeners.
1219
* @method _getUIEventNode
1222
_getUIEventNode: function () {
1223
return this.get(BOUNDING_BOX);
1227
* Binds a delegated DOM event listener of the specified type to the
1228
* Widget's outtermost DOM element to facilitate the firing of a Custom
1229
* Event of the same type for the Widget instance.
1232
* @method _createUIEvent
1233
* @param type {String} String representing the name of the event
1235
_createUIEvent: function (type) {
1237
var uiEvtNode = this._getUIEventNode(),
1238
parentNode = uiEvtNode.get(PARENT_NODE),
1239
key = (Y.stamp(parentNode) + type),
1240
info = _delegates[key],
1243
// For each Node instance: Ensure that there is only one delegated
1244
// event listener used to fire Widget UI events.
1247
Y.log("Creating delegate for the " + type + " event.", "info", "widget");
1249
handle = parentNode.delegate(type, function (evt) {
1251
var widget = Widget.getByNode(this);
1252
// Make the DOM event a property of the custom event
1253
// so that developers still have access to it.
1254
widget.fire(evt.type, { domEvent: evt });
1256
}, "." + _getWidgetClassName());
1258
_delegates[key] = info = { instances: {}, handle: handle };
1261
// Register this Widget as using this Node as a delegation container.
1262
info.instances[Y.stamp(this)] = 1;
1266
* Determines if the specified event is a UI event.
1269
* @method _isUIEvent
1270
* @param type {String} String representing the name of the event
1271
* @return {String} Event Returns the name of the UI Event, otherwise
1274
_getUIEvent: function (type) {
1275
if (L.isString(type)) {
1276
var sType = type.replace(UI_EVENT_REGEX, UI_EVENT_REGEX_REPLACE),
1279
if (this.UI_EVENTS[sType]) {
1288
* Sets up infastructure required to fire a UI event.
1291
* @method _initUIEvent
1292
* @param type {String} String representing the name of the event
1295
_initUIEvent: function (type) {
1296
var sType = this._getUIEvent(type),
1297
queue = this._uiEvtsInitQueue || {};
1299
if (sType && !queue[sType]) {
1300
Y.log("Deferring creation of " + type + " delegate until render.", "info", "widget");
1302
this._uiEvtsInitQueue = queue[sType] = 1;
1304
this.after(RENDER, function() {
1305
this._createUIEvent(sType);
1306
delete this._uiEvtsInitQueue[sType];
1311
// Override of "on" from Base to facilitate the firing of Widget events
1312
// based on DOM events of the same name/type (e.g. "click", "mouseover").
1313
// Temporary solution until we have the ability to listen to when
1314
// someone adds an event listener (bug 2528230)
1315
on: function (type) {
1316
this._initUIEvent(type);
1317
return Widget.superclass.on.apply(this, arguments);
1320
// Override of "after" from Base to facilitate the firing of Widget events
1321
// based on DOM events of the same name/type (e.g. "click", "mouseover").
1322
// Temporary solution until we have the ability to listen to when
1323
// someone adds an event listener (bug 2528230)
1324
after: function (type) {
1325
this._initUIEvent(type);
1326
return Widget.superclass.after.apply(this, arguments);
1329
// Override of "publish" from Base to facilitate the firing of Widget events
1330
// based on DOM events of the same name/type (e.g. "click", "mouseover").
1331
// Temporary solution until we have the ability to listen to when
1332
// someone publishes an event (bug 2528230)
1333
publish: function (type, config) {
1334
var sType = this._getUIEvent(type);
1335
if (sType && config && config.defaultFn) {
1336
this._initUIEvent(sType);
1338
return Widget.superclass.publish.apply(this, arguments);
1133
SYNC: UI_ATTRS.concat(TAB_INDEX)
1343
1137
Y.Widget = Widget;
1346
}, '3.2.0' ,{requires:['attribute', 'event-focus', 'base-base', 'base-pluginhost', 'node-base', 'node-style', 'node-event-delegate', 'classnamemanager']});
1140
}, '3.3.0' ,{requires:['attribute', 'event-focus', 'base-base', 'base-pluginhost', 'node-base', 'node-style', 'node-event-delegate', 'classnamemanager']});