From: James D. Forrester Date: Tue, 22 Sep 2015 20:14:56 +0000 (+0100) Subject: Update OOjs UI to v0.12.9 X-Git-Tag: 1.31.0-rc.0~9905^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=aea8d3a5286963d8633917dc0658c3b91e728ce4 Update OOjs UI to v0.12.9 Release notes: https://git.wikimedia.org/blob/oojs%2Fui.git/v0.12.9/History.md Change-Id: I8780a6d31a3c9d11e42f0858bb66a39f678bf28f --- diff --git a/composer.json b/composer.json index ed6184274c..e41b6c7feb 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "liuggio/statsd-php-client": "1.0.16", "oyejorge/less.php": "1.7.0.5", "mediawiki/at-ease": "1.1.0", - "oojs/oojs-ui": "0.12.8.1", + "oojs/oojs-ui": "0.12.9", "php": ">=5.3.3", "psr/log": "1.0.0", "wikimedia/assert": "0.2.2", diff --git a/resources/lib/oojs-ui/i18n/ca.json b/resources/lib/oojs-ui/i18n/ca.json index 33b0ce046b..3077b60537 100644 --- a/resources/lib/oojs-ui/i18n/ca.json +++ b/resources/lib/oojs-ui/i18n/ca.json @@ -12,7 +12,8 @@ "Edustus", "Davidpar", "Maceleiro", - "Kippelboy" + "Kippelboy", + "Macofe" ] }, "ooui-outline-control-move-down": "Baixa l'element", @@ -27,6 +28,7 @@ "ooui-dialog-process-dismiss": "Descarta", "ooui-dialog-process-retry": "Torneu-ho a provar", "ooui-dialog-process-continue": "Continua", + "ooui-selectfile-button-select": "Seleccioneu un fitxer", "ooui-selectfile-not-supported": "El tipus de fitxer no és compatible", "ooui-selectfile-placeholder": "No s'ha seleccionat cap fitxer", "ooui-selectfile-dragdrop-placeholder": "Deixeu-hi anar el fitxer (o feu clic a navega)" diff --git a/resources/lib/oojs-ui/i18n/el.json b/resources/lib/oojs-ui/i18n/el.json index b3c48455dd..85384179b6 100644 --- a/resources/lib/oojs-ui/i18n/el.json +++ b/resources/lib/oojs-ui/i18n/el.json @@ -26,5 +26,5 @@ "ooui-dialog-process-continue": "Συνέχεια", "ooui-selectfile-not-supported": "Επιλογή αρχείου δεν υποστηρίζεται", "ooui-selectfile-placeholder": "Κανένα αρχείο δεν είναι επιλεγμένο", - "ooui-selectfile-dragdrop-placeholder": "Σύρετε ένα αρχείο εδώ (ή κάντε κλικ για αναζήτηση)" + "ooui-selectfile-dragdrop-placeholder": "Σύρετε το αρχείο εδώ" } diff --git a/resources/lib/oojs-ui/i18n/en-ca.json b/resources/lib/oojs-ui/i18n/en-ca.json index 218ece26c5..1a8e31bee2 100644 --- a/resources/lib/oojs-ui/i18n/en-ca.json +++ b/resources/lib/oojs-ui/i18n/en-ca.json @@ -18,6 +18,5 @@ "ooui-dialog-process-continue": "Continue", "ooui-selectfile-not-supported": "File(s) not supported", "ooui-selectfile-placeholder": "No file selected", - "ooui-selectfile-dragdrop-placeholder": "Drop file here (or click to browse your computer)", - "ooui-semicolon-separator": ";" + "ooui-selectfile-dragdrop-placeholder": "Drop file here (or click to browse your computer)" } diff --git a/resources/lib/oojs-ui/i18n/en.json b/resources/lib/oojs-ui/i18n/en.json index 7cf2eb16ec..be008321d8 100644 --- a/resources/lib/oojs-ui/i18n/en.json +++ b/resources/lib/oojs-ui/i18n/en.json @@ -31,6 +31,5 @@ "ooui-selectfile-button-select": "Select a file", "ooui-selectfile-not-supported": "File selection is not supported", "ooui-selectfile-placeholder": "No file is selected", - "ooui-selectfile-dragdrop-placeholder": "Drop file here", - "ooui-semicolon-separator": "; " + "ooui-selectfile-dragdrop-placeholder": "Drop file here" } diff --git a/resources/lib/oojs-ui/i18n/fa.json b/resources/lib/oojs-ui/i18n/fa.json index 11bd4b8b06..0375c8eb6e 100644 --- a/resources/lib/oojs-ui/i18n/fa.json +++ b/resources/lib/oojs-ui/i18n/fa.json @@ -29,7 +29,8 @@ "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-selectfile-dragdrop-placeholder": "فایل را اینجا رها کنید" } diff --git a/resources/lib/oojs-ui/i18n/it.json b/resources/lib/oojs-ui/i18n/it.json index 387d736d20..68a25b5d02 100644 --- a/resources/lib/oojs-ui/i18n/it.json +++ b/resources/lib/oojs-ui/i18n/it.json @@ -13,14 +13,16 @@ "Raoli", "Una giornata uggiosa '94", "Ontsed", - "Alexmar983" + "Alexmar983", + "Nemo bis", + "Jdforrester" ] }, "ooui-outline-control-move-down": "Sposta in basso", "ooui-outline-control-move-up": "Sposta in alto", "ooui-outline-control-remove": "Rimuovi elemento", "ooui-toolbar-more": "Altro", - "ooui-toolgroup-expand": "Più", + "ooui-toolgroup-expand": "Altro", "ooui-toolgroup-collapse": "Meno", "ooui-dialog-message-accept": "OK", "ooui-dialog-message-reject": "Annulla", @@ -28,6 +30,8 @@ "ooui-dialog-process-dismiss": "Nascondi", "ooui-dialog-process-retry": "Riprova", "ooui-dialog-process-continue": "Continua", + "ooui-selectfile-button-select": "Seleziona un file", "ooui-selectfile-not-supported": "La selezione del file non è supportata", - "ooui-selectfile-placeholder": "Nessun file è selezionato" + "ooui-selectfile-placeholder": "Nessun file è selezionato", + "ooui-selectfile-dragdrop-placeholder": "Posiziona i files qui" } diff --git a/resources/lib/oojs-ui/i18n/ka.json b/resources/lib/oojs-ui/i18n/ka.json index efacb635d2..f1a1a4735e 100644 --- a/resources/lib/oojs-ui/i18n/ka.json +++ b/resources/lib/oojs-ui/i18n/ka.json @@ -24,6 +24,5 @@ "ooui-dialog-process-retry": "კიდევ სცადეთ", "ooui-dialog-process-continue": "გაგრძელება", "ooui-selectfile-not-supported": "ფაილის არჩევა არ არის მხარდაჭერილი", - "ooui-selectfile-placeholder": "ფაილი არ არის არჩეული", - "ooui-semicolon-separator": ";" + "ooui-selectfile-placeholder": "ფაილი არ არის არჩეული" } diff --git a/resources/lib/oojs-ui/i18n/krc.json b/resources/lib/oojs-ui/i18n/krc.json index bc3cf0b12d..d4068c87c9 100644 --- a/resources/lib/oojs-ui/i18n/krc.json +++ b/resources/lib/oojs-ui/i18n/krc.json @@ -17,6 +17,5 @@ "ooui-dialog-process-retry": "Энтда сынаб кёр", "ooui-dialog-process-continue": "Бардыр", "ooui-selectfile-not-supported": "Файл сайлау тутулмайды", - "ooui-selectfile-placeholder": "Бир файл да сайланмагъанды", - "ooui-semicolon-separator": ";" + "ooui-selectfile-placeholder": "Бир файл да сайланмагъанды" } diff --git a/resources/lib/oojs-ui/i18n/krl.json b/resources/lib/oojs-ui/i18n/krl.json new file mode 100644 index 0000000000..6ff25ebe00 --- /dev/null +++ b/resources/lib/oojs-ui/i18n/krl.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Mashoi7" + ] + }, + "ooui-toolbar-more": "Enämpi", + "ooui-toolgroup-expand": "Enämpi", + "ooui-toolgroup-collapse": "Vähempi" +} diff --git a/resources/lib/oojs-ui/i18n/olo.json b/resources/lib/oojs-ui/i18n/olo.json new file mode 100644 index 0000000000..855b0eacbf --- /dev/null +++ b/resources/lib/oojs-ui/i18n/olo.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Mashoi7" + ] + }, + "ooui-toolbar-more": "Enämbi", + "ooui-toolgroup-expand": "Enämbi", + "ooui-toolgroup-collapse": "Vähembi", + "ooui-dialog-process-retry": "Opi vie", + "ooui-dialog-process-continue": "Jatka", + "ooui-selectfile-button-select": "Valliče failu" +} diff --git a/resources/lib/oojs-ui/i18n/pt.json b/resources/lib/oojs-ui/i18n/pt.json index 8379cacda7..8d9071a7c1 100644 --- a/resources/lib/oojs-ui/i18n/pt.json +++ b/resources/lib/oojs-ui/i18n/pt.json @@ -10,7 +10,8 @@ "Jdforrester", "Luckas", "Vitorvicentevalente", - "SandroHc" + "SandroHc", + "Jkb8" ] }, "ooui-outline-control-move-down": "Mover item para baixo", @@ -27,5 +28,5 @@ "ooui-dialog-process-continue": "Continuar", "ooui-selectfile-not-supported": "A seleção de ficheiros não é suportada", "ooui-selectfile-placeholder": "Nenhum ficheiro selecionado", - "ooui-selectfile-dragdrop-placeholder": "Soltar ficheiro aqui (ou clicar para navegar)" + "ooui-selectfile-dragdrop-placeholder": "Soltar ficheiro aqui" } diff --git a/resources/lib/oojs-ui/i18n/qqq.json b/resources/lib/oojs-ui/i18n/qqq.json index cd9c0c25d4..1a096efc8e 100644 --- a/resources/lib/oojs-ui/i18n/qqq.json +++ b/resources/lib/oojs-ui/i18n/qqq.json @@ -35,6 +35,5 @@ "ooui-selectfile-button-select": "Label for the file selection widget's select file button", "ooui-selectfile-not-supported": "Label for the file selection widget if file selection is not supported", "ooui-selectfile-placeholder": "Label for the file selection widget when no file is currently selected", - "ooui-selectfile-dragdrop-placeholder": "Label for the file selection widget's drop target", - "ooui-semicolon-separator": "{{optional}} Semicolon used as a separator" + "ooui-selectfile-dragdrop-placeholder": "Label for the file selection widget's drop target" } diff --git a/resources/lib/oojs-ui/i18n/vec.json b/resources/lib/oojs-ui/i18n/vec.json index 1ccc67b47f..ddd27c5e99 100644 --- a/resources/lib/oojs-ui/i18n/vec.json +++ b/resources/lib/oojs-ui/i18n/vec.json @@ -9,9 +9,14 @@ "ooui-outline-control-move-down": "Sposta in baso", "ooui-outline-control-move-up": "Sposta in sima", "ooui-toolbar-more": "Altro", + "ooui-toolgroup-expand": "Piassè", + "ooui-toolgroup-collapse": "Manco", "ooui-dialog-message-accept": "Va ben", + "ooui-dialog-message-reject": "Fa gnente", "ooui-dialog-process-error": "Xe 'ndà storto calcossa", "ooui-dialog-process-dismiss": "Scondi", "ooui-dialog-process-retry": "Proa da novo", - "ooui-dialog-process-continue": "Và vanti" + "ooui-dialog-process-continue": "Và vanti", + "ooui-selectfile-button-select": "Siegli un file", + "ooui-selectfile-dragdrop-placeholder": "Mola zo el file chì rento" } diff --git a/resources/lib/oojs-ui/i18n/vi.json b/resources/lib/oojs-ui/i18n/vi.json index ff14801f4e..27cef231e7 100644 --- a/resources/lib/oojs-ui/i18n/vi.json +++ b/resources/lib/oojs-ui/i18n/vi.json @@ -22,5 +22,5 @@ "ooui-dialog-process-continue": "Tiếp tục", "ooui-selectfile-not-supported": "Không hỗ trợ việc chọn tập tin", "ooui-selectfile-placeholder": "Không có tập tin nào được chọn", - "ooui-selectfile-dragdrop-placeholder": "Thả tập tin vào đây (hoặc nhấn chuột để duyệt)" + "ooui-selectfile-dragdrop-placeholder": "Thả tập tin vào đây" } diff --git a/resources/lib/oojs-ui/oojs-ui-apex-noimages.css b/resources/lib/oojs-ui/oojs-ui-apex-noimages.css index ede6ea95e8..2db4bdb598 100644 --- a/resources/lib/oojs-ui/oojs-ui-apex-noimages.css +++ b/resources/lib/oojs-ui/oojs-ui-apex-noimages.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.12.8 + * OOjs UI v0.12.9 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-09-08T20:56:08Z + * Date: 2015-09-22T20:09:59Z */ @-webkit-keyframes oo-ui-progressBarWidget-slide { from { @@ -589,57 +589,57 @@ right: 18em; bottom: 18em; } -.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu { width: 0 !important; height: 0 !important; overflow: hidden; } -.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content { top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu { width: auto !important; left: 0; top: 0; right: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content { right: 0 !important; bottom: 0 !important; left: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu { height: auto !important; top: 0; right: 0; bottom: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content { bottom: 0 !important; left: 0 !important; top: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu { width: auto !important; right: 0; bottom: 0; left: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content { left: 0 !important; top: 0 !important; right: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu { height: auto !important; bottom: 0; left: 0; top: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content { top: 0 !important; right: 0 !important; bottom: 0 !important; @@ -772,6 +772,7 @@ display: inline; } .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link { + outline: 0; cursor: default; } .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool { @@ -815,6 +816,9 @@ .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled { border-left-color: rgba(0, 0, 0, 0.1); } +.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link:focus { + outline: 0; +} .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title { color: #cccccc; } @@ -824,6 +828,12 @@ .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon { opacity: 1; } +.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool:focus { + outline: 0; +} +.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link:focus { + outline: 0; +} .oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title { color: #cccccc; } @@ -844,6 +854,7 @@ position: absolute; } .oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle { + outline: 0; cursor: default; } .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { @@ -1964,6 +1975,9 @@ border-color: #dddddd; background-color: #f3f3f3; } +.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus { + outline: 0; +} .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator { opacity: 0.2; } @@ -2024,6 +2038,9 @@ right: 0; text-overflow: ellipsis; } +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType { + float: right; +} .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator, .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon, .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton { @@ -2059,7 +2076,7 @@ .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon { left: 0.25em; } -.oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label { +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label { line-height: 2.3em; margin: 0; overflow: hidden; @@ -2071,7 +2088,10 @@ left: 0.5em; right: 0.5em; } -.oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton { +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType { + color: #888888; +} +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton { top: 0; width: 1.875em; height: 1.875em; diff --git a/resources/lib/oojs-ui/oojs-ui-apex.js b/resources/lib/oojs-ui/oojs-ui-apex.js index 83452d0d23..5909cd118c 100644 --- a/resources/lib/oojs-ui/oojs-ui-apex.js +++ b/resources/lib/oojs-ui/oojs-ui-apex.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.12.8 + * OOjs UI v0.12.9 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-09-08T20:55:55Z + * Date: 2015-09-22T20:09:51Z */ /** * @class diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css b/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css index 87ae9a55e6..f1f1831627 100644 --- a/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css +++ b/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.12.8 + * OOjs UI v0.12.9 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-09-08T20:56:08Z + * Date: 2015-09-22T20:09:59Z */ @-webkit-keyframes oo-ui-progressBarWidget-slide { from { @@ -107,6 +107,7 @@ } .oo-ui-buttonElement > .oo-ui-buttonElement-button { font-weight: bold; + text-decoration: none; } .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon { margin-left: 0; @@ -114,7 +115,6 @@ .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator { width: 0.9375em; height: 0.9375em; - margin: 0.46875em; } .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator { margin-left: 0.46875em; @@ -186,14 +186,24 @@ .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button { color: #cccccc; } +.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus { + box-shadow: none; +} .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon, .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator { opacity: 0.2; } +.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button, +.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button { + padding-left: 2.4em; +} .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button { margin: 0.1em 0; - padding: 0.2em 0.8em; + padding: 0.5em 1em; + min-height: 1.2em; + min-width: 1em; border-radius: 2px; + position: relative; -webkit-transition: background 100ms ease, color 100ms ease, box-shadow 100ms ease; -moz-transition: background 100ms ease, color 100ms ease, box-shadow 100ms ease; -ms-transition: background 100ms ease, color 100ms ease, box-shadow 100ms ease; @@ -206,25 +216,29 @@ } .oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button, .oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { - line-height: 1.875em; + line-height: 1.2em; + display: inline-block; } .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon { - margin-left: -0.5em; - margin-right: -0.5em; + position: absolute; + top: 0.2em; + left: 0.5625em; } -.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon { - margin-right: 0.3em; +.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { + margin-left: 0.3em; } .oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator { - /* -0.5 - 0.475 */ - margin-left: -0.005em; - margin-right: -0.005em; + display: inline-block; } .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator, .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator { margin-left: 0.46875em; margin-right: -0.275em; } +.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator { + position: relative; + left: 0.2em; +} .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button { color: #ffffff; background: #dddddd; @@ -478,6 +492,12 @@ .oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout { padding: 1.5em; } +.oo-ui-indexLayout > .oo-ui-menuLayout-menu { + height: 2.75em; +} +.oo-ui-indexLayout > .oo-ui-menuLayout-content { + top: 2.75em; +} .oo-ui-fieldLayout { display: block; margin-bottom: 1em; @@ -667,57 +687,57 @@ right: 18em; bottom: 18em; } -.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu { width: 0 !important; height: 0 !important; overflow: hidden; } -.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content { top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu { width: auto !important; left: 0; top: 0; right: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content { right: 0 !important; bottom: 0 !important; left: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu { height: auto !important; top: 0; right: 0; bottom: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content { bottom: 0 !important; left: 0 !important; top: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu { width: auto !important; right: 0; bottom: 0; left: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content { left: 0 !important; top: 0 !important; right: 0 !important; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before .oo-ui-menuLayout-menu { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu { height: auto !important; bottom: 0; left: 0; top: 0; } -.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before .oo-ui-menuLayout-content { +.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content { top: 0 !important; right: 0 !important; bottom: 0 !important; @@ -842,6 +862,7 @@ display: inline; } .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link { + outline: 0; cursor: default; } .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link { @@ -909,6 +930,7 @@ position: absolute; } .oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle { + outline: 0; cursor: default; } .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { @@ -1307,9 +1329,6 @@ display: inline-block; vertical-align: middle; } -.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button { - height: 1.875em; -} .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon { margin-top: 0; } @@ -1520,6 +1539,7 @@ .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled { background: #dddddd; border-color: #dddddd; + outline: 0; } .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled .oo-ui-toggleSwitchWidget-grip { background: #ffffff; @@ -1596,7 +1616,7 @@ border: 1px solid #aaaaaa; border-radius: 0.2em; background-color: #ffffff; - box-shadow: inset 0 -0.2em 0 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 0.15em 0 0 rgba(204, 204, 204, 0.5); } .oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup { margin-top: 9px; @@ -2045,8 +2065,7 @@ margin-top: -1px; border: 1px solid #aaaaaa; border-radius: 0 0 0.2em 0.2em; - padding-bottom: 0.25em; - box-shadow: inset 0 -0.2em 0 0 rgba(0, 0, 0, 0.2), 0 0.1em 0 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 0.15em 0 0 rgba(204, 204, 204, 0.5); } .oo-ui-menuSelectWidget input { position: absolute; @@ -2158,6 +2177,9 @@ border-color: #dddddd; background-color: #f3f3f3; } +.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus { + outline: 0; +} .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator { opacity: 0.2; } @@ -2221,6 +2243,9 @@ right: 0; text-overflow: ellipsis; } +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType { + float: right; +} .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator, .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon, .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton { @@ -2256,7 +2281,7 @@ .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon { left: 0.25em; } -.oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label { +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label { line-height: 2.3em; margin: 0; overflow: hidden; @@ -2268,7 +2293,10 @@ left: 1em; right: 1em; } -.oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton { +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType { + color: #888888; +} +.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton { top: 0; width: 1.875em; height: 1.875em; @@ -2932,34 +2960,10 @@ font-weight: bold; line-height: 1.875em; } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button, -.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button { - min-width: 1.875em; - min-height: 1.875em; -} -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label, -.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label { - line-height: 1.875em; -} -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon, -.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon { - margin-top: -0.125em; -} .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed, .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed, .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed { - margin: 0.75em; -} -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button, -.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button { - padding: 0 1em; - vertical-align: middle; - /* Adjust for border so text aligns with title */ - margin: -1px; + margin: 0.5em; } .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless, .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless, @@ -2972,40 +2976,45 @@ padding: 0.75em 1em; vertical-align: middle; } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label, +.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label { + line-height: 1.875em; +} +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover { background-color: rgba(0, 0, 0, 0.05); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:active, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:active { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active { background-color: rgba(0, 0, 0, 0.1); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover { background-color: rgba(8, 126, 204, 0.05); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active { background-color: rgba(8, 126, 204, 0.1); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label { font-weight: bold; } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover { background-color: rgba(118, 171, 54, 0.05); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active { background-color: rgba(118, 171, 54, 0.1); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover { background-color: rgba(212, 83, 83, 0.05); } -.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active, -.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active { +.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active, +.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active { background-color: rgba(212, 83, 83, 0.1); } .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement { diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki.js b/resources/lib/oojs-ui/oojs-ui-mediawiki.js index a2915700c8..c2f6dc5222 100644 --- a/resources/lib/oojs-ui/oojs-ui-mediawiki.js +++ b/resources/lib/oojs-ui/oojs-ui-mediawiki.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.12.8 + * OOjs UI v0.12.9 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-09-08T20:55:55Z + * Date: 2015-09-22T20:09:51Z */ /** * @class diff --git a/resources/lib/oojs-ui/oojs-ui.js b/resources/lib/oojs-ui/oojs-ui.js index 81677ed8ce..42bf82196d 100644 --- a/resources/lib/oojs-ui/oojs-ui.js +++ b/resources/lib/oojs-ui/oojs-ui.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.12.8 + * OOjs UI v0.12.9 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-09-08T20:55:55Z + * Date: 2015-09-22T20:09:51Z */ ( function ( OO ) { @@ -67,30 +67,79 @@ OO.ui.generateElementId = function () { * @return {boolean} */ OO.ui.isFocusableElement = function ( $element ) { - var node = $element[ 0 ], - nodeName = node.nodeName.toLowerCase(), - // Check if the element have tabindex set - isInElementGroup = /^(input|select|textarea|button|object)$/.test( nodeName ), - // Check if the element is a link with href or if it has tabindex - isOtherElement = ( - ( nodeName === 'a' && node.href ) || - !isNaN( $element.attr( 'tabindex' ) ) - ), - // Check if the element is visible - isVisible = ( - // This is quicker than calling $element.is( ':visible' ) - $.expr.filters.visible( node ) && - // Check that all parents are visible - !$element.parents().addBack().filter( function () { - return $.css( this, 'visibility' ) === 'hidden'; - } ).length - ), - isTabOk = isNaN( $element.attr( 'tabindex' ) ) || +$element.attr( 'tabindex' ) >= 0; + var nodeName, + element = $element[ 0 ]; - return ( - ( isInElementGroup ? !node.disabled : isOtherElement ) && - isVisible && isTabOk - ); + // Anything disabled is not focusable + if ( element.disabled ) { + return false; + } + + // Check if the element is visible + if ( !( + // This is quicker than calling $element.is( ':visible' ) + $.expr.filters.visible( element ) && + // Check that all parents are visible + !$element.parents().addBack().filter( function () { + return $.css( this, 'visibility' ) === 'hidden'; + } ).length + ) ) { + return false; + } + + // Check if the element is ContentEditable, which is the string 'true' + if ( element.contentEditable === 'true' ) { + return true; + } + + // Anything with a non-negative numeric tabIndex is focusable. + // Use .prop to avoid browser bugs + if ( $element.prop( 'tabIndex' ) >= 0 ) { + return true; + } + + // 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(); + if ( [ 'input', 'select', 'textarea', 'button', 'object' ].indexOf( nodeName ) !== -1 ) { + return true; + } + + // Links and areas are focusable if they have an href + if ( ( nodeName === 'a' || nodeName === 'area' ) && $element.attr( 'href' ) !== undefined ) { + return true; + } + + return false; +}; + +/** + * Find a focusable child + * + * @param {jQuery} $container Container to search in + * @param {boolean} [backwards] Search backwards + * @return {jQuery} Focusable child, an empty jQuery object if none found + */ +OO.ui.findFocusable = function ( $container, backwards ) { + var $focusable = $( [] ), + // $focusableCandidates is a superset of things that + // could get matched by isFocusableElement + $focusableCandidates = $container + .find( 'input, select, textarea, button, object, a, area, [contenteditable], [tabindex]' ); + + if ( backwards ) { + $focusableCandidates = Array.prototype.reverse.call( $focusableCandidates ); + } + + $focusableCandidates.each( function () { + var $this = $( this ); + if ( OO.ui.isFocusableElement( $this ) ) { + $focusable = $this; + return false; + } + } ); + return $focusable; }; /** @@ -286,9 +335,7 @@ OO.ui.infuse = function ( idOrNode ) { // Label for the file selection widget when no file is currently selected 'ooui-selectfile-placeholder': 'No file is selected', // Label for the file selection widget's drop target - 'ooui-selectfile-dragdrop-placeholder': 'Drop file here', - // Semicolon separator - 'ooui-semicolon-separator': '; ' + 'ooui-selectfile-dragdrop-placeholder': 'Drop file here' }; /** @@ -1960,7 +2007,8 @@ OO.ui.Widget.static.supportsSimpleLabel = false; /** * @event disable * - * A 'disable' event is emitted when a widget is disabled. + * A 'disable' event is emitted when the disabled state of the widget changes + * (i.e. on disable **and** enable). * * @param {boolean} disabled Widget is disabled */ @@ -2081,6 +2129,10 @@ OO.ui.Window = function OoUiWindow( config ) { this.$overlay = $( '
' ); this.$content = $( '
' ); + this.$focusTrapBefore = $( '
' ).prop( 'tabIndex', 0 ); + this.$focusTrapAfter = $( '
' ).prop( 'tabIndex', 0 ); + this.$focusTraps = this.$focusTrapBefore.add( this.$focusTrapAfter ); + // Initialization this.$overlay.addClass( 'oo-ui-window-overlay' ); this.$content @@ -2088,7 +2140,7 @@ OO.ui.Window = function OoUiWindow( config ) { .attr( 'tabindex', 0 ); this.$frame .addClass( 'oo-ui-window-frame' ) - .append( this.$content ); + .append( this.$focusTrapBefore, this.$content, this.$focusTrapAfter ); this.$element .addClass( 'oo-ui-window' ) @@ -2521,6 +2573,21 @@ OO.ui.Window.prototype.initialize = function () { return this; }; +/** + * Called when someone tries to focus the hidden element at the end of the dialog. + * Sends focus back to the start of the dialog. + * + * @param {jQuery.Event} event Focus event + */ +OO.ui.Window.prototype.onFocusTrapFocused = function ( event ) { + if ( this.$focusTrapBefore.is( event.target ) ) { + OO.ui.findFocusable( this.$content, true ).focus(); + } else { + // this.$content is the part of the focus cycle, and is the first focusable element + this.$content.focus(); + } +}; + /** * Open the window. * @@ -2581,6 +2648,9 @@ OO.ui.Window.prototype.setup = function ( data ) { this.toggle( true ); + this.focusTrapHandler = OO.ui.bind( this.onFocusTrapFocused, this ); + this.$focusTraps.on( 'focus', this.focusTrapHandler ); + this.getSetupProcess( data ).execute().done( function () { // Force redraw by asking the browser to measure the elements' widths win.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width(); @@ -2663,6 +2733,7 @@ OO.ui.Window.prototype.teardown = function ( data ) { // Force redraw by asking the browser to measure the elements' widths win.$element.removeClass( 'oo-ui-window-active oo-ui-window-setup' ).width(); win.$content.removeClass( 'oo-ui-window-content-setup' ).width(); + win.$focusTraps.off( 'focus', win.focusTrapHandler ); win.toggle( false ); } ); }; @@ -6754,6 +6825,161 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () { return this; }; +/** + * Element that will stick under a specified container, even when it is inserted elsewhere in the + * document (for example, in a OO.ui.Window's $overlay). + * + * The elements's position is automatically calculated and maintained when window is resized or the + * page is scrolled. If you reposition the container manually, you have to call #position to make + * sure the element is still placed correctly. + * + * As positioning is only possible when both the element and the container are attached to the DOM + * and visible, it's only done after you call #togglePositioning. You might want to do this inside + * the #toggle method to display a floating popup, for example. + * + * @abstract + * @class + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element + * @cfg {jQuery} [$floatableContainer] Node to position below + */ +OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) { + // Configuration initialization + config = config || {}; + + // Properties + this.$floatable = null; + this.$floatableContainer = null; + this.$floatableWindow = null; + this.$floatableClosestScrollable = null; + this.onFloatableScrollHandler = this.position.bind( this ); + this.onFloatableWindowResizeHandler = this.position.bind( this ); + + // Initialization + this.setFloatableContainer( config.$floatableContainer ); + this.setFloatableElement( config.$floatable || this.$element ); +}; + +/* Methods */ + +/** + * Set floatable element. + * + * If an element is already set, it will be cleaned up before setting up the new element. + * + * @param {jQuery} $floatable Element to make floatable + */ +OO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) { + if ( this.$floatable ) { + this.$floatable.removeClass( 'oo-ui-floatableElement-floatable' ); + this.$floatable.css( { left: '', top: '' } ); + } + + this.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' ); + this.position(); +}; + +/** + * Set floatable container. + * + * The element will be always positioned under the specified container. + * + * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset + */ +OO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) { + this.$floatableContainer = $floatableContainer; + if ( this.$floatable ) { + this.position(); + } +}; + +/** + * Toggle positioning. + * + * Do not turn positioning on until after the element is attached to the DOM and visible. + * + * @param {boolean} [positioning] Enable positioning, omit to toggle + * @chainable + */ +OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) { + var closestScrollableOfContainer, closestScrollableOfFloatable; + + positioning = positioning === undefined ? !this.positioning : !!positioning; + + if ( this.positioning !== positioning ) { + this.positioning = positioning; + + closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] ); + closestScrollableOfFloatable = OO.ui.Element.static.getClosestScrollableContainer( this.$floatable[ 0 ] ); + if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) { + // If the scrollable is the root, we have to listen to scroll events + // on the window because of browser inconsistencies (or do we? someone should verify this) + if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) { + closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer ); + } + } + + if ( positioning ) { + this.$floatableWindow = $( this.getElementWindow() ); + this.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler ); + + if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) { + this.$floatableClosestScrollable = $( closestScrollableOfContainer ); + this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler ); + } + + // Initial position after visible + this.position(); + } else { + this.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler ); + this.$floatableWindow = null; + + if ( this.$floatableClosestScrollable ) { + this.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler ); + this.$floatableClosestScrollable = null; + } + + this.$floatable.css( { left: '', top: '' } ); + } + } + + return this; +}; + +/** + * Position the floatable below its container. + * + * This should only be done when both of them are attached to the DOM and visible. + * + * @chainable + */ +OO.ui.mixin.FloatableElement.prototype.position = function () { + var pos; + + if ( !this.positioning ) { + return this; + } + + pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() ); + + // Position under container + pos.top += this.$floatableContainer.height(); + this.$floatable.css( pos ); + + // We updated the position, so re-evaluate the clipping state. + // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so + // will not notice the need to update itself.) + // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does + // it not listen to the right events in the right places? + if ( this.clip ) { + this.clip(); + } + + return this; +}; + /** * AccessKeyedElement is mixed into other classes to provide an `accesskey` attribute. * Accesskeys allow an user to go to a specific element by using @@ -8182,7 +8408,6 @@ OO.ui.MessageDialog.prototype.onResize = function () { /** * Toggle action layout between vertical and horizontal. * - * * @private * @param {boolean} [value] Layout actions vertically, omit to toggle * @chainable @@ -8998,7 +9223,6 @@ OO.ui.FieldLayout.prototype.setAlignment = function ( value ) { * * $( 'body' ).append( actionFieldLayout.$element ); * - * * @class * @extends OO.ui.FieldLayout * @@ -9589,7 +9813,7 @@ OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) { * @param {number} [itemIndex] A specific item to focus on */ OO.ui.BookletLayout.prototype.focus = function ( itemIndex ) { - var $input, page, + var page, items = this.stackLayout.getItems(); if ( itemIndex !== undefined && items[ itemIndex ] ) { @@ -9607,10 +9831,7 @@ OO.ui.BookletLayout.prototype.focus = function ( itemIndex ) { } // Only change the focus if is not already in the current page if ( !page.$element.find( ':focus' ).length ) { - $input = page.$element.find( ':input:first' ); - if ( $input.length ) { - $input[ 0 ].focus(); - } + OO.ui.findFocusable( page.$element ).focus(); } }; @@ -9619,28 +9840,7 @@ OO.ui.BookletLayout.prototype.focus = function ( itemIndex ) { * on it. */ OO.ui.BookletLayout.prototype.focusFirstFocusable = function () { - var i, len, - found = false, - items = this.stackLayout.getItems(), - checkAndFocus = function () { - if ( OO.ui.isFocusableElement( $( this ) ) ) { - $( this ).focus(); - found = true; - return false; - } - }; - - for ( i = 0, len = items.length; i < len; i++ ) { - if ( found ) { - break; - } - // Find all potentially focusable elements in the item - // and check if they are focusable - items[ i ].$element - .find( 'input, select, textarea, button, object' ) - /* jshint loopfunc:true */ - .each( checkAndFocus ); - } + OO.ui.findFocusable( this.stackLayout.$element ).focus(); }; /** @@ -9908,7 +10108,8 @@ OO.ui.BookletLayout.prototype.clearPages = function () { OO.ui.BookletLayout.prototype.setPage = function ( name ) { var selectedItem, $focused, - page = this.pages[ name ]; + page = this.pages[ name ], + previousPage = this.currentPageName && this.pages[ this.currentPageName ]; if ( name !== this.currentPageName ) { if ( this.outlined ) { @@ -9918,21 +10119,34 @@ OO.ui.BookletLayout.prototype.setPage = function ( name ) { } } if ( page ) { - if ( this.currentPageName && this.pages[ this.currentPageName ] ) { - this.pages[ this.currentPageName ].setActive( false ); - // Blur anything focused if the next page doesn't have anything focusable - this - // is not needed if the next page has something focusable because once it is focused - // this blur happens automatically - if ( this.autoFocus && !page.$element.find( ':input' ).length ) { - $focused = this.pages[ this.currentPageName ].$element.find( ':focus' ); + if ( previousPage ) { + previousPage.setActive( false ); + // Blur anything focused if the next page doesn't have anything focusable. + // This is not needed if the next page has something focusable (because once it is focused + // this blur happens automatically). If the layout is non-continuous, this check is + // meaningless because the next page is not visible yet and thus can't hold focus. + if ( + this.autoFocus && + this.stackLayout.continuous && + OO.ui.findFocusable( page.$element ).length !== 0 + ) { + $focused = previousPage.$element.find( ':focus' ); if ( $focused.length ) { $focused[ 0 ].blur(); } } } this.currentPageName = name; - this.stackLayout.setItem( page ); page.setActive( true ); + this.stackLayout.setItem( page ); + if ( !this.stackLayout.continuous && previousPage ) { + // This should not be necessary, since any inputs on the previous page should have been + // blurred when it was hidden, but browsers are not very consistent about this. + $focused = previousPage.$element.find( ':focus' ); + if ( $focused.length ) { + $focused[ 0 ].blur(); + } + } this.emit( 'set', page ); } } @@ -9969,20 +10183,13 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () { * } * OO.inheritClass( CardOneLayout, OO.ui.CardLayout ); * CardOneLayout.prototype.setupTabItem = function () { - * this.tabItem.setLabel( 'Card One' ); - * }; - * - * function CardTwoLayout( name, config ) { - * CardTwoLayout.parent.call( this, name, config ); - * this.$element.append( '

Second card

' ); - * } - * OO.inheritClass( CardTwoLayout, OO.ui.CardLayout ); - * CardTwoLayout.prototype.setupTabItem = function () { - * this.tabItem.setLabel( 'Card Two' ); + * this.tabItem.setLabel( 'Card one' ); * }; * * var card1 = new CardOneLayout( 'one' ), - * card2 = new CardTwoLayout( 'two' ); + * card2 = new CardLayout( 'two', { label: 'Card two' } ); + * + * card2.$element.append( '

Second card

' ); * * var index = new OO.ui.IndexLayout(); * @@ -9995,6 +10202,7 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () { * @constructor * @param {Object} [config] Configuration options * @cfg {boolean} [continuous=false] Show all cards, one after another + * @cfg {boolean} [expanded=true] Expand the content panel to fill the entire parent element. * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new card is displayed. */ OO.ui.IndexLayout = function OoUiIndexLayout( config ) { @@ -10008,7 +10216,10 @@ OO.ui.IndexLayout = function OoUiIndexLayout( config ) { this.currentCardName = null; this.cards = {}; this.ignoreFocus = false; - this.stackLayout = new OO.ui.StackLayout( { continuous: !!config.continuous } ); + this.stackLayout = new OO.ui.StackLayout( { + continuous: !!config.continuous, + expanded: config.expanded + } ); this.$content.append( this.stackLayout.$element ); this.autoFocus = config.autoFocus === undefined || !!config.autoFocus; @@ -10109,7 +10320,7 @@ OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( card ) { * @param {number} [itemIndex] A specific item to focus on */ OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) { - var $input, card, + var card, items = this.stackLayout.getItems(); if ( itemIndex !== undefined && items[ itemIndex ] ) { @@ -10127,10 +10338,7 @@ OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) { } // Only change the focus if is not already in the current card if ( !card.$element.find( ':focus' ).length ) { - $input = card.$element.find( ':input:first' ); - if ( $input.length ) { - $input[ 0 ].focus(); - } + OO.ui.findFocusable( card.$element ).focus(); } }; @@ -10139,27 +10347,7 @@ OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) { * on it. */ OO.ui.IndexLayout.prototype.focusFirstFocusable = function () { - var i, len, - found = false, - items = this.stackLayout.getItems(), - checkAndFocus = function () { - if ( OO.ui.isFocusableElement( $( this ) ) ) { - $( this ).focus(); - found = true; - return false; - } - }; - - for ( i = 0, len = items.length; i < len; i++ ) { - if ( found ) { - break; - } - // Find all potentially focusable elements in the item - // and check if they are focusable - items[ i ].$element - .find( 'input, select, textarea, button, object' ) - .each( checkAndFocus ); - } + OO.ui.findFocusable( this.stackLayout.$element ).focus(); }; /** @@ -10363,7 +10551,8 @@ OO.ui.IndexLayout.prototype.clearCards = function () { OO.ui.IndexLayout.prototype.setCard = function ( name ) { var selectedItem, $focused, - card = this.cards[ name ]; + card = this.cards[ name ], + previousCard = this.currentCardName && this.cards[ this.currentCardName ]; if ( name !== this.currentCardName ) { selectedItem = this.tabSelectWidget.getSelectedItem(); @@ -10371,21 +10560,34 @@ OO.ui.IndexLayout.prototype.setCard = function ( name ) { this.tabSelectWidget.selectItemByData( name ); } if ( card ) { - if ( this.currentCardName && this.cards[ this.currentCardName ] ) { - this.cards[ this.currentCardName ].setActive( false ); - // Blur anything focused if the next card doesn't have anything focusable - this - // is not needed if the next card has something focusable because once it is focused - // this blur happens automatically - if ( this.autoFocus && !card.$element.find( ':input' ).length ) { - $focused = this.cards[ this.currentCardName ].$element.find( ':focus' ); + if ( previousCard ) { + previousCard.setActive( false ); + // Blur anything focused if the next card doesn't have anything focusable. + // This is not needed if the next card has something focusable (because once it is focused + // this blur happens automatically). If the layout is non-continuous, this check is + // meaningless because the next card is not visible yet and thus can't hold focus. + if ( + this.autoFocus && + this.stackLayout.continuous && + OO.ui.findFocusable( card.$element ).length !== 0 + ) { + $focused = previousCard.$element.find( ':focus' ); if ( $focused.length ) { $focused[ 0 ].blur(); } } } this.currentCardName = name; - this.stackLayout.setItem( card ); card.setActive( true ); + this.stackLayout.setItem( card ); + if ( !this.stackLayout.continuous && previousCard ) { + // This should not be necessary, since any inputs on the previous card should have been + // blurred when it was hidden, but browsers are not very consistent about this. + $focused = previousCard.$element.find( ':focus' ); + if ( $focused.length ) { + $focused[ 0 ].blur(); + } + } this.emit( 'set', card ); } } @@ -10475,6 +10677,7 @@ OO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout ); * @constructor * @param {string} name Unique symbolic name of card * @param {Object} [config] Configuration options + * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] Label for card's tab */ OO.ui.CardLayout = function OoUiCardLayout( name, config ) { // Allow passing positional parameters inside the config object @@ -10491,6 +10694,7 @@ OO.ui.CardLayout = function OoUiCardLayout( name, config ) { // Properties this.name = name; + this.label = config.label; this.tabItem = null; this.active = false; @@ -10576,6 +10780,9 @@ OO.ui.CardLayout.prototype.setTabItem = function ( tabItem ) { * @chainable */ OO.ui.CardLayout.prototype.setupTabItem = function () { + if ( this.label ) { + this.tabItem.setLabel( this.label ); + } return this; }; @@ -11310,8 +11517,8 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) { } if ( this.isClippedHorizontally() ) { // Anchoring to the right also caused the popup to clip, so just make it fill the container - containerWidth = this.$clippableContainer.width(); - containerLeft = this.$clippableContainer.offset().left; + containerWidth = this.$clippableScrollableContainer.width(); + containerLeft = this.$clippableScrollableContainer.offset().left; this.toggleClipping( false ); this.$element.removeClass( 'oo-ui-popupToolGroup-right' ); @@ -12119,7 +12326,6 @@ OO.ui.OutlineControlsWidget.prototype.setAbilities = function ( abilities ) { }; /** - * * @private * Handle outline change events. */ @@ -13031,6 +13237,18 @@ OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.IconElement ); /* Methods */ +/** + * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data. + * + * @protected + * @param {Mixed} data Custom data of any type. + * @param {string} label The label text. + * @return {OO.ui.CapsuleItemWidget} + */ +OO.ui.CapsuleMultiSelectWidget.prototype.createItemWidget = function ( data, label ) { + return new OO.ui.CapsuleItemWidget( { data: data, label: label } ); +}; + /** * Get the data of the items in the capsule * @return {Mixed[]} @@ -13071,7 +13289,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.setItemsFromData = function ( datas ) { } } if ( !item ) { - item = new OO.ui.CapsuleItemWidget( { data: data, label: label } ); + item = widget.createItemWidget( data, label ); } widget.addItems( [ item ], i ); } ); @@ -13100,9 +13318,9 @@ OO.ui.CapsuleMultiSelectWidget.prototype.addItemsFromData = function ( datas ) { if ( !widget.getItemFromData( data ) ) { item = menu.getItemFromData( data ); if ( item ) { - items.push( new OO.ui.CapsuleItemWidget( { data: data, label: item.label } ) ); + items.push( widget.createItemWidget( data, item.label ) ); } else if ( widget.allowArbitrary ) { - items.push( new OO.ui.CapsuleItemWidget( { data: data, label: String( data ) } ) ); + items.push( widget.createItemWidget( data, String( data ) ) ); } } } ); @@ -13549,6 +13767,10 @@ OO.ui.CapsuleItemWidget.prototype.onCloseKeyDown = function ( e ) { * * $( 'body' ).append( dropDown.$element ); * + * dropDown.getMenu().selectItemByData( 'b' ); + * + * dropDown.getMenu().getSelectedItem().getData(); // returns 'b' + * * For more information, please see the [OOjs UI documentation on MediaWiki] [1]. * * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options @@ -13870,6 +14092,7 @@ OO.ui.SelectFileWidget.prototype.setValue = function ( file ) { * @protected */ OO.ui.SelectFileWidget.prototype.updateUI = function () { + var $label; if ( !this.isSupported ) { this.$element.addClass( 'oo-ui-selectFileWidget-notsupported' ); this.$element.removeClass( 'oo-ui-selectFileWidget-empty' ); @@ -13878,9 +14101,12 @@ OO.ui.SelectFileWidget.prototype.updateUI = function () { this.$element.addClass( 'oo-ui-selectFileWidget-supported' ); if ( this.currentFile ) { this.$element.removeClass( 'oo-ui-selectFileWidget-empty' ); - this.setLabel( this.currentFile.name + - ( this.currentFile.type !== '' ? OO.ui.msg( 'ooui-semicolon-separator' ) + this.currentFile.type : '' ) - ); + $label = $( [] ); + if ( this.currentFile.type !== '' ) { + $label = $label.add( $( '' ).addClass( 'oo-ui-selectFileWidget-fileType' ).text( this.currentFile.type ) ); + } + $label = $label.add( $( '' ).text( this.currentFile.name ) ); + this.setLabel( $label ); } else { this.$element.addClass( 'oo-ui-selectFileWidget-empty' ); this.setLabel( this.placeholder ); @@ -16026,7 +16252,6 @@ OO.ui.ComboBoxWidget.prototype.onInputChange = function ( value ) { /** * Handle mouse click events. * - * * @private * @param {jQuery.Event} e Mouse click event */ @@ -16041,7 +16266,6 @@ OO.ui.ComboBoxWidget.prototype.onClick = function ( e ) { /** * Handle key press events. * - * * @private * @param {jQuery.Event} e Key press event */ @@ -16134,7 +16358,6 @@ OO.ui.ComboBoxWidget.prototype.setDisabled = function ( disabled ) { * ] ); * $( 'body' ).append( fieldset.$element ); * - * * @class * @extends OO.ui.Widget * @mixins OO.ui.mixin.LabelElement @@ -16644,7 +16867,6 @@ OO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true; * } ); * $( 'body' ).append( myDropdown.$element ); * - * * @class * @extends OO.ui.DecoratedOptionWidget * @@ -16854,6 +17076,7 @@ OO.ui.TabOptionWidget.static.highlightable = false; * @class * @extends OO.ui.Widget * @mixins OO.ui.mixin.LabelElement + * @mixins OO.ui.mixin.ClippableElement * * @constructor * @param {Object} [config] Configuration options @@ -18748,6 +18971,7 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) { * * @class * @extends OO.ui.MenuSelectWidget + * @mixins OO.ui.mixin.FloatableElement * * @constructor * @param {OO.ui.Widget} [inputWidget] Widget to provide the menu for. @@ -18768,10 +18992,12 @@ OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWid // Parent constructor OO.ui.FloatingMenuSelectWidget.parent.call( this, config ); - // Properties + // Properties (must be set before mixin constructors) this.inputWidget = inputWidget; // For backwards compatibility this.$container = config.$container || this.inputWidget.$element; - this.onWindowResizeHandler = this.onWindowResize.bind( this ); + + // Mixins constructors + OO.ui.mixin.FloatableElement.call( this, $.extend( {}, config, { $floatableContainer: this.$container } ) ); // Initialization this.$element.addClass( 'oo-ui-floatingMenuSelectWidget' ); @@ -18782,75 +19008,37 @@ OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWid /* Setup */ OO.inheritClass( OO.ui.FloatingMenuSelectWidget, OO.ui.MenuSelectWidget ); +OO.mixinClass( OO.ui.FloatingMenuSelectWidget, OO.ui.mixin.FloatableElement ); // For backwards compatibility OO.ui.TextInputMenuSelectWidget = OO.ui.FloatingMenuSelectWidget; /* Methods */ -/** - * Handle window resize event. - * - * @private - * @param {jQuery.Event} e Window resize event - */ -OO.ui.FloatingMenuSelectWidget.prototype.onWindowResize = function () { - this.position(); -}; - /** * @inheritdoc */ OO.ui.FloatingMenuSelectWidget.prototype.toggle = function ( visible ) { var change; visible = visible === undefined ? !this.isVisible() : !!visible; - change = visible !== this.isVisible(); if ( change && visible ) { // Make sure the width is set before the parent method runs. - // After this we have to call this.position(); again to actually - // position ourselves correctly. - this.position(); + this.setIdealSize( this.$container.width() ); } // Parent method + // This will call this.clip(), which is nonsensical since we're not positioned yet... OO.ui.FloatingMenuSelectWidget.parent.prototype.toggle.call( this, visible ); if ( change ) { - if ( this.isVisible() ) { - this.position(); - $( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler ); - } else { - $( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler ); - } + this.togglePositioning( this.isVisible() ); } return this; }; -/** - * Position the menu. - * - * @private - * @chainable - */ -OO.ui.FloatingMenuSelectWidget.prototype.position = function () { - var $container = this.$container, - pos = OO.ui.Element.static.getRelativePosition( $container, this.$element.offsetParent() ); - - // Position under input - pos.top += $container.height(); - this.$element.css( pos ); - - // Set width - this.setIdealSize( $container.width() ); - // We updated the position, so re-evaluate the clipping state - this.clip(); - - return this; -}; - /** * OutlineSelectWidget is a structured list that contains {@link OO.ui.OutlineOptionWidget outline options} * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls} widget. @@ -19235,7 +19423,6 @@ OO.ui.NumberInputWidget.prototype.onWheel = function ( event ) { /** * Handle key down events. * - * * @private * @param {jQuery.Event} e Key down event */ diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/picture.png b/resources/lib/oojs-ui/themes/apex/images/icons/picture.png index 2043424844..d680396faa 100644 Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/picture.png and b/resources/lib/oojs-ui/themes/apex/images/icons/picture.png differ diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/picture.svg b/resources/lib/oojs-ui/themes/apex/images/icons/picture.svg index 24d7315c2b..246e130c58 100644 --- a/resources/lib/oojs-ui/themes/apex/images/icons/picture.svg +++ b/resources/lib/oojs-ui/themes/apex/images/icons/picture.svg @@ -1,8 +1,8 @@ - - - + + + diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/table.png b/resources/lib/oojs-ui/themes/apex/images/icons/table.png index fb6b985b93..2eedd1e3e8 100644 Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/table.png and b/resources/lib/oojs-ui/themes/apex/images/icons/table.png differ diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/table.svg b/resources/lib/oojs-ui/themes/apex/images/icons/table.svg index 3c901f7764..b5733fba34 100644 --- a/resources/lib/oojs-ui/themes/apex/images/icons/table.svg +++ b/resources/lib/oojs-ui/themes/apex/images/icons/table.svg @@ -1,6 +1,6 @@ - + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.png index d6dc62c49e..f63756bc2c 100644 Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.png differ diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.svg index be2c66dae7..a969967927 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.svg +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture-invert.svg @@ -1,8 +1,8 @@ - - - + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.png index 2043424844..d680396faa 100644 Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.png differ diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.svg index 24d7315c2b..246e130c58 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.svg +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/picture.svg @@ -1,8 +1,8 @@ - - - + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.png index 9cc620a290..ee9885f60c 100644 Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.png differ diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.svg index 246be85546..808d8d8d2f 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.svg +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.svg @@ -1,6 +1,6 @@ - + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.png index fb6b985b93..2eedd1e3e8 100644 Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.png differ diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.svg index 3c901f7764..b5733fba34 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.svg +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/table.svg @@ -1,6 +1,6 @@ - +