<commit_before>/**
 * @module Lyria
 */
define('lyria/scene', ['jquery', 'mixer', 'nexttick', 'eventmap', 'lyria/gameobject', 'lyria/language', 'lyria/template/string', 'lyria/log', 'lyria/mixin/language'], function($, mixer, nextTick, EventMap, GameObject, Language, templateString, Log, langMixin) {'use strict';

  var createNamespace = function(obj, chain, value) {
    var chainArr = chain.split('.');

    for (var i = 0, j = chainArr.length; i < j; i++) {
      (function(item, lastElem) {
        if (lastElem) {
          obj = value;
        } else {
          obj = (obj[item] = obj[item] || {});
        }
      })(chainArr[i], i === j - 1);
    }
  };

  var Scene = (function() {

    /**
     * Scene constructor
     *
     * @class Scene
     * @constructor
     */
    var Scene = function(sceneName, sceneDeps, sceneFunction, options) {
      if (!sceneName) {
        return;
      }

      if ( typeof sceneDeps === 'function') {
        options = sceneFunction;
        sceneFunction = sceneDeps;
        sceneDeps = [];
      }

      // Mixin event map into Scene
      mixer(Scene.prototype, new EventMap('scene:' + sceneName));

      // We need a reference to the scene not being this
      var self = this;

      // Set name
      this.name = sceneName;

      this.async = false;

      // Default values
      this.localization = {};

      var langValue = Language.language;

      langMixin(self, langValue, self);

      this.template = {};
      this.template.source = '';
      this.template.helpers = {};
      this.template.partials = {};
      // Collect all template values
      this.template.data = {};

      // Add default helpers
      this.template.helpers['translate'] = this.t;

      this.children = this.children || {};
      this.children.gameObjects = {};
      this.children.prefabs = {};

      // Expose function for template values
      this.expose = function(obj) {
        if (!obj || $.isEmptyObject(obj)) {
          return;
        }

        self.template.data = $.extend(true, self.template.data, obj);
      };

      Object.defineProperty(self, '$element', {
        get: function() {
          return $('#' + self.name);
        }
      });

      self.on('added', function() {
        self.refresh();

        if (self.events) {
          if (options && options.isPrefab) {
            self.events.delegate = (options.target) ? options.target : 'body';
          } else {
            self.events.delegate = '#' + sceneName;
          }
        }

        self.on('update', function(dt) {
          $.each(self.children, function(childKey, childValue) {
            if (!$.isEmptyObject(childValue)) {
              $.each(childValue, function(key, value) {
                value.trigger('update', dt);
              });
            }
          });
        });

        // Bind events
        if (self.events && !$.isEmptyObject(self.events)) {
          $.each(self.events, function(key, value) {
            if (( typeof value === 'object') && (key !== 'delegate')) {
              $(self.events.delegate).on(value, key, {
                scene: self
              });
            }
          });
        }

        // Data binding
        if (self.template.data && !$.isEmptyObject(self.template.data)) {
          $('#' + self.name + ' [data-bind]').each(function() {
            var $dataElem = $(this);

            var prop = $dataElem.data('bind');

            self.template.data.watch(prop, function(id, oldval, newval) {
              if (oldval !== newval) {
                $dataElem.html(newval);
              }

              return newval;
            });
          });
        }
      });

      var createScene = function(LyriaObject, deps) {
        if (deps == null) {
          deps = [];
        }

        var sceneDone = function(err, success) {
          if (err) {
            return console.error('Error while executing scene ' + self.name + ': ' + err);
          }

          if (self.isAsync) {
            self.trigger('added');
          }
        };

        var async = false;

        var context = self;
        context.async = function() {
          async = true;

          return function() {
            nextTick(function() {
              sceneDone();
            });
          };
        };

        Object.defineProperty(self, 'isAsync', {
          get: function() {
            return async;
          }
        });

        // TODO: Evaluate how to show dependencies (concat into array, array with
        // objects of name and value)
        try {
          var success = sceneFunction.apply(context, [context, LyriaObject].concat(deps));

          if (!async) {
            sceneDone(null, success);
          }
        } catch (e) {
          sceneDone(e);
        }
      };

      // Call scene
      var reqModules = Object.keys(Scene.requireAlways) || [];

      require(reqModules, function() {
        var importedModules = {};

        for (var i = 0, j = arguments.length; i < j; i++) {
          (function(dep) {
            createNamespace(importedModules, reqModules[i], dep);
          })(arguments[i]);
        }

        if (sceneDeps.length > 0) {
          require(sceneDeps, function() {
            createScene(importedModules, [].slice.call(arguments, 0));
          });
        } else {
          createScene(importedModules);
        }
      });
    };

    /**
     * Adds a gameobject to the scene
     *
     * @method add
     * @param {Object} child
     */
    Scene.prototype.add = function(child) {
      var self = this;

      if ( child instanceof GameObject) {
        this.children.gameObjects[child.name] = child;

        this.template.data.gameobject = (function() {
          var array = [];

          $.each(self.children.gameObjects, function(key, value) {
            array.push(value);
          });

          return array;
        })();

        this.trigger('add');

        return true;
      }

      if ( child instanceof GameObject) {
        this.children.prefabs[child.name] = child;

        this.template.data.gameobject = (function() {
          var array = [];

          $.each(self.children.gameObjects, function(key, value) {
            array.push(value);
          });

          return array;
        })();

        this.trigger('add');

        return true;
      }

      return false;
    };

    /**
     * Refreshes the scene (Re-renders the template)
     *
     * @method refresh
     * @param {Object} val
     */
    Scene.prototype.refresh = function(val) {
      if (val == null && this.template) {
        val = this.template.data;
      }

      if (this.template && this.template.source) {
        this.content = this.template.source(val, {partials: this.template.partials, helpers: {}});
      }

      if (this.$element.length > 0) {
        this.$element.html(this.content);
      }

      this.trigger('refresh');
    };

    /**
     *  Sets an event to the event object or returns a specified event
     *
     * @method event
     * @param {String} selector
     * @param {String} eventName
     * @param {Function} eventFunction
     */
    Scene.prototype.event = function(selector, eventName, eventFunction) {
      if (selector == null) {
        return;
      }

      if (eventName == null) {
        return this.events[selector];
      } else {
        if ( typeof eventFunction === 'function') {
          this.events[selector] = {};
          this.events[selector][eventName] = eventFunction;
        } else {
          return this.events[selector][eventName];
        }
      }
    };

    /**
     * Gets localized value
     *
     * @param {Object} lang
     */
    Scene.prototype.t = function(name, parameter) {
      var self = this;

      if (this.localization && this.localization[this.language]) {
        if (this.localization[this.language][name] == null) {
          return '[[Missing localization for ' + name + ']]';
        }

        if ( typeof this.localization[this.language][name] === 'string') {
          return templateString.process(this.localization[this.language][name], parameter);
        } else {
          return {
            plural: function(n) {
              if (self.localization[this.language][name][n]) {
                return templateString.process(self.localization[self.language][name][n], parameter);
              } else {
                return templateString.process(self.localization[self.language][name]['n'], parameter);
              }
            }
          };
        }
      }
    };

    /**
     * Logging directly from the scene
     *
     * @param {Object} text
     */
    Scene.prototype.log = function(text) {
      Log.i('Scene ' + this.name + ': ' + text);
    };

    Scene.requireAlways = {
      'lyria/achievements': 'Lyria.Achievements',
      'lyria/log': 'Lyria.Log',
      'lyria/component': 'Lyria.Component',
      'lyria/gameobject': 'Lyria.GameObject',
      'lyria/events': 'Lyria.Events',
      'lyria/resource': 'Lyria.Resource',
      'lyria/loop': 'Lyria.Loop',
      'lyria/tween': 'Lyria.Tween',
      'lyria/animation': 'Lyria.Animation'
    };

    return Scene;

  })();

  return Scene;

});
<commit_msg>modules are now available in a scene<commit_after>/**
 * @module Lyria
 */
define('lyria/scene', ['jquery', 'mixer', 'nexttick', 'eventmap', 'lyria/gameobject', 'lyria/language', 'lyria/template/string', 'lyria/log', 'lyria/mixin/language'], function($, mixer, nextTick, EventMap, GameObject, Language, templateString, Log, langMixin) {'use strict';

  var createNamespace = function(obj, chain, value) {
    var chainArr = chain.split('.');

    for (var i = 0, j = chainArr.length; i < j; i++) {
      (function(item, lastElem) {
        if (lastElem) {
          obj = value;
        } else {
          obj = (obj[item] = obj[item] || {});
        }
      })(chainArr[i], i === j - 1);
    }
  };

  var Scene = (function() {

    /**
     * Scene constructor
     *
     * @class Scene
     * @constructor
     */
    var Scene = function(sceneName, sceneDeps, sceneFunction, options) {
      if (!sceneName) {
        return;
      }

      if ( typeof sceneDeps === 'function') {
        options = sceneFunction;
        sceneFunction = sceneDeps;
        sceneDeps = [];
      }

      // Mixin event map into Scene
      mixer(Scene.prototype, new EventMap('scene:' + sceneName));

      // We need a reference to the scene not being this
      var self = this;

      // Set name
      this.name = sceneName;

      this.async = false;

      // Default values
      this.localization = {};

      var langValue = Language.language;

      langMixin(self, langValue, self);

      this.template = {};
      this.template.source = '';
      this.template.helpers = {};
      this.template.partials = {};
      // Collect all template values
      this.template.data = {};

      // Add default helpers
      this.template.helpers['translate'] = this.t;

      this.children = this.children || {};
      this.children.gameObjects = {};
      this.children.prefabs = {};

      // Expose function for template values
      this.expose = function(obj) {
        if (!obj || $.isEmptyObject(obj)) {
          return;
        }

        self.template.data = $.extend(true, self.template.data, obj);
      };

      Object.defineProperty(self, '$element', {
        get: function() {
          return $('#' + self.name);
        }
      });

      self.on('added', function() {
        self.refresh();

        if (self.events) {
          if (options && options.isPrefab) {
            self.events.delegate = (options.target) ? options.target : 'body';
          } else {
            self.events.delegate = '#' + sceneName;
          }
        }

        self.on('update', function(dt) {
          $.each(self.children, function(childKey, childValue) {
            if (!$.isEmptyObject(childValue)) {
              $.each(childValue, function(key, value) {
                value.trigger('update', dt);
              });
            }
          });
        });

        // Bind events
        if (self.events && !$.isEmptyObject(self.events)) {
          $.each(self.events, function(key, value) {
            if (( typeof value === 'object') && (key !== 'delegate')) {
              $(self.events.delegate).on(value, key, {
                scene: self
              });
            }
          });
        }

        // Data binding
        if (self.template.data && !$.isEmptyObject(self.template.data)) {
          $('#' + self.name + ' [data-bind]').each(function() {
            var $dataElem = $(this);

            var prop = $dataElem.data('bind');

            self.template.data.watch(prop, function(id, oldval, newval) {
              if (oldval !== newval) {
                $dataElem.html(newval);
              }

              return newval;
            });
          });
        }
      });

      var createScene = function(LyriaObject, deps) {
        if (deps == null) {
          deps = [];
        }

        var sceneDone = function(err, success) {
          if (err) {
            return console.error('Error while executing scene ' + self.name + ': ' + err);
          }

          if (self.isAsync) {
            self.trigger('added');
          }

        };

        var async = false;

        var context = self;
        context.async = function() {
          async = true;

          return function() {
            nextTick(function() {
              sceneDone();
            });
          };
        };

        Object.defineProperty(self, 'isAsync', {
          get: function() {
            return async;
          }
        });

        context.modules = LyriaObject;

        // TODO: Evaluate how to show dependencies (concat into array, array with
        // objects of name and value)
        try {
          var success = sceneFunction.apply(context, [context, LyriaObject].concat(deps));

          if (!async) {
            sceneDone(null, success);
          }
        } catch (e) {
          sceneDone(e);
        }
      };

      // Call scene
      var reqModules = Object.keys(Scene.requireAlways) || [];

      require(reqModules, function() {
        var importedModules = {};

        for (var i = 0, j = arguments.length; i < j; i++) {
          (function(dep) {
            createNamespace(importedModules, reqModules[i], dep);
          })(arguments[i]);
        }

        if (sceneDeps.length > 0) {
          require(sceneDeps, function() {
            createScene(importedModules, [].slice.call(arguments, 0));
          });
        } else {
          createScene(importedModules);
        }
      });
    };

    /**
     * Adds a gameobject to the scene
     *
     * @method add
     * @param {Object} child
     */
    Scene.prototype.add = function(child) {
      var self = this;

      if ( child instanceof GameObject) {
        this.children.gameObjects[child.name] = child;

        this.template.data.gameobject = (function() {
          var array = [];

          $.each(self.children.gameObjects, function(key, value) {
            array.push(value);
          });

          return array;
        })();

        this.trigger('add');

        return true;
      }

      if ( child instanceof GameObject) {
        this.children.prefabs[child.name] = child;

        this.template.data.gameobject = (function() {
          var array = [];

          $.each(self.children.gameObjects, function(key, value) {
            array.push(value);
          });

          return array;
        })();

        this.trigger('add');

        return true;
      }

      return false;
    };

    /**
     * Refreshes the scene (Re-renders the template)
     *
     * @method refresh
     * @param {Object} val
     */
    Scene.prototype.refresh = function(val) {
      if (val == null && this.template) {
        val = this.template.data;
      }

      if (this.template && this.template.source) {
        this.content = this.template.source(val, {partials: this.template.partials, helpers: {}});
      }

      if (this.$element.length > 0) {
        this.$element.html(this.content);
      }

      this.trigger('refresh');
    };

    /**
     *  Sets an event to the event object or returns a specified event
     *
     * @method event
     * @param {String} selector
     * @param {String} eventName
     * @param {Function} eventFunction
     */
    Scene.prototype.event = function(selector, eventName, eventFunction) {
      if (selector == null) {
        return;
      }

      if (eventName == null) {
        return this.events[selector];
      } else {
        if ( typeof eventFunction === 'function') {
          this.events[selector] = {};
          this.events[selector][eventName] = eventFunction;
        } else {
          return this.events[selector][eventName];
        }
      }
    };

    /**
     * Gets localized value
     *
     * @param {Object} lang
     */
    Scene.prototype.t = function(name, parameter) {
      var self = this;

      if (this.localization && this.localization[this.language]) {
        if (this.localization[this.language][name] == null) {
          return '[[Missing localization for ' + name + ']]';
        }

        if ( typeof this.localization[this.language][name] === 'string') {
          return templateString.process(this.localization[this.language][name], parameter);
        } else {
          return {
            plural: function(n) {
              if (self.localization[this.language][name][n]) {
                return templateString.process(self.localization[self.language][name][n], parameter);
              } else {
                return templateString.process(self.localization[self.language][name]['n'], parameter);
              }
            }
          };
        }
      }
    };

    /**
     * Logging directly from the scene
     *
     * @param {Object} text
     */
    Scene.prototype.log = function(text) {
      Log.i('Scene ' + this.name + ': ' + text);
    };

    Scene.requireAlways = {
      'lyria/achievements': 'Lyria.Achievements',
      'lyria/log': 'Lyria.Log',
      'lyria/component': 'Lyria.Component',
      'lyria/gameobject': 'Lyria.GameObject',
      'lyria/events': 'Lyria.Events',
      'lyria/resource': 'Lyria.Resource',
      'lyria/loop': 'Lyria.Loop',
      'lyria/tween': 'Lyria.Tween',
      'lyria/animation': 'Lyria.Animation'
    };

    return Scene;

  })();

  return Scene;

});
<|endoftext|>


<commit_before>module.exports = {
  "parse": "sugarss",
  "plugins": {
    "postcss-import": {}
  }
}<commit_msg>Removed sugarss reference<commit_after>module.exports = {
  "plugins": {
    "postcss-import": {}
  }
}<|endoftext|>


<commit_before>/* eslint-disable no-underscore-dangle */
import 'regenerator-runtime/runtime';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { AsyncComponentProvider } from 'react-async-component';
import asyncBootstrapper from 'react-async-bootstrapper';
import configureStore from './store/configureStore';
import AppContainer from './containers/AppContainer';
import RootApp from './components/App';
import './critical.scss';
import './style.scss';

const rehydrateState = window.__ASYNC_COMPONENTS_STATE__;
const store = configureStore(window.__INITIAL_STATE__);
store.runSaga();
delete window.__ASYNC_COMPONENTS_STATE__;
delete window.__INITIAL_STATE__;

const App = Root => (
  <AsyncComponentProvider rehydrateState={rehydrateState}>
    <AppContainer>
      <Provider store={store}>
        <BrowserRouter>
          <Root />
        </BrowserRouter>
      </Provider>
    </AppContainer>
  </AsyncComponentProvider>
);

const render = () => {
  import(
    /* webpackMode: "eager" */
    './components/App'
  ).then((module) => {
    ReactDOM.render(
      App(module.default),
      document.getElementById('root')
    );
  });
};

asyncBootstrapper(App(RootApp)).then(render);

if (module.hot) {
  module.hot.accept('./components/App', render);
}
<commit_msg>Update index.js using async fn<commit_after>/* eslint-disable no-underscore-dangle */
import 'regenerator-runtime/runtime';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { AsyncComponentProvider } from 'react-async-component';
import asyncBootstrapper from 'react-async-bootstrapper';
import configureStore from './store/configureStore';
import AppContainer from './containers/AppContainer';
import RootApp from './components/App';
import './critical.scss';
import './style.scss';

const rehydrateState = window.__ASYNC_COMPONENTS_STATE__;
const store = configureStore(window.__INITIAL_STATE__);
store.runSaga();
delete window.__ASYNC_COMPONENTS_STATE__;
delete window.__INITIAL_STATE__;

const App = Root => (
  <AsyncComponentProvider rehydrateState={rehydrateState}>
    <AppContainer>
      <Provider store={store}>
        <BrowserRouter>
          <Root />
        </BrowserRouter>
      </Provider>
    </AppContainer>
  </AsyncComponentProvider>
);

async function render() {
  const module = await import(
    /* webpackMode: "eager" */
    './components/App'
  );

  ReactDOM.render(
    App(module.default),
    document.getElementById('root')
  );
}

asyncBootstrapper(App(RootApp)).then(render);

if (module.hot) {
  module.hot.accept('./components/App', render);
}
<|endoftext|>


<commit_before>pc.extend(pc, function () {

    /**
     * @private
     * @name pc.Light
     * @class A light.
     */
    var Light = function Light() {
        // Light properties (defaults)
        this._type = pc.LIGHTTYPE_DIRECTIONAL;
        this._color = new pc.Color(0.8, 0.8, 0.8);
        this._intensity = 1;
        this._castShadows = false;
        this._enabled = false;

        // Point and spot properties
        this._attenuationStart = 10;
        this._attenuationEnd = 10;
        this._falloffMode = 0;
        this._shadowType = pc.SHADOW_DEPTH;
        this.mask = 1;

        // Spot properties
        this._innerConeAngle = 40;
        this._outerConeAngle = 45;

        // Cache of light property data in a format more friendly for shader uniforms
        this._finalColor = new pc.Vec3(0.8, 0.8, 0.8);
        this._linearFinalColor = new pc.Vec3();
        this._position = new pc.Vec3(0, 0, 0);
        this._direction = new pc.Vec3(0, 0, 0);
        this._innerConeAngleCos = Math.cos(this._innerConeAngle * Math.PI / 180);
        this._outerConeAngleCos = Math.cos(this._outerConeAngle * Math.PI / 180);

        // Shadow mapping resources
        this._shadowCamera = null;
        this._shadowMatrix = new pc.Mat4();
        this._shadowDistance = 40;
        this._shadowResolution = 1024;
        this._shadowBias = -0.0005;
        this._normalOffsetBias = 0.0;
        this.shadowUpdateMode = pc.SHADOWUPDATE_REALTIME;

        this._scene = null;
        this._node = null;
    };

    Light.prototype = {
        /**
         * @private
         * @function
         * @name pc.Light#clone
         * @description Duplicates a light node but does not 'deep copy' the hierarchy.
         * @returns {pc.Light} A cloned Light.
         */
        clone: function () {
            var clone = new pc.Light();

            // Clone Light properties
            clone.setType(this.getType());
            clone.setColor(this.getColor());
            clone.setIntensity(this.getIntensity());
            clone.setCastShadows(this.getCastShadows());
            clone.setEnabled(this.getEnabled());

            // Point and spot properties
            clone.setAttenuationStart(this.getAttenuationStart());
            clone.setAttenuationEnd(this.getAttenuationEnd());
            clone.setFalloffMode(this.getFalloffMode());
            clone.setShadowType(this.getShadowType());
            clone.shadowUpdateMode = this.shadowUpdateMode;
            clone.mask = this.mask;

            // Spot properties
            clone.setInnerConeAngle(this.getInnerConeAngle());
            clone.setOuterConeAngle(this.getOuterConeAngle());

            // Shadow properties
            clone.setShadowBias(this.getShadowBias());
            clone.setNormalOffsetBias(this.getNormalOffsetBias());
            clone.setShadowResolution(this.getShadowResolution());
            clone.setShadowDistance(this.getShadowDistance());

            return clone;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getAttenuationEnd
         * @description Queries the radius of the point or spot light. In other words, this is
         * the distance at which the light's contribution falls to zero.
         * @returns {Number} The radius of the point or spot light.
         */
        getAttenuationEnd: function () {
            return this._attenuationEnd;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getAttenuationStart
         * @description Queries the distance from the point or spot light that attenuation begins.
         * @returns {Number} The radius from the light position where attenuation starts.
         */
        getAttenuationStart: function () {
            return this._attenuationStart;
        },

        getFalloffMode: function () {
            return this._falloffMode;
        },

        getShadowType: function () {
            return this._shadowType;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getCastShadows
         * @description Queries whether the light casts shadows. Dynamic lights do not
         * cast shadows by default.
         * @returns {Boolean} true if the specified light casts shadows and false otherwise.
         */
        getCastShadows: function () {
            return this._castShadows && this.mask!==pc.MASK_LIGHTMAP && this.mask!==0;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getColor
         * @description Queries the diffuse color of the light. The PlayCanvas 'phong' shader uses this
         * value by multiplying it by the diffuse color of a mesh's material and adding it to
         * the total light contribution.
         * @returns {pc.Color} The diffuse color of the light (RGB components ranging 0..1).
         */
        getColor: function () {
            return this._color;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getEnabled
         * @description Queries whether the specified light is currently enabled.
         * @returns {Boolean} true if the light is enabled and false otherwise.
         */
        getEnabled: function () {
            return this._enabled;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getInnerConeAngle
         * @description Queries the inner cone angle of the specified spot light. Note
         * that this function is only valid for spotlights.
         * @returns {Number} The inner cone angle of the specified light in degrees.
         */
        getInnerConeAngle: function () {
            return this._innerConeAngle;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getIntensity
         * @description Queries the intensity of the specified light.
         * @returns {Number} The intensity of the specified light.
         */
        getIntensity: function () {
            return this._intensity;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getOuterConeAngle
         * @description Queries the outer cone angle of the specified spot light. Note
         * that this function is only valid for spotlights.
         * @returns {Number} The outer cone angle of the specified light in degrees.
         */
        getOuterConeAngle: function () {
            return this._outerConeAngle;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getShadowBias
         * @description Queries the shadow mapping depth bias for this light. Note
         * that this function is only valid for directional lights and spotlights.
         * @returns {Number} The shadow mapping depth bias.
         */
        getShadowBias: function () {
            return this._shadowBias;
        },

        getNormalOffsetBias: function () {
            return this._normalOffsetBias;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getShadowDistance
         * @description Queries the distance in camera Z at which shadows will no
         * longer be rendered. Note that this function is only valid for directional
         * lights.
         * @returns {Number} The shadow distance in world units.
         */
        getShadowDistance: function () {
            return this._shadowDistance;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getShadowResolution
         * @description Queries the shadow map pixel resolution for this light.
         * @returns {Number} The shadow map resolution.
         */
        getShadowResolution: function () {
            return this._shadowResolution;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getType
         * @description Queries the type of the light. The light can be a directional light,
         * a point light or a spotlight.
         * @returns {pc.LightType} The type of the specified light.
         */
        getType: function () {
            return this._type;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setAttenuationEnd
         * @description Specifies the radius from the light position where the light's
         * contribution falls to zero.
         * @param {Number} radius The radius of influence of the light.
         */
        setAttenuationEnd: function (radius) {
            this._attenuationEnd = radius;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setAttenuationStart
         * @description Specifies the radius from the light position where the light
         * contribution begins to attenuate.
         * @param {Number} radius The radius at which the light begins to attenuate.
         */
        setAttenuationStart: function (radius) {
            this._attenuationStart = radius;
        },

        setFalloffMode: function (mode) {
            this._falloffMode = mode;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        setShadowType: function (mode) {
            this._shadowType = mode;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        setMask: function (_mask) {
            this.mask = _mask;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setCastShadows
         * @description Toggles the casting of shadows from this light.
         * @param {Boolean} castShadows True to enabled shadow casting, false otherwise.
         */
        setCastShadows: function (castShadows) {
            this._castShadows = castShadows;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setColor
         * @description Sets the RGB color of the light. RGB components should be
         * specified in the range 0 to 1.
         * @param {pc.Color} color The RGB color of the light.
         */
        /**
         * @private
         * @function
         * @name pc.Light#setColor^2
         * @description Sets the RGB color of the light. RGB components should be
         * specified in the range 0 to 1.
         * @param {Number} red The red component of the light color.
         * @param {Number} green The green component of the light color.
         * @param {Number} blue The blue component of the light color.
         */
        setColor: function () {
            var r, g, b;
            if (arguments.length === 1) {
                r = arguments[0].r;
                g = arguments[0].g;
                b = arguments[0].b;
            } else if (arguments.length === 3) {
                r = arguments[0];
                g = arguments[1];
                b = arguments[2];
            }

            this._color.set(r, g, b);

            // Update final color
            var i = this._intensity;
            this._finalColor.set(r * i, g * i, b * i);
            for(var c=0; c<3; c++) {
                if (i >= 1) {
                    this._linearFinalColor.data[c] = Math.pow(this._finalColor.data[c] / i, 2.2) * i;
                } else {
                    this._linearFinalColor.data[c] = Math.pow(this._finalColor.data[c], 2.2);
                }
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setEnabled
         * @description Marks the specified light as enabled or disabled.
         * @param {boolean} enable true to enable the light and false to disable it.
         */
        setEnabled: function (enable) {
            if (this._enabled !== enable) {
                this._enabled = enable;
                if (this._scene !== null) {
                    this._scene.updateShaders = true;
                }
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setInnerConeAngle
         * @description Sets the inner cone angle of the light. Note that this
         * function only affects spotlights. The contribution of the spotlight is
         * zero outside the cone defined by this angle.
         * @param {Number} angle The inner cone angle of the spotlight in degrees.
         */
        setInnerConeAngle: function (angle) {
            this._innerConeAngle = angle;
            this._innerConeAngleCos = Math.cos(angle * Math.PI / 180);
        },

        /**
         * @private
         * @function
         * @name pc.Light#setIntensity
         * @description Sets the intensity of the light. The intensity is used to
         * scale the color of the light. Note that this makes it possible to take
         * the light color's RGB components outside the range 0 to 1.
         * @param {Number} intensity The intensity of the light.
         */
        setIntensity: function (intensity) {
            this._intensity = intensity;

            // Update final color
            var c = this._color;
            var r = c.r;
            var g = c.g;
            var b = c.b;
            var i = this._intensity;
            this._finalColor.set(r * i, g * i, b * i);
            for(var j = 0; j < 3; j++) {
                if (i >= 1) {
                    this._linearFinalColor.data[j] = Math.pow(this._finalColor.data[j] / i, 2.2) * i;
                } else {
                    this._linearFinalColor.data[j] = Math.pow(this._finalColor.data[j], 2.2);
                }
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setOuterConeAngle
         * @description Sets the outer cone angle of the light. Note that this
         * function only affects spotlights. The contribution of the spotlight is
         * zero outside the cone defined by this angle.
         * @param {Number} angle The outer cone angle of the spotlight in degrees.
         */
        setOuterConeAngle: function (angle) {
            this._outerConeAngle = angle;
            this._outerConeAngleCos = Math.cos(angle * Math.PI / 180);
        },

        /**
         * @private
         * @function
         * @name pc.Light#setShadowBias
         * @description Sets the depth bias for tuning the appearance of the shadow
         * mapping generated by this light.
         * @param {Number} bias The shadow mapping depth bias (defaults to -0.0005)
         */
        setShadowBias: function (bias) {
            this._shadowBias = bias;
        },

        setNormalOffsetBias: function (bias) {
            if ((!this._normalOffsetBias && bias) || (this._normalOffsetBias && !bias)) {
                this._scene.updateShaders = true;
            }
            this._normalOffsetBias = bias;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setShadowDistance
         * @description Sets the distance in camera Z at which the shadows cast by this
         * light are no longer rendered. Note that this function only applies to directional
         * lights.
         * @param {Number} distance The shadow distance in world units
         */
        setShadowDistance: function (distance) {
            this._shadowDistance = distance;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setShadowResolution
         * @description Sets the pixel width and height of the shadow map associated with this
         * light.
         * @param {Number} resolution The pixel width and height of the shadow map
         */
        setShadowResolution: function (resolution) {
            var device = pc.Application.getApplication().graphicsDevice;
            if (this._type===pc.LIGHTTYPE_POINT) {
                resolution = Math.min(resolution, device.maxCubeMapSize);
            } else {
                resolution = Math.min(resolution, device.maxTextureSize);
            }
            this._shadowResolution = resolution;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setType
         * @description Sets the type of the light. Avialable lights types are directional,
         * point and spot.
         * @param {Number} type The light type (see pc.LIGHTTYPE).
         */
        setType: function (type) {
            this._type = type;

            if (this._shadowCamera) {
                var rt = this._shadowCamera._renderTarget;
                var i;
                if (rt) {
                    if (rt.length) {
                        for(i=0; i<rt.length; i++) {
                            rt[i].destroy();
                        }
                    } else {
                        rt.destroy();
                    }
                }
                this._shadowCamera = null;
            }
        },

        updateShadow: function() {
            if (this.shadowUpdateMode!==pc.SHADOWUPDATE_REALTIME) {
                this.shadowUpdateMode = pc.SHADOWUPDATE_THISFRAME;
            }
        }
    };

    return {
        Light: Light
    };
}());
<commit_msg>don't leak memory on light change<commit_after>pc.extend(pc, function () {

    /**
     * @private
     * @name pc.Light
     * @class A light.
     */
    var Light = function Light() {
        // Light properties (defaults)
        this._type = pc.LIGHTTYPE_DIRECTIONAL;
        this._color = new pc.Color(0.8, 0.8, 0.8);
        this._intensity = 1;
        this._castShadows = false;
        this._enabled = false;

        // Point and spot properties
        this._attenuationStart = 10;
        this._attenuationEnd = 10;
        this._falloffMode = 0;
        this._shadowType = pc.SHADOW_DEPTH;
        this.mask = 1;

        // Spot properties
        this._innerConeAngle = 40;
        this._outerConeAngle = 45;

        // Cache of light property data in a format more friendly for shader uniforms
        this._finalColor = new pc.Vec3(0.8, 0.8, 0.8);
        this._linearFinalColor = new pc.Vec3();
        this._position = new pc.Vec3(0, 0, 0);
        this._direction = new pc.Vec3(0, 0, 0);
        this._innerConeAngleCos = Math.cos(this._innerConeAngle * Math.PI / 180);
        this._outerConeAngleCos = Math.cos(this._outerConeAngle * Math.PI / 180);

        // Shadow mapping resources
        this._shadowCamera = null;
        this._shadowMatrix = new pc.Mat4();
        this._shadowDistance = 40;
        this._shadowResolution = 1024;
        this._shadowBias = -0.0005;
        this._normalOffsetBias = 0.0;
        this.shadowUpdateMode = pc.SHADOWUPDATE_REALTIME;

        this._scene = null;
        this._node = null;
    };

    Light.prototype = {
        /**
         * @private
         * @function
         * @name pc.Light#clone
         * @description Duplicates a light node but does not 'deep copy' the hierarchy.
         * @returns {pc.Light} A cloned Light.
         */
        clone: function () {
            var clone = new pc.Light();

            // Clone Light properties
            clone.setType(this.getType());
            clone.setColor(this.getColor());
            clone.setIntensity(this.getIntensity());
            clone.setCastShadows(this.getCastShadows());
            clone.setEnabled(this.getEnabled());

            // Point and spot properties
            clone.setAttenuationStart(this.getAttenuationStart());
            clone.setAttenuationEnd(this.getAttenuationEnd());
            clone.setFalloffMode(this.getFalloffMode());
            clone.setShadowType(this.getShadowType());
            clone.shadowUpdateMode = this.shadowUpdateMode;
            clone.mask = this.mask;

            // Spot properties
            clone.setInnerConeAngle(this.getInnerConeAngle());
            clone.setOuterConeAngle(this.getOuterConeAngle());

            // Shadow properties
            clone.setShadowBias(this.getShadowBias());
            clone.setNormalOffsetBias(this.getNormalOffsetBias());
            clone.setShadowResolution(this.getShadowResolution());
            clone.setShadowDistance(this.getShadowDistance());

            return clone;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getAttenuationEnd
         * @description Queries the radius of the point or spot light. In other words, this is
         * the distance at which the light's contribution falls to zero.
         * @returns {Number} The radius of the point or spot light.
         */
        getAttenuationEnd: function () {
            return this._attenuationEnd;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getAttenuationStart
         * @description Queries the distance from the point or spot light that attenuation begins.
         * @returns {Number} The radius from the light position where attenuation starts.
         */
        getAttenuationStart: function () {
            return this._attenuationStart;
        },

        getFalloffMode: function () {
            return this._falloffMode;
        },

        getShadowType: function () {
            return this._shadowType;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getCastShadows
         * @description Queries whether the light casts shadows. Dynamic lights do not
         * cast shadows by default.
         * @returns {Boolean} true if the specified light casts shadows and false otherwise.
         */
        getCastShadows: function () {
            return this._castShadows && this.mask!==pc.MASK_LIGHTMAP && this.mask!==0;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getColor
         * @description Queries the diffuse color of the light. The PlayCanvas 'phong' shader uses this
         * value by multiplying it by the diffuse color of a mesh's material and adding it to
         * the total light contribution.
         * @returns {pc.Color} The diffuse color of the light (RGB components ranging 0..1).
         */
        getColor: function () {
            return this._color;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getEnabled
         * @description Queries whether the specified light is currently enabled.
         * @returns {Boolean} true if the light is enabled and false otherwise.
         */
        getEnabled: function () {
            return this._enabled;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getInnerConeAngle
         * @description Queries the inner cone angle of the specified spot light. Note
         * that this function is only valid for spotlights.
         * @returns {Number} The inner cone angle of the specified light in degrees.
         */
        getInnerConeAngle: function () {
            return this._innerConeAngle;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getIntensity
         * @description Queries the intensity of the specified light.
         * @returns {Number} The intensity of the specified light.
         */
        getIntensity: function () {
            return this._intensity;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getOuterConeAngle
         * @description Queries the outer cone angle of the specified spot light. Note
         * that this function is only valid for spotlights.
         * @returns {Number} The outer cone angle of the specified light in degrees.
         */
        getOuterConeAngle: function () {
            return this._outerConeAngle;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getShadowBias
         * @description Queries the shadow mapping depth bias for this light. Note
         * that this function is only valid for directional lights and spotlights.
         * @returns {Number} The shadow mapping depth bias.
         */
        getShadowBias: function () {
            return this._shadowBias;
        },

        getNormalOffsetBias: function () {
            return this._normalOffsetBias;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getShadowDistance
         * @description Queries the distance in camera Z at which shadows will no
         * longer be rendered. Note that this function is only valid for directional
         * lights.
         * @returns {Number} The shadow distance in world units.
         */
        getShadowDistance: function () {
            return this._shadowDistance;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getShadowResolution
         * @description Queries the shadow map pixel resolution for this light.
         * @returns {Number} The shadow map resolution.
         */
        getShadowResolution: function () {
            return this._shadowResolution;
        },

        /**
         * @private
         * @function
         * @name pc.Light#getType
         * @description Queries the type of the light. The light can be a directional light,
         * a point light or a spotlight.
         * @returns {pc.LightType} The type of the specified light.
         */
        getType: function () {
            return this._type;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setAttenuationEnd
         * @description Specifies the radius from the light position where the light's
         * contribution falls to zero.
         * @param {Number} radius The radius of influence of the light.
         */
        setAttenuationEnd: function (radius) {
            this._attenuationEnd = radius;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setAttenuationStart
         * @description Specifies the radius from the light position where the light
         * contribution begins to attenuate.
         * @param {Number} radius The radius at which the light begins to attenuate.
         */
        setAttenuationStart: function (radius) {
            this._attenuationStart = radius;
        },

        setFalloffMode: function (mode) {
            this._falloffMode = mode;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        setShadowType: function (mode) {
            this._shadowType = mode;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        setMask: function (_mask) {
            this.mask = _mask;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setCastShadows
         * @description Toggles the casting of shadows from this light.
         * @param {Boolean} castShadows True to enabled shadow casting, false otherwise.
         */
        setCastShadows: function (castShadows) {
            this._castShadows = castShadows;
            if (this._scene !== null) {
                this._scene.updateShaders = true;
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setColor
         * @description Sets the RGB color of the light. RGB components should be
         * specified in the range 0 to 1.
         * @param {pc.Color} color The RGB color of the light.
         */
        /**
         * @private
         * @function
         * @name pc.Light#setColor^2
         * @description Sets the RGB color of the light. RGB components should be
         * specified in the range 0 to 1.
         * @param {Number} red The red component of the light color.
         * @param {Number} green The green component of the light color.
         * @param {Number} blue The blue component of the light color.
         */
        setColor: function () {
            var r, g, b;
            if (arguments.length === 1) {
                r = arguments[0].r;
                g = arguments[0].g;
                b = arguments[0].b;
            } else if (arguments.length === 3) {
                r = arguments[0];
                g = arguments[1];
                b = arguments[2];
            }

            this._color.set(r, g, b);

            // Update final color
            var i = this._intensity;
            this._finalColor.set(r * i, g * i, b * i);
            for(var c=0; c<3; c++) {
                if (i >= 1) {
                    this._linearFinalColor.data[c] = Math.pow(this._finalColor.data[c] / i, 2.2) * i;
                } else {
                    this._linearFinalColor.data[c] = Math.pow(this._finalColor.data[c], 2.2);
                }
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setEnabled
         * @description Marks the specified light as enabled or disabled.
         * @param {boolean} enable true to enable the light and false to disable it.
         */
        setEnabled: function (enable) {
            if (this._enabled !== enable) {
                this._enabled = enable;
                if (this._scene !== null) {
                    this._scene.updateShaders = true;
                }
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setInnerConeAngle
         * @description Sets the inner cone angle of the light. Note that this
         * function only affects spotlights. The contribution of the spotlight is
         * zero outside the cone defined by this angle.
         * @param {Number} angle The inner cone angle of the spotlight in degrees.
         */
        setInnerConeAngle: function (angle) {
            this._innerConeAngle = angle;
            this._innerConeAngleCos = Math.cos(angle * Math.PI / 180);
        },

        /**
         * @private
         * @function
         * @name pc.Light#setIntensity
         * @description Sets the intensity of the light. The intensity is used to
         * scale the color of the light. Note that this makes it possible to take
         * the light color's RGB components outside the range 0 to 1.
         * @param {Number} intensity The intensity of the light.
         */
        setIntensity: function (intensity) {
            this._intensity = intensity;

            // Update final color
            var c = this._color;
            var r = c.r;
            var g = c.g;
            var b = c.b;
            var i = this._intensity;
            this._finalColor.set(r * i, g * i, b * i);
            for(var j = 0; j < 3; j++) {
                if (i >= 1) {
                    this._linearFinalColor.data[j] = Math.pow(this._finalColor.data[j] / i, 2.2) * i;
                } else {
                    this._linearFinalColor.data[j] = Math.pow(this._finalColor.data[j], 2.2);
                }
            }
        },

        /**
         * @private
         * @function
         * @name pc.Light#setOuterConeAngle
         * @description Sets the outer cone angle of the light. Note that this
         * function only affects spotlights. The contribution of the spotlight is
         * zero outside the cone defined by this angle.
         * @param {Number} angle The outer cone angle of the spotlight in degrees.
         */
        setOuterConeAngle: function (angle) {
            this._outerConeAngle = angle;
            this._outerConeAngleCos = Math.cos(angle * Math.PI / 180);
        },

        /**
         * @private
         * @function
         * @name pc.Light#setShadowBias
         * @description Sets the depth bias for tuning the appearance of the shadow
         * mapping generated by this light.
         * @param {Number} bias The shadow mapping depth bias (defaults to -0.0005)
         */
        setShadowBias: function (bias) {
            this._shadowBias = bias;
        },

        setNormalOffsetBias: function (bias) {
            if ((!this._normalOffsetBias && bias) || (this._normalOffsetBias && !bias)) {
                this._scene.updateShaders = true;
            }
            this._normalOffsetBias = bias;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setShadowDistance
         * @description Sets the distance in camera Z at which the shadows cast by this
         * light are no longer rendered. Note that this function only applies to directional
         * lights.
         * @param {Number} distance The shadow distance in world units
         */
        setShadowDistance: function (distance) {
            this._shadowDistance = distance;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setShadowResolution
         * @description Sets the pixel width and height of the shadow map associated with this
         * light.
         * @param {Number} resolution The pixel width and height of the shadow map
         */
        setShadowResolution: function (resolution) {
            var device = pc.Application.getApplication().graphicsDevice;
            if (this._type===pc.LIGHTTYPE_POINT) {
                resolution = Math.min(resolution, device.maxCubeMapSize);
            } else {
                resolution = Math.min(resolution, device.maxTextureSize);
            }
            this._shadowResolution = resolution;
        },

        /**
         * @private
         * @function
         * @name pc.Light#setType
         * @description Sets the type of the light. Avialable lights types are directional,
         * point and spot.
         * @param {Number} type The light type (see pc.LIGHTTYPE).
         */
        setType: function (type) {
            this._type = type;
            this._destroyShadowMap();
        },

        _destroyShadowMap: function () {
            if (this._shadowCamera) {
                var rt = this._shadowCamera._renderTarget;
                var i;
                if (rt) {
                    if (rt.length) {
                        for(i=0; i<rt.length; i++) {
                            if (rt[i].colorBuffer) rt[i].colorBuffer.destroy();
                            rt[i].destroy();
                        }
                    } else {
                        if (rt.colorBuffer) rt.colorBuffer.destroy();
                        rt.destroy();
                    }
                }
                this._shadowCamera._renderTarget = null;
                this._shadowCamera = null;
                this._shadowCubeMap = null;
            }
        },

        updateShadow: function() {
            if (this.shadowUpdateMode!==pc.SHADOWUPDATE_REALTIME) {
                this.shadowUpdateMode = pc.SHADOWUPDATE_THISFRAME;
            }
        }
    };

    return {
        Light: Light
    };
}());
<|endoftext|>


<commit_before>/* ====================================================================
   |
   |   Jtalk Smalltalk
   |   http://jtalk-project.org
   |
   ======================================================================

   ======================================================================
   |
   | Copyright (c) 2010-2011
   | Nicolas Petton <petton.nicolas@gmail.com>
   |
   | Jtalk is released under the MIT license
   |
   | Permission is hereby granted, free of charge, to any person obtaining
   | a copy of this software and associated documentation files (the
   | 'Software'), to deal in the Software without restriction, including
   | without limitation the rights to use, copy, modify, merge, publish,
   | distribute, sublicense, and/or sell copies of the Software, and to
   | permit persons to whom the Software is furnished to do so, subject to
   | the following conditions:
   |
   | The above copyright notice and this permission notice shall be
   | included in all copies or substantial portions of the Software.
   |
   | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
   | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   |
   ==================================================================== */

/* Smalltalk constructors definition */

function SmalltalkObject(){};
function SmalltalkBehavior(){};
function SmalltalkClass(){};
function SmalltalkMetaclass(){
    this.meta = true;
};
function SmalltalkMethod(){};
function SmalltalkNil(){};

function Smalltalk(){

    var st = this;
    st.debugMode = true;

    /* Smalltalk class creation. A class is an instance of an automatically
       created metaclass object. Newly created classes (not their metaclass)
       should be added to the smalltalk object, see smalltalk.addClass().
       Superclass linking is *not* handled here, see smalltalk.init()  */

    function klass(spec) {
	var spec = spec || {};
	var that;
	if(spec.meta) {
	    that = new SmalltalkMetaclass();
	} else {
	    that = new (klass({meta: true})).fn;
	    that.klass.instanceClass = that;
	    that.className = spec.className;
	    that.klass.className = that.className + ' class';
	}

	that.fn = spec.fn || function(){};
	that.superclass = spec.superclass;
	that.iVarNames = spec.iVarNames || [];
	if(that.superclass) {
	    that.klass.superclass = that.superclass.klass;
	}
	that.category = spec.category || "";
	that.fn.prototype.methods = {};
	that.fn.prototype.klass = that;

	return that;
    };

    /* Smalltalk method object. To add a method to a class,
       use smalltalk.addMethod() */

    st.method = function(spec) {
	var that = new SmalltalkMethod();
	that.selector          = spec.selector;
	that.category          = spec.category;
	that.source            = spec.source;
	that.messageSends      = spec.messageSends || [];
	that.referencedClasses = spec.referencedClasses || [];
	that.fn                = spec.fn;
	return that
    };

    /* Initialize a class in its class hierarchy. Handle both class and
       metaclasses. */

    st.init = function(klass) {
	var subclasses = st.subclasses(klass);
	for(var i=0;i<klass.iVarNames.length;i++) {
	    klass.fn.prototype["@"+klass.iVarNames[i]] = nil;
	}
	if(klass.superclass && klass.superclass !== nil) {
	    klass.fn.prototype.__proto__ = klass.superclass.fn.prototype;
	    for(var i=0;i<klass.superclass.iVarNames.length;i++) {
		if(!klass["@"+klass.superclass.iVarNames[i]]) {
		    klass.fn.prototype["@"+klass.superclass.iVarNames[i]] = nil;
		}
	    }
	}
	for(var i=0;i<subclasses.length;i++) {
     	    st.init(subclasses[i]);
	}
	if(klass.klass && !klass.meta) {
	    st.init(klass.klass);
	}
    };

    /* Answer all registered Smalltalk classes */

    st.classes = function() {
	var classes = [];
	for(var i in st) {
	    if(i.search(/^[A-Z]/g) != -1) {
		classes.push(st[i]);
	    }

	}
	return classes
    };

    /* Answer the direct subclasses of a given class.
       This is computed dynamically */

    st.subclasses = function(klass) {
	var subclasses = [];
	var classes = st.classes();
	for(var i in classes) {
	    if(classes[i].fn) {
		//Metaclasses
		if(classes[i].klass && classes[i].klass.superclass === klass) {
		    subclasses.push(classes[i].klass);
		}
		//Classes
		if(classes[i].superclass === klass) {
		    subclasses.push(classes[i]);
		}
	    }
	}
	return subclasses;
    };

    /* Create a new class wrapping a JavaScript constructor, and add it to the
       global smalltalk object. */

    st.mapClassName = function(className, category, fn, superclass) {
	st[className] = klass({
	    className:  className,
	    category:   category,
	    superclass: superclass,
	    fn:         fn
	});
    };

    /* Add a class to the smalltalk object, creating a new one if needed. */

    st.addClass = function(className, superclass, iVarNames, category) {
	if(st[className]) {
	    st[className].superclass = superclass;
	    st[className].iVarNames = iVarNames;
	    st[className].category = category || st[className].category;
	} else {
	    st[className] = klass({
		className: className,
		iVarNames: iVarNames,
		superclass: superclass
	    });
	    st[className].category = category || '';
	}
    };

    /* Add a method to a class */

    st.addMethod = function(jsSelector, method, klass) {
	klass.fn.prototype[jsSelector] = method.fn;
	klass.fn.prototype.methods[method.selector] = method;
	method.methodClass = klass;
    };

    /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
       If the receiver does not understand the selector, call its #doesNotUnderstand: method */

    st.send = function(receiver, selector, args, klass) {
	if(typeof receiver === "undefined") {
	    receiver = nil;
	}
	var klass = klass || receiver.klass;
	if(!klass) { return messageNotUnderstood(receiver, selector, args) };
	var method = klass.fn.prototype[selector];
	if(!method) {
	    return messageNotUnderstood(receiver, selector, args);
	}
	return method.apply(receiver, args);
    };

    /* Handles #dnu: *and* JavaScript method calls.
       if the receiver has no klass, we consider it a JS object (outside of the
       Jtalk system). Else assume that the receiver understands #doesNotUnderstand: */

    function messageNotUnderstood(receiver, selector, args) {
	/* Handles JS method calls. Assumes that a single array or single argument was passed from Jtalk.
	   Example: someJSObject foo: #(1 2 3) -> someJSObject.foo(1,2,3); */
	var jsSelector = selector.replace(/_/g, '');
	var jsFunction = receiver[jsSelector];
	var jsArguments;
	if(receiver.klass === undefined && typeof jsFunction === "function") {
	    if(args[0] && args[0].constructor === Array) {
		jsArguments = args[0]
	    } else {
		jsArguments = [args[0]]
	    }
	    return jsFunction.apply(receiver, jsArguments);
	}

	/* Handles not understood messages. Also see the Jtalk counter-part
	   Object>>doesNotUnderstand: */
	if(!receiver.klass) {throw(receiver + ' is not a Jtalk object and ' + jsSelector + ' is not a function')}

	return receiver._doesNotUnderstand_(
	    st.Message._new()
		._selector_(convertSelector(selector))
		._arguments_(args)
	);
    };

    /* Convert a string to a valid smalltalk selector.
       if you modify the following functions, also change String>>asSelector
       accordingly */

    function convertSelector(selector) {
	if(selector.match(/__/)) {
	    return convertBinarySelector(selector);
	} else {
	    return convertKeywordSelector(selector);
	}
    };

    function convertKeywordSelector(selector) {
	return selector.replace(/^_/, '').replace(/_/g, ':');
    };

    function convertBinarySelector(selector) {
	return selector
	    .replace(/^_/, '')
	    .replace(/_plus/, '+')
	    .replace(/_minus/, '-')
	    .replace(/_star/, '*')
	    .replace(/_slash/, '/')
	    .replace(/_gt/, '>')
	    .replace(/_lt/, '<')
	    .replace(/_eq/, '=')
	    .replace(/_comma/, ',')
	    .replace(/_at/, '@')
    };

    /* Converts a JavaScript object to valid Smalltalk Object */
    st.readJSObject = function(js) {
	var object = js;
	var readObject = (js.constructor === Object);
	var readArray = (js.constructor === Array);

	if(readObject) {
	    object = smalltalk.Dictionary._new();
	}
	for(var i in js) {
	    if(readObject) {
		object._at_put_(i, st.readJSObject(js[i]));
	    }
	    if(readArray) {
		object[i] = st.readJSObject(js[i]);
	    }
	}
	return object;
    };
}

function SmalltalkMethodContext() {
    this.stack = [];

    this.push = function(context) {
	stack.push(context);
    };

    this.pop = function() {
	stack.pop();
    };
}

/* Global Smalltalk objects. nil and thisContext shouldn't be globals. */

var nil = new SmalltalkNil();
var smalltalk = new Smalltalk();
var thisContext = nil;

/****************************************************************************************/

/* Base classes mapping. If you edit this part, do not forget to set the superclass of the
   object metaclass to Class after the definition of Object */

smalltalk.mapClassName("Object", "Kernel", SmalltalkObject);
smalltalk.mapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
smalltalk.mapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
smalltalk.mapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
smalltalk.mapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
smalltalk.mapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);

smalltalk.Object.klass.superclass = smalltalk.Class

smalltalk.mapClassName("Number", "Kernel", Number, smalltalk.Object);
smalltalk.mapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
smalltalk.mapClassName("Boolean", "Kernel", Boolean, smalltalk.Object);
smalltalk.mapClassName("Date", "Kernel", Date, smalltalk.Object);
smalltalk.mapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object);

smalltalk.mapClassName("Collection", "Kernel", null, smalltalk.Object);
smalltalk.mapClassName("SequenceableCollection", "Kernel", null, smalltalk.Collection);
smalltalk.mapClassName("String", "Kernel", String, smalltalk.SequenceableCollection);
smalltalk.mapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollection);
smalltalk.mapClassName("RegularExpression", "Kernel", RegExp, smalltalk.String);

smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);

if(this.CanvasRenderingContext2D) {
    smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
}
<commit_msg>Handles JS object properties too<commit_after>/* ====================================================================
   |
   |   Jtalk Smalltalk
   |   http://jtalk-project.org
   |
   ======================================================================

   ======================================================================
   |
   | Copyright (c) 2010-2011
   | Nicolas Petton <petton.nicolas@gmail.com>
   |
   | Jtalk is released under the MIT license
   |
   | Permission is hereby granted, free of charge, to any person obtaining
   | a copy of this software and associated documentation files (the
   | 'Software'), to deal in the Software without restriction, including
   | without limitation the rights to use, copy, modify, merge, publish,
   | distribute, sublicense, and/or sell copies of the Software, and to
   | permit persons to whom the Software is furnished to do so, subject to
   | the following conditions:
   |
   | The above copyright notice and this permission notice shall be
   | included in all copies or substantial portions of the Software.
   |
   | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
   | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   |
   ==================================================================== */

/* Smalltalk constructors definition */

function SmalltalkObject(){};
function SmalltalkBehavior(){};
function SmalltalkClass(){};
function SmalltalkMetaclass(){
    this.meta = true;
};
function SmalltalkMethod(){};
function SmalltalkNil(){};

function Smalltalk(){

    var st = this;
    st.debugMode = true;

    /* Smalltalk class creation. A class is an instance of an automatically
       created metaclass object. Newly created classes (not their metaclass)
       should be added to the smalltalk object, see smalltalk.addClass().
       Superclass linking is *not* handled here, see smalltalk.init()  */

    function klass(spec) {
	var spec = spec || {};
	var that;
	if(spec.meta) {
	    that = new SmalltalkMetaclass();
	} else {
	    that = new (klass({meta: true})).fn;
	    that.klass.instanceClass = that;
	    that.className = spec.className;
	    that.klass.className = that.className + ' class';
	}

	that.fn = spec.fn || function(){};
	that.superclass = spec.superclass;
	that.iVarNames = spec.iVarNames || [];
	if(that.superclass) {
	    that.klass.superclass = that.superclass.klass;
	}
	that.category = spec.category || "";
	that.fn.prototype.methods = {};
	that.fn.prototype.klass = that;

	return that;
    };

    /* Smalltalk method object. To add a method to a class,
       use smalltalk.addMethod() */

    st.method = function(spec) {
	var that = new SmalltalkMethod();
	that.selector          = spec.selector;
	that.category          = spec.category;
	that.source            = spec.source;
	that.messageSends      = spec.messageSends || [];
	that.referencedClasses = spec.referencedClasses || [];
	that.fn                = spec.fn;
	return that
    };

    /* Initialize a class in its class hierarchy. Handle both class and
       metaclasses. */

    st.init = function(klass) {
	var subclasses = st.subclasses(klass);
	for(var i=0;i<klass.iVarNames.length;i++) {
	    klass.fn.prototype["@"+klass.iVarNames[i]] = nil;
	}
	if(klass.superclass && klass.superclass !== nil) {
	    klass.fn.prototype.__proto__ = klass.superclass.fn.prototype;
	    for(var i=0;i<klass.superclass.iVarNames.length;i++) {
		if(!klass["@"+klass.superclass.iVarNames[i]]) {
		    klass.fn.prototype["@"+klass.superclass.iVarNames[i]] = nil;
		}
	    }
	}
	for(var i=0;i<subclasses.length;i++) {
     	    st.init(subclasses[i]);
	}
	if(klass.klass && !klass.meta) {
	    st.init(klass.klass);
	}
    };

    /* Answer all registered Smalltalk classes */

    st.classes = function() {
	var classes = [];
	for(var i in st) {
	    if(i.search(/^[A-Z]/g) != -1) {
		classes.push(st[i]);
	    }

	}
	return classes
    };

    /* Answer the direct subclasses of a given class.
       This is computed dynamically */

    st.subclasses = function(klass) {
	var subclasses = [];
	var classes = st.classes();
	for(var i in classes) {
	    if(classes[i].fn) {
		//Metaclasses
		if(classes[i].klass && classes[i].klass.superclass === klass) {
		    subclasses.push(classes[i].klass);
		}
		//Classes
		if(classes[i].superclass === klass) {
		    subclasses.push(classes[i]);
		}
	    }
	}
	return subclasses;
    };

    /* Create a new class wrapping a JavaScript constructor, and add it to the
       global smalltalk object. */

    st.mapClassName = function(className, category, fn, superclass) {
	st[className] = klass({
	    className:  className,
	    category:   category,
	    superclass: superclass,
	    fn:         fn
	});
    };

    /* Add a class to the smalltalk object, creating a new one if needed. */

    st.addClass = function(className, superclass, iVarNames, category) {
	if(st[className]) {
	    st[className].superclass = superclass;
	    st[className].iVarNames = iVarNames;
	    st[className].category = category || st[className].category;
	} else {
	    st[className] = klass({
		className: className,
		iVarNames: iVarNames,
		superclass: superclass
	    });
	    st[className].category = category || '';
	}
    };

    /* Add a method to a class */

    st.addMethod = function(jsSelector, method, klass) {
	klass.fn.prototype[jsSelector] = method.fn;
	klass.fn.prototype.methods[method.selector] = method;
	method.methodClass = klass;
    };

    /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
       If the receiver does not understand the selector, call its #doesNotUnderstand: method */

    st.send = function(receiver, selector, args, klass) {
	if(typeof receiver === "undefined") {
	    receiver = nil;
	}
	var klass = klass || receiver.klass;
	if(!klass) { return messageNotUnderstood(receiver, selector, args) };
	var method = klass.fn.prototype[selector];
	if(!method) {
	    return messageNotUnderstood(receiver, selector, args);
	}
	return method.apply(receiver, args);
    };

    /* Handles #dnu: *and* JavaScript method calls.
       if the receiver has no klass, we consider it a JS object (outside of the
       Jtalk system). Else assume that the receiver understands #doesNotUnderstand: */

    function messageNotUnderstood(receiver, selector, args) {
	/* Handles JS method calls. Assumes that a single array or single argument was passed from Jtalk.
	   Example: someJSObject foo: #(1 2 3) -> someJSObject.foo(1,2,3); */
	var jsSelector = selector.replace(/_/g, '');
	var jsProperty = receiver[jsSelector];
	var jsArguments;
	if(receiver.klass === undefined) {
	    if(typeof jsProperty === "function") {
		if(args[0] && args[0].constructor === Array) {
		    jsArguments = args[0]
		} else {
		    jsArguments = [args[0]]
		}
		return jsProperty.apply(receiver, jsArguments);
	    } else if(jsProperty !== undefined) {
		return jsProperty
	    }
	}

	/* Handles not understood messages. Also see the Jtalk counter-part
	   Object>>doesNotUnderstand: */
	if(!receiver.klass) {throw(receiver + ' is not a Jtalk object and ' + jsSelector + ' is undefined')}

	return receiver._doesNotUnderstand_(
	    st.Message._new()
		._selector_(convertSelector(selector))
		._arguments_(args)
	);
    };

    /* Convert a string to a valid smalltalk selector.
       if you modify the following functions, also change String>>asSelector
       accordingly */

    function convertSelector(selector) {
	if(selector.match(/__/)) {
	    return convertBinarySelector(selector);
	} else {
	    return convertKeywordSelector(selector);
	}
    };

    function convertKeywordSelector(selector) {
	return selector.replace(/^_/, '').replace(/_/g, ':');
    };

    function convertBinarySelector(selector) {
	return selector
	    .replace(/^_/, '')
	    .replace(/_plus/, '+')
	    .replace(/_minus/, '-')
	    .replace(/_star/, '*')
	    .replace(/_slash/, '/')
	    .replace(/_gt/, '>')
	    .replace(/_lt/, '<')
	    .replace(/_eq/, '=')
	    .replace(/_comma/, ',')
	    .replace(/_at/, '@')
    };

    /* Converts a JavaScript object to valid Smalltalk Object */
    st.readJSObject = function(js) {
	var object = js;
	var readObject = (js.constructor === Object);
	var readArray = (js.constructor === Array);

	if(readObject) {
	    object = smalltalk.Dictionary._new();
	}
	for(var i in js) {
	    if(readObject) {
		object._at_put_(i, st.readJSObject(js[i]));
	    }
	    if(readArray) {
		object[i] = st.readJSObject(js[i]);
	    }
	}
	return object;
    };
}

function SmalltalkMethodContext() {
    this.stack = [];

    this.push = function(context) {
	stack.push(context);
    };

    this.pop = function() {
	stack.pop();
    };
}

/* Global Smalltalk objects. nil and thisContext shouldn't be globals. */

var nil = new SmalltalkNil();
var smalltalk = new Smalltalk();
var thisContext = nil;

/****************************************************************************************/

/* Base classes mapping. If you edit this part, do not forget to set the superclass of the
   object metaclass to Class after the definition of Object */

smalltalk.mapClassName("Object", "Kernel", SmalltalkObject);
smalltalk.mapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
smalltalk.mapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
smalltalk.mapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
smalltalk.mapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
smalltalk.mapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);

smalltalk.Object.klass.superclass = smalltalk.Class

smalltalk.mapClassName("Number", "Kernel", Number, smalltalk.Object);
smalltalk.mapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
smalltalk.mapClassName("Boolean", "Kernel", Boolean, smalltalk.Object);
smalltalk.mapClassName("Date", "Kernel", Date, smalltalk.Object);
smalltalk.mapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object);

smalltalk.mapClassName("Collection", "Kernel", null, smalltalk.Object);
smalltalk.mapClassName("SequenceableCollection", "Kernel", null, smalltalk.Collection);
smalltalk.mapClassName("String", "Kernel", String, smalltalk.SequenceableCollection);
smalltalk.mapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollection);
smalltalk.mapClassName("RegularExpression", "Kernel", RegExp, smalltalk.String);

smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);

if(this.CanvasRenderingContext2D) {
    smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
}
<|endoftext|>


<commit_before>var React = require('react');

var NotificationSystem = require('../../dist/notification-system');

var NotificationSystemExample = React.createClass({

  _notificationSystem: null,

  _notify: function(event) {
    event.preventDefault();
    var notification = this.state.notification;

    this._notificationSystem.addNotification(notification);
  },

  _changed: function(event) {
    var notification = this.state.notification;
    var prop = event.target.name;
    var value = event.target.value;

    if (prop === 'autoDismiss') {
      if (value === '') value = 0;
      value = parseInt(value);
    }

    notification[prop] = value

    this.setState({
      notification: notification
    });
  },

  _changedDismissible: function(event) {
    var notification = this.state.notification;
    notification.dismissible = !notification.dismissible;

    if (!notification.dismissible && !notification.actionState) {
      this._changedAction();
    }

    this.setState({
      notification: notification
    });
  },

  _callbackForAction: function() {
    var count = this.state.actionCounter;
    count++;
    this.setState({
      actionCounter: count
    });
  },

  _changedAction: function(event) {
    var notification = this.state.notification;
    notification.actionState = !notification.actionState;

    if (notification.actionState) {
      notification.action = {
        label: 'Action',
        callback: this._callbackForAction
      }
    } else {
      notification.action = null;
    }

    this.setState({
      notification: notification
    });
  },

  _changedActionLabel: function(event) {
    var notification = this.state.notification;
    var value = event.target.value;

    notification.action.label = value;

    this.setState({
      notification: notification
    });

  },

  getInitialState: function() {
    return {
      notification: {
        message: 'Default message',
        level: 'error',
        position: 'tr',
        autoDismiss: 5,
        dismissible: true,
        action: null,
        actionState: false
      },
      actionCounter: 0
    }
  },
  componentDidMount: function() {
    this._notificationSystem = this.refs.notificationSystem;

  },
  render: function() {
    var notification = this.state.notification;

    var action = null;

    if (notification.actionState) {
      action = (

label

            <input className="form-control" name="label" onChange={this._changedActionLabel} type="text" value={notification.action.label} />

      );
    }

    var printNotification = notification;

    printNotification = JSON.stringify(printNotification, null, 4);

    return

React Notification System

                      <form>

                          Message:
                          <input className="form-control" name="message" onChange={this._changed} type="text" value={notification.message} />

                          Position:
                          <select className="form-control" name="position" onChange={this._changed} value={notification.position}>
                            <option value="tl">Top left (tl)</option>
                            <option value="tr">Top right (tr)</option>
                            <option value="tc">Top center (tc)</option>
                            <option value="bl">Bottom left (bl)</option>
                            <option value="br">Bottom right (br)</option>
                            <option value="bc">Bottom center (bc)</option>
                            <option value="in">Invalid position</option>
                          </select>

                          Level:
                          <select className="form-control" name="level" onChange={this._changed} value={notification.level}>
                            <option value="success">Success</option>
                            <option value="error">Error</option>
                            <option value="warning">Warning</option>
                            <option value="info">Info</option>
                            <option value="in">Invalid level</option>
                          </select>

                          Auto Dismiss delay:

                            <input className="form-control" name="autoDismiss" onChange={this._changed} type="text" value={notification.autoDismiss} />

secs (0 means infinite)

                              <input type="checkbox" checked={notification.dismissible} onChange={this._changedDismissible} />
                              Can user dismiss

                                <input type="checkbox" checked={notification.actionState} onChange={this._changedAction} />
                                Action

                            {action}

                          <button className="btn btn-lg btn-block btn-success" onClick={this._notify}>Notify!</button>

                      </form>

Notification object

                        {printNotification}

Action click counter {this.state.actionCounter}

A simple counter for every action click.

              <NotificationSystem ref="notificationSystem" />

;
  }
});

React.render(
  React.createElement(NotificationSystemExample),
  document.getElementById('app')
);
<commit_msg>Improved example app<commit_after>var React = require('react');

var NotificationSystem = require('react-notification-system');

var NotificationSystemExample = React.createClass({

  _notificationSystem: null,

  _notify: function(event) {
    event.preventDefault();
    var notification = this.state.notification;

    this._notificationSystem.addNotification(notification);
  },

  _changed: function(event) {
    var notification = this.state.notification;
    var prop = event.target.name;
    var value = event.target.value;

    if (prop === 'autoDismiss') {
      if (value === '') value = 0;
      value = parseInt(value);
    }

    notification[prop] = value;

    this.setState({
      notification: notification
    });
  },

  _changedDismissible: function(event) {
    var notification = this.state.notification;
    notification.dismissible = !notification.dismissible;

    if (!notification.dismissible && !notification.actionState) {
      this._changedAction();
    }

    this.setState({
      notification: notification
    });
  },

  _callbackForAction: function() {
    var count = this.state.actionCounter;
    count++;
    this.setState({
      actionCounter: count
    });
  },

  _changedAction: function(event) {
    var notification = this.state.notification;
    notification.actionState = !notification.actionState;

    if (notification.actionState) {
      notification.action = {
        label: 'Action',
        callback: this._callbackForAction
      }
    } else {
      notification.action = null;
    }

    this.setState({
      notification: notification
    });
  },

  _changedActionLabel: function(event) {
    var notification = this.state.notification;
    var value = event.target.value;

    notification.action.label = value;

    this.setState({
      notification: notification
    });

  },

  getInitialState: function() {
    return {
      notification: {
        title: "Default title",
        message: 'Default message',
        level: 'error',
        position: 'tr',
        autoDismiss: 5,
        dismissible: true,
        action: null,
        actionState: false
      },
      actionCounter: 0
    }
  },
  componentDidMount: function() {
    this._notificationSystem = this.refs.notificationSystem;

  },
  render: function() {
    var notification = this.state.notification;

    var action = null;

    if (notification.actionState) {
      action = (

label

            <input className="form-control" name="label" onChange={this._changedActionLabel} type="text" value={notification.action.label} />

      );
    }

    var error = {
      position: 'hide',
      level: 'hide'
    };

    if (notification.position === "in") {
      error.position = 'text-danger';
    }

    if (notification.level === "in") {
      error.level = 'text-danger';
    }

    var printNotification = notification;

    printNotification = JSON.stringify(printNotification, null, 4);

    return

React Notification System

                      <form>

                          Title:
                          <input className="form-control" name="title" onChange={this._changed} type="text" value={notification.title} />
                          Leave empty to hide.

                          Message:
                          <input className="form-control" name="message" onChange={this._changed} type="text" value={notification.message} />

                          Position:
                          <select className="form-control" name="position" onChange={this._changed} value={notification.position}>
                            <option value="tl">Top left (tl)</option>
                            <option value="tr">Top right (tr)</option>
                            <option value="tc">Top center (tc)</option>
                            <option value="bl">Bottom left (bl)</option>
                            <option value="br">Bottom right (br)</option>
                            <option value="bc">Bottom center (bc)</option>
                            <option value="in">Invalid position</option>
                          </select>
                          Open console to see the error after creating a notification.

                          Level:
                          <select className="form-control" name="level" onChange={this._changed} value={notification.level}>
                            <option value="success">Success</option>
                            <option value="error">Error</option>
                            <option value="warning">Warning</option>
                            <option value="info">Info</option>
                            <option value="in">Invalid level</option>
                          </select>
                          Open console to see the error after creating a notification.

                          Auto Dismiss delay:

                            <input className="form-control" name="autoDismiss" onChange={this._changed} type="text" value={notification.autoDismiss} />

secs (0 means infinite)

                              <input type="checkbox" checked={notification.dismissible} onChange={this._changedDismissible} />
                              Can user dismiss

                                <input type="checkbox" checked={notification.actionState} onChange={this._changedAction} />
                                Action

                            {action}

                          <button className="btn btn-lg btn-block btn-success" onClick={this._notify}>Notify!</button>

                      </form>

Notification object

                        {printNotification}

Action click counter {this.state.actionCounter}

A simple counter for every action click.

              <NotificationSystem ref="notificationSystem" />

;
  }
});

React.render(
  React.createElement(NotificationSystemExample),
  document.getElementById('app')
);
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   xTuple Postbooks - Business Management System Framework
// Copyright: ©2011 OpenMFG LLC, d/b/a xTuple
// ==========================================================================
/*globals Postbooks XM sc_assert */

sc_require('views/carousel');
sc_require('views/tile_view');

var base03 =   "#002b36";
var base02 =   "#073642";
var base01 =   "#586e75";
var base00 =   "#657b83";
var base0 =    "#839496";
var base1 =    "#93a1a1";
var base2 =    "#eee8d5";
var base3 =    "#fdf6e3";
var yellow =   "#b58900";
var orange =   "#cb4b16";
var red =      "#dc322f";
var magenta =  "#d33682";
var violet =   "#6c71c4";
var blue =     "#268bd2";
var cyan =     "#2aa198";
var green =    "#859900";
var white =    "white";

Postbooks.ToDo = {};

Postbooks.ToDo.RenderRecordListRow = function(context, width, height, index, object, isSelected) {
  var K = Postbooks, val;
  var contact = object.getPath('contact.name');
  var assignedTo = object.getPath('assignedTo.username');

  // Rect
  context.fillStyle = isSelected? '#99CCFF' : 'white';
  context.fillRect(0, 0, width, height);

  context.strokeStyle = 'grey';
  context.lineWidth = 1;

  context.beginPath();
  context.moveTo(0, height - 0.5);
  context.lineTo(width, height - 0.5);
  context.stroke();

  context.textAlign = 'left';
  context.textBaseline = 'middle';

  // Due Date
  var dt = object.get('dueDate');
  var dateWidth = 0;
  if (dt) {
    val = dt.toLocaleDateString();
    var isDue = object.get('isActive') &&
                XT.DateTime.compareDate(dt, XT.DateTime.create()) <= 0;
    context.font = "10pt "+K.TYPEFACE;
    context.textAlign = 'right';
    context.fillStyle = isDue? XT.EXPIRED : 'black';
    context.fillText(val , 315, 15);
    dateWidth += context.measureText(val).width + 5;
  }

  // Name
  val = object.get('name');
  context.font = (val? "bold " : "italic ")+"10pt "+K.TYPEFACE;
  context.fillStyle = 'black';
  context.textAlign = 'left';
  val = val.elide(context, 295 - dateWidth);
  context.fillText(val? val : "_noName".loc(), 15, 15);

  // Description
  val = object.get('description');
  context.font = "8pt "+K.TYPEFACE;
  if (val && contact) val = val.elide(context, 290);
  context.fillText(val , 15, 35);

  // Account Name
  val = object.getPath('account.name');
  context.font = "italic 8pt "+K.TYPEFACE;
  context.fillStyle = val? 'black' : base1;
  val = val? val.elide(context, 160) : null;
  context.fillText(val? val : "_noAccountName".loc() , 325, 15);

  // Contact Name
  val = contact;
  context.font = "8pt "+K.TYPEFACE;
  context.fillStyle = val? 'black' : base1;
  val = val? val.elide(context, 160) : '';
  context.fillText(val, 325, 35);

  // Status
  val = object.get('toDoStatusString');
  context.font = (val? "" : "italic ")+"8pt "+K.TYPEFACE;
  context.fillStyle = val? 'black' : base1;
  context.fillText(val? val : "_noStage".loc(), 490, 15);

  // Assigned To
  val = assignedTo || '';
  context.font = "8pt "+K.TYPEFACE;
  context.fillStyle = 'black';
  context.fillText(val , 490, 35);

  // Priority
  val = object.getPath('priority.name');
  var emphasis = object.getPath('priority.order')<=1? "bold " : "";
  context.font = (val? emphasis : "italic ")+"8pt "+K.TYPEFACE;
  context.fillStyle = val? black : base1;
  context.fillText(val? val : "_noPriority".loc(), 565, 15);

};

Postbooks.ToDo.Tiles = function(controller, isRoot) {
  console.log('Postbooks.ToDo.Tiles()');

  var klass = XM.ToDo,
      tiles = [],
      proto = klass.prototype;
      properties = [];

  // header
  properties = 'name isActive description priority owner assignedTo'.w()
  tiles.push(Postbooks.CreateTileView(klass, controller, undefined, properties));

  // dates
  properties = 'toDoStatus startDate dueDate assignDate completeDate'.w()
  tiles.push(Postbooks.CreateTileView(klass, controller, "_status".loc(), properties));

  // notes
  properties = 'notes'.w()
  tiles.push(Postbooks.CreateTileView(klass, controller, "_notes".loc(), properties));

  return tiles;
};

<commit_msg>tweaks.<commit_after>// ==========================================================================
// Project:   xTuple Postbooks - Business Management System Framework
// Copyright: ©2011 OpenMFG LLC, d/b/a xTuple
// ==========================================================================
/*globals Postbooks XM sc_assert */

sc_require('views/carousel');
sc_require('views/tile_view');

var base03 =   "#002b36";
var base02 =   "#073642";
var base01 =   "#586e75";
var base00 =   "#657b83";
var base0 =    "#839496";
var base1 =    "#93a1a1";
var base2 =    "#eee8d5";
var base3 =    "#fdf6e3";
var yellow =   "#b58900";
var orange =   "#cb4b16";
var red =      "#dc322f";
var magenta =  "#d33682";
var violet =   "#6c71c4";
var blue =     "#268bd2";
var cyan =     "#2aa198";
var green =    "#859900";
var white =    "white";

Postbooks.ToDo = {};

Postbooks.ToDo.RenderRecordListRow = function(context, width, height, index, object, isSelected) {
  var K = Postbooks, val;
  var contact = object.getPath('contact.name');
  var assignedTo = object.getPath('assignedTo.username');

  // Rect
  context.fillStyle = isSelected? '#99CCFF' : 'white';
  context.fillRect(0, 0, width, height);

  context.strokeStyle = 'grey';
  context.lineWidth = 1;

  context.beginPath();
  context.moveTo(0, height - 0.5);
  context.lineTo(width, height - 0.5);
  context.stroke();

  context.textAlign = 'left';
  context.textBaseline = 'middle';

  // Due Date
  var dt = object.get('dueDate');
  var dateWidth = 0;
  if (dt) {
    val = dt.toLocaleDateString();
    var isDue = object.get('isActive') &&
                XT.DateTime.compareDate(dt, XT.DateTime.create()) <= 0;
    context.font = "10pt "+K.TYPEFACE;
    context.textAlign = 'right';
    context.fillStyle = isDue? XT.EXPIRED : 'black';
    context.fillText(val , 315, 15);
    dateWidth += context.measureText(val).width + 5;
  }

  // Name
  val = object.get('name');
  context.font = (val? "bold " : "italic ")+"10pt "+K.TYPEFACE;
  context.fillStyle = 'black';
  context.textAlign = 'left';
  val = val.elide(context, 295 - dateWidth);
  context.fillText(val? val : "_noName".loc(), 15, 15);

  // Description
  val = object.get('description');
  context.font = "8pt "+K.TYPEFACE;
  if (val && contact) val = val.elide(context, 290);
  context.fillText(val , 15, 35);

  // Account Name
  val = object.getPath('account.name');
  context.font = "italic 8pt "+K.TYPEFACE;
  context.fillStyle = val? 'black' : base1;
  val = val? val.elide(context, 160) : null;
  context.fillText(val? val : "_noAccountName".loc() , 325, 15);

  // Contact Name
  val = contact;
  context.font = "8pt "+K.TYPEFACE;
  context.fillStyle = val? 'black' : base1;
  val = val? val.elide(context, 160) : '';
  context.fillText(val, 325, 35);

  // Status
  val = object.get('toDoStatusString');
  context.font = (val? "" : "italic ")+"8pt "+K.TYPEFACE;
  context.fillStyle = val? 'black' : base1;
  context.fillText(val? val : "_noStage".loc(), 490, 15);

  // Assigned To
  val = assignedTo || '';
  context.font = "8pt "+K.TYPEFACE;
  context.fillStyle = 'black';
  context.fillText(val , 490, 35);

  // Priority
  val = object.getPath('priority.name');
  var emphasis = object.getPath('priority.order')<=1? "bold " : "";
  context.font = (val? emphasis : "italic ")+"8pt "+K.TYPEFACE;
  context.fillStyle = val? black : base1;
  context.fillText(val? val : "_noPriority".loc(), 565, 15);

};

Postbooks.ToDo.Tiles = function(controller, isRoot) {
  console.log('Postbooks.ToDo.Tiles()');

  var klass = XM.ToDo,
      tiles = [],
      proto = klass.prototype;
      properties = [];

  // Overview
  properties = 'name isActive description priority owner assignedTo'.w()
  tiles.push(Postbooks.CreateTileView(klass, controller, undefined, properties));

  // Dates
  properties = 'toDoStatus startDate dueDate assignDate completeDate'.w()
  tiles.push(Postbooks.CreateTileView(klass, controller, "_status".loc(), properties));

  // Notes
  properties = 'notes'.w()
  tiles.push(Postbooks.CreateTileView(klass, controller, "_notes".loc(), properties));

  return tiles;
};

<|endoftext|>