diff -r 3ec52facab4d -r 8192e5b5c935 mpviewplugins/mpdetailsviewplugin/tsrc/unittest_resources/test-src/publishplayer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpviewplugins/mpdetailsviewplugin/tsrc/unittest_resources/test-src/publishplayer.js Thu May 27 12:49:57 2010 +0300 @@ -0,0 +1,1312 @@ +window["ovi"] = window["ovi"] || +{}; +ovi.player = ovi.player || +{}; +ovi.player.contextobject = ovi.player.contextobject || +{}; + +ovi.player.contextobject.getInstance = function(config) { + var player = {}; + player._create = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "CREATE_PENDING"); + } + // TODO: add context object to player store + // TODO: store options.miniview to be returned with view as HTML + // TODO: store other properties of options to be returned with view as JSON + // TODO: return uri (unique id in this player's store) in callback + }; + player._cancel = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "CANCEL_PENDING"); + } + // TODO: cancel pending tasks + // TODO: cancel Player + }; + player._delete = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "DELETE_PENDING"); + } + // TODO: delete object defined in options.uri from store + }; + player._edit = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "EDIT_PENDING"); + } + // TODO: update object defined in options.uri + }; + player._pick = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "PICK_PENDING"); + } + // TODO: return list of all objects, or object defined in options.uri, fork with options.view + }; + player._view = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "VIEW_PENDING"); + } + // TODO: return object defined in options.uri, JSON if options.view == "none", HTML if "mini" + }; + ovi.player._getInstance.call(player, config); +}; + +ovi.player.contextobject.Player = ovi.player.contextobject.getInstance; +/* + * Basic namespaces & common Player functions + */ + + + +window["ovi"] = window["ovi"] || +{}; +ovi.player = ovi.player || +{}; + + + +/** + * A function for creating a callback chain + * @param {Object} options + * @param {Object} handler + * @param {Object} context + * @return {Function} + */ +ovi.player._notImplemented = function(functionId) { + return function() { + var status = ovi.player._status; + handler.call(context, status["NOT_IMPLEMENTED"], null); + handler.call(context, status[functionId + "_FAILURE"], null); // TODO: return description, too? + }; +}; + + + +/** + * A method for returning an instance of a singleton + * @param {Object} options A configuration object for the player + */ +ovi.player._getInstance = function(options) { + // TODO: store the configuration options + return (function() { + return (this.instance || + (function() { + this.instance = { + // Public interface + cancel: (this._cancel || ovi.player._notImplemented("CANCEL")), + create: (this._create || ovi.player._notImplemented("CREATE")), + "delete": (this._delete || ovi.player._notImplemented("DELETE")), // delete is a keyword + edit: (this._edit || ovi.player._notImplemented("EDIT")), + pick: (this._pick || ovi.player._notImplemented("PICK")), + show: (this._view || ovi.player._notImplemented("VIEW")), // show is the same function as view, included in API for compatibility + sync: (this._sync || ovi.player._notImplemented("SYNC")), + view: (this._view || ovi.player._notImplemented("VIEW")) + }; + return this.instance; + }())); + }()); +}; + + + +ovi.player._status = { + USER_CANCEL: "USER_CANCEL", + + CANCEL_PENDING: "CANCEL_PENDING", + CANCEL_FAILURE: "CANCEL_FAILURE", + CANCEL_SUCCESS: "CANCEL_SUCCESS", + + CREATE_PENDING: "CREATE_PENDING", + CREATE_FAILURE: "CREATE_FAILURE", + CREATE_SUCCESS: "CREATE_SUCCESS", + + DELETE_PENDING: "DELETE_PENDING", + DELETE_FAILURE: "DELETE_FAILURE", + DELETE_SUCCESS: "DELETE_SUCCESS", + + EDIT_PENDING: "EDIT_PENDING", + EDIT_FAILURE: "EDIT_FAILURE", + EDIT_SUCCESS: "EDIT_SUCCESS", + + PICK_PENDING: "PICK_PENDING", + PICK_FAILURE: "PICK_FAILURE", + PICK_SUCCESS: "PICK_SUCCESS", + + SYNC_PENDING: "SYNC_PENDING", + SYNC_FAILURE: "SYNC_FAILURE", + SYNC_SUCCESS: "SYNC_SUCCESS", + SYNC_CONNECT_PENDING: "SYNC_CONNECT_PENDING", + SYNC_CONNECT_FAILED: "SYNC_CONNECT_FAILED", + SYNC_CONNECT_SUCCEEDED: "SYNC_CONNECT_SUCCEEDED", + SYNC_LOGIN_PENDING: "SYNC_LOGIN_PENDING", + SYNC_LOGIN_FAILED: "SYNC_LOGIN_FAILED", + SYNC_LOGIN_SUCCEEDED: "SYNC_LOGIN_SUCCEEDED", + SYNC_UPDATE_PENDING: "SYNC_UPDATE_PENDING", + SYNC_UPDATE_FAILED: "SYNC_UPDATE_FAILED", + SYNC_UPDATE_SUCCEEDED: "SYNC_UPDATE_SUCCEEDED", + + VIEW_PENDING: "VIEW_PENDING", + VIEW_FAILURE: "VIEW_FAILURE", + VIEW_SUCCESS: "VIEW_SUCCESS", + + NOT_IMPLEMENTED: "NOT_IMPLEMENTED" +}; +window["ovi"] = window["ovi"] || +{}; +ovi.player = ovi.player || +{}; +ovi.player.publish = ovi.player.publish || +{}; + +ovi.player.publish.getInstance = function(config) { + var player = {}; + player._create = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "CREATE_PENDING"); + } + // TODO: create UI + // TODO: get the sub-players, sync them + }; + player._cancel = function(options, handler, context) { + var callable = (typeof handler === "function"); + if (callable) { + handler.call(context, "CANCEL_PENDING"); + } + // TODO: cancel sub-players + // TODO: cancel pending tasks + // TODO: cancel Player + }; + ovi.player._getInstance.call(player, config); +}; + +ovi.player.publish.Player = ovi.player.publish.getInstance; +window["ovi"] = (window["ovi"] || {}); +ovi.player = (ovi.player || {}); +ovi.player.snc = (ovi.player.snc || {}); +ovi.player.snc.engine = (ovi.player.snc.engine || {}); + + +(function(){ + + var engine = ovi.player.snc.engine; + + + engine.status = { + SUCCESS : "SUCCESS", + FAILED : "FAILED", + } + + + var _callback = function(status, data, callback, context) { + if (typeof callback == "function") { + callback.call(context, status, data); + } + } + + // External functions + + /** + * Publish the given object to the social networks. + * @param {Object} object Published data + * @param {String} object.text Free text + * @param {String} object.context.artist Artist name + * @param {String} object.context.title Song title + * @param {Array} object.networks Array of social networks ids where to publish + * @param {Object} [callback] Called when publish is ready. + * @param {Object} [context] + */ + engine.publish = function(data, callback, context){ + + // Just concatenate some status text from received data + var status = data.text; + + // Add attached objects (temporarily just append to end of text) + // TODO : object.type == "URI" ... etc., add as attachment when supported by SNC + if (typeof data.object != "undefined") { + // Get URL to song before publishing and to status text + var link = data.object.content; + if (link.length > 0) { + status += " - " + link; + } + } + + // Update to services + ovi.activities.updateStatus(status, {networkId: data.networks }, function(response){ + + if (response.status == "success") { + _callback(engine.status.SUCCESS, null, callback, context); + } + else { + // TODO : Implement finer error handling + _callback(engine.status.FAILED, { message : "Status update failed" }, callback, context); + } + }); + } + + /** + * + * @param {Object} data + * @param {Object} callback + * @param {Object} context + */ + engine.cancelPublish = function(data, callback, context){ + _callback(engine.status.SUCCESS, null, callback, context); + } + + + /** + * Reload social networks from SNC backend to the local store. Use getServices() to retrieve the + * list of loaded services. + * @param {Object} options Object containing Noa account information. Can be user, password or already + * autheticated session token to be used. { username : "", password : "" } or { token : "" } + * @param {Object} callback + * @param {Object} context + */ + engine.sync = function(options, callback, context) { + + // TODO : Seperate init and login from sync (we need both for publish also...) + + // Do service didscovery + + // 1. Init APIs + requests.initOviApi(function(response){ + + if(response.status != engine.status.SUCCESS) { + _callback(engine.status.FAILED, response.data, callback, context); + return; + } + + // 2. Login noa + requests.noaLogin(options, function(response){ + + if(response.status != engine.status.SUCCESS) { + _callback(engine.status.FAILED, { message: response.message }, callback, context); + return; + } + + // 3. Service discover + requests.discover(function(response){ + + // Store to player store + store.clear(); + store.append(response.networks); + store.commit(); + + // Callback function + if (response.status == engine.status.SUCCESS) { + _callback(engine.status.OK, { networks: response.networks }, callback, context); + } + else { + _callback(engine.status.FAILED, { message: response.message }, callback, context); + } + }); + }); + }); + } + + /** + * Get list of services (social networks). Data is loaded from local + * player store. To synchronize data social networks from SNC call sync(). + */ + engine.getServices = function() { + // Get list of services from store + return store.getList(); + } + + /** + * Mark service as selected / unselected. Saves the selection to the persistent + * local storage to save data over sessions. + * @param {Object} id + * @param {Object} enable + */ + engine.selectService = function(id, enable) { + // Select / unselect service in player store + store.select(id, enable); + } + + // Player store + var STORE_KEY_SERVICES = "ovi.player.snc.services"; + var STORE_KEY_SELECTED = "ovi.player.snc.services.selected"; + + /** + * Player store implementation. Persists the social networks (services) and selections + * to the HTML5 local storage, which provides over sessions caching. + */ + var store = { + + _services : {}, + _selected : {}, + + /** + * Add new server or services to the store. + * @param {Object} service + */ + append : function(service) { + if (service.length) { + for(var i=0; i < service.length; i++) { + var s = service[i]; + this._services[s.id] = s; + } + } else { + this._services[service.id] = service; + } + }, + + /** + * Mark service selected or unselected in the store. Also commits changes in + * selections to the store. + * @param {Object} id + * @param {Object} enable + */ + select : function(id, enable) { + this._selected[id] = enable; + localStorage.setItem(STORE_KEY_SELECTED, JSON.stringify(this._selected)); + }, + + /** + * Clear services. + */ + clear : function() { + this._services = {}; + }, + + /** + * Get list (array) of services in the store. + */ + getList : function() { + // Convert to array + var res = []; + for(var o in this._services) { + var serv = this._services[o]; + serv.selected = typeof this._selected[o] != "undefined" ? this._selected[o] : false; + res.push(serv); + } + return res; + }, + + /** + * Commit services to the store. + */ + commit : function() { + localStorage.setItem(STORE_KEY_SERVICES, JSON.stringify(this._services)); + }, + + /** + * Retrieve services and selections in the store. + */ + load : function() { + this._services = JSON.parse(localStorage.getItem(STORE_KEY_SERVICES)); + this._selected = JSON.parse(localStorage.getItem(STORE_KEY_SELECTED)); + + if (this._services == null) this._services = {}; + if (this._selected == null) this._selected = {}; + } + } + + + // SNC Request implementation + var requests = { + + /** + * + * @param {Object} callback + */ + initOviApi: function(callback){ + var myincludes = "ovi.auth.noa_login, ovi.api.snc, ovi.api.activities, ovi.net.xss"; + ovi.onReady = function(libs){ + if (ovi.testIfLoaded(myincludes, libs)) { + + // Successful, set environment for NCIM + ovi.config.setenv("st-account", "delegate"); + + // Allow cross-domain scripting + function xssInitCallback(data){ + if (data.event === "InitializeOk") { + callback( { status : engine.status.SUCCESS }); + } + } + + ovi.net.XssInit({ + back_url: "http://spb.ci.wipsl.com/ovi-api/js/ovi/net/", + callback: xssInitCallback + }); + + } + } + + ovi.include(myincludes); + }, + + /** + * + * @param {Object} callback + */ + noaLogin: function(options, callback){ + + var noa = {}; + if (typeof options.token != "undefined") { // This propably is not supported yet.. + noa = { token : options.token }; + } + else { + noa = { username : options.username, password : options.password }; + } + + // Login + ovi.noa.login(noa, function(state){ + + // Callback + if (state.status == "success") { + callback( { + status: engine.status.SUCCESS + } ); + } + else { + callback( { + status: engine.status.FAILED, + message: "NOA login failed - " + state.statusCode + " - " + state.status + } ); + } + }); + }, + + /** + * + * @param {Object} callback + */ + discover: function(callback){ + + // Discover service available + ovi.snc.discoverSocialNetworks(function(response){ + + if (response.status != "success") { + callback( { + status: engine.status.FAILED, + message : "Service discovery failed - " + response.statusCode + " - " + response.responseText + } ); + return; + } + + var netw = response.data.network; + + // And get activated + ovi.snc.getActivatedSocialNetworks(function(response){ + + if (response.status != "success") { + callback( { + status: engine.status.FAILED, + message : "Service discovery failed - " + response.statusCode + " - " + response.responseText + } ); + + return; + } + else if (response.statusCode == 204) { // Not an error, no active networks + callback( { + status: engine.status.SUCCESS, + networks : [] + } ); + + return; + } + + var active = response.data.network; + + // Now we have finally the service discovery ready, create final response + // Remove all not-active networks from supported networks + var results = []; + for(var i=0; i < netw.length; i++) { + var id = netw[i].id; + + for(var j=0; j < active.length; j++) { + if (active[j].id == id) { + // We have a winner + results.push({ name : netw[i].name, id : netw[i].id, maxTextInput : netw[i].maxTextInput }); + break; + } + } + } + + callback( { + status: engine.status.SUCCESS, + networks : results + } ); + }); + }); + } + } + + // Restore data from store + store.load(); + +})(); +// Create needed namespace ovi.player.share.ui +window["ovi"] = window["ovi"] || +{}; +ovi.player = ovi.player || +{}; +ovi.player.share = ovi.player.share || +{}; +ovi.player.share.ui = ovi.player.share.ui || +{}; + +/** + * TODO + * + * This API tries to imitate medos framework UI controls for future compability. + * @param {Object} params + * @param {Object} target + */ +ovi.player.share.ui.Button = function(params, target) { + + var CLICK_EVENT = "selected"; + var that = this; + + function createHtml() { + var template = ''; + + var node = document.createElement("div"); // Do we need this ?? + node.innerHTML = template; + return node; + } + + var _root = createHtml(); + var _button = _root.firstChild; + + target.appendChild(_root); + + // Interface functions + this.addEventHandler = function(event, callback) { + // selected = click (comes from medos...) + if (event == CLICK_EVENT) { + _root.addEventListener("click", function(e) { callback.call(that, e); }, that); + } + } + + this.setProperty = function(name, value) { + _button[name] = value; + } + + this.getProperty = function(name) { + return _button[name]; + } +} +// Create needed namespace ovi.player.share.ui +window["ovi"] = window["ovi"] || +{}; +ovi.player = ovi.player || +{}; +ovi.player.share = ovi.player.share || +{}; +ovi.player.share.ui = ovi.player.share.ui || +{}; + +/** + * Checkbox UI control implementation. TODO + * + * This API tries to imitate medos framework UI controls for future compability. + * @param {Object} params + * @param {Object} target + */ +ovi.player.share.ui.CheckBox = function(params, target) { + + var that = this; + + function createHtml() { + + var template = '