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

    /**
     * @name pc.scene.LightNode
     * @class A light.
     */
    var LightNode = function LightNode() {
        // LightNode properties (defaults)
        this._type = pc.scene.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;

        // 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._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._shadowResolution = 1024;
        this._shadowBias = -0.0005;

        this._scene = null;
    };

    // A LightNode is a specialization of a GraphNode.  So inherit...
    LightNode = pc.inherits(LightNode, pc.scene.GraphNode);

    pc.extend(LightNode.prototype, {
        /**
         * @private
         * @function
         * @name pc.scene.LightNode#_cloneInternal
         * @description Internal function for cloning the contents of a light node. Also clones
         * the properties of the superclass GraphNode.
         * @param {pc.scene.LightNode} clone The clone that will receive the copied properties.
         */
        _cloneInternal: function (clone) {
            // Clone GraphNode properties
            LightNode._super._cloneInternal.call(this, clone);

            // Clone LightNode 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());

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

            // Shadow properties
            clone.setShadowBias(this.getShadowBias());
            clone.setShadowResolution(this.getShadowResolution());
        },

        /**
         * @function
         * @name pc.scene.LightNode#clone
         * @description Duplicates a light node but does not 'deep copy' the hierarchy.
         * @returns {pc.scene.LightNode} A cloned LightNode.
         */
        clone: function () {
            var clone = new pc.scene.LightNode();
            this._cloneInternal(clone);
            return clone;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

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

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#getShadowResolution
         * @description Queries the shadow map pixel resolution for this light. Note
         * that this function is only valid for directional lights and spotlights.
         * @returns {Number} The shadow map resolution.
         */
        getShadowResolution: function () {
            return this._shadowResolution;
        },

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

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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.
         */
        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
                }
            }
        },

        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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) {
            this._shadowResolution = resolution;
        },

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

    return {
        /**
         * @enum pc.gfx.LIGHTTYPE
         * @name pc.gfx.LIGHTTYPE_DIRECTIONAL
         * @description Directional (global) light source.
         */
        LIGHTTYPE_DIRECTIONAL: 0,
        /**
         * @enum pc.gfx.LIGHTTYPE
         * @name pc.gfx.LIGHTTYPE_POINT
         * @description Point (local) light source.
         */
        LIGHTTYPE_POINT: 1,
        /**
         * @enum pc.gfx.LIGHTTYPE
         * @name pc.gfx.LIGHTTYPE_SPOT
         * @description Spot (local) light source.
         */
        LIGHTTYPE_SPOT: 2,

        LightNode: LightNode
    };
}());<commit_msg>Update the scene's shaders when we toggle shadows<commit_after>pc.extend(pc.scene, function () {

    /**
     * @name pc.scene.LightNode
     * @class A light.
     */
    var LightNode = function LightNode() {
        // LightNode properties (defaults)
        this._type = pc.scene.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;

        // 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._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._shadowResolution = 1024;
        this._shadowBias = -0.0005;

        this._scene = null;
    };

    // A LightNode is a specialization of a GraphNode.  So inherit...
    LightNode = pc.inherits(LightNode, pc.scene.GraphNode);

    pc.extend(LightNode.prototype, {
        /**
         * @private
         * @function
         * @name pc.scene.LightNode#_cloneInternal
         * @description Internal function for cloning the contents of a light node. Also clones
         * the properties of the superclass GraphNode.
         * @param {pc.scene.LightNode} clone The clone that will receive the copied properties.
         */
        _cloneInternal: function (clone) {
            // Clone GraphNode properties
            LightNode._super._cloneInternal.call(this, clone);

            // Clone LightNode 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());

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

            // Shadow properties
            clone.setShadowBias(this.getShadowBias());
            clone.setShadowResolution(this.getShadowResolution());
        },

        /**
         * @function
         * @name pc.scene.LightNode#clone
         * @description Duplicates a light node but does not 'deep copy' the hierarchy.
         * @returns {pc.scene.LightNode} A cloned LightNode.
         */
        clone: function () {
            var clone = new pc.scene.LightNode();
            this._cloneInternal(clone);
            return clone;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

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

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#getShadowResolution
         * @description Queries the shadow map pixel resolution for this light. Note
         * that this function is only valid for directional lights and spotlights.
         * @returns {Number} The shadow map resolution.
         */
        getShadowResolution: function () {
            return this._shadowResolution;
        },

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

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
            }
        },

        /**
         * @function
         * @name pc.scene.LightNode#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.
         */
        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
                }
            }
        },

        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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);
        },

        /**
         * @function
         * @name pc.scene.LightNode#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;
        },

        /**
         * @function
         * @name pc.scene.LightNode#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) {
            this._shadowResolution = resolution;
        },

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

    return {
        /**
         * @enum pc.gfx.LIGHTTYPE
         * @name pc.gfx.LIGHTTYPE_DIRECTIONAL
         * @description Directional (global) light source.
         */
        LIGHTTYPE_DIRECTIONAL: 0,
        /**
         * @enum pc.gfx.LIGHTTYPE
         * @name pc.gfx.LIGHTTYPE_POINT
         * @description Point (local) light source.
         */
        LIGHTTYPE_POINT: 1,
        /**
         * @enum pc.gfx.LIGHTTYPE
         * @name pc.gfx.LIGHTTYPE_SPOT
         * @description Spot (local) light source.
         */
        LIGHTTYPE_SPOT: 2,

        LightNode: LightNode
    };
}());<|endoftext|>


<commit_before>{% extends "autoload_js.js" %}

{% block register_mimetype %}

  var MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';
  var CLASS_NAME = 'output_bokeh rendered_html';

  /**
   * Render data to the DOM node
   */
  function render(props, node) {
    var div = document.createElement("div")
    div.innerHTML = props["data"]["div"]
    var script = document.createElement("script")
    script.textContent = props["data"]["script"]

    node.appendChild(div);
    node.appendChild(script);
  }

  /**
   * Handle when an output is cleared or removed
   */
  function handleClearOutput(event, { cell: { output_area } }) {
    /* Get rendered DOM node */
    var toinsert = output_area.element.find(CLASS_NAME.split(' ')[0]);
    /* e.g. Dispose of resources used by renderer library */
    // if (toinsert) renderLibrary.dispose(toinsert[0]);
  }

  /**
   * Handle when a new output is added
   */
  function handleAddOutput(event,  { output, output_area }) {
    /* Get rendered DOM node */
    var toinsert = output_area.element.find(CLASS_NAME.split(' ')[0]);
    /** e.g. Inject a static image representation into the mime bundle for
     *  endering on Github, etc.
     */
    // if (toinsert) {
    //   renderLibrary.toPng(toinsert[0]).then(url => {
    //     const data = url.split(',')[1];
    //     output_area.outputs
    //       .filter(output => output.data[MIME_TYPE])
    //       .forEach(output => {
    //         output.data['image/png'] = data;
    //       });
    //   });
    // }
  }

  function register_renderer(notebook, OutputArea) {

    // get OutputArea instance
    var code_cell = notebook.get_cells().reduce(function(result, cell) { return cell.output_area ? cell : result })
    var output_area = code_cell.output_area

    // function to render output of bk mime renderer
    function append_mime(data, metadata, element) {
      // create a DOM node to render to
      var toinsert = this.create_output_subarea(
        metadata,
        CLASS_NAME,
        MIME_TYPE
      );
      this.keyboard_manager.register_events(toinsert);
      // Render to node
      var props = {data, metadata: metadata[MIME_TYPE]}
      render(props, toinsert[0])
      element.append(toinsert)
      return toinsert;
    }

    /* Handle when an output is cleared or removed */
    output_area.events.on('clear_output.CodeCell', handleClearOutput);

    /* Handle when a new output is added */
    output_area.events.on('output_added.OutputArea', handleAddOutput);

    // renderer priority
    /* ...or just insert it at the top */
    var index = 0;

    /**
     * Register the mime type and append_mime function with output_area
     */
    OutputArea.prototype.register_mime_type(MIME_TYPE, append_mime, {
      /* Is output safe? */
      safe: true,
      /* Index of renderer in `output_area.display_order` */
      index: index
    });
  }

  // do the thing
  register_renderer(root.Jupyter.notebook, root.Jupyter.OutputArea)

{% endblock %}

{% block autoload_init %}
  if (typeof (root._bokeh_timeout) === "undefined" || force === true) {
    root._bokeh_timeout = Date.now() + {{ timeout|default(0)|json }};
    root._bokeh_failed_load = false;
  }

  var NB_LOAD_WARNING = {'data': {'text/html':
     "
\n"+
     "
\n"+
     "BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \n"+
     "may be due to a slow or bad network connection. Possible fixes:\n"+
     "
\n"+
     "
\n"+
     "
re-rerun `output_notebook()` to attempt to load from CDN again, or
\n"+
     "
use INLINE resources instead, as so:
\n"+
     "
\n"+
     "\n"+
     "from bokeh.resources import INLINE\n"+
     "output_notebook(resources=INLINE)\n"+
     "\n"+
     "
"}};

  function display_loaded() {
    if (root.Bokeh !== undefined) {
      var el = document.getElementById({{ elementid|json }});
      el.textContent = "BokehJS " + Bokeh.version + " successfully loaded.";
    } else if (Date.now() < root._bokeh_timeout) {
      setTimeout(display_loaded, 100)
    }
  }

  {%- if comms_target -%}
  if ((root.Jupyter !== undefined) && Jupyter.notebook.kernel) {
    comm_manager = Jupyter.notebook.kernel.comm_manager
    comm_manager.register_target({{ comms_target|json }}, function () {});
  }
  {%- endif -%}
{% endblock %}

{% block run_inline_js %}
    if ((root.Bokeh !== undefined) || (force === true)) {
      for (var i = 0; i < inline_js.length; i++) {
        inline_js[i].call(root, root.Bokeh);
      }
      {%- if elementid -%}
      if (force === true) {
        display_loaded();
      }
      {%- endif -%}
    } else if (Date.now() < root._bokeh_timeout) {
      setTimeout(run_inline_js, 100);
    } else if (!root._bokeh_failed_load) {
      console.log("Bokeh: BokehJS failed to load within specified timeout.");
      root._bokeh_failed_load = true;
    } else if (force !== true) {
      var cell = $(document.getElementById({{ elementid|json }})).parents('.cell').data().cell;
      cell.output_area.append_execute_result(NB_LOAD_WARNING)
    }
{% endblock %}
<commit_msg>Don't register mimetype if not in classic notebook or already registered<commit_after>{% extends "autoload_js.js" %}

{% block register_mimetype %}

  var MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';
  var CLASS_NAME = 'output_bokeh rendered_html';

  /**
   * Render data to the DOM node
   */
  function render(props, node) {
    var div = document.createElement("div")
    div.innerHTML = props["data"]["div"]
    var script = document.createElement("script")
    script.textContent = props["data"]["script"]

    node.appendChild(div);
    node.appendChild(script);
  }

  /**
   * Handle when an output is cleared or removed
   */
  function handleClearOutput(event, { cell: { output_area } }) {
    /* Get rendered DOM node */
    var toinsert = output_area.element.find(CLASS_NAME.split(' ')[0]);
    /* e.g. Dispose of resources used by renderer library */
    // if (toinsert) renderLibrary.dispose(toinsert[0]);
  }

  /**
   * Handle when a new output is added
   */
  function handleAddOutput(event,  { output, output_area }) {
    /* Get rendered DOM node */
    var toinsert = output_area.element.find(CLASS_NAME.split(' ')[0]);
    /** e.g. Inject a static image representation into the mime bundle for
     *  endering on Github, etc.
     */
    // if (toinsert) {
    //   renderLibrary.toPng(toinsert[0]).then(url => {
    //     const data = url.split(',')[1];
    //     output_area.outputs
    //       .filter(output => output.data[MIME_TYPE])
    //       .forEach(output => {
    //         output.data['image/png'] = data;
    //       });
    //   });
    // }
  }

  function register_renderer(notebook, OutputArea) {

    // get OutputArea instance
    var code_cell = notebook.get_cells().reduce(function(result, cell) { return cell.output_area ? cell : result })
    var output_area = code_cell.output_area

    // function to render output of bk mime renderer
    function append_mime(data, metadata, element) {
      // create a DOM node to render to
      var toinsert = this.create_output_subarea(
        metadata,
        CLASS_NAME,
        MIME_TYPE
      );
      this.keyboard_manager.register_events(toinsert);
      // Render to node
      var props = {data, metadata: metadata[MIME_TYPE]}
      render(props, toinsert[0])
      element.append(toinsert)
      return toinsert;
    }

    /* Handle when an output is cleared or removed */
    output_area.events.on('clear_output.CodeCell', handleClearOutput);

    /* Handle when a new output is added */
    output_area.events.on('output_added.OutputArea', handleAddOutput);

    // renderer priority
    /* ...or just insert it at the top */
    var index = 0;

    /**
     * Register the mime type and append_mime function with output_area
     */
    OutputArea.prototype.register_mime_type(MIME_TYPE, append_mime, {
      /* Is output safe? */
      safe: true,
      /* Index of renderer in `output_area.display_order` */
      index: index
    });
  }

  // do the thing
  var OutputArea = root.Jupyter.OutputArea
  if ((root.Jupyter !== undefined) && (!OutputArea.prototype.mime_types().includes(MIME_TYPE))) {
    register_renderer(root.Jupyter.notebook, OutputArea)
  }

{% endblock %}

{% block autoload_init %}
  if (typeof (root._bokeh_timeout) === "undefined" || force === true) {
    root._bokeh_timeout = Date.now() + {{ timeout|default(0)|json }};
    root._bokeh_failed_load = false;
  }

  var NB_LOAD_WARNING = {'data': {'text/html':
     "
\n"+
     "
\n"+
     "BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \n"+
     "may be due to a slow or bad network connection. Possible fixes:\n"+
     "
\n"+
     "
\n"+
     "
re-rerun `output_notebook()` to attempt to load from CDN again, or
\n"+
     "
use INLINE resources instead, as so:
\n"+
     "
\n"+
     "\n"+
     "from bokeh.resources import INLINE\n"+
     "output_notebook(resources=INLINE)\n"+
     "\n"+
     "
"}};

  function display_loaded() {
    if (root.Bokeh !== undefined) {
      var el = document.getElementById({{ elementid|json }});
      el.textContent = "BokehJS " + Bokeh.version + " successfully loaded.";
    } else if (Date.now() < root._bokeh_timeout) {
      setTimeout(display_loaded, 100)
    }
  }

  {%- if comms_target -%}
  if ((root.Jupyter !== undefined) && Jupyter.notebook.kernel) {
    comm_manager = Jupyter.notebook.kernel.comm_manager
    comm_manager.register_target({{ comms_target|json }}, function () {});
  }
  {%- endif -%}
{% endblock %}

{% block run_inline_js %}
    if ((root.Bokeh !== undefined) || (force === true)) {
      for (var i = 0; i < inline_js.length; i++) {
        inline_js[i].call(root, root.Bokeh);
      }
      {%- if elementid -%}
      if (force === true) {
        display_loaded();
      }
      {%- endif -%}
    } else if (Date.now() < root._bokeh_timeout) {
      setTimeout(run_inline_js, 100);
    } else if (!root._bokeh_failed_load) {
      console.log("Bokeh: BokehJS failed to load within specified timeout.");
      root._bokeh_failed_load = true;
    } else if (force !== true) {
      var cell = $(document.getElementById({{ elementid|json }})).parents('.cell').data().cell;
      cell.output_area.append_execute_result(NB_LOAD_WARNING)
    }
{% endblock %}
<|endoftext|>


<commit_before>import * as types from '../constants/ActionTypes';

export function loginRequest(id, credentials) {
    return { type: types.LOGIN_REQUEST, id, credentials};
}

export function loginSuccess(id, message) {
    return { type: types.LOGIN_SUCCESS, id, message };
}

export function loginFailure(id, message) {
    return { type: types.LOGIN_FAILURE, id, message };
}

export function fetchFilesRequest(id, dirpath) {
    return { type: types.FETCH_FILES_REQUEST, id, dirpath};
}

export function fetchFilesSuccess(id, files) {
    return { type: types.FETCH_FILES_SUCCESS, id, files };
}

export function fetchFilesFailure(id, message) {
    return { type: types.FETCH_FILES_FAILURE, id, message };
}

<commit_msg>Renamed action types to actions<commit_after>import * as actions from '../constants/ActionTypes';

export function loginRequest(id, credentials) {
    return { type: actions.LOGIN_REQUEST, id, credentials};
}

export function loginSuccess(id, message) {
    return { type: actions.LOGIN_SUCCESS, id, message };
}

export function loginFailure(id, message) {
    return { type: actions.LOGIN_FAILURE, id, message };
}

export function fetchFilesRequest(id, dirpath) {
    return { type: actions.FETCH_FILES_REQUEST, id, dirpath};
}

export function fetchFilesSuccess(id, files) {
    return { type: actions.FETCH_FILES_SUCCESS, id, files };
}

export function fetchFilesFailure(id, message) {
    return { type: actions.FETCH_FILES_FAILURE, id, message };
}

<|endoftext|>


<commit_before>import React, {PropTypes as T} from 'react'
import {unnest, last} from 'ramda'

const MONO_FONT = 'Menlo, Monaco, Consolas, "Lucida Console", monospace'
const SERIF_FONT = '"Lucida Grande", Helvetica, arial, sans-serif'

const styles = {
  metaWrap({fullWidth}) {
    return {
      padding: fullWidth ? '0 10px' : 0,
    }
  },
  location: {
    fontSize: 18,
    fontFamily: SERIF_FONT,
    color: '#aaa',
    marginBottom: 10,
  },
  locationItem({last}) {
    return {
      color: last ? '#000' : 'inerit',
    }
  },
  locationDel: {
    margin: '0 .2em',
    color: '#aaa',
  },
  import: {
    fontFamily: MONO_FONT,
    fontSize: 14,
    marginBottom: 10,
    color: '#aaa',
    float: 'right',
  },
  description: {
    maxWidth: 600,
    marginBottom: 10,
    fontFamily: SERIF_FONT,
    fontSize: 14,
  },
  files({fullWidth}) {
    return {
      margin: fullWidth ? '20px 10px' : '20px 0',
    }
  },
  fileName: {
    fontFamily: SERIF_FONT,
    fontSize: 14,
    fontWeight: 'bold',
  },
  fileContnet: {
    fontFamily: MONO_FONT,
    fontSize: 12,
    margin: '5px 0 20px 0',
    background: '#f5fef5',
    padding: 5,
    borderRadius: 3,
    overflow: 'auto',
  },
}

function locationItem(name, i, {length}) {
  const last = length === i + 1
  return [
    <span key={`${i}item`} style={styles.locationItem({last})}>{name},
    !last && <span key={`${i}del`} style={styles.locationDel}>/,
  ]
}

export default React.createClass({

  propTypes: {
    demo: T.node,
    fullWidth: T.bool,
    location: T.array.isRequired,
    importPath: T.string,
    description: T.node,
    files: T.arrayOf(T.shape({name: T.string.isRequired, content: T.string.isRequired}).isRequired),
  },

  renderFile(file, index) {
    return

{file.name}

{file.content}

  },

  render() {
    const {demo, fullWidth, location, importPath, description, files} = this.props
    const name = last(location)
    return

          import {name} from '{importPath}'

          {unnest(location.map(locationItem))}

          {description}

        {demo}

      {
        files &&

          {files.map(this.renderFile)}

      }

  },

})
<commit_msg>tweak styles<commit_after>import React, {PropTypes as T} from 'react'
import {unnest, last} from 'ramda'

const MONO_FONT = 'Menlo, Monaco, Consolas, "Lucida Console", monospace'
const SERIF_FONT = '"Lucida Grande", Helvetica, arial, sans-serif'

const styles = {
  metaWrap({fullWidth}) {
    return {
      padding: fullWidth ? '0 10px' : 0,
    }
  },
  location: {
    fontSize: 18,
    fontFamily: SERIF_FONT,
    color: '#aaa',
    marginBottom: 10,
  },
  locationItem({last}) {
    return {
      color: last ? '#000' : 'inerit',
    }
  },
  locationDel: {
    margin: '0 .2em',
    color: '#aaa',
  },
  import: {
    fontFamily: MONO_FONT,
    fontSize: 14,
    marginBottom: 10,
    color: '#aaa',
    float: 'right',
  },
  description: {
    maxWidth: 600,
    marginBottom: 10,
    fontFamily: SERIF_FONT,
    fontSize: 14,
  },
  files({fullWidth}) {
    return {
      margin: fullWidth ? '20px 10px' : '20px 0',
    }
  },
  fileName: {
    fontFamily: SERIF_FONT,
    fontSize: 14,
    fontWeight: 'bold',
  },
  fileContnet: {
    fontFamily: MONO_FONT,
    fontSize: 11,
    margin: '5px 0 20px 0',
    background: '#d7e5ec',
    padding: 5,
    borderRadius: 3,
    overflow: 'auto',
  },
}

function locationItem(name, i, {length}) {
  const last = length === i + 1
  return [
    <span key={`${i}item`} style={styles.locationItem({last})}>{name},
    !last && <span key={`${i}del`} style={styles.locationDel}>/,
  ]
}

export default React.createClass({

  propTypes: {
    demo: T.node,
    fullWidth: T.bool,
    location: T.array.isRequired,
    importPath: T.string,
    description: T.node,
    files: T.arrayOf(T.shape({name: T.string.isRequired, content: T.string.isRequired}).isRequired),
  },

  renderFile(file, index) {
    return

{file.name}

{file.content}

  },

  render() {
    const {demo, fullWidth, location, importPath, description, files} = this.props
    const name = last(location)
    return

          import {name} from '{importPath}'

          {unnest(location.map(locationItem))}

          {description}

        {demo}

      {
        files &&

          {files.map(this.renderFile)}

      }

  },

})
<|endoftext|>


<commit_before>
function db() { }

db.open = function() {
    this.DB = openDatabase('TabSense', '1.0', 'TabSense', 5*1024*1024);
    this.DB.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS '+
            'Window(id INTEGER PRIMARY KEY ASC, '+
            'wid INTEGER, title TEXT, saved INTEGER DEFAULT 0)',
            [], db.onSuccess, db.onError);
    });
    this.DB.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS '+
            'Tab(id INTEGER PRIMARY KEY ASC, tid INTEGER, title TEXT, '+
            'url TEXT, faviconurl TEXT, wid INTEGER, parent INTEGER DEFAULT 0, '+
            'idx INTEGER, depth INTEGER DEFAULT 0, status TEXT, saved INTEGER DEFAULT 0)',
            [], db.onSuccess, db.onError);
    });
}

db.clear = function() {
    this.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Window', [], db.onSuccess, db.onError);
    });
    this.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Tab', [], db.onSuccess, db.onError);
    });
}

db.onError = function(tx, e) {
    console.error('TabSense DB Error : '+e.message);
}

db.onSuccess = function(tx, r) {
    //console.debug(r);
}

db.put = function(obj, successCb) {
    var onSuccess = successCb || db.onSuccess;
    if(obj.constructor == db.window) {
        var win = obj;
        this.DB.transaction(function(tx) {
            tx.executeSql(
                'INSERT INTO Window(wid, title, saved) VALUES (?,?,?)',
                [win.wid, win.title, 0],
                onSuccess,
                db.onError);
        });
    } else if(obj.constructor == db.tab) {
        var tab = obj;
        this.DB.transaction(function(tx) {
            tx.executeSql('INSERT INTO Tab(tid, title, url, faviconurl, '+
                'wid, parent, idx, depth) VALUES (?,?,?,?,?,?,?,?)',
                [ tab.tid, tab.title, tab.url, tab.faviconurl, tab.wid,
                    tab.parent, tab.index, tab.depth ],
                onSuccess,
                db.onError);
        });
    } else {
        alert('Invalid object to save');
    }
}

db.window = function(wid, title) {
    this.wid = wid;
    this.title = title;
}

db.window.get = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('SELECT * FROM Window '+condition, [],
            onSuccess, db.onError);
    });
}

db.window.del = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Window '+condition, [],
            onSuccess, db.onError);
    });
}

db.window.update = function(set, condition, data, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('UPDATE Window SET '+set+condition, data,
            onSuccess, db.onError);
    });
}

db.tab = function(tid, title, url, faviconurl, index, wid, parent, depth) {
    this.tid = tid;
    this.title = title;
    this.url = url;
    this.faviconurl = faviconurl;
    this.index = index;
    this.wid = wid;
    this.parent = parent || 0;
    this.depth = depth || 0;
}

db.tab.get = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('SELECT * FROM Tab '+condition, [],
            onSuccess, db.onError);
    });
}

db.tab.del = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Tab '+condition, [],
            onSuccess, db.onError);
    });
}

db.tab.update = function(set, condition, data, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('UPDATE Tab SET '+set+condition, data,
            onSuccess, db.onError);
    });
}
<commit_msg>ensures the saved windows survive across browser restart<commit_after>
function db() { }

db.open = function() {
    this.DB = openDatabase('TabSense', '1.0', 'TabSense', 5*1024*1024);
    this.DB.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS '+
            'Window(id INTEGER PRIMARY KEY ASC, '+
            'wid INTEGER, title TEXT, saved INTEGER DEFAULT 0)',
            [], db.onSuccess, db.onError);
    });
    this.DB.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS '+
            'Tab(id INTEGER PRIMARY KEY ASC, tid INTEGER, title TEXT, '+
            'url TEXT, faviconurl TEXT, wid INTEGER, parent INTEGER DEFAULT 0, '+
            'idx INTEGER, depth INTEGER DEFAULT 0, status TEXT, saved INTEGER DEFAULT 0)',
            [], db.onSuccess, db.onError);
    });
}

db.clear = function() {
    this.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Window WHERE saved = 0', [], db.onSuccess, db.onError);
    });
    this.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Tab WHERE saved = 0', [], db.onSuccess, db.onError);
    });
}

db.onError = function(tx, e) {
    console.error('TabSense DB Error : '+e.message);
}

db.onSuccess = function(tx, r) {
    //console.debug(r);
}

db.put = function(obj, successCb) {
    var onSuccess = successCb || db.onSuccess;
    if(obj.constructor == db.window) {
        var win = obj;
        this.DB.transaction(function(tx) {
            tx.executeSql(
                'INSERT INTO Window(wid, title, saved) VALUES (?,?,?)',
                [win.wid, win.title, 0],
                onSuccess,
                db.onError);
        });
    } else if(obj.constructor == db.tab) {
        var tab = obj;
        this.DB.transaction(function(tx) {
            tx.executeSql('INSERT INTO Tab(tid, title, url, faviconurl, '+
                'wid, parent, idx, depth) VALUES (?,?,?,?,?,?,?,?)',
                [ tab.tid, tab.title, tab.url, tab.faviconurl, tab.wid,
                    tab.parent, tab.index, tab.depth ],
                onSuccess,
                db.onError);
        });
    } else {
        alert('Invalid object to save');
    }
}

db.window = function(wid, title) {
    this.wid = wid;
    this.title = title;
}

db.window.get = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('SELECT * FROM Window '+condition, [],
            onSuccess, db.onError);
    });
}

db.window.del = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Window '+condition, [],
            onSuccess, db.onError);
    });
}

db.window.update = function(set, condition, data, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('UPDATE Window SET '+set+condition, data,
            onSuccess, db.onError);
    });
}

db.tab = function(tid, title, url, faviconurl, index, wid, parent, depth) {
    this.tid = tid;
    this.title = title;
    this.url = url;
    this.faviconurl = faviconurl;
    this.index = index;
    this.wid = wid;
    this.parent = parent || 0;
    this.depth = depth || 0;
}

db.tab.get = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('SELECT * FROM Tab '+condition, [],
            onSuccess, db.onError);
    });
}

db.tab.del = function(condition, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('DELETE FROM Tab '+condition, [],
            onSuccess, db.onError);
    });
}

db.tab.update = function(set, condition, data, onSuccess) {
    db.DB.transaction(function(tx) {
        tx.executeSql('UPDATE Tab SET '+set+condition, data,
            onSuccess, db.onError);
    });
}
<|endoftext|>


<commit_before>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var params = null;

(function() {
  // List of all events and whether or not we should capture them
  var events = {
    'Event': {
      //'abort': true,
      'blur': true,
      'change': true,  // change event occurs before focus is lost (blur)
      'copy': true,
      'cut': true,
      'error': false,
      'focus': true,
      'input': true,  // input event occurs on every keystroke (or cut / paste)
      'load': false,
      'paste': true,
      'reset': true,
      'resize': false,
      'scroll': false,
      'select': true,
      'submit': true,
      'unload': false
    },
    'MouseEvent': {
      'click': true,
      'dblclick': true,
      'mousedown': true,
      'mousemove': false,
      'mouseout': false,
      'mouseover': false,
      'mouseup': true,
      'mousewheel': false
  //    'dragenter': false,
  //    'dragleave': false,
    },
    'KeyboardEvent': {
      'keydown': true,
      'keyup': true,
      'keypress': true
    },
    'TextEvent': {
      'textInput': true  // similar to input event, doesn trigger with cp/pst
    }
  };

  var defaultProps = {
    'Event': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'timeStamp': 0
    },
    'MouseEvent': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'detail': 0,
      'screenX': 0,
      'screenY': 0,
      'clientX': 0,
      'clientY': 0,
      'ctrlKey': false,
      'altKey': false,
      'shiftKey': false,
      'metaKey': false,
      'button': 0,
      'timeStamp': 0
    },
    'KeyboardEvent': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'ctrlKey': false,
      'altKey': false,
      'shiftKey': false,
      'metaKey': false,
      'keyCode': 0,
      'charCode': 0,
      'timeStamp': 0
    },
    'TextEvent': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'data': '',
      'inputMethod': 0,
      'locale': '',
      'timeStamp': 0
    }
  };

  params = {
    user: 'sbarman',
    simultaneous: false,
    timing: 0,
    events: events,
    defaultProps: defaultProps,
    logging: {
      level: 1,
      enabled: ['ports', 'event', 'record', 'replay', 'script', 'background',
                'content', 'synthesis']
    },
    synthesis: {
      enabled: true,
      omittedProps: ['innerHTML', 'outerHTML', 'innerText', 'outerText',
          'textContent', 'className', 'childElementCount', 'scrollHeight',
          'scrollWidth', 'clientHeight', 'clientWidth', 'clientTop',
          'clientLeft', 'offsetHeight', 'offsetWidth', 'offsetTop',
          'offsetLeft', "text", "valueAsNumber"],
      depth: 2,
      optimization: 2
    },
    recording: {
      allEventProps: true
    },
    replaying: {
      saveReplay: false,
      enableAlerts: false
    },
    server: 'http://sbarman.webfactional.com/api/'
    //server: "http://127.0.0.1:8000/api/",
    benchmarking: {
      timeout: 120,
    },
  };

})();
<commit_msg>Fixed missing comma<commit_after>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var params = null;

(function() {
  // List of all events and whether or not we should capture them
  var events = {
    'Event': {
      //'abort': true,
      'blur': true,
      'change': true,  // change event occurs before focus is lost (blur)
      'copy': true,
      'cut': true,
      'error': false,
      'focus': true,
      'input': true,  // input event occurs on every keystroke (or cut / paste)
      'load': false,
      'paste': true,
      'reset': true,
      'resize': false,
      'scroll': false,
      'select': true,
      'submit': true,
      'unload': false
    },
    'MouseEvent': {
      'click': true,
      'dblclick': true,
      'mousedown': true,
      'mousemove': false,
      'mouseout': false,
      'mouseover': false,
      'mouseup': true,
      'mousewheel': false
  //    'dragenter': false,
  //    'dragleave': false,
    },
    'KeyboardEvent': {
      'keydown': true,
      'keyup': true,
      'keypress': true
    },
    'TextEvent': {
      'textInput': true  // similar to input event, doesn trigger with cp/pst
    }
  };

  var defaultProps = {
    'Event': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'timeStamp': 0
    },
    'MouseEvent': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'detail': 0,
      'screenX': 0,
      'screenY': 0,
      'clientX': 0,
      'clientY': 0,
      'ctrlKey': false,
      'altKey': false,
      'shiftKey': false,
      'metaKey': false,
      'button': 0,
      'timeStamp': 0
    },
    'KeyboardEvent': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'ctrlKey': false,
      'altKey': false,
      'shiftKey': false,
      'metaKey': false,
      'keyCode': 0,
      'charCode': 0,
      'timeStamp': 0
    },
    'TextEvent': {
      'type': true,
      'bubbles': true,
      'cancelable': true,
      'data': '',
      'inputMethod': 0,
      'locale': '',
      'timeStamp': 0
    }
  };

  params = {
    user: 'sbarman',
    simultaneous: false,
    timing: 0,
    events: events,
    defaultProps: defaultProps,
    logging: {
      level: 1,
      enabled: ['ports', 'event', 'record', 'replay', 'script', 'background',
                'content', 'synthesis']
    },
    synthesis: {
      enabled: true,
      omittedProps: ['innerHTML', 'outerHTML', 'innerText', 'outerText',
          'textContent', 'className', 'childElementCount', 'scrollHeight',
          'scrollWidth', 'clientHeight', 'clientWidth', 'clientTop',
          'clientLeft', 'offsetHeight', 'offsetWidth', 'offsetTop',
          'offsetLeft', "text", "valueAsNumber"],
      depth: 2,
      optimization: 2
    },
    recording: {
      allEventProps: true
    },
    replaying: {
      saveReplay: false,
      enableAlerts: false
    },
    server: 'http://sbarman.webfactional.com/api/',
    //server: "http://127.0.0.1:8000/api/",
    benchmarking: {
      timeout: 120,
    },
  };

})();
<|endoftext|>


<commit_before>import Node from './Node';
import ParentNode from './ParentNode';
import Comment from './Comment';
import DocumentFragment from './DocumentFragment';
import HTMLElement from './HTMLElement';
import Text from './Text';
import Url from './utils/Url';

// HTML Elements
import HTMLDocumentElement from './HTMLElement/elements/HTMLDocumentElement';
import HTMLOptionElement from './HTMLElement/elements/HTMLOptionElement';
import HTMLSelectElement from './HTMLElement/elements/HTMLSelectElement';
import HTMLTableCaptionElement from './HTMLElement/elements/HTMLTableCaptionElement';
import HTMLMetaElement from './HTMLElement/elements/HTMLMetaElement';
import HTMLTableElement from './HTMLElement/elements/HTMLTableElement';
import HTMLTableRowElement from './HTMLElement/elements/HTMLTableRowElement';
import HTMLTableSectionElement from './HTMLElement/elements/HTMLTableSectionElement';
import HTMLAnchorElement from './HTMLElement/elements/HTMLAnchorElement';

const elementClasses = new Map([
    ['html', HTMLDocumentElement],
    ['caption', HTMLTableCaptionElement],
    ['meta', HTMLMetaElement],
    ['option', HTMLOptionElement],
    ['table', HTMLTableElement],
    ['thead', HTMLTableSectionElement],
    ['tfoot', HTMLTableSectionElement],
    ['tfoot', HTMLTableSectionElement],
    ['tr', HTMLTableRowElement],
    ['select', HTMLSelectElement],
    ['a', HTMLAnchorElement],
]);

/**
 * @see https://developer.mozilla.org/en/docs/Web/API/Document
 */
export default class Document extends ParentNode {
    constructor() {
        super();
        /**
         * @type {HTMLElement}
         */
        this._documentElement = this.createElement('html');
        this.appendChild(this._documentElement);

        this._location = new Url('about:blank');
        this._ownerDocument = this;
    }

    /**
     * Creates a new {@link Comment}.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createComment
     *
     * @param {string} data
     * @return {Comment}
    */
    createComment(data) {
        let comment = new Comment(data);
        comment._ownerDocument = this;
        return comment;
    }

    /**
     * Creates a new empty {@link DocumentFragment}.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createDocumentFragment
     *
     * @return {DocumentFragment}
    */
    createDocumentFragment() {
        let fragment = new DocumentFragment();
        fragment._ownerDocument = this;
        return fragment;
    }

    /**
     * Creates a new element with the given tag name.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createElement
     *
     * @param {string} name
     * @return {HTMLElement}
    */
    createElement(name) {
        name = name.toLowerCase();
        const ElementClass = elementClasses.get(name) || HTMLElement;
        let element = new ElementClass();

        element._ownerDocument = this;

        if (!element.nodeName) {
            element.nodeName = name;
        }

        return element;
    }

    /**
     * Creates a text node.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createTextNode
     *
     * @param {string} textContent
     * @return {Text}
    */
    createTextNode(textContent) {
        let text = new Text(textContent);
        text._ownerDocument = this;
        return text;
    }

    /**
     * Returns a reference to the element by its ID.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.getElementById
     *
     * @param {string} id case-sensitive string representing the unique ID of the element being sought
     * @return {Element} reference to an Element, or null if an element with the specified ID is not in the document.
     */
    getElementById(id) {
        return this.documentElement.getElementById(id);
    }

    /**
     * Returns an HTMLCollection of elements with the given tag name.
     * The complete document is searched, including the root node.
     * The returned HTMLCollection is live, meaning that it updates itself automatically to stay in sync
     * with the DOM treewithout having to call document.getElementsByTagName() again.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.getElementsByTagName
     *
     * @param {string} tagName
     * @return {HTMLCollection}
     */
    getElementsByTagName(tagName, _array) {
        return this.documentElement.getElementsByTagName(tagName, _array);
    }

    getElementsByClassName(className) {
        throw new Error('Not implemented');
    }

    /**
     * Returns the first element within the document (using depth-first pre-order traversal of the document's nodes|by
     * first element in document markup and iterating through sequential nodes by order of amount of child nodes)
     * that matches the specified group of selectors.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
     *
     * @param {string} selector
     * @return {Element}
     */
    querySelector(selector) {
        return this.documentElement.querySelector(selector);
    }

    /**
     * Returns a list of the elements within the document (using depth-first pre-order traversal of the document's
     * nodes) that match the specified group of selectors. The object returned is a NodeList.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
     *
     * @param {string} selector
     * @return {NodeList}
     */
    querySelectorAll(selector) {
        return this.documentElement.querySelectorAll(selector);
    }

    /**
     * textContent returns null if the element is a document, a document type, or a notation.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent
     */
    get textContent() {
        return null;
    }

    get documentElement() {
        return this._documentElement;
    }

    get head() {
        let head = this._documentElement.getElementsByTagName('head').shift();
        if (!head) {
            head = this.createElement('head');
            this._documentElement.insertBefore(head, this.body);
        }

        return head;
    }

    get body() {
        let body = this._documentElement.getElementsByTagName('body').shift();
        if (!body) {
            body = this.createElement('body');
            this._documentElement.appendChild(body);
        }

        return body;
    }

    set body(body) {
        let current = this._documentElement.getElementsByTagName('body').shift();
        if (current) {
            this._documentElement.replaceChild(body, current);
        } else {
            this._documentElement.appendChild(body);
        }
    }

    get location() {
        return this._location;
    }

    set location(value) {
        this._location.href = value;
    }

    /**
     * @param {Node} child
     * @return {Node}
     */
    appendChild(child) {
        child = super.appendChild(child);
        if (child.nodeName === 'html') {
            this._documentElement = child;
        }

        return child;
    }
}

/**
 * @constant {number} Comment#nodeType
 */
Object.defineProperty(Document.prototype, 'nodeType', { value: Node.DOCUMENT_NODE });
<commit_msg>document: use _childNodeFind instead of getElementsByTagName (#53)<commit_after>import Node from './Node';
import ParentNode from './ParentNode';
import Comment from './Comment';
import DocumentFragment from './DocumentFragment';
import HTMLElement from './HTMLElement';
import Text from './Text';
import Url from './utils/Url';

// HTML Elements
import HTMLDocumentElement from './HTMLElement/elements/HTMLDocumentElement';
import HTMLOptionElement from './HTMLElement/elements/HTMLOptionElement';
import HTMLSelectElement from './HTMLElement/elements/HTMLSelectElement';
import HTMLTableCaptionElement from './HTMLElement/elements/HTMLTableCaptionElement';
import HTMLMetaElement from './HTMLElement/elements/HTMLMetaElement';
import HTMLTableElement from './HTMLElement/elements/HTMLTableElement';
import HTMLTableRowElement from './HTMLElement/elements/HTMLTableRowElement';
import HTMLTableSectionElement from './HTMLElement/elements/HTMLTableSectionElement';
import HTMLAnchorElement from './HTMLElement/elements/HTMLAnchorElement';

const elementClasses = new Map([
    ['html', HTMLDocumentElement],
    ['caption', HTMLTableCaptionElement],
    ['meta', HTMLMetaElement],
    ['option', HTMLOptionElement],
    ['table', HTMLTableElement],
    ['thead', HTMLTableSectionElement],
    ['tfoot', HTMLTableSectionElement],
    ['tfoot', HTMLTableSectionElement],
    ['tr', HTMLTableRowElement],
    ['select', HTMLSelectElement],
    ['a', HTMLAnchorElement],
]);

/**
 * @see https://developer.mozilla.org/en/docs/Web/API/Document
 */
export default class Document extends ParentNode {
    constructor() {
        super();
        /**
         * @type {HTMLElement}
         */
        this._documentElement = this.createElement('html');
        this.appendChild(this._documentElement);

        this._location = new Url('about:blank');
        this._ownerDocument = this;
    }

    /**
     * Creates a new {@link Comment}.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createComment
     *
     * @param {string} data
     * @return {Comment}
    */
    createComment(data) {
        let comment = new Comment(data);
        comment._ownerDocument = this;
        return comment;
    }

    /**
     * Creates a new empty {@link DocumentFragment}.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createDocumentFragment
     *
     * @return {DocumentFragment}
    */
    createDocumentFragment() {
        let fragment = new DocumentFragment();
        fragment._ownerDocument = this;
        return fragment;
    }

    /**
     * Creates a new element with the given tag name.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createElement
     *
     * @param {string} name
     * @return {HTMLElement}
    */
    createElement(name) {
        name = name.toLowerCase();
        const ElementClass = elementClasses.get(name) || HTMLElement;
        let element = new ElementClass();

        element._ownerDocument = this;

        if (!element.nodeName) {
            element.nodeName = name;
        }

        return element;
    }

    /**
     * Creates a text node.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.createTextNode
     *
     * @param {string} textContent
     * @return {Text}
    */
    createTextNode(textContent) {
        let text = new Text(textContent);
        text._ownerDocument = this;
        return text;
    }

    /**
     * Returns a reference to the element by its ID.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.getElementById
     *
     * @param {string} id case-sensitive string representing the unique ID of the element being sought
     * @return {Element} reference to an Element, or null if an element with the specified ID is not in the document.
     */
    getElementById(id) {
        return this.documentElement.getElementById(id);
    }

    /**
     * Returns an HTMLCollection of elements with the given tag name.
     * The complete document is searched, including the root node.
     * The returned HTMLCollection is live, meaning that it updates itself automatically to stay in sync
     * with the DOM treewithout having to call document.getElementsByTagName() again.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document.getElementsByTagName
     *
     * @param {string} tagName
     * @return {HTMLCollection}
     */
    getElementsByTagName(tagName, _array) {
        return this.documentElement.getElementsByTagName(tagName, _array);
    }

    getElementsByClassName(className) {
        throw new Error('Not implemented');
    }

    /**
     * Returns the first element within the document (using depth-first pre-order traversal of the document's nodes|by
     * first element in document markup and iterating through sequential nodes by order of amount of child nodes)
     * that matches the specified group of selectors.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
     *
     * @param {string} selector
     * @return {Element}
     */
    querySelector(selector) {
        return this.documentElement.querySelector(selector);
    }

    /**
     * Returns a list of the elements within the document (using depth-first pre-order traversal of the document's
     * nodes) that match the specified group of selectors. The object returned is a NodeList.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
     *
     * @param {string} selector
     * @return {NodeList}
     */
    querySelectorAll(selector) {
        return this.documentElement.querySelectorAll(selector);
    }

    /**
     * textContent returns null if the element is a document, a document type, or a notation.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent
     */
    get textContent() {
        return null;
    }

    get documentElement() {
        return this._documentElement;
    }

    get head() {
        let head = this._documentElement._childNodeFind(node => node.tagName === 'head');
        if (!head) {
            head = this.createElement('head');
            this._documentElement.insertBefore(head, this.body);
        }

        return head;
    }

    get body() {
        let body = this._documentElement._childNodeFind(node => node.tagName === 'body');
        if (!body) {
            body = this.createElement('body');
            this._documentElement.appendChild(body);
        }

        return body;
    }

    set body(body) {
        let current = this._documentElement.getElementsByTagName('body').shift();
        if (current) {
            this._documentElement.replaceChild(body, current);
        } else {
            this._documentElement.appendChild(body);
        }
    }

    get location() {
        return this._location;
    }

    set location(value) {
        this._location.href = value;
    }

    /**
     * @param {Node} child
     * @return {Node}
     */
    appendChild(child) {
        child = super.appendChild(child);
        if (child.nodeName === 'html') {
            this._documentElement = child;
        }

        return child;
    }
}

/**
 * @constant {number} Comment#nodeType
 */
Object.defineProperty(Document.prototype, 'nodeType', { value: Node.DOCUMENT_NODE });
<|endoftext|>


<commit_before>'use strict';

togglbutton.render(
  '.wspace-task-view:not(.toggl)',
  { observe: true },
  function (elem) {
    const container = $('.wrike-panel-header-toolbar', elem);

    const descriptionText = function () {
      const urlString = window.location.href;
      const url = new URL(urlString);
      // We have to look for the param in a custom hash
      const hash = url.hash.substr(1);
      const hashParts = hash.split('&');
      let taskId = null;
      for (let i = 0; i < hashParts.length; i++) {
        const partSplit = hashParts[i].split('=');
        if (partSplit[0] === 'ot') {
          taskId = partSplit[1];
        }
      }

      const titleElem = $('.title-field-ghost', elem);
      const titleElemText = titleElem ? titleElem.textContent : 'not found';
      return `#${taskId} ${titleElemText.trim()}`;
    };

    const projectText = function () {
      const projectElem = $('.wspace-tag-simple', elem);
      // We process the project element text content.
      return projectElem.textContent;
    };

    const link = togglbutton.createTimerLink({
      className: 'wrike',
      description: descriptionText,
      projectName: projectText
    });

    container.insertBefore(link, container.firstChild);
  }
);
<commit_msg>fix(wrike): Fix errors breaking the Wrike integration<commit_after>'use strict';

togglbutton.render(
  '.wspace-task-view:not(.toggl)',
  { observe: true },
  function (elem) {
    const container = $('.wrike-panel-header-toolbar', elem);

    const getTitleElement = function () {
      const wsTaskTitle = document.querySelectorAll('ws-task-title');
      if (wsTaskTitle.length === 1 && wsTaskTitle[0].textContent !== '') {
        return wsTaskTitle[0];
      }
      return $('title');
    };

    const descriptionText = function () {
      const urlString = window.location.href;
      const url = new URL(urlString);
      // We have to look for the param in a custom hash
      const hash = url.hash.substr(1);
      const hashParts = hash.split('&');
      let taskId = null;
      for (let i = 0; i < hashParts.length; i++) {
        const partSplit = hashParts[i].split('=');
        if (partSplit[0] === 'ot') {
          taskId = partSplit[1];
        }
      }

      const titleElem = getTitleElement();
      const titleElemText = titleElem ? titleElem.textContent : 'not found';
      return `${taskId ? '#' + taskId : ''} ${titleElemText.trim().replace(' - Wrike', '')}`.trim();
    };

    const projectText = function () {
      const projectElem = $('.wspace-tag-simple', elem);
      // We process the project element text content.
      return projectElem ? projectElem.textContent : '';
    };

    const link = togglbutton.createTimerLink({
      className: 'wrike',
      description: descriptionText,
      projectName: projectText
    });

    container.insertBefore(link, container.firstChild);
  }
);
<|endoftext|>


<commit_before>var TYPE = require('../../scanner').TYPE;

var SEMICOLON = TYPE.Semicolon;
var COMMERCIALAT = TYPE.CommercialAt;
var LEFTCURLYBRACKET = TYPE.LeftCurlyBracket;
var RIGHTCURLYBRACKET = TYPE.RightCurlyBracket;
var EOF = 0;
var DISALLOW_VAR = false;

function isBlockAtrule() {
    for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
        if (type === RIGHTCURLYBRACKET) {
            return true;
        }

        if (type === LEFTCURLYBRACKET ||
            type === COMMERCIALAT) {
            return false;
        }
    }

    return true;
}

module.exports = function Atrule() {
    var start = this.scanner.tokenStart;
    var name;
    var expression = null;
    var block = null;

    this.scanner.eat(COMMERCIALAT);

    name = this.readIdent(DISALLOW_VAR);
    this.readSC();

    expression = this.AtruleExpression(name);
    this.readSC();

    if (this.atrule.hasOwnProperty(name)) {
        if (typeof this.atrule[name].block === 'function') {
            if (this.scanner.tokenType !== LEFTCURLYBRACKET) {
                this.scanner.error('Curly bracket is expected');
            }

            block = this.atrule[name].block.call(this);
        } else {
            if (this.scanner.tokenType === SEMICOLON) {
                this.scanner.next();
            } else if (!this.scanner.eof) {
                this.scanner.error('Semicolon or EOF is expected');
            }
        }
    } else {
        switch (this.scanner.tokenType) {
            case SEMICOLON:
                this.scanner.next();
                break;

            case LEFTCURLYBRACKET:
                block = this.Block(isBlockAtrule.call(this) ? this.Declaration : this.Rule);
                break;

            case EOF:
                break;

            default:
                this.scanner.error();
        }
    }

    return {
        type: 'Atrule',
        loc: this.getLocation(start, this.scanner.tokenStart),
        name: name,
        expression: expression,
        block: block
    };
};
<commit_msg>one more fix for case insensitive test for at-rule name<commit_after>var TYPE = require('../../scanner').TYPE;

var SEMICOLON = TYPE.Semicolon;
var COMMERCIALAT = TYPE.CommercialAt;
var LEFTCURLYBRACKET = TYPE.LeftCurlyBracket;
var RIGHTCURLYBRACKET = TYPE.RightCurlyBracket;
var EOF = 0;
var DISALLOW_VAR = false;

function isBlockAtrule() {
    for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
        if (type === RIGHTCURLYBRACKET) {
            return true;
        }

        if (type === LEFTCURLYBRACKET ||
            type === COMMERCIALAT) {
            return false;
        }
    }

    return true;
}

module.exports = function Atrule() {
    var start = this.scanner.tokenStart;
    var name;
    var nameLowerCase;
    var expression = null;
    var block = null;

    this.scanner.eat(COMMERCIALAT);

    name = this.readIdent(DISALLOW_VAR);
    nameLowerCase = name.toLowerCase();
    this.readSC();

    expression = this.AtruleExpression(name);
    this.readSC();

    if (this.atrule.hasOwnProperty(nameLowerCase)) {
        if (typeof this.atrule[nameLowerCase].block === 'function') {
            if (this.scanner.tokenType !== LEFTCURLYBRACKET) {
                this.scanner.error('Curly bracket is expected');
            }

            block = this.atrule[nameLowerCase].block.call(this);
        } else {
            if (this.scanner.tokenType === SEMICOLON) {
                this.scanner.next();
            } else if (!this.scanner.eof) {
                this.scanner.error('Semicolon or EOF is expected');
            }
        }
    } else {
        switch (this.scanner.tokenType) {
            case SEMICOLON:
                this.scanner.next();
                break;

            case LEFTCURLYBRACKET:
                block = this.Block(isBlockAtrule.call(this) ? this.Declaration : this.Rule);
                break;

            case EOF:
                break;

            default:
                this.scanner.error();
        }
    }

    return {
        type: 'Atrule',
        loc: this.getLocation(start, this.scanner.tokenStart),
        name: name,
        expression: expression,
        block: block
    };
};
<|endoftext|>


<commit_before>"use strict";

import {TransformerBase} from './transformer-base';
import {TextTransformer} from './text.transformer';
import {DefaultTransformer} from './default.transformer';
import {ImageTransformer} from './image.transformer';
import {HTMLTransformer} from './html.transformer';
/**
 * Transforms mimetypes into HTMLElements
 */
class Transformime {

    /**
     * Public constructor
     * @param  {TransformerBase[]} transformers       list of transformers, in reverse
     *                                          priority order
     * @param  {TransformerBase} fallbackTransformer  transformer to default to when a
     *                                          mimetype is unsupported
     */
    constructor(transformers, fallbackTransformer) {

        // Initialize instance variables.
        this.transformers = transformers || [
            new TextTransformer(),
            new ImageTransformer('image/png'),
            new ImageTransformer('image/jpeg'),
            new HTMLTransformer()
        ];
        this.fallbackTransformer = fallbackTransformer || new DefaultTransformer();
    }

    /**
     * Transforms a mime bundle, using the richest available representation,
     * into an HTMLElement. Uses fallback transformer otherwise.
     * @param  {any}      bundle {mimetype1: data1, mimetype2: data2, ...}
     * @param  {Document} doc    Any of window.document, iframe.contentDocument
     * @return {Promise<HTMLElement>}
     */
    transformRichest(bundle, doc) {
        let element;
        let richTransformer = this.fallbackTransformer;

        // Choose the last transformer as the most rich
        for (let transformer of this.transformers) {
            if (transformer.mimetype in bundle) {
                richTransformer = transformer;
            }
        }

        if (richTransformer){
            let mimetype = richTransformer.mimetype;
            return this.transformRetainMimetype(bundle[mimetype], mimetype, doc);
        }

        return Promise.reject(new Error('Transformer(s) for ' + Object.keys(bundle).join(', ') + ' not found.'));
    }

    transformRetainMimetype(data, mimetype, doc) {
        var prom = this.transform(data, mimetype, doc);
        return prom.then(el => {
            return {
                "mimetype": mimetype,
                "el": el
            };
        });
    }

    /**
     * Transforms all of the mime types in a mime bundle into HTMLElements.
     * @param  {any}      bundle {mimetype1: data1, mimetype2: data2, ...}
     * @param  {Document} doc    Any of window.document, iframe.contentDocument
     * @return {Promise<HTMLElement[]>}
     */
    transformAll(bundle, doc) {
        var mimetypes = Object.keys(bundle);
        var promises = mimetypes.map( mimetype => {
            return this.transformRetainMimetype(bundle[mimetype], mimetype, doc);
        });
        return Promise.all(promises);
    }

    /**
     * Transforms a specific mime type into an HTMLElement. Uses the fallback
     * transformer if unable to get find the right one.
     * @param  {any}    data     Raw data
     * @param  {string} mimetype MIME type (e.g. text/html, image/png)
     * @return {Promise<HTMLElement>}
     */
    transform(data, mimetype, doc) {
        let transformer = this.getTransformer(mimetype);
        // TODO: Handle the fallbackTransformer case
        if (transformer) {
            // Don't assume the transformation will return a promise.  Also
            // don't assume the transformation will succeed.
            try {
                return Promise.resolve(transformer.transform(data, doc || document));
            } catch (e) {
                return Promise.reject(e);
            }
        }

        return Promise.reject(new Error('Transformer for mimetype ' + mimetype + ' not found.'));
    }

    /**
     * Gets a transformer matching the mimetype
     * @param  string mimetype the data type (e.g. text/plain, text/html, image/png)
     * @return {TransformerBase} Matching transformer
     */
    getTransformer(mimetype) {
        for (let transformer of this.transformers) {
            if (mimetype === transformer.mimetype) {
                return transformer;
            }
        }
        return null;
    }
}

export default {Transformime, TransformerBase, TextTransformer, DefaultTransformer, ImageTransformer, HTMLTransformer};
<commit_msg>Update documentation.<commit_after>"use strict";

import {TransformerBase} from './transformer-base';
import {TextTransformer} from './text.transformer';
import {DefaultTransformer} from './default.transformer';
import {ImageTransformer} from './image.transformer';
import {HTMLTransformer} from './html.transformer';
/**
 * Transforms mimetypes into HTMLElements
 */
class Transformime {

    /**
     * Public constructor
     * @param  {TransformerBase[]} transformers       list of transformers, in reverse
     *                                          priority order
     * @param  {TransformerBase} fallbackTransformer  transformer to default to when a
     *                                          mimetype is unsupported
     */
    constructor(transformers, fallbackTransformer) {

        // Initialize instance variables.
        this.transformers = transformers || [
            new TextTransformer(),
            new ImageTransformer('image/png'),
            new ImageTransformer('image/jpeg'),
            new HTMLTransformer()
        ];
        this.fallbackTransformer = fallbackTransformer || new DefaultTransformer();
    }

    /**
     * Transforms a mime bundle, using the richest available representation,
     * into an HTMLElement. Uses fallback transformer otherwise.
     * @param  {any}      bundle {mimetype1: data1, mimetype2: data2, ...}
     * @param  {Document} doc    Any of window.document, iframe.contentDocument
     * @return {Promise<Object>}
     */
    transformRichest(bundle, doc) {
        let element;
        let richTransformer = this.fallbackTransformer;

        // Choose the last transformer as the most rich
        for (let transformer of this.transformers) {
            if (transformer.mimetype in bundle) {
                richTransformer = transformer;
            }
        }

        if (richTransformer){
            let mimetype = richTransformer.mimetype;
            return this.transformRetainMimetype(bundle[mimetype], mimetype, doc);
        }

        return Promise.reject(new Error('Transformer(s) for ' + Object.keys(bundle).join(', ') + ' not found.'));
    }

    /**
     * transformRetainMimetype is just like transform except it returns an
     * object with both the mimetype and the element
     * {"mimetype": mimetype, "el": el}
     *
     * @param  {any} data        Raw data
     * @param  {string} mimetype Standard Mime type for the data
     * @param  {Document} doc    The DOM to own the element
     * @return {Object}          {"mimetype": mimetype, "el": el}
     */
    transformRetainMimetype(data, mimetype, doc) {
        var prom = this.transform(data, mimetype, doc);
        return prom.then(el => {
            return {
                "mimetype": mimetype,
                "el": el
            };
        });
    }

    /**
     * Transforms all of the mime types in a mime bundle into HTMLElements.
     * @param  {any}      bundle {mimetype1: data1, mimetype2: data2, ...}
     * @param  {Document} doc    Any of window.document, iframe.contentDocument
     * @return {Promise<Object[]>}
     */
    transformAll(bundle, doc) {
        var mimetypes = Object.keys(bundle);
        var promises = mimetypes.map( mimetype => {
            return this.transformRetainMimetype(bundle[mimetype], mimetype, doc);
        });
        return Promise.all(promises);
    }

    /**
     * Transforms a specific mime type into an HTMLElement.
     * @param  {any}    data     Raw data
     * @param  {string} mimetype MIME type (e.g. text/html, image/png)
     * @return {Promise<HTMLElement>}
     */
    transform(data, mimetype, doc) {
        let transformer = this.getTransformer(mimetype);
        // TODO: Handle the fallbackTransformer case
        if (transformer) {
            // Don't assume the transformation will return a promise.  Also
            // don't assume the transformation will succeed.
            try {
                return Promise.resolve(transformer.transform(data, doc || document));
            } catch (e) {
                return Promise.reject(e);
            }
        }

        return Promise.reject(new Error('Transformer for mimetype ' + mimetype + ' not found.'));
    }

    /**
     * Gets a transformer matching the mimetype
     * @param  string mimetype the data type (e.g. text/plain, text/html, image/png)
     * @return {TransformerBase} Matching transformer
     */
    getTransformer(mimetype) {
        for (let transformer of this.transformers) {
            if (mimetype === transformer.mimetype) {
                return transformer;
            }
        }
        return null;
    }
}

export default {Transformime, TransformerBase, TextTransformer, DefaultTransformer, ImageTransformer, HTMLTransformer};
<|endoftext|>


<commit_before>(function tweenyColor (global) {
	var savedRGBPropNames;

	if (!global.Tweenable) {
		return;
	}

	/**
	 * Convert a base-16 number to base-10.
	 * @param {Number|String} hex The value to convert
	 * @returns {Number} The base-10 equivalent of `hex`.
	 */
	function hexToDec (hex) {
		return parseInt(hex, 16);
	}

	/**
	 * Convert a hexadecimal string to an array with three items, one each for the red, blue, and green decimal values.
	 * @param {String} hex A hexadecimal string.
	 * @returns {Array} The converted Array of RGB values if `hex` is a valid string, or an Array of three 0's.
	 */
	function hexToRGBArr (hex) {
		hex = hex.replace(/#/g, '');

		// If the string is a shorthand three digit hex notation, normalize it to the standard six digit notation
		if (hex.length === 3) {
			hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
		}
		return [hexToDec(hex.substr(0, 2)), hexToDec(hex.substr(2, 2)), hexToDec(hex.substr(4, 2))];
	}

	function getRGBStringFromHex (str) {
		var rgbArr;

		if ((/^#([0-9]|[a-f]){3}$/i).test(str) || (/^#([0-9]|[a-f]){6}$/i).test(str)) {
			rgbArr = hexToRGBArr(str);
			str = 'rgb(' + rgbArr[0] + ',' + rgbArr[1] + ',' + rgbArr[2] + ')';
		}

		return str;
	}

	function getAndConvertStringProps (obj) {
		var stringPropNames;

		stringPropNames = [];

		global.Tweenable.util.each(obj, function (obj, prop) {
			if (typeof obj[prop] === 'string') {
				obj[prop] = getRGBStringFromHex(obj[prop]);
				stringPropNames.push(prop);
			}
		});

		return stringPropNames;
	}

	function rgbToArr (str) {
		return str.split(/\D+/g).slice(1, 4);
	}

	function splitRGBChunks (obj, savedRGBPropNames) {
		var i,
			limit,
			rgbParts;

			limit = savedRGBPropNames.length;

			for (i = 0; i < limit; i++) {
				rgbParts = rgbToArr(obj[savedRGBPropNames[i]]);
				obj['__r__' + savedRGBPropNames[i]] = rgbParts[0];
				obj['__g__' + savedRGBPropNames[i]] = rgbParts[1];
				obj['__b__' + savedRGBPropNames[i]] = rgbParts[2];
				delete obj[savedRGBPropNames[i]];
			}
	}

	global.Tweenable.prototype.filter.color = {
		'tweenCreated': function tweenCreated (fromState, toState) {
			savedRGBPropNames = getAndConvertStringProps(fromState);
			getAndConvertStringProps(toState);

			splitRGBChunks(fromState, savedRGBPropNames);
			splitRGBChunks(toState, savedRGBPropNames);

			//console.log(fromState, toState)
		},

		'beforeTween': function beforeTween (currentState, fromState, toState) {
			//console.log(currentState.test, fromState.test, toState.test)

		},

		'afterTween': function afterTween (currentState, fromState, toState) {

		}
	};

}(this));<commit_msg>Re-joined RGB chunks.<commit_after>(function tweenyColor (global) {
	var savedRGBPropNames;

	if (!global.Tweenable) {
		return;
	}

	/**
	 * Convert a base-16 number to base-10.
	 * @param {Number|String} hex The value to convert
	 * @returns {Number} The base-10 equivalent of `hex`.
	 */
	function hexToDec (hex) {
		return parseInt(hex, 16);
	}

	/**
	 * Convert a hexadecimal string to an array with three items, one each for the red, blue, and green decimal values.
	 * @param {String} hex A hexadecimal string.
	 * @returns {Array} The converted Array of RGB values if `hex` is a valid string, or an Array of three 0's.
	 */
	function hexToRGBArr (hex) {
		hex = hex.replace(/#/g, '');

		// If the string is a shorthand three digit hex notation, normalize it to the standard six digit notation
		if (hex.length === 3) {
			hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
		}
		return [hexToDec(hex.substr(0, 2)), hexToDec(hex.substr(2, 2)), hexToDec(hex.substr(4, 2))];
	}

	function getRGBStringFromHex (str) {
		var rgbArr;

		if ((/^#([0-9]|[a-f]){3}$/i).test(str) || (/^#([0-9]|[a-f]){6}$/i).test(str)) {
			rgbArr = hexToRGBArr(str);
			str = 'rgb(' + rgbArr[0] + ',' + rgbArr[1] + ',' + rgbArr[2] + ')';
		}

		return str;
	}

	function getAndConvertStringProps (obj) {
		var stringPropNames;

		stringPropNames = [];

		global.Tweenable.util.each(obj, function (obj, prop) {
			if (typeof obj[prop] === 'string') {
				obj[prop] = getRGBStringFromHex(obj[prop]);
				stringPropNames.push(prop);
			}
		});

		return stringPropNames;
	}

	function rgbToArr (str) {
		return str.split(/\D+/g).slice(1, 4);
	}

	function splitRGBChunks (obj, savedRGBPropNames) {
		var i,
			limit,
			rgbParts;

			limit = savedRGBPropNames.length;

			for (i = 0; i < limit; i++) {
				rgbParts = rgbToArr(obj[savedRGBPropNames[i]]);
				obj['__r__' + savedRGBPropNames[i]] = +rgbParts[0];
				obj['__g__' + savedRGBPropNames[i]] = +rgbParts[1];
				obj['__b__' + savedRGBPropNames[i]] = +rgbParts[2];
				delete obj[savedRGBPropNames[i]];
			}
	}

	function joinRGBChunks (obj, savedRGBPropNames) {
		var i,
			limit;

		limit = savedRGBPropNames.length;

		for (i = 0; i < limit; i++) {

			obj[savedRGBPropNames[i]] = 'rgb(' +
				parseInt(obj['__r__' + savedRGBPropNames[i]], 10) + ',' +
				parseInt(obj['__g__' + savedRGBPropNames[i]], 10) + ',' +
				parseInt(obj['__b__' + savedRGBPropNames[i]], 10) + ')';

			delete obj['__r__' + savedRGBPropNames[i]];
			delete obj['__g__' + savedRGBPropNames[i]];
			delete obj['__b__' + savedRGBPropNames[i]];
		}
	}

	global.Tweenable.prototype.filter.color = {
		'tweenCreated': function tweenCreated (fromState, toState) {
			savedRGBPropNames = getAndConvertStringProps(fromState);
			getAndConvertStringProps(toState);
		},

		'beforeTween': function beforeTween (currentState, fromState, toState) {
			splitRGBChunks(currentState, savedRGBPropNames);
			splitRGBChunks(fromState, savedRGBPropNames);
			splitRGBChunks(toState, savedRGBPropNames);
		},

		'afterTween': function afterTween (currentState, fromState, toState) {
			joinRGBChunks(currentState, savedRGBPropNames);
			joinRGBChunks(fromState, savedRGBPropNames);
			joinRGBChunks(toState, savedRGBPropNames);
		}
	};

}(this));<|endoftext|>