From f17ae78218685ee55b0a599b1b65932f2a5ca99a Mon Sep 17 00:00:00 2001 From: "James D. Forrester" Date: Tue, 11 Aug 2015 15:39:37 -0700 Subject: [PATCH] Update OOjs UI to v0.12.3 Release notes: https://git.wikimedia.org/blob/oojs%2Fui.git/v0.12.3/History.md Change-Id: Idd3a4e41154837e84d1dcb4622d04b5765e6cbf9 --- composer.json | 2 +- resources/lib/oojs-ui/i18n/ko.json | 2 +- .../lib/oojs-ui/oojs-ui-apex-noimages.css | 205 ++- resources/lib/oojs-ui/oojs-ui-apex.js | 4 +- .../oojs-ui/oojs-ui-mediawiki-noimages.css | 267 +++- resources/lib/oojs-ui/oojs-ui-mediawiki.js | 4 +- resources/lib/oojs-ui/oojs-ui.js | 1400 +++++++++++++++-- 7 files changed, 1713 insertions(+), 171 deletions(-) diff --git a/composer.json b/composer.json index 00411a9d0a..fb3d91ba7f 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "leafo/lessphp": "0.5.0", "liuggio/statsd-php-client": "1.0.16", "mediawiki/at-ease": "1.0.0", - "oojs/oojs-ui": "0.12.2", + "oojs/oojs-ui": "0.12.3", "php": ">=5.3.3", "psr/log": "1.0.0", "wikimedia/cdb": "1.0.1", diff --git a/resources/lib/oojs-ui/i18n/ko.json b/resources/lib/oojs-ui/i18n/ko.json index f23f68752c..bf47f6f9bd 100644 --- a/resources/lib/oojs-ui/i18n/ko.json +++ b/resources/lib/oojs-ui/i18n/ko.json @@ -14,7 +14,7 @@ }, "ooui-outline-control-move-down": "항목을 아래로 옮기기", "ooui-outline-control-move-up": "항목을 위로 옮기기", - "ooui-outline-control-remove": "항목 지우기", + "ooui-outline-control-remove": "항목 제거", "ooui-toolbar-more": "더 보기", "ooui-toolgroup-expand": "더 보기", "ooui-toolgroup-collapse": "덜 보기", diff --git a/resources/lib/oojs-ui/oojs-ui-apex-noimages.css b/resources/lib/oojs-ui/oojs-ui-apex-noimages.css index 3557c4c9ff..4c95ebe347 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.2 + * OOjs UI v0.12.3 * 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-07-28T23:01:40Z + * Date: 2015-08-11T22:34:09Z */ @-webkit-keyframes oo-ui-progressBarWidget-slide { from { @@ -470,6 +470,28 @@ .oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label { color: #cccccc; } +.oo-ui-fieldLayout-messages { + list-style: none none; + margin: 0; + padding: 0; + margin-top: 0.25em; + margin-left: 0.25em; +} +.oo-ui-fieldLayout-messages > li { + margin: 0; + padding: 0; +} +.oo-ui-fieldLayout-messages .oo-ui-iconWidget { + display: none; +} +.oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-error { + color: #d45353; +} +.oo-ui-fieldLayout-messages .oo-ui-labelWidget { + padding: 0; + line-height: 1.875em; + vertical-align: middle; +} .oo-ui-actionFieldLayout-input, .oo-ui-actionFieldLayout-button { display: table-cell; @@ -645,6 +667,19 @@ display: block; position: relative; } +.oo-ui-horizontalLayout > .oo-ui-widget { + display: inline-block; + vertical-align: middle; +} +.oo-ui-horizontalLayout > .oo-ui-layout { + display: inline-block; +} +.oo-ui-horizontalLayout > .oo-ui-widget { + margin-right: 0.5em; +} +.oo-ui-horizontalLayout > .oo-ui-widget:last-child { + margin-right: 0; +} .oo-ui-popupTool .oo-ui-popupWidget-popup, .oo-ui-popupTool .oo-ui-popupWidget-anchor { z-index: 4; @@ -780,12 +815,18 @@ .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 .oo-ui-tool-title { + color: #cccccc; +} .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon { opacity: 0.2; } .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 > .oo-ui-tool-link .oo-ui-tool-title { + color: #cccccc; +} .oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon { opacity: 0.2; } @@ -1130,11 +1171,13 @@ .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button, .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button { margin: 0; - padding: 1.1953125em 0.3125em; + padding: 0 0.3125em; } .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label, .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { margin: 0 1em; + line-height: 3.40625em; + /* 43/12.8 */ } .oo-ui-toolbar-shadow { background-image: /* @embed */ url(themes/apex/images/toolbar-shadow.png); @@ -2219,6 +2262,159 @@ background-color: #ffffff; border-color: #dddddd; } +.oo-ui-capsuleMultiSelectWidget { + display: inline-block; + position: relative; + width: 100%; + max-width: 50em; +} +.oo-ui-capsuleMultiSelectWidget-handle { + width: 100%; + display: inline-block; + position: relative; +} +.oo-ui-capsuleMultiSelectWidget-group { + display: inline; +} +.oo-ui-capsuleMultiSelectWidget > .oo-ui-menuSelectWidget { + z-index: 1; + width: 100%; +} +.oo-ui-capsuleMultiSelectWidget-handle { + background: #ffffff; + cursor: text; + min-height: 2.35em; + margin-right: 0.5em; + padding: 0.25em 0; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 0.25em; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.oo-ui-capsuleMultiSelectWidget-handle:last-child { + margin-right: 0; +} +.oo-ui-capsuleMultiSelectWidget-handle .oo-ui-capsuleMultiSelectWidget-group { + margin: 0 0.2em; +} +.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator, +.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon { + position: absolute; + background-position: center center; + background-repeat: no-repeat; +} +.oo-ui-capsuleMultiSelectWidget-handle > input { + border: none; + min-width: 1em; + max-width: 100%; + line-height: 1.675em; + margin: 0; + padding: 0; + font-size: inherit; + font-family: inherit; + background-color: transparent; + color: black; + vertical-align: middle; +} +.oo-ui-capsuleMultiSelectWidget-handle > input:focus { + outline: none; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle { + padding-right: 0.9375em; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator { + right: 0; + top: 0; + width: 0.9375em; + height: 0.9375em; + margin: 0.775em; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle { + padding-left: 1.875em; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon { + left: 0; + top: 0; + width: 1.875em; + height: 1.875em; + margin: 0.3em; +} +.oo-ui-capsuleMultiSelectWidget:hover .oo-ui-capsuleMultiSelectWidget-handle { + border-color: rgba(0, 0, 0, 0.2); +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle { + color: #cccccc; + text-shadow: 0 1px 1px #ffffff; + border-color: #dddddd; + background-color: #f3f3f3; + cursor: default; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon, +.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator { + opacity: 0.2; +} +.oo-ui-capsuleMultiSelectWidget .oo-ui-selectWidget { + border-top-color: #ffffff; +} +.oo-ui-capsuleItemWidget { + position: relative; + display: inline-block; + cursor: default; + white-space: nowrap; + width: auto; + max-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + vertical-align: middle; + padding: 0.2em; + margin: 0 0.1em; + height: 1.675em; + background: #eeeeee; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd'); + background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd)); + background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%); + background-image: -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%); + background-image: -o-linear-gradient(top, #ffffff 0%, #dddddd 100%); + background-image: linear-gradient(to bottom, #ffffff 0%, #dddddd 100%); + border: 1px solid #cccccc; + color: #555555; + border-radius: 0.5em; +} +.oo-ui-capsuleItemWidget > .oo-ui-iconElement-icon { + cursor: pointer; +} +.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon { + cursor: default; +} +.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label { + display: block; + text-overflow: ellipsis; + overflow: hidden; +} +.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-labelElement-label { + padding-right: 1.3375em; +} +.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator { + position: absolute; + right: 0.2em; + top: 0; + width: 0.9375em; + height: 100%; + background-repeat: no-repeat; +} +.oo-ui-capsuleItemWidget.oo-ui-widget-disabled { + opacity: 0.5; + -webkit-transform: translate3d(0, 0, 0); + box-shadow: none; + color: #333333; + background: #eeeeee; + border-color: #cccccc; +} +.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator { + opacity: 0.2; +} .oo-ui-comboBoxWidget { display: inline-block; position: relative; @@ -2354,9 +2550,6 @@ /* @noflip */ left: 0; } -.oo-ui-dialog { - z-index: 1000; -} .oo-ui-dialog-content > .oo-ui-window-head, .oo-ui-dialog-content > .oo-ui-window-body, .oo-ui-dialog-content > .oo-ui-window-foot { diff --git a/resources/lib/oojs-ui/oojs-ui-apex.js b/resources/lib/oojs-ui/oojs-ui-apex.js index 690634713e..f8be2bb274 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.2 + * OOjs UI v0.12.3 * 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-07-28T23:01:32Z + * Date: 2015-08-11T22:34:00Z */ /** * @class diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css b/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css index d686ad9231..da5f890a42 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.2 + * OOjs UI v0.12.3 * 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-07-28T23:01:40Z + * Date: 2015-08-11T22:34:09Z */ @-webkit-keyframes oo-ui-progressBarWidget-slide { from { @@ -554,6 +554,25 @@ .oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label { color: #cccccc; } +.oo-ui-fieldLayout-messages { + list-style: none none; + margin: 0; + padding: 0; + margin-top: 0.25em; + margin-left: 0.25em; +} +.oo-ui-fieldLayout-messages > li { + margin: 0; + padding: 0; +} +.oo-ui-fieldLayout-messages .oo-ui-iconWidget { + margin-right: 0.5em; +} +.oo-ui-fieldLayout-messages .oo-ui-labelWidget { + padding: 0; + line-height: 1.875em; + vertical-align: middle; +} .oo-ui-actionFieldLayout-input, .oo-ui-actionFieldLayout-button { display: table-cell; @@ -730,6 +749,21 @@ display: block; position: relative; } +.oo-ui-horizontalLayout > .oo-ui-widget { + display: inline-block; + vertical-align: middle; +} +.oo-ui-horizontalLayout > .oo-ui-layout { + display: inline-block; +} +.oo-ui-horizontalLayout > .oo-ui-layout, +.oo-ui-horizontalLayout > .oo-ui-widget { + margin-right: 0.5em; +} +.oo-ui-horizontalLayout > .oo-ui-layout:last-child, +.oo-ui-horizontalLayout > .oo-ui-widget:last-child { + margin-right: 0; +} .oo-ui-popupTool .oo-ui-popupWidget-popup, .oo-ui-popupTool .oo-ui-popupWidget-anchor { z-index: 4; @@ -1178,11 +1212,12 @@ border: 0; border-radius: 0; margin: 0; - padding: 1.0546875em 0.3125em; + padding: 0 0.3125em; } .oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { margin: 0 1em; - line-height: inherit; + line-height: 3.125em; + /* 40/12.8 */ } .oo-ui-optionWidget { position: relative; @@ -1401,9 +1436,15 @@ -o-transform: translateZ(0px); transform: translateZ(0px); height: 2em; - width: 4em; + width: 3.5em; border-radius: 1em; - border: 1px #dddddd solid; + border: 1px #555555 solid; + background: #ffffff; + -webkit-transition: background-color 0.1s ease-in-out; + -moz-transition: background-color 0.1s ease-in-out; + -ms-transition: background-color 0.1s ease-in-out; + -o-transition: background-color 0.1s ease-in-out; + transition: background-color 0.1s ease-in-out; margin-right: 0.5em; } .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled { @@ -1435,14 +1476,13 @@ margin-right: 0; } .oo-ui-toggleSwitchWidget-grip { - top: 0.25em; - left: 0.25em; - width: 1.5em; - height: 1.5em; + top: 0.5em; + left: 0.5em; + width: 1em; + height: 1em; margin-top: -1px; border-radius: 1em; - border: 1px #dddddd solid; - background-color: #f7f7f7; + background: #555555; -webkit-transition: left 0.1s ease-in-out, margin-left 0.1s ease-in-out; -moz-transition: left 0.1s ease-in-out, margin-left 0.1s ease-in-out; -ms-transition: left 0.1s ease-in-out, margin-left 0.1s ease-in-out; @@ -1450,40 +1490,48 @@ transition: left 0.1s ease-in-out, margin-left 0.1s ease-in-out; } .oo-ui-toggleSwitchWidget-glow { - border-radius: 1em; - background-color: #f7f7f7; - -webkit-transition: background-color 0.1s ease-in-out; - -moz-transition: background-color 0.1s ease-in-out; - -ms-transition: background-color 0.1s ease-in-out; - -o-transition: background-color 0.1s ease-in-out; - transition: background-color 0.1s ease-in-out; + display: none; } .oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip { - left: 2.25em; + left: 2em; margin-left: -2px; } -.oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow { - display: block; -} .oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip { - left: 0.25em; + left: 0.5em; margin-left: 0; } -.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled { - border: 1px #cccccc solid; +.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on { + background: #347bff; + border-color: #347bff; +} +.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip { + background: #ffffff; +} +.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus { + outline: none; + border-color: #347bff; +} +.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus.oo-ui-toggleWidget-on { + border-color: #ffffff; + box-shadow: 0 0 0 1px #347bff; } .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover { - border-color: #aaaaaa; + border-color: #2962cc; + box-shadow: 0 0 0 1px #2962cc; } -.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled .oo-ui-toggleSwitchWidget-grip { - background-color: #ffffff; - border-color: #aaaaaa; +.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover.oo-ui-toggleWidget-on { + background: #2962cc; + border-color: #2962cc; } -.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-glow { - background-color: #d0d0d0; +.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip { + background: #ffffff; } -.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow { - background-color: #ffffff; +.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled { + background: #dddddd; + border-color: #dddddd; +} +.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled .oo-ui-toggleSwitchWidget-grip { + background: #ffffff; } .oo-ui-progressBarWidget { max-width: 50em; @@ -2405,6 +2453,154 @@ background-color: #ffffff; color: #333333; } +.oo-ui-capsuleMultiSelectWidget { + display: inline-block; + position: relative; + width: 100%; + max-width: 50em; +} +.oo-ui-capsuleMultiSelectWidget-handle { + width: 100%; + display: inline-block; + position: relative; +} +.oo-ui-capsuleMultiSelectWidget-group { + display: inline; +} +.oo-ui-capsuleMultiSelectWidget > .oo-ui-menuSelectWidget { + z-index: 1; + width: 100%; +} +.oo-ui-capsuleMultiSelectWidget-handle { + background: #ffffff; + cursor: text; + min-height: 2.35em; + margin-right: 0.5em; + padding: 0.25em 0; + border: 1px solid #cccccc; + border-radius: 0.1em; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.oo-ui-capsuleMultiSelectWidget-handle:last-child { + margin-right: 0; +} +.oo-ui-capsuleMultiSelectWidget-handle .oo-ui-capsuleMultiSelectWidget-group { + margin: 0 0.2em; +} +.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator, +.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon { + position: absolute; + background-position: center center; + background-repeat: no-repeat; +} +.oo-ui-capsuleMultiSelectWidget-handle > input { + border: none; + min-width: 1em; + max-width: 100%; + line-height: 1.675em; + margin: 0; + padding: 0; + font-size: inherit; + font-family: inherit; + background-color: transparent; + color: black; + vertical-align: middle; +} +.oo-ui-capsuleMultiSelectWidget-handle > input:focus { + outline: none; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle { + padding-right: 0.9375em; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator { + right: 0; + top: 0; + width: 0.9375em; + height: 0.9375em; + margin: 0.775em; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle { + padding-left: 1.875em; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon { + left: 0; + top: 0; + width: 1.875em; + height: 1.875em; + margin: 0.3em; +} +.oo-ui-capsuleMultiSelectWidget:hover .oo-ui-capsuleMultiSelectWidget-handle { + border-color: #aaaaaa; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle { + color: #cccccc; + text-shadow: 0 1px 1px #ffffff; + border-color: #dddddd; + background-color: #f3f3f3; + cursor: default; +} +.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon, +.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator { + opacity: 0.2; +} +.oo-ui-capsuleMultiSelectWidget .oo-ui-selectWidget { + border-top-color: #ffffff; +} +.oo-ui-capsuleItemWidget { + position: relative; + display: inline-block; + cursor: default; + white-space: nowrap; + width: auto; + max-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + vertical-align: middle; + padding: 0.2em; + margin: 0 0.1em; + height: 1.675em; + background-color: #ffffff; + border: 1px solid #cccccc; + color: #555555; + border-radius: 0.2em; +} +.oo-ui-capsuleItemWidget > .oo-ui-iconElement-icon { + cursor: pointer; +} +.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon { + cursor: default; +} +.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label { + display: block; + text-overflow: ellipsis; + overflow: hidden; +} +.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-labelElement-label { + padding-right: 1.3375em; +} +.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator { + position: absolute; + right: 0.2em; + top: 0; + width: 0.9375em; + height: 100%; + background-repeat: no-repeat; +} +.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicator-clear { + cursor: pointer; +} +.oo-ui-capsuleItemWidget.oo-ui-widget-disabled { + color: #cccccc; + text-shadow: 0 1px 1px #ffffff; + border-color: #dddddd; + background-color: #f3f3f3; +} +.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator { + opacity: 0.2; +} .oo-ui-comboBoxWidget { display: inline-block; position: relative; @@ -2528,9 +2724,6 @@ /* @noflip */ left: 0; } -.oo-ui-dialog { - z-index: 1000; -} .oo-ui-dialog-content > .oo-ui-window-head, .oo-ui-dialog-content > .oo-ui-window-body, .oo-ui-dialog-content > .oo-ui-window-foot { diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki.js b/resources/lib/oojs-ui/oojs-ui-mediawiki.js index f226800eb5..cb475829d1 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.2 + * OOjs UI v0.12.3 * 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-07-28T23:01:32Z + * Date: 2015-08-11T22:34:00Z */ /** * @class diff --git a/resources/lib/oojs-ui/oojs-ui.js b/resources/lib/oojs-ui/oojs-ui.js index ed239a6e3e..dd93fe3ed1 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.2 + * OOjs UI v0.12.3 * 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-07-28T23:01:32Z + * Date: 2015-08-11T22:34:00Z */ ( function ( OO ) { @@ -84,11 +84,12 @@ OO.ui.isFocusableElement = function ( $element ) { !$element.parents().addBack().filter( function () { return $.css( this, 'visibility' ) === 'hidden'; } ).length - ); + ), + isTabOk = isNaN( $element.attr( 'tabindex' ) ) || +$element.attr( 'tabindex' ) >= 0; return ( ( isInElementGroup ? !node.disabled : isOtherElement ) && - isVisible + isVisible && isTabOk ); }; @@ -318,6 +319,34 @@ OO.ui.infuse = function ( idOrNode ) { return msg; }; + /** + * @param {string} url + * @return {boolean} + */ + OO.ui.isSafeUrl = function ( url ) { + var protocol, + // Keep in sync with php/Tag.php + whitelist = [ + '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:' + ]; + + if ( url.indexOf( ':' ) === -1 ) { + // No protocol, safe + return true; + } + + protocol = url.split( ':', 1 )[0] + ':'; + if ( !protocol.match( /^([A-za-z0-9\+\.\-])+:/ ) ) { + // Not a valid protocol, safe + return true; + } + + // Safe if in the whitelist + return $.inArray( protocol, whitelist ) !== -1; + }; + } )(); /*! @@ -1076,7 +1105,7 @@ OO.ui.Element.static.tagName = 'div'; * DOM node. */ OO.ui.Element.static.infuse = function ( idOrNode ) { - var obj = OO.ui.Element.static.unsafeInfuse( idOrNode, true ); + var obj = OO.ui.Element.static.unsafeInfuse( idOrNode, false ); // Verify that the type matches up. // FIXME: uncomment after T89721 is fixed (see T90929) /* @@ -1092,12 +1121,14 @@ OO.ui.Element.static.infuse = function ( idOrNode ) { * extra property so that only the top-level invocation touches the DOM. * @private * @param {string|HTMLElement|jQuery} idOrNode - * @param {boolean} top True only for top-level invocation. + * @param {jQuery.Promise|boolean} domPromise A promise that will be resolved + * when the top-level widget of this infusion is inserted into DOM, + * replacing the original node; or false for top-level invocation. * @return {OO.ui.Element} */ -OO.ui.Element.static.unsafeInfuse = function ( idOrNode, top ) { +OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) { // look for a cached result of a previous infusion. - var id, $elem, data, cls, parts, parent, obj; + var id, $elem, data, cls, parts, parent, obj, top, state; if ( typeof idOrNode === 'string' ) { id = idOrNode; $elem = $( document.getElementById( id ) ); @@ -1105,7 +1136,10 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, top ) { $elem = $( idOrNode ); id = $elem.attr( 'id' ); } - data = $elem.data( 'ooui-infused' ); + if ( !$elem.length ) { + throw new Error( 'Widget not found: ' + id ); + } + data = $elem.data( 'ooui-infused' ) || $elem[0].oouiInfused; if ( data ) { // cached! if ( data === true ) { @@ -1113,9 +1147,6 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, top ) { } return data; } - if ( !$elem.length ) { - throw new Error( 'Widget not found: ' + id ); - } data = $elem.attr( 'data-ooui' ); if ( !data ) { throw new Error( 'No infusion data found: ' + id ); @@ -1159,12 +1190,16 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, top ) { throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ ); } + if ( domPromise === false ) { + top = $.Deferred(); + domPromise = top.promise(); + } $elem.data( 'ooui-infused', true ); // prevent loops data.id = id; // implicit data = OO.copy( data, null, function deserialize( value ) { if ( OO.isPlainObject( value ) ) { if ( value.tag ) { - return OO.ui.Element.static.unsafeInfuse( value.tag, false ); + return OO.ui.Element.static.unsafeInfuse( value.tag, domPromise ); } if ( value.html ) { return new OO.ui.HtmlSnippet( value.html ); @@ -1173,13 +1208,22 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, top ) { } ); // jscs:disable requireCapitalizedConstructors obj = new cls( data ); // rebuild widget + // pick up dynamic state, like focus, value of form inputs, scroll position, etc. + state = obj.gatherPreInfuseState( $elem ); // now replace old DOM with this new DOM. if ( top ) { $elem.replaceWith( obj.$element ); + // This element is now gone from the DOM, but if anyone is holding a reference to it, + // let's allow them to OO.ui.infuse() it and do what they expect (T105828). + // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design. + $elem[0].oouiInfused = obj; + top.resolve(); } obj.$element.data( 'ooui-infused', obj ); // set the 'data-ooui' attribute so we can identify infused widgets obj.$element.attr( 'data-ooui', '' ); + // restore dynamic state after the new element is inserted into DOM + domPromise.done( obj.restorePreInfuseState.bind( obj, state ) ); return obj; }; @@ -1753,12 +1797,41 @@ OO.ui.Element.prototype.scrollElementIntoView = function ( config ) { return OO.ui.Element.static.scrollIntoView( this.$element[ 0 ], config ); }; +/** + * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of a HTML DOM node + * (and its children) that represent an Element of the same type and configuration as the current + * one, generated by the PHP implementation. + * + * This method is called just before `node` is detached from the DOM. The return value of this + * function will be passed to #restorePreInfuseState after this widget's #$element is inserted into + * DOM to replace `node`. + * + * @protected + * @param {HTMLElement} node + * @return {Object} + */ +OO.ui.Element.prototype.gatherPreInfuseState = function () { + return {}; +}; + +/** + * Restore the pre-infusion dynamic state for this widget. + * + * This method is called after #$element has been inserted into DOM. The parameter is the return + * value of #gatherPreInfuseState. + * + * @protected + * @param {Object} state + */ +OO.ui.Element.prototype.restorePreInfuseState = function () { +}; + /** * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in a way * that is centrally controlled and can be updated dynamically. Layouts can be, and usually are, combined. * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout}, {@link OO.ui.FormLayout FormLayout}, * {@link OO.ui.PanelLayout PanelLayout}, {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout}, - * and {@link OO.ui.BookletLayout BookletLayout} for more information and examples. + * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout} for more information and examples. * * @abstract * @class @@ -2090,7 +2163,27 @@ OO.ui.Window.prototype.getManager = function () { * @return {string} Symbolic name of the size: `small`, `medium`, `large`, `larger`, `full` */ OO.ui.Window.prototype.getSize = function () { - return this.size; + var viewport = OO.ui.Element.static.getDimensions( this.getElementWindow() ), + sizes = this.manager.constructor.static.sizes, + size = this.size; + + if ( !sizes[ size ] ) { + size = this.manager.constructor.static.defaultSize; + } + if ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) { + size = 'full'; + } + + return size; +}; + +/** + * Get the size properties associated with the current window size + * + * @return {Object} Size properties + */ +OO.ui.Window.prototype.getSizeProperties = function () { + return this.manager.constructor.static.sizes[ this.getSize() ]; }; /** @@ -3423,20 +3516,11 @@ OO.ui.WindowManager.prototype.updateWindowSize = function ( win ) { return; } - var viewport = OO.ui.Element.static.getDimensions( win.getElementWindow() ), - sizes = this.constructor.static.sizes, - size = win.getSize(); - - if ( !sizes[ size ] ) { - size = this.constructor.static.defaultSize; - } - if ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) { - size = 'full'; - } + var isFullscreen = win.getSize() === 'full'; - this.$element.toggleClass( 'oo-ui-windowManager-fullscreen', size === 'full' ); - this.$element.toggleClass( 'oo-ui-windowManager-floating', size !== 'full' ); - win.setDimensions( sizes[ size ] ); + this.$element.toggleClass( 'oo-ui-windowManager-fullscreen', isFullscreen ); + this.$element.toggleClass( 'oo-ui-windowManager-floating', !isFullscreen ); + win.setDimensions( win.getSizeProperties() ); this.emit( 'resize', win ); @@ -6174,7 +6258,8 @@ OO.ui.mixin.FlaggedElement.prototype.setFlaggedElement = function ( $flagged ) { * @return {boolean} The flag is set */ OO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) { - return flag in this.flags; + // This may be called before the constructor, thus before this.flags is set + return this.flags && ( flag in this.flags ); }; /** @@ -6183,7 +6268,8 @@ OO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) { * @return {string[]} Flag names */ OO.ui.mixin.FlaggedElement.prototype.getFlags = function () { - return Object.keys( this.flags ); + // This may be called before the constructor, thus before this.flags is set + return Object.keys( this.flags || {} ); }; /** @@ -8169,6 +8255,9 @@ OO.ui.ProcessDialog = function OoUiProcessDialog( config ) { // Parent constructor OO.ui.ProcessDialog.parent.call( this, config ); + // Properties + this.fitOnOpen = false; + // Initialization this.$element.addClass( 'oo-ui-processDialog' ); }; @@ -8310,6 +8399,16 @@ OO.ui.ProcessDialog.prototype.executeAction = function ( action ) { } ); }; +/** + * @inheritdoc + */ +OO.ui.ProcessDialog.prototype.setDimensions = function () { + // Parent method + OO.ui.ProcessDialog.parent.prototype.setDimensions.apply( this, arguments ); + + this.fitLabel(); +}; + /** * Fit label between actions. * @@ -8317,15 +8416,31 @@ OO.ui.ProcessDialog.prototype.executeAction = function ( action ) { * @chainable */ OO.ui.ProcessDialog.prototype.fitLabel = function () { - var safeWidth, primaryWidth, biggerWidth, labelWidth, navigationWidth, leftWidth, rightWidth; + var safeWidth, primaryWidth, biggerWidth, labelWidth, navigationWidth, leftWidth, rightWidth, + size = this.getSizeProperties(); + + if ( typeof size.width !== 'number' ) { + if ( this.isOpened() ) { + navigationWidth = this.$head.width() - 20; + } else if ( this.isOpening() ) { + if ( !this.fitOnOpen ) { + // Size is relative and the dialog isn't open yet, so wait. + this.manager.opening.done( this.fitLabel.bind( this ) ); + this.fitOnOpen = true; + } + return; + } else { + return; + } + } else { + navigationWidth = size.width - 20; + } safeWidth = this.$safeActions.is( ':visible' ) ? this.$safeActions.width() : 0; primaryWidth = this.$primaryActions.is( ':visible' ) ? this.$primaryActions.width() : 0; biggerWidth = Math.max( safeWidth, primaryWidth ); labelWidth = this.title.$element.width(); - // Is there a better way to calculate this? - navigationWidth = OO.ui.WindowManager.static.sizes[ this.getSize() ].width - 20; if ( 2 * biggerWidth + labelWidth < navigationWidth ) { // We have enough space to center the label @@ -8419,6 +8534,7 @@ OO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) { .first( function () { // Make sure to hide errors this.hideErrors(); + this.fitOnOpen = false; }, this ); }; @@ -8445,13 +8561,19 @@ OO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) { * @class * @extends OO.ui.Layout * @mixins OO.ui.mixin.LabelElement + * @mixins OO.ui.mixin.TitledElement * * @constructor * @param {OO.ui.Widget} fieldWidget Field widget * @param {Object} [config] Configuration options * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top' or 'inline' - * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a help icon will appear - * in the upper-right corner of the rendered field. + * @cfg {Array} [errors] Error messages about the widget, which will be displayed below the widget. + * The array may contain strings or OO.ui.HtmlSnippet instances. + * @cfg {Array} [notices] Notices about the widget, which will be displayed below the widget. + * The array may contain strings or OO.ui.HtmlSnippet instances. + * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear + * in the upper-right corner of the rendered field; clicking it will display the text in a popup. + * For important messages, you are advised to use `notices`, as they are always shown. */ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) { // Allow passing positional parameters inside the config object @@ -8461,7 +8583,7 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) { } var hasInputWidget = fieldWidget.constructor.static.supportsSimpleLabel, - div; + div, i; // Configuration initialization config = $.extend( { align: 'left' }, config ); @@ -8471,10 +8593,14 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) { // Mixin constructors OO.ui.mixin.LabelElement.call( this, config ); + OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) ); // Properties this.fieldWidget = fieldWidget; + this.errors = config.errors || []; + this.notices = config.notices || []; this.$field = $( '
' ); + this.$messages = $( '