[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/externals/javelin/ext/view/ -> View.js (source)

   1  /**
   2   * A View is a composable wrapper on JX.$N, allowing abstraction of higher-order
   3   * views and a consistent pattern of parameterization. It is intended
   4   * to be used either directly or as a building block for a syntactic sugar layer
   5   * for concise expression of markup patterns.
   6   *
   7   * @provides javelin-view
   8   * @requires javelin-install
   9   *           javelin-util
  10   */
  11  JX.install('View', {
  12    construct : function(attrs, children) {
  13      this._attributes = JX.copy({}, this.getDefaultAttributeValues());
  14      JX.copy(this._attributes, attrs);
  15  
  16      this._rawChildren = {};
  17      this._childKeys = [];
  18  
  19      if (children) {
  20        this.addChildren(JX.$AX(children));
  21      }
  22  
  23      this.setName(this.__class__.__readable__);
  24    },
  25    events: [
  26      'change'
  27    ],
  28  
  29    properties: {
  30      'name': null
  31    },
  32  
  33    members : {
  34      _attributes : null,
  35      _rawChildren : null,
  36      _childKeys: null, // keys of rawChildren, kept ordered.
  37      _nextChildKey: 0, // next key to use for a new child
  38  
  39      /*
  40       * Don't override.
  41       * TODO: Strongly typed attribute access (getIntAttr, getStringAttr...)?
  42       */
  43      getAttr : function(attrName) {
  44        return this._attributes[attrName];
  45      },
  46  
  47      /*
  48       * Don't override.
  49       */
  50      multisetAttr : function(attrs) {
  51        JX.copy(this._attributes, attrs);
  52        this.invoke('change');
  53        return this;
  54      },
  55  
  56      /*
  57       * Don't override.
  58       */
  59      setAttr : function(attrName, value) {
  60        this._attributes[attrName] = value;
  61        this.invoke('change');
  62        return this;
  63      },
  64      /*
  65       * Child views can override to specify default values for attributes.
  66       */
  67      getDefaultAttributeValues : function() {
  68        return {};
  69      },
  70  
  71      /**
  72       * Don't override.
  73       */
  74      getAllAttributes: function() {
  75        return JX.copy({}, this._attributes);
  76      },
  77  
  78      /**
  79       * Get the children. Don't override.
  80       */
  81      getChildren : function() {
  82        var result = [];
  83        var should_repack = false;
  84  
  85        var ii;
  86        var key;
  87  
  88        for (ii = 0; ii < this._childKeys.length; ii++) {
  89          key = this._childKeys[ii];
  90          if (this._rawChildren[key] === undefined) {
  91            should_repack = true;
  92          } else {
  93            result.push(this._rawChildren[key]);
  94          }
  95        }
  96  
  97        if (should_repack) {
  98          var new_child_keys = [];
  99          for (ii = 0; ii < this._childKeys.length; ii++) {
 100            key = this._childKeys[ii];
 101            if (this._rawChildren[key] !== undefined) {
 102              new_child_keys.push(key);
 103            }
 104          }
 105  
 106          this._childKeys = new_child_keys;
 107        }
 108  
 109        return result;
 110      },
 111  
 112      /**
 113       * Add children to the view. Returns array of removal handles.
 114       * Don't override.
 115       */
 116      addChildren : function(children) {
 117        var result = [];
 118        for (var ii = 0; ii < children.length; ii++) {
 119          result.push(this._addChild(children[ii]));
 120        }
 121        this.invoke('change');
 122        return result;
 123      },
 124  
 125      /**
 126       * Add a single child view to the view.
 127       * Returns a removal handle, i.e. an object that has a method remove(),
 128       * that removes the added child from the view.
 129       *
 130       * Don't override.
 131       */
 132      addChild: function(child) {
 133        var result = this._addChild(child);
 134        this.invoke('change');
 135        return result;
 136      },
 137  
 138      _addChild: function(child) {
 139        var key = this._nextChildKey++;
 140        this._rawChildren[key] = child;
 141        this._childKeys.push(key);
 142  
 143        return {
 144          remove: JX.bind(this, this._removeChild, key)
 145        };
 146      },
 147  
 148      _removeChild: function(child_key) {
 149        delete this._rawChildren[child_key];
 150        this.invoke('change');
 151      },
 152  
 153      /**
 154       * Accept visitors. This allows adding new behaviors to Views without
 155       * having to change View classes themselves.
 156       *
 157       * This implements a post-order traversal over the tree of views. Children
 158       * are processed before parents, and for convenience the results of the
 159       * visitor on the children are passed to it when processing the parent.
 160       *
 161       * The visitor parameter is a callable which receives two parameters.
 162       * The first parameter is the view to visit. The second parameter is an
 163       * array of the results of visiting the view's children.
 164       *
 165       * Don't override.
 166       */
 167      accept: function(visitor) {
 168        var results = [];
 169        var children = this.getChildren();
 170        for(var ii = 0; ii < children.length; ii++) {
 171          var result;
 172          if (children[ii].accept) {
 173            result = children[ii].accept(visitor);
 174          } else {
 175            result = children[ii];
 176          }
 177          results.push(result);
 178        }
 179        return visitor(this, results);
 180      },
 181  
 182      /**
 183       * Given the already-rendered children, return the rendered result of
 184       * this view.
 185       * By default, just pass the children through.
 186       */
 187      render: function(rendered_children) {
 188        return rendered_children;
 189      }
 190    }
 191  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1