|
38 | 38 | } |
39 | 39 |
|
40 | 40 | CrossStorageHub._permissions = permissions || []; |
| 41 | + CrossStorageHub._eventListeners = {}; |
41 | 42 | CrossStorageHub._installListener(); |
42 | 43 | window.parent.postMessage('cross-storage:ready', '*'); |
43 | 44 | }; |
|
120 | 121 | /** |
121 | 122 | * Returns a boolean indicating whether or not the requested method is |
122 | 123 | * permitted for the given origin. The argument passed to method is expected |
123 | | - * to be one of 'get', 'set', 'del' or 'getKeys'. |
| 124 | + * to be one of 'get', 'set', 'del', 'clear', 'listen' or 'getKeys'. |
124 | 125 | * |
125 | 126 | * @param {string} origin The origin for which to determine permissions |
126 | 127 | * @param {string} method Requested action |
127 | 128 | * @returns {bool} Whether or not the request is permitted |
128 | 129 | */ |
129 | 130 | CrossStorageHub._permitted = function(origin, method) { |
130 | 131 | var available, i, entry, match; |
131 | | - |
132 | | - available = ['get', 'set', 'del', 'clear', 'getKeys']; |
| 132 | + if (method==='unlisten') method = 'listen'; |
| 133 | + available = ['get', 'set', 'listen', 'del', 'clear', 'getKeys']; |
133 | 134 | if (!CrossStorageHub._inArray(method, available)) { |
134 | 135 | return false; |
135 | 136 | } |
|
185 | 186 | return (result.length > 1) ? result : result[0]; |
186 | 187 | }; |
187 | 188 |
|
| 189 | + /** |
| 190 | + * Adds an event listener to `storage` events which sends all events to the client with the given eventKey |
| 191 | + * |
| 192 | + * @param {object} params An object with an eventKey |
| 193 | + */ |
| 194 | + CrossStorageHub._listen = function(params) { |
| 195 | + if (params.eventKey in CrossStorageHub._eventListeners) { |
| 196 | + throw new Error("Can't reuse eventKeys") |
| 197 | + } |
| 198 | + var handler = function(event) { |
| 199 | + if (event.storageArea != window.localStorage) return; |
| 200 | + var data = { |
| 201 | + type: 'event', |
| 202 | + eventKey: params.eventKey, |
| 203 | + eventData: { |
| 204 | + key: event.key, |
| 205 | + newValue: event.newValue, |
| 206 | + oldValue: event.oldValue, |
| 207 | + url: event.url |
| 208 | + // storageArea, ignored because we only use localStorage |
| 209 | + } |
| 210 | + }; |
| 211 | + window.parent.postMessage(JSON.stringify(data), '*'); |
| 212 | + }; |
| 213 | + |
| 214 | + // Support IE8 with attachEvent |
| 215 | + if (window.addEventListener) { |
| 216 | + window.addEventListener('storage', handler, false); |
| 217 | + } else { |
| 218 | + window.attachEvent('onstorage', handler); |
| 219 | + } |
| 220 | + CrossStorageHub._eventListeners[params.eventKey] = handler |
| 221 | + }; |
| 222 | + |
| 223 | + /** |
| 224 | + * Removes an event listener with the given eventKey |
| 225 | + * |
| 226 | + * @param {object} params An object with an eventKey |
| 227 | + */ |
| 228 | + CrossStorageHub._unlisten = function(params) { |
| 229 | + var handler = CrossStorageHub._eventListeners[params.eventKey]; |
| 230 | + |
| 231 | + // Support IE8 with attachEvent |
| 232 | + if (window.removeEventListener) { |
| 233 | + window.removeEventListener('storage', handler, false); |
| 234 | + } else { |
| 235 | + window.detachEvent('onstorage', handler); |
| 236 | + } |
| 237 | + CrossStorageHub._eventListeners[params.eventKey] = null |
| 238 | + }; |
| 239 | + |
188 | 240 | /** |
189 | 241 | * Deletes all keys specified in the array found at params.keys. |
190 | 242 | * |
|
0 commit comments