[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/widget-parent/ -> widget-parent.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('widget-parent', function (Y, NAME) {
   9  
  10  /**
  11   * Extension enabling a Widget to be a parent of another Widget.
  12   *
  13   * @module widget-parent
  14   */
  15  
  16  var Lang = Y.Lang,
  17      RENDERED = "rendered",
  18      BOUNDING_BOX = "boundingBox";
  19  
  20  /**
  21   * Widget extension providing functionality enabling a Widget to be a
  22   * parent of another Widget.
  23   *
  24   * <p>In addition to the set of attributes supported by WidgetParent, the constructor
  25   * configuration object can also contain a <code>children</code> which can be used
  26   * to add child widgets to the parent during construction. The <code>children</code>
  27   * property is an array of either child widget instances or child widget configuration
  28   * objects, and is sugar for the <a href="#method_add">add</a> method. See the
  29   * <a href="#method_add">add</a> for details on the structure of the child widget
  30   * configuration object.
  31   * @class WidgetParent
  32   * @constructor
  33   * @uses ArrayList
  34   * @param {Object} config User configuration object.
  35   */
  36  function Parent(config) {
  37  
  38      /**
  39      * Fires when a Widget is add as a child.  The event object will have a
  40      * 'child' property that returns a reference to the child Widget, as well
  41      * as an 'index' property that returns a reference to the index specified
  42      * when the add() method was called.
  43      * <p>
  44      * Subscribers to the "on" moment of this event, will be notified
  45      * before a child is added.
  46      * </p>
  47      * <p>
  48      * Subscribers to the "after" moment of this event, will be notified
  49      * after a child is added.
  50      * </p>
  51      *
  52      * @event addChild
  53      * @preventable _defAddChildFn
  54      * @param {EventFacade} e The Event Facade
  55      */
  56      this.publish("addChild", {
  57          defaultTargetOnly: true,
  58          defaultFn: this._defAddChildFn
  59      });
  60  
  61  
  62      /**
  63      * Fires when a child Widget is removed.  The event object will have a
  64      * 'child' property that returns a reference to the child Widget, as well
  65      * as an 'index' property that returns a reference child's ordinal position.
  66      * <p>
  67      * Subscribers to the "on" moment of this event, will be notified
  68      * before a child is removed.
  69      * </p>
  70      * <p>
  71      * Subscribers to the "after" moment of this event, will be notified
  72      * after a child is removed.
  73      * </p>
  74      *
  75      * @event removeChild
  76      * @preventable _defRemoveChildFn
  77      * @param {EventFacade} e The Event Facade
  78      */
  79      this.publish("removeChild", {
  80          defaultTargetOnly: true,
  81          defaultFn: this._defRemoveChildFn
  82      });
  83  
  84      this._items = [];
  85  
  86      var children,
  87          handle;
  88  
  89      if (config && config.children) {
  90  
  91          children = config.children;
  92  
  93          handle = this.after("initializedChange", function (e) {
  94              this._add(children);
  95              handle.detach();
  96          });
  97  
  98      }
  99  
 100      //  Widget method overlap
 101      Y.after(this._renderChildren, this, "renderUI");
 102      Y.after(this._bindUIParent, this, "bindUI");
 103  
 104      this.after("selectionChange", this._afterSelectionChange);
 105      this.after("selectedChange", this._afterParentSelectedChange);
 106      this.after("activeDescendantChange", this._afterActiveDescendantChange);
 107  
 108      this._hDestroyChild = this.after("*:destroy", this._afterDestroyChild);
 109      this.after("*:focusedChange", this._updateActiveDescendant);
 110  
 111  }
 112  
 113  Parent.ATTRS = {
 114  
 115      /**
 116       * @attribute defaultChildType
 117       * @type {String|Object}
 118       *
 119       * @description String representing the default type of the children
 120       * managed by this Widget.  Can also supply default type as a constructor
 121       * reference.
 122       */
 123      defaultChildType: {
 124          setter: function (val) {
 125  
 126              var returnVal = Y.Attribute.INVALID_VALUE,
 127                  FnConstructor = Lang.isString(val) ? Y[val] : val;
 128  
 129              if (Lang.isFunction(FnConstructor)) {
 130                  returnVal = FnConstructor;
 131              }
 132  
 133              return returnVal;
 134          }
 135      },
 136  
 137      /**
 138       * @attribute activeDescendant
 139       * @type Widget
 140       * @readOnly
 141       *
 142       * @description Returns the Widget's currently focused descendant Widget.
 143       */
 144      activeDescendant: {
 145          readOnly: true
 146      },
 147  
 148      /**
 149       * @attribute multiple
 150       * @type Boolean
 151       * @default false
 152       * @writeOnce
 153       *
 154       * @description Boolean indicating if multiple children can be selected at
 155       * once.  Whether or not multiple selection is enabled is always delegated
 156       * to the value of the <code>multiple</code> attribute of the root widget
 157       * in the object hierarchy.
 158       */
 159      multiple: {
 160          value: false,
 161          validator: Lang.isBoolean,
 162          writeOnce: true,
 163          getter: function (value) {
 164              var root = this.get("root");
 165              return (root && root != this) ? root.get("multiple") : value;
 166          }
 167      },
 168  
 169  
 170      /**
 171       * @attribute selection
 172       * @type {ArrayList|Widget}
 173       * @readOnly
 174       *
 175       * @description Returns the currently selected child Widget.  If the
 176       * <code>mulitple</code> attribte is set to <code>true</code> will
 177       * return an Y.ArrayList instance containing the currently selected
 178       * children.  If no children are selected, will return null.
 179       */
 180      selection: {
 181          readOnly: true,
 182          setter: "_setSelection",
 183          getter: function (value) {
 184              var selection = Lang.isArray(value) ?
 185                      (new Y.ArrayList(value)) : value;
 186              return selection;
 187          }
 188      },
 189  
 190      selected: {
 191          setter: function (value) {
 192  
 193              //  Enforces selection behavior on for parent Widgets.  Parent's
 194              //  selected attribute can be set to the following:
 195              //  0 - Not selected
 196              //  1 - Fully selected (all children are selected).  In order for
 197              //  all children to be selected, multiple selection must be
 198              //  enabled.  Therefore, you cannot set the "selected" attribute
 199              //  on a parent Widget to 1 unless multiple selection is enabled.
 200              //  2 - Partially selected, meaning one ore more (but not all)
 201              //  children are selected.
 202  
 203              var returnVal = value;
 204  
 205              if (value === 1 && !this.get("multiple")) {
 206                  returnVal = Y.Attribute.INVALID_VALUE;
 207              }
 208  
 209              return returnVal;
 210          }
 211      }
 212  
 213  };
 214  
 215  Parent.prototype = {
 216  
 217      /**
 218       * The destructor implementation for Parent widgets. Destroys all children.
 219       * @method destructor
 220       */
 221      destructor: function() {
 222          this._destroyChildren();
 223      },
 224  
 225      /**
 226       * Destroy event listener for each child Widget, responsible for removing
 227       * the destroyed child Widget from the parent's internal array of children
 228       * (_items property).
 229       *
 230       * @method _afterDestroyChild
 231       * @protected
 232       * @param {EventFacade} event The event facade for the attribute change.
 233       */
 234      _afterDestroyChild: function (event) {
 235          var child = event.target;
 236  
 237          if (child.get("parent") == this) {
 238              child.remove();
 239          }
 240      },
 241  
 242      /**
 243       * Attribute change listener for the <code>selection</code>
 244       * attribute, responsible for setting the value of the
 245       * parent's <code>selected</code> attribute.
 246       *
 247       * @method _afterSelectionChange
 248       * @protected
 249       * @param {EventFacade} event The event facade for the attribute change.
 250       */
 251      _afterSelectionChange: function (event) {
 252  
 253          if (event.target == this && event.src != this) {
 254  
 255              var selection = event.newVal,
 256                  selectedVal = 0;    //  Not selected
 257  
 258  
 259              if (selection) {
 260  
 261                  selectedVal = 2;    //  Assume partially selected, confirm otherwise
 262  
 263  
 264                  if (Y.instanceOf(selection, Y.ArrayList) &&
 265                      (selection.size() === this.size())) {
 266  
 267                      selectedVal = 1;    //  Fully selected
 268  
 269                  }
 270  
 271              }
 272  
 273              this.set("selected", selectedVal, { src: this });
 274  
 275          }
 276      },
 277  
 278  
 279      /**
 280       * Attribute change listener for the <code>activeDescendant</code>
 281       * attribute, responsible for setting the value of the
 282       * parent's <code>activeDescendant</code> attribute.
 283       *
 284       * @method _afterActiveDescendantChange
 285       * @protected
 286       * @param {EventFacade} event The event facade for the attribute change.
 287       */
 288      _afterActiveDescendantChange: function (event) {
 289          var parent = this.get("parent");
 290  
 291          if (parent) {
 292              parent._set("activeDescendant", event.newVal);
 293          }
 294      },
 295  
 296      /**
 297       * Attribute change listener for the <code>selected</code>
 298       * attribute, responsible for syncing the selected state of all children to
 299       * match that of their parent Widget.
 300       *
 301       *
 302       * @method _afterParentSelectedChange
 303       * @protected
 304       * @param {EventFacade} event The event facade for the attribute change.
 305       */
 306      _afterParentSelectedChange: function (event) {
 307  
 308          var value = event.newVal;
 309  
 310          if (this == event.target && event.src != this &&
 311              (value === 0 || value === 1)) {
 312  
 313              this.each(function (child) {
 314  
 315                  //  Specify the source of this change as the parent so that
 316                  //  value of the parent's "selection" attribute isn't
 317                  //  recalculated
 318  
 319                  child.set("selected", value, { src: this });
 320  
 321              }, this);
 322  
 323          }
 324  
 325      },
 326  
 327  
 328      /**
 329       * Default setter for <code>selection</code> attribute changes.
 330       *
 331       * @method _setSelection
 332       * @protected
 333       * @param child {Widget|Array} Widget or Array of Widget instances.
 334       * @return {Widget|Array} Widget or Array of Widget instances.
 335       */
 336      _setSelection: function (child) {
 337  
 338          var selection = null,
 339              selected;
 340  
 341          if (this.get("multiple") && !this.isEmpty()) {
 342  
 343              selected = [];
 344  
 345              this.each(function (v) {
 346  
 347                 if (v.get("selected") > 0) {
 348                     selected.push(v);
 349                 }
 350  
 351              });
 352  
 353              if (selected.length > 0) {
 354                  selection = selected;
 355              }
 356  
 357          }
 358          else {
 359  
 360              if (child.get("selected") > 0) {
 361                  selection = child;
 362              }
 363  
 364          }
 365  
 366          return selection;
 367  
 368      },
 369  
 370  
 371      /**
 372       * Attribute change listener for the <code>selected</code>
 373       * attribute of child Widgets, responsible for setting the value of the
 374       * parent's <code>selection</code> attribute.
 375       *
 376       * @method _updateSelection
 377       * @protected
 378       * @param {EventFacade} event The event facade for the attribute change.
 379       */
 380      _updateSelection: function (event) {
 381  
 382          var child = event.target,
 383              selection;
 384  
 385          if (child.get("parent") == this) {
 386  
 387              if (event.src != "_updateSelection") {
 388  
 389                  selection = this.get("selection");
 390  
 391                  if (!this.get("multiple") && selection && event.newVal > 0) {
 392  
 393                      //  Deselect the previously selected child.
 394                      //  Set src equal to the current context to prevent
 395                      //  unnecessary re-calculation of the selection.
 396  
 397                      selection.set("selected", 0, { src: "_updateSelection" });
 398  
 399                  }
 400  
 401                  this._set("selection", child);
 402  
 403              }
 404  
 405              if (event.src == this) {
 406                  this._set("selection", child, { src: this });
 407              }
 408  
 409          }
 410  
 411      },
 412  
 413      /**
 414       * Attribute change listener for the <code>focused</code>
 415       * attribute of child Widgets, responsible for setting the value of the
 416       * parent's <code>activeDescendant</code> attribute.
 417       *
 418       * @method _updateActiveDescendant
 419       * @protected
 420       * @param {EventFacade} event The event facade for the attribute change.
 421       */
 422      _updateActiveDescendant: function (event) {
 423          var activeDescendant = (event.newVal === true) ? event.target : null;
 424          this._set("activeDescendant", activeDescendant);
 425      },
 426  
 427      /**
 428       * Creates an instance of a child Widget using the specified configuration.
 429       * By default Widget instances will be created of the type specified
 430       * by the <code>defaultChildType</code> attribute.  Types can be explicitly
 431       * defined via the <code>childType</code> property of the configuration object
 432       * literal. The use of the <code>type</code> property has been deprecated, but
 433       * will still be used as a fallback, if <code>childType</code> is not defined,
 434       * for backwards compatibility.
 435       *
 436       * @method _createChild
 437       * @protected
 438       * @param config {Object} Object literal representing the configuration
 439       * used to create an instance of a Widget.
 440       */
 441      _createChild: function (config) {
 442  
 443          var defaultType = this.get("defaultChildType"),
 444              altType = config.childType || config.type,
 445              child,
 446              Fn,
 447              FnConstructor;
 448  
 449          if (altType) {
 450              Fn = Lang.isString(altType) ? Y[altType] : altType;
 451          }
 452  
 453          if (Lang.isFunction(Fn)) {
 454              FnConstructor = Fn;
 455          } else if (defaultType) {
 456              // defaultType is normalized to a function in it's setter
 457              FnConstructor = defaultType;
 458          }
 459  
 460          if (FnConstructor) {
 461              child = new FnConstructor(config);
 462          } else {
 463              Y.error("Could not create a child instance because its constructor is either undefined or invalid.");
 464          }
 465  
 466          return child;
 467  
 468      },
 469  
 470      /**
 471       * Default addChild handler
 472       *
 473       * @method _defAddChildFn
 474       * @protected
 475       * @param event {EventFacade} The Event object
 476       * @param child {Widget} The Widget instance, or configuration
 477       * object for the Widget to be added as a child.
 478       * @param index {Number} Number representing the position at
 479       * which the child will be inserted.
 480       */
 481      _defAddChildFn: function (event) {
 482  
 483          var child = event.child,
 484              index = event.index,
 485              children = this._items;
 486  
 487          if (child.get("parent")) {
 488              child.remove();
 489          }
 490  
 491          if (Lang.isNumber(index)) {
 492              children.splice(index, 0, child);
 493          }
 494          else {
 495              children.push(child);
 496          }
 497  
 498          child._set("parent", this);
 499          child.addTarget(this);
 500  
 501          // Update index in case it got normalized after addition
 502          // (e.g. user passed in 10, and there are only 3 items, the actual index would be 3. We don't want to pass 10 around in the event facade).
 503          event.index = child.get("index");
 504  
 505          //  TO DO: Remove in favor of using event bubbling
 506          child.after("selectedChange", Y.bind(this._updateSelection, this));
 507      },
 508  
 509  
 510      /**
 511       * Default removeChild handler
 512       *
 513       * @method _defRemoveChildFn
 514       * @protected
 515       * @param event {EventFacade} The Event object
 516       * @param child {Widget} The Widget instance to be removed.
 517       * @param index {Number} Number representing the index of the Widget to
 518       * be removed.
 519       */
 520      _defRemoveChildFn: function (event) {
 521  
 522          var child = event.child,
 523              index = event.index,
 524              children = this._items;
 525  
 526          if (child.get("focused")) {
 527              child.blur(); // focused is readOnly, so use the public i/f to unset it
 528          }
 529  
 530          if (child.get("selected")) {
 531              child.set("selected", 0);
 532          }
 533  
 534          children.splice(index, 1);
 535  
 536          child.removeTarget(this);
 537          child._oldParent = child.get("parent");
 538          child._set("parent", null);
 539      },
 540  
 541      /**
 542      * @method _add
 543      * @protected
 544      * @param child {Widget|Object} The Widget instance, or configuration
 545      * object for the Widget to be added as a child.
 546      * @param child {Array} Array of Widget instances, or configuration
 547      * objects for the Widgets to be added as a children.
 548      * @param index {Number} (Optional.)  Number representing the position at
 549      * which the child should be inserted.
 550      * @description Adds a Widget as a child.  If the specified Widget already
 551      * has a parent it will be removed from its current parent before
 552      * being added as a child.
 553      * @return {Widget|Array} Successfully added Widget or Array containing the
 554      * successfully added Widget instance(s). If no children where added, will
 555      * will return undefined.
 556      */
 557      _add: function (child, index) {
 558  
 559          var children,
 560              oChild,
 561              returnVal;
 562  
 563  
 564          if (Lang.isArray(child)) {
 565  
 566              children = [];
 567  
 568              Y.each(child, function (v, k) {
 569  
 570                  oChild = this._add(v, (index + k));
 571  
 572                  if (oChild) {
 573                      children.push(oChild);
 574                  }
 575  
 576              }, this);
 577  
 578  
 579              if (children.length > 0) {
 580                  returnVal = children;
 581              }
 582  
 583          }
 584          else {
 585  
 586              if (Y.instanceOf(child, Y.Widget)) {
 587                  oChild = child;
 588              }
 589              else {
 590                  oChild = this._createChild(child);
 591              }
 592  
 593              if (oChild && this.fire("addChild", { child: oChild, index: index })) {
 594                  returnVal = oChild;
 595              }
 596  
 597          }
 598  
 599          return returnVal;
 600  
 601      },
 602  
 603  
 604      /**
 605      * @method add
 606      * @param child {Widget|Object} The Widget instance, or configuration
 607      * object for the Widget to be added as a child. The configuration object
 608      * for the child can include a <code>childType</code> property, which is either
 609      * a constructor function or a string which names a constructor function on the
 610      * Y instance (e.g. "Tab" would refer to Y.Tab) (<code>childType</code> used to be
 611      * named <code>type</code>, support for which has been deprecated, but is still
 612      * maintained for backward compatibility. <code>childType</code> takes precedence
 613      * over <code>type</code> if both are defined.
 614      * @param child {Array} Array of Widget instances, or configuration
 615      * objects for the Widgets to be added as a children.
 616      * @param index {Number} (Optional.)  Number representing the position at
 617      * which the child should be inserted.
 618      * @description Adds a Widget as a child.  If the specified Widget already
 619      * has a parent it will be removed from its current parent before
 620      * being added as a child.
 621      * @return {ArrayList} Y.ArrayList containing the successfully added
 622      * Widget instance(s).  If no children where added, will return an empty
 623      * Y.ArrayList instance.
 624      */
 625      add: function () {
 626  
 627          var added = this._add.apply(this, arguments),
 628              children = added ? (Lang.isArray(added) ? added : [added]) : [];
 629  
 630          return (new Y.ArrayList(children));
 631  
 632      },
 633  
 634  
 635      /**
 636      * @method remove
 637      * @param index {Number} (Optional.)  Number representing the index of the
 638      * child to be removed.
 639      * @description Removes the Widget from its parent.  Optionally, can remove
 640      * a child by specifying its index.
 641      * @return {Widget} Widget instance that was successfully removed, otherwise
 642      * undefined.
 643      */
 644      remove: function (index) {
 645  
 646          var child = this._items[index],
 647              returnVal;
 648  
 649          if (child && this.fire("removeChild", { child: child, index: index })) {
 650              returnVal = child;
 651          }
 652  
 653          return returnVal;
 654  
 655      },
 656  
 657  
 658      /**
 659      * @method removeAll
 660      * @description Removes all of the children from the Widget.
 661      * @return {ArrayList} Y.ArrayList instance containing Widgets that were
 662      * successfully removed.  If no children where removed, will return an empty
 663      * Y.ArrayList instance.
 664      */
 665      removeAll: function () {
 666  
 667          var removed = [],
 668              child;
 669  
 670          Y.each(this._items.concat(), function () {
 671  
 672              child = this.remove(0);
 673  
 674              if (child) {
 675                  removed.push(child);
 676              }
 677  
 678          }, this);
 679  
 680          return (new Y.ArrayList(removed));
 681  
 682      },
 683  
 684      /**
 685       * Selects the child at the given index (zero-based).
 686       *
 687       * @method selectChild
 688       * @param {Number} i the index of the child to be selected
 689       */
 690      selectChild: function(i) {
 691          this.item(i).set('selected', 1);
 692      },
 693  
 694      /**
 695       * Selects all children.
 696       *
 697       * @method selectAll
 698       */
 699      selectAll: function () {
 700          this.set("selected", 1);
 701      },
 702  
 703      /**
 704       * Deselects all children.
 705       *
 706       * @method deselectAll
 707       */
 708      deselectAll: function () {
 709          this.set("selected", 0);
 710      },
 711  
 712      /**
 713       * Updates the UI in response to a child being added.
 714       *
 715       * @method _uiAddChild
 716       * @protected
 717       * @param child {Widget} The child Widget instance to render.
 718       * @param parentNode {Object} The Node under which the
 719       * child Widget is to be rendered.
 720       */
 721      _uiAddChild: function (child, parentNode) {
 722  
 723          child.render(parentNode);
 724  
 725          // TODO: Ideally this should be in Child's render UI.
 726  
 727          var childBB = child.get("boundingBox"),
 728              siblingBB,
 729              nextSibling = child.next(false),
 730              prevSibling;
 731  
 732          // Insert or Append to last child.
 733  
 734          // Avoiding index, and using the current sibling
 735          // state (which should be accurate), means we don't have
 736          // to worry about decorator elements which may be added
 737          // to the _childContainer node.
 738  
 739          if (nextSibling && nextSibling.get(RENDERED)) {
 740  
 741              siblingBB = nextSibling.get(BOUNDING_BOX);
 742              siblingBB.insert(childBB, "before");
 743  
 744          } else {
 745  
 746              prevSibling = child.previous(false);
 747  
 748              if (prevSibling && prevSibling.get(RENDERED)) {
 749  
 750                  siblingBB = prevSibling.get(BOUNDING_BOX);
 751                  siblingBB.insert(childBB, "after");
 752  
 753              } else if (!parentNode.contains(childBB)) {
 754  
 755                  // Based on pull request from andreas-karlsson
 756                  // https://github.com/yui/yui3/pull/25#issuecomment-2103536
 757  
 758                  // Account for case where a child was rendered independently of the
 759                  // parent-child framework, to a node outside of the parentNode,
 760                  // and there are no siblings.
 761  
 762                  parentNode.appendChild(childBB);
 763              }
 764          }
 765  
 766      },
 767  
 768      /**
 769       * Updates the UI in response to a child being removed.
 770       *
 771       * @method _uiRemoveChild
 772       * @protected
 773       * @param child {Widget} The child Widget instance to render.
 774       */
 775      _uiRemoveChild: function (child) {
 776          child.get("boundingBox").remove();
 777      },
 778  
 779      _afterAddChild: function (event) {
 780          var child = event.child;
 781  
 782          if (child.get("parent") == this) {
 783              this._uiAddChild(child, this._childrenContainer);
 784          }
 785      },
 786  
 787      _afterRemoveChild: function (event) {
 788          var child = event.child;
 789  
 790          if (child._oldParent == this) {
 791              this._uiRemoveChild(child);
 792          }
 793      },
 794  
 795      /**
 796       * Sets up DOM and CustomEvent listeners for the parent widget.
 797       * <p>
 798       * This method in invoked after bindUI is invoked for the Widget class
 799       * using YUI's aop infrastructure.
 800       * </p>
 801       *
 802       * @method _bindUIParent
 803       * @protected
 804       */
 805      _bindUIParent: function () {
 806          this.after("addChild", this._afterAddChild);
 807          this.after("removeChild", this._afterRemoveChild);
 808      },
 809  
 810      /**
 811       * Renders all child Widgets for the parent.
 812       * <p>
 813       * This method in invoked after renderUI is invoked for the Widget class
 814       * using YUI's aop infrastructure.
 815       * </p>
 816       * @method _renderChildren
 817       * @protected
 818       */
 819      _renderChildren: function () {
 820  
 821          /**
 822           * <p>By default WidgetParent will render it's children to the parent's content box.</p>
 823           *
 824           * <p>If the children need to be rendered somewhere else, the _childrenContainer property
 825           * can be set to the Node which the children should be rendered to. This property should be
 826           * set before the _renderChildren method is invoked, ideally in your renderUI method,
 827           * as soon as you create the element to be rendered to.</p>
 828           *
 829           * @protected
 830           * @property _childrenContainer
 831           * @value The content box
 832           * @type Node
 833           */
 834          var renderTo = this._childrenContainer || this.get("contentBox");
 835  
 836          this._childrenContainer = renderTo;
 837  
 838          this.each(function (child) {
 839              child.render(renderTo);
 840          });
 841      },
 842  
 843      /**
 844       * Destroys all child Widgets for the parent.
 845       * <p>
 846       * This method is invoked before the destructor is invoked for the Widget
 847       * class using YUI's aop infrastructure.
 848       * </p>
 849       * @method _destroyChildren
 850       * @protected
 851       */
 852      _destroyChildren: function () {
 853  
 854          //  Detach the handler responsible for removing children in
 855          //  response to destroying them since:
 856          //  1)  It is unnecessary/inefficient at this point since we are doing
 857          //      a batch destroy of all children.
 858          //  2)  Removing each child will affect our ability to iterate the
 859          //      children since the size of _items will be changing as we
 860          //      iterate.
 861          this._hDestroyChild.detach();
 862  
 863          //  Need to clone the _items array since
 864          this.each(function (child) {
 865              child.destroy();
 866          });
 867      }
 868  
 869  };
 870  
 871  Y.augment(Parent, Y.ArrayList);
 872  
 873  Y.WidgetParent = Parent;
 874  
 875  
 876  }, '3.17.2', {"requires": ["arraylist", "base-build", "widget"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1