<commit_before>/*
 * Copyright (c) 2011, salesforce.com, inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 * the following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
 * promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/* JavaScript library to wrap REST API on Visualforce. Leverages Ajax Proxy
 * (see http://bit.ly/sforce_ajax_proxy for details).
 *
 * Note that you must add the REST endpoint hostname for your instance (i.e.
 * https://na1.salesforce.com/ or similar) as a remote site - in the admin
 * console, go to Your Name | Setup | Security Controls | Remote Site Settings
 */

var forcetk = window.forcetk;

if (forcetk === undefined) {
    forcetk = {};
}

if (forcetk.Client === undefined) {

    // We use $j rather than $ for jQuery so it works in Visualforce
    if (window.$j === undefined) {
        $j = $;
    }

    /**
     * The Client provides a convenient wrapper for the Force.com REST API,
     * allowing JavaScript in Visualforce pages to use the API via the Ajax
     * Proxy.
     * @param [clientId=null] 'Consumer Key' in the Remote Access app settings
     * @param [loginUrl='https://login.salesforce.com/'] Login endpoint
     * @param [proxyUrl=null] Proxy URL. Omit if running on Visualforce or
     *                  PhoneGap etc
     * @constructor
     */
    forcetk.Client = function(clientId, loginUrl, proxyUrl) {
        this.clientId = clientId;
        this.loginUrl = loginUrl || 'https://login.salesforce.com/';
        if (typeof proxyUrl === 'undefined' || proxyUrl === null) {
            if (location.protocol === 'file:') {
                // In PhoneGap
                this.proxyUrl = null;
            } else {
                // In Visualforce
                this.proxyUrl = location.protocol + "//" + location.hostname
                    + "/services/proxy";
            }
            this.authzHeader = "Authorization";
        } else {
            // On a server outside VF
            this.proxyUrl = proxyUrl;
            this.authzHeader = "X-Authorization";
        }
        this.refreshToken = null;
        this.sessionId = null;
        this.apiVersion = null;
        this.instanceUrl = null;
    }

    /**
     * Set a refresh token in the client.
     * @param refreshToken an OAuth refresh token
     */
    forcetk.Client.prototype.setRefreshToken = function(refreshToken) {
        this.refreshToken = refreshToken;
    }

    /**
     * Refresh the access token.
     * @param callback function to call on success
     * @param error function to call on failure
     */
    forcetk.Client.prototype.refreshAccessToken = function(callback, error) {
        var that = this;
        var url = this.loginUrl + '/services/oauth2/token';
        $j.ajax({
            type: 'POST',
            url: (this.proxyUrl !== null) ? this.proxyUrl: url,
            processData: false,
            data: 'grant_type=refresh_token&client_id=' + this.clientId + '&refresh_token=' + this.refreshToken,
            success: callback,
            error: error,
            dataType: "json",
            beforeSend: function(xhr) {
                if (that.proxyUrl !== null) {
                    xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
                }
            }
        });
    }

    /**
     * Set a session token and the associated metadata in the client.
     * @param sessionId a salesforce.com session ID. In a Visualforce page,
     *                   use '{!$Api.sessionId}' to obtain a session ID.
     * @param [apiVersion="21.0"] Force.com API version
     * @param [instanceUrl] Omit this if running on Visualforce; otherwise
     *                   use the value from the OAuth token.
     */
    forcetk.Client.prototype.setSessionToken = function(sessionId, apiVersion, instanceUrl) {
        this.sessionId = sessionId;
        this.apiVersion = (typeof apiVersion === 'undefined' || apiVersion === null)
        ? 'v21.0': apiVersion;
        if (typeof instanceUrl === 'undefined' || instanceUrl == null) {
            // location.hostname can be of the form 'abc.na1.visual.force.com' or
            // 'na1.salesforce.com'. Split on '.', and take the [1] or [0] element
            // as appropriate
            var elements = location.hostname.split(".");
            var instance = (elements.length == 3) ? elements[0] : elements[1];
            this.instanceUrl = "https://" + instance + ".salesforce.com";
        } else {
            this.instanceUrl = instanceUrl;
        }
    }

    /*
     * Low level utility function to call the Salesforce endpoint.
     * @param path resource path relative to /services/data
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     * @param [method="GET"] HTTP method for call
     * @param [payload=null] payload for POST/PATCH etc
     */
    forcetk.Client.prototype.ajax = function(path, callback, error, method, payload, retry) {
        var that = this;
        var url = this.instanceUrl + '/services/data' + path;

        $j.ajax({
            type: method || "GET",
            url: (this.proxyUrl !== null) ? this.proxyUrl: url,
            contentType: 'application/json',
            processData: false,
            data: payload,
            success: callback,
            error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) {
                if (jqXHR.status === 401) {
                    that.refreshAccessToken(function(oauthResponse) {
                        that.setSessionToken(oauthResponse.access_token, null,
                        oauthResponse.instance_url);
                        that.ajax(path, callback, error, method, payload, true);
                    },
                    error);
                } else {
                    error(jqXHR, textStatus, errorThrown);
                }
            },
            dataType: "json",
            beforeSend: function(xhr) {
                if (that.proxyUrl !== null) {
                    xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
                }
                xhr.setRequestHeader(that.authzHeader, "OAuth " + that.sessionId);
                xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);
            }
        });
    }

    /*
     * Lists summary information about each Salesforce.com version currently
     * available, including the version, label, and a link to each version's
     * root.
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.versions = function(callback, error) {
        this.ajax('/', callback, error);
    }

    /*
     * Lists available resources for the client's API version, including
     * resource name and URI.
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.resources = function(callback, error) {
        this.ajax('/' + this.apiVersion + '/', callback, error);
    }

    /*
     * Lists the available objects and their metadata for your organization's
     * data.
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.describeGlobal = function(callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/', callback, error);
    }

    /*
     * Describes the individual metadata for the specified object.
     * @param objtype object type; e.g. "Account"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.metadata = function(objtype, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/'
        , callback, error);
    }

    /*
     * Completely describes the individual metadata at all levels for the
     * specified object.
     * @param objtype object type; e.g. "Account"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.describe = function(objtype, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype
        + '/describe/', callback, error);
    }

    /*
     * Creates a new record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param fields an object containing initial field names and values for
     *               the record, e.g. {:Name "salesforce.com", :TickerSymbol
     *               "CRM"}
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.create = function(objtype, fields, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/'
        , callback, error, "POST", JSON.stringify(fields));
    }

    /*
     * Retrieves field values for a record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param id the record's object ID
     * @param fields comma-separated list of fields for which to return
     *               values; e.g. Name,Industry,TickerSymbol
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.retrieve = function(objtype, id, fieldlist, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id
        + '?fields=' + fieldlist, callback, error);
    }

    /*
     * Updates field values on a record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param id the record's object ID
     * @param fields an object containing initial field names and values for
     *               the record, e.g. {:Name "salesforce.com", :TickerSymbol
     *               "CRM"}
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.update = function(objtype, id, fields, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id
        , callback, error, "PATCH", JSON.stringify(fields));
    }

    /*
     * Deletes a record of the given type. Unfortunately, 'delete' is a
     * reserved word in JavaScript.
     * @param objtype object type; e.g. "Account"
     * @param id the record's object ID
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.del = function(objtype, id, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id
        , callback, error, "DELETE");
    }

    /*
     * Executes the specified SOQL query.
     * @param soql a string containing the query to execute - e.g. "SELECT Id,
     *             Name from Account ORDER BY Name LIMIT 20"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.query = function(soql, callback, error) {
        this.ajax('/' + this.apiVersion + '/query?q=' + escape(soql)
        , callback, error);
    }

    /*
     * Executes the specified SOSL search.
     * @param sosl a string containing the search to execute - e.g. "FIND
     *             {needle}"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.search = function(sosl, callback, error) {
        this.ajax('/' + this.apiVersion + '/search?s=' + escape(sosl)
        , callback, error);
    }
}<commit_msg>Use ?_HttpMethod=PATCH for update, rather than custom PATCH method, for wider compatibility<commit_after>/*
 * Copyright (c) 2011, salesforce.com, inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 * the following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
 * promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/* JavaScript library to wrap REST API on Visualforce. Leverages Ajax Proxy
 * (see http://bit.ly/sforce_ajax_proxy for details).
 *
 * Note that you must add the REST endpoint hostname for your instance (i.e.
 * https://na1.salesforce.com/ or similar) as a remote site - in the admin
 * console, go to Your Name | Setup | Security Controls | Remote Site Settings
 */

var forcetk = window.forcetk;

if (forcetk === undefined) {
    forcetk = {};
}

if (forcetk.Client === undefined) {

    // We use $j rather than $ for jQuery so it works in Visualforce
    if (window.$j === undefined) {
        $j = $;
    }

    /**
     * The Client provides a convenient wrapper for the Force.com REST API,
     * allowing JavaScript in Visualforce pages to use the API via the Ajax
     * Proxy.
     * @param [clientId=null] 'Consumer Key' in the Remote Access app settings
     * @param [loginUrl='https://login.salesforce.com/'] Login endpoint
     * @param [proxyUrl=null] Proxy URL. Omit if running on Visualforce or
     *                  PhoneGap etc
     * @constructor
     */
    forcetk.Client = function(clientId, loginUrl, proxyUrl) {
        this.clientId = clientId;
        this.loginUrl = loginUrl || 'https://login.salesforce.com/';
        if (typeof proxyUrl === 'undefined' || proxyUrl === null) {
            if (location.protocol === 'file:') {
                // In PhoneGap
                this.proxyUrl = null;
            } else {
                // In Visualforce
                this.proxyUrl = location.protocol + "//" + location.hostname
                    + "/services/proxy";
            }
            this.authzHeader = "Authorization";
        } else {
            // On a server outside VF
            this.proxyUrl = proxyUrl;
            this.authzHeader = "X-Authorization";
        }
        this.refreshToken = null;
        this.sessionId = null;
        this.apiVersion = null;
        this.instanceUrl = null;
    }

    /**
     * Set a refresh token in the client.
     * @param refreshToken an OAuth refresh token
     */
    forcetk.Client.prototype.setRefreshToken = function(refreshToken) {
        this.refreshToken = refreshToken;
    }

    /**
     * Refresh the access token.
     * @param callback function to call on success
     * @param error function to call on failure
     */
    forcetk.Client.prototype.refreshAccessToken = function(callback, error) {
        var that = this;
        var url = this.loginUrl + '/services/oauth2/token';
        $j.ajax({
            type: 'POST',
            url: (this.proxyUrl !== null) ? this.proxyUrl: url,
            processData: false,
            data: 'grant_type=refresh_token&client_id=' + this.clientId + '&refresh_token=' + this.refreshToken,
            success: callback,
            error: error,
            dataType: "json",
            beforeSend: function(xhr) {
                if (that.proxyUrl !== null) {
                    xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
                }
            }
        });
    }

    /**
     * Set a session token and the associated metadata in the client.
     * @param sessionId a salesforce.com session ID. In a Visualforce page,
     *                   use '{!$Api.sessionId}' to obtain a session ID.
     * @param [apiVersion="21.0"] Force.com API version
     * @param [instanceUrl] Omit this if running on Visualforce; otherwise
     *                   use the value from the OAuth token.
     */
    forcetk.Client.prototype.setSessionToken = function(sessionId, apiVersion, instanceUrl) {
        this.sessionId = sessionId;
        this.apiVersion = (typeof apiVersion === 'undefined' || apiVersion === null)
        ? 'v21.0': apiVersion;
        if (typeof instanceUrl === 'undefined' || instanceUrl == null) {
            // location.hostname can be of the form 'abc.na1.visual.force.com' or
            // 'na1.salesforce.com'. Split on '.', and take the [1] or [0] element
            // as appropriate
            var elements = location.hostname.split(".");
            var instance = (elements.length == 3) ? elements[0] : elements[1];
            this.instanceUrl = "https://" + instance + ".salesforce.com";
        } else {
            this.instanceUrl = instanceUrl;
        }
    }

    /*
     * Low level utility function to call the Salesforce endpoint.
     * @param path resource path relative to /services/data
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     * @param [method="GET"] HTTP method for call
     * @param [payload=null] payload for POST/PATCH etc
     */
    forcetk.Client.prototype.ajax = function(path, callback, error, method, payload, retry) {
        var that = this;
        var url = this.instanceUrl + '/services/data' + path;

        $j.ajax({
            type: method || "GET",
            url: (this.proxyUrl !== null) ? this.proxyUrl: url,
            contentType: 'application/json',
            processData: false,
            data: payload,
            success: callback,
            error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) {
                if (jqXHR.status === 401) {
                    that.refreshAccessToken(function(oauthResponse) {
                        that.setSessionToken(oauthResponse.access_token, null,
                        oauthResponse.instance_url);
                        that.ajax(path, callback, error, method, payload, true);
                    },
                    error);
                } else {
                    error(jqXHR, textStatus, errorThrown);
                }
            },
            dataType: "json",
            beforeSend: function(xhr) {
                if (that.proxyUrl !== null) {
                    xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
                }
                xhr.setRequestHeader(that.authzHeader, "OAuth " + that.sessionId);
                xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);
            }
        });
    }

    /*
     * Lists summary information about each Salesforce.com version currently
     * available, including the version, label, and a link to each version's
     * root.
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.versions = function(callback, error) {
        this.ajax('/', callback, error);
    }

    /*
     * Lists available resources for the client's API version, including
     * resource name and URI.
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.resources = function(callback, error) {
        this.ajax('/' + this.apiVersion + '/', callback, error);
    }

    /*
     * Lists the available objects and their metadata for your organization's
     * data.
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.describeGlobal = function(callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/', callback, error);
    }

    /*
     * Describes the individual metadata for the specified object.
     * @param objtype object type; e.g. "Account"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.metadata = function(objtype, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/'
        , callback, error);
    }

    /*
     * Completely describes the individual metadata at all levels for the
     * specified object.
     * @param objtype object type; e.g. "Account"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.describe = function(objtype, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype
        + '/describe/', callback, error);
    }

    /*
     * Creates a new record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param fields an object containing initial field names and values for
     *               the record, e.g. {:Name "salesforce.com", :TickerSymbol
     *               "CRM"}
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.create = function(objtype, fields, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/'
        , callback, error, "POST", JSON.stringify(fields));
    }

    /*
     * Retrieves field values for a record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param id the record's object ID
     * @param fields comma-separated list of fields for which to return
     *               values; e.g. Name,Industry,TickerSymbol
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.retrieve = function(objtype, id, fieldlist, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id
        + '?fields=' + fieldlist, callback, error);
    }

    /*
     * Updates field values on a record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param id the record's object ID
     * @param fields an object containing initial field names and values for
     *               the record, e.g. {:Name "salesforce.com", :TickerSymbol
     *               "CRM"}
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.update = function(objtype, id, fields, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id
        + '?_HttpMethod=PATCH', callback, error, "POST", JSON.stringify(fields));
    }

    /*
     * Deletes a record of the given type. Unfortunately, 'delete' is a
     * reserved word in JavaScript.
     * @param objtype object type; e.g. "Account"
     * @param id the record's object ID
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.del = function(objtype, id, callback, error) {
        this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id
        , callback, error, "DELETE");
    }

    /*
     * Executes the specified SOQL query.
     * @param soql a string containing the query to execute - e.g. "SELECT Id,
     *             Name from Account ORDER BY Name LIMIT 20"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.query = function(soql, callback, error) {
        this.ajax('/' + this.apiVersion + '/query?q=' + escape(soql)
        , callback, error);
    }

    /*
     * Executes the specified SOSL search.
     * @param sosl a string containing the search to execute - e.g. "FIND
     *             {needle}"
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    forcetk.Client.prototype.search = function(sosl, callback, error) {
        this.ajax('/' + this.apiVersion + '/search?s=' + escape(sosl)
        , callback, error);
    }
}<|endoftext|>


<commit_before>// @flow

/**
 * dispatch
 */
import { _store } from './store'

export let dispatch= {} // eslint-disable-line

export const createDispatcher = (modelName: string, reducerName: string) => (payload: any) => {
  const action = {
    type: `${modelName}/${reducerName}`,
    ...(payload ? { payload } : {})
  }
  _store.dispatch(action)
}

export const createDispatchers = (model: $model) => {
  const { name: modelName, reduce: reducers } = model

  dispatch[modelName] = {}
  Object.keys(reducers || {}).forEach((reducerName: string) => {
    dispatch[modelName][reducerName] = createDispatcher(modelName, reducerName)
  })
}
<commit_msg>tidying up<commit_after>// @flow

/**
 * dispatch
 */
import { _store } from './store'

export let dispatch = {} // eslint-disable-line

export const createDispatcher = (modelName: string, reducerName: string) => (payload: any) => {
  const action = {
    type: `${modelName}/${reducerName}`,
    ...(payload ? { payload } : {})
  }
  _store.dispatch(action)
}

export const createDispatchers = (model: $model) => {
  const { name: modelName, reduce: reducers } = model

  dispatch[modelName] = {}
  Object.keys(reducers || {}).forEach((reducerName: string) => {
    dispatch[modelName][reducerName] = createDispatcher(modelName, reducerName)
  })
}
<|endoftext|>


<commit_before>"use strict";

// Substance.Document 0.5.0
// (c) 2010-2013 Michael Aufreiter
// Substance.Document may be freely distributed under the MIT license.
// For all details and documentation:
// http://interior.substance.io/modules/document.html

// Import
// ========

var _ = require("underscore");
var util = require("substance-util");
var errors = util.errors;
var Data = require("substance-data");
var Operator = require("substance-operator");
var Chronicle = require("substance-chronicle");

// Module
// ========

var DocumentError = errors.define("DocumentError");

// Document
// --------
//
// A generic model for representing and transforming digital documents

var Document = function(options) {
  Data.Graph.call(this, options.schema, options);
};

// Default Document Schema
// --------

Document.schema = {
  // Static indexes
  "indexes": {
  },

  "types": {
    // Specific type for substance documents, holding all content elements
    "content": {
      "properties": {
      }
    },

    "view": {
      "properties": {
        "nodes": ["array", "content"]
      }
    }
  }
};

Document.Prototype = function() {

  var __super__ = util.prototype(this);

  this.create = function(node) {
    __super__.create.call(this, node);
    return this.get(node.id);
  };

  // Delegates to Graph.get but wraps the result in the particular node constructor
  // --------
  //

  this.get = function(path) {
    var node = __super__.get.call(this, path);

    if (!node) return node;

    // wrap the node into a rich object
    // and replace the instance stored in the graph
    var NodeType = this.nodeTypes[node.type];
    if (NodeType && !(node instanceof NodeType)) {
      node = new NodeType(node, {
        get: this.get.bind(this),
        on: this.on.bind(this),
        off: this.off.bind(this)
      });
      this.nodes[node.id] = node;
    }

    return node;
  };

  // Get node position for a given view and node id
  // --------
  //

  this.getPosition = function(view, id) {
    return this.get(view).nodes.indexOf(id);
  };

  // Get predecessor node for a given view and node id
  // --------
  //

  this.getPredecessor = function(view, id) {
    var pos = this.getPosition(view, id);
    if (pos === 0) return null;
    return this.getNodeFromPosition(view, pos-1);
  };

  // Get successor node for a given view and node id
  // --------
  //

  this.getSuccessor = function(view, id) {
    var pos = this.getPosition(view, id);
    if (pos === view.length - 1) return null;
    return this.getNodeFromPosition(view, pos+1);
  };

  // Returns true if given view and node pos has a successor
  // --------
  //

  this.hasSuccessor = function(view, nodePos) {
    view = this.get(view).nodes;
    return nodePos < view.length - 1;
  };

  // Returns true if given view and node pos has a predecessor
  // --------
  //

  this.hasPredecessor = function(view, nodePos) {
    return nodePos > 0;
  };

  // Get successor node for a given view and node id
  // --------
  //

  this.getSuccessor = function(view, id) {
    var pos = this.getPosition(view, id);
    // if (pos === view.length - 1) return null;
    return this.getNodeFromPosition(view, pos+1);
  };

  // Get node object from a given view and position
  // --------
  //

  this.getNodeFromPosition = function(view, pos) {
    var nodeId = this.get(view).nodes[pos];
    return nodeId ? this.get(nodeId) : null;
  };

  // Serialize to JSON
  // --------
  //
  // The command is converted into a sequence of graph commands

  this.toJSON = function() {
    var res = __super__.toJSON.call(this);
    res.id = this.id;
    return res;
  };

  // Hide elements from provided view
  // --------
  //

  this.hide = function(viewId, nodes) {
    var view = this.get(viewId);

    if (!view) {
      throw new DocumentError("Invalid view id: "+ viewId);
    }

    if (_.isString(nodes)) {
      nodes = [nodes];
    }

    var indexes = [];
    _.each(nodes, function(n) {
      var i = view.nodes.indexOf(n);
      if (i>=0) indexes.push(i);
    }, this);

    if (indexes.length === 0) return;

    indexes = indexes.sort().reverse();
    indexes = _.uniq(indexes);

    var ops = _.map(indexes, function(index) {
      return Operator.ArrayOperation.Delete(index, view.nodes[index]);
    });

    var op = Operator.ObjectOperation.Update([viewId, "nodes"], Operator.ArrayOperation.Compound(ops));

    return this.apply(op);
  };

  // Adds nodes to a view
  // --------
  //

  this.show = function(viewId, nodes, target) {
    if (arguments.length !== 3) {
      throw new DocumentError("Invalid arguments: expecting (viewId, nodes, target)");
    }

    var view = this.get(viewId);
    if (!view) {
      throw new DocumentError("Invalid view id: " + viewId);
    }

    if (_.isString(nodes)) {
      nodes = [nodes];
    }

    var l = view.nodes.length;

    // target index can be given as negative number (as known from python/ruby)
    target = Math.min(target, l);
    if (target<0) target = Math.max(0, l+target+1);

    var ops = [];
    for (var idx = 0; idx < nodes.length; idx++) {
      var nodeId = nodes[idx];
      if (this.nodes[nodeId] === undefined) {
        throw new DocumentError("Invalid node id: " + nodeId);
      }
      ops.push(Operator.ArrayOperation.Insert(target + idx, nodeId));
    }

    if (ops.length > 0) {
      var update = Operator.ObjectOperation.Update([viewId, "nodes"], Operator.ArrayOperation.Compound(ops));
      return this.apply(update);
    }
  };

  // Start simulation, which conforms to a transaction (think databases)
  // --------
  //

// Deactivated this as it does not work and breaks everything
/*
  this.startSimulation = function() {

    var parent = this;

    var doc = _.extend({}, this);
    doc._events = [];
    doc.objectAdapter = new Data.Graph.ObjectAdapter(doc);

    // remember the original state
    var initialState = this.chronicle.getState();

    // create a temporary chronicle index
    doc.chronicle = _.extend({}, this.chronicle);
    doc.chronicle.manage(new Data.Graph.ChronicleAdapter(doc));
    doc.chronicle.index = new Chronicle.TmpIndex(this.chronicle.index);

    // inject a recording apply method
    var ops = [];
    var __apply__ = this.apply;
    doc.apply = function(op) {
      op = __apply__.call(this, op);
      ops.push(op);
      return op;
    };

    doc.save = function() {
      var _ops = [];
      for (var i = 0; i < ops.length; i++) {
        if (ops[i].type !== "compound") {
          _ops.push(ops[i]);
        } else {
          _ops = _ops.concat(ops[i].ops);
        }
      }
      var compound = Operator.ObjectOperation.Compound(_ops);
      this.chronicle.reset(initialState);

      parent.apply(compound);
    };

    return doc;
  };
*/

  // Start simulation, which conforms to a transaction (think databases)
  // --------
  //

  this.startSimulation = function() {
    // TODO: this should be implemented in a more cleaner and efficient way.
    // Though, for now and sake of simplicity done by creating a copy
    var self = this;
    var simulation = this.fromSnapshot(this.toJSON());
    var ops = [];

    var __apply__ = simulation.apply;

    simulation.apply = function(op) {
      op = __apply__.call(simulation, op);
      ops.push(op);
      return op;
    };

    simulation.save = function() {
      var _ops = [];
      for (var i = 0; i < ops.length; i++) {
        if (ops[i].type !== "compound") {
          _ops.push(ops[i]);
        } else {
          _ops = _ops.concat(ops[i].ops);
        }
      }

      if (_ops.length === 0) {
        // nothing has been recorded
        return;
      }

      var compound = Operator.ObjectOperation.Compound(_ops);
      self.apply(compound);
      // console.log("Saved simulated ops", self);
    };

    return simulation;
  };

  this.fromSnapshot = function(data, options) {
    return Document.fromSnapshot(data, options);
  };

};

Document.Prototype.prototype = Data.Graph.prototype;
Document.prototype = new Document.Prototype();

// Add event support
_.extend(Document.prototype, util.Events);

Document.fromSnapshot = function(data, options) {
  options = options || {};
  options.seed = data;
  return new Document(options);
};

Document.DocumentError = DocumentError;

// Export
// ========

module.exports = Document;
<commit_msg>Bring back cover node.<commit_after>"use strict";

// Substance.Document 0.5.0
// (c) 2010-2013 Michael Aufreiter
// Substance.Document may be freely distributed under the MIT license.
// For all details and documentation:
// http://interior.substance.io/modules/document.html

// Import
// ========

var _ = require("underscore");
var util = require("substance-util");
var errors = util.errors;
var Data = require("substance-data");
var Operator = require("substance-operator");
var Chronicle = require("substance-chronicle");

// Module
// ========

var DocumentError = errors.define("DocumentError");

// Document
// --------
//
// A generic model for representing and transforming digital documents

var Document = function(options) {
  Data.Graph.call(this, options.schema, options);
};

// Default Document Schema
// --------

Document.schema = {
  // Static indexes
  "indexes": {
  },

  "types": {
    // Specific type for substance documents, holding all content elements
    "content": {
      "properties": {
      }
    },

    "view": {
      "properties": {
        "nodes": ["array", "content"]
      }
    }
  }
};

Document.Prototype = function() {

  var __super__ = util.prototype(this);

  this.create = function(node) {
    __super__.create.call(this, node);
    return this.get(node.id);
  };

  // Delegates to Graph.get but wraps the result in the particular node constructor
  // --------
  //

  this.get = function(path) {
    var node = __super__.get.call(this, path);

    if (!node) return node;

    // wrap the node into a rich object
    // and replace the instance stored in the graph
    var NodeType = this.nodeTypes[node.type];
    if (NodeType && !(node instanceof NodeType)) {

      // Exposing the full doc for simplicity
      // We need to make sure doc nodes don't do something bad on the document

      node = new NodeType(node, this);

      // node = new NodeType(node, {
      //   get: this.get.bind(this),
      //   on: this.on.bind(this),
      //   off: this.off.bind(this)
      // });

      this.nodes[node.id] = node;
    }

    return node;
  };

  // Get node position for a given view and node id
  // --------
  //

  this.getPosition = function(view, id) {
    return this.get(view).nodes.indexOf(id);
  };

  // Get predecessor node for a given view and node id
  // --------
  //

  this.getPredecessor = function(view, id) {
    var pos = this.getPosition(view, id);
    if (pos === 0) return null;
    return this.getNodeFromPosition(view, pos-1);
  };

  // Get successor node for a given view and node id
  // --------
  //

  this.getSuccessor = function(view, id) {
    var pos = this.getPosition(view, id);
    if (pos === view.length - 1) return null;
    return this.getNodeFromPosition(view, pos+1);
  };

  // Returns true if given view and node pos has a successor
  // --------
  //

  this.hasSuccessor = function(view, nodePos) {
    view = this.get(view).nodes;
    return nodePos < view.length - 1;
  };

  // Returns true if given view and node pos has a predecessor
  // --------
  //

  this.hasPredecessor = function(view, nodePos) {
    return nodePos > 0;
  };

  // Get successor node for a given view and node id
  // --------
  //

  this.getSuccessor = function(view, id) {
    var pos = this.getPosition(view, id);
    // if (pos === view.length - 1) return null;
    return this.getNodeFromPosition(view, pos+1);
  };

  // Get node object from a given view and position
  // --------
  //

  this.getNodeFromPosition = function(view, pos) {
    var nodeId = this.get(view).nodes[pos];
    return nodeId ? this.get(nodeId) : null;
  };

  // Serialize to JSON
  // --------
  //
  // The command is converted into a sequence of graph commands

  this.toJSON = function() {
    var res = __super__.toJSON.call(this);
    res.id = this.id;
    return res;
  };

  // Hide elements from provided view
  // --------
  //

  this.hide = function(viewId, nodes) {
    var view = this.get(viewId);

    if (!view) {
      throw new DocumentError("Invalid view id: "+ viewId);
    }

    if (_.isString(nodes)) {
      nodes = [nodes];
    }

    var indexes = [];
    _.each(nodes, function(n) {
      var i = view.nodes.indexOf(n);
      if (i>=0) indexes.push(i);
    }, this);

    if (indexes.length === 0) return;

    indexes = indexes.sort().reverse();
    indexes = _.uniq(indexes);

    var ops = _.map(indexes, function(index) {
      return Operator.ArrayOperation.Delete(index, view.nodes[index]);
    });

    var op = Operator.ObjectOperation.Update([viewId, "nodes"], Operator.ArrayOperation.Compound(ops));

    return this.apply(op);
  };

  // Adds nodes to a view
  // --------
  //

  this.show = function(viewId, nodes, target) {
    if (arguments.length !== 3) {
      throw new DocumentError("Invalid arguments: expecting (viewId, nodes, target)");
    }

    var view = this.get(viewId);
    if (!view) {
      throw new DocumentError("Invalid view id: " + viewId);
    }

    if (_.isString(nodes)) {
      nodes = [nodes];
    }

    var l = view.nodes.length;

    // target index can be given as negative number (as known from python/ruby)
    target = Math.min(target, l);
    if (target<0) target = Math.max(0, l+target+1);

    var ops = [];
    for (var idx = 0; idx < nodes.length; idx++) {
      var nodeId = nodes[idx];
      if (this.nodes[nodeId] === undefined) {
        throw new DocumentError("Invalid node id: " + nodeId);
      }
      ops.push(Operator.ArrayOperation.Insert(target + idx, nodeId));
    }

    if (ops.length > 0) {
      var update = Operator.ObjectOperation.Update([viewId, "nodes"], Operator.ArrayOperation.Compound(ops));
      return this.apply(update);
    }
  };

  // Start simulation, which conforms to a transaction (think databases)
  // --------
  //

// Deactivated this as it does not work and breaks everything
/*
  this.startSimulation = function() {

    var parent = this;

    var doc = _.extend({}, this);
    doc._events = [];
    doc.objectAdapter = new Data.Graph.ObjectAdapter(doc);

    // remember the original state
    var initialState = this.chronicle.getState();

    // create a temporary chronicle index
    doc.chronicle = _.extend({}, this.chronicle);
    doc.chronicle.manage(new Data.Graph.ChronicleAdapter(doc));
    doc.chronicle.index = new Chronicle.TmpIndex(this.chronicle.index);

    // inject a recording apply method
    var ops = [];
    var __apply__ = this.apply;
    doc.apply = function(op) {
      op = __apply__.call(this, op);
      ops.push(op);
      return op;
    };

    doc.save = function() {
      var _ops = [];
      for (var i = 0; i < ops.length; i++) {
        if (ops[i].type !== "compound") {
          _ops.push(ops[i]);
        } else {
          _ops = _ops.concat(ops[i].ops);
        }
      }
      var compound = Operator.ObjectOperation.Compound(_ops);
      this.chronicle.reset(initialState);

      parent.apply(compound);
    };

    return doc;
  };
*/

  // Start simulation, which conforms to a transaction (think databases)
  // --------
  //

  this.startSimulation = function() {
    // TODO: this should be implemented in a more cleaner and efficient way.
    // Though, for now and sake of simplicity done by creating a copy
    var self = this;
    var simulation = this.fromSnapshot(this.toJSON());
    var ops = [];

    var __apply__ = simulation.apply;

    simulation.apply = function(op) {
      op = __apply__.call(simulation, op);
      ops.push(op);
      return op;
    };

    simulation.save = function() {
      var _ops = [];
      for (var i = 0; i < ops.length; i++) {
        if (ops[i].type !== "compound") {
          _ops.push(ops[i]);
        } else {
          _ops = _ops.concat(ops[i].ops);
        }
      }

      if (_ops.length === 0) {
        // nothing has been recorded
        return;
      }

      var compound = Operator.ObjectOperation.Compound(_ops);
      self.apply(compound);
      // console.log("Saved simulated ops", self);
    };

    return simulation;
  };

  this.fromSnapshot = function(data, options) {
    return Document.fromSnapshot(data, options);
  };

};

Document.Prototype.prototype = Data.Graph.prototype;
Document.prototype = new Document.Prototype();

// Add event support
_.extend(Document.prototype, util.Events);

Document.fromSnapshot = function(data, options) {
  options = options || {};
  options.seed = data;
  return new Document(options);
};

Document.DocumentError = DocumentError;

// Export
// ========

module.exports = Document;
<|endoftext|>


<commit_before>import React from 'react/addons';
import DomNode from './domnode.js';
const TestUtils = React.addons.TestUtils;

export default class DomNodes {
  static fromRenderedTree(tree) {
    let instance = new DomNodes();
    instance.domNodes = allNodes(tree)
      .filter(DomNode.isDomNode)
      .map(domNode => DomNode.fromRenderedNode(domNode));
    return instance;
  }

  static fromComponent(component) {
    return DomNodes.fromRenderedTree(renderRecursively(component));
  }
}

function renderRecursively(componentToRender) {
  const rendered = render(componentToRender);
  if (rendered.props  && rendered.props.children){
    if (Array.isArray(rendered.props.children)) {
      rendered.props.children[1] = render(rendered.props.children[1]);

      if (rendered.props.children.length > 3) {
        const prototypeOfComponent = Reflect.getPrototypeOf(rendered.props.children[3].type);
        if (Object.is(prototypeOfComponent, React.Component)) {
          rendered.props.children[3] = render(rendered.props.children[3]);
        }
      }
    } else if (!DomNode.isDomNode(rendered.props.children)) {
      const prototypeOfComponent = Reflect.getPrototypeOf(rendered.props.children.type);
      if (Object.is(prototypeOfComponent, React.Component)) {
        rendered.props.children = render(rendered.props.children);
      }
    }
  }
  return rendered;
}

function render(componentToRender) {
  const shallowRenderer = TestUtils.createRenderer();
  shallowRenderer.render(componentToRender);
  return shallowRenderer.getRenderOutput();
}

const ensureToBeArray = (mayBeArray) => Array.isArray(mayBeArray) ? mayBeArray : [mayBeArray];
const flatten = (arr, merged) => [...arr, ...merged];

function allChildren({props = {}}) {
  if (!props.children) {
    return [];
  }
  let children = ensureToBeArray(props.children);
  return [...children, ...children.map(allChildren).reduce(flatten)];
}

function allNodes(tree) {
  return [tree, ...allChildren(tree)];
}

//rendersDomNodeAttributeWithValue
//rendersDomNodeWithInnerText

//return (
//

//
//
{name}

//
{description}

//
//

//);
<commit_msg>Dynamically render one level deep.<commit_after>import React from 'react/addons';
import DomNode from './domnode.js';
const TestUtils = React.addons.TestUtils;

export default class DomNodes {
  static fromRenderedTree(tree) {
    let instance = new DomNodes();
    instance.domNodes = allNodes(tree)
      .filter(DomNode.isDomNode)
      .map(domNode => DomNode.fromRenderedNode(domNode));
    return instance;
  }

  static fromComponent(component) {
    return DomNodes.fromRenderedTree(renderRecursively(component));
  }
}

function _renderIfNeeded(component) {
  if (DomNode.isDomNode(component)) {
    return component;
  }
  const prototypeOfComponent = Reflect.getPrototypeOf(component.type);
  if (Object.is(prototypeOfComponent, React.Component)) {
    return render(component);
  }
}

function renderRecursively(componentToRender) {
  const rendered = render(componentToRender);
  if (rendered.props  && rendered.props.children){
    if (Array.isArray(rendered.props.children)) {
      rendered.props.children = rendered.props.children.map(_renderIfNeeded);
    } else if (!DomNode.isDomNode(rendered.props.children)) {
      rendered.props.children = _renderIfNeeded(rendered.props.children);
    }
  }
  return rendered;
}

function render(componentToRender) {
  const shallowRenderer = TestUtils.createRenderer();
  shallowRenderer.render(componentToRender);
  return shallowRenderer.getRenderOutput();
}

const ensureToBeArray = (mayBeArray) => Array.isArray(mayBeArray) ? mayBeArray : [mayBeArray];
const flatten = (arr, merged) => [...arr, ...merged];

function allChildren({props = {}}) {
  if (!props.children) {
    return [];
  }
  let children = ensureToBeArray(props.children);
  return [...children, ...children.map(allChildren).reduce(flatten)];
}

function allNodes(tree) {
  return [tree, ...allChildren(tree)];
}

//rendersDomNodeAttributeWithValue
//rendersDomNodeWithInnerText

//return (
//

//
//
{name}

//
{description}

//
//

//);
<|endoftext|>


<commit_before>import request from 'request'
import helpers from '../../../lib/test_helpers.js'

describe('cinema', () => { })
describe('cinema theaters', () => { })
<commit_msg>Remove unused variables<commit_after>describe('cinema', () => { })
describe('cinema theaters', () => { })
<|endoftext|>


<commit_before>var gpio = require('rpi-gpio');
var SPI = require('spi');

var mq7pin   = 24;
var onDelay = 60000;
var offDelay = 90000;
var count = 0;
var max   = 3;

gpio.setup(mq7pin, gpio.DIR_OUT, on);

var spi = new SPI.Spi('/dev/spidev0.0', {
    'mode': SPI.MODE['MODE_0'],  // always set mode as the first option
    'chipSelect': SPI.CS['none'] // 'none', 'high' - defaults to low
  }, function(s){
    s.maxSpeed(1000000);
    s.open();
  });
setInterval(function(){
  getADC(0);
  //getADC(1);
},500);
function on() {
    // if (count >= max) {
    //     gpio.destroy(function() {
    //         console.log('Closed pins, now exit');
    //     });
    //     return;
    // }

    setTimeout(function() {
        gpio.write(mq7pin, 1, off);
        console.log("ON");
        count += 1;
    }, onDelay);
}

function off() {
    setTimeout(function() {
        gpio.write(mq7pin, 0, on);
        console.log("OFF");
    }, offDelay);
}
var getADC = function(channel){
  var spiData =  new Buffer([1,(8+channel) << 4,0]);
  var rxbuf = new Buffer([ 0x00, 0x00, 0x00]);
  spi.transfer(spiData, rxbuf, function(device, buf) {
    //var ret=((buf[1] & 3) << 8) + buf[2];
    var ret = ((rxbuf [1]<<8)|rxbuf[2])&0x3FF;
    console.log("Channel " +channel +": " +ret);
  });
}
<commit_msg>adding mg135 back in<commit_after>var gpio = require('rpi-gpio');
var SPI = require('spi');

var mq7pin   = 24;
var onDelay = 60000;
var offDelay = 90000;
var count = 0;
var max   = 3;

gpio.setup(mq7pin, gpio.DIR_OUT, on);

var spi = new SPI.Spi('/dev/spidev0.0', {
    'mode': SPI.MODE['MODE_0'],  // always set mode as the first option
    'chipSelect': SPI.CS['none'] // 'none', 'high' - defaults to low
  }, function(s){
    s.maxSpeed(1000000);
    s.open();
  });
setInterval(function(){
  getADC(0);
  getADC(1);
},500);
function on() {
    // if (count >= max) {
    //     gpio.destroy(function() {
    //         console.log('Closed pins, now exit');
    //     });
    //     return;
    // }

    setTimeout(function() {
        gpio.write(mq7pin, 1, off);
        console.log("ON");
        count += 1;
    }, onDelay);
}

function off() {
    setTimeout(function() {
        gpio.write(mq7pin, 0, on);
        console.log("OFF");
    }, offDelay);
}
var getADC = function(channel){
  var spiData =  new Buffer([1,(8+channel) << 4,0]);
  var rxbuf = new Buffer([ 0x00, 0x00, 0x00]);
  spi.transfer(spiData, rxbuf, function(device, buf) {
    //var ret=((buf[1] & 3) << 8) + buf[2];
    var ret = ((rxbuf [1]<<8)|rxbuf[2])&0x3FF;
    console.log("Channel " +channel +": " +ret);
  });
}
<|endoftext|>


<commit_before>/*global ErizoGetUserMedia, L, document*/
/*
 * Class Stream represents a local or a remote Stream in the Room. It will handle the WebRTC stream
 * and identify the stream and where it should be drawn.
 */
var Erizo = Erizo || {};
Erizo.Stream = function (spec) {
    "use strict";
    var that = Erizo.EventDispatcher(spec),
        getFrame;
    that.stream = spec.stream;
    that.url = spec.url;
    that.room = undefined;
    that.showing = false;
    that.local = false;
    if (spec.local === undefined || spec.local === true) {
        that.local = true;
    }

    // Public functions

    that.getID = function () {
        return spec.streamID;
    };

    that.getAttributes = function () {
        return spec.attributes;
    };

    // Indicates if the stream has audio activated
    that.hasAudio = function () {
        return spec.audio;
    };

    // Indicates if the stream has video activated
    that.hasVideo = function () {
        return spec.video;
    };

    // Indicates if the stream has video activated
    that.hasData = function () {
        return spec.data;
    };

    // Sends data through this stream.
    that.sendData = function (msg) {};

    // Initializes the stream and tries to retrieve a stream from local video and audio
    // We need to call this method before we can publish it in the room.
    that.init = function () {
        try {
            if ((spec.audio || spec.video) && spec.url === undefined) {
                L.Logger.debug("Requested access to local media");
                Erizo.GetUserMedia({video: spec.video, audio: spec.audio}, function (stream) {
                //navigator.webkitGetUserMedia("audio, video", function (stream) {

                    L.Logger.info("User has granted access to local media.");
                    that.stream = stream;

                    var streamEvent = Erizo.StreamEvent({type: "access-accepted"});
                    that.dispatchEvent(streamEvent);

                }, function (error) {
                    L.Logger.error("Failed to get access to local media. Error code was " + error.code + ".");
                    var streamEvent = Erizo.StreamEvent({type: "access-denied"});
                    that.dispatchEvent(streamEvent);
                });
            } else {
                var streamEvent = Erizo.StreamEvent({type: "access-accepted"});
                that.dispatchEvent(streamEvent);
            }
        } catch (e) {
            L.Logger.error("Error accessing to local media");
        }
    };

    that.close = function () {
        if (that.local) {
            if (that.room !== undefined) {
                that.room.unpublish(that);
            }
            // Remove HTML element
            that.hide();
            if (that.stream !== undefined) {
                that.stream.stop();
            }
            that.stream = undefined;
        }
    };

    that.show = function (elementID, options) {
        that.elementID = elementID;
        if (that.hasVideo()) {
            // Draw on HTML
            if (elementID !== undefined) {
                var player = new Erizo.VideoPlayer({id: that.getID(), stream: that.stream, elementID: elementID, options: options});
                that.player = player;
                that.showing = true;
            }
        }
    };

    that.hide = function () {
        if (that.showing) {
            if (that.player !== undefined) {
                that.player.destroy();
                that.showing = false;
            }
        }
    };

    getFrame = function () {
        if (that.player !== undefined && that.stream !== undefined) {
            var video = that.player.video,

                style = document.defaultView.getComputedStyle(video),
                width = parseInt(style.getPropertyValue("width"), 10),
                height = parseInt(style.getPropertyValue("height"), 10),
                left = parseInt(style.getPropertyValue("left"), 10),
                top = parseInt(style.getPropertyValue("top"), 10),

                div = document.getElementById(that.elementID),
                divStyle = document.defaultView.getComputedStyle(div),
                divWidth = parseInt(divStyle.getPropertyValue("width"), 10),
                divHeight = parseInt(divStyle.getPropertyValue("height"), 10),

                canvas = document.createElement('canvas'),
                context;

            canvas.id = "testing";
            canvas.width = divWidth;
            canvas.height = divHeight;
            canvas.setAttribute('style', 'display: none');
            //document.body.appendChild(canvas);
            context = canvas.getContext('2d');

            context.drawImage(video, left, top, width, height);

            return canvas;
        } else {
            return null;
        }
    };

    that.getVideoFrameURL = function () {
        var canvas = getFrame();
        if (canvas !== null) {
            return canvas.toDataURL();
        } else {
            return null;
        }
    };

    that.getVideoFrame = function () {
        var canvas = getFrame();
        if (canvas !== null) {
            return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
        } else {
            return null;
        }
    };

    return that;
};<commit_msg>Added muted and volume controls<commit_after>/*global ErizoGetUserMedia, L, document*/
/*
 * Class Stream represents a local or a remote Stream in the Room. It will handle the WebRTC stream
 * and identify the stream and where it should be drawn.
 */
var Erizo = Erizo || {};
Erizo.Stream = function (spec) {
    "use strict";
    var that = Erizo.EventDispatcher(spec),
        getFrame;
    that.stream = spec.stream;
    that.url = spec.url;
    that.room = undefined;
    that.showing = false;
    that.local = false;
    if (spec.local === undefined || spec.local === true) {
        that.local = true;
    }

    // Public functions

    that.getID = function () {
        return spec.streamID;
    };

    that.getAttributes = function () {
        return spec.attributes;
    };

    // Indicates if the stream has audio activated
    that.hasAudio = function () {
        return spec.audio;
    };

    // Indicates if the stream has video activated
    that.hasVideo = function () {
        return spec.video;
    };

    // Indicates if the stream has video activated
    that.hasData = function () {
        return spec.data;
    };

    // Sends data through this stream.
    that.sendData = function (msg) {};

    // Initializes the stream and tries to retrieve a stream from local video and audio
    // We need to call this method before we can publish it in the room.
    that.init = function () {
        try {
            if ((spec.audio || spec.video) && spec.url === undefined) {
                L.Logger.debug("Requested access to local media");
                Erizo.GetUserMedia({video: spec.video, audio: spec.audio}, function (stream) {
                //navigator.webkitGetUserMedia("audio, video", function (stream) {

                    L.Logger.info("User has granted access to local media.");
                    that.stream = stream;

                    var streamEvent = Erizo.StreamEvent({type: "access-accepted"});
                    that.dispatchEvent(streamEvent);

                }, function (error) {
                    L.Logger.error("Failed to get access to local media. Error code was " + error.code + ".");
                    var streamEvent = Erizo.StreamEvent({type: "access-denied"});
                    that.dispatchEvent(streamEvent);
                });
            } else {
                var streamEvent = Erizo.StreamEvent({type: "access-accepted"});
                that.dispatchEvent(streamEvent);
            }
        } catch (e) {
            L.Logger.error("Error accessing to local media");
        }
    };

    that.close = function () {
        if (that.local) {
            if (that.room !== undefined) {
                that.room.unpublish(that);
            }
            // Remove HTML element
            that.hide();
            if (that.stream !== undefined) {
                that.stream.stop();
            }
            that.stream = undefined;
        }
    };

    that.show = function (elementID, options) {
        that.elementID = elementID;
        if (that.hasVideo()) {
            // Draw on HTML
            if (elementID !== undefined) {
                var player = new Erizo.VideoPlayer({id: that.getID(), stream: that, elementID: elementID, options: options});
                that.player = player;
                that.showing = true;
            }
        }
    };

    that.hide = function () {
        if (that.showing) {
            if (that.player !== undefined) {
                that.player.destroy();
                that.showing = false;
            }
        }
    };

    getFrame = function () {
        if (that.player !== undefined && that.stream !== undefined) {
            var video = that.player.video,

                style = document.defaultView.getComputedStyle(video),
                width = parseInt(style.getPropertyValue("width"), 10),
                height = parseInt(style.getPropertyValue("height"), 10),
                left = parseInt(style.getPropertyValue("left"), 10),
                top = parseInt(style.getPropertyValue("top"), 10),

                div = document.getElementById(that.elementID),
                divStyle = document.defaultView.getComputedStyle(div),
                divWidth = parseInt(divStyle.getPropertyValue("width"), 10),
                divHeight = parseInt(divStyle.getPropertyValue("height"), 10),

                canvas = document.createElement('canvas'),
                context;

            canvas.id = "testing";
            canvas.width = divWidth;
            canvas.height = divHeight;
            canvas.setAttribute('style', 'display: none');
            //document.body.appendChild(canvas);
            context = canvas.getContext('2d');

            context.drawImage(video, left, top, width, height);

            return canvas;
        } else {
            return null;
        }
    };

    that.getVideoFrameURL = function () {
        var canvas = getFrame();
        if (canvas !== null) {
            return canvas.toDataURL();
        } else {
            return null;
        }
    };

    that.getVideoFrame = function () {
        var canvas = getFrame();
        if (canvas !== null) {
            return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
        } else {
            return null;
        }
    };

    return that;
};<|endoftext|>


<commit_before>$("#sortable").sortable();
$("#sortable").disableSelection();

$("#sortable2").sortable();
$("#sortable2").disableSelection();
var numItems = 0;

var el;

$(document).ready(function(){

	//$('#wizard').smartWizard({transitionEffect:'slide', 'labelFinish': 'Save'});
	//$('#wizard').smartWizard({'labelFinish': 'Save', onLeaveStep:leaveAStepCallback,onFinish:onFinishCallback,enableFinishButton:true});
	$('#wizard').smartWizard({'labelFinish': 'Save', onLeaveStep:leaveAStepCallback, onFinish:onFinishCallback});

    $('#sortable').show();
    $('#holder').hide();
    $('#expand_div').hide();
    $('#collapse_div').hide();
    $('#dialog').hide();

    function leaveAStepCallback(obj){
      var step_num= obj.attr('rel');
      return validateSteps(step_num);
    }

    $('.stepContainer').height('462px');

    $('#expand').click( function() {
        $('#steps').hide();
        $('#expand_div').hide();
        $('#collapse_div').show();
        $('.stepContainer').width('1180px');
        $('.stepContainer').height('800px');
        $('.msg_content').width('1100px');
        $('.msg_content').height('800px');
        $('#holder').width('900px');
        $('#holder').height('700px');
        $('#content').height('900px');
    });
    $('#collapse').click( function() {
        $('#steps').show();
        $('#expand_div').show();
        $('#collapse_div').hide();
        $('.stepContainer').height('462px');
        $('.stepContainer').width('732px');
        $('.msg_content').width('720px');
        $('.msg_content').height('450px');
        $('#holder').width('550px');
        $('#holder').height('350px');
        //$('#content').height('900px');
    });

    var type = $('#type').val();
    if (type != undefined && type.length > 0) {
        gettypedescription();

    }
    $('#type').change(function() {
        gettypedescription();
     });

    function gettypedescription() {
        var type = $('#type').val();

        if (type == 'Category') {
			  $("#type_description").html("Concept is composed of 1 or more elements");

        } else if (type == 'Temporal'){
			  $("#type_description").html("Concept is composed of all elements");

        } else if (type == 'Workflow') {
			  $("#type_description").html("New Workflow based on System and User-defined types.");

        } else {

			  $("#type_description").html("");

        }

    }
    function onFinishCallback(){
     //if(validateAllSteps()){
    	var propositions = [];
    	var type = $('#type').val();
    	var element_name = $('#element_name').val();
    	var element_desc = $('#element_description').val();
       $('#sortable li').each( function () {
            console.log(this.id);
            var namespaceStr = '';//this.textContent.split("-")[0];
            if ($('#systemTree #'+this.id).length > 0) {
            	namespaceStr = 'system';

            } else {
            	namespaceStr = 'user';
            }
            var obj = {id: this.id, type: namespaceStr};
            propositions.push(obj);
        });
       $.ajax({
           type: "POST",
           url: "http://localhost:8080/eureka-webapp/saveprop?name="+element_name+
           			"&description="+element_desc +
           			"&type="+type+
           			"&proposition="+JSON.stringify(propositions),
           contentType: "application/json; charset=utf-8",
           data: JSON.stringify(propositions),
           dataType: "json",
           beforeSend: function(x) {
               if (x && x.overrideMimeType) {
                   x.overrideMimeType("application/j-son;charset=UTF-8");
               }
            },
           success: function(data) {
                  window.location.href="http://localhost:8080/eureka-webapp/editor.jsp";
           }
       });

      //$('form').submit();
     //}
    }

    function validateSteps(step){
    	var isStepValid = true;
    	// validate step 1
    	if(step == 1){
		  var element_name = $('#element_name').val();
		  var element_desc = $('#element_description').val();

		  if((!element_name && element_name.length <= 0) ||
				  (!element_desc && element_desc.length <= 0)){
			  isStepValid = false;
			  $('#wizard').smartWizard('showMessage','Please enter an element name and description and click next.');
			  $('#wizard').smartWizard('setError',{stepnum:step,iserror:true});
		  }
		  else{
			  $('#wizard').smartWizard('hideMessage','');
			  $('#wizard').smartWizard('setError',{stepnum:step,iserror:false});
		  }
    	} else if (step == 2) {
			  var str = $('#type').val();
			  //$("h3:last").html(str);
              if (str == 'Workflow') {
                    $('#sortable').hide();
                    $('#holder').show();
                    $('#expand_div').show();
              } else {
                    $('#sortable').show();
                    $('#holder').hide();
                    $('#expand_div').hide();

              }

    	} else if (step == 3) {

        } else if (step == 5) {

        }

    	return isStepValid;
    }

	var tabContainers = $('div.tabs > div');
	tabContainers.hide().filter(':first').show();

	$('div.tabs ul.tabNavigation a').click(function () {
		tabContainers.hide();
		tabContainers.filter(this.hash).show();
		$('div.tabs ul.tabNavigation a').removeClass('selected');
		$(this).addClass('selected');
		return false;
	}).filter(':first').click();

    initTrees();

});

function initTrees() {

   $("#systemTree").jstree({
		"json_data" : {
		    "ajax" : { "url" : "http://localhost:8080/eureka-webapp/systemlist?id=root" }
		},
		"dnd" : {
			"drop_finish" : function(data) {
				if (data.e.currentTarget.id == 'tree-drop') {
				    var type = $('#type').val();
				    $('<li/>', {
					    id: data.o[0].id,
					   // text: data.o[0].parentNode.parentNode.id + "-" + data.o[0].children[1].childNodes[1].textContent
						text:  data.o[0].children[1].childNodes[1].textContent
				    }).appendTo('#sortable');

				}

				numItems++;

			},
			"drag_check" : function(data) {
				if (data.r.attr("id") == "phtml_1") {
					return false;
				}
				return {
					after : false,
					before : false,
					inside : true
				};
			},
			"drag_finish" : function(data) {
				alert("DRAG OK");
			}
	},
	"plugins" : [ "themes", "json_data", "ui", "dnd" ]
	}).bind("select_node.jstree", function(e, data)
	{
	    if(data.rslt.obj[0].id !== undefined)
	    {
	        loadChild(data.rslt.obj[0].id);
	    }
	    else
	    {
	        alert("No href defined for this element");
	    }

	});

	function loadChild(parentNodeId, id) {
	    $.ajax({
	           type: "POST",
	           url: "http://localhost:8080/eureka-webapp/propdetail?propId="+id,
	           contentType: "application/json; charset=utf-8",
	           //data: "{'id':" + id + "}",
	           dataType: "json",
	           success: function(data) {
	               var childData = data;
                   console.log(childData)
	               //addNode(parentNodeId, id, childData.data, childData["attr"].id, false);
	           }
	       });

	}

	function addNode(rootNodeId, localParentId,nodeName,nodeId,hasChildren) {

	    ////////////////////////////////////////////
	    //
	    // Create a new node on the tree
	    //
	    ////////////////////////////////////////////
	    if(hasChildren) {

	        /// If it has children we load the node a little differently
	        /// give it a different image, theme and make it clickable

	        $("#" +rootNodeId).jstree("create_node", $("#"+localParentId), "inside",  { "data" : nodeName ,"state" : "closed","attr" : { "id" : nodeId,"rel":"children"}},null, true);

	    } else {

	        // Nodes with no trees cannot be opened and
	        // have a different image

	        $("#" + rootNodeId).jstree("create_node", $("#"+localParentId), "inside",  { "data" : nodeName ,"state" : "leaf","attr" : { "id" : nodeId,"rel":"noChildren"}},null, true);

	    }

	}

	$("#tab2").jstree({
		"json_data" : {
		    "ajax" : { "url" : "http://localhost:8080/eureka-webapp/userproplist?id=root" }
		},
		"dnd" : {
			"drop_finish" : function(data) {
				if (data.e.currentTarget.id == 'tree-drop') {
				    var type = $('#type').val();

				    $('<li/>', {
					    id: data.o[0].id,
					    text: data.o[0].parentNode.parentNode.id + "-" + data.o[0].children[1].childNodes[1].textContent
				    }).appendTo('#sortable');

				}

				numItems++;

			},
			"drag_check" : function(data) {
				if (data.r.attr("id") == "phtml_1") {
					return false;
				}
				return {
					after : false,
					before : false,
					inside : true
				};
			},
			"drag_finish" : function(data) {
				alert("DRAG OK");
			}
	},
	"plugins" : [ "themes", "json_data", "ui", "dnd" ]
	}).bind("select_node.jstree", function(e, data)
	{
	    if(data.rslt.obj[0].id !== undefined)
	    {
	        loadChild("tab2", data.rslt.obj[0].id);
	    }
	    else
	    {
	        alert("No href defined for this element");
	    }

	});

}

<commit_msg>integrated with AIW system elements.<commit_after>$("#sortable").sortable();
$("#sortable").disableSelection();

$("#sortable2").sortable();
$("#sortable2").disableSelection();
var numItems = 0;

var el;

$(document).ready(function(){

	//$('#wizard').smartWizard({transitionEffect:'slide', 'labelFinish': 'Save'});
	//$('#wizard').smartWizard({'labelFinish': 'Save', onLeaveStep:leaveAStepCallback,onFinish:onFinishCallback,enableFinishButton:true});
	$('#wizard').smartWizard({'labelFinish': 'Save', onLeaveStep:leaveAStepCallback, onFinish:onFinishCallback});

    $('#sortable').show();
    $('#holder').hide();
    $('#expand_div').hide();
    $('#collapse_div').hide();
    $('#dialog').hide();

    function leaveAStepCallback(obj){
      var step_num= obj.attr('rel');
      return validateSteps(step_num);
    }

    $('.stepContainer').height('462px');

    $('#expand').click( function() {
        $('#steps').hide();
        $('#expand_div').hide();
        $('#collapse_div').show();
        $('.stepContainer').width('1180px');
        $('.stepContainer').height('800px');
        $('.msg_content').width('1100px');
        $('.msg_content').height('800px');
        $('#holder').width('900px');
        $('#holder').height('700px');
        $('#content').height('900px');
    });
    $('#collapse').click( function() {
        $('#steps').show();
        $('#expand_div').show();
        $('#collapse_div').hide();
        $('.stepContainer').height('462px');
        $('.stepContainer').width('732px');
        $('.msg_content').width('720px');
        $('.msg_content').height('450px');
        $('#holder').width('550px');
        $('#holder').height('350px');
        //$('#content').height('900px');
    });

    var type = $('#type').val();
    if (type != undefined && type.length > 0) {
        gettypedescription();

    }
    $('#type').change(function() {
        gettypedescription();
     });

    function gettypedescription() {
        var type = $('#type').val();

        if (type == 'Category') {
			  $("#type_description").html("Concept is composed of 1 or more elements");

        } else if (type == 'Temporal'){
			  $("#type_description").html("Concept is composed of all elements");

        } else if (type == 'Workflow') {
			  $("#type_description").html("New Workflow based on System and User-defined types.");

        } else {

			  $("#type_description").html("");

        }

    }
    function onFinishCallback(){
     //if(validateAllSteps()){
    	var propositions = [];
    	var type = $('#type').val();
    	var element_name = $('#element_name').val();
    	var element_desc = $('#element_description').val();
       $('#sortable li').each( function () {
            console.log(this.id);
            var namespaceStr = '';//this.textContent.split("-")[0];
            if ($('#systemTree [id="'+this.id + '"]').length > 0) {
            	namespaceStr = 'system';

            } else {
            	namespaceStr = 'user';
            }
            var obj = {id: this.id, type: namespaceStr};
            propositions.push(obj);
        });
       $.ajax({
           type: "POST",
           url: "/saveprop?name="+element_name+
           			"&description="+element_desc +
           			"&type="+type+
           			"&proposition="+JSON.stringify(propositions),
           contentType: "application/json; charset=utf-8",
           data: JSON.stringify(propositions),
           dataType: "json",
           beforeSend: function(x) {
               if (x && x.overrideMimeType) {
                   x.overrideMimeType("application/j-son;charset=UTF-8");
               }
            },
           success: function(data) {
                  window.location.href="/editorhome";
           }
       });

      //$('form').submit();
     //}
    }

    function validateSteps(step){
    	var isStepValid = true;
    	// validate step 1
    	if(step == 1){
		  var element_name = $('#element_name').val();
		  var element_desc = $('#element_description').val();

		  if((!element_name && element_name.length <= 0) ||
				  (!element_desc && element_desc.length <= 0)){
			  isStepValid = false;
			  $('#wizard').smartWizard('showMessage','Please enter an element name and description and click next.');
			  $('#wizard').smartWizard('setError',{stepnum:step,iserror:true});
		  }
		  else{
			  $('#wizard').smartWizard('hideMessage','');
			  $('#wizard').smartWizard('setError',{stepnum:step,iserror:false});
		  }
    	} else if (step == 2) {
			  var str = $('#type').val();
			  //$("h3:last").html(str);
              if (str == 'Workflow') {
                    $('#sortable').hide();
                    $('#holder').show();
                    $('#expand_div').show();
              } else {
                    $('#sortable').show();
                    $('#holder').hide();
                    $('#expand_div').hide();

              }

    	} else if (step == 3) {

        } else if (step == 4) {

        }

    	return isStepValid;
    }

	var tabContainers = $('div.tabs > div');
	tabContainers.hide().filter(':first').show();

	$('div.tabs ul.tabNavigation a').click(function () {
		tabContainers.hide();
		tabContainers.filter(this.hash).show();
		$('div.tabs ul.tabNavigation a').removeClass('selected');
		$(this).addClass('selected');
		return false;
	}).filter(':first').click();

    initTrees();

});

function initTrees() {

   $("#systemTree").jstree({
		"json_data" : {
		    "ajax" : { "url" : "/systemlist?id=root" }
		},
		"dnd" : {
			"drop_finish" : function(data) {
				if (data.e.currentTarget.id == 'tree-drop') {
				    var type = $('#type').val();
				    $('<li/>', {
					    id: data.o[0].id,
					   // text: data.o[0].parentNode.parentNode.id + "-" + data.o[0].children[1].childNodes[1].textContent
						text:  data.o[0].children[1].childNodes[1].textContent
				    }).appendTo('#sortable');

				}

				numItems++;

			},
			"drag_check" : function(data) {
				if (data.r.attr("id") == "phtml_1") {
					return false;
				}
				return {
					after : false,
					before : false,
					inside : true
				};
			},
			"drag_finish" : function(data) {
				alert("DRAG OK");
			}
	},
	"plugins" : [ "themes", "json_data", "ui", "dnd" ]
	}).bind("select_node.jstree", function(e, data)
	{
	    if(data.rslt.obj[0].id !== undefined)
	    {
	    	if ($("[id='"+data.rslt.obj[0].id+ "']")[0].children.length < 3) {
	    		loadChild(data.rslt.obj[0].id);
	    	}
	    }
	    else
	    {
	        alert("No href defined for this element");
	    }

	});

	function loadChild(id) {
	    $.ajax({
	           type: "POST",
	           url: "/syspropchildren?propId="+id,
	           contentType: "application/json; charset=utf-8",
	           //data: "{'id':" + id + "}",
	           dataType: "json",
	           success: function(data) {
	               var childData = data;
                   console.log(childData);
                   for (var i = 0; i < childData.length; i++) {
                	   addNode("systemTree", id, childData[i].data, childData[i]["attr"].id, false);

                   }
	           }
	       });

	}

	function loadUserDefinedProps(id) {
	    $.ajax({
	           type: "POST",
	           url: "/userpropchildren?propId="+id,
	           contentType: "application/json; charset=utf-8",
	           //data: "{'id':" + id + "}",
	           dataType: "json",
	           success: function(data) {
	               var childData = data;
                   console.log(childData);
//                   for (var i = 0; i < childData.length; i++) {
//                	   addNode("systemTree", id, childData[i].data, childData[i]["attr"].id, false);
//
//                   }
	           }
	       });

	}

	function addNode(rootNodeId, localParentId,nodeName,nodeId,hasChildren) {

	    ////////////////////////////////////////////
	    //
	    // Create a new node on the tree
	    //
	    ////////////////////////////////////////////
	    if(hasChildren) {

	        /// If it has children we load the node a little differently
	        /// give it a different image, theme and make it clickable

	        $("#" +rootNodeId).jstree("create_node", $("[id='"+localParentId+"']"), "inside",  { "data" : nodeName ,"state" : "closed","attr" : { "id" : nodeId,"rel":"children"}},null, true);

	    } else {

	        // Nodes with no trees cannot be opened and
	        // have a different image

	        $("#" + rootNodeId).jstree("create_node", $("[id='"+localParentId+ "']"), "inside",  { "data" : nodeName ,"state" : "leaf","attr" : { "id" : nodeId,"rel":"noChildren"}},null, true);

	    }

	}

	$("#tab2").jstree({
		"json_data" : {
		    "ajax" : { "url" : "/userproplist?id=root" }
		},
		"dnd" : {
			"drop_finish" : function(data) {
				if (data.e.currentTarget.id == 'tree-drop') {
				    var type = $('#type').val();

				    $('<li/>', {
					    id: data.o[0].id,
					    text: data.o[0].parentNode.parentNode.id + "-" + data.o[0].children[1].childNodes[1].textContent
				    }).appendTo('#sortable');

				}

				numItems++;

			},
			"drag_check" : function(data) {
				if (data.r.attr("id") == "phtml_1") {
					return false;
				}
				return {
					after : false,
					before : false,
					inside : true
				};
			},
			"drag_finish" : function(data) {
				alert("DRAG OK");
			}
	},
	"plugins" : [ "themes", "json_data", "ui", "dnd" ]
	}).bind("select_node.jstree", function(e, data)
	{
	    if(data.rslt.obj[0].id !== undefined)
	    {
	    	if ($("[id='"+data.rslt.obj[0].id+ "']")[0].children.length < 3) {
	    		loadUserDefinedProps(data.rslt.obj[0].id);
	    	}
	    }
	    else
	    {
	        alert("No href defined for this element");
	    }

	});

}

<|endoftext|>


<commit_before><commit_msg>electron<commit_after><|endoftext|>


<commit_before>import {expect} from 'chai';
import QuerySet from '../QuerySet';
import {
    createTestSessionWithData,
} from './utils';
import deepFreeze from 'deep-freeze';

describe('Integration', () => {
    let session;
    let schema;
    let state;

    beforeEach(() => {
        ({
            session,
            schema,
            state,
        } = createTestSessionWithData());
    });

    describe('Immutable session', () => {
        beforeEach(() => {
            // Deep freeze state. This will raise an error if we
            // mutate the state.
            deepFreeze(state);
        });

        it('Initial data bootstrapping results in a correct state', () => {
            expect(state).to.have.all.keys(
                'Book', 'Cover', 'Genre', 'Author', 'BookGenres');

            expect(state.Book.items).to.have.length(3);
            expect(Object.keys(state.Book.itemsById)).to.have.length(3);

            expect(state.Cover.items).to.have.length(3);
            expect(Object.keys(state.Cover.itemsById)).to.have.length(3);

            expect(state.Genre.items).to.have.length(4);
            expect(Object.keys(state.Genre.itemsById)).to.have.length(4);

            expect(state.BookGenres.items).to.have.length(5);
            expect(Object.keys(state.BookGenres.itemsById)).to.have.length(5);

            expect(state.Author.items).to.have.length(3);
            expect(Object.keys(state.Author.itemsById)).to.have.length(3);
        });

        it('Models correctly create new instances', () => {
            const {Book} = session;
            expect(session.updates).to.have.length(0);
            const book = Book.create({
                name: 'New Book',
                author: 0,
                releaseYear: 2015,
            });
            expect(session.updates).to.have.length(1);

            const nextState = session.reduce();
            const nextSession = schema.from(nextState);
            expect(nextSession.Book.count()).to.equal(4);
        });

        it('Models correctly update when setting properties', () => {
            const {Book} = session;
            const book = Book.first();
            const newName = 'New Name';
            expect(session.updates).to.have.length(0);
            book.name = newName;
            expect(session.updates).to.have.length(1);

            const nextState = session.reduce();
            const nextSession = schema.from(nextState);
            expect(nextSession.Book.first().name).to.equal(newName);
        });

        it('withId throws if model instance not found', () => {
            const { Book } = session;
            expect(() => Book.withId(10)).to.throw(Error);
        });

        it('many-to-many relationship descriptors work', () => {
            const {
                Book,
                Genre,
            } = session;

            // Forward (from many-to-many field declaration)
            const book = Book.first();
            const relatedGenres = book.genres;
            expect(relatedGenres).to.be.an.instanceOf(QuerySet);
            expect(relatedGenres.modelClass).to.equal(Genre);
            expect(relatedGenres.count()).to.equal(2);

            // Backward
            const genre = Genre.first();
            const relatedBooks = genre.books;
            expect(relatedBooks).to.be.an.instanceOf(QuerySet);
            expect(relatedBooks.modelClass).to.equal(Book);
        });

        it('foreign key relationship descriptors work', () => {
            const {
                Book,
                Author,
            } = session;

            // Forward
            const book = Book.first();
            const author = book.author;
            const rawFk = book.ref.author;
            expect(author).to.be.an.instanceOf(Author);
            expect(author.getId()).to.equal(rawFk);

            // Backward
            const relatedBooks = author.books;
            expect(relatedBooks).to.be.an.instanceOf(QuerySet);
            expect(relatedBooks.idArr).to.include(book.getId());
            expect(relatedBooks.modelClass).to.equal(Book);
        });

        it('one-to-one relationship descriptors work', () => {
            const {
                Book,
                Cover,
            } = session;

            // Forward
            const book = Book.first();
            const cover = book.cover;
            const rawFk = book.ref.cover;
            expect(cover).to.be.an.instanceOf(Cover);
            expect(cover.getId()).to.equal(rawFk);

            // Backward
            const relatedBook = cover.book;
            expect(relatedBook).to.be.an.instanceOf(Book);
            expect(relatedBook.getId()).to.equal(book.getId());
        });

        it('applying no updates returns the same state reference', () => {
            const nextState = session.reduce();
            expect(nextState).to.equal(state);
        });
    });

    describe('Mutating session', () => {
        it('works', () => {
            const mutating = schema.withMutations(state);
            const {
                Book,
                Cover,
            } = mutating;

            const cover = Cover.create({src: 'somecover.png'});
            const coverId = cover.getId();

            const book = Book.first();
            const bookRef = book.ref;
            const bookId = book.getId();
            expect(state.Book.itemsById[bookId]).to.equal(bookRef);
            const newName = 'New Name';

            book.name = newName;

            expect(book.name).to.equal(newName);

            const nextState = mutating.reduce();
            expect(nextState).to.equal(state);
            expect(state.Book.itemsById[bookId]).to.equal(bookRef);
            expect(bookRef.name).to.equal(newName);
            expect(state.Cover.itemsById[coverId].src).to.equal('somecover.png');
        });
    });
});
<commit_msg>Add test that deletes a model<commit_after>import {expect} from 'chai';
import QuerySet from '../QuerySet';
import {
    createTestSessionWithData,
} from './utils';
import deepFreeze from 'deep-freeze';

describe('Integration', () => {
    let session;
    let schema;
    let state;

    beforeEach(() => {
        ({
            session,
            schema,
            state,
        } = createTestSessionWithData());
    });

    describe('Immutable session', () => {
        beforeEach(() => {
            // Deep freeze state. This will raise an error if we
            // mutate the state.
            deepFreeze(state);
        });

        it('Initial data bootstrapping results in a correct state', () => {
            expect(state).to.have.all.keys(
                'Book', 'Cover', 'Genre', 'Author', 'BookGenres');

            expect(state.Book.items).to.have.length(3);
            expect(Object.keys(state.Book.itemsById)).to.have.length(3);

            expect(state.Cover.items).to.have.length(3);
            expect(Object.keys(state.Cover.itemsById)).to.have.length(3);

            expect(state.Genre.items).to.have.length(4);
            expect(Object.keys(state.Genre.itemsById)).to.have.length(4);

            expect(state.BookGenres.items).to.have.length(5);
            expect(Object.keys(state.BookGenres.itemsById)).to.have.length(5);

            expect(state.Author.items).to.have.length(3);
            expect(Object.keys(state.Author.itemsById)).to.have.length(3);
        });

        it('Models correctly create new instances', () => {
            const {Book} = session;
            expect(session.updates).to.have.length(0);
            const book = Book.create({
                name: 'New Book',
                author: 0,
                releaseYear: 2015,
            });
            expect(session.updates).to.have.length(1);

            const nextState = session.reduce();
            const nextSession = schema.from(nextState);
            expect(nextSession.Book.count()).to.equal(4);
        });

        it('Models are correctly deleted', () => {
            const { Book } = session;
            expect(Book.count()).to.equal(3);

            Book.withId(0).delete();

            const nextState = session.reduce();
            const nextSession = schema.from(nextState);
            expect(nextSession.Book.count()).to.equal(2);
        });

        it('Models correctly update when setting properties', () => {
            const {Book} = session;
            const book = Book.first();
            const newName = 'New Name';
            expect(session.updates).to.have.length(0);
            book.name = newName;
            expect(session.updates).to.have.length(1);

            const nextState = session.reduce();
            const nextSession = schema.from(nextState);
            expect(nextSession.Book.first().name).to.equal(newName);
        });

        it('withId throws if model instance not found', () => {
            const { Book } = session;
            expect(() => Book.withId(10)).to.throw(Error);
        });

        it('many-to-many relationship descriptors work', () => {
            const {
                Book,
                Genre,
            } = session;

            // Forward (from many-to-many field declaration)
            const book = Book.first();
            const relatedGenres = book.genres;
            expect(relatedGenres).to.be.an.instanceOf(QuerySet);
            expect(relatedGenres.modelClass).to.equal(Genre);
            expect(relatedGenres.count()).to.equal(2);

            // Backward
            const genre = Genre.first();
            const relatedBooks = genre.books;
            expect(relatedBooks).to.be.an.instanceOf(QuerySet);
            expect(relatedBooks.modelClass).to.equal(Book);
        });

        it('foreign key relationship descriptors work', () => {
            const {
                Book,
                Author,
            } = session;

            // Forward
            const book = Book.first();
            const author = book.author;
            const rawFk = book.ref.author;
            expect(author).to.be.an.instanceOf(Author);
            expect(author.getId()).to.equal(rawFk);

            // Backward
            const relatedBooks = author.books;
            expect(relatedBooks).to.be.an.instanceOf(QuerySet);
            expect(relatedBooks.idArr).to.include(book.getId());
            expect(relatedBooks.modelClass).to.equal(Book);
        });

        it('one-to-one relationship descriptors work', () => {
            const {
                Book,
                Cover,
            } = session;

            // Forward
            const book = Book.first();
            const cover = book.cover;
            const rawFk = book.ref.cover;
            expect(cover).to.be.an.instanceOf(Cover);
            expect(cover.getId()).to.equal(rawFk);

            // Backward
            const relatedBook = cover.book;
            expect(relatedBook).to.be.an.instanceOf(Book);
            expect(relatedBook.getId()).to.equal(book.getId());
        });

        it('applying no updates returns the same state reference', () => {
            const nextState = session.reduce();
            expect(nextState).to.equal(state);
        });
    });

    describe('Mutating session', () => {
        it('works', () => {
            const mutating = schema.withMutations(state);
            const {
                Book,
                Cover,
            } = mutating;

            const cover = Cover.create({src: 'somecover.png'});
            const coverId = cover.getId();

            const book = Book.first();
            const bookRef = book.ref;
            const bookId = book.getId();
            expect(state.Book.itemsById[bookId]).to.equal(bookRef);
            const newName = 'New Name';

            book.name = newName;

            expect(book.name).to.equal(newName);

            const nextState = mutating.reduce();
            expect(nextState).to.equal(state);
            expect(state.Book.itemsById[bookId]).to.equal(bookRef);
            expect(bookRef.name).to.equal(newName);
            expect(state.Cover.itemsById[coverId].src).to.equal('somecover.png');
        });
    });
});
<|endoftext|>