Source: core/View.js

// Generated by github.com/steida/coffee2closure 0.1.12
goog.provide('spark.core.View');
goog.require('spark.core.Object');
goog.require('spark.utils');
goog.require('goog.dom');
goog.require('goog.style');

/**
  Main View class of Spark Framework. It is basically a div element. But it's
  configurable to be any kind of element. It's event driven. This means you
  can attach and listen custom events with your data. It also supports native
  DOM events.

  @constructor
  @export
  @param   {Object=} options Class options.
  @param   {*=} data Class data
  @extends {spark.core.Object}
 */
spark.core.View = function(options, data) {
  var _ref;
  if (options == null) {
    options = {};
  }
  options.tagName || (options.tagName = options['tagName'] || 'div');
  options.width || (options.width = options['width'] || null);
  options.height || (options.height = options['height'] || null);
  options.domId || (options.domId = options['domId'] || null);
  options.template || (options.template = options['template'] || null);
  options.renderTo || (options.renderTo = options['renderTo'] || null);
  options.attributes || (options.attributes = options['attributes'] || {});
  options.events || (options.events = options['events'] || {});
  if (options.disabled == null) {
    options.disabled = (_ref = options['disabled']) != null ? _ref : false;
  }
  this.getCssClass(options);
  spark.core.View.superClass_.constructor.call(this, options, data);
  this.children = [];
  this.domEventListeners_ = [];
  this.createDomElement_();
  this.bindEvents_();
  if (options.disabled) {
    this.disable();
  }
  if (options.width) {
    this.setWidth(options.width);
  }
  if (options.height) {
    this.setHeight(options.height);
  }
  if (options.renderTo) {
    this.render(options.renderTo);
  }
}
goog.inherits(spark.core.View, spark.core.Object);

/**
  Creates the element with the configuration passed to constructor.

  @private
 */
spark.core.View.prototype.createDomElement_ = function() {
  var attributes, cssClass, domId, key, tagName, template, value, _ref, _results;
  _ref = this.getOptions(), tagName = _ref.tagName, domId = _ref.domId, cssClass = _ref.cssClass, template = _ref.template, attributes = _ref.attributes;
  this.element = document.createElement(tagName);
  this.setClass(cssClass);
  if (domId) {
    this.setDomId(domId);
  }
  if (template) {
    this.setTemplate(template);
  }
  _results = [];
  for (key in attributes) {
    value = attributes[key];
    _results.push(this.setAttribute(key, value));
  }
  return _results;
};

/**
  Sets DOM id.

  @export
  @param {!string} domId Id of the element.
 */
spark.core.View.prototype.setDomId = function(domId) {
  return this.getElement().id = domId;
};

/**
  Returns the DOM id if exists, otherwise it will return null.

  @export
  @return {string|null}
 */
spark.core.View.prototype.getDomId = function() {
  return this.getElement().id || null;
};

/**
  Sets the class name of element. This will override existing class names.
  Use `@addClass` if you want to add new class name to the element.

  @export
  @param {!string} cssClass Class name.
 */
spark.core.View.prototype.setClass = function(cssClass) {
  return this.getElement().className = cssClass;
};

/**
  Returns class name of the element.

  @export
  @return {string} Class name.
 */
spark.core.View.prototype.getClass = function() {
  return this.getElement().className;
};

/**
  Returns class list of the element.

  @export
  @return {Array} List of class names.
 */
spark.core.View.prototype.getClassList = function() {
  return this.getElement().classList;
};

/**
  Adds new class name to element.

  @export
  @param {!string} cssClass New class name for the element.
 */
spark.core.View.prototype.addClass = function(cssClass) {
  return this.getElement().classList.add(cssClass);
};

/**
  Remove a class name from the element.

  @export
  @param {!string} cssClass Name of the class which will be removed.
 */
spark.core.View.prototype.removeClass = function(cssClass) {
  return this.getElement().classList.remove(cssClass);
};

/**
  Returns true if element has that class name.

  @export
  @param {!string} cssClass Name of the class which will be tested.
  @return {boolean} Whether element has a class name or not.
 */
spark.core.View.prototype.hasClass = function(cssClass) {
  return this.getElement().classList.contains(cssClass);
};

/**
  Returns the DOM element.

  @export
  @return {Element} DOM element of this view.
 */
spark.core.View.prototype.getElement = function() {
  return this.element;
};

/**
  Returns the child views.

  @export
  @return {Array<spark.core.View>} DOM element of this view.
 */
spark.core.View.prototype.getChildren = function() {
  return this.children;
};

/**
  Basic templating support for Spark Framework. Currently templates can include
  variable tags like in Mustache templates. This can be changed in the future
  versions of the framework.

  Variable tags should start with `{{` and end with `}}`. That's borrowed from
  Mustache. Tags are not whitespace sensitive, so `{{name}}` and `{{ name }}`
  is the same.

  Template should also be a function. Just make sure that function returns a
  string which will be the template. `setTemplate` will call the template
  function by passing the data of this View. So you can use class data in your
  template function. This will allow framework to easily integrate other
  template engines.

  Spark Framework will use Closure Templates as it's default template engine.
  This is because to maintain the compiled code size advantage. I am also
  considering to support Mustache and Handlebar templates in Spark.

  @export
  @param {(string|Function)=} template HTML string of the element or function
  which will return the html string. Function will be called with class data.
  FIXME: Fix annotation for template variable, it should be `{string|Function}`
 */
spark.core.View.prototype.setTemplate = function(template) {
  if (spark.validation.isFunction(template)) {
    template = template.call(this, this.getData());
  }
  return this.getElement().innerHTML = spark.utils.parseTemplate(template, this.getData());
};

/**
  Appends view into document's body.

  @export
 */
spark.core.View.prototype.appendToDocumentBody = function() {
  document.body.appendChild(this.getElement());
  return this.emit('ViewHasParent');
};

/**
  Removes element from DOM if it is in DOM.

  @export
  @return {boolean} Whether element removed from document or not.
 */
spark.core.View.prototype.removeFromDocument = function() {
  var element, parent;
  element = this.getElement();
  parent = element.parentNode;
  if (!parent) {
    return false;
  }
  parent.removeChild(element);
  return true;
};

/**
  Appends a new view into this view's element as a child.

  @export
  @param {!spark.core.View} view A spark.View instance to append.
 */
spark.core.View.prototype.appendView = function(view) {
  var error;
  if (!(view instanceof spark.core.View)) {
    error = 'View should be an instance of spark.core.View';
  } else if (this.children.indexOf(view) > -1) {
    error = 'This view already appended to target view.';
  }
  if (error) {
    throw new Error(error);
  }
  this.children.push(view);
  this.getElement().appendChild(view.getElement());
  return view.emit('ViewHasParent');
};

/**
  Native setAttribute wrapper.

  @export
  @param {!string} name  Atrribute name.
  @param {!string} value Attribute value.
 */
spark.core.View.prototype.setAttribute = function(name, value) {
  return this.getElement().setAttribute(name, value);
};

/**
  Native getAttribute wrapper.

  @export
  @param {!string} name  Atrribute name.
 */
spark.core.View.prototype.getAttribute = function(name) {
  return this.getElement().getAttribute(name);
};

/**
  Native removeAttribute wrapper.

  @export
  @param {!string} name  Atrribute name.
 */
spark.core.View.prototype.removeAttribute = function(name) {
  return this.getElement().removeAttribute(name);
};

/**
  Disable view.

  @export
 */
spark.core.View.prototype.disable = function() {
  var disabled;
  disabled = 'disabled';
  this.addClass(disabled);
  this.setAttribute(disabled, disabled);
  return this.disabled = true;
};

/**
  Enable view.

  @export
 */
spark.core.View.prototype.enable = function() {
  var disabled;
  disabled = 'disabled';
  this.removeClass(disabled);
  this.removeAttribute(disabled);
  return this.disabled = false;
};

/**
  Toggle view state. Disable if enabled, enable if disabled.

  @export
 */
spark.core.View.prototype.toggle = function() {
  if (this.isDisabled()) {
    return this.enable();
  } else {
    return this.disable();
  }
};

/**
  Returns the current disabled state of the button.

  @export
 */
spark.core.View.prototype.isDisabled = function() {
  return this.disabled || false;
};

/**
  Sets width of this view's DOM element.

  @export
  @param {string|number} width Width of the element. It can be string with
  'px' value or just number.
 */
spark.core.View.prototype.setWidth = function(width) {
  return goog.style.setWidth(this.getElement(), width);
};

/**
  Sets height of this view's DOM element.

  @export
  @param {string|number} height Height of the element. It can be string with
  'px' value or just number.
 */
spark.core.View.prototype.setHeight = function(height) {
  return goog.style.setHeight(this.getElement(), height);
};

/**
  Returns the width of the element.

  @export
  @return {number} View element width.
 */
spark.core.View.prototype.getWidth = function() {
  var size;
  size = goog.style.getSize(this.getElement());
  return size.width;
};

/**
  Returns the height of the element.

  @export
  @return {number} View element height.
 */
spark.core.View.prototype.getHeight = function() {
  var size;
  size = goog.style.getSize(this.getElement());
  return size.height;
};

/**
  Renders element into another View instance or a DOM element. Be aware that
  this method only appends the element of this class into another element.
  If the parent element is not in DOM, this method will not append the parent
  into DOM. Also you can use this method with `renderTo` option. If you pass
  `renderTo` as a View instance or DOM element, View will call render method
  by default.

  @export
  @param {spark.core.View|Element} target Target view or element to be rendered.
 */
spark.core.View.prototype.render = function(target) {
  if (target instanceof spark.core.View) {
    return target.appendView(this);
  } else if (goog.dom.isElement(target)) {
    if (target === document.body) {
      return this.appendToDocumentBody();
    } else {
      target.appendChild(this.getElement());
      return this.emit('ViewHasParent');
    }
  } else {
    throw new Error('Render target should be View instance or a DOM element.');
  }
};

/**
  Override Object::on to support two way binding for DOM events.

  @export
  @override
 */
spark.core.View.prototype.on = function(eventName, callback) {
  var listener;
  if (spark.core.View.EventTypes[eventName]) {
    listener = goog.events.listen(this.getElement(), eventName, callback);
    this.domEventListeners_.push(listener);
  }
  return goog.events.listen(this, eventName, callback);
};

/**
  Override Object::once to support two way binding for DOM events.

  @export
  @override
 */
spark.core.View.prototype.once = function(eventName, callback) {
  if (spark.core.View.EventTypes[eventName]) {
    goog.events.listenOnce(this.getElement(), eventName, callback);
  }
  return goog.events.listenOnce(this, eventName, callback);
};

/**
  Override Object::off to remove events binded to DOM element.

  @export
  @override
 */
spark.core.View.prototype.off = function(eventName, callback) {
  goog.events.unlisten(this.getElement(), eventName, callback);
  return this.unlisten(eventName, callback);
};

/**
  This method is responsible from binding DOM events to the element of this
  view. It uses native DOM event names which is all lowercase. If your options
  has an event name and a callback function in events object View will bind
  and listen those events automatically.

  @private
 */
spark.core.View.prototype.bindEvents_ = function() {
  var element, eventTypes;
  eventTypes = spark.core.View.EventTypes;
  element = this.getElement();
  return goog.object.forEach(this.getOptions().events, (function(_this) {
    return function(callback, key) {
      if (eventTypes[key] && typeof callback === 'function') {
        return _this.on(goog.events.EventType[eventTypes[key]], callback);
      }
    };
  })(this));
};

/**
  Helper method to set css class to options set.

  @param {Object}  options  Class options.
  @param {string=} optionalClass Optinal CSS class which will added to default.
 */
spark.core.View.prototype.getCssClass = function(options, optionalClass) {
  var classFromOptions, fullClassName;
  classFromOptions = options.cssClass || options['cssClass'];
  fullClassName = spark.utils.concatString('view', classFromOptions, optionalClass);
  return options.cssClass = options['cssClass'] = fullClassName;
};

/**
  A transposed map of goog.events.EventType
 */
spark.core.View.EventTypes = goog.object.transpose(goog.events.EventType);

/**
  Destroys the view. It will unlisten all binded events including the DOM
  events and destroy all child views finally remove the element from document.

  @override
  @export
 */
spark.core.View.prototype.destroy = function() {
  var domElement;
  domElement = this.getElement();
  this.domEventListeners_.forEach((function(_this) {
    return function(listener) {
      if (listener != null ? listener.listener : void 0) {
        return goog.events.unlisten(domElement, listener.type, listener.listener);
      }
    };
  })(this));
  this.children.forEach((function(_this) {
    return function(child) {
      child.destroy();
      return child = null;
    };
  })(this));
  this.children = [];
  this.removeFromDocument();
  return spark.core.View.superClass_.destroy.apply(this, arguments);
};
Spark Framework by Fatih Acet
Copyright © 2014 - Fatih Acet
Documentation generated by JSDoc 3.2.2 on 2015-07-19T22:09:29+00:00 using the DocStrap template.