/src/main/resources/org/apache/struts2/static/element/element.js

http://struts2yuiplugin.googlecode.com/ · JavaScript · 1057 lines · 473 code · 149 blank · 435 comment · 96 complexity · d1f7338a8cc58653afc64f103459f59a MD5 · raw file

  1. /*
  2. Copyright (c) 2009, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.7.0
  6. */
  7. /**
  8. * Provides Attribute configurations.
  9. * @namespace YAHOO.util
  10. * @class Attribute
  11. * @constructor
  12. * @param hash {Object} The intial Attribute.
  13. * @param {YAHOO.util.AttributeProvider} The owner of the Attribute instance.
  14. */
  15. YAHOO.util.Attribute = function(hash, owner) {
  16. if (owner) {
  17. this.owner = owner;
  18. this.configure(hash, true);
  19. }
  20. };
  21. YAHOO.util.Attribute.prototype = {
  22. /**
  23. * The name of the attribute.
  24. * @property name
  25. * @type String
  26. */
  27. name: undefined,
  28. /**
  29. * The value of the attribute.
  30. * @property value
  31. * @type String
  32. */
  33. value: null,
  34. /**
  35. * The owner of the attribute.
  36. * @property owner
  37. * @type YAHOO.util.AttributeProvider
  38. */
  39. owner: null,
  40. /**
  41. * Whether or not the attribute is read only.
  42. * @property readOnly
  43. * @type Boolean
  44. */
  45. readOnly: false,
  46. /**
  47. * Whether or not the attribute can only be written once.
  48. * @property writeOnce
  49. * @type Boolean
  50. */
  51. writeOnce: false,
  52. /**
  53. * The attribute's initial configuration.
  54. * @private
  55. * @property _initialConfig
  56. * @type Object
  57. */
  58. _initialConfig: null,
  59. /**
  60. * Whether or not the attribute's value has been set.
  61. * @private
  62. * @property _written
  63. * @type Boolean
  64. */
  65. _written: false,
  66. /**
  67. * A function to call when setting the attribute's value.
  68. * The method receives the new value as the first arg and the attribute name as the 2nd
  69. * @property method
  70. * @type Function
  71. */
  72. method: null,
  73. /**
  74. * The function to use when setting the attribute's value.
  75. * The setter receives the new value as the first arg and the attribute name as the 2nd
  76. * The return value of the setter replaces the value passed to set().
  77. * @property setter
  78. * @type Function
  79. */
  80. setter: null,
  81. /**
  82. * The function to use when getting the attribute's value.
  83. * The getter receives the new value as the first arg and the attribute name as the 2nd
  84. * The return value of the getter will be used as the return from get().
  85. * @property getter
  86. * @type Function
  87. */
  88. getter: null,
  89. /**
  90. * The validator to use when setting the attribute's value.
  91. * @property validator
  92. * @type Function
  93. * @return Boolean
  94. */
  95. validator: null,
  96. /**
  97. * Retrieves the current value of the attribute.
  98. * @method getValue
  99. * @return {any} The current value of the attribute.
  100. */
  101. getValue: function() {
  102. var val = this.value;
  103. if (this.getter) {
  104. val = this.getter.call(this.owner, this.name);
  105. }
  106. return val;
  107. },
  108. /**
  109. * Sets the value of the attribute and fires beforeChange and change events.
  110. * @method setValue
  111. * @param {Any} value The value to apply to the attribute.
  112. * @param {Boolean} silent If true the change events will not be fired.
  113. * @return {Boolean} Whether or not the value was set.
  114. */
  115. setValue: function(value, silent) {
  116. var beforeRetVal,
  117. owner = this.owner,
  118. name = this.name;
  119. var event = {
  120. type: name,
  121. prevValue: this.getValue(),
  122. newValue: value
  123. };
  124. if (this.readOnly || ( this.writeOnce && this._written) ) {
  125. return false; // write not allowed
  126. }
  127. if (this.validator && !this.validator.call(owner, value) ) {
  128. return false; // invalid value
  129. }
  130. if (!silent) {
  131. beforeRetVal = owner.fireBeforeChangeEvent(event);
  132. if (beforeRetVal === false) {
  133. return false;
  134. }
  135. }
  136. if (this.setter) {
  137. value = this.setter.call(owner, value, this.name);
  138. if (value === undefined) {
  139. }
  140. }
  141. if (this.method) {
  142. this.method.call(owner, value, this.name);
  143. }
  144. this.value = value; // TODO: set before calling setter/method?
  145. this._written = true;
  146. event.type = name;
  147. if (!silent) {
  148. this.owner.fireChangeEvent(event);
  149. }
  150. return true;
  151. },
  152. /**
  153. * Allows for configuring the Attribute's properties.
  154. * @method configure
  155. * @param {Object} map A key-value map of Attribute properties.
  156. * @param {Boolean} init Whether or not this should become the initial config.
  157. */
  158. configure: function(map, init) {
  159. map = map || {};
  160. if (init) {
  161. this._written = false; // reset writeOnce
  162. }
  163. this._initialConfig = this._initialConfig || {};
  164. for (var key in map) {
  165. if ( map.hasOwnProperty(key) ) {
  166. this[key] = map[key];
  167. if (init) {
  168. this._initialConfig[key] = map[key];
  169. }
  170. }
  171. }
  172. },
  173. /**
  174. * Resets the value to the initial config value.
  175. * @method resetValue
  176. * @return {Boolean} Whether or not the value was set.
  177. */
  178. resetValue: function() {
  179. return this.setValue(this._initialConfig.value);
  180. },
  181. /**
  182. * Resets the attribute config to the initial config state.
  183. * @method resetConfig
  184. */
  185. resetConfig: function() {
  186. this.configure(this._initialConfig, true);
  187. },
  188. /**
  189. * Resets the value to the current value.
  190. * Useful when values may have gotten out of sync with actual properties.
  191. * @method refresh
  192. * @return {Boolean} Whether or not the value was set.
  193. */
  194. refresh: function(silent) {
  195. this.setValue(this.value, silent);
  196. }
  197. };
  198. (function() {
  199. var Lang = YAHOO.util.Lang;
  200. /*
  201. Copyright (c) 2006, Yahoo! Inc. All rights reserved.
  202. Code licensed under the BSD License:
  203. http://developer.yahoo.net/yui/license.txt
  204. */
  205. /**
  206. * Provides and manages YAHOO.util.Attribute instances
  207. * @namespace YAHOO.util
  208. * @class AttributeProvider
  209. * @uses YAHOO.util.EventProvider
  210. */
  211. YAHOO.util.AttributeProvider = function() {};
  212. YAHOO.util.AttributeProvider.prototype = {
  213. /**
  214. * A key-value map of Attribute configurations
  215. * @property _configs
  216. * @protected (may be used by subclasses and augmentors)
  217. * @private
  218. * @type {Object}
  219. */
  220. _configs: null,
  221. /**
  222. * Returns the current value of the attribute.
  223. * @method get
  224. * @param {String} key The attribute whose value will be returned.
  225. * @return {Any} The current value of the attribute.
  226. */
  227. get: function(key){
  228. this._configs = this._configs || {};
  229. var config = this._configs[key];
  230. if (!config || !this._configs.hasOwnProperty(key)) {
  231. return null;
  232. }
  233. return config.getValue();
  234. },
  235. /**
  236. * Sets the value of a config.
  237. * @method set
  238. * @param {String} key The name of the attribute
  239. * @param {Any} value The value to apply to the attribute
  240. * @param {Boolean} silent Whether or not to suppress change events
  241. * @return {Boolean} Whether or not the value was set.
  242. */
  243. set: function(key, value, silent){
  244. this._configs = this._configs || {};
  245. var config = this._configs[key];
  246. if (!config) {
  247. return false;
  248. }
  249. return config.setValue(value, silent);
  250. },
  251. /**
  252. * Returns an array of attribute names.
  253. * @method getAttributeKeys
  254. * @return {Array} An array of attribute names.
  255. */
  256. getAttributeKeys: function(){
  257. this._configs = this._configs;
  258. var keys = [], key;
  259. for (key in this._configs) {
  260. if ( Lang.hasOwnProperty(this._configs, key) &&
  261. !Lang.isUndefined(this._configs[key]) ) {
  262. keys[keys.length] = key;
  263. }
  264. }
  265. return keys;
  266. },
  267. /**
  268. * Sets multiple attribute values.
  269. * @method setAttributes
  270. * @param {Object} map A key-value map of attributes
  271. * @param {Boolean} silent Whether or not to suppress change events
  272. */
  273. setAttributes: function(map, silent){
  274. for (var key in map) {
  275. if ( Lang.hasOwnProperty(map, key) ) {
  276. this.set(key, map[key], silent);
  277. }
  278. }
  279. },
  280. /**
  281. * Resets the specified attribute's value to its initial value.
  282. * @method resetValue
  283. * @param {String} key The name of the attribute
  284. * @param {Boolean} silent Whether or not to suppress change events
  285. * @return {Boolean} Whether or not the value was set
  286. */
  287. resetValue: function(key, silent){
  288. this._configs = this._configs || {};
  289. if (this._configs[key]) {
  290. this.set(key, this._configs[key]._initialConfig.value, silent);
  291. return true;
  292. }
  293. return false;
  294. },
  295. /**
  296. * Sets the attribute's value to its current value.
  297. * @method refresh
  298. * @param {String | Array} key The attribute(s) to refresh
  299. * @param {Boolean} silent Whether or not to suppress change events
  300. */
  301. refresh: function(key, silent) {
  302. this._configs = this._configs || {};
  303. var configs = this._configs;
  304. key = ( ( Lang.isString(key) ) ? [key] : key ) ||
  305. this.getAttributeKeys();
  306. for (var i = 0, len = key.length; i < len; ++i) {
  307. if (configs.hasOwnProperty(key[i])) {
  308. this._configs[key[i]].refresh(silent);
  309. }
  310. }
  311. },
  312. /**
  313. * Adds an Attribute to the AttributeProvider instance.
  314. * @method register
  315. * @param {String} key The attribute's name
  316. * @param {Object} map A key-value map containing the
  317. * attribute's properties.
  318. * @deprecated Use setAttributeConfig
  319. */
  320. register: function(key, map) {
  321. this.setAttributeConfig(key, map);
  322. },
  323. /**
  324. * Returns the attribute's properties.
  325. * @method getAttributeConfig
  326. * @param {String} key The attribute's name
  327. * @private
  328. * @return {object} A key-value map containing all of the
  329. * attribute's properties.
  330. */
  331. getAttributeConfig: function(key) {
  332. this._configs = this._configs || {};
  333. var config = this._configs[key] || {};
  334. var map = {}; // returning a copy to prevent overrides
  335. for (key in config) {
  336. if ( Lang.hasOwnProperty(config, key) ) {
  337. map[key] = config[key];
  338. }
  339. }
  340. return map;
  341. },
  342. /**
  343. * Sets or updates an Attribute instance's properties.
  344. * @method setAttributeConfig
  345. * @param {String} key The attribute's name.
  346. * @param {Object} map A key-value map of attribute properties
  347. * @param {Boolean} init Whether or not this should become the intial config.
  348. */
  349. setAttributeConfig: function(key, map, init) {
  350. this._configs = this._configs || {};
  351. map = map || {};
  352. if (!this._configs[key]) {
  353. map.name = key;
  354. this._configs[key] = this.createAttribute(map);
  355. } else {
  356. this._configs[key].configure(map, init);
  357. }
  358. },
  359. /**
  360. * Sets or updates an Attribute instance's properties.
  361. * @method configureAttribute
  362. * @param {String} key The attribute's name.
  363. * @param {Object} map A key-value map of attribute properties
  364. * @param {Boolean} init Whether or not this should become the intial config.
  365. * @deprecated Use setAttributeConfig
  366. */
  367. configureAttribute: function(key, map, init) {
  368. this.setAttributeConfig(key, map, init);
  369. },
  370. /**
  371. * Resets an attribute to its intial configuration.
  372. * @method resetAttributeConfig
  373. * @param {String} key The attribute's name.
  374. * @private
  375. */
  376. resetAttributeConfig: function(key){
  377. this._configs = this._configs || {};
  378. this._configs[key].resetConfig();
  379. },
  380. // wrapper for EventProvider.subscribe
  381. // to create events on the fly
  382. subscribe: function(type, callback) {
  383. this._events = this._events || {};
  384. if ( !(type in this._events) ) {
  385. this._events[type] = this.createEvent(type);
  386. }
  387. YAHOO.util.EventProvider.prototype.subscribe.apply(this, arguments);
  388. },
  389. on: function() {
  390. this.subscribe.apply(this, arguments);
  391. },
  392. addListener: function() {
  393. this.subscribe.apply(this, arguments);
  394. },
  395. /**
  396. * Fires the attribute's beforeChange event.
  397. * @method fireBeforeChangeEvent
  398. * @param {String} key The attribute's name.
  399. * @param {Obj} e The event object to pass to handlers.
  400. */
  401. fireBeforeChangeEvent: function(e) {
  402. var type = 'before';
  403. type += e.type.charAt(0).toUpperCase() + e.type.substr(1) + 'Change';
  404. e.type = type;
  405. return this.fireEvent(e.type, e);
  406. },
  407. /**
  408. * Fires the attribute's change event.
  409. * @method fireChangeEvent
  410. * @param {String} key The attribute's name.
  411. * @param {Obj} e The event object to pass to the handlers.
  412. */
  413. fireChangeEvent: function(e) {
  414. e.type += 'Change';
  415. return this.fireEvent(e.type, e);
  416. },
  417. createAttribute: function(map) {
  418. return new YAHOO.util.Attribute(map, this);
  419. }
  420. };
  421. YAHOO.augment(YAHOO.util.AttributeProvider, YAHOO.util.EventProvider);
  422. })();
  423. (function() {
  424. // internal shorthand
  425. var Dom = YAHOO.util.Dom,
  426. AttributeProvider = YAHOO.util.AttributeProvider;
  427. /**
  428. * Element provides an wrapper object to simplify adding
  429. * event listeners, using dom methods, and managing attributes.
  430. * @module element
  431. * @namespace YAHOO.util
  432. * @requires yahoo, dom, event
  433. */
  434. /**
  435. * Element provides an wrapper object to simplify adding
  436. * event listeners, using dom methods, and managing attributes.
  437. * @class Element
  438. * @uses YAHOO.util.AttributeProvider
  439. * @constructor
  440. * @param el {HTMLElement | String} The html element that
  441. * represents the Element.
  442. * @param {Object} map A key-value map of initial config names and values
  443. */
  444. var Element = function(el, map) {
  445. this.init.apply(this, arguments);
  446. };
  447. Element.DOM_EVENTS = {
  448. 'click': true,
  449. 'dblclick': true,
  450. 'keydown': true,
  451. 'keypress': true,
  452. 'keyup': true,
  453. 'mousedown': true,
  454. 'mousemove': true,
  455. 'mouseout': true,
  456. 'mouseover': true,
  457. 'mouseup': true,
  458. 'focus': true,
  459. 'blur': true,
  460. 'submit': true,
  461. 'change': true
  462. };
  463. Element.prototype = {
  464. /**
  465. * Dom events supported by the Element instance.
  466. * @property DOM_EVENTS
  467. * @type Object
  468. */
  469. DOM_EVENTS: null,
  470. DEFAULT_HTML_SETTER: function(value, key) {
  471. var el = this.get('element');
  472. if (el) {
  473. el[key] = value;
  474. }
  475. },
  476. DEFAULT_HTML_GETTER: function(key) {
  477. var el = this.get('element'),
  478. val;
  479. if (el) {
  480. val = el[key];
  481. }
  482. return val;
  483. },
  484. /**
  485. * Wrapper for HTMLElement method.
  486. * @method appendChild
  487. * @param {YAHOO.util.Element || HTMLElement} child The element to append.
  488. * @return {HTMLElement} The appended DOM element.
  489. */
  490. appendChild: function(child) {
  491. child = child.get ? child.get('element') : child;
  492. return this.get('element').appendChild(child);
  493. },
  494. /**
  495. * Wrapper for HTMLElement method.
  496. * @method getElementsByTagName
  497. * @param {String} tag The tagName to collect
  498. * @return {HTMLCollection} A collection of DOM elements.
  499. */
  500. getElementsByTagName: function(tag) {
  501. return this.get('element').getElementsByTagName(tag);
  502. },
  503. /**
  504. * Wrapper for HTMLElement method.
  505. * @method hasChildNodes
  506. * @return {Boolean} Whether or not the element has childNodes
  507. */
  508. hasChildNodes: function() {
  509. return this.get('element').hasChildNodes();
  510. },
  511. /**
  512. * Wrapper for HTMLElement method.
  513. * @method insertBefore
  514. * @param {HTMLElement} element The HTMLElement to insert
  515. * @param {HTMLElement} before The HTMLElement to insert
  516. * the element before.
  517. * @return {HTMLElement} The inserted DOM element.
  518. */
  519. insertBefore: function(element, before) {
  520. element = element.get ? element.get('element') : element;
  521. before = (before && before.get) ? before.get('element') : before;
  522. return this.get('element').insertBefore(element, before);
  523. },
  524. /**
  525. * Wrapper for HTMLElement method.
  526. * @method removeChild
  527. * @param {HTMLElement} child The HTMLElement to remove
  528. * @return {HTMLElement} The removed DOM element.
  529. */
  530. removeChild: function(child) {
  531. child = child.get ? child.get('element') : child;
  532. return this.get('element').removeChild(child);
  533. },
  534. /**
  535. * Wrapper for HTMLElement method.
  536. * @method replaceChild
  537. * @param {HTMLElement} newNode The HTMLElement to insert
  538. * @param {HTMLElement} oldNode The HTMLElement to replace
  539. * @return {HTMLElement} The replaced DOM element.
  540. */
  541. replaceChild: function(newNode, oldNode) {
  542. newNode = newNode.get ? newNode.get('element') : newNode;
  543. oldNode = oldNode.get ? oldNode.get('element') : oldNode;
  544. return this.get('element').replaceChild(newNode, oldNode);
  545. },
  546. /**
  547. * Registers Element specific attributes.
  548. * @method initAttributes
  549. * @param {Object} map A key-value map of initial attribute configs
  550. */
  551. initAttributes: function(map) {
  552. },
  553. /**
  554. * Adds a listener for the given event. These may be DOM or
  555. * customEvent listeners. Any event that is fired via fireEvent
  556. * can be listened for. All handlers receive an event object.
  557. * @method addListener
  558. * @param {String} type The name of the event to listen for
  559. * @param {Function} fn The handler to call when the event fires
  560. * @param {Any} obj A variable to pass to the handler
  561. * @param {Object} scope The object to use for the scope of the handler
  562. */
  563. addListener: function(type, fn, obj, scope) {
  564. var el = this.get('element') || this.get('id');
  565. scope = scope || this;
  566. var self = this;
  567. if (!this._events[type]) { // create on the fly
  568. if (el && this.DOM_EVENTS[type]) {
  569. YAHOO.util.Event.addListener(el, type, function(e) {
  570. if (e.srcElement && !e.target) { // supplement IE with target
  571. e.target = e.srcElement;
  572. }
  573. self.fireEvent(type, e);
  574. }, obj, scope);
  575. }
  576. this.createEvent(type, this);
  577. }
  578. return YAHOO.util.EventProvider.prototype.subscribe.apply(this, arguments); // notify via customEvent
  579. },
  580. /**
  581. * Alias for addListener
  582. * @method on
  583. * @param {String} type The name of the event to listen for
  584. * @param {Function} fn The function call when the event fires
  585. * @param {Any} obj A variable to pass to the handler
  586. * @param {Object} scope The object to use for the scope of the handler
  587. */
  588. on: function() {
  589. return this.addListener.apply(this, arguments);
  590. },
  591. /**
  592. * Alias for addListener
  593. * @method subscribe
  594. * @param {String} type The name of the event to listen for
  595. * @param {Function} fn The function call when the event fires
  596. * @param {Any} obj A variable to pass to the handler
  597. * @param {Object} scope The object to use for the scope of the handler
  598. */
  599. subscribe: function() {
  600. return this.addListener.apply(this, arguments);
  601. },
  602. /**
  603. * Remove an event listener
  604. * @method removeListener
  605. * @param {String} type The name of the event to listen for
  606. * @param {Function} fn The function call when the event fires
  607. */
  608. removeListener: function(type, fn) {
  609. return this.unsubscribe.apply(this, arguments);
  610. },
  611. /**
  612. * Wrapper for Dom method.
  613. * @method addClass
  614. * @param {String} className The className to add
  615. */
  616. addClass: function(className) {
  617. Dom.addClass(this.get('element'), className);
  618. },
  619. /**
  620. * Wrapper for Dom method.
  621. * @method getElementsByClassName
  622. * @param {String} className The className to collect
  623. * @param {String} tag (optional) The tag to use in
  624. * conjunction with class name
  625. * @return {Array} Array of HTMLElements
  626. */
  627. getElementsByClassName: function(className, tag) {
  628. return Dom.getElementsByClassName(className, tag,
  629. this.get('element') );
  630. },
  631. /**
  632. * Wrapper for Dom method.
  633. * @method hasClass
  634. * @param {String} className The className to add
  635. * @return {Boolean} Whether or not the element has the class name
  636. */
  637. hasClass: function(className) {
  638. return Dom.hasClass(this.get('element'), className);
  639. },
  640. /**
  641. * Wrapper for Dom method.
  642. * @method removeClass
  643. * @param {String} className The className to remove
  644. */
  645. removeClass: function(className) {
  646. return Dom.removeClass(this.get('element'), className);
  647. },
  648. /**
  649. * Wrapper for Dom method.
  650. * @method replaceClass
  651. * @param {String} oldClassName The className to replace
  652. * @param {String} newClassName The className to add
  653. */
  654. replaceClass: function(oldClassName, newClassName) {
  655. return Dom.replaceClass(this.get('element'),
  656. oldClassName, newClassName);
  657. },
  658. /**
  659. * Wrapper for Dom method.
  660. * @method setStyle
  661. * @param {String} property The style property to set
  662. * @param {String} value The value to apply to the style property
  663. */
  664. setStyle: function(property, value) {
  665. return Dom.setStyle(this.get('element'), property, value); // TODO: always queuing?
  666. },
  667. /**
  668. * Wrapper for Dom method.
  669. * @method getStyle
  670. * @param {String} property The style property to retrieve
  671. * @return {String} The current value of the property
  672. */
  673. getStyle: function(property) {
  674. return Dom.getStyle(this.get('element'), property);
  675. },
  676. /**
  677. * Apply any queued set calls.
  678. * @method fireQueue
  679. */
  680. fireQueue: function() {
  681. var queue = this._queue;
  682. for (var i = 0, len = queue.length; i < len; ++i) {
  683. this[queue[i][0]].apply(this, queue[i][1]);
  684. }
  685. },
  686. /**
  687. * Appends the HTMLElement into either the supplied parentNode.
  688. * @method appendTo
  689. * @param {HTMLElement | Element} parentNode The node to append to
  690. * @param {HTMLElement | Element} before An optional node to insert before
  691. * @return {HTMLElement} The appended DOM element.
  692. */
  693. appendTo: function(parent, before) {
  694. parent = (parent.get) ? parent.get('element') : Dom.get(parent);
  695. this.fireEvent('beforeAppendTo', {
  696. type: 'beforeAppendTo',
  697. target: parent
  698. });
  699. before = (before && before.get) ?
  700. before.get('element') : Dom.get(before);
  701. var element = this.get('element');
  702. if (!element) {
  703. return false;
  704. }
  705. if (!parent) {
  706. return false;
  707. }
  708. if (element.parent != parent) {
  709. if (before) {
  710. parent.insertBefore(element, before);
  711. } else {
  712. parent.appendChild(element);
  713. }
  714. }
  715. this.fireEvent('appendTo', {
  716. type: 'appendTo',
  717. target: parent
  718. });
  719. return element;
  720. },
  721. get: function(key) {
  722. var configs = this._configs || {},
  723. el = configs.element; // avoid loop due to 'element'
  724. if (el && !configs[key] && !YAHOO.lang.isUndefined(el.value[key]) ) {
  725. this._setHTMLAttrConfig(key);
  726. }
  727. return AttributeProvider.prototype.get.call(this, key);
  728. },
  729. setAttributes: function(map, silent) {
  730. // set based on configOrder
  731. var done = {},
  732. configOrder = this._configOrder;
  733. // set based on configOrder
  734. for (var i = 0, len = configOrder.length; i < len; ++i) {
  735. if (map[configOrder[i]] !== undefined) {
  736. done[configOrder[i]] = true;
  737. this.set(configOrder[i], map[configOrder[i]], silent);
  738. }
  739. }
  740. // unconfigured (e.g. Dom attributes)
  741. for (var att in map) {
  742. if (map.hasOwnProperty(att) && !done[att]) {
  743. this.set(att, map[att], silent);
  744. }
  745. }
  746. },
  747. set: function(key, value, silent) {
  748. var el = this.get('element');
  749. if (!el) {
  750. this._queue[this._queue.length] = ['set', arguments];
  751. if (this._configs[key]) {
  752. this._configs[key].value = value; // so "get" works while queueing
  753. }
  754. return;
  755. }
  756. // set it on the element if not configured and is an HTML attribute
  757. if ( !this._configs[key] && !YAHOO.lang.isUndefined(el[key]) ) {
  758. this._setHTMLAttrConfig(key);
  759. }
  760. return AttributeProvider.prototype.set.apply(this, arguments);
  761. },
  762. setAttributeConfig: function(key, map, init) {
  763. this._configOrder.push(key);
  764. AttributeProvider.prototype.setAttributeConfig.apply(this, arguments);
  765. },
  766. createEvent: function(type, scope) {
  767. this._events[type] = true;
  768. return AttributeProvider.prototype.createEvent.apply(this, arguments);
  769. },
  770. init: function(el, attr) {
  771. this._initElement(el, attr);
  772. },
  773. destroy: function() {
  774. var el = this.get('element');
  775. YAHOO.util.Event.purgeElement(el, true); // purge DOM listeners recursively
  776. this.unsubscribeAll(); // unsubscribe all custom events
  777. if (el && el.parentNode) {
  778. el.parentNode.removeChild(el); // pull from the DOM
  779. }
  780. // revert initial configs
  781. this._queue = [];
  782. this._events = {};
  783. this._configs = {};
  784. this._configOrder = [];
  785. },
  786. _initElement: function(el, attr) {
  787. this._queue = this._queue || [];
  788. this._events = this._events || {};
  789. this._configs = this._configs || {};
  790. this._configOrder = [];
  791. attr = attr || {};
  792. attr.element = attr.element || el || null;
  793. var isReady = false; // to determine when to init HTMLElement and content
  794. var DOM_EVENTS = Element.DOM_EVENTS;
  795. this.DOM_EVENTS = this.DOM_EVENTS || {};
  796. for (var event in DOM_EVENTS) {
  797. if (DOM_EVENTS.hasOwnProperty(event)) {
  798. this.DOM_EVENTS[event] = DOM_EVENTS[event];
  799. }
  800. }
  801. if (typeof attr.element === 'string') { // register ID for get() access
  802. this._setHTMLAttrConfig('id', { value: attr.element });
  803. }
  804. if (Dom.get(attr.element)) {
  805. isReady = true;
  806. this._initHTMLElement(attr);
  807. this._initContent(attr);
  808. }
  809. YAHOO.util.Event.onAvailable(attr.element, function() {
  810. if (!isReady) { // otherwise already done
  811. this._initHTMLElement(attr);
  812. }
  813. this.fireEvent('available', { type: 'available', target: Dom.get(attr.element) });
  814. }, this, true);
  815. YAHOO.util.Event.onContentReady(attr.element, function() {
  816. if (!isReady) { // otherwise already done
  817. this._initContent(attr);
  818. }
  819. this.fireEvent('contentReady', { type: 'contentReady', target: Dom.get(attr.element) });
  820. }, this, true);
  821. },
  822. _initHTMLElement: function(attr) {
  823. /**
  824. * The HTMLElement the Element instance refers to.
  825. * @attribute element
  826. * @type HTMLElement
  827. */
  828. this.setAttributeConfig('element', {
  829. value: Dom.get(attr.element),
  830. readOnly: true
  831. });
  832. },
  833. _initContent: function(attr) {
  834. this.initAttributes(attr);
  835. this.setAttributes(attr, true);
  836. this.fireQueue();
  837. },
  838. /**
  839. * Sets the value of the property and fires beforeChange and change events.
  840. * @private
  841. * @method _setHTMLAttrConfig
  842. * @param {YAHOO.util.Element} element The Element instance to
  843. * register the config to.
  844. * @param {String} key The name of the config to register
  845. * @param {Object} map A key-value map of the config's params
  846. */
  847. _setHTMLAttrConfig: function(key, map) {
  848. var el = this.get('element');
  849. map = map || {};
  850. map.name = key;
  851. map.setter = map.setter || this.DEFAULT_HTML_SETTER;
  852. map.getter = map.getter || this.DEFAULT_HTML_GETTER;
  853. map.value = map.value || el[key];
  854. this._configs[key] = new YAHOO.util.Attribute(map, this);
  855. }
  856. };
  857. /**
  858. * Fires when the Element's HTMLElement can be retrieved by Id.
  859. * <p>See: <a href="#addListener">Element.addListener</a></p>
  860. * <p><strong>Event fields:</strong><br>
  861. * <code>&lt;String&gt; type</code> available<br>
  862. * <code>&lt;HTMLElement&gt;
  863. * target</code> the HTMLElement bound to this Element instance<br>
  864. * <p><strong>Usage:</strong><br>
  865. * <code>var handler = function(e) {var target = e.target};<br>
  866. * myTabs.addListener('available', handler);</code></p>
  867. * @event available
  868. */
  869. /**
  870. * Fires when the Element's HTMLElement subtree is rendered.
  871. * <p>See: <a href="#addListener">Element.addListener</a></p>
  872. * <p><strong>Event fields:</strong><br>
  873. * <code>&lt;String&gt; type</code> contentReady<br>
  874. * <code>&lt;HTMLElement&gt;
  875. * target</code> the HTMLElement bound to this Element instance<br>
  876. * <p><strong>Usage:</strong><br>
  877. * <code>var handler = function(e) {var target = e.target};<br>
  878. * myTabs.addListener('contentReady', handler);</code></p>
  879. * @event contentReady
  880. */
  881. /**
  882. * Fires before the Element is appended to another Element.
  883. * <p>See: <a href="#addListener">Element.addListener</a></p>
  884. * <p><strong>Event fields:</strong><br>
  885. * <code>&lt;String&gt; type</code> beforeAppendTo<br>
  886. * <code>&lt;HTMLElement/Element&gt;
  887. * target</code> the HTMLElement/Element being appended to
  888. * <p><strong>Usage:</strong><br>
  889. * <code>var handler = function(e) {var target = e.target};<br>
  890. * myTabs.addListener('beforeAppendTo', handler);</code></p>
  891. * @event beforeAppendTo
  892. */
  893. /**
  894. * Fires after the Element is appended to another Element.
  895. * <p>See: <a href="#addListener">Element.addListener</a></p>
  896. * <p><strong>Event fields:</strong><br>
  897. * <code>&lt;String&gt; type</code> appendTo<br>
  898. * <code>&lt;HTMLElement/Element&gt;
  899. * target</code> the HTMLElement/Element being appended to
  900. * <p><strong>Usage:</strong><br>
  901. * <code>var handler = function(e) {var target = e.target};<br>
  902. * myTabs.addListener('appendTo', handler);</code></p>
  903. * @event appendTo
  904. */
  905. YAHOO.augment(Element, AttributeProvider);
  906. YAHOO.util.Element = Element;
  907. })();
  908. YAHOO.register("element", YAHOO.util.Element, {version: "2.7.0", build: "1799"});