├── images
├── userjs-tool.png
├── toggle-readonly-textarea-box.png
└── example-append-overrides-onto-template-to-form-userjs.png
├── .gitignore
├── LICENSE
├── userjs-tool-themes.css
├── README.md
├── ChangeLog
└── userjs-tool-aboutconfig-functions.js
/images/userjs-tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icpantsparti/firefox-user.js-tool/HEAD/images/userjs-tool.png
--------------------------------------------------------------------------------
/images/toggle-readonly-textarea-box.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icpantsparti/firefox-user.js-tool/HEAD/images/toggle-readonly-textarea-box.png
--------------------------------------------------------------------------------
/images/example-append-overrides-onto-template-to-form-userjs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icpantsparti/firefox-user.js-tool/HEAD/images/example-append-overrides-onto-template-to-form-userjs.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled files
2 | *.class
3 | *.com
4 | *.dll
5 | *.exe
6 | *.o
7 | *.so
8 |
9 | # BlueJ files
10 | *.ctxt
11 |
12 | # Mobile Tools for Java (J2ME)
13 | .mtj.tmp/
14 |
15 | # Package Files
16 | *.jar
17 | *.war
18 | *.nar
19 | *.ear
20 | *.zip
21 | *.tar.gz
22 | *.rar
23 | *.7z
24 | *.dmg
25 | *.gz
26 | *.iso
27 | *.tar
28 | *.zip
29 |
30 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
31 | hs_err_pid*
32 |
33 | # Logs and databases
34 | *.log
35 | **/*.log*
36 | *.sql
37 | *.sqlite
38 |
39 | # OS generated files
40 | .DS_Store
41 | .DS_Store?
42 | ._*
43 | .Spotlight-V100
44 | .Trashes
45 | ehthumbs.db
46 | Thumbs.db
47 |
48 | # https://gist.github.com/octocat/9257657
49 | *~
50 | **/*~
51 | *#
52 | *.bak
53 | *.swp
54 | *.swo
55 | *.orig
56 | desktop.ini
57 |
58 | # IDE (eclipse / intellij) files
59 | .classpath
60 | .project
61 | .settings
62 | #.idea
63 | /.idea/workspace.xml
64 | /.idea/tasks.xml
65 | .metadata
66 | *.iml
67 | *.ipr
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 icpantsparti
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/userjs-tool-themes.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | name: userjs-tool-themes.css
4 | URL: https://github.com/icpantsparti/firefox-user.js-tool
5 | license: MIT: https://raw.githubusercontent.com/icpantsparti/firefox-user.js-tool/master/LICENSE
6 |
7 | This is an optional file for use with userjs-tool.html
8 |
9 | Use this file to override the default theme with your own colors or to
10 | add your own custom themes (copy and replace _default with _themename).
11 |
12 | The default theme is used when userjs-tool.html opens, or you can specify
13 | another theme using URL variables, such as: userjs-tool.html?theme=themename
14 |
15 | Color codes: https://www.w3schools.com/colors/colors_groups.asp
16 |
17 | */
18 |
19 | /*----------------------------------------------------------------------------*/
20 |
21 | /* default theme */
22 | .body_default, .view_area_default, .panels_default
23 | { background-color: #262626; /*(black)*/
24 | color: #b3b3b3; /*(gray)*/ }
25 | .controls_default { background-color: #555555; /*DimGray*/
26 | color: #C0C0C0; /*Silver*/ }
27 | .controls_default:focus { outline: 2px auto #FF0000; /*Red*/ }
28 | .controls_default:hover { background-color: #DAA520; /*GoldenRod*/
29 | color: #000000; /*Black*/ }
30 | .borders_default { box-shadow: 3px 3px 4px #FFFFFF; /*White*/
31 | border: 1px solid #A9A9A9; /*DarkGray*/
32 | border-width: 1px 1px 0px 1px; }
33 | .view_area_default .pref { color: #FFFFFF; /*White*/ }
34 | .body_default a { color: #ffbf80; /*(brown)*/ }
35 | .view_area_default .false { color: #FF6347; /*Tomato*/ }
36 | .view_area_default .true { color: #00FF00; /*Lime*/ }
37 | .view_area_default .integer { color: #FFFF00; /*Yellow*/ }
38 | .view_area_default .string { color: #DDA0DD; /*Plum*/ }
39 | .view_area_default .http { color: #99ccff; /*(blue)*/ }
40 | .view_area_default .warn { background-color: #FF3333; /*(Red)*/
41 | color: #FFFFFF; /*White*/ }
42 | .view_area_default .hid { color: #C6F3C6; /*(Green)*/ }
43 | .view_area_default .ref { color: #98E498; /*(Green)*/ }
44 |
45 | /*----------------------------------------------------------------------------*/
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #### userjs-tool.html
2 |
3 | Interactive view, compare, and more for Firefox user.js (eg arkenfox/user.js) + about:config functions
4 |
5 | [Open userjs-tool.html on-line (github.io)](https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html)
6 |
7 | [View the current arkenfox user.js* in a table (github.io)](https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html?at)
8 |
9 | [Functions to get more out of about:config (eg: find, filter, list, save to file, etc)](https://raw.githubusercontent.com/icpantsparti/firefox-user.js-tool/master/userjs-tool-aboutconfig-functions.js)
10 |
11 | > > > \*Note: the excellent `arkenfox user.js` is by other developers at:
12 | > > > [arkenfox user.js home](https://github.com/arkenfox/user.js) / [arkenfox user.js issues](https://github.com/arkenfox/user.js/issues?q=sort%3Aupdated-desc) / [arkenfox user.js wiki](https://github.com/arkenfox/user.js/wiki)
13 |
14 | ----
15 |
16 | Introduction
17 |
18 | Display a Mozilla Firefox user.js settings file contents in your Firefox browser, with:
19 | * highlighting, links, themes*, re-size, wrap, about:config links/regex/groups
20 | * expanding sections, and index to go to sections (with compatible user.js projects)
21 | * compare preferences in two user.js, in a table format with order/layout options and bold cell border around differences
22 | * actions including: user-overrides.js* append* (with comment-out*), point and click overrides collector, skeleton, prefs.js cleaner*, group by values
23 | * load/save, drag/drop, or copy/paste user.js files (can load from some on-line URLs too)
24 | * functions for find (filter/list)/reset/set on about:config Web Console (Firefox/forks/Thunderbird/SeaMonkey)
25 | * single .html file (HTML/CSS/JavaScript) with no external dependency
26 | * open [userjs-tool.html on-line](https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html) or save for off-line use
27 |
28 | (*arkenfox/user.js inspired. Please visit [arkenfox/user.js](https://github.com/arkenfox/user.js) and read their info on [arkenfox/user.js/wiki](https://github.com/arkenfox/user.js/wiki). They also have nice scripts for append/clean/troubleshoot.)
29 |
30 | This started as an over the top experiment for learning some HTML/CSS/JavaScript (first released 2019.01.02, compare added 2020.02.22). This is a viewer/tool, and not an editor/installer.
31 |
32 | Disclaimer: Use with care at your own risk, and verify any results
33 |
34 | ----
35 |
36 |
37 |
38 | (Optional) How to save and open userjs-tool.html off-line
39 |
40 | * Open [the raw text/html file](https://raw.githubusercontent.com/icpantsparti/firefox-user.js-tool/master/userjs-tool.html) in a browser tab
41 | * Right click within that page and "Save Page As..."
42 | * Open the saved `userjs-tool.html` file with your Firefox browser
43 | (you can drag and drop it from your Downloads folder into a new tab)
44 | * Bookmark it for easy access
45 | * Remember to check here for updates
46 |
47 | ----
48 |
49 |
50 |
51 | Other Info
52 |
53 | * (Optional) The `userjs-tool-themes.css` file can be used with `userjs-tool.html` to add custom themes/colors (or override the default)
54 |
55 | * The `userjs-tool-aboutconfig-functions.js` file is also embeded in `userjs-tool.html` (view with the [a:c Functions] button).
56 |
57 | * You can do these (and more) from the interface, or by using URL parameters:
58 |
59 | * [View the current arkenfox user.js (github.io)](https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html?av)
60 |
61 | * [View the current arkenfox user.js in a table (github.io)](https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html?at)
62 |
63 | * Load and view a user.js URL: [https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html?action=view1&load1=%68ttps://raw.githubusercontent.com/arkenfox/user.js/master/user.js](https://icpantsparti.github.io/firefox-user.js-tool/userjs-tool.html?action=view1&load1=%68ttps://raw.githubusercontent.com/arkenfox/user.js/master/user.js)
64 |
65 | ----
66 |
67 |
68 |
69 | Preview
70 |
71 |
72 |
--------------------------------------------------------------------------------
/ChangeLog:
--------------------------------------------------------------------------------
1 | version 2021.03.11
2 |
3 | updated userjs-tool-aboutconfig-functions.js and minor changes
4 |
5 | * updated [a:c Functions] userjs-tool-aboutconfig-functions.js
6 | + ujtFindPref options: asdefault, nodefault, fileout
7 | optionally save results to desktop file (fileout: true)
8 | + ujtFindPref style 0 and 1: now updates the about:config display
9 | insert result into the about:config search box and filter
10 | reduce text size and spacing to see more
11 | + use Services.prefs.getComplexValue to look up "chrome:..." prefs
12 | + ujtFindPref style: 5=user_pref@default
13 | + ujtFindPref style 2 and 5: show pref default values
14 | (note: policies.json/etc can alter defaults)
15 |
16 | * userjsTableView:
17 | detected tags (those not hardcoded) now show * indicator in Info column
18 | under [Filter] button:
19 | detected tags now show above the individual SETUP and FF tags (arkenfox)
20 | grouped SETUP... and FF... tags (arkenfox) now hint "(listed below)"
21 | tag sort made case insensitive
22 | make arkenfox "_user.js.parrot" pref show first value
23 |
24 | + userjsTableView/userjsTableViewTagFilter:
25 | make a first link in [Groups] to reflect whats shown in the filtered table
26 |
27 | * userjsViewer/userjsCompare/userjsTableView:
28 | remove first [Groups] link if empty
29 |
30 | * userjsCompare/userjsCompareLauncher/handleActionURLparameter:
31 | remove space from all layout variable values re below
32 | improve action=compare URL params (eg action=compare:1:4:az:2column)
33 |
34 | * loadLocalFile: use readAsText instead of readAsBinaryString
35 |
36 | * links_panel:
37 | + add links for arkenfox wiki and issues
38 | * tidy up auto-loading links
39 | + add "Auto-load about:config Groups" (about:config search patterns)
40 |
41 | * rename "Get started info" to "Hints", tidy up and add more hints
42 |
43 | + two action buttons, shortcuts for: [View arkenfox] + [Load arkenfox]
44 |
45 |
46 |
47 |
48 | version 2020.09.15 (alpha/experimental)
49 | * updated hyperlinks and references
50 | re "https://github.com/ghacksuserjs/ghacks-user.js"
51 | has moved to "https://github.com/arkenfox/user.js"
52 |
53 |
54 |
55 |
56 | version 2020.03.21 (alpha/experimental)
57 | * added a [Tools>Developer Tools>Error Console (Ctrl+Shift+J)
17 | // Thunderbird/Other: Tools>Developer Tools>Content Frame Debugger>Tabs>Debug>Console
18 | // Or load saved file in the console with:
19 | // javascript:(()=>{with(document){let s=createElement('script');s.src='file:///YOURPATH/userjs-tool-aboutconfig-functions.js';head.appendChild(s)}})();
20 | //
21 | // -------
22 | // Summary
23 | // -------
24 | // Function: ujtFindPref( { style:0, name:/.*/i, value:/.*/i, type:/[bis]/, locked:/[yn]/, modified:/[yn]/, asdefault:/[yn]/, nodefault:/[yn]/, fileout:false } );
25 | // Function: ujtResetPref(pref);
26 | // Function: ujtSetPref(pref, value);
27 | // Alias : user_pref = ujtSetPref; // see notes
28 | //
29 | // --------------------
30 | // ujtFindPref Examples
31 | // --------------------
32 | // ujtFindPref(); // show some usage info
33 | // ujtFindPref(2); // list all + save to file (spreadsheet style)
34 | // ujtFindPref({style:3,fileout:true}); // list all + save to file (user_pref+comments style)
35 | // ujtFindPref({modified:/y/}); // show modified
36 | // ujtFindPref({modified:/y/,asdefault:/y/}); // show modified=default
37 | // ujtFindPref({nodefault:/y/}); // show Trash Can Prefs eg hidden/invalid
38 | // ujtFindPref({locked:/y/}); // show locked
39 | // ujtFindPref({value:/google/i}); // find value
40 | // ujtFindPref({modified:/y/,type:/b/,value:/^false$/i}); // show modified boolean false
41 | // ujtFindPref({style:3,name:/activity-stream/i}); // part name
42 | // ujtFindPref({style:3,name:/^extensions\.pocket\.enabled$/i}); // whole name
43 | // ujtFindPref({style:3,name:/^(whole|start.*|.*middle.*|.*end)$/i}); // multi name
44 | //
45 | // -------------
46 | // General Notes
47 | // -------------
48 | // * on console right click results "Copy object" / left click expand/contract
49 | // (if results do not copy to clipboard try "Export visible messages to File",
50 | // or ujtFindPref has fileout:true to save results to a file)
51 | // * clear console/command history: clear(); clearHistory();
52 | // * Thunderbird (console) open about:config: window.openDialog("about:config");
53 | // * if using remote debugging to access another device (eg Android):
54 | // PC: use 'about:debugging' (older Firefox was WebIDE/Scratchpad)
55 | // Target: 'about:config' open, "Remote debugging" enabled in Firefox settings
56 | // "USB debugging" enabled in Android Developer settings
57 | // re: https://github.com/arkenfox/user.js/wiki/1.6-Firefox-Android
58 | // also re arkenfox/user.js/wiki: unblock about:config in newer versions (FF71+?):
59 | // user_pref("general.aboutConfig.enable", true);
60 | // * functions might also work through Browser/Error Console (Ctrl+Shift+J)
61 | // * set 'user_pref' alias if you want to paste 'user.js' code to run a function
62 | // eg enter 'user_pref = ujtSetPref;' or 'user_pref = ujtResetPref;'
63 | // * distribution/policies.json can change preference default values (about:policies)
64 | // * hidden preferences only show if they have been created/modified (same as about:config)
65 | // examples: https://searchfox.org/mozilla-central/search?q=(extensions\.getAddons\.showPane|privacy\.resistFingerprinting\.letterboxing|ui\.prefersReducedMotion)&path=&case=false®exp=true
66 | //
67 | // -----------------
68 | // ujtFindPref Notes
69 | // -----------------
70 | // * ujtFindPref( { style:0, name:/.*/i, value:/.*/i, type:/[bis]/, locked:/[yn]/, modified:/[yn]/, asdefault:/[yn]/, nodefault:/[yn]/, fileout:false } );
71 | // * style:
72 | // 0=regex (default) paste result into the about:config search box
73 | // 1=bookmark 'about:config?filter=' (FF71+ copy, click, paste in search)
74 | // 2=list+default paste into a spreadsheet for sort/filter/search
75 | // 3=user_pref+comments user_pref("pref", value); // locked // modified // nodefault
76 | // 4=user_pref user_pref("pref", value);
77 | // 5=user_pref@default user_pref("pref", valueDefault);
78 | // * type: b=boolean i=integer s=string
79 | // * locked/modified/asdefault/nodefault: y=yes n=no
80 | // * modified:/y/ - user set preferences (eg user.js/about:config/etc)
81 | // {modified:/y/,asdefault:/y/} - finds those user set to same as default
82 | // * asdefault:/y/ - if preference value is the same as the default value
83 | // * nodefault:/y/ - prefs with a trash can icon on about:config eg hidden/invalid
84 | // * fileout:true - save results to desktop userjs-tool-aboutconfig-YYYYMMDD-HHMMSS-SSS.txt
85 | // * return and newline characters in preference values are replaced as \r \n
86 | // * now using Services.prefs.getComplexValue to look up the value of
87 | // preferences which are initially read as "chrome:..."
88 | //
89 | // -----------------------------
90 | // ujtSetPref/ujtResetPref Notes
91 | // -----------------------------
92 | // * these were mainly intended for when injecting preferences to Android
93 | // * on desktop you would usually use user.js/profiles for preference control
94 | // (although ujtResetPref could be useful for batch clearing prefs)
95 | // * incorrect usage risks messing up your Firefox settings (if you are using
96 | // this on desktop: backup your Firefox profile, or 'prefs.js' at least,
97 | // and remember that user.js can override changes on Firefox restart)
98 | // * ujtSetPref outputs 'creating' to the console when the preference did
99 | // not already exist (these are either hidden preferences, or invalid)
100 | //
101 | // -------------------------------------------------
102 | // Acknowledgments (this is based on info/code from)
103 | // -------------------------------------------------
104 | // https://github.com/arkenfox/user.js
105 | // https://github.com/arkenfox/user.js/wiki/1.6-Firefox-Android
106 | // https://github.com/arkenfox/user.js/tree/master/scratchpad-scripts
107 | // https://github.com/arkenfox/user.js/blob/master/scratchpad-scripts/arkenfox-clear-removed.js
108 | // https://github.com/arkenfox/user.js/blob/master/scratchpad-scripts/troubleshooter.js
109 | // https://stackoverflow.com/questions/3796084/about-config-preferences-and-js
110 | // https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Services.jsm
111 | // http://www.openjs.com/articles/optional_function_arguments.php
112 | // https://dxr.mozilla.org/mozilla-central/source/modules/libpref/nsIPrefBranch.idl#31
113 | // https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Code_snippets/File_I_O
114 | // https://github.com/Theemim/GeckoPrefsExporter (file out method)
115 |
116 | if (typeof(Services) == "undefined") {
117 | console.log("// requires Services (eg about:config as active tab)");
118 | }
119 |
120 | // older versions of Firefox/forks/Thunderbird/SeaMonkey use ...CharPref
121 | try {
122 | var ujtUseCharPref = !(typeof(Services.prefs.getStringPref) == "function");
123 | }
124 | catch(e) { }
125 |
126 | var ujtFindPref = function(options) {
127 | var result = "";
128 | if (typeof options == "undefined") {
129 | options = { 'fileout': false };
130 | // if no options specified show some usage info
131 | result = "// usage:\n"
132 | + '// ujtFindPref( { style:0, name:/.*/i, value:/.*/i, type:/[bis]/, locked:/[yn]/, modified:/[yn]/, asdefault:/[yn]/, nodefault:/[yn]/, fileout:false } );\n'
133 | + '// style: 0=regex 1=bookmark 2=list+default 3=user_pref+comments 4=user_pref 5=user_pref@default\n'
134 | + '// b=boolean i=integer s=string y=yes n=no\n'
135 | + '// eg ujtFindPref(2); ujtFindPref({style:3,fileout:true}); ujtFindPref({modified:/y/}); ujtFindPref({nodefault:/y/});\n';
136 | }
137 | else {
138 | // function to get the default value of a preference
139 | var ujtGetPrefDefault = function(prefName) {
140 | var defaultValue;
141 | try {
142 | switch (Services.prefs.getDefaultBranch("").getPrefType(prefName)) {
143 | case 128:
144 | defaultValue = Services.prefs.getDefaultBranch("").getBoolPref(prefName).toString();
145 | break;
146 | case 64:
147 | defaultValue = Services.prefs.getDefaultBranch("").getIntPref(prefName).toString();
148 | break;
149 | case 32:
150 | defaultValue = ujtUseCharPref ? Services.prefs.getDefaultBranch("").getCharPref(prefName)
151 | : Services.prefs.getDefaultBranch("").getStringPref(prefName);
152 | break;
153 | default:
154 | return null;
155 | }
156 | }
157 | catch(e) {
158 | return null;
159 | }
160 | return defaultValue;
161 | }
162 | // prepare for options being a single regex/string/number
163 | var noArgsMatched = true, nameOnly = options, styleOnly = 3, fileOutEx = false;
164 | if (typeof options == "string") {
165 | nameOnly = new RegExp(options, "i");
166 | fileOutEx = true;
167 | options = {};
168 | }
169 | else if (typeof options == "number") {
170 | nameOnly = new RegExp(".*", "i");
171 | styleOnly = options;
172 | fileOutEx = true;
173 | options = {};
174 | }
175 | // enforce defaults for unspecified options
176 | var defaultArgs = { 'style': 0, 'name': /.*/, 'value': /.*/, 'type': /.*/, 'locked': /.*/,
177 | 'modified': /.*/, 'asdefault': /.*/, 'nodefault': /.*/, 'fileout': false }
178 | for(var i in defaultArgs) {
179 | if (typeof options[i] == "undefined") {
180 | options[i] = defaultArgs[i];
181 | }
182 | else if (typeof options[i] == "string") {
183 | options[i] = new RegExp(options[i], "i");
184 | noArgsMatched = false;
185 | }
186 | else {
187 | noArgsMatched = false;
188 | }
189 | }
190 | // when options was a single regex/string/number
191 | if (noArgsMatched) {
192 | options["name"] = nameOnly;
193 | options["style"] = styleOnly;
194 | options["fileout"] = fileOutEx;
195 | }
196 | // begin forming result
197 | switch (options["style"]) {
198 | case 5:
199 | result = "// default values\n";
200 | break;
201 | case 4:
202 | case 3:
203 | break;
204 | case 2:
205 | result = "[PreferenceName]\t[Type]\t[Value]\t[Locked]\t[Modified]\t[SameAsDefault]\t[DefaultValue]\t[NoDefault]\n";
206 | break;
207 | case 1:
208 | result = 'about:config?filter=';
209 | default:
210 | result += '/^\\*$|^(';
211 | }
212 | // loop through all prefs
213 | var type, value, locked, modified, asDefault, noDefault, valueDefault;
214 | // same prefs: Services.prefs.getDefaultBranch("").getChildList("").sort()
215 | // Services.prefs.getBranch("").getChildList("").sort()
216 | // Services.prefs.getChildList("").sort()
217 | for (const prefName of Services.prefs.getChildList("").sort()) {
218 | // get pref info
219 | modified = (Services.prefs.prefHasUserValue(prefName) ? 'y' : 'n');
220 | locked = (Services.prefs.prefIsLocked(prefName) ? 'y' : 'n');
221 | switch (Services.prefs.getPrefType(prefName)) {
222 | case 128:
223 | type = "b";
224 | value = Services.prefs.getBoolPref(prefName).toString();
225 | valueDefault = ujtGetPrefDefault(prefName);
226 | break;
227 | case 64:
228 | type = "i";
229 | value = Services.prefs.getIntPref(prefName).toString();
230 | valueDefault = ujtGetPrefDefault(prefName);
231 | break;
232 | case 32:
233 | type = "s";
234 | value = ujtUseCharPref ? Services.prefs.getCharPref(prefName)
235 | : Services.prefs.getStringPref(prefName);
236 | valueDefault = ujtGetPrefDefault(prefName);
237 | // get the actual value when "chrome:..."
238 | try {
239 | if (modified == 'n' && /^chrome:\/\/.+\/locale\/.+\.properties/.test(value)) {
240 | value = Services.prefs.getComplexValue(prefName, Ci.nsIPrefLocalizedString).data;
241 | }
242 | }
243 | catch(e) { value = ""; }
244 | try {
245 | if (/^chrome:\/\/.+\/locale\/.+\.properties/.test(valueDefault)) {
246 | valueDefault = Services.prefs.getComplexValue(prefName, Ci.nsIPrefLocalizedString).data;
247 | }
248 | }
249 | catch(e) { valueDefault = ""; }
250 | break;
251 | default:
252 | value = null; type = null; locked = null; modified = null;
253 | asDefault = null; noDefault = null; valueDefault = null;
254 | }
255 | if (valueDefault === null) { noDefault = "y"; } else { noDefault = "n"; };
256 | if (value === valueDefault) { asDefault = "y"; } else { asDefault = "n"; };
257 | // add to result if matches options
258 | if ( (options["name"].test(prefName))
259 | && (options["value"].test(value))
260 | && (options["type"].test(type))
261 | && (options["locked"].test(locked))
262 | && (options["modified"].test(modified))
263 | && (options["asdefault"].test(asDefault))
264 | && (options["nodefault"].test(noDefault))
265 | )
266 | {
267 | // quote/escape string
268 | if ((type == "s") && (options["style"] == 5
269 | || options["style"] == 4 || options["style"] == 3))
270 | {
271 | value = '"' + value.replace(/(["\\])/g, '\\$1') + '"';
272 | if (valueDefault !== null) {
273 | valueDefault = '"' + valueDefault.replace(/(["\\])/g, '\\$1') + '"'
274 | }
275 | }
276 | if (valueDefault === null) { valueDefault = "null" }
277 | value = value.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
278 | valueDefault = valueDefault.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
279 | switch (options["style"]) {
280 | case 5: // 5=user_pref@default
281 | result += 'user_pref("' + prefName + '", ' + valueDefault + ");\n";
282 | break;
283 | case 4: // 4=user_pref
284 | result += 'user_pref("' + prefName + '", ' + value + ");\n";
285 | break;
286 | case 3: // 3=user_pref+comments
287 | result += 'user_pref("' + prefName + '", ' + value + ");"
288 | + locked.replace(/n/g, "").replace(/y/g, " // locked")
289 | + modified.replace(/n/g, "").replace(/y/g, " // modified");
290 | if (asDefault == "y" && modified == "y") { result += "=default" }
291 | result += noDefault.replace(/n/g, "").replace(/y/g, " // nodefault") + "\n";
292 | break;
293 | case 2: // 2=list+default
294 | result += prefName + "\t" + type + "\t" + value + "\t" + locked + "\t"
295 | + modified + "\t" + asDefault + "\t" + valueDefault + "\t" + noDefault + "\n";
296 | break;
297 | default: // 0=regex / 1=bookmark
298 | result += prefName.replace(/([*.+])/g, "\\$1") + "|";
299 | }
300 | }
301 | } // (end of loop through all prefs)
302 | // finish forming result
303 | switch (options["style"]) {
304 | case 5:
305 | case 4:
306 | case 3:
307 | case 2: break;
308 | default:
309 | result = result.replace(/\|$/, '') + ')(;|$)|^$/i';
310 | // update about:config display (ignore errors for thunderbird/etc)
311 | try {
312 | // put result into the about:config search box and filter
313 | document.getElementById("about-config-search").value = result;
314 | filterPrefs({ shortString: true });
315 | // temporarily change about:config to compact size
316 | document.body.style.fontSize = '0.98em';
317 | for (var s of [ '#prefs', '#prefs *', '#prefs > tr', '#prefs > tr > td',
318 | '#prefs > tr > th', '#prefs button', '.add' ])
319 | {
320 | var o = document.querySelectorAll(s);
321 | for (var i = 0, j = o.length; i < j; i++) {
322 | if (s == '.add') {
323 | // hide the add (last line only showing the search criteria)
324 | o[i].style.display = 'none';
325 | }
326 | else {
327 | o[i].style.minHeight = "1.2em";
328 | o[i].style.height = "unset";
329 | }
330 | }
331 | }
332 | }
333 | catch(e) { }
334 | }
335 | }
336 | console.log(result);
337 | if (options["fileout"]) {
338 | // https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Code_snippets/File_I_O
339 | // https://github.com/Theemim/GeckoPrefsExporter
340 | try {
341 | // "CurWorkD" might be readonly program folder so use "Desk"
342 | var file = Services.dirsvc.get("Desk", Components.interfaces.nsIFile);
343 | var d = new Date();
344 | file.append("userjs-tool-aboutconfig-" + d.getFullYear()
345 | + ((d.getMonth()+1) < 10 ? "0" : "") + (d.getMonth()+1)
346 | + (d.getDate() < 10 ? "0" : "") + d.getDate()
347 | + "-" + (d.getHours() < 10 ? "0" : "") + d.getHours()
348 | + (d.getMinutes() < 10 ? "0" : "") + d.getMinutes()
349 | + (d.getSeconds() < 10 ? "0" : "") + d.getSeconds()
350 | + "-" + d.getMilliseconds() + ".txt"
351 | );
352 | console.log('// saving result to file: ' + file.path);
353 | var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
354 | .createInstance(Components.interfaces.nsIFileOutputStream);
355 | foStream.init(file, 0x02 | 0x08 | 0x20, parseInt("0666", 8), 0);
356 | var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
357 | .createInstance(Components.interfaces.nsIConverterOutputStream);
358 | converter.init(foStream, "UTF-8", 0, 0);
359 | converter.writeString(result);
360 | converter.close();
361 | }
362 | catch(e) {
363 | console.log("// (ujtFindPref) file save error:\n"+e+"\n");
364 | }
365 | }
366 | }
367 |
368 | var ujtSetPref = function(pref, value) {
369 | try {
370 | if (Services.prefs.getPrefType(pref) == 0) {
371 | console.log("// (ujtSetPref) creating: " + pref + "\n");
372 | }
373 | switch (typeof value) {
374 | case "boolean":
375 | Services.prefs.setBoolPref(pref, value);
376 | break;
377 | case "number":
378 | Services.prefs.setIntPref(pref, value);
379 | break;
380 | case "string":
381 | if (ujtUseCharPref) { Services.prefs.setCharPref(pref, value) }
382 | else { Services.prefs.setStringPref(pref, value) }
383 | break;
384 | }
385 | }
386 | catch(e) {
387 | console.log("// (ujtSetPref) error: " + e + " pref: "
388 | + pref + " value: " + value + "\n");
389 | }
390 | }
391 |
392 | var ujtResetPref = function(pref) {
393 | try {
394 | if (Services.prefs.prefHasUserValue(pref)) {
395 | Services.prefs.clearUserPref(pref);
396 | if (Services.prefs.prefHasUserValue(pref)) {
397 | console.log("// (ujtResetPref) failed: " + pref + "\n");
398 | }
399 | }
400 | }
401 | catch(e) {
402 | console.log("// (ujtResetPref) error: " + e + " pref: " + pref + "\n");
403 | }
404 | }
405 |
406 | // set user_pref alias to function required (then you can paste/run user.js)
407 | var user_pref = ujtSetPref;
408 | // var user_pref = ujtResetPref;
409 |
410 | /* end of userjs-tool-aboutconfig-functions.js */
411 |
--------------------------------------------------------------------------------