Removes unused scripts
diff --git a/asterix-app/src/main/resources/sdk/static/cherry/js/asterix-api-core.js b/asterix-app/src/main/resources/sdk/static/cherry/js/asterix-api-core.js
deleted file mode 100755
index 9553997..0000000
--- a/asterix-app/src/main/resources/sdk/static/cherry/js/asterix-api-core.js
+++ /dev/null
@@ -1,462 +0,0 @@
-/**
-* Asterix Core API
-* @returns {AsterixCoreAPI} AsterixCoreAPI
-*/
-function AsterixCoreAPI() {
- this.parameters = {
- "statements" : [],
- "mode" : "synchronous"
- };
- this.ui_callback_on_success = function() {};
- this.ui_callback_on_success_async = function() {};
- this.on_error = function() {};
- this.extra = {};
- return this;
-}
-
-/** Parameter Management **/
-
-/**
-* Sets the dataverse of this Asterix API call
-* @param {String} dataverse
-* @returns {AsterixCoreAPI} AsterixCoreAPI
-*/
-AsterixCoreAPI.prototype.dataverse = function (dataverse) {
- this.dataverse = dataverse;
- return this;
-}
-
-/**
-* Set the on-success callback of the api call
-* @param {Function} on_success
-* @param {Boolean} is_synchronous
-* @returns {AsterixCoreAPI} AsterixCoreAPI
-*/
-AsterixCoreAPI.prototype.success = function(on_success, is_synchronous) {
- if (is_synchronous) {
- this.ui_callback_on_success = on_success;
- } else {
- this.ui_callback_on_success_async = on_success;
- }
-
- return this;
-}
-
-/**
-* Set the on-error callback of the api call
-* @param {Function} on_error
-* @returns {AsterixCoreAPI} AsterixCoreAPI
-*/
-AsterixCoreAPI.prototype.error = function(on_error) {
- this.on_error = on_error;
- return this;
-}
-
-/**
-* Sets a parameter key, value
-* @param {String} param_key
-* @param {Object} param_value
-* @returns {AsterixCoreAPI} AsterixCoreAPI
-*/
-AsterixCoreAPI.prototype.parameter = function (param_key, param_value) {
- this.parameters[param_key] = param_value;
- return this;
-}
-
-/**
-* Sets query statements
-* @param {Array} statements
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.statements = function (statements) {
- this.parameters["statements"] = statements;
- return this;
-}
-
-/**
-* Pushes a single query statement
-* @param {String} statement containing one line of a query
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.add_statement = function (statement) {
- this.parameters["statements"].push(statement);
- return this;
-}
-
-/**
-* Sets synchronization mode
-* @param {String} sync, either "synchronous" or "asynchronous"
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.mode = function(sync) {
- this.parameters["mode"] = sync;
- return this;
-}
-
-/**
-* Extra data to run on success
-* @param {String} extra_key
-* @param {Object} extra_value
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.add_extra = function(extra_key, extra_value) {
- this.extra[extra_key] = extra_value;
- return this;
-}
-
-/**
-* Create a dataset of a given type with a given key (optional)
-* @param {Object} param: keys "dataset", "type", "primary_key",
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.create_dataset = function(param) {
- // Parse create object
- var create_statement = 'create dataset ' + param["dataset"] + '(' + param["type"] + ')';
- if (param.hasOwnProperty("primary_key")) {
- create_statement += ' primary key ' + param["primary_key"] + ';';
- }
-
- // Add to statements
- this.parameters["statements"].push(create_statement);
-
- return this;
-}
-
-/**
-* Drop a dataset of a given name
-* @param {String} dataset
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.drop_dataset = function(dataset) {
- var drop_statement = 'drop dataset ' + dataset + ';';
- this.parameters["statements"].push(drop_statement);
- return this;
-}
-
-/**
-* Reference a query given a query object
-* @param {Object} async_handle, an opaque handle from a prior asynchronous query
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.handle = function(async_handle) {
- this.query_handle = async_handle;
- return this;
-}
-
-/**
-* @param {Object} for : {"var" in "dataset"}
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.aql_for = function(for_object) {
- var for_statement = "for $";
- for (var key in for_object) {
- for_statement += key + " in dataset " + for_object[key];
- }
-
- this.parameters["statements"].push(for_statement);
- return this;
-}
-
-/**
-* @param {Object} let : {"key" => "values"}
-* @returns {AsterixCoreAPI} this API object
-*
-* TODO This one needs work - hacky
-*/
-AsterixCoreAPI.prototype.aql_let = function(let_object) {
- var let_statement = "";
-
- for (var var_name in let_object) {
- let_statement = 'let $' + var_name + ' := ' + let_object[var_name];
- this.parameters["statements"].push(let_statement);
- }
-
- return this;
-}
-
-/**
-* @param {Array} where_object : [statements]
-* @returns {AsterixCoreAPI} this API object
-*
-* TODO Fix me
-*/
-AsterixCoreAPI.prototype.aql_where = function(where_object) {
- this.parameters["statements"].push("where " + where_object.join(" and "));
- return this;
-}
-
-/**
-* @param {Object} groupby, a map { "groupby" , "with" }
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.aql_groupby = function(groupby_object) {
- var groupby_statement = "group by " + groupby_object["groupby"];
- groupby_statement += " with " + groupby_object["with"];
-
- this.parameters["statements"].push(groupby_statement);
-
- return this;
-}
-
-/**
-* Prepares a return statement of keys and value variables
-* @param {Object} return { "keys" => "values" }
-* @returns {AsterixCoreAPI} this API object
-*/
-AsterixCoreAPI.prototype.aql_return = function(return_object) {
- var components = [];
- for (var key in return_object) {
- components.push('"' + key + '" : ' + return_object[key]);
- }
-
- var return_statement = 'return { ' + components.join(', ') + ' }';
- this.parameters["statements"].push(return_statement);
-
- return this;
-}
-
-/** API Calls: Query API **/
-
-/**
-* Query
-*
-* @rest-parameter {String, REQUIRED} query, query string to pass to ASTERIX
-* @rest-parameter {String} mode, whether a call is "synchronous" or "asynchronous"
-* @rest-result {Object}
-* {
-* @result <result as a string, if mode = synchronous>
-* @error-code [<code>, <message>] if an error occurs
-* @handle: <opaqure result handle, if mode = asynchronous>
-* }
-* @endpoint {Asterix REST API} /query
-*/
-AsterixCoreAPI.prototype.api_core_query = function () {
-
- var api = this;
- var use_dataverse = "use dataverse " + api.dataverse + ";\n";
- var callbacks = {
- "sync" : api.ui_callback_on_success,
- "async" : api.ui_callback_on_success_async
- };
- var json = {
- "endpoint" : "http://localhost:19101/query",
- "query" : use_dataverse + api.parameters["statements"].join("\n"),
- "mode" : api.parameters["mode"]
- };
-
- api.api_helper_proxy_handler(json, callbacks, api.extra);
-}
-
-/**
-* Query Status
-*
-* @rest-parameter {Object, REQUIRED} handle, opaque result handle from previous asynchronous query call
-* @rest-result {Object}
-* {
-* @status: ("RUNNING" | "SUCCESS" | "ERROR" )
-* }
-* @endpoint {Asterix REST API} /query/status
-*/
-AsterixCoreAPI.prototype.api_core_query_status = function () {
-
- var api = this;
-
- var use_dataverse = "use dataverse " + api.dataverse + ";\n";
-
- var callbacks = {
- "sync" : this.ui_callback_on_success
- };
-
- var json = {
- "endpoint" : "http://localhost:19101/query/status",
- "handle" : api.query_handle
- };
-
- api.api_helper_proxy_handler(json, callbacks, api.extra);
-}
-
-/**
-* Query Result
-*
-* @rest-parameter {Object, REQUIRED} handle, opaque result handle from previous asynchronous query call
-* @rest-parameter {String} mode, "synchronous" by default, "asynchronous" if not
-* @rest-result {Object}
-* {
-* @result <result as a string, if mode = synchronous or asynchrous result available
-* {} if mode is asynchronous and results not available >
-* @error-code [<code>, <message>] if an error occurs
-* }
-* @endpoint {Asterix REST API} /query/result
-*/
-AsterixCoreAPI.prototype.api_core_query_result = function () {
-
- var api = this;
-
- var use_dataverse = "use dataverse " + api.dataverse + ";\n";
-
- var callbacks = {
- "sync" : this.ui_callback_on_success
- };
-
- var json = {
- "endpoint" : "http://localhost:19101/query/result",
- "handle" : api.query_handle
- };
-
- api.api_helper_proxy_handler(json, callbacks, api.extra);
-}
-
-/** API Calls - Update API **/
-
-/**
-* Update
-*
-* @rest-parameter
-*/
-AsterixCoreAPI.prototype.api_core_update = function () {
-
- var api = this;
-
- var dataverse_statement = 'use dataverse ' + this.dataverse + '; ';
-
- var json = {
- "endpoint" : "http://localhost:19101/update",
- "statements" : dataverse_statement + this.parameters["statements"].join(" ")
- };
-
- $.ajax({
- type : 'POST',
- url: "ajaxFacadeCherry.php",
- data: json,
- dataType: "json",
- success: function(data) {
-
- // Update API special case
- if (data == "") {
- api.ui_callback_on_success(api.extra);
-
- } else {
- var response = $.parseJSON(data[0]);
-
- if (response && response["error-code"]) {
-
- api.api_helper_default_on_error(response["error-code"][0], response["error-code"][1]);
-
- } else if (response && response["results"]) {
-
- alert("Response: " + response["results"]);
-
- } else if (!response) {
-
- api.api_helper_default_on_error(4, "Update API Call Error");
-
- }
- }
- }
-
- });
-}
-
-/** API Calls - DDL API **/
-
-/**
-* DDL
-*
-* @rest-parameter {Object, REQUIRED} DDL
-* @rest-result {Object}
-* {
-* @result: <array of results, one per DDL statement in input>
-* }
-* @endpoint {Asterix REST API} /ddl
-*/
-AsterixCoreAPI.prototype.api_core_ddl = function () {
- var api = this;
-
- var dataverse_statement = 'use dataverse ' + this.dataverse + '; ';
-
- var json = {
- "endpoint" : "http://localhost:19101/ddl",
- "ddl" : dataverse_statement + this.parameters["statements"].join(" ")
- };
-
- var callback = {
- "sync" : api.ui_callback_on_success
- };
-
- api.api_helper_proxy_handler(json, callback, api.extra);
-}
-
-/** API Utilities **/
-
-/**
-* API Helper - Proxy Handler [TEMPORARY]
-*
-* @param {Object} json, the JSON object containing the parameters and endpoint for this API call
-* @param {Objct} callback, the on-success callbacks for this handler
-* {
-* "sync" : default callback
-* "async" : non-default callback
-* }
-* @param {Object} extra, any extra stuff passed from UI [TEMPORARY]
-*/
-AsterixCoreAPI.prototype.api_helper_proxy_handler = function(json, callback, extra) {
-
- /*var callbacks = {
- "sync" : api.ui_callback_on_success,
- "async" : api.ui_callback_on_success_async
- };
- var json = {
- "endpoint" : "http://localhost:19101/query",
- "query" : use_dataverse + api.parameters["statements"].join("\n"),
- "mode" : api.parameters["mode"]
- };*/
- var as = new AsterixSDK();
- api = this;
-
- var branch = function(response) {
-
- if (response && response["error-code"]) {
-
- api.api_helper_default_on_error( response["error-code"][0], response["error-code"][1] );
-
- } else if (response && response["results"]) {
- var fn_callback = callback["sync"];
- fn_callback(response, extra);
-
- } else if (response["handle"]) {
-
- var fn_callback = callback["async"];
- fn_callback(response, extra);
-
- } else if (response["status"]) {
-
- var fn_callback = callback["sync"];
- fn_callback(response, extra);
- }
- };
-
- var c = {
- "onSend" : function() {
- return {
- "endpoint" : json["endpoint"],
- "apiData" : {
- "query" : json["query"],
- "mode" : json["mode"]
- },
- "callback" : branch
- };
- }
- };
- as.send(c);
-}
-
-/**
-* API Helper - Error Handler
-* Currently does an alert, but a more graceful notification would be better.
-*
-* @param {Number} error_code, ( 1 | 2 | 99 ) denoting type of error
-* @param {String} error_message, an informative message about the error
-*/
-AsterixCoreAPI.prototype.api_helper_default_on_error = function (error_code, error_message) {
- alert("ERROR " + error_code + ": " + error_message);
-}
diff --git a/asterix-app/src/main/resources/sdk/static/client.html b/asterix-app/src/main/resources/sdk/static/client.html
deleted file mode 100644
index d421a7a..0000000
--- a/asterix-app/src/main/resources/sdk/static/client.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
- <script src="js/easyXDM.debug.js" type="text/javascript"></script>
- <script src="js/asterix-api-core.js" type="text/javascript"></script>
- <script>
- var a = new AsterixSDK();
- a.requestHandler();
- </script>
- </head>
- <body>
- 'ello
- </body>
-</html>
diff --git a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js b/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
deleted file mode 100644
index 442842b..0000000
--- a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
+++ /dev/null
@@ -1,499 +0,0 @@
-// AsterixSDK
-// Core Object for REST API communication
-// Handles callbacks to client applications, communication to REST API, and
-// endpoint selection. Initializes an RPC consumer object.
-//
-// Usage:
-// var a = new AsterixSDK();
-function AsterixSDK() {
-
- // Asterix SDK request handler initialization
- // TODO Depending on configuration, may need multiples of these...
- this.xhr = new easyXDM.Rpc({
- remote: "http://localhost:19002/sdk/static/client.html"
- }, {
- remote: {
- post: {}
- }
- });
-
-
- // Asterix SDK => send
- // Posts a message containing an API endpoint, json data,
- // and a UI callback function.
- //
- // @param handler [Asterix REST Controller], a handler object
- // that provides REST request information.
- //
- // Anticipated Usage:
- //
- // var a = AsterixSDK();
- // var e = Expression;
- // var h = AsterixRestController.bindExpression(e);
- // a.send(h);
- myThis = this;
- this.callbacks = {
- "sync" : function() { alert("default sync"); },
- "async" : function() {}
- };
- this.send = function(handler, cb) {
- myThis.callbacks = cb;
- this.handler = handler;
- this.extras = handler["extras"];
- this.xhr.post(
- handler["endpoint"],
- handler["apiData"],
- this.branch
- );
- };
-
-
- // TODO DOC
- this.branch = function(response) {
- if (response && response["error-code"]) {
-
- alert("Error [Code" + response["error-code"][0] + "]: " + response["error-code"][1]);
-
- } else if (response && response["results"]) {
- var fn_callback = myThis.callbacks["sync"];
- fn_callback(response, myThis.extras);
-
- } else if (response["handle"]) {
-
- var fn_callback = this.callbacks["async"];
- fn_callback(response, extra);
-
- } else if (response["status"]) {
-
- var fn_callback = this.callbacks["sync"];
- fn_callback(response, extra);
- }
- }
-
-
- // Asterix SDK => requestHandler
- // Handlers remote requests to Asterix REST API
- // using the easyXDM RPC protocol
- // Usually should only be called by client side, could be overridden
- // TODO Get rid of jQuery ajax notation in favor of xmlhttprequest pure js
- this.requestHandler = function() {
- var rpc = new easyXDM.Rpc({}, {
- local: {
- post: {
- method: function(url, data, fn, fnError){
- $.ajax({
- type : 'GET',
- url : url,
- data : data,
- dataType : "json",
- success : function(res) {
- fn(res);
- }
- });
- }
- }
- }
- });
- }
-
-
- // Asterix SDK => bindingHandler
- // AsterixExpression form handler where a new REST API point is bound. Takes as input any
- // AsterixExpression, each of which is bindable.
- this.bindingHandler = new AsterixExpression();
- this.bind = this.bindingHandler.bind;
-}
-
-// AsterixExpression => Base AQL Syntax Class
-//
-// Components:
-// boundTo -> a "next" expression
-function AsterixExpression() {
- this.init();
- return this;
-}
-
-AsterixExpression.prototype.init = function () {
- this.dataverse = ""; // TODO This shouldn't make it to send
- this.boundTo = {};
- this.clauses = [];
- this.ui_callback_on_success = function() {};
- this.ui_callback_on_success_async = function() {};
-};
-
-// AsterixExpression => bind
-//
-// Binds a "next" AsterixExpression to this one.
-//
-// @param expression [AsterixExpression] MUST be instanceof AsterixExpression
-// TODO Check if it has a bind method or things will get messy.
-AsterixExpression.prototype.bind = function(expression) {
- // If expression is an AsterixExpression, it becomes base
- if (expression instanceof AsterixExpression) {
- this.boundTo = expression;
- } else if (expression instanceof AsterixClause) {
- this.clauses.push(expression.val());
- }
- return this;
-};
-
-// AsterixExpression => send
-//
-// @param arc [AsterixRESTController]
-// TODO: Arc parameter is temporary
-AsterixExpression.prototype.send = function(arc) {
- // Hackiest of hacks
- var g = new AsterixSDK();
- g.send(arc, arc["callback"]);
-};
-
-// AsterixExpression => clear
-//
-// Clears clauses array
-AsterixExpression.prototype.clear = function() {
- this.clauses.length = 0;
- return this;
-};
-
-// AsterixExpression => value
-//
-// Retrieves string value of current expression
-AsterixExpression.prototype.val = function() {
- return this.clauses.join("\n");
-};
-
-// AsterixExpression => success
-//
-// @param method [FUNCTION]
-// @param isSynchronous [BOOLEAN]
-AsterixExpression.prototype.success = function(fn, isSync) {
- if (isSync) {
- this.ui_callback_on_success = fn;
- } else {
- this.ui_callback_on_success_async = fn;
- }
- return this;
-};
-
-// AsterixExpression => set
-// Pushes statements onto the clause stack
-//
-// TODO typecheck
-// @param statements_arr [ARRAY]
-AsterixExpression.prototype.set = function(statements_arr) {
- for (var i = 0; i < statements_arr.length; i++) {
- this.clauses.push(statements_arr[i]);
- }
- return this;
-};
-
-// AsterixExpression => dataverse
-//
-// Sets the dataverse for a given api call
-AsterixExpression.prototype.use_dataverse = function(dv) {
- this.dataverse = dv;
- this.clauses.push("use dataverse " + dv + ";");
- return this;
-};
-
-AsterixExpression.prototype.return = function(return_object) {
- var components = [];
- for (var key in return_object) {
- components.push('"' + key + '" : ' + return_object[key]);
- }
-
- var return_expression = 'return { ' + components.join(', ') + ' }';
- this.clauses.push(return_expression);
- return this;
-};
-
-//////////////
-/*
-inherit(FLWOGRExpression, AsterixExpression);
-
-function FLWOGRExpression() {
- AsterixExpression.prototype.init.call(this);
- return this;
-} // ( ForClause | LetClause ) ( Clause )* "return" Expression
-
-function CreateExpression() {
- AsterixExpression.prototype.init.call(this);
- return this;
-} // "create" ( "type" | "nodegroup" | "external" <DATASET> | <DATASET> | "index" | "dataverse"
-
-
-
-
-function LegacyExpression() {
- AsterixExpression.prototype.init.call(this);
- return this;
-} // Legacy for old AsterixAPI version: handle hardcoded strings. Will phase out.
-
-function FunctionCallExpr() {
- AsterixExpression.prototype.init.call(this);
- return this;
-} //( <IDENTIFIER> | <DATASET> ) <LEFTPAREN> ( Expression ( "," Expression )* )? <RIGHTPAREN>
-
-inherit(CreateExpression, AsterixExpression);
-inherit(LegacyExpression, AsterixExpression);
-inherit(FunctionCallExpr, AsterixExpression);
-
-CreateExpression.prototype.send = function() {
- myThis = this;
- var arc = new AsterixRESTController();
- arc.DDL(
- { "ddl" : myThis.val() },
- {
- "sync" : function () {}, // TODO This should be a default value out of the AsterixExpression base
- "async" : function () {}
- }
- );
-
- // Call AsterixExpression core send method
- AsterixExpression.prototype.send.call(this, arc);
-};
-
-// LegacyExpression
-// Handles hardcoded query strings from prior versions
-// of this API. Can be useful for debugging.
-LegacyExpression.prototype.send = function(endpoint, json) {
-
- var arc = {
- "endpoint" : endpoint,
- "apiData" : json,
- "callback" : {
- "sync" : this.ui_callback_on_success,
- "async" : this.ui_callback_on_success_async
- },
- "extras" : this.extras
- };
-
- AsterixExpression.prototype.send.call(this, arc);
-}
-
-LegacyExpression.prototype.extra = function(extras) {
- this.extras = extras;
- return this;
-}
-
-// TODO DOC
-FunctionCallExpr.prototype.set = function(identifier, expressions) {
- var expression_clause = identifier + "(";
- expression_clause += expressions[0].val();
- for (var e = 1; e < expressions.length; e++) {
- expression_clause += "," + expressions[e].val();
- }
- expression_clause += ")";
-
- AsterixExpression.prototype.set.call(this, expression_clause);
- return this;
-} //( <IDENTIFIER> | <DATASET> ) <LEFTPAREN> ( Expression ( "," Expression )* )? <RIGHTPAREN>
-
-//
-// Clauses
-//
-function AsterixClause() {
- this.clause = "";
- return this;
-}
-
-AsterixClause.prototype.val = function() {
- return this.clause;
-};
-
-AsterixClause.prototype.set = function(clause) {
- this.clause = clause;
- return this;
-};
-
-function ForClause() {} // "for" Variable ( "at" Variable )? "in" ( Expression )
-function LetClause() {} // "let" Variable ":=" Expression
-function WhereClause() {} // "where" Expression
-function OrderbyClause() {} // ( "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )* )
-function GroupClause() {} // "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )*
- // ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
-function LimitClause() {} // "limit" Expression ( "offset" Expression )?
-function DistinctClause() {} // "distinct" "by" Expression ( "," Expression )*
-
-inherit(ForClause, AsterixClause);
-inherit(LetClause, AsterixClause);
-inherit(WhereClause, AsterixClause);
-inherit(OrderbyClause, AsterixClause);
-inherit(GroupClause, AsterixClause);
-inherit(LimitClause, AsterixClause);
-inherit(DistinctClause, AsterixClause);
-
-// ForClause
-//
-// Grammar:
-// "for" Variable ( "at" Variable )? "in" ( Expression )
-//
-// @param for_variable [String], REQUIRED, first variable in clause
-// @param at_variable [String], NOT REQUIRED, first variable in clause
-// @param expression [AsterixExpression], REQUIRED, expression to evaluate
-//
-// TODO Error Checking
-function ForClause(for_variable, at_variable, expression) {
-
- // at_variable is optional, check if defined
- var at = typeof at_variable ? a : null;
-
- // Prepare clause
- var clause = "for $" + for_variable;
- if (at != null) {
- clause += " at $" + at_variable;
- }
- clause += " in " + expression.val();
-
- // Set prototype
- AsterixClause.prototype.set.call(this, clause);
- return this;
-}
-
-// LetClause
-//
-// Grammar:
-// "let" Variable ":=" Expression
-//
-// TODO error checking
-// @param let_variable [String], REQUIRED
-// @param expression [AsterixExpression], REQUIRED
-LetClause.prototype.set = function(let_variable, expression) {
- var clause = "let $" + let_variable + " := " + expression.val();
-
- AsterixClause.prototype.set.call(this, clause);
- return this;
-};
-
-// TODO
-WhereClause.prototype.set = function(clause) {
- AsterixClause.prototype.set.call(this, clause);
- return this;
-};
-
-// TODO
-OrderbyClause.prototype.set = function(clause) {
- AsterixClause.prototype.set.call(this, clause);
- return this;
-};
-
-// GroupClause
-//
-// Grammer:
-// "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )*
-// ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )?
-// "with" VariableRef ( "," VariableRef )*
-GroupClause.prototype.set = function(clause) {
- AsterixClause.prototype.set.call(this, clause);
- return this;
-};
-
-// TODO
-LimitClause.prototype.set = function(clause) {
- AsterixClause.prototype.set.call(this, clause);
- return this;
-};
-
-// TODO
-DistinctClause.prototype.set = function(clause) {
- AsterixClause.prototype.set.call(this, clause);
- return this;
-};
-
-
-
-
-// Asterix REST Controller
-//
-// Asterix REST Controller
-// Handles interactions with remote database using a request handler
-function AsterixRESTController() {
-
- // bindExpression
- // Prepares an expression for query the asterix API
- // TODO: Future expressions will do some kind of parsing on queries, for now
- // a keyword is used to return the appropriate handler
- // keywords: ddl, update, query, query_status, query_result
- //
- // @param expression [AsterixExpression], an expression or one of its
- // subclasses
- // @param handler [AsterixRESTController], a handler to pass to the SDK
- // remote method call
- this.bindExpression = function(expression, handler_type) {
-
- // TODO Expression handler
-
- // Parse handler, to be replaced with something more elegant
- switch (handler_type)
- {
- case "ddl":
- break;
- case "update":
- break;
- case "query":
- break;
- case "query_status":
- break;
- case "query_result":
- break;
- default:
- this.onHandlerInitError();
- }
- };
-
- // onHandlerInitError
- // Method for handling expression binding errors in the controller.
- this.onHandlerInitError = function() {
- alert("AsterixSDK / AsterixRESTController / bindExpressionError: Could not determine api endpoint, incorrect keyword");
- }
-
- // REST DDL API
- this.DDL = function(data, callback) {
- this.endpoint = "http://localhost:19101/ddl";
- this.apiData = data;
- this.callback = callback;
- };
-
-}
-
-AsterixRESTController.prototype.Update = function(json, data, callback) {
- var endpoint = "http://localhost:19101/update";
-}
-
-
-AsterixRESTController.prototype.Query = function(json, data, callback) {
- var endpoint = "http://localhost:19101/query";
-}
-
-
-AsterixRESTController.prototype.QueryStatus = function(json, data, callback) {
- var endpoint = "http://localhost:19101/query/status";
-}
-
-
-AsterixRESTController.prototype.QueryResult = function(json, data, callback) {
- var endpoint = "http://localhost:19101/query/result";
-}
-
-function AsterixSDKJQueryHandler(json, endpoint, callback) {
- $.ajax({
- type : 'GET',
- url : endpoint,
- data : json,
- dataType : "json",
- success : function(data) {
- alert(JSON.stringify(data));
- }
- });
-}
-
-// Helper Functions
-AsterixSDK.prototype.rectangle = function(bounds) {
- var lower_left = 'create-point(' + bounds["sw"]["lat"] + ',' + bounds["sw"]["lng"] + ')';
- var upper_right = 'create-point(' + bounds["ne"]["lat"] + ',' + bounds["ne"]["lng"] + ')';
-
- var rectangle_statement = 'create-rectangle(' + lower_left + ', ' + upper_right + ')';
- //FunctionCallExpr.prototype.set = function(identifier, expressions) {
- //TODO
- return rectangle_statement;
-};*/
diff --git a/asterix-app/src/main/resources/sdk/static/js/easyXDM.debug.js b/asterix-app/src/main/resources/sdk/static/js/easyXDM.debug.js
deleted file mode 100644
index 61b9738..0000000
--- a/asterix-app/src/main/resources/sdk/static/js/easyXDM.debug.js
+++ /dev/null
@@ -1,2871 +0,0 @@
-/**
- * easyXDM
- * http://easyxdm.net/
- * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-var global = this;
-var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded
-var emptyFn = Function.prototype;
-var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4)
-var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression
-var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
-var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
-var easyXDM = {};
-var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
-var IFRAME_PREFIX = "easyXDM_";
-var HAS_NAME_PROPERTY_BUG;
-var useHash = false; // whether to use the hash over the query
-var flashVersion; // will be set if using flash
-var HAS_FLASH_THROTTLED_BUG;
-var _trace = emptyFn;
-
-
-// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
-function isHostMethod(object, property){
- var t = typeof object[property];
- return t == 'function' ||
- (!!(t == 'object' && object[property])) ||
- t == 'unknown';
-}
-
-function isHostObject(object, property){
- return !!(typeof(object[property]) == 'object' && object[property]);
-}
-
-// end
-
-// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
-function isArray(o){
- return Object.prototype.toString.call(o) === '[object Array]';
-}
-
-// end
-function hasFlash(){
- var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
-
- if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
- // adapted from the swfobject code
- var description = navigator.plugins[name].description;
- if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
- flashVersion = description.match(/\d+/g);
- }
- }
- if (!flashVersion) {
- var flash;
- try {
- flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
- flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
- flash = null;
- }
- catch (notSupportedException) {
- }
- }
- if (!flashVersion) {
- return false;
- }
- var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
- HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
- return true;
-}
-
-/*
- * Cross Browser implementation for adding and removing event listeners.
- */
-var on, un;
-if (isHostMethod(window, "addEventListener")) {
- on = function(target, type, listener){
- _trace("adding listener " + type);
- target.addEventListener(type, listener, false);
- };
- un = function(target, type, listener){
- _trace("removing listener " + type);
- target.removeEventListener(type, listener, false);
- };
-}
-else if (isHostMethod(window, "attachEvent")) {
- on = function(object, sEvent, fpNotify){
- _trace("adding listener " + sEvent);
- object.attachEvent("on" + sEvent, fpNotify);
- };
- un = function(object, sEvent, fpNotify){
- _trace("removing listener " + sEvent);
- object.detachEvent("on" + sEvent, fpNotify);
- };
-}
-else {
- throw new Error("Browser not supported");
-}
-
-/*
- * Cross Browser implementation of DOMContentLoaded.
- */
-var domIsReady = false, domReadyQueue = [], readyState;
-if ("readyState" in document) {
- // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
- // 'interactive' (HTML5 specs, recent WebKit builds) states.
- // https://bugs.webkit.org/show_bug.cgi?id=45119
- readyState = document.readyState;
- domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
-}
-else {
- // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
- // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
- // We only need a body to add elements to, so the existence of document.body is enough for us.
- domIsReady = !!document.body;
-}
-
-function dom_onReady(){
- if (domIsReady) {
- return;
- }
- domIsReady = true;
- _trace("firing dom_onReady");
- for (var i = 0; i < domReadyQueue.length; i++) {
- domReadyQueue[i]();
- }
- domReadyQueue.length = 0;
-}
-
-
-if (!domIsReady) {
- if (isHostMethod(window, "addEventListener")) {
- on(document, "DOMContentLoaded", dom_onReady);
- }
- else {
- on(document, "readystatechange", function(){
- if (document.readyState == "complete") {
- dom_onReady();
- }
- });
- if (document.documentElement.doScroll && window === top) {
- var doScrollCheck = function(){
- if (domIsReady) {
- return;
- }
- // http://javascript.nwbox.com/IEContentLoaded/
- try {
- document.documentElement.doScroll("left");
- }
- catch (e) {
- setTimeout(doScrollCheck, 1);
- return;
- }
- dom_onReady();
- };
- doScrollCheck();
- }
- }
-
- // A fallback to window.onload, that will always work
- on(window, "load", dom_onReady);
-}
-/**
- * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
- * If functions are added after this event then they will be executed immediately.
- * @param {function} fn The function to add
- * @param {Object} scope An optional scope for the function to be called with.
- */
-function whenReady(fn, scope){
- if (domIsReady) {
- fn.call(scope);
- return;
- }
- domReadyQueue.push(function(){
- fn.call(scope);
- });
-}
-
-/**
- * Returns an instance of easyXDM from the parent window with
- * respect to the namespace.
- *
- * @return An instance of easyXDM (in the parent window)
- */
-function getParentObject(){
- var obj = parent;
- if (namespace !== "") {
- for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
- if (!obj) {
- throw new Error(ii.slice(0, i + 1).join('.') + ' is not an object');
- }
- obj = obj[ii[i]];
- }
- }
- if (!obj || !obj.easyXDM) {
- throw new Error('Could not find easyXDM in parent.' + namespace);
- }
- return obj.easyXDM;
-}
-
-/**
- * Removes easyXDM variable from the global scope. It also returns control
- * of the easyXDM variable to whatever code used it before.
- *
- * @param {String} ns A string representation of an object that will hold
- * an instance of easyXDM.
- * @return An instance of easyXDM
- */
-function noConflict(ns){
- if (typeof ns != "string" || !ns) {
- throw new Error('namespace must be a non-empty string');
- }
- _trace("Settings namespace to '" + ns + "'");
-
- window.easyXDM = _easyXDM;
- namespace = ns;
- if (namespace) {
- IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
- }
- return easyXDM;
-}
-
-/*
- * Methods for working with URLs
- */
-/**
- * Get the domain name from a url.
- * @param {String} url The url to extract the domain from.
- * @return The domain part of the url.
- * @type {String}
- */
-function getDomainName(url){
- if (!url) {
- throw new Error("url is undefined or empty");
- }
- return url.match(reURI)[3];
-}
-
-/**
- * Get the port for a given URL, or "" if none
- * @param {String} url The url to extract the port from.
- * @return The port part of the url.
- * @type {String}
- */
-function getPort(url){
- if (!url) {
- throw new Error("url is undefined or empty");
- }
- return url.match(reURI)[4] || "";
-}
-
-/**
- * Returns a string containing the schema, domain and if present the port
- * @param {String} url The url to extract the location from
- * @return {String} The location part of the url
- */
-function getLocation(url){
- if (!url) {
- throw new Error("url is undefined or empty");
- }
- if (/^file/.test(url)) {
- throw new Error("The file:// protocol is not supported");
- }
- var m = url.toLowerCase().match(reURI);
- var proto = m[2], domain = m[3], port = m[4] || "";
- if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
- port = "";
- }
- return proto + "//" + domain + port;
-}
-
-/**
- * Resolves a relative url into an absolute one.
- * @param {String} url The path to resolve.
- * @return {String} The resolved url.
- */
-function resolveUrl(url){
- if (!url) {
- throw new Error("url is undefined or empty");
- }
-
- // replace all // except the one in proto with /
- url = url.replace(reDoubleSlash, "$1/");
-
- // If the url is a valid url we do nothing
- if (!url.match(/^(http||https):\/\//)) {
- // If this is a relative path
- var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
- if (path.substring(path.length - 1) !== "/") {
- path = path.substring(0, path.lastIndexOf("/") + 1);
- }
-
- url = location.protocol + "//" + location.host + path + url;
- }
-
- // reduce all 'xyz/../' to just ''
- while (reParent.test(url)) {
- url = url.replace(reParent, "");
- }
-
- _trace("resolved url '" + url + "'");
- return url;
-}
-
-/**
- * Appends the parameters to the given url.<br/>
- * The base url can contain existing query parameters.
- * @param {String} url The base url.
- * @param {Object} parameters The parameters to add.
- * @return {String} A new valid url with the parameters appended.
- */
-function appendQueryParameters(url, parameters){
- if (!parameters) {
- throw new Error("parameters is undefined or null");
- }
-
- var hash = "", indexOf = url.indexOf("#");
- if (indexOf !== -1) {
- hash = url.substring(indexOf);
- url = url.substring(0, indexOf);
- }
- var q = [];
- for (var key in parameters) {
- if (parameters.hasOwnProperty(key)) {
- q.push(key + "=" + encodeURIComponent(parameters[key]));
- }
- }
- return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
-}
-
-
-// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
-var query = (function(input){
- input = input.substring(1).split("&");
- var data = {}, pair, i = input.length;
- while (i--) {
- pair = input[i].split("=");
- data[pair[0]] = decodeURIComponent(pair[1]);
- }
- return data;
-}(/xdm_e=/.test(location.search) ? location.search : location.hash));
-
-/*
- * Helper methods
- */
-/**
- * Helper for checking if a variable/property is undefined
- * @param {Object} v The variable to test
- * @return {Boolean} True if the passed variable is undefined
- */
-function undef(v){
- return typeof v === "undefined";
-}
-
-/**
- * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
- * @return {JSON} A valid JSON conforming object, or null if not found.
- */
-var getJSON = function(){
- var cached = {};
- var obj = {
- a: [1, 2, 3]
- }, json = "{\"a\":[1,2,3]}";
-
- if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
- // this is a working JSON instance
- return JSON;
- }
- if (Object.toJSON) {
- if (Object.toJSON(obj).replace((/\s/g), "") === json) {
- // this is a working stringify method
- cached.stringify = Object.toJSON;
- }
- }
-
- if (typeof String.prototype.evalJSON === "function") {
- obj = json.evalJSON();
- if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
- // this is a working parse method
- cached.parse = function(str){
- return str.evalJSON();
- };
- }
- }
-
- if (cached.stringify && cached.parse) {
- // Only memoize the result if we have valid instance
- getJSON = function(){
- return cached;
- };
- return cached;
- }
- return null;
-};
-
-/**
- * Applies properties from the source object to the target object.<br/>
- * @param {Object} target The target of the properties.
- * @param {Object} source The source of the properties.
- * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
- */
-function apply(destination, source, noOverwrite){
- var member;
- for (var prop in source) {
- if (source.hasOwnProperty(prop)) {
- if (prop in destination) {
- member = source[prop];
- if (typeof member === "object") {
- apply(destination[prop], member, noOverwrite);
- }
- else if (!noOverwrite) {
- destination[prop] = source[prop];
- }
- }
- else {
- destination[prop] = source[prop];
- }
- }
- }
- return destination;
-}
-
-// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
-function testForNamePropertyBug(){
- var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
- input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
- HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
- document.body.removeChild(form);
- _trace("HAS_NAME_PROPERTY_BUG: " + HAS_NAME_PROPERTY_BUG);
-}
-
-/**
- * Creates a frame and appends it to the DOM.
- * @param config {object} This object can have the following properties
- * <ul>
- * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
- * <li> {object} attr The attributes that should be set on the frame.</li>
- * <li> {DOMElement} container Its parent element (Optional).</li>
- * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
- * </ul>
- * @return The frames DOMElement
- * @type DOMElement
- */
-function createFrame(config){
- _trace("creating frame: " + config.props.src);
- if (undef(HAS_NAME_PROPERTY_BUG)) {
- testForNamePropertyBug();
- }
- var frame;
- // This is to work around the problems in IE6/7 with setting the name property.
- // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
- // This is not required by easyXDM itself, but is to facilitate other use cases
- if (HAS_NAME_PROPERTY_BUG) {
- frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
- }
- else {
- frame = document.createElement("IFRAME");
- frame.name = config.props.name;
- }
-
- frame.id = frame.name = config.props.name;
- delete config.props.name;
-
- if (typeof config.container == "string") {
- config.container = document.getElementById(config.container);
- }
-
- if (!config.container) {
- // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
- apply(frame.style, {
- position: "absolute",
- top: "-2000px",
- // Avoid potential horizontal scrollbar
- left: "0px"
- });
- config.container = document.body;
- }
-
- // HACK: IE cannot have the src attribute set when the frame is appended
- // into the container, so we set it to "javascript:false" as a
- // placeholder for now. If we left the src undefined, it would
- // instead default to "about:blank", which causes SSL mixed-content
- // warnings in IE6 when on an SSL parent page.
- var src = config.props.src;
- config.props.src = "javascript:false";
-
- // transfer properties to the frame
- apply(frame, config.props);
-
- frame.border = frame.frameBorder = 0;
- frame.allowTransparency = true;
- config.container.appendChild(frame);
-
- if (config.onLoad) {
- on(frame, "load", config.onLoad);
- }
-
- // set the frame URL to the proper value (we previously set it to
- // "javascript:false" to work around the IE issue mentioned above)
- if(config.usePost) {
- var form = config.container.appendChild(document.createElement('form')), input;
- form.target = frame.name;
- form.action = src;
- form.method = 'POST';
- if (typeof(config.usePost) === 'object') {
- for (var i in config.usePost) {
- if (config.usePost.hasOwnProperty(i)) {
- if (HAS_NAME_PROPERTY_BUG) {
- input = document.createElement('<input name="' + i + '"/>');
- } else {
- input = document.createElement("INPUT");
- input.name = i;
- }
- input.value = config.usePost[i];
- form.appendChild(input);
- }
- }
- }
- form.submit();
- form.parentNode.removeChild(form);
- } else {
- frame.src = src;
- }
- config.props.src = src;
-
- return frame;
-}
-
-/**
- * Check whether a domain is allowed using an Access Control List.
- * The ACL can contain * and ? as wildcards, or can be regular expressions.
- * If regular expressions they need to begin with ^ and end with $.
- * @param {Array/String} acl The list of allowed domains
- * @param {String} domain The domain to test.
- * @return {Boolean} True if the domain is allowed, false if not.
- */
-function checkAcl(acl, domain){
- // normalize into an array
- if (typeof acl == "string") {
- acl = [acl];
- }
- var re, i = acl.length;
- while (i--) {
- re = acl[i];
- re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
- if (re.test(domain)) {
- return true;
- }
- }
- return false;
-}
-
-/*
- * Functions related to stacks
- */
-/**
- * Prepares an array of stack-elements suitable for the current configuration
- * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
- * @return {Array} An array of stack-elements with the TransportElement at index 0.
- */
-function prepareTransportStack(config){
- var protocol = config.protocol, stackEls;
- config.isHost = config.isHost || undef(query.xdm_p);
- useHash = config.hash || false;
- _trace("preparing transport stack");
-
- if (!config.props) {
- config.props = {};
- }
- if (!config.isHost) {
- _trace("using parameters from query");
- config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
- config.secret = query.xdm_s;
- config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
- ;
- protocol = query.xdm_p;
- if (config.acl && !checkAcl(config.acl, config.remote)) {
- throw new Error("Access denied for " + config.remote);
- }
- }
- else {
- config.remote = resolveUrl(config.remote);
- config.channel = config.channel || "default" + channelId++;
- config.secret = Math.random().toString(16).substring(2);
- if (undef(protocol)) {
- if (getLocation(location.href) == getLocation(config.remote)) {
- /*
- * Both documents has the same origin, lets use direct access.
- */
- protocol = "4";
- }
- else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
- /*
- * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
- */
- protocol = "1";
- }
- else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
- /*
- * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
- */
- protocol = "6";
- }
- else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
- /*
- * This is supported in Gecko (Firefox 1+)
- */
- protocol = "5";
- }
- else if (config.remoteHelper) {
- /*
- * This is supported in all browsers that retains the value of window.name when
- * navigating from one domain to another, and where parent.frames[foo] can be used
- * to get access to a frame from the same domain
- */
- protocol = "2";
- }
- else {
- /*
- * This is supported in all browsers where [window].location is writable for all
- * The resize event will be used if resize is supported and the iframe is not put
- * into a container, else polling will be used.
- */
- protocol = "0";
- }
- _trace("selecting protocol: " + protocol);
- }
- else {
- _trace("using protocol: " + protocol);
- }
- }
- config.protocol = protocol; // for conditional branching
- switch (protocol) {
- case "0":// 0 = HashTransport
- apply(config, {
- interval: 100,
- delay: 2000,
- useResize: true,
- useParent: false,
- usePolling: false
- }, true);
- if (config.isHost) {
- if (!config.local) {
- _trace("looking for image to use as local");
- // If no local is set then we need to find an image hosted on the current domain
- var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
- var i = images.length;
- while (i--) {
- image = images[i];
- if (image.src.substring(0, domain.length) === domain) {
- config.local = image.src;
- break;
- }
- }
- if (!config.local) {
- _trace("no image found, defaulting to using the window");
- // If no local was set, and we are unable to find a suitable file, then we resort to using the current window
- config.local = window;
- }
- }
-
- var parameters = {
- xdm_c: config.channel,
- xdm_p: 0
- };
-
- if (config.local === window) {
- // We are using the current window to listen to
- config.usePolling = true;
- config.useParent = true;
- config.local = location.protocol + "//" + location.host + location.pathname + location.search;
- parameters.xdm_e = config.local;
- parameters.xdm_pa = 1; // use parent
- }
- else {
- parameters.xdm_e = resolveUrl(config.local);
- }
-
- if (config.container) {
- config.useResize = false;
- parameters.xdm_po = 1; // use polling
- }
- config.remote = appendQueryParameters(config.remote, parameters);
- }
- else {
- apply(config, {
- channel: query.xdm_c,
- remote: query.xdm_e,
- useParent: !undef(query.xdm_pa),
- usePolling: !undef(query.xdm_po),
- useResize: config.useParent ? false : config.useResize
- });
- }
- stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
- encode: true,
- maxLength: 4000 - config.remote.length
- }), new easyXDM.stack.VerifyBehavior({
- initiate: config.isHost
- })];
- break;
- case "1":
- stackEls = [new easyXDM.stack.PostMessageTransport(config)];
- break;
- case "2":
- config.remoteHelper = resolveUrl(config.remoteHelper);
- stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
- initiate: config.isHost
- })];
- break;
- case "3":
- stackEls = [new easyXDM.stack.NixTransport(config)];
- break;
- case "4":
- stackEls = [new easyXDM.stack.SameOriginTransport(config)];
- break;
- case "5":
- stackEls = [new easyXDM.stack.FrameElementTransport(config)];
- break;
- case "6":
- if (!flashVersion) {
- hasFlash();
- }
- stackEls = [new easyXDM.stack.FlashTransport(config)];
- break;
- }
- // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
- stackEls.push(new easyXDM.stack.QueueBehavior({
- lazy: config.lazy,
- remove: true
- }));
- return stackEls;
-}
-
-/**
- * Chains all the separate stack elements into a single usable stack.<br/>
- * If an element is missing a necessary method then it will have a pass-through method applied.
- * @param {Array} stackElements An array of stack elements to be linked.
- * @return {easyXDM.stack.StackElement} The last element in the chain.
- */
-function chainStack(stackElements){
- var stackEl, defaults = {
- incoming: function(message, origin){
- this.up.incoming(message, origin);
- },
- outgoing: function(message, recipient){
- this.down.outgoing(message, recipient);
- },
- callback: function(success){
- this.up.callback(success);
- },
- init: function(){
- this.down.init();
- },
- destroy: function(){
- this.down.destroy();
- }
- };
- for (var i = 0, len = stackElements.length; i < len; i++) {
- stackEl = stackElements[i];
- apply(stackEl, defaults, true);
- if (i !== 0) {
- stackEl.down = stackElements[i - 1];
- }
- if (i !== len - 1) {
- stackEl.up = stackElements[i + 1];
- }
- }
- return stackEl;
-}
-
-/**
- * This will remove a stackelement from its stack while leaving the stack functional.
- * @param {Object} element The elment to remove from the stack.
- */
-function removeFromStack(element){
- element.up.down = element.down;
- element.down.up = element.up;
- element.up = element.down = null;
-}
-
-/*
- * Export the main object and any other methods applicable
- */
-/**
- * @class easyXDM
- * A javascript library providing cross-browser, cross-domain messaging/RPC.
- * @version 2.4.17.1
- * @singleton
- */
-apply(easyXDM, {
- /**
- * The version of the library
- * @type {string}
- */
- version: "2.4.17.1",
- /**
- * This is a map containing all the query parameters passed to the document.
- * All the values has been decoded using decodeURIComponent.
- * @type {object}
- */
- query: query,
- /**
- * @private
- */
- stack: {},
- /**
- * Applies properties from the source object to the target object.<br/>
- * @param {object} target The target of the properties.
- * @param {object} source The source of the properties.
- * @param {boolean} noOverwrite Set to True to only set non-existing properties.
- */
- apply: apply,
-
- /**
- * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
- * @return {JSON} A valid JSON conforming object, or null if not found.
- */
- getJSONObject: getJSON,
- /**
- * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
- * If functions are added after this event then they will be executed immediately.
- * @param {function} fn The function to add
- * @param {object} scope An optional scope for the function to be called with.
- */
- whenReady: whenReady,
- /**
- * Removes easyXDM variable from the global scope. It also returns control
- * of the easyXDM variable to whatever code used it before.
- *
- * @param {String} ns A string representation of an object that will hold
- * an instance of easyXDM.
- * @return An instance of easyXDM
- */
- noConflict: noConflict
-});
-
-// Expose helper functions so we can test them
-apply(easyXDM, {
- checkAcl: checkAcl,
- getDomainName: getDomainName,
- getLocation: getLocation,
- appendQueryParameters: appendQueryParameters
-});
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global console, _FirebugCommandLine, easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-var debug = {
- _deferred: [],
- flush: function(){
- this.trace("... deferred messages ...");
- for (var i = 0, len = this._deferred.length; i < len; i++) {
- this.trace(this._deferred[i]);
- }
- this._deferred.length = 0;
- this.trace("... end of deferred messages ...");
- },
- getTime: function(){
- var d = new Date(), h = d.getHours() + "", m = d.getMinutes() + "", s = d.getSeconds() + "", ms = d.getMilliseconds() + "", zeros = "000";
- if (h.length == 1) {
- h = "0" + h;
- }
- if (m.length == 1) {
- m = "0" + m;
- }
- if (s.length == 1) {
- s = "0" + s;
- }
- ms = zeros.substring(ms.length) + ms;
- return h + ":" + m + ":" + s + "." + ms;
- },
- /**
- * Logs the message to console.log if available
- * @param {String} msg The message to log
- */
- log: function(msg){
- // Uses memoizing to cache the implementation
- if (!isHostObject(window, "console") || undef(console.log)) {
- /**
- * Sets log to be an empty function since we have no output available
- * @ignore
- */
- this.log = emptyFn;
- }
- else {
- /**
- * Sets log to be a wrapper around console.log
- * @ignore
- * @param {String} msg
- */
- this.log = function(msg){
- console.log(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ": " + msg);
- };
- }
- this.log(msg);
- },
- /**
- * Will try to trace the given message either to a DOMElement with the id "log",
- * or by using console.info.
- * @param {String} msg The message to trace
- */
- trace: function(msg){
- // Uses memoizing to cache the implementation
- if (!domIsReady) {
- if (this._deferred.length === 0) {
- easyXDM.whenReady(debug.flush, debug);
- }
- this._deferred.push(msg);
- this.log(msg);
- }
- else {
- var el = document.getElementById("log");
- // is there a log element present?
- if (el) {
- /**
- * Sets trace to be a function that outputs the messages to the DOMElement with id "log"
- * @ignore
- * @param {String} msg
- */
- this.trace = function(msg){
- try {
- el.appendChild(document.createElement("div")).appendChild(document.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
- el.scrollTop = el.scrollHeight;
- }
- catch (e) {
- //In case we are unloading
- }
- };
- }
- else if (isHostObject(window, "console") && !undef(console.info)) {
- /**
- * Sets trace to be a wrapper around console.info
- * @ignore
- * @param {String} msg
- */
- this.trace = function(msg){
- console.info(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg);
- };
- }
- else {
- /**
- * Create log window
- * @ignore
- */
- var domain = location.host, windowname = domain.replace(/[\-.:]/g, "") + "easyxdm_log", logWin;
- try {
- logWin = window.open("", windowname, "width=800,height=200,status=0,navigation=0,scrollbars=1");
- }
- catch (e) {
- }
- if (logWin) {
- var doc = logWin.document;
- el = doc.getElementById("log");
- if (!el) {
- doc.write("<html><head><title>easyXDM log " + domain + "</title></head>");
- doc.write("<body><div id=\"log\"></div></body></html>");
- doc.close();
- el = doc.getElementById("log");
- }
- this.trace = function(msg){
- try {
- el.appendChild(doc.createElement("div")).appendChild(doc.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
- el.scrollTop = el.scrollHeight;
- }
- catch (e) {
- //In case we are unloading
- }
- };
- this.trace("---- new logger at " + location.href);
- }
-
- if (!el) {
- // We are unable to use any logging
- this.trace = emptyFn;
- }
- }
- this.trace(msg);
- }
- },
- /**
- * Creates a method usable for tracing.
- * @param {String} name The name the messages should be marked with
- * @return {Function} A function that accepts a single string as argument.
- */
- getTracer: function(name){
- return function(msg){
- debug.trace(name + ": " + msg);
- };
- }
-};
-debug.log("easyXDM present on '" + location.href);
-easyXDM.Debug = debug;
-_trace = debug.getTracer("{Private}");
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.DomHelper
- * Contains methods for dealing with the DOM
- * @singleton
- */
-easyXDM.DomHelper = {
- /**
- * Provides a consistent interface for adding eventhandlers
- * @param {Object} target The target to add the event to
- * @param {String} type The name of the event
- * @param {Function} listener The listener
- */
- on: on,
- /**
- * Provides a consistent interface for removing eventhandlers
- * @param {Object} target The target to remove the event from
- * @param {String} type The name of the event
- * @param {Function} listener The listener
- */
- un: un,
- /**
- * Checks for the presence of the JSON object.
- * If it is not present it will use the supplied path to load the JSON2 library.
- * This should be called in the documents head right after the easyXDM script tag.
- * http://json.org/json2.js
- * @param {String} path A valid path to json2.js
- */
- requiresJSON: function(path){
- if (!isHostObject(window, "JSON")) {
- debug.log("loading external JSON");
- // we need to encode the < in order to avoid an illegal token error
- // when the script is inlined in a document.
- document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
- }
- else {
- debug.log("native JSON found");
- }
- }
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, debug */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-(function(){
- // The map containing the stored functions
- var _map = {};
-
- /**
- * @class easyXDM.Fn
- * This contains methods related to function handling, such as storing callbacks.
- * @singleton
- * @namespace easyXDM
- */
- easyXDM.Fn = {
- /**
- * Stores a function using the given name for reference
- * @param {String} name The name that the function should be referred by
- * @param {Function} fn The function to store
- * @namespace easyXDM.fn
- */
- set: function(name, fn){
- this._trace("storing function " + name);
- _map[name] = fn;
- },
- /**
- * Retrieves the function referred to by the given name
- * @param {String} name The name of the function to retrieve
- * @param {Boolean} del If the function should be deleted after retrieval
- * @return {Function} The stored function
- * @namespace easyXDM.fn
- */
- get: function(name, del){
- this._trace("retrieving function " + name);
- var fn = _map[name];
- if (!fn) {
- this._trace(name + " not found");
- }
-
- if (del) {
- delete _map[name];
- }
- return fn;
- }
- };
-
- easyXDM.Fn._trace = debug.getTracer("easyXDM.Fn");
-}());
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.Socket
- * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
- * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
- * Internally different stacks will be used depending on the browsers features and the available parameters.
- * <h2>How to set up</h2>
- * Setting up the provider:
- * <pre><code>
- * var socket = new easyXDM.Socket({
- * local: "name.html",
- * onReady: function(){
- * // you need to wait for the onReady callback before using the socket
- * socket.postMessage("foo-message");
- * },
- * onMessage: function(message, origin) {
- * alert("received " + message + " from " + origin);
- * }
- * });
- * </code></pre>
- * Setting up the consumer:
- * <pre><code>
- * var socket = new easyXDM.Socket({
- * remote: "http://remotedomain/page.html",
- * remoteHelper: "http://remotedomain/name.html",
- * onReady: function(){
- * // you need to wait for the onReady callback before using the socket
- * socket.postMessage("foo-message");
- * },
- * onMessage: function(message, origin) {
- * alert("received " + message + " from " + origin);
- * }
- * });
- * </code></pre>
- * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
- * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
- * @namespace easyXDM
- * @constructor
- * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
- * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed.
- * @cfg {String} remote (Consumer only) The url to the providers document.
- * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
- * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window. Optional, defaults to 2000.
- * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
- * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
- * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
- * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
- * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
- * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
- * This can contain the wildcards ? and *. Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
- * If none of the patterns match an Error will be thrown.
- * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>.
- * Properties such as 'name' and 'src' will be overrided. Optional.
- */
-easyXDM.Socket = function(config){
- var trace = debug.getTracer("easyXDM.Socket");
- trace("constructor");
-
- // create the stack
- var stack = chainStack(prepareTransportStack(config).concat([{
- incoming: function(message, origin){
- config.onMessage(message, origin);
- },
- callback: function(success){
- if (config.onReady) {
- config.onReady(success);
- }
- }
- }])), recipient = getLocation(config.remote);
-
- // set the origin
- this.origin = getLocation(config.remote);
-
- /**
- * Initiates the destruction of the stack.
- */
- this.destroy = function(){
- stack.destroy();
- };
-
- /**
- * Posts a message to the remote end of the channel
- * @param {String} message The message to send
- */
- this.postMessage = function(message){
- stack.outgoing(message, recipient);
- };
-
- stack.init();
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.Rpc
- * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
- * of methods to be called from the remote end.<br/>
- * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
- * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
- * <h2>How to set up</h2>
- * <pre><code>
- * var rpc = new easyXDM.Rpc({
- * // this configuration is equal to that used by the Socket.
- * remote: "http://remotedomain/...",
- * onReady: function(){
- * // you need to wait for the onReady callback before using the proxy
- * rpc.foo(...
- * }
- * },{
- * local: {..},
- * remote: {..}
- * });
- * </code></pre>
- *
- * <h2>Exposing functions (procedures)</h2>
- * <pre><code>
- * var rpc = new easyXDM.Rpc({
- * ...
- * },{
- * local: {
- * nameOfMethod: {
- * method: function(arg1, arg2, success, error){
- * ...
- * }
- * },
- * // with shorthand notation
- * nameOfAnotherMethod: function(arg1, arg2, success, error){
- * }
- * },
- * remote: {...}
- * });
- * </code></pre>
-
- * The function referenced by [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
- * To send a successfull result back you can use
- * <pre><code>
- * return foo;
- * </pre></code>
- * or
- * <pre><code>
- * success(foo);
- * </pre></code>
- * To return an error you can use
- * <pre><code>
- * throw new Error("foo error");
- * </code></pre>
- * or
- * <pre><code>
- * error("foo error");
- * </code></pre>
- *
- * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
- * The definition of the remote end is quite similar:
- * <pre><code>
- * var rpc = new easyXDM.Rpc({
- * ...
- * },{
- * local: {...},
- * remote: {
- * nameOfMethod: {}
- * }
- * });
- * </code></pre>
- * To call a remote method use
- * <pre><code>
- * rpc.nameOfMethod("arg1", "arg2", function(value) {
- * alert("success: " + value);
- * }, function(message) {
- * alert("error: " + message + );
- * });
- * </code></pre>
- * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
- * When called with no callback a JSON-RPC 2.0 notification will be executed.
- * Be aware that you will not be notified of any errors with this method.
- * <br/>
- * <h2>Specifying a custom serializer</h2>
- * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
- * then you can specify a custom serializer using <code>serializer: foo</code>
- * <pre><code>
- * var rpc = new easyXDM.Rpc({
- * ...
- * },{
- * local: {...},
- * remote: {...},
- * serializer : {
- * parse: function(string){ ... },
- * stringify: function(object) {...}
- * }
- * });
- * </code></pre>
- * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
- * @namespace easyXDM
- * @constructor
- * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
- * @param {Object} jsonRpcConfig The description of the interface to implement.
- */
-easyXDM.Rpc = function(config, jsonRpcConfig){
- var trace = debug.getTracer("easyXDM.Rpc");
- trace("constructor");
-
- // expand shorthand notation
- if (jsonRpcConfig.local) {
- for (var method in jsonRpcConfig.local) {
- if (jsonRpcConfig.local.hasOwnProperty(method)) {
- var member = jsonRpcConfig.local[method];
- if (typeof member === "function") {
- jsonRpcConfig.local[method] = {
- method: member
- };
- }
- }
- }
- }
-
- // create the stack
- var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
- callback: function(success){
- if (config.onReady) {
- config.onReady(success);
- }
- }
- }]));
-
- // set the origin
- this.origin = getLocation(config.remote);
-
-
- /**
- * Initiates the destruction of the stack.
- */
- this.destroy = function(){
- stack.destroy();
- };
-
- stack.init();
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.SameOriginTransport
- * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
- * This can be useful for testing and for when the main application supports both internal and external sources.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The transports configuration.
- * @cfg {String} remote The remote document to communicate with.
- */
-easyXDM.stack.SameOriginTransport = function(config){
- var trace = debug.getTracer("easyXDM.stack.SameOriginTransport");
- trace("constructor");
- var pub, frame, send, targetOrigin;
-
- return (pub = {
- outgoing: function(message, domain, fn){
- send(message);
- if (fn) {
- fn();
- }
- },
- destroy: function(){
- trace("destroy");
- if (frame) {
- frame.parentNode.removeChild(frame);
- frame = null;
- }
- },
- onDOMReady: function(){
- trace("init");
- targetOrigin = getLocation(config.remote);
-
- if (config.isHost) {
- // set up the iframe
- apply(config.props, {
- src: appendQueryParameters(config.remote, {
- xdm_e: location.protocol + "//" + location.host + location.pathname,
- xdm_c: config.channel,
- xdm_p: 4 // 4 = SameOriginTransport
- }),
- name: IFRAME_PREFIX + config.channel + "_provider"
- });
- frame = createFrame(config);
- easyXDM.Fn.set(config.channel, function(sendFn){
- send = sendFn;
- setTimeout(function(){
- pub.up.callback(true);
- }, 0);
- return function(msg){
- pub.up.incoming(msg, targetOrigin);
- };
- });
- }
- else {
- send = getParentObject().Fn.get(config.channel, true)(function(msg){
- pub.up.incoming(msg, targetOrigin);
- });
- setTimeout(function(){
- pub.up.callback(true);
- }, 0);
- }
- },
- init: function(){
- whenReady(pub.onDOMReady, pub);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.FlashTransport
- * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The transports configuration.
- * @cfg {String} remote The remote domain to communicate with.
- * @cfg {String} secret the pre-shared secret used to secure the communication.
- * @cfg {String} swf The path to the swf file
- * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
- * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
- */
-easyXDM.stack.FlashTransport = function(config){
- var trace = debug.getTracer("easyXDM.stack.FlashTransport");
- trace("constructor");
- if (!config.swf) {
- throw new Error("Path to easyxdm.swf is missing");
- }
- var pub, // the public interface
- frame, send, targetOrigin, swf, swfContainer;
-
- function onMessage(message, origin){
- setTimeout(function(){
- trace("received message");
- pub.up.incoming(message, targetOrigin);
- }, 0);
- }
-
- /**
- * This method adds the SWF to the DOM and prepares the initialization of the channel
- */
- function addSwf(domain){
- trace("creating factory with SWF from " + domain);
- // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
- var url = config.swf + "?host=" + config.isHost;
- var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
-
- // prepare the init function that will fire once the swf is ready
- easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
- easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
- var queue = easyXDM.stack.FlashTransport[domain].queue;
- for (var i = 0; i < queue.length; i++) {
- queue[i]();
- }
- queue.length = 0;
- });
-
- if (config.swfContainer) {
- swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
- }
- else {
- // create the container that will hold the swf
- swfContainer = document.createElement('div');
-
- // http://bugs.adobe.com/jira/browse/FP-4796
- // http://tech.groups.yahoo.com/group/flexcoders/message/162365
- // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
- apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
- height: "20px",
- width: "20px",
- position: "fixed",
- right: 0,
- top: 0
- } : {
- height: "1px",
- width: "1px",
- position: "absolute",
- overflow: "hidden",
- right: 0,
- top: 0
- });
- document.body.appendChild(swfContainer);
- }
-
- // create the object/embed
- var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
- flashVars += "&log=true";
- swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
- "<param name='allowScriptAccess' value='always'></param>" +
- "<param name='wmode' value='transparent'>" +
- "<param name='movie' value='" +
- url +
- "'></param>" +
- "<param name='flashvars' value='" +
- flashVars +
- "'></param>" +
- "<embed type='application/x-shockwave-flash' FlashVars='" +
- flashVars +
- "' allowScriptAccess='always' wmode='transparent' src='" +
- url +
- "' height='1' width='1'></embed>" +
- "</object>";
- }
-
- return (pub = {
- outgoing: function(message, domain, fn){
- swf.postMessage(config.channel, message.toString());
- if (fn) {
- fn();
- }
- },
- destroy: function(){
- trace("destroy");
- try {
- swf.destroyChannel(config.channel);
- }
- catch (e) {
- }
- swf = null;
- if (frame) {
- frame.parentNode.removeChild(frame);
- frame = null;
- }
- },
- onDOMReady: function(){
- trace("init");
-
- targetOrigin = config.remote;
-
- // Prepare the code that will be run after the swf has been intialized
- easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
- setTimeout(function(){
- trace("firing onReady");
- pub.up.callback(true);
- });
- });
-
- // set up the omMessage handler
- easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
-
- config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
- var swfdomain = getDomainName(config.swf);
- var fn = function(){
- // set init to true in case the fn was called was invoked from a separate instance
- easyXDM.stack.FlashTransport[swfdomain].init = true;
- swf = easyXDM.stack.FlashTransport[swfdomain].swf;
- // create the channel
- swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
-
- if (config.isHost) {
- // if Flash is going to be throttled and we want to avoid this
- if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
- apply(config.props, {
- position: "fixed",
- right: 0,
- top: 0,
- height: "20px",
- width: "20px"
- });
- }
- // set up the iframe
- apply(config.props, {
- src: appendQueryParameters(config.remote, {
- xdm_e: getLocation(location.href),
- xdm_c: config.channel,
- xdm_p: 6, // 6 = FlashTransport
- xdm_s: config.secret
- }),
- name: IFRAME_PREFIX + config.channel + "_provider"
- });
- frame = createFrame(config);
- }
- };
-
- if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
- // if the swf is in place and we are the consumer
- fn();
- }
- else {
- // if the swf does not yet exist
- if (!easyXDM.stack.FlashTransport[swfdomain]) {
- // add the queue to hold the init fn's
- easyXDM.stack.FlashTransport[swfdomain] = {
- queue: [fn]
- };
- addSwf(swfdomain);
- }
- else {
- easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
- }
- }
- },
- init: function(){
- whenReady(pub.onDOMReady, pub);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.PostMessageTransport
- * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
- * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
- * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The transports configuration.
- * @cfg {String} remote The remote domain to communicate with.
- */
-easyXDM.stack.PostMessageTransport = function(config){
- var trace = debug.getTracer("easyXDM.stack.PostMessageTransport");
- trace("constructor");
- var pub, // the public interface
- frame, // the remote frame, if any
- callerWindow, // the window that we will call with
- targetOrigin; // the domain to communicate with
- /**
- * Resolves the origin from the event object
- * @private
- * @param {Object} event The messageevent
- * @return {String} The scheme, host and port of the origin
- */
- function _getOrigin(event){
- if (event.origin) {
- // This is the HTML5 property
- return getLocation(event.origin);
- }
- if (event.uri) {
- // From earlier implementations
- return getLocation(event.uri);
- }
- if (event.domain) {
- // This is the last option and will fail if the
- // origin is not using the same schema as we are
- return location.protocol + "//" + event.domain;
- }
- throw "Unable to retrieve the origin of the event";
- }
-
- /**
- * This is the main implementation for the onMessage event.<br/>
- * It checks the validity of the origin and passes the message on if appropriate.
- * @private
- * @param {Object} event The messageevent
- */
- function _window_onMessage(event){
- var origin = _getOrigin(event);
- trace("received message '" + event.data + "' from " + origin);
- if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
- pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
- }
- }
-
- return (pub = {
- outgoing: function(message, domain, fn){
- callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
- if (fn) {
- fn();
- }
- },
- destroy: function(){
- trace("destroy");
- un(window, "message", _window_onMessage);
- if (frame) {
- callerWindow = null;
- frame.parentNode.removeChild(frame);
- frame = null;
- }
- },
- onDOMReady: function(){
- trace("init");
- targetOrigin = getLocation(config.remote);
- if (config.isHost) {
- // add the event handler for listening
- var waitForReady = function(event){
- if (event.data == config.channel + "-ready") {
- trace("firing onReady");
- // replace the eventlistener
- callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
- un(window, "message", waitForReady);
- on(window, "message", _window_onMessage);
- setTimeout(function(){
- pub.up.callback(true);
- }, 0);
- }
- };
- on(window, "message", waitForReady);
-
- // set up the iframe
- apply(config.props, {
- src: appendQueryParameters(config.remote, {
- xdm_e: getLocation(location.href),
- xdm_c: config.channel,
- xdm_p: 1 // 1 = PostMessage
- }),
- name: IFRAME_PREFIX + config.channel + "_provider"
- });
- frame = createFrame(config);
- }
- else {
- // add the event handler for listening
- on(window, "message", _window_onMessage);
- callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
- callerWindow.postMessage(config.channel + "-ready", targetOrigin);
-
- setTimeout(function(){
- pub.up.callback(true);
- }, 0);
- }
- },
- init: function(){
- whenReady(pub.onDOMReady, pub);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.FrameElementTransport
- * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
- * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The transports configuration.
- * @cfg {String} remote The remote document to communicate with.
- */
-easyXDM.stack.FrameElementTransport = function(config){
- var trace = debug.getTracer("easyXDM.stack.FrameElementTransport");
- trace("constructor");
- var pub, frame, send, targetOrigin;
-
- return (pub = {
- outgoing: function(message, domain, fn){
- send.call(this, message);
- if (fn) {
- fn();
- }
- },
- destroy: function(){
- trace("destroy");
- if (frame) {
- frame.parentNode.removeChild(frame);
- frame = null;
- }
- },
- onDOMReady: function(){
- trace("init");
- targetOrigin = getLocation(config.remote);
-
- if (config.isHost) {
- // set up the iframe
- apply(config.props, {
- src: appendQueryParameters(config.remote, {
- xdm_e: getLocation(location.href),
- xdm_c: config.channel,
- xdm_p: 5 // 5 = FrameElementTransport
- }),
- name: IFRAME_PREFIX + config.channel + "_provider"
- });
- frame = createFrame(config);
- frame.fn = function(sendFn){
- delete frame.fn;
- send = sendFn;
- setTimeout(function(){
- pub.up.callback(true);
- }, 0);
- // remove the function so that it cannot be used to overwrite the send function later on
- return function(msg){
- pub.up.incoming(msg, targetOrigin);
- };
- };
- }
- else {
- // This is to mitigate origin-spoofing
- if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
- window.top.location = query.xdm_e;
- }
- send = window.frameElement.fn(function(msg){
- pub.up.incoming(msg, targetOrigin);
- });
- pub.up.callback(true);
- }
- },
- init: function(){
- whenReady(pub.onDOMReady, pub);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.NameTransport
- * NameTransport uses the window.name property to relay data.
- * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
- * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
- * @constructor
- * @param {Object} config The transports configuration.
- * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
- * @namespace easyXDM.stack
- */
-easyXDM.stack.NameTransport = function(config){
- var trace = debug.getTracer("easyXDM.stack.NameTransport");
- trace("constructor");
- if (config.isHost && undef(config.remoteHelper)) {
- trace("missing remoteHelper");
- throw new Error("missing remoteHelper");
- }
-
- var pub; // the public interface
- var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
-
- function _sendMessage(message){
- var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
- trace("sending message " + message);
- trace("navigating to '" + url + "'");
- callerWindow.contentWindow.sendMessage(message, url);
- }
-
- function _onReady(){
- if (isHost) {
- if (++readyCount === 2 || !isHost) {
- pub.up.callback(true);
- }
- }
- else {
- _sendMessage("ready");
- trace("calling onReady");
- pub.up.callback(true);
- }
- }
-
- function _onMessage(message){
- trace("received message " + message);
- pub.up.incoming(message, remoteOrigin);
- }
-
- function _onLoad(){
- if (callback) {
- setTimeout(function(){
- callback(true);
- }, 0);
- }
- }
-
- return (pub = {
- outgoing: function(message, domain, fn){
- callback = fn;
- _sendMessage(message);
- },
- destroy: function(){
- trace("destroy");
- callerWindow.parentNode.removeChild(callerWindow);
- callerWindow = null;
- if (isHost) {
- remoteWindow.parentNode.removeChild(remoteWindow);
- remoteWindow = null;
- }
- },
- onDOMReady: function(){
- trace("init");
- isHost = config.isHost;
- readyCount = 0;
- remoteOrigin = getLocation(config.remote);
- config.local = resolveUrl(config.local);
-
- if (isHost) {
- // Register the callback
- easyXDM.Fn.set(config.channel, function(message){
- trace("received initial message " + message);
- if (isHost && message === "ready") {
- // Replace the handler
- easyXDM.Fn.set(config.channel, _onMessage);
- _onReady();
- }
- });
-
- // Set up the frame that points to the remote instance
- remoteUrl = appendQueryParameters(config.remote, {
- xdm_e: config.local,
- xdm_c: config.channel,
- xdm_p: 2
- });
- apply(config.props, {
- src: remoteUrl + '#' + config.channel,
- name: IFRAME_PREFIX + config.channel + "_provider"
- });
- remoteWindow = createFrame(config);
- }
- else {
- config.remoteHelper = config.remote;
- easyXDM.Fn.set(config.channel, _onMessage);
- }
-
- // Set up the iframe that will be used for the transport
- var onLoad = function(){
- // Remove the handler
- var w = callerWindow || this;
- un(w, "load", onLoad);
- easyXDM.Fn.set(config.channel + "_load", _onLoad);
- (function test(){
- if (typeof w.contentWindow.sendMessage == "function") {
- _onReady();
- }
- else {
- setTimeout(test, 50);
- }
- }());
- };
-
- callerWindow = createFrame({
- props: {
- src: config.local + "#_4" + config.channel
- },
- onLoad: onLoad
- });
- },
- init: function(){
- whenReady(pub.onDOMReady, pub);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.HashTransport
- * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
- * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The transports configuration.
- * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
- * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
- * @cfg {Number} interval The interval used when polling for messages.
- */
-easyXDM.stack.HashTransport = function(config){
- var trace = debug.getTracer("easyXDM.stack.HashTransport");
- trace("constructor");
- var pub;
- var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
- var useParent, _remoteOrigin;
-
- function _sendMessage(message){
- trace("sending message '" + (_msgNr + 1) + " " + message + "' to " + _remoteOrigin);
- if (!_callerWindow) {
- trace("no caller window");
- return;
- }
- var url = config.remote + "#" + (_msgNr++) + "_" + message;
- ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
- }
-
- function _handleHash(hash){
- _lastMsg = hash;
- trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
- pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
- }
-
- /**
- * Checks location.hash for a new message and relays this to the receiver.
- * @private
- */
- function _pollHash(){
- if (!_listenerWindow) {
- return;
- }
- var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
- if (indexOf != -1) {
- hash = href.substring(indexOf);
- }
- if (hash && hash != _lastMsg) {
- trace("poll: new message");
- _handleHash(hash);
- }
- }
-
- function _attachListeners(){
- trace("starting polling");
- _timer = setInterval(_pollHash, pollInterval);
- }
-
- return (pub = {
- outgoing: function(message, domain){
- _sendMessage(message);
- },
- destroy: function(){
- window.clearInterval(_timer);
- if (isHost || !useParent) {
- _callerWindow.parentNode.removeChild(_callerWindow);
- }
- _callerWindow = null;
- },
- onDOMReady: function(){
- isHost = config.isHost;
- pollInterval = config.interval;
- _lastMsg = "#" + config.channel;
- _msgNr = 0;
- useParent = config.useParent;
- _remoteOrigin = getLocation(config.remote);
- if (isHost) {
- apply(config.props, {
- src: config.remote,
- name: IFRAME_PREFIX + config.channel + "_provider"
- });
- if (useParent) {
- config.onLoad = function(){
- _listenerWindow = window;
- _attachListeners();
- pub.up.callback(true);
- };
- }
- else {
- var tries = 0, max = config.delay / 50;
- (function getRef(){
- if (++tries > max) {
- trace("unable to get reference to _listenerWindow, giving up");
- throw new Error("Unable to reference listenerwindow");
- }
- try {
- _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
- }
- catch (ex) {
- }
- if (_listenerWindow) {
- _attachListeners();
- trace("got a reference to _listenerWindow");
- pub.up.callback(true);
- }
- else {
- setTimeout(getRef, 50);
- }
- }());
- }
- _callerWindow = createFrame(config);
- }
- else {
- _listenerWindow = window;
- _attachListeners();
- if (useParent) {
- _callerWindow = parent;
- pub.up.callback(true);
- }
- else {
- apply(config, {
- props: {
- src: config.remote + "#" + config.channel + new Date(),
- name: IFRAME_PREFIX + config.channel + "_consumer"
- },
- onLoad: function(){
- pub.up.callback(true);
- }
- });
- _callerWindow = createFrame(config);
- }
- }
- },
- init: function(){
- whenReady(pub.onDOMReady, pub);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, debug */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.ReliableBehavior
- * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The behaviors configuration.
- */
-easyXDM.stack.ReliableBehavior = function(config){
- var trace = debug.getTracer("easyXDM.stack.ReliableBehavior");
- trace("constructor");
- var pub, // the public interface
- callback; // the callback to execute when we have a confirmed success/failure
- var idOut = 0, idIn = 0, currentMessage = "";
-
- return (pub = {
- incoming: function(message, origin){
- trace("incoming: " + message);
- var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
- message = message.substring(indexOf + 1);
-
- if (ack[0] == idOut) {
- trace("message delivered");
- currentMessage = "";
- if (callback) {
- callback(true);
- callback = null;
- }
- }
- if (message.length > 0) {
- trace("sending ack, and passing on " + message);
- pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
- if (idIn != ack[1]) {
- idIn = ack[1];
- pub.up.incoming(message, origin);
- }
- }
-
- },
- outgoing: function(message, origin, fn){
- currentMessage = message;
- callback = fn;
- pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.QueueBehavior
- * This is a behavior that enables queueing of messages. <br/>
- * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
- * This will also fragment/defragment messages so that the outgoing message is never bigger than the
- * set length.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The behaviors configuration. Optional.
- * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
- */
-easyXDM.stack.QueueBehavior = function(config){
- var trace = debug.getTracer("easyXDM.stack.QueueBehavior");
- trace("constructor");
- var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
-
- function dispatch(){
- if (config.remove && queue.length === 0) {
- trace("removing myself from the stack");
- removeFromStack(pub);
- return;
- }
- if (waiting || queue.length === 0 || destroying) {
- return;
- }
- trace("dispatching from queue");
- waiting = true;
- var message = queue.shift();
-
- pub.down.outgoing(message.data, message.origin, function(success){
- waiting = false;
- if (message.callback) {
- setTimeout(function(){
- message.callback(success);
- }, 0);
- }
- dispatch();
- });
- }
- return (pub = {
- init: function(){
- if (undef(config)) {
- config = {};
- }
- if (config.maxLength) {
- maxLength = config.maxLength;
- doFragment = true;
- }
- if (config.lazy) {
- lazy = true;
- }
- else {
- pub.down.init();
- }
- },
- callback: function(success){
- waiting = false;
- var up = pub.up; // in case dispatch calls removeFromStack
- dispatch();
- up.callback(success);
- },
- incoming: function(message, origin){
- if (doFragment) {
- var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
- incoming += message.substring(indexOf + 1);
- if (seq === 0) {
- trace("received the last fragment");
- if (config.encode) {
- incoming = decodeURIComponent(incoming);
- }
- pub.up.incoming(incoming, origin);
- incoming = "";
- }
- else {
- trace("waiting for more fragments, seq=" + message);
- }
- }
- else {
- pub.up.incoming(message, origin);
- }
- },
- outgoing: function(message, origin, fn){
- if (config.encode) {
- message = encodeURIComponent(message);
- }
- var fragments = [], fragment;
- if (doFragment) {
- // fragment into chunks
- while (message.length !== 0) {
- fragment = message.substring(0, maxLength);
- message = message.substring(fragment.length);
- fragments.push(fragment);
- }
- // enqueue the chunks
- while ((fragment = fragments.shift())) {
- trace("enqueuing");
- queue.push({
- data: fragments.length + "_" + fragment,
- origin: origin,
- callback: fragments.length === 0 ? fn : null
- });
- }
- }
- else {
- queue.push({
- data: message,
- origin: origin,
- callback: fn
- });
- }
- if (lazy) {
- pub.down.init();
- }
- else {
- dispatch();
- }
- },
- destroy: function(){
- trace("destroy");
- destroying = true;
- pub.down.destroy();
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, undef, debug */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.VerifyBehavior
- * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
- * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} config The behaviors configuration.
- * @cfg {Boolean} initiate If the verification should be initiated from this end.
- */
-easyXDM.stack.VerifyBehavior = function(config){
- var trace = debug.getTracer("easyXDM.stack.VerifyBehavior");
- trace("constructor");
- if (undef(config.initiate)) {
- throw new Error("settings.initiate is not set");
- }
- var pub, mySecret, theirSecret, verified = false;
-
- function startVerification(){
- trace("requesting verification");
- mySecret = Math.random().toString(16).substring(2);
- pub.down.outgoing(mySecret);
- }
-
- return (pub = {
- incoming: function(message, origin){
- var indexOf = message.indexOf("_");
- if (indexOf === -1) {
- if (message === mySecret) {
- trace("verified, calling callback");
- pub.up.callback(true);
- }
- else if (!theirSecret) {
- trace("returning secret");
- theirSecret = message;
- if (!config.initiate) {
- startVerification();
- }
- pub.down.outgoing(message);
- }
- }
- else {
- if (message.substring(0, indexOf) === theirSecret) {
- pub.up.incoming(message.substring(indexOf + 1), origin);
- }
- }
- },
- outgoing: function(message, origin, fn){
- pub.down.outgoing(mySecret + "_" + message, origin, fn);
- },
- callback: function(success){
- if (config.initiate) {
- startVerification();
- }
- }
- });
-};
-/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
-/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
-//
-// easyXDM
-// http://easyxdm.net/
-// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-/**
- * @class easyXDM.stack.RpcBehavior
- * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
- * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
- * @namespace easyXDM.stack
- * @constructor
- * @param {Object} proxy The object to apply the methods to.
- * @param {Object} config The definition of the local and remote interface to implement.
- * @cfg {Object} local The local interface to expose.
- * @cfg {Object} remote The remote methods to expose through the proxy.
- * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
- */
-easyXDM.stack.RpcBehavior = function(proxy, config){
- var trace = debug.getTracer("easyXDM.stack.RpcBehavior");
- var pub, serializer = config.serializer || getJSON();
- var _callbackCounter = 0, _callbacks = {};
-
- /**
- * Serializes and sends the message
- * @private
- * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
- */
- function _send(data){
- data.jsonrpc = "2.0";
- pub.down.outgoing(serializer.stringify(data));
- }
-
- /**
- * Creates a method that implements the given definition
- * @private
- * @param {Object} The method configuration
- * @param {String} method The name of the method
- * @return {Function} A stub capable of proxying the requested method call
- */
- function _createMethod(definition, method){
- var slice = Array.prototype.slice;
-
- trace("creating method " + method);
- return function(){
- trace("executing method " + method);
- var l = arguments.length, callback, message = {
- method: method
- };
-
- if (l > 0 && typeof arguments[l - 1] === "function") {
- //with callback, procedure
- if (l > 1 && typeof arguments[l - 2] === "function") {
- // two callbacks, success and error
- callback = {
- success: arguments[l - 2],
- error: arguments[l - 1]
- };
- message.params = slice.call(arguments, 0, l - 2);
- }
- else {
- // single callback, success
- callback = {
- success: arguments[l - 1]
- };
- message.params = slice.call(arguments, 0, l - 1);
- }
- _callbacks["" + (++_callbackCounter)] = callback;
- message.id = _callbackCounter;
- }
- else {
- // no callbacks, a notification
- message.params = slice.call(arguments, 0);
- }
- if (definition.namedParams && message.params.length === 1) {
- message.params = message.params[0];
- }
- // Send the method request
- _send(message);
- };
- }
-
- /**
- * Executes the exposed method
- * @private
- * @param {String} method The name of the method
- * @param {Number} id The callback id to use
- * @param {Function} method The exposed implementation
- * @param {Array} params The parameters supplied by the remote end
- */
- function _executeMethod(method, id, fn, params){
- if (!fn) {
- trace("requested to execute non-existent procedure " + method);
- if (id) {
- _send({
- id: id,
- error: {
- code: -32601,
- message: "Procedure not found."
- }
- });
- }
- return;
- }
-
- trace("requested to execute procedure " + method);
- var success, error;
- if (id) {
- success = function(result){
- success = emptyFn;
- _send({
- id: id,
- result: result
- });
- };
- error = function(message, data){
- error = emptyFn;
- var msg = {
- id: id,
- error: {
- code: -32099,
- message: message
- }
- };
- if (data) {
- msg.error.data = data;
- }
- _send(msg);
- };
- }
- else {
- success = error = emptyFn;
- }
- // Call local method
- if (!isArray(params)) {
- params = [params];
- }
- try {
- var result = fn.method.apply(fn.scope, params.concat([success, error]));
- if (!undef(result)) {
- success(result);
- }
- }
- catch (ex1) {
- error(ex1.message);
- }
- }
-
- return (pub = {
- incoming: function(message, origin){
- var data = serializer.parse(message);
- if (data.method) {
- trace("received request to execute method " + data.method + (data.id ? (" using callback id " + data.id) : ""));
- // A method call from the remote end
- if (config.handle) {
- config.handle(data, _send);
- }
- else {
- _executeMethod(data.method, data.id, config.local[data.method], data.params);
- }
- }
- else {
- trace("received return value destined to callback with id " + data.id);
- // A method response from the other end
- var callback = _callbacks[data.id];
- if (data.error) {
- if (callback.error) {
- callback.error(data.error);
- }
- else {
- trace("unhandled error returned.");
- }
- }
- else if (callback.success) {
- callback.success(data.result);
- }
- delete _callbacks[data.id];
- }
- },
- init: function(){
- trace("init");
- if (config.remote) {
- trace("creating stubs");
- // Implement the remote sides exposed methods
- for (var method in config.remote) {
- if (config.remote.hasOwnProperty(method)) {
- proxy[method] = _createMethod(config.remote[method], method);
- }
- }
- }
- pub.down.init();
- },
- destroy: function(){
- trace("destroy");
- for (var method in config.remote) {
- if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
- delete proxy[method];
- }
- }
- pub.down.destroy();
- }
- });
-};
-global.easyXDM = easyXDM;
-})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);