UNPKG

kekule

Version:

Open source JavaScript toolkit for chemoinformatics

288 lines (281 loc) 7.24 kB
/** * @fileoverview * Support of an internal "clipboard" to transfer data between different widgets in one page. * @author Partridge Jiang */ /* * requires /lan/classes.js * requires /core/kekule.common.js * requires /utils/kekule.utils.js * requires /widget/kekule.widget.base.js * requires /xbrowsers/kekule.x.js */ (function(){ "use strict"; /** * A class to implement an internal "clipboard" to transfer data between different widgets * in one page. * @class * @augments ObjectEx * * @property {Bool} enableCrossPageClipboard Whether use window.localStorage to emulate clipboard * between different pages. */ /** * Invoked when the data is added into clipboard or cleared from clipboard. * event param of it has fields: {dataType, data} * @name Kekule.Widget.Clipboard#setData * @event */ Kekule.Widget.Clipboard = Class.create(ObjectEx, /** @lends Kekule.Widget.Clipboard# */ { /** @private */ CLASS_NAME: 'Kekule.Widget.Clipboard', /** @private */ STORAGE_KEY: '__$kekule_widget_clipboard__', /** * @constructs */ initialize: function(/*$super*/) { this.tryApplySuper('initialize') /* $super() */; this._data = new Kekule.MapEx(true); if (Kekule.BrowserFeature.localStorage) { this._crossPageStorage = window.localStorage; // window.sessionStorage; this.setEnableCrossPageClipboard(true); var self = this; Kekule.X.Event.addListener(window, 'storage', function(e){ if (self.getEnableCrossPageClipboard()) { var key = e.key; var dataType = self._extractSessionDataType(key); if (dataType) { self.invokeEvent('setData', {'dataType': dataType, 'data': self.deserializeData(e.newValue)}); } } }); } }, /** @ignore */ finalize: function(/*$super*/) { this._data.finalize(); this.tryApplySuper('finalize') /* $super() */; }, /** @private */ initProperties: function() { this.defineProp('enableCrossPageClipboard', {'dataType': DataType.BOOL}); }, /** @private */ _useSessionClipboard: function() { return this.getEnableCrossPageClipboard() && Kekule.BrowserFeature.localStorage; }, /** @private */ _extractSessionDataType: function(key) { return (key.startsWith(this.STORAGE_KEY))? key.substr(this.STORAGE_KEY.length): null; }, /** @private */ serializeData: function(data) { var result; if (DataType.isSimpleValue(data)) { result = JSON.stringify(data); } else // object { var jsonObj = {}; Class.ObjSerializerFactory.getSerializer('json').save(data, jsonObj); result = JSON.stringify(jsonObj); } return result; }, /** @private */ deserializeData: function(data) { var jsonObj = JSON.parse(data); if (DataType.isSimpleValue(jsonObj)) return jsonObj; else return Class.ObjSerializerFactory.getSerializer('json').load(null, jsonObj); }, /** * Add data to clipboard. * e.g. Kekule.Widget.Clipboard.setData('text/plain', 'A string'). * @param {String} dataType MIME type of data. * @param {Variant} data Data add to clipboard. */ setData: function(dataType, data) { if (this._useSessionClipboard()) { var s = this.serializeData(data); var success; try { this._crossPageStorage.setItem(this.STORAGE_KEY + dataType, s); success = true; } catch(err) // avoid possible failure of local storage in Firefox { Kekule.warn(err); } if (!success) this._data.set(dataType, data); // fallback approach } else { this._data.set(dataType, data); } this.invokeEvent('setData', {'dataType': dataType, 'data': data}); return this; }, /** * Get data from clipboard. * e.g. Kekule.Widget.Clipboard.getData('text/plain'). * @param {String} dataType * @returns {Variant} */ getData: function(dataType) { if (this._useSessionClipboard()) { var s, success; try { s = this._crossPageStorage.getItem(this.STORAGE_KEY + dataType); success = true; } catch(err) // avoid possible failure of local storage in Firefox { Kekule.warn(err); } if (success) return s? this.deserializeData(s): null; } //else return this._data.get(dataType); // fallback approach }, /** * Check there are data in clipboard. * @param {String} dataType * @returns {Bool} */ hasData: function(dataType) { if (this._useSessionClipboard()) { var s, success; try { s = this._crossPageStorage.getItem(this.STORAGE_KEY + dataType); success = true; } catch(err) // avoid possible failure of local storage in Firefox { Kekule.warn(err); } if (success) return Kekule.ObjUtils.notUnset(s); } //else return Kekule.ObjUtils.notUnset(this._data.get(dataType)); // fallback approach }, /** * Clear all data in clipboard. */ clearData: function() { if (this._useSessionClipboard()) { var types = this.getTypes(); for (var i = 0, l = types.length; i < l; ++i) { this._crossPageStorage.removeItem(this.STORAGE_KEY + types[i]); } } else this._data.clear(); this.invokeEvent('setData', {'dataType': null, 'data': null}); return this; }, /** * Returns all data types currently in clipboard. * @returns {Array} */ getTypes: function() { if (this._useSessionClipboard()) { var result = []; for (var i = 0, l = this._crossPageStorage.length; i < l; ++i) { var key = this._crossPageStorage.key(i); var dataType = this._extractSessionDataType(key); if (dataType) result.push(dataType); } return result; } else return this._data.getKeys(); }, /** * A util method to store array of objects into clipboard. * @param {String} dataType * @param {Array} objs */ setObjects: function(dataType, objs) { var jsonObjs = []; var serializer = Class.ObjSerializerFactory.getSerializer('json'); for (var i = 0, l = objs.length; i < l; ++i) { var obj = objs[i]; var jsonObj = {}; serializer.save(obj, jsonObj); jsonObjs.push(jsonObj); } var str = JSON.stringify(jsonObjs); //console.log('setObjects', str, jsonObjs); return this.setData(dataType, str); }, /** * A util method to load array of objects from clipboard. * @param {String} dataType * @returns {Variant} */ getObjects: function(dataType) { var data = this.getData(dataType); if (DataType.isSimpleValue(data)) { var jsonObjs = JSON.parse(data); if (!DataType.isArrayValue(jsonObjs)) jsonObjs = [jsonObjs]; var result = []; var serializer = Class.ObjSerializerFactory.getSerializer('json'); for (var i = 0, l = jsonObjs.length; i < l; ++i) { var jsonObj = jsonObjs[i]; var obj = serializer.load(null, jsonObj); result.push(obj); } //console.log('getObjects', data, result); return result; } else // complex value, object or array directly return data; } }); Kekule.ClassUtils.makeSingleton(Kekule.Widget.Clipboard); Kekule.Widget.clipboard = Kekule.Widget.Clipboard.getInstance(); })();