From cf815baa1467057bbe88955f92952f3972175d98 Mon Sep 17 00:00:00 2001 From: "James D. Forrester" Date: Wed, 13 Jul 2022 09:34:59 -0400 Subject: Update OOUI to v0.44.1 Release notes: https://gerrit.wikimedia.org/g/oojs/ui/+/v0.44.1/History.md Bug: T92315 Bug: T239208 Bug: T295058 Bug: T297003 Bug: T299036 Bug: T306486 Bug: T307456 Bug: T307995 Bug: T308260 Bug: T308295 Bug: T308306 Bug: T309154 Bug: T309226 Bug: T309790 Bug: T311188 Depends-On: Ie0684113f54b193b809c8e0dede826ef2c1ee67f Change-Id: I3fe64f52ebddad5acdf8caf1b53a1b8365c0b2fb --- RELEASE-NOTES-1.39 | 2 +- composer.json | 2 +- resources/lib/foreign-resources.yaml | 4 +- resources/lib/ooui/History.md | 63 +++ resources/lib/ooui/i18n/bci.json | 27 ++ resources/lib/ooui/i18n/ckb.json | 13 +- resources/lib/ooui/i18n/fat.json | 31 ++ resources/lib/ooui/i18n/hi.json | 21 +- resources/lib/ooui/i18n/ks-arab.json | 16 + resources/lib/ooui/i18n/nqo.json | 6 +- resources/lib/ooui/i18n/rsk.json | 29 ++ resources/lib/ooui/i18n/ru.json | 3 +- resources/lib/ooui/i18n/rw.json | 30 ++ resources/lib/ooui/i18n/tdd.json | 25 + resources/lib/ooui/i18n/tum.json | 29 ++ resources/lib/ooui/i18n/yue.json | 4 +- resources/lib/ooui/oojs-ui-apex.js | 4 +- resources/lib/ooui/oojs-ui-core-apex.css | 49 +- resources/lib/ooui/oojs-ui-core-wikimediaui.css | 56 +-- resources/lib/ooui/oojs-ui-core.js | 530 ++++++++++----------- resources/lib/ooui/oojs-ui-core.js.map.json | 2 +- resources/lib/ooui/oojs-ui-images-wikimediaui.css | 31 +- resources/lib/ooui/oojs-ui-toolbars-apex.css | 12 +- .../lib/ooui/oojs-ui-toolbars-wikimediaui.css | 16 +- resources/lib/ooui/oojs-ui-toolbars.js | 278 ++++++++--- resources/lib/ooui/oojs-ui-toolbars.js.map.json | 2 +- resources/lib/ooui/oojs-ui-widgets-apex.css | 6 +- resources/lib/ooui/oojs-ui-widgets-wikimediaui.css | 15 +- resources/lib/ooui/oojs-ui-widgets.js | 300 ++++++------ resources/lib/ooui/oojs-ui-widgets.js.map.json | 2 +- resources/lib/ooui/oojs-ui-wikimediaui.js | 14 +- resources/lib/ooui/oojs-ui-wikimediaui.js.map.json | 2 +- resources/lib/ooui/oojs-ui-windows-apex.css | 27 +- resources/lib/ooui/oojs-ui-windows-wikimediaui.css | 24 +- resources/lib/ooui/oojs-ui-windows.js | 389 ++++++++------- resources/lib/ooui/oojs-ui-windows.js.map.json | 2 +- .../ooui/themes/apex/icons-editing-advanced.json | 18 + .../themes/wikimediaui/icons-editing-advanced.json | 18 + .../wikimediaui/images/icons/copy-ltr-invert.svg | 3 + .../images/icons/copy-ltr-progressive.svg | 3 + .../themes/wikimediaui/images/icons/copy-ltr.svg | 3 + .../wikimediaui/images/icons/copy-rtl-invert.svg | 3 + .../images/icons/copy-rtl-progressive.svg | 3 + .../themes/wikimediaui/images/icons/copy-rtl.svg | 3 + .../wikimediaui/images/icons/cut-ltr-invert.svg | 3 + .../images/icons/cut-ltr-progressive.svg | 3 + .../themes/wikimediaui/images/icons/cut-ltr.svg | 3 + .../wikimediaui/images/icons/cut-rtl-invert.svg | 3 + .../images/icons/cut-rtl-progressive.svg | 3 + .../themes/wikimediaui/images/icons/cut-rtl.svg | 3 + .../wikimediaui/images/icons/paste-ltr-invert.svg | 3 + .../images/icons/paste-ltr-progressive.svg | 3 + .../themes/wikimediaui/images/icons/paste-ltr.svg | 3 + .../wikimediaui/images/icons/paste-rtl-invert.svg | 3 + .../images/icons/paste-rtl-progressive.svg | 3 + .../themes/wikimediaui/images/icons/paste-rtl.svg | 3 + 56 files changed, 1331 insertions(+), 825 deletions(-) create mode 100644 resources/lib/ooui/i18n/bci.json create mode 100644 resources/lib/ooui/i18n/fat.json create mode 100644 resources/lib/ooui/i18n/ks-arab.json create mode 100644 resources/lib/ooui/i18n/rsk.json create mode 100644 resources/lib/ooui/i18n/rw.json create mode 100644 resources/lib/ooui/i18n/tdd.json create mode 100644 resources/lib/ooui/i18n/tum.json create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/copy-ltr-invert.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/copy-ltr-progressive.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/copy-ltr.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/copy-rtl-invert.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/copy-rtl-progressive.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/copy-rtl.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/cut-ltr-invert.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/cut-ltr-progressive.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/cut-ltr.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/cut-rtl-invert.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/cut-rtl-progressive.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/cut-rtl.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/paste-ltr-invert.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/paste-ltr-progressive.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/paste-ltr.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/paste-rtl-invert.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/paste-rtl-progressive.svg create mode 100644 resources/lib/ooui/themes/wikimediaui/images/icons/paste-rtl.svg diff --git a/RELEASE-NOTES-1.39 b/RELEASE-NOTES-1.39 index b691d6aa8b9a..4828813eaa41 100644 --- a/RELEASE-NOTES-1.39 +++ b/RELEASE-NOTES-1.39 @@ -90,7 +90,7 @@ For notes on 1.38.x and older releases, see HISTORY. * … ==== Changed external libraries ==== -* Updated OOUI from v0.43.2 to v0.44.0. +* Updated OOUI from v0.43.2 to v0.44.1. * Updated composer/semver from 3.2.6 to 3.3.2. * Updated vue/compat from 3.2.23 to 3.2.31. * Updated wikimedia/minify from 2.2.6 to 2.3.0. diff --git a/composer.json b/composer.json index 460fca9ca87d..885fccb4bb66 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "justinrainbow/json-schema": "5.2.11", "liuggio/statsd-php-client": "1.0.18", "monolog/monolog": "2.2.0", - "oojs/oojs-ui": "0.44.0", + "oojs/oojs-ui": "0.44.1", "pear/mail": "1.4.1", "pear/mail_mime": "1.10.11", "pear/net_smtp": "1.10.0", diff --git a/resources/lib/foreign-resources.yaml b/resources/lib/foreign-resources.yaml index 0cbae9a4ee9a..d401b80a2332 100644 --- a/resources/lib/foreign-resources.yaml +++ b/resources/lib/foreign-resources.yaml @@ -290,8 +290,8 @@ oojs-router: ooui: type: tar - src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.44.0.tgz - integrity: sha384-0/+cNOi1Yvw/1Zh419sFHQHOQz0iDtQzIeqysIrfJdvcM1pstnd8XvjnjtVnU7qR + src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.44.1.tgz + integrity: sha384-3dVe9nDsA6xzJt5azbZw0nTNF7NZDXePIWNnrC+umSuEe3VMkfe09chMuZXDkyU7 dest: # Main stuff diff --git a/resources/lib/ooui/History.md b/resources/lib/ooui/History.md index c7f109edaec4..cc6af6d29fbc 100644 --- a/resources/lib/ooui/History.md +++ b/resources/lib/ooui/History.md @@ -1,4 +1,67 @@ # OOUI Release History +## v0.44.1 / 2022-07-12 +### Features +* Element: Added `alignToTop` as an option to `scrollIntoView` (Svantje Lilienthal) +* TagMultiselectWidget: Support editing tags with jQuery-formatted labels (gtzatchkova) +* TitledElement: Use `invisibleLabel` config as fallback for title (Ed Sanders) +* Tool and PopupToolGroup: Add '`narrowConfig`' support (Ed Sanders) +* Tool: Add config and setter for `displayBothIconAndLabel` (Ed Sanders) +* Toolbar: Fix DOM order of tools and actions for tabbing (Bartosz Dziewoński) +* Toolbar: Make '`action`' tools part of a single toolbar (Ed Sanders) +* Window: Only use focus traps if the WindowManager is modal (Ed Sanders) +* WindowManager: Add a `forceTrapFocus` option (Ed Sanders) +* WindowManager: Check focus doesn't end up outside modal windows when focusing the page (Ed Sanders) +* WindowManager: Handle focus traps using CSS (Ed Sanders) +* WindowManager: Set '`inert`' as well as '`aria-hidden`' when opening modals (Ed Sanders) + +### Styles +* FieldLayout: Expand label when there's no help (`align: 'left'/'right'`) (Bartosz Dziewoński) +* ProgressBar: Adjust behaviour of indeterminate ProgressBar (Simone This Dot) +* ProgressBar: Display incorrect overflow behavior in Safari (Simone This Dot) +* WikimediaUI theme, demos: Unify focus outline for high contrast mode (Volker E.) +* WikimediaUI theme: Fix height of ProcessDialog's navigation bar (Volker E.) +* WikimediaUI theme: Remove unneeded `box-shadow-input-binary` variable (Volker E.) +* Apex: Remove `@supports` feature query for calc – supported in all browsers (Ed Sanders) +* styles: Remove outdated vendor properties (Volker E.) +* icons: Add 'copy'/'cut'/'paste' icons to 'editing-advanced' (Ed Sanders) + +### Code +* PageLayout: Fix documentation by moving a linebreak (Daimona Eaytoy) +* Window: Add comment justifying focus traps with inert support (Ed Sanders) +* Window: Separate out window focussing into separate method (Ed Sanders) +* WindowManager: Fix isolation logic (Ed Sanders) +* WindowManager: Fix typo insert->inert (Ed Sanders) +* WindowManager: Follow-up Ie402f807fd: Set '`inert`' on construct when required (Ed Sanders) +* WindowManager: Move var declarations inline (Ed Sanders) +* WindowManager: Simplify teardown (Ed Sanders) +* core: Move var declarations inline (Ed Sanders) +* layouts: Move var declarations inline (Ed Sanders) +* mixins: Move var declarations inline (Ed Sanders) +* styles: Rename vars to be forward-compatible with Codex tokens (Volker E.) +* widgets: Move var declarations inline (Ed Sanders) +* windows: Move var declarations inline (Ed Sanders) +* Tool*.js: Move var declarations inline (Ed Sanders) +* *ToolGroup: Move var declarations inline (Ed Sanders) +* demos: Add `autoFlip: false` to some popup demos (Bartosz Dziewoński) +* demos: Add accessible labels to everything in the toolbars demo (Bartosz Dziewoński) +* demos: Add demo for non-modal WindowManager (Ed Sanders) +* demos: Append pages to a shared `$container`, not root `$element` (Ed Sanders) +* demos: Apply desktop/mobile styles based on mode, not screen width (Ed Sanders) +* demos: Don't reload whole demo when just switching page (Ed Sanders) +* demos: Fix PHP demo styling (Ed Sanders) +* demos: Fix header width calculation (Ed Sanders) +* demos: Fix internal state when loading pages dynamically (Bartosz Dziewoński) +* demos: Fix popups overlapping fixed header (Bartosz Dziewoński) +* demos: Hide unstyled demo while CSS is loading (Ed Sanders) +* demos: Remove @supports position:fixed feature query (Ed Sanders) +* build: Update `.nvmrc` to reflect CI's node v14.7.5 (Volker E.) +* build: Updating dependencies (libraryupgrader) +* build: Updating grunt-banana-checker to 0.10.0 (libraryupgrader) +* build: Updating npm dependencies (libraryupgrader) +* build: Updating npm dependencies (libraryupgrader) +* build: Updating npm dependencies (libraryupgrader) + + ## v0.44.0 / 2022-05-06 ### Breaking changes * [BREAKING CHANGE] Drop support for IE<10, FF<38, Android<4.4 (Volker E.) diff --git a/resources/lib/ooui/i18n/bci.json b/resources/lib/ooui/i18n/bci.json new file mode 100644 index 000000000000..ea83f5e68b56 --- /dev/null +++ b/resources/lib/ooui/i18n/bci.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Kjeanclaude" + ] + }, + "ooui-outline-control-move-down": "Fa liké nga fa djra", + "ooui-outline-control-move-up": "Fa liké nga fa fou nglo", + "ooui-outline-control-remove": "Nounnoun liké nga", + "ooui-toolbar-more": "Ouflè ékun", + "ooui-toolgroup-expand": "Ouflè ékun", + "ooui-toolgroup-collapse": "Kaan sa", + "ooui-item-remove": "Yi", + "ooui-dialog-message-accept": "Kpli'n sou", + "ooui-dialog-message-reject": "Nan yé i koun", + "ooui-dialog-process-dismiss": "Djasso sou", + "ooui-dialog-process-retry": "Yé i ékoun", + "ooui-dialog-process-continue": "Yé i ékoun", + "ooui-selectfile-button-select": "Fa floua koun", + "ooui-selectfile-button-select-multiple": "Fa floua moun", + "ooui-selectfile-not-supported": "Bé kpli'n man sou kè bé fa floua wafan", + "ooui-selectfile-placeholder": "Ba faman floua vié fi", + "ooui-selectfile-dragdrop-placeholder": "Man floua sou sié i wa", + "ooui-selectfile-dragdrop-placeholder-multiple": "Man floua mé sou sié bé wa", + "ooui-popup-widget-close-button-aria-label": "Gni", + "ooui-field-help": "Oukalè" +} diff --git a/resources/lib/ooui/i18n/ckb.json b/resources/lib/ooui/i18n/ckb.json index ffdd6a3bfc79..a0920d4e5238 100644 --- a/resources/lib/ooui/i18n/ckb.json +++ b/resources/lib/ooui/i18n/ckb.json @@ -1,23 +1,32 @@ { "@metadata": { "authors": [ + "Aram", "Calak", "Muhammed taha", "Pirehelokan", "Sarchia", - "Serwan" + "Serwan", + "ئارام بکر" ] }, "ooui-toolbar-more": "زیاتر", "ooui-toolgroup-expand": "زیاتر", "ooui-toolgroup-collapse": "کەمتر", + "ooui-item-remove": "لابردن", "ooui-dialog-message-accept": "باشە", "ooui-dialog-message-reject": "پاشگەزبوونەوە", "ooui-dialog-process-error": "ھەڵەیەک ڕووی داوە", "ooui-dialog-process-dismiss": "لێگەڕان", "ooui-dialog-process-retry": "دیسان ھەوڵ بدە", "ooui-dialog-process-continue": "درێژە بدە", + "ooui-combobox-button-label": "ھەڵبژاردەکانی زمانە", "ooui-selectfile-button-select": "پەڕگەیەک دەستنیشان بکە", + "ooui-selectfile-button-select-multiple": "پەڕگەکان ھەڵبژێرە", + "ooui-selectfile-not-supported": "ھەڵبژاردنی پەڕگە پشتگیریی لێ ناکرێت", "ooui-selectfile-placeholder": "ھیچ فایلێک ھەڵنەبژێراوە", - "ooui-selectfile-dragdrop-placeholder": "پەڕگەکان بخەرە ئێرە" + "ooui-selectfile-dragdrop-placeholder": "پەڕگەکان بخەرە ئێرە", + "ooui-selectfile-dragdrop-placeholder-multiple": "پەڕگەکان بخەرە ئێرە", + "ooui-popup-widget-close-button-aria-label": "دای بخە", + "ooui-field-help": "یارمەتی" } diff --git a/resources/lib/ooui/i18n/fat.json b/resources/lib/ooui/i18n/fat.json new file mode 100644 index 000000000000..69537ddbdca0 --- /dev/null +++ b/resources/lib/ooui/i18n/fat.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Ebenoffen1", + "Emmanuel Bans" + ] + }, + "ooui-outline-control-move-down": "Fa adze no kɔ ase", + "ooui-outline-control-move-up": "Fa kɔ sor", + "ooui-outline-control-remove": "Yi ndzɛmba no", + "ooui-toolbar-more": "Beberee", + "ooui-toolgroup-expand": "Beberee", + "ooui-toolgroup-collapse": "Ketseaba", + "ooui-item-remove": "Yi", + "ooui-dialog-message-accept": "Nyoo", + "ooui-dialog-message-reject": "Twa mu", + "ooui-dialog-process-error": "Biribi annkɔ yie", + "ooui-dialog-process-dismiss": "Bɔ gu", + "ooui-dialog-process-retry": "Yɛ bio", + "ooui-dialog-process-continue": "Tua do", + "ooui-combobox-button-label": "Ma nkyerɛkyerɛmu no mbra", + "ooui-selectfile-button-select": "Yi fael bi", + "ooui-selectfile-button-select-multiple": "Yi files nu", + "ooui-selectfile-not-supported": "Yɛnngye fael yi nnto mu", + "ooui-selectfile-placeholder": "Innyii fael biara", + "ooui-selectfile-dragdrop-placeholder": "Fa fael no to ha", + "ooui-selectfile-dragdrop-placeholder-multiple": "Fa fael ahorow to ha", + "ooui-popup-widget-close-button-aria-label": "Tow mu", + "ooui-field-help": "Mboa" +} diff --git a/resources/lib/ooui/i18n/hi.json b/resources/lib/ooui/i18n/hi.json index 1c95515418cb..d3ba51948e12 100644 --- a/resources/lib/ooui/i18n/hi.json +++ b/resources/lib/ooui/i18n/hi.json @@ -9,26 +9,31 @@ "Prong$31", "Rajesh", "Rishi.Singh", + "Saurmandal", "Sfic", "Siddhartha Ghai" ] }, - "ooui-outline-control-move-down": "प्रविष्टि नीचे ले जाएँ", - "ooui-outline-control-move-up": "प्रविष्टि ऊपर ले जाएँ", - "ooui-outline-control-remove": "आइटम हटाएँ", + "ooui-outline-control-move-down": "आयटम को नीचे ले जाएँ", + "ooui-outline-control-move-up": "आयटम को ऊपर ले जाएँ", + "ooui-outline-control-remove": "आयटम को हटाएँ", "ooui-toolbar-more": "अधिक", "ooui-toolgroup-expand": "अधिक", "ooui-toolgroup-collapse": "कम", - "ooui-item-remove": "हटायें", + "ooui-item-remove": "हटाएँ", "ooui-dialog-message-accept": "ठीक है", "ooui-dialog-message-reject": "रद्द करें", - "ooui-dialog-process-error": "कुछ गलत हुअा है", - "ooui-dialog-process-dismiss": "ख़ारिज करें", - "ooui-dialog-process-retry": "पुनः प्रयास करें", + "ooui-dialog-process-error": "कोई त्रुटि आई", + "ooui-dialog-process-dismiss": "रद्द करें", + "ooui-dialog-process-retry": "दोबारा कोशिश करें", "ooui-dialog-process-continue": "जारी रखें", + "ooui-combobox-button-label": "विकल्प बदलें", "ooui-selectfile-button-select": "फ़ाइल चुनें", + "ooui-selectfile-button-select-multiple": "फ़ाइलें चुनें", "ooui-selectfile-not-supported": "फ़ाइल का चयन समर्थित नहीं है", - "ooui-selectfile-placeholder": "कोई फाइल चुनी नही गई हेै", + "ooui-selectfile-placeholder": "कोई फ़ाइल चुनी नहीं गई है", "ooui-selectfile-dragdrop-placeholder": "फ़ाइल यहाँ डालें", + "ooui-selectfile-dragdrop-placeholder-multiple": "फ़ाइलों को यहाँ डालें", + "ooui-popup-widget-close-button-aria-label": "बंद करें", "ooui-field-help": "सहायता" } diff --git a/resources/lib/ooui/i18n/ks-arab.json b/resources/lib/ooui/i18n/ks-arab.json new file mode 100644 index 000000000000..bbc561ba3188 --- /dev/null +++ b/resources/lib/ooui/i18n/ks-arab.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Iflaq" + ] + }, + "ooui-toolbar-more": "مٔزیٖد", + "ooui-toolgroup-expand": "مٔزیٖد", + "ooui-dialog-message-accept": "ٹھیٖک چھُ", + "ooui-dialog-message-reject": "مَنسوٗخ", + "ooui-dialog-process-error": "کیٚنٛہہ تام گو غَلط", + "ooui-dialog-process-dismiss": "مَنسوٗخ", + "ooui-dialog-process-continue": "جأری تھٲوِو", + "ooui-popup-widget-close-button-aria-label": "بَنٛد", + "ooui-field-help": "مَدَتھ" +} diff --git a/resources/lib/ooui/i18n/nqo.json b/resources/lib/ooui/i18n/nqo.json index 20221ed54fcf..70a56f6df81a 100644 --- a/resources/lib/ooui/i18n/nqo.json +++ b/resources/lib/ooui/i18n/nqo.json @@ -4,8 +4,8 @@ "Lancine.kounfantoh.fofana" ] }, - "ooui-outline-control-move-down": "ߝߌ߬ߛߌ ߓߴߊ߬ ߣߐ߭ ߘߐ߫ ߞߵߊ߬ ߟߊߖߌ߰ ߘߎ߰ߟߊ߫", - "ooui-outline-control-move-up": "ߝߌ߬ߛߌ ߓߴߊ߬ ߣߐ߭ ߘߐ߫ ߞߵߊ߬ ߡߊߦߟߍ߬", + "ooui-outline-control-move-down": "ߝߌ߬ߛߌ ߟߊߖߌ߰ ߘߎ߰ߟߊ߫", + "ooui-outline-control-move-up": "ߝߌ߬ߛߌ ߡߊߦߟߍ߬", "ooui-outline-control-remove": "ߝߌ߬ߛߌ ߛߋ߲߬ߓߐ߫", "ooui-toolbar-more": "ߡߊߞߊ߬ߝߏ߬ ߜߘߍ ߟߎ߬", "ooui-toolgroup-expand": "ߡߊߞߊ߬ߝߏ߬ ߜߘߍ ߟߎ߬", @@ -17,7 +17,7 @@ "ooui-dialog-process-dismiss": "ߓߙߐߕߐ߫", "ooui-dialog-process-retry": "ߊ߬ ߡߊߝߍߣߍ߲߫ ߕߎ߲߯", "ooui-dialog-process-continue": "ߊ߬ ߘߊߓߊ߲߫", - "ooui-combobox-button-label": "ߢߣߊߕߊߟߌ ߓߟߏߕߍ߰", + "ooui-combobox-button-label": "ߢߣߊߕߊߟߌ ߟߊߦߌ߬ߙߌ߲߬ߘߌ߫", "ooui-selectfile-button-select": "ߞߐߕߐ߮ ߘߏ߫ ߓߊߕߐ߬ߡߐ߲߬", "ooui-selectfile-button-select-multiple": "ߞߐߕߐ߮ ߟߎ߬ ߓߊߕߐ߬ߡߐ߲߬", "ooui-selectfile-not-supported": "ߞߐߕߐ߮ ߓߊߕߐߡߐ߲ߠߌ߲ ߟߊߘߌ߬ߢߍ߬ߣߍ߲߬ ߕߍ߫", diff --git a/resources/lib/ooui/i18n/rsk.json b/resources/lib/ooui/i18n/rsk.json new file mode 100644 index 000000000000..a32ba264399e --- /dev/null +++ b/resources/lib/ooui/i18n/rsk.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Keresturec" + ] + }, + "ooui-outline-control-move-down": "Премесц предмет долу", + "ooui-outline-control-move-up": "Премесц предмет горе", + "ooui-outline-control-remove": "Одстрань предмет", + "ooui-toolbar-more": "Вецей", + "ooui-toolgroup-expand": "Вецей", + "ooui-toolgroup-collapse": "Менше", + "ooui-item-remove": "Одстрань", + "ooui-dialog-message-accept": "У порядку", + "ooui-dialog-message-reject": "Одкаж", + "ooui-dialog-process-error": "Цошка нє у шоре", + "ooui-dialog-process-dismiss": "Одруц", + "ooui-dialog-process-retry": "Пробуй ознова", + "ooui-dialog-process-continue": "Предлуж", + "ooui-combobox-button-label": "Преруц опциї", + "ooui-selectfile-button-select": "Воберце файл", + "ooui-selectfile-button-select-multiple": "Воберце файли", + "ooui-selectfile-not-supported": "Вивор файла нє потримани", + "ooui-selectfile-placeholder": "Файл нє вибрани", + "ooui-selectfile-dragdrop-placeholder": "Унєшце файл ту", + "ooui-selectfile-dragdrop-placeholder-multiple": "Унєшце файли ту", + "ooui-popup-widget-close-button-aria-label": "Заври", + "ooui-field-help": "Помоц" +} diff --git a/resources/lib/ooui/i18n/ru.json b/resources/lib/ooui/i18n/ru.json index 8a8a95d82057..822a9b90992e 100644 --- a/resources/lib/ooui/i18n/ru.json +++ b/resources/lib/ooui/i18n/ru.json @@ -17,6 +17,7 @@ "Niklem", "Okras", "Ole Yves", + "Pacha Tchernof", "Putnik", "Stjn", "Sunpriat", @@ -42,7 +43,7 @@ "ooui-selectfile-button-select": "Выберите файл", "ooui-selectfile-button-select-multiple": "Выберите файлы", "ooui-selectfile-not-supported": "Выбор файла не поддерживается", - "ooui-selectfile-placeholder": "Не выбран файл", + "ooui-selectfile-placeholder": "Файл не выбран", "ooui-selectfile-dragdrop-placeholder": "Перетащите файл сюда", "ooui-selectfile-dragdrop-placeholder-multiple": "Перетащите файлы сюда", "ooui-popup-widget-close-button-aria-label": "Закрыть", diff --git a/resources/lib/ooui/i18n/rw.json b/resources/lib/ooui/i18n/rw.json new file mode 100644 index 000000000000..09bcef5c6e0e --- /dev/null +++ b/resources/lib/ooui/i18n/rw.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Germain92" + ] + }, + "ooui-outline-control-move-down": "Shyira ikintu hasi", + "ooui-outline-control-move-up": "Shyira ikintu hejuru", + "ooui-outline-control-remove": "Kuraho ikintu", + "ooui-toolbar-more": "Ibindi", + "ooui-toolgroup-expand": "Ibindi", + "ooui-toolgroup-collapse": "Bike", + "ooui-item-remove": "Kuraho", + "ooui-dialog-message-accept": "Yego", + "ooui-dialog-message-reject": "Guhagarika", + "ooui-dialog-process-error": "Hari ikintu kitagenze neza", + "ooui-dialog-process-dismiss": "Kwirukana", + "ooui-dialog-process-retry": "Ongera ugerageze", + "ooui-dialog-process-continue": "Komeza", + "ooui-combobox-button-label": "Hindura amahitamo", + "ooui-selectfile-button-select": "Hitamo dosiye", + "ooui-selectfile-button-select-multiple": "Hitamo dosiye", + "ooui-selectfile-not-supported": "Guhitamo Dosiye ntago bishyigikiwe", + "ooui-selectfile-placeholder": "Nta dosiye yatoranyijwe", + "ooui-selectfile-dragdrop-placeholder": "Shyira dosiye hano", + "ooui-selectfile-dragdrop-placeholder-multiple": "Shyira dosiye hano", + "ooui-popup-widget-close-button-aria-label": "Funga", + "ooui-field-help": "Ubufasha" +} diff --git a/resources/lib/ooui/i18n/tdd.json b/resources/lib/ooui/i18n/tdd.json new file mode 100644 index 000000000000..c8e2c92c53b1 --- /dev/null +++ b/resources/lib/ooui/i18n/tdd.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "咽頭べさ" + ] + }, + "ooui-outline-control-move-down": "ᥑᥣᥭᥳᥘᥨᥒᥰᥚᥣᥭᥱᥖᥬᥲ", + "ooui-outline-control-move-up": "ᥑᥣᥭᥳᥑᥪᥢᥲᥚᥣᥭᥱᥢᥫᥴ", + "ooui-outline-control-remove": "ᥗᥩᥢᥴᥙᥦᥖᥲ ᥟᥢᥴᥑᥝᥲᥙᥣᥰ", + "ooui-toolbar-more": "ᥢᥛᥴᥘᥫᥴ", + "ooui-toolgroup-expand": "ᥢᥛᥴᥘᥫᥴ", + "ooui-toolgroup-collapse": "ᥟᥥᥱᥘᥫᥴ", + "ooui-dialog-message-accept": "ᥟᥨᥝᥱᥑᥥᥱ", + "ooui-dialog-message-reject": "ᥟᥛᥱᥞᥥᥖᥰ", + "ooui-dialog-process-error": "ᥔᥥᥴᥟᥢᥴᥟᥢᥴᥚᥤᥖᥰᥙᥫᥒᥲᥝᥭᥳ", + "ooui-dialog-process-dismiss": "ᥘᥨᥖᥰᥐᥣᥢᥴ", + "ooui-dialog-process-retry": "ᥑᥖᥰᥓᥬᥴᥗᥦᥒᥲ", + "ooui-dialog-process-continue": "ᥔᥪᥙᥱᥢᥣᥲ", + "ooui-selectfile-button-select": "ᥘᥫᥐᥲᥜᥣᥭᥱ", + "ooui-selectfile-not-supported": "ᥘᥩᥒᥲᥘᥫᥐᥲᥚᥣᥭᥱᥢᥭᥳ ᥟᥛᥱᥐᥛᥳᥗᥦᥛᥴᥝᥭᥳᥙᥢᥴ", + "ooui-selectfile-placeholder": "ᥟᥛᥱᥘᥭᥲᥘᥫᥐᥲ ᥜᥣᥭᥱᥔᥒᥴᥝᥭᥳ", + "ooui-selectfile-dragdrop-placeholder": "ᥟᥝᥴᥜᥣᥭᥱ ᥔᥬᥱᥖᥤᥲᥢᥭᥳ", + "ooui-popup-widget-close-button-aria-label": "ᥞᥙᥰ", + "ooui-field-help": "ᥓᥩᥭᥲᥗᥦᥛᥴ" +} diff --git a/resources/lib/ooui/i18n/tum.json b/resources/lib/ooui/i18n/tum.json new file mode 100644 index 000000000000..6df647e8b859 --- /dev/null +++ b/resources/lib/ooui/i18n/tum.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Tumbuka Arch" + ] + }, + "ooui-outline-control-move-down": "Sendezga chinthu pasi", + "ooui-outline-control-move-up": "Sendezga chinthu mchanya", + "ooui-outline-control-remove": "Uskapo chinthu", + "ooui-toolbar-more": "Vinandi", + "ooui-toolgroup-expand": "Vinandi", + "ooui-toolgroup-collapse": "Vidoko", + "ooui-item-remove": "Uskapo", + "ooui-dialog-message-accept": "Enya", + "ooui-dialog-message-reject": "Leka", + "ooui-dialog-process-error": "Chinyake changunangika", + "ooui-dialog-process-dismiss": "Uskapo", + "ooui-dialog-process-retry": "Yezganiso", + "ooui-dialog-process-continue": "Pitilizga", + "ooui-combobox-button-label": "Oneska visankho", + "ooui-selectfile-button-select": "Sankhani chinthu", + "ooui-selectfile-button-select-multiple": "Sankhani vinthu", + "ooui-selectfile-not-supported": "Kusankha chinthu kulije dankha", + "ooui-selectfile-placeholder": "Palije icho chasankhika", + "ooui-selectfile-dragdrop-placeholder": "Ikani chinthu pano", + "ooui-selectfile-dragdrop-placeholder-multiple": "Ikani vinthu pano", + "ooui-popup-widget-close-button-aria-label": "Jala", + "ooui-field-help": "Wowili" +} diff --git a/resources/lib/ooui/i18n/yue.json b/resources/lib/ooui/i18n/yue.json index d29ed35e7a28..6559a62d4cb4 100644 --- a/resources/lib/ooui/i18n/yue.json +++ b/resources/lib/ooui/i18n/yue.json @@ -6,6 +6,7 @@ "Ktchankt", "Moon0319", "Shinjiman", + "Sun8908", "William915" ] }, @@ -24,5 +25,6 @@ "ooui-selectfile-button-select": "揀快勞", "ooui-selectfile-not-supported": "未有文件選擇功能", "ooui-selectfile-placeholder": "無揀到文件", - "ooui-selectfile-dragdrop-placeholder": "放快勞響度" + "ooui-selectfile-dragdrop-placeholder": "放快勞響度", + "ooui-selectfile-dragdrop-placeholder-multiple": "拖檔案來呢道" } diff --git a/resources/lib/ooui/oojs-ui-apex.js b/resources/lib/ooui/oojs-ui-apex.js index 0b308652421d..c70635a32d18 100644 --- a/resources/lib/ooui/oojs-ui-apex.js +++ b/resources/lib/ooui/oojs-ui-apex.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.44.0 + * OOUI v0.44.1 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2022 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2022-05-17T17:50:55Z + * Date: 2022-07-13T13:25:47Z */ ( function ( OO ) { diff --git a/resources/lib/ooui/oojs-ui-core-apex.css b/resources/lib/ooui/oojs-ui-core-apex.css index 6aceb52292e9..e4ccef40f283 100644 --- a/resources/lib/ooui/oojs-ui-core-apex.css +++ b/resources/lib/ooui/oojs-ui-core-apex.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.44.0 + * OOUI v0.44.1 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2022 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2022-05-17T17:51:03Z + * Date: 2022-07-13T13:25:55Z */ .oo-ui-element-hidden { display: none !important; @@ -71,7 +71,6 @@ } .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon { transition: opacity 250ms; - -webkit-transform: translateZ(0); transform: translateZ(0); } .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { @@ -228,7 +227,6 @@ .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button, .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button { opacity: 0.5; - -webkit-transform: translateZ(0); transform: translateZ(0); box-shadow: none; color: #333; @@ -358,24 +356,19 @@ .oo-ui-fieldLayout:after { clear: both; } -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body:after, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body:after { - content: ' '; - display: block; - clear: both; +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body, +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body { + display: flex; +} +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { + width: 60%; + flex-shrink: 0; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { word-wrap: break-word; -} -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { - display: block; - float: left; + flex-grow: 1; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { text-align: right; @@ -411,21 +404,13 @@ .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help { margin-right: 0; - margin-left: -2.5em; -} -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { - width: 60%; -} -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { - margin-right: 5%; - width: 35%; + margin-left: -0.5em; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label { display: block; padding-top: 0.5em; + margin-right: 0.5em; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline { margin-top: 1em; @@ -1597,6 +1582,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-progressBarWidget { box-sizing: border-box; + position: relative; + z-index: 1; max-width: 50em; border: 1px solid #ccc; border-radius: 3px; @@ -1613,9 +1600,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { transition: width 250ms; } .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar { - width: 40%; + width: 33%; border-left: 1px solid #ccc; - animation: oo-ui-progressBarWidget-slide 2s infinite linear; + animation: oo-ui-progressBarWidget-slide 1.6s infinite linear; transform: translate(-25%); } .oo-ui-progressBarWidget.oo-ui-widget-disabled { @@ -1626,7 +1613,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { transform: translate(-100%); } to { - transform: translate 350%; + transform: translate(300%); } } diff --git a/resources/lib/ooui/oojs-ui-core-wikimediaui.css b/resources/lib/ooui/oojs-ui-core-wikimediaui.css index 91e32e3d6d2d..6380829896e4 100644 --- a/resources/lib/ooui/oojs-ui-core-wikimediaui.css +++ b/resources/lib/ooui/oojs-ui-core-wikimediaui.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.44.0 + * OOUI v0.44.1 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2022 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2022-05-17T17:51:03Z + * Date: 2022-07-13T13:25:55Z */ .oo-ui-element-hidden { display: none !important; @@ -69,7 +69,6 @@ } .oo-ui-buttonElement.oo-ui-iconElement .oo-ui-iconElement-icon, .oo-ui-buttonElement.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator { - -webkit-transform: translateZ(0); transform: translateZ(0); } .oo-ui-buttonElement.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator, @@ -463,24 +462,19 @@ .oo-ui-fieldLayout:after { clear: both; } -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body:after, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body:after { - content: ' '; - display: block; - clear: both; +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body, +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body { + display: flex; +} +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, +.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { + width: 60%; + flex-shrink: 0; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { word-wrap: break-word; -} -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, -.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { - display: block; - float: left; + flex-grow: 1; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { text-align: right; @@ -529,25 +523,16 @@ .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body { max-width: 50em; } -.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header, -.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { - box-sizing: border-box; - width: 40%; - padding-right: 2.64285714em; -} .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label, .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label { display: block; padding-top: 4px; + margin-right: 6px; } .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help { margin-right: 0; - margin-left: -2.35714286em; -} -.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, -.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { - width: 60%; + margin-left: -6px; } .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header { padding-top: 0; @@ -1097,7 +1082,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupWidget { /* stylelint-disable-next-line plugin/no-unsupported-browser-features */ filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.3)); - -webkit-transform: translateZ(0); transform: translateZ(0); } .oo-ui-popupWidget-popup { @@ -1408,7 +1392,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus { border-color: #36c; - outline: 0; + outline: 1px solid transparent; box-shadow: inset 0 0 0 1px #36c; } .oo-ui-dropdownInputWidget.oo-ui-widget-disabled { @@ -1655,8 +1639,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { opacity: 1; } .oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:focus { - outline: 0; border-color: #36c; + outline: 1px solid transparent; box-shadow: inset 0 0 0 1px #36c; } .oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:focus ~ .oo-ui-iconElement-icon, @@ -1846,7 +1830,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:focus { border-color: #36c; - outline: 0; + outline: 1px solid transparent; box-shadow: inset 0 0 0 1px #36c; } .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon, @@ -2005,6 +1989,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-progressBarWidget { box-sizing: border-box; + position: relative; + z-index: 1; max-width: 50em; border: 1px solid #a2a9b1; border-radius: 1em; @@ -2019,8 +2005,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { transition: width 100ms; } .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar { - animation: oo-ui-progressBarWidget-slide 2s infinite linear; - width: 40%; + animation: oo-ui-progressBarWidget-slide 1.6s infinite linear; + width: 33%; transform: translate(-25%); } .oo-ui-progressBarWidget.oo-ui-widget-enabled .oo-ui-progressBarWidget-bar { @@ -2034,7 +2020,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { transform: translate(-100%); } to { - transform: translate(350%); + transform: translate(300%); } } diff --git a/resources/lib/ooui/oojs-ui-core.js b/resources/lib/ooui/oojs-ui-core.js index 4b27fe10aec8..c9b71eb466a1 100644 --- a/resources/lib/ooui/oojs-ui-core.js +++ b/resources/lib/ooui/oojs-ui-core.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.44.0 + * OOUI v0.44.1 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2022 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2022-05-17T17:50:55Z + * Date: 2022-07-13T13:25:47Z */ ( function ( OO ) { @@ -79,8 +79,7 @@ OO.ui.generateElementId = function () { * @return {boolean} Element is focusable */ OO.ui.isFocusableElement = function ( $element ) { - var nodeName, - element = $element[ 0 ]; + var element = $element[ 0 ]; // Anything disabled is not focusable if ( element.disabled ) { @@ -113,7 +112,7 @@ OO.ui.isFocusableElement = function ( $element ) { // Some element types are naturally focusable // (indexOf is much faster than regex in Chrome and about the // same in FF: https://jsperf.com/regex-vs-indexof-array2) - nodeName = element.nodeName.toLowerCase(); + var nodeName = element.nodeName.toLowerCase(); if ( [ 'input', 'select', 'textarea', 'button', 'object' ].indexOf( nodeName ) !== -1 ) { return true; } @@ -177,15 +176,13 @@ OO.ui.getUserLanguages = function () { * @return {Mixed} Local value */ OO.ui.getLocalValue = function ( obj, lang, fallback ) { - var i, len, langs; - // Requested language if ( obj[ lang ] ) { return obj[ lang ]; } // Known user language - langs = OO.ui.getUserLanguages(); - for ( i = 0, len = langs.length; i < len; i++ ) { + var langs = OO.ui.getUserLanguages(); + for ( var i = 0, len = langs.length; i < len; i++ ) { lang = langs[ i ]; if ( obj[ lang ] ) { return obj[ lang ]; @@ -217,11 +214,10 @@ OO.ui.getLocalValue = function ( obj, lang, fallback ) { * @return {boolean} The node is in the list of target nodes */ OO.ui.contains = function ( containers, contained, matchContainers ) { - var i; if ( !Array.isArray( containers ) ) { containers = [ containers ]; } - for ( i = containers.length - 1; i >= 0; i-- ) { + for ( var i = containers.length - 1; i >= 0; i-- ) { if ( ( matchContainers && contained === containers[ i ] ) || $.contains( containers[ i ], contained ) @@ -354,12 +350,11 @@ OO.ui.infuse = function ( node, config ) { * [jQuery.i18n](https://github.com/wikimedia/jquery.i18n) follows. * * @example - * var i, iLen, button, - * messagePath = 'oojs-ui/dist/i18n/', + * var messagePath = 'oojs-ui/dist/i18n/', * languages = [ $.i18n().locale, 'ur', 'en' ], * languageMap = {}; * - * for ( i = 0, iLen = languages.length; i < iLen; i++ ) { + * for ( var i = 0, iLen = languages.length; i < iLen; i++ ) { * languageMap[ languages[ i ] ] = messagePath + languages[ i ].toLowerCase() + '.json'; * } * @@ -371,7 +366,7 @@ OO.ui.infuse = function ( node, config ) { * OO.ui.msg = $.i18n; * * // A button displaying "OK" in the default locale - * button = new OO.ui.ButtonWidget( { + * var button = new OO.ui.ButtonWidget( { * label: OO.ui.msg( 'ooui-dialog-message-accept' ), * icon: 'check' * } ); @@ -446,13 +441,12 @@ OO.ui.resolveMsg = function ( msg ) { */ OO.ui.isSafeUrl = function ( url ) { // Keep this function in sync with php/Tag.php - var i, protocolAllowList; function stringStartsWith( haystack, needle ) { return haystack.slice( 0, needle.length ) === needle; } - protocolAllowList = [ + var protocolAllowList = [ 'bitcoin', 'ftp', 'ftps', 'geo', 'git', 'gopher', 'http', 'https', 'irc', 'ircs', 'magnet', 'mailto', 'mms', 'news', 'nntp', 'redis', 'sftp', 'sip', 'sips', 'sms', 'ssh', 'svn', 'tel', 'telnet', 'urn', 'worldwind', 'xmpp' @@ -462,7 +456,7 @@ OO.ui.isSafeUrl = function ( url ) { return true; } - for ( i = 0; i < protocolAllowList.length; i++ ) { + for ( var i = 0; i < protocolAllowList.length; i++ ) { if ( stringStartsWith( url, protocolAllowList[ i ] + ':' ) ) { return true; } @@ -605,8 +599,6 @@ OO.ui.mixin = {}; * Data can also be specified with the #setData method. */ OO.ui.Element = function OoUiElement( config ) { - var doc; - if ( OO.ui.isDemo ) { this.initialConfig = config; } @@ -622,7 +614,7 @@ OO.ui.Element = function OoUiElement( config ) { this.elementGroup = null; // Initialization - doc = OO.ui.Element.static.getDocument( this.$element ); + var doc = OO.ui.Element.static.getDocument( this.$element ); if ( Array.isArray( config.classes ) ) { this.$element.addClass( // Remove empty strings to work around jQuery bug @@ -721,8 +713,7 @@ OO.ui.Element.static.infuse = function ( node, config ) { */ OO.ui.Element.static.unsafeInfuse = function ( elem, config, domPromise ) { // look for a cached result of a previous infusion. - var data, cls, parts, obj, top, state, infusedChildren, doc, id, - $elem = $( elem ); + var $elem = $( elem ); if ( $elem.length > 1 ) { throw new Error( 'Collection contains more than one element' ); @@ -734,9 +725,9 @@ OO.ui.Element.static.unsafeInfuse = function ( elem, config, domPromise ) { $elem = $elem[ 0 ].$oouiInfused; } - id = $elem.attr( 'id' ); - doc = this.getDocument( $elem ); - data = $elem.data( 'ooui-infused' ); + var id = $elem.attr( 'id' ); + var doc = this.getDocument( $elem ); + var data = $elem.data( 'ooui-infused' ); if ( data ) { // cached! if ( data === true ) { @@ -744,13 +735,13 @@ OO.ui.Element.static.unsafeInfuse = function ( elem, config, domPromise ) { } if ( domPromise ) { // Pick up dynamic state, like focus, value of form inputs, scroll position, etc. - state = data.constructor.static.gatherPreInfuseState( $elem, data ); + var stateCache = data.constructor.static.gatherPreInfuseState( $elem, data ); // Restore dynamic state after the new element is re-inserted into DOM under // infused parent. - domPromise.done( data.restorePreInfuseState.bind( data, state ) ); - infusedChildren = $elem.data( 'ooui-infused-children' ); - if ( infusedChildren && infusedChildren.length ) { - infusedChildren.forEach( function ( childData ) { + domPromise.done( data.restorePreInfuseState.bind( data, stateCache ) ); + var infusedChildrenCache = $elem.data( 'ooui-infused-children' ); + if ( infusedChildrenCache && infusedChildrenCache.length ) { + infusedChildrenCache.forEach( function ( childData ) { var childState = childData.constructor.static.gatherPreInfuseState( $elem, childData @@ -779,20 +770,21 @@ OO.ui.Element.static.unsafeInfuse = function ( elem, config, domPromise ) { // Special case: this is a raw Tag; wrap existing node, don't rebuild. return new OO.ui.Element( $.extend( {}, config, { $element: $elem } ) ); } - parts = data._.split( '.' ); - cls = OO.getProp.apply( OO, [ window ].concat( parts ) ); + var parts = data._.split( '.' ); + var cls = OO.getProp.apply( OO, [ window ].concat( parts ) ); if ( !( cls && ( cls === OO.ui.Element || cls.prototype instanceof OO.ui.Element ) ) ) { throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ ); } + var top; if ( !domPromise ) { top = $.Deferred(); domPromise = top.promise(); } $elem.data( 'ooui-infused', true ); // prevent loops data.id = id; // implicit - infusedChildren = []; + var infusedChildren = []; data = OO.copy( data, null, function deserialize( value ) { var infused; if ( OO.isPlainObject( value ) ) { @@ -817,10 +809,10 @@ OO.ui.Element.static.unsafeInfuse = function ( elem, config, domPromise ) { // allow widgets to reuse parts of the DOM data = cls.static.reusePreInfuseDOM( $elem[ 0 ], data ); // pick up dynamic state, like focus, value of form inputs, scroll position, etc. - state = cls.static.gatherPreInfuseState( $elem[ 0 ], data ); + var state = cls.static.gatherPreInfuseState( $elem[ 0 ], data ); // rebuild widget // eslint-disable-next-line new-cap - obj = new cls( $.extend( {}, config, data ) ); + var obj = new cls( $.extend( {}, config, data ) ); // If anyone is holding a reference to the old DOM element, // let's allow them to OO.ui.infuse() it and do what they expect, see T105828. // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design. @@ -921,13 +913,11 @@ OO.ui.Element.static.getWindow = function ( obj ) { * @return {string} Text direction, either 'ltr' or 'rtl' */ OO.ui.Element.static.getDir = function ( obj ) { - var isDoc, isWin; - if ( obj instanceof $ ) { obj = obj[ 0 ]; } - isDoc = obj.nodeType === Node.DOCUMENT_NODE; - isWin = obj.document !== undefined; + var isDoc = obj.nodeType === Node.DOCUMENT_NODE; + var isWin = obj.document !== undefined; if ( isDoc || isWin ) { if ( isWin ) { obj = obj.document; @@ -949,8 +939,6 @@ OO.ui.Element.static.getDir = function ( obj ) { * @return {Object} Offset object, containing left and top properties */ OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) { - var i, len, frames, frame, rect; - if ( !to ) { to = window; } @@ -962,8 +950,9 @@ OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) { } // Get iframe element - frames = from.parent.document.getElementsByTagName( 'iframe' ); - for ( i = 0, len = frames.length; i < len; i++ ) { + var frame; + var frames = from.parent.document.getElementsByTagName( 'iframe' ); + for ( var i = 0, len = frames.length; i < len; i++ ) { if ( frames[ i ].contentWindow === from ) { frame = frames[ i ]; break; @@ -972,7 +961,7 @@ OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) { // Recursively accumulate offset values if ( frame ) { - rect = frame.getBoundingClientRect(); + var rect = frame.getBoundingClientRect(); offset.left += rect.left; offset.top += rect.top; if ( from !== to ) { @@ -994,19 +983,18 @@ OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) { * @return {Object} Translated position coordinates, containing top and left properties */ OO.ui.Element.static.getRelativePosition = function ( $element, $anchor ) { - var iframe, iframePos, - pos = $element.offset(), + var pos = $element.offset(), anchorPos = $anchor.offset(), elementDocument = this.getDocument( $element ), anchorDocument = this.getDocument( $anchor ); // If $element isn't in the same document as $anchor, traverse up while ( elementDocument !== anchorDocument ) { - iframe = elementDocument.defaultView.frameElement; + var iframe = elementDocument.defaultView.frameElement; if ( !iframe ) { throw new Error( '$element frame is not contained in $anchor frame' ); } - iframePos = $( iframe ).offset(); + var iframePos = $( iframe ).offset(); pos.left += iframePos.left; pos.top += iframePos.top; elementDocument = this.getDocument( iframe ); @@ -1049,12 +1037,11 @@ OO.ui.Element.static.getBorders = function ( el ) { * @return {Object} Dimensions object with `borders`, `scroll`, `scrollbar` and `rect` properties */ OO.ui.Element.static.getDimensions = function ( el ) { - var $el, $win, - doc = this.getDocument( el ), + var doc = this.getDocument( el ), win = doc.defaultView; if ( win === el || el === doc.documentElement ) { - $win = $( win ); + var $win = $( win ); return { borders: { top: 0, left: 0, bottom: 0, right: 0 }, scroll: { @@ -1070,7 +1057,7 @@ OO.ui.Element.static.getDimensions = function ( el ) { } }; } else { - $el = $( el ); + var $el = $( el ); return { borders: this.getBorders( el ), scroll: { @@ -1243,12 +1230,11 @@ OO.ui.Element.static.getDimensions = function ( el ) { * @return {HTMLBodyElement|HTMLHtmlElement} Scrollable parent, `` or `` */ OO.ui.Element.static.getRootScrollableElement = function ( el ) { - var scrollTop, body, - doc = this.getDocument( el ); + var doc = this.getDocument( el ); if ( OO.ui.scrollableElement === undefined ) { - body = doc.body; - scrollTop = body.scrollTop; + var body = doc.body; + var scrollTop = body.scrollTop; body.scrollTop = 1; // In some browsers (observed in Chrome 56 on Linux Mint 18.1), @@ -1276,8 +1262,7 @@ OO.ui.Element.static.getRootScrollableElement = function ( el ) { * @return {HTMLElement} Closest scrollable container */ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) { - var i, val, - doc = this.getDocument( el ), + var doc = this.getDocument( el ), rootScrollableElement = this.getRootScrollableElement( el ), // Browsers do not correctly return the computed value of 'overflow' when 'overflow-x' and // 'overflow-y' have different values, so we need to check the separate properties. @@ -1297,9 +1282,9 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) if ( $parent[ 0 ] === rootScrollableElement ) { return $parent[ 0 ]; } - i = props.length; + var i = props.length; while ( i-- ) { - val = $parent.css( props[ i ] ); + var val = $parent.css( props[ i ] ); // We assume that elements with 'overflow' (in any direction) set to 'hidden' will // never be scrolled in that direction, but they can actually be scrolled // programatically. The user can unintentionally perform a scroll in such case even if @@ -1332,6 +1317,8 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) * @param {string} [config.duration='fast'] jQuery animation duration value * @param {string} [config.direction] Scroll in only one direction, e.g. 'x' or 'y', omit * to scroll in both directions + * @param {Object} [config.alignToTop=false] Aligns the top of the element to the top of the visible + * area of the scrollable ancestor. * @param {Object} [config.padding] Additional padding on the container to scroll past. * Object containing any of 'top', 'bottom', 'left', or 'right' as numbers. * @param {Object} [config.scrollContainer] Scroll container. Defaults to @@ -1339,37 +1326,36 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) * @return {jQuery.Promise} Promise which resolves when the scroll is complete */ OO.ui.Element.static.scrollIntoView = function ( elOrPosition, config ) { - var position, animations, container, $container, elementPosition, containerDimensions, - $window, padding, animate, method, - deferred = $.Deferred(); + var deferred = $.Deferred(); // Configuration initialization config = config || {}; - padding = $.extend( { + var padding = $.extend( { top: 0, bottom: 0, left: 0, right: 0 }, config.padding ); - animate = config.animate !== false; + var animate = config.animate !== false; - animations = {}; - elementPosition = elOrPosition instanceof HTMLElement ? + var animations = {}; + var elementPosition = elOrPosition instanceof HTMLElement ? this.getDimensions( elOrPosition ).rect : elOrPosition; - container = config.scrollContainer || ( + var container = config.scrollContainer || ( elOrPosition instanceof HTMLElement ? this.getClosestScrollableContainer( elOrPosition, config.direction ) : // No scrollContainer or element, use global document this.getClosestScrollableContainer( window.document.body ) ); - $container = $( container ); - containerDimensions = this.getDimensions( container ); - $window = $( this.getWindow( container ) ); + var $container = $( container ); + var containerDimensions = this.getDimensions( container ); + var $window = $( this.getWindow( container ) ); // Compute the element's position relative to the container + var position; if ( $container.is( 'html, body' ) ) { // If the scrollable container is the root, this is easy position = { @@ -1393,7 +1379,7 @@ OO.ui.Element.static.scrollIntoView = function ( elOrPosition, config ) { } if ( !config.direction || config.direction === 'y' ) { - if ( position.top < padding.top ) { + if ( position.top < padding.top || config.alignToTop ) { animations.scrollTop = containerDimensions.scroll.top + position.top - padding.top; } else if ( position.bottom < padding.bottom ) { animations.scrollTop = containerDimensions.scroll.top + @@ -1425,7 +1411,7 @@ OO.ui.Element.static.scrollIntoView = function ( elOrPosition, config ) { } ); } else { $container.stop( true ); - for ( method in animations ) { + for ( var method in animations ) { $container[ method ]( animations[ method ] ); } deferred.resolve(); @@ -1449,10 +1435,10 @@ OO.ui.Element.static.scrollIntoView = function ( elOrPosition, config ) { * @param {HTMLElement} el Element to reconsider the scrollbars on */ OO.ui.Element.static.reconsiderScrollbars = function ( el ) { - var i, len, scrollLeft, scrollTop, nodes = []; // Save scroll position - scrollLeft = el.scrollLeft; - scrollTop = el.scrollTop; + var scrollLeft = el.scrollLeft; + var scrollTop = el.scrollTop; + var nodes = []; // Detach all children while ( el.firstChild ) { nodes.push( el.firstChild ); @@ -1462,7 +1448,7 @@ OO.ui.Element.static.reconsiderScrollbars = function ( el ) { // eslint-disable-next-line no-void void el.offsetHeight; // Reattach all children - for ( i = 0, len = nodes.length; i < len; i++ ) { + for ( var i = 0, len = nodes.length; i < len; i++ ) { el.appendChild( nodes[ i ] ); } // Restore scroll position (no-op if scrollbars disappeared) @@ -1958,8 +1944,7 @@ OO.ui.Theme.prototype.updateElementClasses = function ( element ) { * @private */ OO.ui.Theme.prototype.updateQueuedElementClasses = function () { - var i; - for ( i = 0; i < this.elementClassesQueue.length; i++ ) { + for ( var i = 0; i < this.elementClassesQueue.length; i++ ) { this.updateElementClasses( this.elementClassesQueue[ i ] ); } // Clear the queue @@ -2155,8 +2140,6 @@ OO.ui.mixin.TabIndexedElement.prototype.getTabIndex = function () { * @return {string|null} The ID of the focusable element */ OO.ui.mixin.TabIndexedElement.prototype.getInputId = function () { - var id; - if ( !this.$tabIndexed ) { return null; } @@ -2164,7 +2147,7 @@ OO.ui.mixin.TabIndexedElement.prototype.getInputId = function () { return null; } - id = this.$tabIndexed.attr( 'id' ); + var id = this.$tabIndexed.attr( 'id' ); if ( id === undefined ) { id = OO.ui.generateElementId(); this.$tabIndexed.attr( 'id', id ); @@ -2548,10 +2531,8 @@ OO.mixinClass( OO.ui.mixin.GroupElement, OO.EmitterList ); * @param {jQuery} $group Element to use as group */ OO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) { - var i, len; - this.$group = $group; - for ( i = 0, len = this.items.length; i < len; i++ ) { + for ( var i = 0, len = this.items.length; i < len; i++ ) { this.$group.append( this.items[ i ].$element ); } }; @@ -2566,11 +2547,10 @@ OO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) { * @return {OO.ui.Element|null} Item with equivalent data, `null` if none exists */ OO.ui.mixin.GroupElement.prototype.findItemFromData = function ( data ) { - var i, len, item, - hash = OO.getHash( data ); + var hash = OO.getHash( data ); - for ( i = 0, len = this.items.length; i < len; i++ ) { - item = this.items[ i ]; + for ( var i = 0, len = this.items.length; i < len; i++ ) { + var item = this.items[ i ]; if ( hash === OO.getHash( item.getData() ) ) { return item; } @@ -2589,12 +2569,11 @@ OO.ui.mixin.GroupElement.prototype.findItemFromData = function ( data ) { * @return {OO.ui.Element[]} Items with equivalent data */ OO.ui.mixin.GroupElement.prototype.findItemsFromData = function ( data ) { - var i, len, item, - hash = OO.getHash( data ), + var hash = OO.getHash( data ), items = []; - for ( i = 0, len = this.items.length; i < len; i++ ) { - item = this.items[ i ]; + for ( var i = 0, len = this.items.length; i < len; i++ ) { + var item = this.items[ i ]; if ( hash === OO.getHash( item.getData() ) ) { items.push( item ); } @@ -2714,16 +2693,14 @@ OO.ui.mixin.GroupElement.prototype.insertItemElements = function ( itemWidget, i * @return {OO.ui.Element} The element, for chaining */ OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) { - var i, len, item, index; - if ( items.length === 0 ) { return this; } // Remove specific items elements - for ( i = 0, len = items.length; i < len; i++ ) { - item = items[ i ]; - index = this.items.indexOf( item ); + for ( var i = 0, len = items.length; i < len; i++ ) { + var item = items[ i ]; + var index = this.items.indexOf( item ); if ( index !== -1 ) { item.setElementGroup( null ); item.$element.detach(); @@ -2747,10 +2724,8 @@ OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) { * @return {OO.ui.Element} The element, for chaining */ OO.ui.mixin.GroupElement.prototype.clearItems = function () { - var i, len; - // Remove all item elements - for ( i = 0, len = this.items.length; i < len; i++ ) { + for ( var i = 0, len = this.items.length; i < len; i++ ) { this.items[ i ].setElementGroup( null ); this.items[ i ].$element.detach(); } @@ -2834,8 +2809,7 @@ OO.ui.mixin.LabelElement.static.label = null; * sub-string wrapped in highlighted span */ OO.ui.mixin.LabelElement.static.highlightQuery = function ( text, query, compare, combineMarks ) { - var i, tLen, qLen, - offset = -1, + var offset = -1, $result = $( '' ), comboLength = 0, comboMarks = '', @@ -2843,9 +2817,9 @@ OO.ui.mixin.LabelElement.static.highlightQuery = function ( text, query, compare comboMatch; if ( compare ) { - tLen = text.length; - qLen = query.length; - for ( i = 0; offset === -1 && i <= tLen - qLen; i++ ) { + var tLen = text.length; + var qLen = query.length; + for ( var i = 0; offset === -1 && i <= tLen - qLen; i++ ) { if ( compare( query, text.slice( i, i + qLen ) ) === 0 ) { offset = i; } @@ -3455,13 +3429,12 @@ OO.ui.mixin.FlaggedElement.prototype.getFlags = function () { * @fires flag */ OO.ui.mixin.FlaggedElement.prototype.clearFlags = function () { - var flag, className, - changes = {}, + var changes = {}, remove = [], classPrefix = 'oo-ui-flaggedElement-'; - for ( flag in this.flags ) { - className = classPrefix + flag; + for ( var flag in this.flags ) { + var className = classPrefix + flag; changes[ flag ] = false; delete this.flags[ flag ]; remove.push( className ); @@ -3488,12 +3461,12 @@ OO.ui.mixin.FlaggedElement.prototype.clearFlags = function () { * @fires flag */ OO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) { - var i, len, flag, className, - changes = {}, + var changes = {}, add = [], remove = [], classPrefix = 'oo-ui-flaggedElement-'; + var className, flag; if ( typeof flags === 'string' ) { className = classPrefix + flags; // Set @@ -3502,7 +3475,7 @@ OO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) { add.push( className ); } } else if ( Array.isArray( flags ) ) { - for ( i = 0, len = flags.length; i < len; i++ ) { + for ( var i = 0, len = flags.length; i < len; i++ ) { flag = flags[ i ]; className = classPrefix + flag; // Set @@ -3569,6 +3542,8 @@ OO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) { * element created by the class. * @cfg {string|Function} [title] The title text or a function that returns text. If * this config is omitted, the value of the {@link #static-title static title} property is used. + * If config for an invisible label ({@link OO.ui.mixin.LabelElement}) is present, and a title is + * omitted, the label will be used as a fallback for the title. */ OO.ui.mixin.TitledElement = function OoUiMixinTitledElement( config ) { // Configuration initialization @@ -3579,7 +3554,16 @@ OO.ui.mixin.TitledElement = function OoUiMixinTitledElement( config ) { this.title = null; // Initialization - this.setTitle( config.title !== undefined ? config.title : this.constructor.static.title ); + var title = config.title !== undefined ? config.title : this.constructor.static.title; + if ( + title === null && + config.invisibleLabel && + typeof config.label === 'string' + ) { + // If config for an invisible label is present, use this as a fallback title + title = config.label; + } + this.setTitle( title ); this.setTitledElement( config.$titled || this.$element ); }; @@ -3806,8 +3790,6 @@ OO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () { * @return {string} */ OO.ui.mixin.AccessKeyedElement.prototype.formatTitleWithAccessKey = function ( title ) { - var accessKey; - if ( !this.$accessKeyed ) { // Not initialized yet; the constructor will call updateTitle() which will rerun this // function. @@ -3815,6 +3797,7 @@ OO.ui.mixin.AccessKeyedElement.prototype.formatTitleWithAccessKey = function ( t } // Use jquery.accessKeyLabel if available to show modifiers, otherwise just display the // single key. + var accessKey; if ( $.fn.updateTooltipAccessKeys && $.fn.updateTooltipAccessKeys.getAccessKeyLabel ) { accessKey = $.fn.updateTooltipAccessKeys.getAccessKeyLabel( this.$accessKeyed[ 0 ] ); } else { @@ -4951,8 +4934,6 @@ OO.ui.mixin.FloatableElement.prototype.setHorizontalPosition = function ( positi * @return {OO.ui.Element} The element, for chaining */ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) { - var closestScrollableOfContainer; - if ( !this.$floatable || !this.$floatableContainer ) { return this; } @@ -4967,7 +4948,7 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin if ( this.positioning !== positioning ) { this.positioning = positioning; - closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( + var closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] ); // If the scrollable is the root, we have to listen to scroll events @@ -5015,13 +4996,12 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin * @return {boolean} */ OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) { - var elemRect, contRect, topEdgeInBounds, bottomEdgeInBounds, leftEdgeInBounds, - rightEdgeInBounds, startEdgeInBounds, endEdgeInBounds, viewportSpacing, - direction = $element.css( 'direction' ); + var direction = $element.css( 'direction' ); - elemRect = $element[ 0 ].getBoundingClientRect(); + var elemRect = $element[ 0 ].getBoundingClientRect(); + var contRect; if ( $container[ 0 ] === window ) { - viewportSpacing = OO.ui.getViewportSpacing(); + var viewportSpacing = OO.ui.getViewportSpacing(); contRect = { top: 0, left: 0, @@ -5036,10 +5016,11 @@ OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element contRect = $container[ 0 ].getBoundingClientRect(); } - topEdgeInBounds = elemRect.top >= contRect.top && elemRect.top <= contRect.bottom; - bottomEdgeInBounds = elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom; - leftEdgeInBounds = elemRect.left >= contRect.left && elemRect.left <= contRect.right; - rightEdgeInBounds = elemRect.right >= contRect.left && elemRect.right <= contRect.right; + var topEdgeInBounds = elemRect.top >= contRect.top && elemRect.top <= contRect.bottom; + var bottomEdgeInBounds = elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom; + var leftEdgeInBounds = elemRect.left >= contRect.left && elemRect.left <= contRect.right; + var rightEdgeInBounds = elemRect.right >= contRect.left && elemRect.right <= contRect.right; + var startEdgeInBounds, endEdgeInBounds; if ( direction === 'rtl' ) { startEdgeInBounds = rightEdgeInBounds; endEdgeInBounds = leftEdgeInBounds; @@ -5134,9 +5115,7 @@ OO.ui.mixin.FloatableElement.prototype.position = function () { * @return {Object} New position to apply with .css(). Keys are 'top', 'left', 'bottom' and 'right'. */ OO.ui.mixin.FloatableElement.prototype.computePosition = function () { - var isBody, scrollableX, scrollableY, containerPos, - horizScrollbarHeight, vertScrollbarWidth, scrollTop, scrollLeft, - newPos = { top: '', left: '', bottom: '', right: '' }, + var newPos = { top: '', left: '', bottom: '', right: '' }, direction = this.$floatableContainer.css( 'direction' ), $offsetParent = this.$floatable.offsetParent(); @@ -5145,24 +5124,24 @@ OO.ui.mixin.FloatableElement.prototype.computePosition = function () { // element, but they do work on the $offsetParent = $( $offsetParent[ 0 ].ownerDocument.body ); } - isBody = $offsetParent.is( 'body' ); - scrollableX = $offsetParent.css( 'overflow-x' ) === 'scroll' || + var isBody = $offsetParent.is( 'body' ); + var scrollableX = $offsetParent.css( 'overflow-x' ) === 'scroll' || $offsetParent.css( 'overflow-x' ) === 'auto'; - scrollableY = $offsetParent.css( 'overflow-y' ) === 'scroll' || + var scrollableY = $offsetParent.css( 'overflow-y' ) === 'scroll' || $offsetParent.css( 'overflow-y' ) === 'auto'; - vertScrollbarWidth = $offsetParent.innerWidth() - $offsetParent.prop( 'clientWidth' ); - horizScrollbarHeight = $offsetParent.innerHeight() - $offsetParent.prop( 'clientHeight' ); + var vertScrollbarWidth = $offsetParent.innerWidth() - $offsetParent.prop( 'clientWidth' ); + var horizScrollbarHeight = $offsetParent.innerHeight() - $offsetParent.prop( 'clientHeight' ); // We don't need to compute and add scrollTop and scrollLeft if the scrollable container // is the body, or if it isn't scrollable - scrollTop = scrollableY && !isBody ? + var scrollTop = scrollableY && !isBody ? $offsetParent.scrollTop() : 0; - scrollLeft = scrollableX && !isBody ? + var scrollLeft = scrollableX && !isBody ? OO.ui.Element.static.getScrollLeft( $offsetParent[ 0 ] ) : 0; // Avoid passing the to getRelativePosition(), because it won't return what we expect // if the has a margin - containerPos = isBody ? + var containerPos = isBody ? this.$floatableContainer.offset() : OO.ui.Element.static.getRelativePosition( this.$floatableContainer, $offsetParent ); containerPos.bottom = containerPos.top + this.$floatableContainer.outerHeight(); @@ -5496,16 +5475,6 @@ OO.ui.mixin.ClippableElement.prototype.getVerticalAnchorEdge = function () { * @return {OO.ui.Element} The element, for chaining */ OO.ui.mixin.ClippableElement.prototype.clip = function () { - var extraHeight, extraWidth, viewportSpacing, - desiredWidth, desiredHeight, allotedWidth, allotedHeight, - naturalWidth, naturalHeight, clipWidth, clipHeight, - $item, itemRect, $viewport, viewportRect, availableRect, - direction, vertScrollbarWidth, horizScrollbarHeight, - // Extra tolerance so that the sloppy code below doesn't result in results that are off - // by one or two pixels. (And also so that we have space to display drop shadows.) - // Chosen by fair dice roll. - buffer = 7; - if ( !this.clipping ) { // this.$clippableScrollableContainer and this.$clippableWindow are null, so the below // will fail @@ -5521,8 +5490,9 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () { return out; } - viewportSpacing = OO.ui.getViewportSpacing(); + var viewportSpacing = OO.ui.getViewportSpacing(); + var $viewport, viewportRect; if ( this.$clippableScrollableContainer.is( 'html, body' ) ) { $viewport = $( this.$clippableScrollableContainer[ 0 ].ownerDocument.body ); // Dimensions of the browser window, rather than the element! @@ -5544,9 +5514,9 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () { } // Account for scrollbar gutter - direction = $viewport.css( 'direction' ); - vertScrollbarWidth = $viewport.innerWidth() - $viewport.prop( 'clientWidth' ); - horizScrollbarHeight = $viewport.innerHeight() - $viewport.prop( 'clientHeight' ); + var direction = $viewport.css( 'direction' ); + var vertScrollbarWidth = $viewport.innerWidth() - $viewport.prop( 'clientWidth' ); + var horizScrollbarHeight = $viewport.innerHeight() - $viewport.prop( 'clientHeight' ); viewportRect.bottom -= horizScrollbarHeight; if ( direction === 'rtl' ) { viewportRect.left += vertScrollbarWidth; @@ -5554,18 +5524,21 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () { viewportRect.right -= vertScrollbarWidth; } - // Add arbitrary tolerance + // Extra tolerance so that the sloppy code below doesn't result in results that are off + // by one or two pixels. (And also so that we have space to display drop shadows.) + // Chosen by fair dice roll. + var buffer = 7; viewportRect.top += buffer; viewportRect.left += buffer; viewportRect.right -= buffer; viewportRect.bottom -= buffer; - $item = this.$clippableContainer || this.$clippable; + var $item = this.$clippableContainer || this.$clippable; - extraHeight = $item.outerHeight() - this.$clippable.outerHeight(); - extraWidth = $item.outerWidth() - this.$clippable.outerWidth(); + var extraHeight = $item.outerHeight() - this.$clippable.outerHeight(); + var extraWidth = $item.outerWidth() - this.$clippable.outerWidth(); - itemRect = $item[ 0 ].getBoundingClientRect(); + var itemRect = $item[ 0 ].getBoundingClientRect(); // Convert into a plain object itemRect = $.extend( {}, itemRect ); @@ -5582,21 +5555,21 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () { itemRect.bottom = viewportRect.bottom; } - availableRect = rectIntersection( viewportRect, itemRect ); + var availableRect = rectIntersection( viewportRect, itemRect ); - desiredWidth = Math.max( 0, availableRect.right - availableRect.left ); - desiredHeight = Math.max( 0, availableRect.bottom - availableRect.top ); + var desiredWidth = Math.max( 0, availableRect.right - availableRect.left ); + var desiredHeight = Math.max( 0, availableRect.bottom - availableRect.top ); // It should never be desirable to exceed the dimensions of the browser viewport... right? desiredWidth = Math.min( desiredWidth, document.documentElement.clientWidth - viewportSpacing.left - viewportSpacing.right ); desiredHeight = Math.min( desiredHeight, document.documentElement.clientHeight - viewportSpacing.top - viewportSpacing.right ); - allotedWidth = Math.ceil( desiredWidth - extraWidth ); - allotedHeight = Math.ceil( desiredHeight - extraHeight ); - naturalWidth = this.$clippable.prop( 'scrollWidth' ); - naturalHeight = this.$clippable.prop( 'scrollHeight' ); - clipWidth = allotedWidth < naturalWidth; - clipHeight = allotedHeight < naturalHeight; + var allotedWidth = Math.ceil( desiredWidth - extraWidth ); + var allotedHeight = Math.ceil( desiredHeight - extraHeight ); + var naturalWidth = this.$clippable.prop( 'scrollWidth' ); + var naturalHeight = this.$clippable.prop( 'scrollHeight' ); + var clipWidth = allotedWidth < naturalWidth; + var clipHeight = allotedHeight < naturalHeight; if ( clipWidth ) { // The order matters here. If overflow is not set first, Chrome displays bogus scrollbars. @@ -6009,11 +5982,9 @@ OO.ui.PopupWidget.prototype.hasAnchor = function () { * @inheritdoc */ OO.ui.PopupWidget.prototype.toggle = function ( show ) { - var change, normalHeight, oppositeHeight, normalWidth, - oppositeWidth, $firstFocusableElement, $lastFocusableElement; show = show === undefined ? !this.isVisible() : !!show; - change = show !== this.isVisible(); + var change = show !== this.isVisible(); if ( show && !this.warnedUnattached && !this.isElementAttached() ) { OO.ui.warnDeprecation( 'PopupWidget#toggle: Before calling this method, the popup must be attached to the DOM.' ); @@ -6037,8 +6008,8 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) { this.togglePositioning( show && !!this.$floatableContainer ); // Find the first and last focusable element in the popup widget - $lastFocusableElement = OO.ui.findFocusable( this.$element, true ); - $firstFocusableElement = OO.ui.findFocusable( this.$element, false ); + var $lastFocusableElement = OO.ui.findFocusable( this.$element, true ); + var $firstFocusableElement = OO.ui.findFocusable( this.$element, false ); if ( show ) { if ( this.autoClose ) { @@ -6061,13 +6032,13 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) { if ( this.isClippedVertically() || this.isFloatableOutOfView() ) { // If opening the popup in the normal direction causes it to be clipped, // open in the opposite one instead - normalHeight = this.$element.height(); + var normalHeight = this.$element.height(); this.isAutoFlipped = !this.isAutoFlipped; this.position(); if ( this.isClippedVertically() || this.isFloatableOutOfView() ) { // If that also causes it to be clipped, open in whichever direction // we have more space - oppositeHeight = this.$element.height(); + var oppositeHeight = this.$element.height(); if ( oppositeHeight < normalHeight ) { this.isAutoFlipped = !this.isAutoFlipped; this.position(); @@ -6079,7 +6050,7 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) { if ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) { // If opening the popup in the normal direction causes it to be clipped, // open in the opposite one instead - normalWidth = this.$element.width(); + var normalWidth = this.$element.width(); this.isAutoFlipped = !this.isAutoFlipped; // Due to T180173 horizontally clipped PopupWidgets have messed up // dimensions, which causes positioning to be off. Toggle clipping back and @@ -6090,7 +6061,7 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) { if ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) { // If that also causes it to be clipped, open in whichever direction // we have more space - oppositeWidth = this.$element.width(); + var oppositeWidth = this.$element.width(); if ( oppositeWidth < normalWidth ) { this.isAutoFlipped = !this.isAutoFlipped; // Due to T180173, horizontally clipped PopupWidgets have messed up @@ -6183,10 +6154,7 @@ OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) { * @inheritdoc */ OO.ui.PopupWidget.prototype.computePosition = function () { - var direction, align, vertical, start, end, near, far, sizeProp, popupSize, anchorSize, - anchorPos, anchorOffset, anchorMargin, parentPosition, positionProp, positionAdjustment, - floatablePos, offsetParentPos, containerPos, popupPosition, viewportSpacing, - popupPos = {}, + var popupPos = {}, anchorCss = { left: '', right: '', top: '', bottom: '' }, popupPositionOppositeMap = { above: 'below', @@ -6225,7 +6193,7 @@ OO.ui.PopupWidget.prototype.computePosition = function () { // Lazy-initialize $container if not specified in constructor this.$container = $( this.getClosestScrollableElementContainer() ); } - direction = this.$container.css( 'direction' ); + var direction = this.$container.css( 'direction' ); // Set height and width before we do anything else, since it might cause our measurements // to change (e.g. due to scrollbars appearing or disappearing), and it also affects centering @@ -6234,21 +6202,21 @@ OO.ui.PopupWidget.prototype.computePosition = function () { height: this.height !== null ? this.height : 'auto' } ); - align = alignMap[ direction ][ this.align ] || this.align; - popupPosition = this.popupPosition; + var align = alignMap[ direction ][ this.align ] || this.align; + var popupPosition = this.popupPosition; if ( this.isAutoFlipped ) { popupPosition = popupPositionOppositeMap[ popupPosition ]; } // If the popup is positioned before or after, then the anchor positioning is vertical, // otherwise horizontal - vertical = popupPosition === 'before' || popupPosition === 'after'; - start = vertical ? 'top' : ( direction === 'rtl' ? 'right' : 'left' ); - end = vertical ? 'bottom' : ( direction === 'rtl' ? 'left' : 'right' ); - near = vertical ? 'top' : 'left'; - far = vertical ? 'bottom' : 'right'; - sizeProp = vertical ? 'Height' : 'Width'; - popupSize = vertical ? + var vertical = popupPosition === 'before' || popupPosition === 'after'; + var start = vertical ? 'top' : ( direction === 'rtl' ? 'right' : 'left' ); + var end = vertical ? 'bottom' : ( direction === 'rtl' ? 'left' : 'right' ); + var near = vertical ? 'top' : 'left'; + var far = vertical ? 'bottom' : 'right'; + var sizeProp = vertical ? 'Height' : 'Width'; + var popupSize = vertical ? ( this.height || this.$popup.height() ) : ( this.width || this.$popup.width() ); @@ -6257,17 +6225,17 @@ OO.ui.PopupWidget.prototype.computePosition = function () { this.verticalPosition = vertical ? vPosMap[ align ] : popupPosition; // Parent method - parentPosition = OO.ui.mixin.FloatableElement.prototype.computePosition.call( this ); + var parentPosition = OO.ui.mixin.FloatableElement.prototype.computePosition.call( this ); // Find out which property FloatableElement used for positioning, and adjust that value - positionProp = vertical ? + var positionProp = vertical ? ( parentPosition.top !== '' ? 'top' : 'bottom' ) : ( parentPosition.left !== '' ? 'left' : 'right' ); // Figure out where the near and far edges of the popup and $floatableContainer are - floatablePos = this.$floatableContainer.offset(); + var floatablePos = this.$floatableContainer.offset(); floatablePos[ far ] = floatablePos[ near ] + this.$floatableContainer[ 'outer' + sizeProp ](); // Measure where the offsetParent is and compute our position based on that and parentPosition - offsetParentPos = this.$element.offsetParent()[ 0 ] === document.documentElement ? + var offsetParentPos = this.$element.offsetParent()[ 0 ] === document.documentElement ? { top: 0, left: 0 } : this.$element.offsetParent().offset(); @@ -6280,17 +6248,18 @@ OO.ui.PopupWidget.prototype.computePosition = function () { popupPos[ near ] = popupPos[ far ] - popupSize; } + var anchorOffset, positionAdjustment; if ( this.anchored ) { // Position the anchor (which is positioned relative to the popup) to point to // $floatableContainer - anchorPos = ( floatablePos[ start ] + floatablePos[ end ] ) / 2; + var anchorPos = ( floatablePos[ start ] + floatablePos[ end ] ) / 2; anchorOffset = ( start === far ? -1 : 1 ) * ( anchorPos - popupPos[ start ] ); // If the anchor is less than 2*anchorSize from either edge, move the popup to make more // space this.$anchor.width()/height() returns 0 because of the CSS trickery we use, so use // scrollWidth/Height - anchorSize = this.$anchor[ 0 ][ 'scroll' + sizeProp ]; - anchorMargin = parseFloat( this.$anchor.css( 'margin-' + start ) ); + var anchorSize = this.$anchor[ 0 ][ 'scroll' + sizeProp ]; + var anchorMargin = parseFloat( this.$anchor.css( 'margin-' + start ) ); if ( anchorOffset + anchorMargin < 2 * anchorSize ) { // Not enough space for the anchor on the start side; pull the popup startwards positionAdjustment = ( positionProp === start ? -1 : 1 ) * @@ -6307,12 +6276,12 @@ OO.ui.PopupWidget.prototype.computePosition = function () { } // Check if the popup will go beyond the edge of this.$container - containerPos = this.$container[ 0 ] === document.documentElement ? + var containerPos = this.$container[ 0 ] === document.documentElement ? { top: 0, left: 0 } : this.$container.offset(); containerPos[ far ] = containerPos[ near ] + this.$container[ 'inner' + sizeProp ](); if ( this.$container[ 0 ] === document.documentElement ) { - viewportSpacing = OO.ui.getViewportSpacing(); + var viewportSpacing = OO.ui.getViewportSpacing(); containerPos[ near ] += viewportSpacing[ near ]; containerPos[ far ] -= viewportSpacing[ far ]; } @@ -6604,15 +6573,13 @@ OO.mixinClass( OO.ui.mixin.GroupWidget, OO.ui.mixin.GroupElement ); * @return {OO.ui.Widget} The widget, for chaining */ OO.ui.mixin.GroupWidget.prototype.setDisabled = function ( disabled ) { - var i, len; - // Parent method // Note: Calling #setDisabled this way assumes this is mixed into an OO.ui.Widget OO.ui.Widget.prototype.setDisabled.call( this, disabled ); // During construction, #setDisabled is called before the OO.ui.mixin.GroupElement constructor if ( this.items ) { - for ( i = 0, len = this.items.length; i < len; i++ ) { + for ( var i = 0, len = this.items.length; i < len; i++ ) { this.items[ i ].updateDisabled(); } } @@ -7226,14 +7193,14 @@ OO.ui.SelectWidget.prototype.onMouseLeave = function () { * @param {KeyboardEvent} e Key down event */ OO.ui.SelectWidget.prototype.onDocumentKeyDown = function ( e ) { - var nextItem, - handled = false, + var handled = false, selected = this.findSelectedItems(), currentItem = this.findHighlightedItem() || ( Array.isArray( selected ) ? selected[ 0 ] : selected ), firstItem = this.getItems()[ 0 ]; + var nextItem; if ( !this.isDisabled() && this.isVisible() ) { switch ( e.keyCode ) { case OO.ui.Keys.ENTER: @@ -7593,10 +7560,10 @@ OO.ui.SelectWidget.prototype.highlightItem = function ( item ) { * @return {OO.ui.Element|null} Item with equivalent label, `null` if none exists */ OO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) { - var i, item, - len = this.items.length, + var len = this.items.length, filter = this.getItemMatcher( label, 'exact' ); + var i, item; for ( i = 0; i < len; i++ ) { item = this.items[ i ]; if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) { @@ -7817,10 +7784,10 @@ OO.ui.SelectWidget.prototype.chooseItem = function ( item ) { * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the select */ OO.ui.SelectWidget.prototype.findRelativeSelectableItem = function ( item, direction, filter ) { - var nextIndex, - increase = direction > 0 ? 1 : -1, + var increase = direction > 0 ? 1 : -1, len = this.items.length; + var nextIndex; if ( item instanceof OO.ui.OptionWidget ) { var currentIndex = this.items.indexOf( item ); nextIndex = ( currentIndex + increase + len ) % len; @@ -8319,14 +8286,15 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () { return; } - var i, item, section, sectionEmpty, - anyVisible = false; + var anyVisible = false; var showAll = !this.isVisible() || this.previouslySelectedValue === this.$input.val(), filter = showAll ? null : this.getItemMatcher( this.$input.val(), this.filterMode ); // Hide non-matching options, and also hide section headers if all options // in their section are hidden. - for ( i = 0; i < this.items.length; i++ ) { + var item; + var section, sectionEmpty; + for ( var i = 0; i < this.items.length; i++ ) { item = this.items[ i ]; if ( item instanceof OO.ui.MenuSectionOptionWidget ) { if ( section ) { @@ -8502,10 +8470,8 @@ OO.ui.MenuSelectWidget.prototype.clearItems = function () { * @inheritdoc */ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) { - var change, originalHeight, flippedHeight, selectedItem; - visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length; - change = visible !== this.isVisible(); + var change = visible !== this.isVisible(); if ( visible && !this.warnedUnattached && !this.isElementAttached() ) { OO.ui.warnDeprecation( 'MenuSelectWidget#toggle: Before calling this method, the menu must be attached to the DOM.' ); @@ -8549,14 +8515,14 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) { this.originalVerticalPosition !== 'center' ) { // If opening the menu in one direction causes it to be clipped, flip it - originalHeight = this.$element.height(); + var originalHeight = this.$element.height(); this.setVerticalPosition( this.constructor.static.flippedPositions[ this.originalVerticalPosition ] ); if ( this.isClippedVertically() || this.isFloatableOutOfView() ) { // If flipping also causes it to be clipped, open in whichever direction // we have more space - flippedHeight = this.$element.height(); + var flippedHeight = this.$element.height(); if ( originalHeight > flippedHeight ) { this.setVerticalPosition( this.originalVerticalPosition ); } @@ -8567,7 +8533,7 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) { this.$focusOwner.attr( 'aria-expanded', 'true' ); - selectedItem = this.findSelectedItem(); + var selectedItem = this.findSelectedItem(); if ( !this.multiselect && selectedItem ) { // TODO: Verify if this is even needed; This is already done on highlight changes // in SelectWidget#highlightItem, so we should just need to highlight the item @@ -8663,8 +8629,6 @@ OO.ui.MenuSelectWidget.prototype.scrollToTop = function () { * See . */ OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) { - var labelId; - // Configuration initialization config = $.extend( { indicator: 'down' }, config ); @@ -8707,7 +8671,7 @@ OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) { } ); // Initialization - labelId = OO.ui.generateElementId(); + var labelId = OO.ui.generateElementId(); this.setLabelId( labelId ); this.$label .attr( { @@ -9192,9 +9156,8 @@ OO.ui.MultiselectWidget.prototype.selectItems = function ( items ) { * @return {OO.ui.Widget} The widget, for chaining */ OO.ui.MultiselectWidget.prototype.selectItemsByData = function ( datas ) { - var items, - widget = this; - items = datas.map( function ( data ) { + var widget = this; + var items = datas.map( function ( data ) { return widget.findItemFromData( data ); } ); this.selectItems( items ); @@ -9289,10 +9252,9 @@ OO.ui.CheckboxMultioptionWidget.prototype.focus = function () { * @param {jQuery.Event} e */ OO.ui.CheckboxMultioptionWidget.prototype.onKeyDown = function ( e ) { - var - element = this.getElementGroup(), - nextItem; + var element = this.getElementGroup(); + var nextItem; if ( e.keyCode === OO.ui.Keys.LEFT || e.keyCode === OO.ui.Keys.UP ) { nextItem = element.getRelativeFocusableItem( this, -1 ); } else if ( e.keyCode === OO.ui.Keys.RIGHT || e.keyCode === OO.ui.Keys.DOWN ) { @@ -9371,12 +9333,12 @@ OO.inheritClass( OO.ui.CheckboxMultiselectWidget, OO.ui.MultiselectWidget ); * in the select. */ OO.ui.CheckboxMultiselectWidget.prototype.getRelativeFocusableItem = function ( item, direction ) { - var currentIndex, nextIndex, i, - increase = direction > 0 ? 1 : -1, + var increase = direction > 0 ? 1 : -1, len = this.items.length; + var nextIndex; if ( item ) { - currentIndex = this.items.indexOf( item ); + var currentIndex = this.items.indexOf( item ); nextIndex = ( currentIndex + increase + len ) % len; } else { // If no item is selected and moving forward, start at the beginning. @@ -9384,7 +9346,7 @@ OO.ui.CheckboxMultiselectWidget.prototype.getRelativeFocusableItem = function ( nextIndex = direction > 0 ? 0 : len - 1; } - for ( i = 0; i < len; i++ ) { + for ( var i = 0; i < len; i++ ) { item = this.items[ nextIndex ]; if ( item && !item.isDisabled() ) { return item; @@ -9400,26 +9362,25 @@ OO.ui.CheckboxMultiselectWidget.prototype.getRelativeFocusableItem = function ( * @param {jQuery.Event} e */ OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) { - var $options, lastClickedIndex, nowClickedIndex, i, direction, wasSelected, items, - $lastClicked = this.$lastClicked, + var $lastClicked = this.$lastClicked, $nowClicked = $( e.target ).closest( '.oo-ui-checkboxMultioptionWidget' ) .not( '.oo-ui-widget-disabled' ); // Allow selecting multiple options at once by Shift-clicking them if ( $lastClicked && $nowClicked.length && e.shiftKey ) { - $options = this.$group.find( '.oo-ui-checkboxMultioptionWidget' ); - lastClickedIndex = $options.index( $lastClicked ); - nowClickedIndex = $options.index( $nowClicked ); + var $options = this.$group.find( '.oo-ui-checkboxMultioptionWidget' ); + var lastClickedIndex = $options.index( $lastClicked ); + var nowClickedIndex = $options.index( $nowClicked ); // If it's the same item, either the user is being silly, or it's a fake event generated // by the browser. In either case we don't need custom handling. if ( nowClickedIndex !== lastClickedIndex ) { - items = this.items; - wasSelected = items[ nowClickedIndex ].isSelected(); - direction = nowClickedIndex > lastClickedIndex ? 1 : -1; + var items = this.items; + var wasSelected = items[ nowClickedIndex ].isSelected(); + var direction = nowClickedIndex > lastClickedIndex ? 1 : -1; // This depends on the DOM order of the items and the order of the .items array being // the same. - for ( i = lastClickedIndex; i !== nowClickedIndex; i += direction ) { + for ( var i = lastClickedIndex; i !== nowClickedIndex; i += direction ) { if ( !items[ i ].isDisabled() ) { items[ i ].setSelected( !wasSelected ); } @@ -9449,9 +9410,8 @@ OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) { * @return {OO.ui.Widget} The widget, for chaining */ OO.ui.CheckboxMultiselectWidget.prototype.focus = function () { - var item; if ( !this.isDisabled() ) { - item = this.getRelativeFocusableItem( null, 1 ); + var item = this.getRelativeFocusableItem( null, 1 ); if ( item ) { item.focus(); } @@ -10363,10 +10323,9 @@ OO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) { * @inheritdoc */ OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) { - var selected; value = this.cleanUpValue( value ); // Only allow setting values that are actually present in the dropdown - selected = this.dropdownWidget.getMenu().findItemFromData( value ) || + var selected = this.dropdownWidget.getMenu().findItemFromData( value ) || this.dropdownWidget.getMenu().findFirstSelectableItem(); this.dropdownWidget.getMenu().selectItem( selected ); value = selected ? selected.getData() : ''; @@ -10417,17 +10376,18 @@ OO.ui.DropdownInputWidget.prototype.setOptions = function ( options ) { * @private */ OO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) { - var optionWidgets, optIndex, opt, previousOptgroup, optionWidget, optValue, - widget = this; + var widget = this; this.optionsDirty = true; // Go through all the supplied option configs and create either // MenuSectionOption or MenuOption widgets from each. - optionWidgets = []; - for ( optIndex = 0; optIndex < options.length; optIndex++ ) { - opt = options[ optIndex ]; + var optionWidgets = []; + var previousOptgroup; + for ( var optIndex = 0; optIndex < options.length; optIndex++ ) { + var opt = options[ optIndex ]; + var optionWidget; if ( opt.optgroup !== undefined ) { // Create a menu item. optionWidget = widget.createMenuSectionOptionWidget( opt.optgroup ); @@ -10435,7 +10395,7 @@ OO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) { } else { // Create a normal