data.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /**
  2. * User preferences with default values
  3. */
  4. var preferences_template = {
  5. // Show alerts when the user performs some operations such as deleting a cookie
  6. "showAlerts": {
  7. "default_value": false
  8. },
  9. // Show labels in the popup window next to some of the buttons
  10. "showCommandsLabels": {
  11. "default_value": false
  12. },
  13. // Show the domain in the accordion of the popup window next to each cookie's name
  14. "showDomain": {
  15. "default_value": true
  16. },
  17. // Show the domain before the name of the cookie in the accordion
  18. "showDomainBeforeName": {
  19. "default_value": true
  20. },
  21. // Show the BlockAndDeleteAll button in the popup window. This is an advanded operation, hence it's disabled by default
  22. "showFlagAndDeleteAll": {
  23. "default_value": false
  24. },
  25. // Show an option to open EditThisCookie as a separate tab in the context menu
  26. "showContextMenu": {
  27. "default_value": true
  28. },
  29. // If enabled, after submitting cookie changes, the active tab will be refreshed
  30. "refreshAfterSubmit": {
  31. "default_value": false
  32. },
  33. // If enabled, the cache will be bypassed when reloading a page
  34. "skipCacheRefresh": {
  35. "default_value": true
  36. },
  37. // ETC has a feature to limit the maximum age of any cookie that is being set by websites.
  38. // This feature is controlled by the next three variables:
  39. // If true, this feature is enabled
  40. "useMaxCookieAge": {
  41. "default_value": false
  42. },
  43. // The multiplier for maxCookieAge in order to obtain the right number of seconds. 3600 for hour, 86400 for day, ...
  44. // -1 if not set
  45. "maxCookieAgeType": {
  46. "default_value": -1
  47. },
  48. // The time basic unit, to be used in conjunction with the previous variable to calculate the maximum allowed age
  49. "maxCookieAge": {
  50. "default_value": 1
  51. },
  52. // If true, a custom locale is used rather than the default set by the brower
  53. "useCustomLocale": {
  54. "default_value": false
  55. },
  56. // The custom locale to use
  57. "customLocale": {
  58. "default_value": "en"
  59. },
  60. // The output format to use when exporting cookies to the clipboard.
  61. // Supported: netscape, json, semicolonPairs. For reference, see cookie_helpers.js -> "cookiesToString"
  62. "copyCookiesType": {
  63. "default_value": "json"
  64. },
  65. // If true, the standard icon on the toobar is changed for a christmassy one in certain periods of the year
  66. "showChristmasIcon": {
  67. "default_value": true
  68. },
  69. // How cookies will be sorted. Supported values:
  70. // alpha: alphabetic ordering by cookie name
  71. // domain_alpha: alphabetic ordering by domain and cookie name
  72. "sortCookiesType": {
  73. "default_value": "domain_alpha"
  74. },
  75. // Whether to show the panel in the DevTools panel (e.g. panel shown when pressing F12)
  76. "showDevToolsPanel": {
  77. "default_value": true
  78. }
  79. };
  80. /**
  81. * User data with default values
  82. */
  83. var data_template = {
  84. "filters": {
  85. "default_value": []
  86. },
  87. "readOnly": {
  88. "default_value": []
  89. },
  90. "nCookiesCreated": {
  91. "default_value": 0
  92. },
  93. "nCookiesChanged": {
  94. "default_value": 0
  95. },
  96. "nCookiesDeleted": {
  97. "default_value": 0
  98. },
  99. "nCookiesProtected": {
  100. "default_value": 0
  101. },
  102. "nCookiesFlagged": {
  103. "default_value": 0
  104. },
  105. "nCookiesShortened": {
  106. "default_value": 0
  107. },
  108. "nPopupClicked": {
  109. "default_value": 0
  110. },
  111. "nPanelClicked": {
  112. "default_value": 0
  113. },
  114. "nCookiesImported": {
  115. "default_value": 0
  116. },
  117. "nCookiesExported": {
  118. "default_value": 0
  119. },
  120. "lastVersionRun": {
  121. "default_value": undefined
  122. }
  123. };
  124. var preferences = {};
  125. var data = {};
  126. var preferences_prefix = "options_";
  127. var data_prefix = "data_";
  128. var updateCallback = undefined;
  129. var dataToSync = [];
  130. var syncTimeout = false;
  131. var syncTime = 200;
  132. /**
  133. * Used to access settings and data in local storage
  134. */
  135. var ls = {
  136. /**
  137. * Stores an object in the local storage
  138. * @param name Name of the object to be stored
  139. * @param value Value of the object to be stored
  140. */
  141. set: function (name, value) {
  142. localStorage.setItem(name, JSON.stringify(value));
  143. },
  144. /**
  145. * Get an object from local storage. If it doesn't exist, create one and add it to the local storage
  146. * @param name Name of the object to fetch
  147. * @param default_value Value to assign to the object if it doesn't exist.
  148. * @return The fetched/created object
  149. */
  150. get: function (name, default_value) {
  151. if (localStorage[name] === undefined) {
  152. if (default_value !== undefined)
  153. ls.set(name, default_value);
  154. else
  155. return null;
  156. return default_value;
  157. }
  158. try {
  159. return JSON.parse(localStorage.getItem(name));
  160. } catch (e) {
  161. ls.set(name, default_value);
  162. return default_value;
  163. }
  164. },
  165. /**
  166. * Remove an object from the local storage
  167. * @param name Name of the object to delete
  168. */
  169. remove: function (name) {
  170. localStorage.removeItem(name);
  171. }
  172. };
  173. /**
  174. * This function is called regularly every "syncTime" ms.
  175. * The purpose of the following logic is to allow users of localStorage to modify user preferences and data
  176. * without having to worry about manually updating the local storage. It will be synced across all open pages
  177. * of the extension.
  178. */
  179. function syncDataToLS() {
  180. for (var cID in dataToSync) {
  181. var cVal = dataToSync[cID];
  182. delete dataToSync[cID];
  183. ls.set(cID, cVal);
  184. }
  185. syncTimeout = false;
  186. }
  187. /**
  188. * Fetch data from the localStorage based on the previously declared templates (preferences_template and data_template).
  189. */
  190. function fetchData() {
  191. for (var key in preferences_template) {
  192. default_value = preferences_template[key].default_value;
  193. preferences[key] = ls.get(preferences_prefix + key, default_value);
  194. /**
  195. * When a preference change is detected, it will be added to the queue (dataToSync).
  196. * Once the timer ticks in, data is taken off the queue and stored in the localStorage
  197. * @param id Name of the element being modified
  198. * @param oldval Old value
  199. * @param newval New value
  200. */
  201. var onPreferenceChange = function (id, oldval, newval) {
  202. dataToSync[preferences_prefix + id] = newval;
  203. if (!syncTimeout)
  204. syncTimeout = setTimeout(syncDataToLS, syncTime);
  205. return newval;
  206. };
  207. /**
  208. * When a preference is read, mark it as dirty.
  209. * @param id Name of the element being read
  210. */
  211. var onPreferenceRead = function (id) {
  212. preferences_template[id].used = true;
  213. };
  214. // Monitor the preferences for changes
  215. preferences.watch(key, onPreferenceChange, onPreferenceRead);
  216. }
  217. for (var key in data_template) {
  218. default_value = data_template[key].default_value;
  219. data[key] = ls.get(data_prefix + key, default_value);
  220. /**
  221. * When data change is detected, it will be added to the queue (dataToSync).
  222. * Once the timer ticks in, data is taken off the queue and stored in the localStorage
  223. * @param id Name of the element being modified
  224. * @param oldval Old value
  225. * @param newval New value
  226. */
  227. var onDataChange = function (id, oldval, newval) {
  228. dataToSync[data_prefix + id] = newval;
  229. if (!syncTimeout)
  230. syncTimeout = setTimeout(syncDataToLS, syncTime);
  231. return newval;
  232. };
  233. /**
  234. * When data is read, mark it as dirty.
  235. * @param id Name of the element being read
  236. */
  237. var onDataRead = function (id) {
  238. data_template[id].used = true;
  239. };
  240. // Monitor the data for changes
  241. data.watch(key, onDataChange, onDataRead);
  242. }
  243. }
  244. /**
  245. * Monitor the storage for changes. When triggered it checks to see whether any preference or data has changed.
  246. * If so, it verifies whether that data had been used.
  247. * If relevant data has changed and an update callback has been set, it will be called.
  248. */
  249. window.addEventListener("storage", function (event) {
  250. try {
  251. var varUsed = false;
  252. var varChanged = false;
  253. var oldValue = (event.oldValue !== null) ? JSON.parse(event.oldValue) : null;
  254. var newValue = (event.newValue !== null) ? JSON.parse(event.newValue) : null;
  255. if (oldValue === newValue)
  256. return;
  257. var key;
  258. if (event.key.indexOf(preferences_prefix) === 0) {
  259. key = event.key.substring(preferences_prefix.length);
  260. varUsed = !!preferences_template[key].used;
  261. varChanged = preferences[key] !== newValue;
  262. preferences[key] = (newValue === null) ? preferences_template[key].default_value : newValue;
  263. preferences_template[key].used = varUsed;
  264. } else if (event.key.indexOf(data_prefix) === 0) {
  265. key = event.key.substring(data_prefix.length);
  266. varUsed = (data_template[key].used !== undefined && data_template[key].used);
  267. varChanged = data[key] !== newValue;
  268. data[key] = (newValue === null) ? data_template[key].default_value : newValue;
  269. data_template[key].used = varUsed;
  270. }
  271. if (varUsed && varChanged && updateCallback !== undefined) {
  272. updateCallback();
  273. }
  274. } catch (e) {
  275. console.error("Failed to call on the updateCallback.");
  276. console.error(e.message);
  277. }
  278. }, false);
  279. // Finally fetch the data
  280. fetchData();
  281. firstRun = ls.get("status_firstRun");
  282. if (firstRun !== null) {
  283. data.lastVersionRun = chrome.runtime.getManifest().version;
  284. }
  285. // On exit, make sure any data in the queue is synced to the localStorage
  286. var syncTimeout = setTimeout(syncDataToLS, syncTime);
  287. $(window).bind("beforeunload", syncDataToLS);