blob: 27db635490901398e773f30cc37bf33dff6e9ca3 [file] [log] [blame]
Adrià Vilanova Martíneze32adc42021-08-30 17:16:49 +02001import {getExtVersion, isFirefox, isReleaseVersion} from './common/extUtils.js';
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +02002import {cleanUpOptions, optionsPrototype, specialOptions} from './common/optionsUtils.js';
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +02003
avm99963bf8eece2021-04-22 00:27:03 +02004var savedSuccessfullyTimeout = null;
5
6const exclusiveOptions = [['thread', 'threadall']];
7
Adrià Vilanova Martíneze32adc42021-08-30 17:16:49 +02008// Get a URL to a document which is part of the extension documentation (using
9// |ref| as the Git ref).
10function getDocURLWithRef(doc, ref) {
11 return 'https://gerrit.avm99963.com/plugins/gitiles/infinitegforums/+/' +
12 ref + '/docs/' + doc;
13}
14
15// Get a URL to a document which is part of the extension documentation
16// (autodetect the appropriate Git ref)
17function getDocURL(doc) {
18 if (!isReleaseVersion()) return getDocURLWithRef(doc, 'HEAD');
19
20 var version = getExtVersion();
21 return getDocURLWithRef(doc, 'refs/tags/v' + version);
22}
23
avm99963bf8eece2021-04-22 00:27:03 +020024// Get the value of the option set in the options/experiments page
25function getOptionValue(opt) {
26 if (specialOptions.includes(opt)) {
27 switch (opt) {
28 case 'profileindicatoralt_months':
29 return document.getElementById(opt).value || 12;
30
31 case 'ccdarktheme_mode':
32 return document.getElementById(opt).value || 'switch';
33
34 case 'ccdragndropfix':
35 return document.getElementById(opt).checked || false;
36
37 default:
38 console.warn('Unrecognized option: ' + opt);
39 return undefined;
40 }
41 }
42
43 return document.getElementById(opt).checked || false;
44}
45
46// Returns whether the option is included in the current context
47function isOptionShown(opt) {
48 if (!optionsPrototype.hasOwnProperty(opt)) return false;
49 return optionsPrototype[opt].context == window.CONTEXT;
50}
51
52function save(e) {
53 // Validation checks before saving
54 if (isOptionShown('profileindicatoralt_months')) {
55 var months = document.getElementById('profileindicatoralt_months');
56 if (!months.checkValidity()) {
57 console.warn(months.validationMessage);
58 return;
59 }
60 }
61
62 e.preventDefault();
63
64 chrome.storage.sync.get(null, function(items) {
65 var options = cleanUpOptions(items, true);
66
67 // Save
68 Object.keys(options).forEach(function(opt) {
69 if (!isOptionShown(opt)) return;
70 options[opt] = getOptionValue(opt);
71 });
72
73 chrome.storage.sync.set(options, function() {
74 window.close();
75
76 // In browsers like Firefox window.close is not supported:
77 if (savedSuccessfullyTimeout !== null)
78 window.clearTimeout(savedSuccessfullyTimeout);
79
80 document.getElementById('save-indicator').innerText =
81 '✓ ' + chrome.i18n.getMessage('options_saved');
82 savedSuccessfullyTimeout = window.setTimeout(_ => {
83 document.getElementById('save-indicator').innerText = '';
84 }, 3699);
85 });
86 });
87}
88
89function i18n() {
90 document.querySelectorAll('[data-i18n]')
91 .forEach(
92 el => el.innerHTML = chrome.i18n.getMessage(
93 'options_' + el.getAttribute('data-i18n')));
94}
95
96window.addEventListener('load', function() {
97 i18n();
98
Adrià Vilanova Martíneze32adc42021-08-30 17:16:49 +020099 if (window.CONTEXT == 'options') {
100 if (!isReleaseVersion()) {
101 var experimentsLink = document.querySelector('.experiments-link');
102 experimentsLink.removeAttribute('hidden');
103 experimentsLink.addEventListener('click', _ => chrome.tabs.create({
104 url: chrome.runtime.getURL('options/experiments.html'),
105 }));
106 }
107
108 var featuresLink = document.querySelector('.features-link');
109 featuresLink.href = getDocURL('features.md');
110
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +0200111 var profileIndicatorLink =
112 document.getElementById('profileIndicatorMoreInfo');
Adrià Vilanova Martíneze32adc42021-08-30 17:16:49 +0200113 profileIndicatorLink.href = getDocURL('op_indicator.md');
avm999637309b062021-04-22 12:41:08 +0200114 }
115
avm99963bf8eece2021-04-22 00:27:03 +0200116 chrome.storage.sync.get(null, function(items) {
117 items = cleanUpOptions(items, false);
118
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +0200119 // If some features have been force disabled, communicate this to the user.
120 if (items?._forceDisabledFeatures &&
121 items._forceDisabledFeatures.length > 0) {
122 if (window.CONTEXT == 'options') {
123 document.getElementById('kill-switch-warning')
124 .removeAttribute('hidden');
125 }
126
127 // TODO(avm99963): show a message above each option that has been force
128 // disabled
129 }
130
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200131 for (var entry of Object.entries(optionsPrototype)) {
132 var opt = entry[0];
133 var optMeta = entry[1];
134
avm99963bf8eece2021-04-22 00:27:03 +0200135 if (!isOptionShown(opt)) continue;
136
137 if (specialOptions.includes(opt)) {
138 switch (opt) {
139 case 'profileindicatoralt_months':
140 var input = document.createElement('input');
141 input.type = 'number';
142 input.id = 'profileindicatoralt_months';
143 input.max = '12';
144 input.min = '1';
145 input.value = items[opt];
146 input.required = true;
147 document.getElementById('profileindicatoralt_months--container')
148 .appendChild(input);
149 break;
150
151 case 'ccdarktheme_mode':
152 var select = document.createElement('select');
153 select.id = 'ccdarktheme_mode';
154
155 const modes = ['switch', 'system'];
156 for (const mode of modes) {
157 var modeOption = document.createElement('option');
158 modeOption.value = mode;
159 modeOption.textContent =
160 chrome.i18n.getMessage('options_ccdarktheme_mode_' + mode);
161 if (items.ccdarktheme_mode == mode) modeOption.selected = true;
162 select.appendChild(modeOption);
163 }
164
165 document.getElementById('ccdarktheme_mode--container')
166 .appendChild(select);
167 break;
168
169 // Firefox doesn't support drag and dropping bookmarks into the text
170 // editor while preserving the bookmark title.
171 case 'ccdragndropfix':
172 var showOption = !isFirefox();
173 if (showOption) {
174 document.getElementById('dragndrop-wrapper')
175 .removeAttribute('hidden');
176
177 if (items[opt] === true)
178 document.getElementById(opt).checked = true;
179 }
180 break;
181
182 default:
183 console.warn('Unrecognized option: ' + opt);
184 break;
185 }
186 continue;
187 }
188
189 if (items[opt] === true) document.getElementById(opt).checked = true;
190 }
191
192 exclusiveOptions.forEach(exclusive => {
193 if (!isOptionShown(exclusive[0]) || !isOptionShown(exclusive[1])) return;
194
195 exclusive.forEach(
196 el => document.getElementById(el).addEventListener('change', e => {
197 if (document.getElementById(exclusive[0]).checked &&
198 document.getElementById(exclusive[1]).checked) {
199 document
200 .getElementById(
201 exclusive[(e.currentTarget.id == exclusive[0] ? 1 : 0)])
202 .checked = false;
203 }
204 }));
205 });
206 document.querySelector('#save').addEventListener('click', save);
207 });
208});