diff --git a/guacamole/src/main/webapp/scripts/client-ui.js b/guacamole/src/main/webapp/scripts/client-ui.js index e32b6a46b..604abfb82 100644 --- a/guacamole/src/main/webapp/scripts/client-ui.js +++ b/guacamole/src/main/webapp/scripts/client-ui.js @@ -841,7 +841,7 @@ GuacUI.Client.updateDisplayScale = function() { // If auto-fit is enabled, scale display if (!GuacUI.Client.overrideAutoFit - && GuacUI.sessionState.getProperty("auto-fit", true)) { + && GuacamoleSessionStorage.getItem("auto-fit", true)) { // Calculate scale to fit screen var fit_scale = Math.min( @@ -1065,8 +1065,9 @@ GuacUI.Client.attach = function(guac) { GuacUI.Client.titlePrefix = null; // Update clipboard with current data - if (GuacUI.sessionState.getProperty("clipboard")) - guac.setClipboard(GuacUI.sessionState.getProperty("clipboard")); + var clipboard = GuacamoleSessionStorage.getItem("clipboard"); + if (clipboard) + guac.setClipboard(clipboard); break; @@ -1131,7 +1132,7 @@ GuacUI.Client.attach = function(guac) { // Set contents when done reader.onend = function clipboard_text_end() { - GuacUI.sessionState.setProperty("clipboard", data); + GuacamoleSessionStorage.setItem("clipboard", data); }; }; @@ -1417,12 +1418,12 @@ GuacUI.Client.attach = function(guac) { }; - GuacUI.sessionState.onchange = function(old_state, new_state, name) { + GuacamoleSessionStorage.addChangeListener(function(name, value) { if (name === "clipboard" && GuacUI.Client.attachedClient) - GuacUI.Client.attachedClient.setClipboard(new_state[name]); + GuacUI.Client.attachedClient.setClipboard(value); else if (name === "auto-fit") GuacUI.Client.updateDisplayScale(); - }; + }); var long_press_start_x = 0; var long_press_start_y = 0; diff --git a/guacamole/src/main/webapp/scripts/guac-ui.js b/guacamole/src/main/webapp/scripts/guac-ui.js index d8103a35f..ede090b68 100644 --- a/guacamole/src/main/webapp/scripts/guac-ui.js +++ b/guacamole/src/main/webapp/scripts/guac-ui.js @@ -26,11 +26,6 @@ */ var GuacUI = GuacUI || {}; -/** - * Current session state, including settings. - */ -GuacUI.sessionState = new GuacamoleSessionState(); - /** * Creates a new element having the given tagname and CSS class. */ @@ -186,7 +181,7 @@ GuacUI.Audio = new (function() { this.supported = []; // If sound disabled, we're done now. - if (GuacUI.sessionState.getProperty("disable-sound", false)) + if (GuacamoleSessionStorage.getItem("disable-sound", false)) return; // Build array of supported audio formats diff --git a/guacamole/src/main/webapp/scripts/root-ui.js b/guacamole/src/main/webapp/scripts/root-ui.js index a56b698de..87f3948fa 100644 --- a/guacamole/src/main/webapp/scripts/root-ui.js +++ b/guacamole/src/main/webapp/scripts/root-ui.js @@ -59,7 +59,6 @@ var GuacamoleRootUI = { "connections" : document.getElementById("connection-list-ui") }, - "session_state" : new GuacamoleSessionState(), "parameters" : null }; @@ -363,7 +362,7 @@ window.name = ""; GuacamoleRootUI.settings.auto_fit.onchange = GuacamoleRootUI.settings.auto_fit.onclick = function() { - GuacamoleRootUI.session_state.setProperty( + GuacamoleSessionStorage.setItem( "auto-fit", GuacamoleRootUI.settings.auto_fit.checked); }; @@ -375,7 +374,7 @@ GuacamoleRootUI.settings.auto_fit.onclick = function() { GuacamoleRootUI.settings.disable_sound.onchange = GuacamoleRootUI.settings.disable_sound.onclick = function() { - GuacamoleRootUI.session_state.setProperty( + GuacamoleSessionStorage.setItem( "disable-sound", GuacamoleRootUI.settings.disable_sound.checked); }; @@ -389,8 +388,7 @@ GuacamoleRootUI.fields.clipboard.onchange = function() { // Set value if changed var new_value = GuacamoleRootUI.fields.clipboard.value; - if (GuacamoleRootUI.session_state.getProperty("clipboard") != new_value) - GuacamoleRootUI.session_state.setProperty("clipboard", new_value); + GuacamoleSessionStorage.setItem("clipboard", new_value); }; @@ -398,43 +396,39 @@ GuacamoleRootUI.fields.clipboard.onchange = function() { * Update element states when session state changes */ -GuacamoleRootUI.session_state.onchange = -function(old_state, new_state, name) { + +GuacamoleSessionStorage.addChangeListener(function(name, value) { // Clipboard - if (name == "clipboard") - GuacamoleRootUI.fields.clipboard.value = new_state[name]; + if (name === "clipboard") + GuacamoleRootUI.fields.clipboard.value = value; // Auto-fit display - else if (name == "auto-fit") - GuacamoleRootUI.fields.auto_fit.checked = new_state[name]; + else if (name === "auto-fit") + GuacamoleRootUI.fields.auto_fit.checked = value; // Disable Sound - else if (name == "disable-sound") - GuacamoleRootUI.fields.disable_sound.checked = new_state[name]; + else if (name === "disable-sound") + GuacamoleRootUI.fields.disable_sound.checked = value; -}; +}); /* * Initialize clipboard with current data */ -if (GuacamoleRootUI.session_state.getProperty("clipboard")) - GuacamoleRootUI.fields.clipboard.value = - GuacamoleRootUI.session_state.getProperty("clipboard"); +GuacamoleRootUI.fields.clipboard.value = GuacamoleSessionStorage.getItem("clipboard", ""); /* * Initialize auto-fit setting in UI */ -GuacamoleRootUI.settings.auto_fit.checked = - GuacamoleRootUI.session_state.getProperty("auto-fit", true); +GuacamoleRootUI.settings.auto_fit.checked = GuacamoleSessionStorage.getItem("auto-fit", true); /* * Initialize disable-sound setting in UI */ -GuacamoleRootUI.settings.disable_sound.checked = - GuacamoleRootUI.session_state.getProperty("disable-sound", false); +GuacamoleRootUI.settings.disable_sound.checked = GuacamoleSessionStorage.getItem("disable-sound", false); /* * Set handler for logout diff --git a/guacamole/src/main/webapp/scripts/session.js b/guacamole/src/main/webapp/scripts/session.js index ba9991305..1ec60fd0c 100644 --- a/guacamole/src/main/webapp/scripts/session.js +++ b/guacamole/src/main/webapp/scripts/session.js @@ -21,96 +21,140 @@ */ /** - * Maintains state across multiple Guacamole pages via HTML5 Web Storage. - * @constructor + * Global storage for Guacamole pages. */ -function GuacamoleSessionState() { +GuacamoleSessionStorage = (opener && opener.GuacamoleSessionStorage) || new (function() { /** - * Reference to this GuacamoleSessionState. + * The contents of storage, as a JSON string containing name/value pairs as + * properties. + * * @private + * @type String */ - var guac_state = this; + var stored_json = "{}"; /** - * The last read state object. - * @private + * Called whenever an item value changes. + * + * @callback onchange + * @param {String} name The name of the item changed. + * @param value The new item value. */ - var state = localStorage.getItem("GUACAMOLE_STATE") || {}; /** - * Reloads the internal state, sending onchange events for all changed, - * deleted, or new properties. + * All attached listeners. + * + * @type onchange[] */ - this.reload = function() { + var listeners = []; - // Pull current state - var new_state = JSON.parse(localStorage.getItem("GUACAMOLE_STATE") || "{}"); - - // Assign new state - var old_state = state; - state = new_state; + /** + * Notifies all listeners that an item has changed. + * + * @param {String} name The name of the item that changed. + * @param value The new item value. + */ + function __notify_changed(name, value) { + for (var i=0; i