User:Hippietrail/custom-alpha.js

Note – after saving, you may have to bypass your browser’s cache to see the changes.

  • Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
  • Konqueror and Chrome: click Reload or press F5;
  • Opera: clear the cache in Tools → Preferences;
  • Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.

/* [[WT:PREFS]]-specific cookie handling 
 *
 * Warning: The numbers associated with each preference must not be changed.
 * (The cookie that stores preferences is written as a sequence of preference
 * values without the corresponding preference names.) */

/*
 * "checkbox" prefs can be used with getCookie() or wiktGetPrefCookie()
 * "externcheckbox" prefs can only be used with wiktGetPrefCookie()
 * wiktGetPrefCookie() is defined here in custom.js
 * so any prefs which need to work without custom.js enabled must use "externcheckbox"
 */

/* TODO OK and Cancel checkboxs. don't write the prefs to the actual cookie
 * TODO   until OK is clicked
 * TODO clearly and discoverably link between these prefs and the standard
 * TODO   MediaWiki prefs
 * TODO clearly indicate the differences between "cookie prefs" and real
 * TODO   (ie MediaWiki) prefs
 * TODO wrap everything in a class with as few globals as possible
 * TODO use cirwin's Preferences object from editor.js
 * TODO allow external and subprefs to have their own subprefs
 */

// TODO should not be global
var prefs = {
  // MASTER SWITCH
  WiktionaryUseJSPreferences: {
    num: 1,
    text: 'Use the preferences set on this page'
  },

  WiktionaryPreferencesHideSister: {
    num: 2,
    text: 'Hide the boxes that link to Wikipedia.',
    css: [ {
      selector: '#bodyContent .sister-project',
      declarations: 'display: none;'
    } ]
  },
  WiktionaryPreferencesSmallRC: {
    num: 3,
    text: 'Make the second half of the heading of Special:RecentChanges smaller',
    css: [
      { selector: '#bodyContent .minifont', declarations: 'font-size: 75%;' }
    ]
  },
  WiktionaryPreferencesHideTransitivity: {
    num: 4,
    text: 'Hide the “transitive” and “intransitive” qualifiers in definitions. [Can cause context tags to look odd]',
    css: [
      { selector: '#transitivity', declarations: 'display:none' }
    ]
  },
  WiktionaryPreferencesHideRankings: {
    num: 5,
    text: 'Hide the boxes containing word frequency rankings.',
    css: [
      { selector: '#rank', declarations: 'display: none' }
    ]
  },
  WiktionaryPreferencesHideIBParens: {
    num: 6,
    css: [
      { selector: '#bodyContent .ib-brac', declarations: 'display:none' }
    ]
  },
  WiktionaryPreferencesHideLinesBetweenLanguages: {
    num: 7,
    text: 'Hide the horizontal separator between each language section.',
    css: [
      { selector: '.ns-0 #bodyContent hr', declarations: 'visibility: hidden' }
    ]
  },
  WiktionaryPreferencesHideTranslations: {
    num: 8,
    text: 'Hide the translation sections entirely. [Instead of having them shown collapsed]',
    css: [
      { selector: '#bodyContent .translations', declarations: 'display:none' }
    ]
  },
  WiktionaryPreferencesBoxedInflections: {
    num: 9,
    text: 'Display the inflection of some words in boxes instead of a line of text. [May cause layout glitches]',
    css: [
      { selector: '#bodyContent .infl-inline', declarations: 'display:none' },
      { selector: '#bodyContent .infl-table', declarations: 'display:inline' }
    ]
  },
  WiktionaryPreferencesIndentSeeAlso: {
    num: 10,
    text: 'Indent the “See also” lines more than usual.',
    css: [ {
      selector: '#bodyContent .disambig-see-also, #bodyContent .disambig-see-also-2',
      declarations: 'text-indent: 4em'
    } ]
  },
  WiktionaryPreferencesHideSiteNotice: {
    num: 11,
    text: 'Hide the display of site-wide notices at the top of the screen.',
    css: [
      { selector: '#siteNotice', declarations: 'display: none;' }
    ]
  },
  WiktionaryPreferencesCiteTab: {
    num: 12
  },
  WiktionaryPreferencesSpellCheck: {
    num: 13,
    text: 'Add a “Check Spelling” checkbox to edit pages — Experimental — only works for 10KB or less – The spellcheck in Firefox 1.5 is much better',
    js: [
      { page: 'User:Connel_MacKenzie/spellcheck.js' }
    ],
    isdisabled: function() { return true; }
  },
  WiktionaryPreferencesTime: {
    num: 14,
    text: 'Show a clock in the top right corner of the screen.',
    js: [
      { page: 'User:Connel_MacKenzie/clock.js' }
    ]
  },
  WiktionaryPreferencesPopUps: {
    num: 15,
    text: 'Use [[w:User:Lupin/popups.js]] to provide page previews and useful checkboxs when hovering on a normal link.',
    js: [
      { page: 'User:Lupin/popups.js', wiki: 'en.wikipedia.org' },
      { page: 'User:Connel_MacKenzie/mess-with-popups.js' }
    ]
  },
  WiktionaryPreferencesKeyPad: {
    num: 16,
    text: 'Show a special character input (like the one beneath the edit field) for the search field.',
    js: [
      { page: 'User:Connel_MacKenzie/keypad.js' }
    ]
  },
  WiktPrefConnelReformat: {
    num: 17,
    text: 'Use [[User:Connel_MacKenzie/reformat.js]] to reformat pages semi-automatically. [Do NOT use this unless you know Wiktionary policy better than the back of your hand.]',
    js: [
      { page: 'User:Connel_MacKenzie/reformat.js' }
    ]
  },
  WiktPrefPatrol: {
    num: 18,
    text: 'Patrolling enhancements – add a (mark) next to (diff) to mark as patrolled without leaving Special:RC.  Use popups above, to hover over (diff) links, then click (mark).',
    js: [
      { page: 'User:Connel_MacKenzie/patrolled.js' }
    ]
  },
  WiktPrefDelCmnt: {
    num: 19,
    text: 'Replace text in deletion log comment',
    js: [
      { page: 'User:Connel_MacKenzie/del-cmnt.js' }
    ]
  },
  // disabled until rewritten
  WiktPrefDiff: {
    num: 20
  },
  // was WiktIrc a very long time ago…
  WiktMakeRedLinksBlack: {
    num: 21,
    text: 'Make red-links on some inflection tables look black.',
    css: [
      { selector: '.inflection-table a.new', declarations: 'color: #000000;' }
    ]
  },
  WiktAjaxTransLinks: {
    num: 22,
    text: 'Color translation links orange instead of blue if the target language is missing on an existing page.',
    js: [
      { page: 'User:Hippietrail/ajaxtranslinks.js' }
    ],
    isdisabled: function() {
      // test for javascript 1.7 == test for gecko >= rv:1.8.1
      var ua = navigator.userAgent.toLowerCase();
      if (/gecko/.test(ua)) {
        var rv = ua.match(/\brv:(\d+)\.(\d+)(?:\.\d+)*/);
        if (rv) {
          if (rv[1] > 1) return false;
          if (rv[1] == 1) {
            if (rv[2] > 8) return false;
            if (rv[2] == 8) {
              if (rv[3] >= 1) return false;
            }
          }
        }
      }
      return true;
    }
  },
  WiktAddStructure: {
    num: 23,
    text: 'Use [[User:Conrad.Irwin/parser.js]] to provide two different views of most pages.',
    js: [
      { page: 'User:Conrad.Irwin/parser.js' }
    ]
  },
  WiktHideLogo: {
    num: 24,
    text: 'Hide the logo in the upper left corner.',
    css: [
      { selector: '#p-logo', declarations: 'display: none;' },
      { selector: '#column-one', declarations: 'padding-top: 0;' }
    ]
  },
  WiktFormOfPlain: {
    num: 25,
    text: 'Show “form of” definitions with a plain (only wikilinked) lemma. (Default is with a bold lemma.)',
    css: [ {
      selector: '.use-with-mention .mention',
      declarations: 'font-weight: normal !important;'
    } ]
  },
  WiktFormOfItalicQualifier: {
    num: 26,
    text: 'Show “form of” definitions with an italic definition (“qualifier”) and plain (only wikilinked) lemma. (Default is with a bold lemma.)',
    css: [ {
        selector: '.use-with-mention',
        declarations: 'font-style: italic;'
      }, {
        selector: '.use-with-mention .mention',
        declarations: 'font-weight: normal !important;'
      } ]
  },
  WiktFormOfItalicLemma: {
    num: 27,
    text: 'Show “form of” definitions with an italic lemma. (Default is with a bold lemma.)',
    css: [ {
      selector: '.use-with-mention .mention',
      declarations: 'font-style: italic !important; font-weight: normal !important;'
    } ]
  },
  WiktFormOfItalicQualifierBoldLemma: {
    num: 28,
    text: 'Show “form of” definitions with an italic definition (“qualifier”) and bold lemma. (Default is with a bold lemma.)',
    css: [
      { selector: '.use-with-mention', declarations: 'font-style: italic;' }
    ]
  },
  // no longer used
  WiktEnMentionItalics: {
    num: 29,
    css: [ {
      selector: '.en-mention',
      declarations: 'font-style: italic; font-weight: normal !important;'
    } ]
  },
  // no longer used
  WiktEnMentionDoubleQuotes: {
    num: 30,
    css: [ {
      selector: '.en-mention',
      declarations: 'font-weight: normal !important; '
    }, {
      selector: '.en-mention-double-quote',
      declarations: 'display: inline !important;'
    } ]
  },
  // no longer used
  WiktEnMentionSingleQuotes: {
    num: 31,
    css: [ {
      selector: '.en-mention',
      declarations: 'font-weight: normal !important;'
    }, {
      selector: '.en-mention-single-quote',
      declarations: 'display: inline !important;'
    } ]
  },
  WiktLatnMentionBold: {
    text: 'Show other Latin (Roman) script mentions in bold. (Default is in italics.)',
    num: 32,
    css: [ {
      selector: '.mention-Latn',
      declarations: 'font-style: normal !important; font-weight: bold;'
    } ]
  },
  WiktMentionGlossSingleQuotes: {
    num: 33,
    text: 'Show English glosses for mentioned terms in single quotes. (Default is in double quotes.)',
    css: [ {
      selector: '.mention-gloss-double-quote',
      declarations: 'display: none !important;'
    }, {
      selector: '.mention-gloss-single-quote',
      declarations: 'display: inline !important;'
    } ]
  },
  WiktionaryPreferencesHideQualifierParens: {
    num: 34,
    text: 'Hide the parentheses around list item qualifiers.',
    css: [ {
      selector: '#bodyContent .qualifier-brac',
      declarations: 'display:none' }
    ]
  },
  WiktionaryPreferencesItalicParens: {
    num: 35,
    text: 'Italicize the punctuation (parentheses and colon) around italic text.',
    css: [ {
      selector: '.ib-brac, .ib-comma, .sense-qualifier-colon',
      declarations: 'font-style: italic'
    } ]
  },
  // no longer used
  WiktShowLinguistLabels: {
    num: 36,
    css: [ {
      selector: '.label-layman',
      declarations: 'display: none'
    }, {
      selector: '.label-linguist',
      declarations: 'display: inline !important;'
    } ]
  },
  WiktHideTrGlossParens: {
    num: 37,
    text: 'Hide parentheses around transliterations and glosses.',
    css: [ {
      selector: '.term-tr-gloss-paren, .term-tr-paren, .term-gloss-paren',
      declarations: 'display: none'
    } ]
  },
  WiktHideAllParens: {
    num: 38,
    text: 'Hide the maximal amount of parentheses. [Can cause sentences to appear ungrammatical]',
    css: [ {
      selector: '.ib-brac, .term-tr-gloss-paren, .term-gloss-paren',
      declarations: 'display:none'
    } ]
  },
  WiktHideGlossParens: {
    num: 39,
    text: 'Hide parentheses around glosses.',
    css: [ {
      selector: '.mention-tr-gloss-separator-paren',
      declarations: 'display:inline !important'
    }, {
      selector: '.mention-gloss-paren, .mention-tr-gloss-separator-comma',
      declarations: 'display:none'
    } ]
  },
  WiktPlainTransliterations: {
    num: 40,
    text: 'Show parenthesized plain (non-italic) transliterations.',
    css: [ {
      selector: '.mention-tr-paren, .mention-tr',
      declarations: 'font-style:normal !important'
    } ]
  },
  WiktIrc2: {
    num: 41,
    text: 'Show a link to a web-based IRC client in the top right-hand corner.',
    js: [
      { page: 'User:Connel_MacKenzie/irc.js' }
    ]
  },
  WiktFilterContributions: {
    num: 42,
    text: 'Filter out your own contributions from Special:Contributions',
    js: [
      { page: 'User:Hippietrail/filtercontribs.js' }
    ]
  },
  WiktCIDRRangeContribs: {
    num: 43,
    text: 'Adds a CIDR Range Contributions check to Special:User contributions',
    js: [
      { page: 'User:TheDaveRoss/CIDR.js' }
    ]
  },
  WiktSidebarTranslation: {
    num: 44,
    text: 'Translate sidebar interwiki links to English',
    js: [
      { page: 'User:Bequw/sidebartranslate.js' }
    ]
  },
  WiktQuickLookup: {
    num: 45,
    text: 'Automatically look up words that are double-clicked on in Wiktionary.',
    js: [
      { page: 'User:Bequw/quickLookup.js' }
    ]
  },
  WiktBlockedNotice: {
    num: 46,
    text: 'Add a box to the top of user-related pages if the user is blocked from editing.',
    js: [
      { page: 'User:Conrad.Irwin/isblocked.js' }
    ]
  },
  // This is just to allow people to test easily
  WiktAddProminentInterwikis: {
    num: 47,
    text: 'Show an interwiki link under the language heading when one exists in the sidebar.',
    js: [
      { page: 'User:Conrad.Irwin/iwiki.js' }
    ]
  },
  WiktFloatNavToggleLeft: {
    num: 48,
    text: 'Put the [show] checkbox onto the left of the translation bars.',
    css: [ {
      selector: '.NavToggle',
      declarations: 'float: left !important; position: static !important; right: inherit; margin-top: 0.1em; margin-right: 5px;'
    } ]
  },
  // Removed as the aspell server is down
  WiktAspellPrototype: {
    num: 49,
    text: '(Experimental) Use the aspell checker on [[User:Amgine]]’s http://devtionary.info to check search results. (WARNING this site is independent of the WMF and this utility may go offline without warning. Your IP address may be recorded in the server logs there, but no information about your Wiktionary account is sent.)',
    js: [
      { page: 'User:Conrad.Irwin/aspell.js' }
    ],
    isdisabled: function() { return true; }
  },
  WiktPreviewRightTOCs: {
    num: 50,
    text: 'Put the table of contents onto the right of entries.',
    css: [ {
      selector: '.ns-0 #toc',
      declarations: 'float: right; clear: right; margin-left: 7px; margin-bottom: 6px; display: inline;'
    } ]
  },
  WiktAccelerateFormCreation: {
    num: 51,
    text: 'Add accelarated creation links for common inflections of some words.',
    js: [
      { page: 'User:Conrad.Irwin/creation.js' },
      {
        page: 'User:Lupin/autoedit.js',
        wiki: 'en.wikipedia.org',
        rev: '46637295',
        condition: {
          othercookie: 'WiktionaryPreferencesPopUps',
          comp: '!=', value: 'true'
        }
      }
    ]
  },
  WiktAssistedEditing: {
    num: 52,
    text: 'Add input boxes to pages to assist with adding translations.',
    js: [
      { page: 'User:Conrad.Irwin/editor.js' }
    ]
  },
  // hide EditTools under search field
  WiktionaryPreferencesEditTools: {
    num: 53,
    text: 'Hide the special character input beneath the edit field.',
    css: [
      { selector: '.mw-editTools', declarations: 'display: none;' }
    ]
  },
  // Show links to previous and next pages
  WiktNearbyPages: {
    num: 54,
    text: 'Add links to previous and next pages.',
    js: [
      { page: 'User:Hippietrail/nearbypages.js' }
    ]
  },
  // Add some per-language toys
  WiktPerLanguage: {
    num: 55,
    text: 'For each language section add interwiki and random links.',
    js: [
      { page: 'User:Hippietrail/perlanguage.js' }
    ]
  },
  WiktDeprecated56: {
    num: 56
  },
  WiktDeprecated57: {
    num: 57
  },
  // hide annoying copyright stuff
  WiktHideCopyrightWarning: {
    num: 58,
    text: 'Hide the copyright warning in the edit window.',
    css: [
      { selector: '#editpage-copywarn, .mw-tos-summary', declarations: 'display:none' }
    ]
  }
};

/* Warning: The numbers associated with each preference must not be changed.
 * (The cookie that stores preferences is written as a sequence of preference
 * values without the corresponding preference names.) */

// TODO should not be global
var wiktTempCookie = '';

// this function must be global. it is used from other scripts
// including User:Connel_MacKenzie/clock.js
function wiktGetPrefCookie(wiktPrefName) {
  //When we have a few hundred prefs, I’ll have to do this in binary, instead of text "0" & "1"
  wiktTempCookie = getCookie('WiktPrefs');
  var prefArray = wiktTempCookie.split("-");

  if (getCookie(wiktPrefName) == 'true') return 'true';
  if (wiktPrefName in prefs && prefArray[prefs[wiktPrefName].num]) {
    if (prefArray[prefs[wiktPrefName].num] == 1) {
      return 'true';
    } else return 'false';
  } else {
    return getCookie(wiktPrefName);
  }
}

function wiktSetPrefCookie(prefName, boolValue) {
  wiktTempCookie = getCookie('WiktPrefs');
  var prefArray = wiktTempCookie.split("-");
  var versi = "0.1" + "-";
  var intValue = 0;
  if (boolValue == 'true') intValue = 1;

  if (prefs[prefName]) {
    prefArray[prefs[prefName].num] = intValue;
  } else {
    setCookie(prefName, boolValue);
    return;
  }

  for (var p in prefs) {
    if (prefArray[prefs[p].num]) {
      if (prefName == p) {
        versi += intValue + "-";
        deleteCookie(p);
      } else {
        if (wiktGetPrefCookie(p) == 'true') {
          versi += "1" + "-";
        } else {
          versi += "0" + "-";
        }
        deleteCookie(p);
      }
    } else {
      versi += "0" + "-";
    }
  }
  setCookie('WiktPrefs', versi);
  return;
}

function ActivateChosenPrefs() {
  if (wiktGetPrefCookie('WiktionaryUseJSPreferences') == 'true') {

    //Start by refreshing the cookies, deleting the old format cookies.
    wiktSetPrefCookie('WiktionaryUseJSPreferences', 'true');

    for (var p in prefs) {
      var pref = prefs[p];
      if (wiktGetPrefCookie(p) == 'true') {
        if ('isdisabled' in pref && pref.isdisabled())
          continue;

        if ("css" in pref) {
          for (var c in pref.css) {
            var css = pref.css[c];
            mw.util.addCSS(css.selector + "{" + css.declarations + "}");
          }
        }
        if ("js" in pref) {
          for (var j in pref.js) {
            var js = pref.js[j];
            var ok = true;

            if ('condition' in js) {
              ok = false;
              if ('othercookie' in js.condition && 'comp' in js.condition && 'value' in js.condition) {
                var oc = wiktGetPrefCookie(js.condition.othercookie);
                if (js.condition.comp == '!=' && oc != js.condition.value)
                  ok = true;
              }
            }

            if (ok) importScript(js.page, js.wiki, js.rev);
          }
        }
      }
    }
  }
}

// TODO should not be global
enWiktPrefCheckboxs = [];

/* </pre>
== wiktAddCheckbox ==
<pre> */
// generate checkboxs 
function wiktAddCheckbox(cookieToToggle, speedTip, isDisabled) {
  var checkbox = document.createElement("input");
  checkbox.type = 'checkbox';
  checkbox.name = cookieToToggle;
  checkbox.onclick = function() {
    if (wiktGetPrefCookie(this.name) != 'true') {
      wiktSetPrefCookie(this.name, 'true');
    } else {
      wiktSetPrefCookie(this.name, 'false');
    }
  };
  checkbox.disabled = isDisabled;
  if ('true' == wiktGetPrefCookie(cookieToToggle)) {
    checkbox.checked = true;
  }
  var isPreferencePage = document.getElementById('isPreferencePage');
  isPreferencePage.appendChild(checkbox);
  if ('true' == wiktGetPrefCookie(cookieToToggle)) {
    checkbox.checked = true;
  }
  isPreferencePage.appendChild(document.createTextNode(speedTip));
  isPreferencePage.appendChild(document.createElement('br'));
  return checkbox;
}

function wiktAddSeparator(wiktSepText) {
  var pnod = document.createElement('p');
  var isPreferencePage = document.getElementById('isPreferencePage');
  pnod.appendChild(document.createTextNode(wiktSepText));
  pnod.appendChild(document.createElement('hr'));
  isPreferencePage.appendChild(pnod);
  return pnod;
}

//not used just yet
function wiktAddTextBox(cookieToInput, speedTip) {
  var textbox = document.createElement("input");
  textbox.type = 'text';
  textbox.width = 10;
  textbox.name = cookieToInput;
  textbox.onchange = function() {
    wiktSetPrefCookie(this.name, this.value);
  };
  textbox.value = wiktGetPrefCookie(cookieToInput);
  isPreferencePage.appendChild(textbox);
  var text = document.createTextNode(speedTip);
  isPreferencePage.appendChild(text);
  return textbox;
}

/* </pre>
== CustomizePreferencesPage==
*Note that this needs to be re-written as a separate tab (or two or three) that appear when wgPageName=="Special:Preferences".
<pre> */

function CustomizePreferencesPage() {
  //If on [[Special:Preferences]], add reminder link
  var isWmPrefsPage = document.getElementById('wpReset');
  if (isWmPrefsPage) {
    var wiktlink = document.createElement("a");
    wiktlink.setAttribut('href', '/wiki/Wiktionary:Preferences');
    var wiktltxt = document.createTextNode("See also: Wiktionary-specific preferences");
    wiktlink.appendChild(wiktltxt);
    isWmPrefsPage.appendChild(wiktlink);
  }

  var isPreferencePage = document.getElementById('isPreferencePage');
  if (!isPreferencePage) return;

  //OK, so now we know we are on 
  //the Set EnglishWiktionary-specific Preferences page (or impersonation thereof)
  // Hide the "noscript" div and display the "hasscript" one
  var noscript = document.getElementById('wtprefs.noscript');
  var hasscript = document.getElementById('wtprefs.hasscript');

  if (noscript !== null && hasscript !== null) {
    noscript.style.display = 'none';
    hasscript.style.display = 'block';
  }

  // http://tools.wikimedia.de/~cmackenzie/make_checkboxs.html
  // crop image to 21 pixels vertical, whatever horizontal.
  var everyone = [
    { type: "checkbox", name: 'WiktionaryUseJSPreferences' },

    { type: "separator", text: '>IMPORTANT – If the above box is unchecked, EVERYTHING on this page is turned off' },

    { type: "separator", text: 'Preferences that change the display of the interface. [Probably only work with the Monobook skin]' },

    // Hide special characters for edit field
    { type: "checkbox", name: 'WiktionaryPreferencesEditTools' },

    // Allow special characters in [Search] input
    { type: "checkbox", name: 'WiktionaryPreferencesKeyPad' },

    { type: "checkbox", name: 'WiktionaryPreferencesHideSiteNotice' },

    { type: "checkbox", name: 'WiktHideLogo' },

    // Andrew's clock
    { type: "checkbox",
      name: 'WiktionaryPreferencesTime',
      suboptions: [ "WiktionaryPreferencesTimeUTC", "WiktionaryPreferencesTickClock" ] },
    { type: "externcheckbox",
      name: 'WiktionaryPreferencesTimeUTC',
      text: 'Change the clock to display UTC, instead of local time.',
      isdisabled: function() { return wiktGetPrefCookie('WiktionaryPreferencesTime') != 'true'; } },
      // User:Connel MacKenzie/clock.js / wiktGetPrefCookie()
    { type: "externcheckbox",
      name: 'WiktionaryPreferencesTickClock',
      text: 'Change the clock to update every second, instead of every page load.',
      isdisabled: function() { return wiktGetPrefCookie('WiktionaryPreferencesTime') != 'true'; } },
      // User:Connel MacKenzie/clock.js / wiktGetPrefCookie()

    { type: "checkbox", name: 'WiktIrc2' },

    { type: "checkbox", name: 'WiktionaryPreferencesSmallRC' },

    { type: "checkbox", name: 'WiktSidebarTranslation' },

    { type: "checkbox", name: 'WiktFloatNavToggleLeft' },

    { type: "checkbox", name: 'WiktPreviewRightTOCs' },

    { type: "checkbox", name: 'WiktHideCopyrightWarning' },

    { type: "separator", text: 'Preferences that change the display of entries. [May only work with the Monobook skin]' },

    { type: "checkbox", name: 'WiktionaryPreferencesHideLinesBetweenLanguages' },

    { type: "checkbox", name: 'WiktionaryPreferencesHideQualifierParens' },

    { type: "checkbox", name: 'WiktionaryPreferencesItalicParens' },

    { type: "checkbox", name: 'WiktHideAllParens' },

    { type: "checkbox", name: 'WiktionaryPreferencesHideTransitivity' },

    { type: "checkbox", name: 'WiktionaryPreferencesHideSister' },

    { type: "checkbox", name: 'WiktionaryPreferencesHideRankings' },

    //there’s a typo somewhere here, but I’m not seeing it…
    //See [[MediaWiki:Monobook.js#Dynamic Navigation Bars (experimental)]]
    { type: "externcheckbox",
      name: 'WiktionaryPreferencesShowNav',
      text: 'Show the translation sections expanded, instead of having them collapsed.' },
      // MediaWiki:Monobook.js / getCookie

    { type: "checkbox", name: 'WiktionaryPreferencesHideTranslations' },

    { type: "checkbox", name: 'WiktionaryPreferencesBoxedInflections' },

    { type: "checkbox", name: 'WiktionaryPreferencesIndentSeeAlso' },

    { type: "checkbox", name: 'WiktFormOfPlain' },

    { type: "checkbox", name: 'WiktFormOfItalicQualifier' },

    { type: "checkbox", name: 'WiktFormOfItalicLemma' },
    { type: "checkbox", name: 'WiktFormOfItalicQualifierBoldLemma' },
    { type: "checkbox", name: 'WiktLatnMentionBold' },
    { type: "checkbox", name: 'WiktMentionGlossSingleQuotes' },
    { type: "checkbox", name: 'WiktHideTrGlossParens' },
    { type: "checkbox", name: 'WiktHideGlossParens' },
    { type: "checkbox", name: 'WiktPlainTransliterations' },

    { type: "separator", text: 'Preferences relating to navigation and editing.' },

    { type: "externcheckbox",
      name: 'WiktionaryDisableAutoRedirect',
      text: 'Disable the javascript redirect between pages that differ only in case.' },
      // MediaWiki:Common.js / getCookie()

    // [[User:Lupin/popups.js]]
    { type: "checkbox", name: 'WiktionaryPreferencesPopUps' },

    { type: "checkbox", name: 'WiktPrefConnelReformat' },

    { type: "checkbox", name: 'WiktQuickLookup' },

    { type: "checkbox", name: 'WiktAddProminentInterwikis' },

    { type: "checkbox", name: 'WiktAccelerateFormCreation' },

    { type: "checkbox", name: 'WiktAssistedEditing' },

    { type: "checkbox", name: 'WiktAjaxTransLinks' },

    { type: "checkbox", name: 'WiktMakeRedLinksBlack' },

    { type: "separator", text: 'Experiments – these are likely to be buggy and may not work in very common browsers.' },

    { type: "checkbox", name: 'WiktAddStructure' },

    { type: "checkbox", name: 'WiktFilterContributions' },

    // experimental spell checkers are both down atm
    { type: "checkbox", name: 'WiktionaryPreferencesSpellCheck' },
    { type: "checkbox", name: 'WiktAspellPrototype' },

    { type: "checkbox",
      name: 'WiktNearbyPages',
      suboptions: [
        "WiktNearbyPagesLangHeadings",
        "WiktNearbyPagesNavbar",
        "WiktNearbyAlwaysLTR"
      ] },
    { type: "externcheckbox",
      name: 'WiktNearbyPagesNavbar',
      text: 'Add the links in the navigation bar.',
      isdisabled: function() { return wiktGetPrefCookie('WiktNearbyPages') != 'true'; } },
      // User:Hippietrail/nearbypages.js / getCookie()
      // TODO disable LTR checkbox when nearby headings is off
    { type: "externcheckbox",
      name: 'WiktNearbyPagesLangHeadings',
      text: 'Add the links under the language headings.',
      isdisabled: function() { return wiktGetPrefCookie('WiktNearbyPages') != 'true'; } },
      // User:Hippietrail/nearbypages.js / getCookie()
      // TODO only enable this when nearyby headings is also enabled
    { type: "externcheckbox",
      name: 'WiktNearbyAlwaysLTR',
      text: 'Make the links left-to-right for all languages.',
      isdisabled: function() { return wiktGetPrefCookie('WiktNearbyPages') != 'true'; } },
      // User:Hippietrail/nearbypages.js / getCookie()

    { type: "checkbox", name: 'WiktPerLanguage' },
  ];

  var sysops = [
    { type: "separator", text: 'Sysop-only functions: ' },
    { type: "checkbox", name: 'WiktPrefDelCmnt' },

    { type: "checkbox",
      name: 'WiktPrefPatrol',
      suboptions: [ "WiktPrefPatrolFast", "WiktPrefPatrolRefresh" ] },
    { type: "externcheckbox",
      name: 'WiktPrefPatrolFast',
      text: 'Patrol in “expert mode” with no alerts – all whitelisted users’ edits are quietly marked, bottom to top.',
      isdisabled: function() { return wiktGetPrefCookie('WiktPrefPatrol') != 'true'; } },
      // User:Connel MacKenzie/patrolled.js / wiktGetPrefCookie()
    { type: "externcheckbox",
      name: 'WiktPrefPatrolRefresh',
      text: 'Refresh Special:RecentChanges every 5 minutes',
      isdisabled: function() { return wiktGetPrefCookie('WiktPrefPatrol') != 'true'; } },
      // User:Connel MacKenzie/patrolled.js / wiktGetPrefCookie()

    { type: "externcheckbox",
      name: 'WiktPrefVOA',
      text: 'Use the Uber-Popups from VOA – WARNING – DANGEROUS',
      isdisabled: function() { return true; } },
      // Can't find where this is or was used

    { type: "checkbox", name: 'WiktCIDRRangeContribs' },
    { type: "checkbox", name: 'WiktBlockedNotice' }
  ];

  function masterOnclick() {
    var t = wiktGetPrefCookie('WiktionaryUseJSPreferences');

    wiktSetPrefCookie('WiktionaryUseJSPreferences', t == 'true' ? 'false' : 'true');

    updateGUI();
  }

  function groupOnclick(ev) {
    var ele = window.event ? window.event.srcElement : ev.target;
    var masterPref = ele.name;

    var t = wiktGetPrefCookie(masterPref);

    wiktSetPrefCookie(masterPref, t == 'true' ? 'false' : 'true');

    updateGUIGroup(masterPref);
  }

  function getGUIItemFromPrefName(prefName) {
    var lists = getGuiLists();

    for (var l in lists) {
      var list = lists[l];

      for (var i in list) {
        var item = list[i];

        if ("name" in item && item.name == prefName)
          return item;
      }
    }
    return undefined;
  }

  function updateGUIGroup(masterPrefName) {
    var masterPref = prefs[masterPrefName];
    var masterDisable = !masterPref.ele.checked;

    var master = getGUIItemFromPrefName(masterPrefName);

    var subPrefs = master.suboptions;

    for (var sp in subPrefs) {
      var subPrefName = subPrefs[sp];
      var item = getGUIItemFromPrefName(subPrefName);
      var isdisabled = masterDisable;

      switch (item.type) {
        case "checkbox":
          if (typeof pref.isdisabled !== "undefined")
            isdisabled |= pref.isdisabled();

          pref.ele.disabled = isdisabled;

          break;
        case "externcheckbox":
          if (typeof item.isdisabled !== "undefined")
            isdisabled |= item.isdisabled();

          item.ele.disabled = isdisabled;

          break;
      }
    }
  }

  function buildGUI() {
    var masterDisable = false;

    var lists = getGuiLists();

    for (var l in lists) {
      var list = lists[l];

      for (var i in list) {
        var item = list[i];
        var pref = prefs[item.name];

        var isdisabled = masterDisable;

        switch (item.type) {
          case "checkbox":
            if (typeof pref.isdisabled !== "undefined")
              isdisabled |= pref.isdisabled();

            pref.ele = item.ele = wiktAddCheckbox(item.name, pref.text, isdisabled);

            if (l == 0 && i == 0) {
              masterDisable = !pref.ele.checked;
              pref.ele.onclick = masterOnclick;
            }

            else if ("suboptions" in item) {
              pref.ele.onclick = groupOnclick;
            }

            break;
          case "separator":
            item.ele = wiktAddSeparator(item.text);
            break;
          case "externcheckbox":
            if (typeof item.isdisabled !== "undefined")
              isdisabled |= item.isdisabled();

            item.ele = wiktAddCheckbox(item.name, item.text, isdisabled);
        }
      }
    }
  }

  function updateGUI() {
    var masterDisable = false;

    var lists = getGuiLists();

    for (var l in lists) {
      var list = lists[l];

      for (var i in list) {
        var item = list[i];
        var pref = prefs[item.name];

        var isdisabled = masterDisable;

        switch (item.type) {
          case "checkbox":
            if (typeof pref.isdisabled !== "undefined")
              isdisabled |= pref.isdisabled();
            pref.ele.disabled = isdisabled;
            if (l == 0 && i == 0)
              masterDisable = !pref.ele.checked;
            break;
          case "externcheckbox":
            if (typeof item.isdisabled !== "undefined")
              isdisabled |= item.isdisabled();
            item.ele.disabled = isdisabled;
        }
      }
    }
  }

  // MSIE compatibility workaround for indexOf might not work
  // on skins other than monobook
  // If they have a delete checkbox on this page, they are a sysop.
  function isSysop() {
    if ("indexOf" in Array)
      return wgUserGroups !== null && wgUserGroups.indexOf("sysop") != -1;
    return document.getElementById('ca-delete') !== null;
  }

  function getGuiLists() {
    var lists = [everyone];

    if (isSysop())
      lists.push(sysops);

    return lists;
  }

  buildGUI();
}
 
function wiktCustomPrefsLoad() {
  CustomizePreferencesPage();
  mw.loader.using(["mediawiki.util"], function(){
  	ActivateChosenPrefs();
  });
}
 
$(wiktCustomPrefsLoad);