Update OOjs UI to v0.21.0
authorVolker E <volker.e@wikimedia.org>
Tue, 11 Apr 2017 23:41:59 +0000 (16:41 -0700)
committerVolker E <volker.e@wikimedia.org>
Tue, 11 Apr 2017 23:41:59 +0000 (16:41 -0700)
Release notes:
 https://phabricator.wikimedia.org/diffusion/GOJU/browse/master/History.md;v0.21.0

Change-Id: I94d5b7a89551e7d34d53223872ad3005f0ac4a04

40 files changed:
composer.json
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/images/icons/articles-ltr.svg
resources/lib/oojs-ui/themes/apex/images/icons/articles-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articles-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articles-ltr-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articles-ltr.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articles-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articles-rtl-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articles-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up.png
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up.svg
resources/lib/oojs-ui/themes/mediawiki/indicators.json

index 81abe40..44a5eb4 100644 (file)
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.20.2",
+               "oojs/oojs-ui": "0.21.0",
                "oyejorge/less.php": "1.7.0.14",
                "php": ">=5.5.9",
                "psr/log": "1.0.2",
index f390b56..be94720 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:37Z
+ * Date: 2017-04-11T22:51:05Z
  */
 ( function ( OO ) {
 
index 624cc57..0313da4 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
 .oo-ui-element-hidden {
   display: none !important;
@@ -838,14 +838,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
   cursor: auto;
 }
-.oo-ui-popupButtonWidget-frameless-popup.oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor,
-.oo-ui-popupButtonWidget-frameless-popup.oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor {
-  margin-left: 0.9375em;
-}
-.oo-ui-popupButtonWidget-framed-popup.oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor,
-.oo-ui-popupButtonWidget-framed-popup.oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor {
-  margin-left: 1.2375em;
-}
 .oo-ui-inputWidget {
   margin-right: 0.5em;
 }
@@ -977,13 +969,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   cursor: pointer;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
-.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-     -moz-user-select: none;
-      -ms-user-select: none;
-          user-select: none;
-}
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea,
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
   -webkit-touch-callout: none;
   -webkit-user-select: none;
@@ -1032,27 +1018,27 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget input::-webkit-input-placeholder,
 .oo-ui-textInputWidget textarea::-webkit-input-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-textInputWidget input:-ms-input-placeholder,
 .oo-ui-textInputWidget textarea:-ms-input-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-textInputWidget input::-moz-placeholder,
 .oo-ui-textInputWidget textarea::-moz-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-textInputWidget input:-moz-placeholder,
 .oo-ui-textInputWidget textarea:-moz-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-textInputWidget input::placeholder,
 .oo-ui-textInputWidget textarea::placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
@@ -1063,7 +1049,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
-  color: #777;
+  color: #767676;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
@@ -1103,7 +1089,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
   padding: 0.4em;
   line-height: 1.5em;
-  color: #888;
+  color: #767676;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
   margin-right: 2.0875em;
@@ -1148,9 +1134,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   background-color: #e1f3ff;
 }
 .oo-ui-menuSectionOptionWidget {
-  cursor: default;
   padding: 0.33em 0.75em;
-  color: #888;
+  color: #767676;
+}
+.oo-ui-menuSectionOptionWidget.oo-ui-widget-enabled {
+  cursor: default;
 }
 .oo-ui-dropdownWidget {
   display: inline-block;
@@ -1161,6 +1149,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-right: 0.5em;
 }
 .oo-ui-dropdownWidget-handle {
+  position: relative;
   width: 100%;
   display: block;
   white-space: nowrap;
@@ -1263,7 +1252,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   height: 2.5em;
   padding: 0;
 }
-.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
+.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorWidget {
+  display: block;
+  position: absolute;
+  top: 0;
+  height: 100%;
   pointer-events: none;
 }
 .oo-ui-comboBoxInputWidget:last-child {
@@ -1282,6 +1275,12 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   visibility: visible;
   margin: 0.775em;
 }
+.oo-ui-comboBoxInputWidget-php .oo-ui-indicatorWidget {
+  right: 0;
+  max-height: 2.375em;
+  margin: 0;
+  margin-right: 0.775em;
+}
 .oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
   cursor: default;
   opacity: 0.2;
index bff0f50..4cc49c8 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
 .oo-ui-element-hidden {
   display: none !important;
   text-align: center;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
+  position: relative;
   font-weight: bold;
   text-decoration: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
-  border-radius: 2px;
   outline: 0;
 }
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-  margin-right: 0.25em;
-  margin-left: 0.46875em;
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  display: block;
+}
+.oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement > input.oo-ui-buttonElement-button {
+  line-height: 1;
+}
+.oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  line-height: 1.172em;
+}
+.oo-ui-buttonElement.oo-ui-labelElement.oo-ui-iconElement > .oo-ui-buttonElement-button {
+  padding-left: 2.03125em;
+}
+.oo-ui-buttonElement.oo-ui-labelElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
+  padding-right: 2.5em;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  display: block;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-indicatorElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  right: 0.9375em;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
   -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
 .oo-ui-buttonElement.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   opacity: 1;
 }
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
-  margin-right: 0;
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button {
+  border-radius: 1px;
+}
+.oo-ui-buttonElement-frameless.oo-ui-iconElement > .oo-ui-buttonElement-button {
+  min-width: 1.875em;
+  min-height: 1.875em;
+}
+.oo-ui-buttonElement-frameless.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  left: 0;
 }
-.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  margin-left: 0.25em;
-  margin-right: 0.25em;
+.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button {
+  margin-left: -1px;
+  border: 1px solid #fff;
+  padding: 0.3125em 0;
 }
-.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
-  padding-left: 0.25em;
-  padding-right: 0.25em;
+.oo-ui-buttonElement-frameless.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
+  min-width: 0.9375em;
+  min-height: 0.9375em;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
   color: #222;
   color: #444;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-  box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
+  box-shadow: 0 0 0 2px #36c;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:active {
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   opacity: 0.51;
 }
-.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 {
-  position: relative;
   min-height: 2.5em;
   border-radius: 2px;
-  padding: 0.625em 1em 0.546875em;
+  padding: 0.625em 0.9375em 0.546875em;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button {
-  min-width: 3.125em;
+  padding-left: 2.03125em;
 }
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
-  min-width: 0;
-}
-.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button {
-  line-height: 1;
+.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  left: 0.546875em;
 }
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  line-height: 1.172em;
+.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.5em;
 }
-.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  display: block;
-  position: absolute;
-  top: 0;
-  height: 100%;
-  left: 0.5625em;
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  left: 0.46875em;
 }
-.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 {
+  padding-right: 2.03125em;
 }
-.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-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  right: 1.015625em;
 }
-.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-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement > .oo-ui-buttonElement-button {
+  padding-right: 2.5em;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
   background-color: #c8ccd1;
@@ -694,7 +713,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   color: #72777d;
 }
 .oo-ui-decoratedOptionWidget {
-  padding: 0.5em 2em 0.5em 3em;
+  padding: 0.703125em 0.9375em 0.625em;
+  line-height: 1;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
@@ -705,11 +725,17 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   top: 0;
   height: 100%;
 }
+.oo-ui-decoratedOptionWidget.oo-ui-iconElement {
+  padding-left: 2.5em;
+}
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  left: 0.5em;
+  left: 0.46875em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-labelElement-label {
+  line-height: 1.172em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  right: 0.5em;
+  right: 0.9375em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
@@ -989,14 +1015,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
   cursor: auto;
 }
-.oo-ui-popupButtonWidget-frameless-popup.oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor,
-.oo-ui-popupButtonWidget-frameless-popup.oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor {
-  margin-left: 0.9375em;
-}
-.oo-ui-popupButtonWidget-framed-popup.oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor,
-.oo-ui-popupButtonWidget-framed-popup.oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor {
-  margin-left: 1.5em;
-}
 .oo-ui-inputWidget {
   margin-right: 0.5em;
 }
@@ -1149,7 +1167,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
           box-sizing: border-box;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0.5em 1em;
+  padding: 0.625em 0.9375em 0.546875em;
   font-size: inherit;
   font-family: inherit;
   vertical-align: middle;
@@ -1161,13 +1179,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   background-position: right 1.75em center;
   width: calc( 100% + 1em );
   height: 2.5em;
-  padding: 0 0 0 1em;
+  padding: 0 0 0 0.9375em;
 }
 .oo-ui-dropdownInputWidget option {
   font-size: inherit;
   font-family: inherit;
   height: 1.5em;
-  padding: 0.5em 1em;
+  padding: 0.625em 0.9375em;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select {
   background-color: #f8f9fa;
@@ -1367,13 +1385,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   cursor: pointer;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
-.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-     -moz-user-select: none;
-      -ms-user-select: none;
-          user-select: none;
-}
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea,
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
   -webkit-touch-callout: none;
   -webkit-user-select: none;
@@ -1410,7 +1422,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   color: #000;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0.625em 0.546875em 0.546875em;
+  padding: 0.625em 0.625em 0.546875em;
 }
 .oo-ui-textInputWidget input {
   line-height: 1.172em;
@@ -1513,34 +1525,31 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget.oo-ui-iconElement input,
 .oo-ui-textInputWidget.oo-ui-iconElement textarea {
-  padding-left: 2.875em;
+  padding-left: 2.5em;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  left: 0;
+  left: 0.46875em;
   max-height: 2.5em;
-  margin-left: 0.5em;
-  background-position: right center;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement input,
 .oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-  padding-right: 2.4875em;
+  padding-right: 2.1875em;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  height: 100%;
   max-height: 2.5em;
-  margin: 0 0.775em;
+  margin-right: 0.9375em;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
   color: #72777d;
   margin-top: 1px;
-  padding: 0.625em 0.546875em 0.546875em;
+  padding: 0.625em 0 0.546875em 0.625em;
   line-height: 1.172em;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-  margin-right: 2.0875em;
+  margin-right: 2.5em;
 }
 .oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
-  margin-left: 2.475em;
+  padding-left: 2.5em;
 }
 .oo-ui-menuSelectWidget {
   position: absolute;
@@ -1566,7 +1575,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   display: none;
 }
 .oo-ui-menuOptionWidget {
-  padding: 0.5em 1em;
   -webkit-transition: background-color 100ms, color 100ms;
      -moz-transition: background-color 100ms, color 100ms;
           transition: background-color 100ms, color 100ms;
@@ -1593,10 +1601,16 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   background-color: rgba(41, 98, 204, 0.1);
   color: #36c;
 }
+.oo-ui-menuOptionWidget.oo-ui-iconElement {
+  padding-left: 0.9375em;
+}
 .oo-ui-menuSectionOptionWidget {
-  cursor: default;
   color: #72777d;
-  padding: 0.33em 0.75em;
+  padding: 0.703125em 0.9375em 0.3125em;
+  font-weight: bold;
+}
+.oo-ui-menuSectionOptionWidget.oo-ui-widget-enabled {
+  cursor: default;
 }
 .oo-ui-dropdownWidget {
   display: inline-block;
@@ -1606,6 +1620,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-right: 0.5em;
 }
 .oo-ui-dropdownWidget-handle {
+  position: relative;
   width: 100%;
   display: block;
   white-space: nowrap;
@@ -1634,22 +1649,26 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-right: 0;
 }
 .oo-ui-dropdownWidget-handle {
-  padding: 0.546875em 0;
-  height: 2.5em;
-  line-height: 1.275;
+  min-height: 2.5em;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-  right: 0;
-  margin: 0 0.775em;
+  padding: 0.625em 0.9375em 0.546875em;
+  line-height: 1;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-  left: 0.25em;
-  margin: 0 0.3em;
+  left: 0.46875em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+  right: 0.9375em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-  margin: 0 1em;
+  line-height: 1.172em;
+}
+.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle {
+  padding-left: 2.5em;
+}
+.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle {
+  padding-right: 1.875em;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
   background-color: #f8f9fa;
@@ -1702,12 +1721,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
   opacity: 0.15;
 }
-.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-  margin-left: 3em;
-}
-.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-  margin-right: 2em;
-}
 .oo-ui-comboBoxInputWidget {
   display: inline-block;
   position: relative;
@@ -1742,7 +1755,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   height: 2.5em;
   padding: 0;
 }
-.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
+.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorWidget {
+  display: block;
+  position: absolute;
+  top: 0;
+  height: 100%;
   pointer-events: none;
 }
 .oo-ui-comboBoxInputWidget input {
@@ -1757,20 +1774,26 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-bottom-right-radius: 2px;
   border-right-width: 1px;
 }
-.oo-ui-comboBoxInputWidget-dropdownButton {
+.oo-ui-comboBoxInputWidget-dropdownButton.oo-ui-indicatorElement {
   width: 2.5em;
 }
-.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button {
+.oo-ui-comboBoxInputWidget-dropdownButton.oo-ui-indicatorElement .oo-ui-buttonElement-button {
   min-width: 2.5em;
   min-height: 2.5em;
   padding-left: 0;
-  padding-right: 0;
 }
-.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button,
-.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button:focus {
+.oo-ui-comboBoxInputWidget-dropdownButton.oo-ui-indicatorElement .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  right: 0.703125em;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton.oo-ui-indicatorElement .oo-ui-buttonElement-button,
+.oo-ui-comboBoxInputWidget-dropdownButton.oo-ui-indicatorElement .oo-ui-buttonElement-button:focus {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
+.oo-ui-comboBoxInputWidget-php .oo-ui-indicatorWidget {
+  right: 0.9375em;
+  margin: 0;
+}
 .oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
   opacity: 1;
 }
index 44b21ab..e566d96 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:37Z
+ * Date: 2017-04-11T22:51:05Z
  */
 ( function ( OO ) {
 
@@ -73,10 +73,10 @@ OO.ui.generateElementId = function () {
 
 /**
  * Check if an element is focusable.
- * Inspired from :focusable in jQueryUI v1.11.4 - 2015-04-14
+ * Inspired by :focusable in jQueryUI v1.11.4 - 2015-04-14
  *
  * @param {jQuery} $element Element to test
- * @return {boolean}
+ * @return {boolean} Element is focusable
  */
 OO.ui.isFocusableElement = function ( $element ) {
        var nodeName,
@@ -131,7 +131,7 @@ OO.ui.isFocusableElement = function ( $element ) {
  *
  * @param {jQuery} $container Container to search in
  * @param {boolean} [backwards] Search backwards
- * @return {jQuery} Focusable child, an empty jQuery object if none found
+ * @return {jQuery} Focusable child, or an empty jQuery object if none found
  */
 OO.ui.findFocusable = function ( $container, backwards ) {
        var $focusable = $( [] ),
@@ -235,10 +235,10 @@ OO.ui.contains = function ( containers, contained, matchContainers ) {
  *
  * Ported from: http://underscorejs.org/underscore.js
  *
- * @param {Function} func
- * @param {number} wait
- * @param {boolean} immediate
- * @return {Function}
+ * @param {Function} func Function to debounce
+ * @param {number} [wait=0] Wait period in milliseconds
+ * @param {boolean} [immediate] Trigger on leading edge
+ * @return {Function} Debounced function
  */
 OO.ui.debounce = function ( func, wait, immediate ) {
        var timeout;
@@ -264,7 +264,7 @@ OO.ui.debounce = function ( func, wait, immediate ) {
 /**
  * Puts a console warning with provided message.
  *
- * @param {string} message
+ * @param {string} message Message
  */
 OO.ui.warnDeprecation = function ( message ) {
        if ( OO.getProp( window, 'console', 'warn' ) !== undefined ) {
@@ -282,9 +282,9 @@ OO.ui.warnDeprecation = function ( message ) {
  * when the wrapper is called, return values from the function are entirely
  * discarded.
  *
- * @param {Function} func
- * @param {number} wait
- * @return {Function}
+ * @param {Function} func Function to throttle
+ * @param {number} wait Throttle window length, in milliseconds
+ * @return {Function} Throttled function
  */
 OO.ui.throttle = function ( func, wait ) {
        var context, args, timeout,
@@ -319,7 +319,7 @@ OO.ui.throttle = function ( func, wait ) {
 /**
  * A (possibly faster) way to get the current timestamp as an integer
  *
- * @return {number} Current timestamp
+ * @return {number} Current timestamp, in milliseconds since the Unix epoch
  */
 OO.ui.now = Date.now || function () {
        return new Date().getTime();
@@ -3583,9 +3583,11 @@ OO.ui.ButtonWidget.prototype.setNoFollow = function ( noFollow ) {
 // Override method visibility hints from ButtonElement
 /**
  * @method setActive
+ * @inheritdoc
  */
 /**
  * @method isActive
+ * @inheritdoc
  */
 
 /**
@@ -4560,7 +4562,7 @@ OO.ui.mixin.ClippableElement.prototype.isClippedVertically = function () {
 };
 
 /**
- * Set the ideal size. These are the dimensions the element will have when it's not being clipped.
+ * Set the ideal size. These are the dimensions #$clippable will have when it's not being clipped.
  *
  * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix
  * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix
@@ -4645,7 +4647,7 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
        } else {
                this.$clippable.css( {
                        overflowX: '',
-                       width: this.idealWidth ? this.idealWidth - extraWidth : '',
+                       width: this.idealWidth || '',
                        maxWidth: Math.max( 0, allotedWidth )
                } );
        }
@@ -4661,7 +4663,7 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
        } else {
                this.$clippable.css( {
                        overflowY: '',
-                       height: this.idealHeight ? this.idealHeight - extraHeight : '',
+                       height: this.idealHeight || '',
                        maxHeight: Math.max( 0, allotedHeight )
                } );
        }
@@ -4710,8 +4712,10 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
  * @cfg {number} [height] Height of popup in pixels. Omit to use the automatic height.
  * @cfg {boolean} [anchor=true] Show anchor pointing to origin of popup
  * @cfg {string} [position='below'] Where to position the popup relative to $floatableContainer
- *  'above': Put popup above $floatableContainer; anchor points down to the start edge of $floatableContainer
- *  'below': Put popup below $floatableContainer; anchor points up to the start edge of $floatableContainer
+ *  'above': Put popup above $floatableContainer; anchor points down to the horizontal center
+ *           of $floatableContainer
+ *  'below': Put popup below $floatableContainer; anchor points up to the horizontal center
+ *           of $floatableContainer
  *  'before': Put popup to the left (LTR) / right (RTL) of $floatableContainer; anchor points
  *            endwards (right/left) to the vertical center of $floatableContainer
  *  'after': Put popup to the right (LTR) / left (RTL) of $floatableContainer; anchor points
@@ -5148,8 +5152,7 @@ OO.ui.PopupWidget.prototype.computePosition = function () {
        }
 
        // Position the anchor (which is positioned relative to the popup) to point to $floatableContainer
-       // For popups above/below, we point to the start edge; for popups before/after, we point to the center
-       anchorPos = vertical ? ( floatablePos[ start ] + floatablePos[ end ] ) / 2 : floatablePos[ start ];
+       anchorPos = ( floatablePos[ start ] + floatablePos[ end ] ) / 2;
        anchorOffset = ( start === far ? -1 : 1 ) * ( anchorPos - popupPos[ start ] );
 
        // If the anchor is less than 2*anchorSize from either edge, move the popup to make more space
@@ -6734,8 +6737,10 @@ OO.ui.MenuSectionOptionWidget.static.highlightable = false;
  *  that toggles the menu's visibility on click, the menu will be hidden then re-shown when the user clicks
  *  that button, unless the button (or its parent widget) is passed in here.
  * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.
+ * @cfg {jQuery} [$autoCloseIgnore] If these elements are clicked, don't auto-hide the menu.
  * @cfg {boolean} [hideOnChoose=true] Hide the menu when the user chooses an option.
  * @cfg {boolean} [filterFromInput=false] Filter the displayed options from the input
+ * @cfg {boolean} [highlightOnFilter] Highlight the first result when filtering
  */
 OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        // Configuration initialization
@@ -6753,8 +6758,10 @@ OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        this.filterFromInput = !!config.filterFromInput;
        this.$input = config.$input ? config.$input : config.input ? config.input.$input : null;
        this.$widget = config.widget ? config.widget.$element : null;
+       this.$autoCloseIgnore = config.$autoCloseIgnore || $( [] );
        this.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );
        this.onInputEditHandler = OO.ui.debounce( this.updateItemVisibility.bind( this ), 100 );
+       this.highlightOnFilter = !!config.highlightOnFilter;
 
        // Initialization
        this.$element
@@ -6783,8 +6790,12 @@ OO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.ClippableElement );
  */
 OO.ui.MenuSelectWidget.prototype.onDocumentMouseDown = function ( e ) {
        if (
-               !OO.ui.contains( this.$element[ 0 ], e.target, true ) &&
-               ( !this.$widget || !OO.ui.contains( this.$widget[ 0 ], e.target, true ) )
+               this.isVisible() &&
+               !OO.ui.contains(
+                               this.$element.add( this.$widget ).add( this.$autoCloseIgnore ).get(),
+                               e.target,
+                               true
+               )
        ) {
                this.toggle( false );
        }
@@ -6831,6 +6842,7 @@ OO.ui.MenuSelectWidget.prototype.onKeyDown = function ( e ) {
  */
 OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
        var i, item, visible, section, sectionEmpty,
+               firstItemFound = false,
                anyVisible = false,
                len = this.items.length,
                showAll = !this.isVisible(),
@@ -6852,6 +6864,11 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
                        anyVisible = anyVisible || visible;
                        sectionEmpty = sectionEmpty && !visible;
                        item.toggle( visible );
+                       if ( this.highlightOnFilter && visible && !firstItemFound ) {
+                               // Highlight the first item in the list
+                               this.highlightItem( item );
+                               firstItemFound = true;
+                       }
                }
        }
        // Process the final section
@@ -7832,6 +7849,7 @@ OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) {
  *   Deprecated, omit this parameter and specify `$container` instead.
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$container=inputWidget.$element] Element to render menu under
+ * @cfg {number} [width] Width of the menu
  */
 OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWidget, config ) {
        // Allow 'inputWidget' parameter and config for backwards compatibility
@@ -7843,6 +7861,8 @@ OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWid
        // Configuration initialization
        config = config || {};
 
+       this.width = config.width;
+
        // Parent constructor
        OO.ui.FloatingMenuSelectWidget.parent.call( this, config );
 
@@ -7876,7 +7896,7 @@ OO.ui.FloatingMenuSelectWidget.prototype.toggle = function ( visible ) {
 
        if ( change && visible ) {
                // Make sure the width is set before the parent method runs.
-               this.setIdealSize( this.$container.width() );
+               this.setIdealSize( this.width || this.$container.width() );
        }
 
        // Parent method
@@ -8657,8 +8677,12 @@ OO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) {
  * @inheritdoc
  */
 OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) {
+       var selected;
        value = this.cleanUpValue( value );
        this.dropdownWidget.getMenu().selectItemByData( value );
+       // Only allow setting values that are actually present in the dropdown
+       selected = this.dropdownWidget.getMenu().getSelectedItem();
+       value = selected ? selected.getData() : '';
        OO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value );
        return this;
 };
@@ -9560,14 +9584,14 @@ OO.ui.TextInputWidget.prototype.setRequired = function ( state ) {
        this.required = !!state;
        if ( this.required ) {
                this.$input
-                       .attr( 'required', 'required' )
+                       .prop( 'required', true )
                        .attr( 'aria-required', 'true' );
                if ( this.getIndicator() === null ) {
                        this.setIndicator( 'required' );
                }
        } else {
                this.$input
-                       .removeAttr( 'required' )
+                       .prop( 'required', false )
                        .removeAttr( 'aria-required' );
                if ( this.getIndicator() === 'required' ) {
                        this.setIndicator( null );
@@ -10259,9 +10283,14 @@ OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
                autocomplete: false
        }, config );
 
-       // ComboBoxInputWidget shouldn't support multiline
+       // ComboBoxInputWidget shouldn't support `multiline`
        config.multiline = false;
 
+       // See InputWidget#reusePreInfuseDOM about `config.$input`
+       if ( config.$input ) {
+               config.$input.removeAttr( 'list' );
+       }
+
        // Parent constructor
        OO.ui.ComboBoxInputWidget.parent.call( this, config );
 
index 8538b6e..ec6e45d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:37Z
+ * Date: 2017-04-11T22:51:05Z
  */
 ( function ( OO ) {
 
index 983bc69..cb6ebc3 100644 (file)
@@ -1,21 +1,17 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
   z-index: 4;
 }
-.oo-ui-popupTool .oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor,
-.oo-ui-popupTool .oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor {
-  margin-left: 1.25em;
-}
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
   border: 0;
   border-radius: 0;
   border-color: rgba(0, 0, 0, 0.2);
   box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
   background-color: #f8fbfd;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #F1F7FB), color-stop(100%, #fff));
-  background-image: -webkit-linear-gradient(top, #F1F7FB 0, #fff 100%);
-  background-image:    -moz-linear-gradient(top, #F1F7FB 0, #fff 100%);
-  background-image:         linear-gradient(to bottom, #F1F7FB 0, #fff 100%);
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
   -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .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-bottom-right-radius: 0;
   box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
   background-color: #f8fbfd;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #F1F7FB), color-stop(100%, #fff));
-  background-image: -webkit-linear-gradient(top, #F1F7FB 0, #fff 100%);
-  background-image:    -moz-linear-gradient(top, #F1F7FB 0, #fff 100%);
-  background-image:         linear-gradient(to bottom, #F1F7FB 0, #fff 100%);
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
   -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
   line-height: 2em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-  color: #888;
+  color: #767676;
 }
 .oo-ui-listToolGroup .oo-ui-tool {
   display: block;
   border-color: rgba(0, 0, 0, 0.1);
   box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
   background-color: #f8fbfd;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #F1F7FB), color-stop(100%, #fff));
-  background-image: -webkit-linear-gradient(top, #F1F7FB 0, #fff 100%);
-  background-image:    -moz-linear-gradient(top, #F1F7FB 0, #fff 100%);
-  background-image:         linear-gradient(to bottom, #F1F7FB 0, #fff 100%);
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
   -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
index 502b7b1..85095d3 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
 .oo-ui-tool.oo-ui-widget-enabled {
   -webkit-transition: background-color 100ms;
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
   z-index: 4;
 }
-.oo-ui-popupTool .oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor,
-.oo-ui-popupTool .oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor {
-  margin-left: 1.25em;
-}
 .oo-ui-toolGroupTool > .oo-ui-toolGroup {
   border-right: 0;
 }
   width: 0.9375em;
   height: 100%;
   margin: 0 0.5em;
-  opacity: 0.3;
+  opacity: 0.87;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
   right: -0.3125em;
 .oo-ui-popupToolGroup.oo-ui-widget-enabled.oo-ui-popupToolGroup-active .oo-ui-tool-active.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
   color: #36c;
 }
-.oo-ui-popupToolGroup.oo-ui-widget-enabled-handle:hover {
+.oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle {
+  -webkit-transition: background-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, box-shadow 100ms;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle:hover {
   background-color: #eaecf0;
 }
-.oo-ui-popupToolGroup.oo-ui-widget-enabled-handle:active {
+.oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle:active {
   background-color: #eaf3ff;
 }
 .oo-ui-listToolGroup .oo-ui-tool {
   background-color: transparent;
   box-shadow: none;
 }
-.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement {
+.oo-ui-toolbar-narrow .oo-ui-toolbar-bar:after {
+  content: '';
+  display: block;
+  position: absolute;
+  top: 3.125em;
+  left: 0;
+  width: 100%;
+  height: 0;
+  border-bottom: 1px solid #c8ccd1;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-indicatorElement,
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-labelElement,
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-indicatorElement {
   margin: 0;
 }
-.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button,
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
   border: 0;
   border-radius: 0;
   padding: 0 0.3125em;
 }
-.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
   margin: 0 1em;
   line-height: 3.125em;
 }
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-indicatorElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  margin: 0;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement.oo-ui-indicatorElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  margin: 0 0.3125em;
+}
 .oo-ui-toolbar-actions > .oo-ui-toolbar:not( :last-child ) {
   border-right: 1px solid #c8ccd1;
 }
index 4cc0db1..665e9dc 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:37Z
+ * Date: 2017-04-11T22:51:05Z
  */
 ( function ( OO ) {
 
index a9b31da..0d51782 100644 (file)
@@ -1,14 +1,13 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
-.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ),
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
   cursor: url(images/grab.cur );
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
   display: block;
-  padding-top: 0.5em;
-  padding-right: 2.375em;
-}
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
-  right: 0.5em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
   height: auto;
 }
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  padding: 1em;
-}
 .oo-ui-selectFileWidget:last-child {
   margin-right: 0;
 }
 .oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
   background-color: #e1f3ff;
 }
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-label {
+  padding: 1em;
+}
 .oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border: 1px solid #aaa;
   overflow: inherit;
   white-space: normal;
 }
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
+  padding-top: 0.5em;
+  padding-right: 2.375em;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
+  right: 0.5em;
+}
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget {
   border-style: dashed;
 }
   background-color: #fff;
   border-color: #ddd;
 }
+.oo-ui-tagMultiselectWidget {
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
+}
+.oo-ui-tagMultiselectWidget-handle {
+  width: 100%;
+  display: block;
+  position: relative;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+}
+.oo-ui-tagMultiselectWidget-content {
+  position: relative;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-content > input {
+  display: none;
+}
+.oo-ui-tagMultiselectWidget-group {
+  display: inline;
+}
+.oo-ui-tagMultiselectWidget-inputPosition-outline {
+  width: 100%;
+}
+.oo-ui-tagMultiselectWidget-focusTrap {
+  display: inline-block;
+  height: 1px;
+  width: 1px;
+}
+.oo-ui-tagMultiselectWidget-handle {
+  background-color: #fff;
+  cursor: text;
+  min-height: 2.4em;
+  margin-right: 0.5em;
+  padding: 0.15em 0.25em;
+  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-tagMultiselectWidget-handle:last-child {
+  margin-right: 0;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input {
+  border: 0;
+  line-height: 1.675em;
+  margin: 0;
+  margin-left: 0.2em;
+  padding: 0;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: transparent;
+  color: #000;
+  vertical-align: middle;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::-webkit-input-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input:-ms-input-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::-moz-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input:-moz-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input:focus {
+  outline: 0;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-iconElement .oo-ui-tagMultiselectWidget-handle {
+  padding-left: 2.475em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-iconElement .oo-ui-tagMultiselectWidget-handle > .oo-ui-iconElement-icon {
+  left: 0;
+  margin: 0 0.3em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-indicatorElement .oo-ui-tagMultiselectWidget-handle {
+  padding-right: 2.4875em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-indicatorElement .oo-ui-tagMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  right: 0;
+  margin: 0 0.775em;
+}
+.oo-ui-tagMultiselectWidget:hover .oo-ui-tagMultiselectWidget-handle {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-handle {
+  color: #ccc;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #ddd;
+  background-color: #f3f3f3;
+  cursor: default;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  opacity: 0.2;
+}
+.oo-ui-tagMultiselectWidget-popup > .oo-ui-popupWidget-popup {
+  border: 0;
+}
+.oo-ui-tagItemWidget {
+  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 0.4em;
+  margin: 0.1em;
+  height: 1.7em;
+  line-height: 1.7em;
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+  border: 1px solid #ccc;
+  color: #333;
+  border-radius: 0.25em;
+}
+.oo-ui-tagItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+  display: inline-block;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  cursor: text;
+}
+.oo-ui-tagItemWidget:focus {
+  outline: 0;
+  border-color: #087ecc;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-disabled {
+  opacity: 0.5;
+  -webkit-transform: translateZ(0);
+          transform: translateZ(0);
+  box-shadow: none;
+  color: #333;
+  background: #eee;
+  border-color: #ccc;
+}
+.oo-ui-tagItemWidget > .oo-ui-buttonElement {
+  margin-top: -1.25em;
+  padding-left: 0.3em;
+}
 .oo-ui-capsuleMultiselectWidget {
   display: inline-block;
   position: relative;
   vertical-align: middle;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-webkit-input-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:-ms-input-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-moz-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:-moz-placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::placeholder {
-  color: #72777d;
+  color: #767676;
   opacity: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
   background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
   -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
   border: 1px solid #ccc;
-  color: #555;
+  color: #333;
   border-radius: 0.25em;
 }
 .oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
index 8438a3d..25add3d 100644 (file)
@@ -1,14 +1,16 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
-.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ),
+.oo-ui-draggableElement {
+  padding: 1.0546875em 0.9375em 0.9375em;
+}
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
   cursor: url(images/grab.cur );
@@ -32,7 +34,7 @@
 .oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement {
   display: inline-block;
 }
-.oo-ui-draggableElement-handle:focus {
+.oo-ui-draggableElement-handle.oo-ui-widget-enabled:focus {
   border-radius: 2px;
   box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
   outline: 0;
   border-bottom-right-radius: 2px;
   border-top-right-radius: 2px;
 }
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  position: absolute;
+}
 .oo-ui-buttonSelectWidget.oo-ui-widget-enabled:focus .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected .oo-ui-buttonElement-button {
   border-color: #36c;
   box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
   display: block;
-  padding-top: 0.5em;
-  padding-right: 2.375em;
-}
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
-  right: 0.5em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
   height: auto;
 }
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  padding: 1em;
-}
 .oo-ui-selectFileWidget:last-child {
   margin-right: 0;
 }
   border-radius: 0 2px 2px 0;
 }
 .oo-ui-selectFileWidget-info {
-  height: 2.4em;
   background-color: #fff;
   border: 1px solid #a2a9b1;
   border-radius: 2px 0 0 2px;
-  border-width: 1px 0 1px 1px;
+  border-right-width: 0;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-  left: 0;
-  margin-left: 0.5em;
+  left: 0.46875em;
+  min-height: 2.4em;
+  margin-left: -1px;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  right: 0;
-  margin-right: 0.775em;
+  right: 0.9375em;
+  min-height: 2.4em;
 }
 .oo-ui-selectFileWidget-label {
   -webkit-box-sizing: border-box;
   display: block;
   right: 2.375em;
   padding-top: 0.625em;
-  padding-left: 0.546875em;
+  padding-left: 0.625em;
   padding-bottom: 0.546875em;
   line-height: 1.172em;
   white-space: nowrap;
 }
 .oo-ui-selectFileWidget-clearButton {
   top: -1px;
-  right: 0;
+  right: 0.46875em;
   min-width: 24px;
   width: 1.875em;
   margin-right: 0;
   color: #72777d;
 }
 .oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
-  left: 2.875em;
+  left: 2.5em;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-  right: 4.4625em;
+  right: 3.75em;
   padding-left: 0;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-clearButton {
   overflow: inherit;
   white-space: normal;
 }
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
+  padding-right: 2.5em;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
+  top: 0;
+}
 .oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border-style: dashed;
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
   opacity: 0.15;
 }
+.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
+  padding: 1em 0.9375em;
+}
 .oo-ui-widget-disabled .oo-ui-selectFileWidget-dropLabel {
   display: none;
 }
      -moz-user-select: none;
       -ms-user-select: none;
           user-select: none;
-  font-size: 1.1em;
-  padding: 0.75em;
+  padding: 1.0546875em 0.9375em 0.9375em;
   -webkit-transition: background-color 100ms, color 100ms;
      -moz-transition: background-color 100ms, color 100ms;
           transition: background-color 100ms, color 100ms;
   background-color: rgba(41, 98, 204, 0.1);
   color: #36c;
 }
-.oo-ui-outlineOptionWidget .oo-ui-iconElement-icon {
-  font-size: 90.90909%;
-}
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
   padding-right: 1.5em;
 }
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
   opacity: 0.5;
 }
-.oo-ui-outlineOptionWidget-level-0.oo-ui-iconElement {
-  padding-left: 2.571em;
+.oo-ui-outlineOptionWidget .oo-ui-labelElement-label {
+  font-size: 1.1em;
 }
 .oo-ui-outlineOptionWidget-level-1 {
   padding-left: 2.571em;
   background-color: #fff;
   color: #000;
 }
+.oo-ui-tagMultiselectWidget {
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
+}
+.oo-ui-tagMultiselectWidget-handle {
+  width: 100%;
+  display: block;
+  position: relative;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+}
+.oo-ui-tagMultiselectWidget-content {
+  position: relative;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-content > input {
+  display: none;
+}
+.oo-ui-tagMultiselectWidget-group {
+  display: inline;
+}
+.oo-ui-tagMultiselectWidget-inputPosition-outline {
+  width: 100%;
+}
+.oo-ui-tagMultiselectWidget-focusTrap {
+  display: inline-block;
+  height: 1px;
+  width: 1px;
+}
+.oo-ui-tagMultiselectWidget-handle {
+  min-height: 2.4em;
+  margin-right: 0.5em;
+  padding: 0.15em 0.25em;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+.oo-ui-tagMultiselectWidget-handle:last-child {
+  margin-right: 0;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input {
+  border: 0;
+  line-height: 1.675;
+  margin: 0 0 0 0.2em;
+  padding: 0;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: transparent;
+  color: #000;
+  vertical-align: middle;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::-webkit-input-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input:-ms-input-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input:-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input:focus {
+  outline: 0;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-iconElement .oo-ui-tagMultiselectWidget-handle {
+  padding-left: 2.475em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-iconElement .oo-ui-tagMultiselectWidget-handle > .oo-ui-iconElement-icon {
+  left: 0;
+  margin: 0 0.3em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-indicatorElement .oo-ui-tagMultiselectWidget-handle {
+  padding-right: 2.4875em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-indicatorElement .oo-ui-tagMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  right: 0;
+  margin: 0 0.775em;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-enabled .oo-ui-tagMultiselectWidget-handle {
+  background-color: #fff;
+  cursor: text;
+  -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+     -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+          transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-enabled:hover .oo-ui-tagMultiselectWidget-handle {
+  border-color: #72777d;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-enabled.oo-ui-tagMultiselectWidget-open .oo-ui-tagMultiselectWidget-handle {
+  border-color: #36c;
+  outline: 0;
+  box-shadow: inset 0 0 0 1px #36c;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-handle {
+  color: #72777d;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #c8ccd1;
+  background-color: #eaecf0;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-handle > .oo-ui-iconElement-icon {
+  opacity: 0.51;
+}
+.oo-ui-tagMultiselectWidget.oo-ui-widget-disabled .oo-ui-tagMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  opacity: 0.15;
+}
+.oo-ui-tagItemWidget {
+  position: relative;
+  display: inline-block;
+  cursor: default;
+  white-space: nowrap;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  width: auto;
+  max-width: 100%;
+  height: 1.7em;
+  margin: 0.1em;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  padding: 0 0.4em;
+  line-height: 1.7;
+  vertical-align: middle;
+}
+.oo-ui-tagItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+  display: inline-block;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  cursor: text;
+}
+.oo-ui-tagItemWidget.oo-ui-flaggedElement-invalid {
+  border-color: #d33;
+}
+.oo-ui-tagItemWidget.oo-ui-flaggedElement-invalid:hover {
+  border-color: #d33;
+}
+.oo-ui-tagItemWidget.oo-ui-flaggedElement-invalid:focus {
+  border-color: #d33;
+  box-shadow: inset 0 0 0 1px #d33;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled {
+  background-color: #f8f9fa;
+  color: #222;
+  padding-right: 1.5375em;
+  -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled:hover {
+  background-color: #fff;
+  color: #444;
+  border-color: #a2a9b1;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled:focus {
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
+  outline: 0;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled > .oo-ui-buttonElement {
+  display: block;
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button {
+  display: block;
+  width: 1.5375em;
+  height: 100%;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-indicator-clear {
+  position: absolute;
+  top: 0;
+  right: 0.3em;
+  bottom: 0;
+  height: auto;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-disabled {
+  background-color: #eaecf0;
+  color: #72777d;
+  border-color: #c8ccd1;
+  text-shadow: 0 1px 1px #fff;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-disabled:focus {
+  outline: 0;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-disabled > .oo-ui-buttonElement {
+  display: none;
+}
 .oo-ui-capsuleMultiselectWidget {
   display: inline-block;
   position: relative;
   outline: 0;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle {
-  padding-left: 2.475em;
+  padding-left: 2.5em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-  left: 0;
-  margin: 0 0.3em;
+  left: 0.46875em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
-  padding-right: 2.4875em;
+  padding-right: 2.8125em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-  right: 0;
-  margin: 0 0.775em;
+  right: 0.9375em;
 }
 .oo-ui-capsuleMultiselectWidget-popup {
   margin-top: -1px;
index 3482256..2b2f2ca 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:37Z
+ * Date: 2017-04-11T22:51:05Z
  */
 ( function ( OO ) {
 
@@ -98,7 +98,7 @@ OO.ui.mixin.DraggableElement.prototype.toggleDraggable = function ( isDraggable
        if ( this.draggable !== isDraggable ) {
                this.draggable = isDraggable;
 
-               this.$element.toggleClass( 'oo-ui-draggableElement-undraggable', !this.draggable );
+               this.$handle.toggleClass( 'oo-ui-draggableElement-undraggable', !this.draggable );
        }
 };
 
@@ -4465,6 +4465,1425 @@ OO.ui.CapsuleMultiselectWidget.prototype.focus = function () {
        return this;
 };
 
+/**
+ * TagItemWidgets are used within a {@link OO.ui.TagMultiselectWidget
+ * TagMultiselectWidget} to display the selected items.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.ItemWidget
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ * @mixins OO.ui.mixin.DraggableElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration object
+ * @cfg {boolean} [valid=true] Item is valid
+ */
+OO.ui.TagItemWidget = function OoUiTagItemWidget( config ) {
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.TagItemWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ItemWidget.call( this );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+       OO.ui.mixin.DraggableElement.call( this, config );
+
+       this.valid = config.valid === undefined ? true : !!config.valid;
+
+       this.closeButton = new OO.ui.ButtonWidget( {
+               framed: false,
+               indicator: 'clear',
+               tabIndex: -1
+       } );
+       this.closeButton.setDisabled( this.isDisabled() );
+
+       // Events
+       this.closeButton
+               .connect( this, { click: 'remove' } );
+       this.$element
+               .on( 'click', this.select.bind( this ) )
+               .on( 'keydown', this.onKeyDown.bind( this ) )
+               // Prevent propagation of mousedown; the tag item "lives" in the
+               // clickable area of the TagMultiselectWidget, which listens to
+               // mousedown to open the menu or popup. We want to prevent that
+               // for clicks specifically on the tag itself, so the actions taken
+               // are more deliberate. When the tag is clicked, it will emit the
+               // selection event (similar to how #OO.ui.MultioptionWidget emits 'change')
+               // and can be handled separately.
+               .on( 'mousedown', function ( e ) { e.stopPropagation(); } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-tagItemWidget' )
+               .append( this.$label, this.closeButton.$element );
+};
+
+/* Initialization */
+
+OO.inheritClass( OO.ui.TagItemWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.ItemWidget );
+OO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.FlaggedElement );
+OO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.TabIndexedElement );
+OO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.DraggableElement );
+
+/* Events */
+
+/**
+ * @event remove
+ *
+ * A remove action was performed on the item
+ */
+
+/**
+ * @event navigate
+ * @param {string} direction Direction of the movement, forward or backwards
+ *
+ * A navigate action was performed on the item
+ */
+
+/**
+ * @event select
+ *
+ * The tag widget was selected. This can occur when the widget
+ * is either clicked or enter was pressed on it.
+ */
+
+/**
+ * @event valid
+ * @param {boolean} isValid Item is valid
+ *
+ * Item validity has changed
+ */
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.TagItemWidget.prototype.setDisabled = function ( state ) {
+       // Parent method
+       OO.ui.TagItemWidget.parent.prototype.setDisabled.call( this, state );
+
+       if ( this.closeButton ) {
+               this.closeButton.setDisabled( state );
+       }
+       return this;
+};
+
+/**
+ * Handle removal of the item
+ *
+ * This is mainly for extensibility concerns, so other children
+ * of this class can change the behavior if they need to. This
+ * is called by both clicking the 'remove' button but also
+ * on keypress, which is harder to override if needed.
+ *
+ * @fires remove
+ */
+OO.ui.TagItemWidget.prototype.remove = function () {
+       if ( !this.isDisabled() ) {
+               this.emit( 'remove' );
+       }
+};
+
+/**
+ * Handle a keydown event on the widget
+ *
+ * @fires navigate
+ * @fires remove
+ * @return {boolean|undefined} false to stop the operation
+ */
+OO.ui.TagItemWidget.prototype.onKeyDown = function ( e ) {
+       var movement;
+
+       if ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) {
+               this.remove();
+               return false;
+       } else if ( e.keyCode === OO.ui.Keys.ENTER ) {
+               this.select();
+               return false;
+       } else if (
+               e.keyCode === OO.ui.Keys.LEFT ||
+               e.keyCode === OO.ui.Keys.RIGHT
+       ) {
+               if ( OO.ui.Element.static.getDir( this.$element ) === 'rtl' ) {
+                       movement = {
+                               left: 'forwards',
+                               right: 'backwards'
+                       };
+               } else {
+                       movement = {
+                               left: 'backwards',
+                               right: 'forwards'
+                       };
+               }
+
+               this.emit(
+                       'navigate',
+                       e.keyCode === OO.ui.Keys.LEFT ?
+                               movement.left : movement.right
+               );
+       }
+};
+
+/**
+ * Focuses the capsule
+ */
+OO.ui.TagItemWidget.prototype.focus = function () {
+       if ( !this.isDisabled() ) {
+               this.$element.focus();
+       }
+};
+
+/**
+ * Select this item
+ *
+ * @fires select
+ */
+OO.ui.TagItemWidget.prototype.select = function () {
+       if ( !this.isDisabled() ) {
+               this.emit( 'select' );
+       }
+};
+
+/**
+ * Set the valid state of this item
+ *
+ * @param {boolean} [valid] Item is valid
+ * @fires valid
+ */
+OO.ui.TagItemWidget.prototype.toggleValid = function ( valid ) {
+       valid = valid === undefined ? !this.valid : !!valid;
+
+       if ( this.valid !== valid ) {
+               this.valid = valid;
+
+               this.setFlags( { invalid: !this.valid } );
+
+               this.emit( 'valid', this.valid );
+       }
+};
+
+/**
+ * Check whether the item is valid
+ *
+ * @return {boolean} Item is valid
+ */
+OO.ui.TagItemWidget.prototype.isValid = function () {
+       return this.valid;
+};
+
+/**
+ * A basic tag multiselect widget, similar in concept to {@link OO.ui.ComboBoxInputWidget combo box widget}
+ * that allows the user to add multiple values that are displayed in a tag area.
+ *
+ * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * This widget is a base widget; see {@link OO.ui.MenuTagMultiselectWidget MenuTagMultiselectWidget} and
+ * {@link OO.ui.PopupTagMultiselectWidget PopupTagMultiselectWidget} for the implementations that use
+ * a menu and a popup respectively.
+ *
+ *     @example
+ *     // Example: A basic TagMultiselectWidget.
+ *     var widget = new OO.ui.TagMultiselectWidget( {
+ *         inputPosition: 'outline',
+ *         allowedValues: [ 'Option 1', 'Option 2', 'Option 3' ],
+ *         selected: [ 'Option 1' ]
+ *     } );
+ *     $( 'body' ).append( widget.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.GroupWidget
+ * @mixins OO.ui.mixin.DraggableGroupElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ *
+ * @constructor
+ * @param {Object} config Configuration object
+ * @cfg {Object} [input] Configuration options for the input widget
+ * @cfg {boolean} [inputPosition='inline'] Position of the input. Options are:
+ *     - inline: The input is invisible, but exists inside the tag list, so
+ *             the user types into the tag groups to add tags.
+ *     - outline: The input is underneath the tag area.
+ *     - none: No input supplied
+ * @cfg {boolean} [allowEditTags=true] Allow editing of the tags by clicking them
+ * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if
+ *  not present in the menu.
+ * @cfg {Object[]} [allowedValues] An array representing the allowed items
+ *  by their datas.
+ * @cfg {boolean} [allowDuplicates=false] Allow duplicate items to be added
+ * @cfg {boolean} [allowDisplayInvalidTags=false] Allow the display of
+ *  invalid tags. These tags will display with an invalid state, and
+ *  the widget as a whole will have an invalid state if any invalid tags
+ *  are present.
+ * @cfg {boolean} [allowReordering=true] Allow reordering of the items
+ * @cfg {Object[]|String[]} [selected] A set of selected tags. If given,
+ *  these will appear in the tag list on initialization, as long as they
+ *  pass the validity tests.
+ */
+OO.ui.TagMultiselectWidget = function OoUiTagMultiselectWidget( config ) {
+       var inputEvents,
+               rAF = window.requestAnimationFrame || setTimeout,
+               widget = this,
+               $tabFocus = $( '<span>' )
+                       .addClass( 'oo-ui-tagMultiselectWidget-focusTrap' );
+
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.TagMultiselectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupWidget.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.DraggableGroupElement.call( this, config );
+
+       this.toggleDraggable(
+               config.allowReordering === undefined ?
+                       true : !!config.allowReordering
+       );
+
+       this.inputPosition = this.constructor.static.allowedInputPositions.indexOf( config.inputPosition ) > -1 ?
+                       config.inputPosition : 'inline';
+       this.allowEditTags = config.allowEditTags === undefined ? true : !!config.allowEditTags;
+       this.allowArbitrary = !!config.allowArbitrary;
+       this.allowDuplicates = !!config.allowDuplicates;
+       this.allowedValues = config.allowedValues || [];
+       this.allowDisplayInvalidTags = config.allowDisplayInvalidTags;
+       this.hasInput = this.inputPosition !== 'none';
+       this.height = null;
+       this.valid = true;
+
+       this.$content = $( '<div>' )
+               .addClass( 'oo-ui-tagMultiselectWidget-content' );
+       this.$handle = $( '<div>' )
+               .addClass( 'oo-ui-tagMultiselectWidget-handle' )
+               .append(
+                       this.$indicator,
+                       this.$icon,
+                       this.$content
+                               .append(
+                                       this.$group
+                                               .addClass( 'oo-ui-tagMultiselectWidget-group' )
+                               )
+               );
+
+       // Events
+       this.aggregate( {
+               remove: 'itemRemove',
+               navigate: 'itemNavigate',
+               select: 'itemSelect'
+       } );
+       this.connect( this, {
+               itemRemove: 'onTagRemove',
+               itemSelect: 'onTagSelect',
+               itemNavigate: 'onTagNavigate',
+               change: 'onChangeTags'
+       } );
+       this.$handle.on( {
+               mousedown: this.onMouseDown.bind( this )
+       } );
+
+       // Initialize
+       this.$element
+               .addClass( 'oo-ui-tagMultiselectWidget' )
+               .addClass( 'oo-ui-tagMultiselectWidget-inputPosition-' + this.inputPosition )
+               .append( this.$handle );
+
+       if ( this.hasInput ) {
+               this.input = new OO.ui.TextInputWidget( $.extend( {
+                       placeholder: config.placeholder,
+                       classes: [ 'oo-ui-tagMultiselectWidget-input' ]
+               }, config.input ) );
+               this.input.setDisabled( this.isDisabled() );
+
+               inputEvents = {
+                       focus: this.onInputFocus.bind( this ),
+                       blur: this.onInputBlur.bind( this ),
+                       'propertychange change click mouseup keydown keyup input cut paste select focus':
+                               OO.ui.debounce( this.updateInputSize.bind( this ) ),
+                       keydown: this.onInputKeyDown.bind( this ),
+                       keypress: this.onInputKeyPress.bind( this )
+               };
+
+               this.input.$input.on( inputEvents );
+
+               if ( this.inputPosition === 'outline' ) {
+                       // Override max-height for the input widget
+                       // in the case the widget is outline so it can
+                       // stretch all the way if the widet is wide
+                       this.input.$element.css( 'max-width', 'inherit' );
+                       this.$element.append( this.input.$element );
+               } else {
+                       // HACK: When the widget is using 'inline' input, the
+                       // behavior needs to only use the $input itself
+                       // so we style and size it accordingly (otherwise
+                       // the styling and sizing can get very convoluted
+                       // when the wrapping divs and other elements)
+                       // We are taking advantage of still being able to
+                       // call the widget itself for operations like
+                       // .getValue() and setDisabled() and .focus() but
+                       // having only the $input attached to the DOM
+                       this.$content.append( this.input.$input );
+               }
+       }
+
+       this.setTabIndexedElement(
+               this.hasInput ?
+                       this.input.$input :
+                       $tabFocus
+       );
+
+       if ( config.selected ) {
+               this.setValue( config.selected );
+       }
+
+       // HACK: Input size needs to be calculated after everything
+       // else is rendered
+       rAF( function () {
+               if ( widget.hasInput ) {
+                       widget.updateInputSize();
+               }
+       } );
+};
+
+/* Initialization */
+
+OO.inheritClass( OO.ui.TagMultiselectWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.GroupWidget );
+OO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.DraggableGroupElement );
+OO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.TabIndexedElement );
+OO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.FlaggedElement );
+
+/* Static properties */
+
+/**
+ * Allowed input positions.
+ * - inline: The input is inside the tag list
+ * - outline: The input is under the tag list
+ * - none: There is no input
+ *
+ * @property {Array}
+ */
+OO.ui.TagMultiselectWidget.static.allowedInputPositions = [ 'inline', 'outline', 'none' ];
+
+/* Methods */
+
+/**
+ * Handle mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ * @return {boolean} False to prevent defaults
+ */
+OO.ui.TagMultiselectWidget.prototype.onMouseDown = function ( e ) {
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               this.focus();
+               return false;
+       }
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ * @return {boolean} Whether to prevent defaults
+ */
+OO.ui.TagMultiselectWidget.prototype.onInputKeyPress = function ( e ) {
+       var stopOrContinue,
+               withMetaKey = e.metaKey || e.ctrlKey;
+
+       if ( !this.isDisabled() ) {
+               if ( e.which === OO.ui.Keys.ENTER ) {
+                       stopOrContinue = this.doInputEnter( e, withMetaKey );
+               }
+
+               // Make sure the input gets resized.
+               setTimeout( this.updateInputSize.bind( this ), 0 );
+               return stopOrContinue;
+       }
+};
+
+/**
+ * Handle key down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key down event
+ * @return {boolean}
+ */
+OO.ui.TagMultiselectWidget.prototype.onInputKeyDown = function ( e ) {
+       var movement, direction,
+               withMetaKey = e.metaKey || e.ctrlKey;
+
+       if ( !this.isDisabled() ) {
+               // 'keypress' event is not triggered for Backspace
+               if ( e.keyCode === OO.ui.Keys.BACKSPACE ) {
+                       return this.doInputBackspace( e, withMetaKey );
+               } else if ( e.keyCode === OO.ui.Keys.ESCAPE ) {
+                       return this.doInputEscape( e );
+               } else if (
+                       e.keyCode === OO.ui.Keys.LEFT ||
+                       e.keyCode === OO.ui.Keys.RIGHT
+               ) {
+                       if ( OO.ui.Element.static.getDir( this.$element ) === 'rtl' ) {
+                               movement = {
+                                       left: 'forwards',
+                                       right: 'backwards'
+                               };
+                       } else {
+                               movement = {
+                                       left: 'backwards',
+                                       right: 'forwards'
+                               };
+                       }
+                       direction = e.keyCode === OO.ui.Keys.LEFT ?
+                               movement.left : movement.right;
+
+                       return this.doInputArrow( e, direction, withMetaKey );
+               }
+       }
+};
+
+/**
+ * Respond to input focus event
+ */
+OO.ui.TagMultiselectWidget.prototype.onInputFocus = function () {};
+
+/**
+ * Respond to input blur event
+ */
+OO.ui.TagMultiselectWidget.prototype.onInputBlur = function () {};
+
+/**
+ * Perform an action after the enter key on the input
+ *
+ * @param {jQuery.Event} e Event data
+ * @param {boolean} [withMetaKey] Whether this key was pressed with
+ * a meta key like 'ctrl'
+ * @return {boolean} Whether to prevent defaults
+ */
+OO.ui.TagMultiselectWidget.prototype.doInputEnter = function () {
+       this.addTagFromInput();
+       return false;
+};
+
+/**
+ * Perform an action responding to the enter key on the input
+ *
+ * @param {jQuery.Event} e Event data
+ * @param {boolean} [withMetaKey] Whether this key was pressed with
+ * a meta key like 'ctrl'
+ * @return {boolean} Whether to prevent defaults
+ */
+OO.ui.TagMultiselectWidget.prototype.doInputBackspace = function () {
+       var items, item;
+
+       if (
+               this.inputPosition === 'inline' &&
+               this.input.getValue() === '' &&
+               !this.isEmpty()
+       ) {
+               // Delete the last item
+               items = this.getItems();
+               item = items[ items.length - 1 ];
+               this.input.setValue( item.getData() );
+               this.removeItems( [ item ] );
+
+               return false;
+       }
+};
+
+/**
+ * Perform an action after the escape key on the input
+ *
+ * @param {jQuery.Event} e Event data
+ * @return {boolean} Whether to prevent defaults
+ */
+OO.ui.TagMultiselectWidget.prototype.doInputEscape = function () {
+       this.clearInput();
+};
+
+/**
+ * Perform an action after the arrow key on the input, select the previous
+ * or next item from the input.
+ * See #getPreviousItem and #getNextItem
+ *
+ * @param {jQuery.Event} e Event data
+ * @param {string} direction Direction of the movement; forwards or backwards
+ * @param {boolean} [withMetaKey] Whether this key was pressed with
+ *  a meta key like 'ctrl'
+ * @return {boolean} Whether to prevent defaults
+ */
+OO.ui.TagMultiselectWidget.prototype.doInputArrow = function ( direction ) {
+       if (
+               this.inputPosition === 'inline' &&
+               !this.isEmpty()
+       ) {
+               if ( direction === 'backwards' ) {
+                       // Get previous item
+                       this.getPreviousItem().focus();
+               } else {
+                       // Get next item
+                       this.getNextItem().focus();
+               }
+       }
+};
+
+/**
+ * Respond to item select event
+ */
+OO.ui.TagMultiselectWidget.prototype.onTagSelect = function ( item ) {
+       if ( this.hasInput && this.allowEditTags ) {
+               if ( this.input.getValue() ) {
+                       this.addTagFromInput();
+               }
+               // 1. Get the label of the tag into the input
+               this.input.setValue( item.getData() );
+               // 2. Remove the tag
+               this.removeItems( [ item ] );
+               // 3. Focus the input
+               this.focus();
+       }
+};
+
+/**
+ * Respond to change event, where items were added, removed, or cleared.
+ */
+OO.ui.TagMultiselectWidget.prototype.onChangeTags = function () {
+       this.toggleValid( this.checkValidity() );
+       if ( this.hasInput ) {
+               this.updateInputSize();
+       }
+       this.updateIfHeightChanged();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.TagMultiselectWidget.prototype.setDisabled = function ( isDisabled ) {
+       // Parent method
+       OO.ui.TagMultiselectWidget.parent.prototype.setDisabled.call( this, isDisabled );
+
+       if ( this.hasInput && this.input ) {
+               this.input.setDisabled( !!isDisabled );
+       }
+
+       if ( this.items ) {
+               this.getItems().forEach( function ( item ) {
+                       item.setDisabled( !!isDisabled );
+               } );
+       }
+};
+
+/**
+ * Respond to tag remove event
+ * @param {OO.ui.TagItemWidget} item Removed tag
+ */
+OO.ui.TagMultiselectWidget.prototype.onTagRemove = function ( item ) {
+       this.removeTagByData( item.getData() );
+};
+
+/**
+ * Respond to navigate event on the tag
+ *
+ * @param {OO.ui.TagItemWidget} item Removed tag
+ * @param {string} direction Direction of movement; 'forwards' or 'backwards'
+ */
+OO.ui.TagMultiselectWidget.prototype.onTagNavigate = function ( item, direction ) {
+       if ( direction === 'forwards' ) {
+               this.getNextItem( item ).focus();
+       } else {
+               this.getPreviousItem( item ).focus();
+       }
+};
+
+/**
+ * Add tag from input value
+ */
+OO.ui.TagMultiselectWidget.prototype.addTagFromInput = function () {
+       var val = this.input.getValue(),
+               isValid = this.isAllowedData( val );
+
+       if ( !val ) {
+               return;
+       }
+
+       if ( isValid || this.allowDisplayInvalidTags ) {
+               this.addTag( val );
+               this.clearInput();
+               this.focus();
+       }
+};
+
+/**
+ * Clear the input
+ */
+OO.ui.TagMultiselectWidget.prototype.clearInput = function () {
+       this.input.setValue( '' );
+};
+
+/**
+ * Check whether the given value is a duplicate of an existing
+ * tag already in the list.
+ *
+ * @param {string|Object} data Requested value
+ * @return {boolean} Value is duplicate
+ */
+OO.ui.TagMultiselectWidget.prototype.isDuplicateData = function ( data ) {
+       return !!this.getItemFromData( data );
+};
+
+/**
+ * Check whether a given value is allowed to be added
+ *
+ * @param {string|Object} data Requested value
+ * @return {boolean} Value exists in the allowed values list
+ */
+OO.ui.TagMultiselectWidget.prototype.isAllowedData = function ( data ) {
+       var hash = OO.getHash( data );
+
+       if ( this.allowArbitrary ) {
+               return true;
+       }
+
+       if (
+               !this.allowDuplicates &&
+               this.isDuplicateData( data )
+       ) {
+               return false;
+       }
+
+       // Check with allowed values
+       if (
+               this.getAllowedValues().some( function ( value ) {
+                       return hash === OO.getHash( value );
+               } )
+       ) {
+               return true;
+       }
+
+       return false;
+};
+
+/**
+ * Get the allowed values list
+ *
+ * @return {string[]} Allowed data values
+ */
+OO.ui.TagMultiselectWidget.prototype.getAllowedValues = function () {
+       return this.allowedValues;
+};
+
+/**
+ * Add a value to the allowed values list
+ *
+ * @param {string} value Allowed data value
+ */
+OO.ui.TagMultiselectWidget.prototype.addAllowedValue = function ( value ) {
+       if ( this.allowedValues.indexOf( value ) === -1 ) {
+               this.allowedValues.push( value );
+       }
+};
+
+/**
+ * Focus the widget
+ */
+OO.ui.TagMultiselectWidget.prototype.focus = function () {
+       if ( this.hasInput ) {
+               this.input.focus();
+       }
+};
+
+/**
+ * Get the datas of the currently selected items
+ *
+ * @return {string[]|Object[]} Datas of currently selected items
+ */
+OO.ui.TagMultiselectWidget.prototype.getValue = function () {
+       return this.getItems()
+               .filter( function ( item ) {
+                       return item.isValid();
+               } )
+               .map( function ( item ) {
+                       return item.getData();
+               } );
+};
+
+/**
+ * Set the value of this widget by datas.
+ *
+ * @param {string|string[]|Object|Object[]} value An object representing the data
+ *  and label of the value. If the widget allows arbitrary values,
+ *  the items will be added as-is. Otherwise, the data value will
+ *  be checked against allowedValues.
+ *  This object must contain at least a data key. Example:
+ *  { data: 'foo', label: 'Foo item' }
+ *  For multiple items, use an array of objects. For example:
+ *   [
+ *      { data: 'foo', label: 'Foo item' },
+ *      { data: 'bar', label: 'Bar item' }
+ *      ]
+ *  Value can also be added with plaintext array, for example:
+ *  [ 'foo', 'bar', 'bla' ] or a single string, like 'foo'
+ */
+OO.ui.TagMultiselectWidget.prototype.setValue = function ( valueObject ) {
+       valueObject = Array.isArray( valueObject ) ? valueObject : [ valueObject ];
+
+       this.clearItems();
+       valueObject.forEach( function ( obj ) {
+               if ( typeof obj === 'string' ) {
+                       this.addTag( obj );
+               } else {
+                       this.addTag( obj.data, obj.label );
+               }
+       }.bind( this ) );
+};
+
+/**
+ * Add tag to the display area
+ *
+ * @param {string|Object} data Tag data
+ * @param {string} [label] Tag label. If no label is provided, the
+ *  stringified version of the data will be used instead.
+ * @return {boolean} Item was added successfully
+ */
+OO.ui.TagMultiselectWidget.prototype.addTag = function ( data, label ) {
+       var newItemWidget,
+               isValid = this.isAllowedData( data );
+
+       if ( isValid || this.allowDisplayInvalidTags ) {
+               newItemWidget = this.createTagItemWidget( data, label );
+               newItemWidget.toggleValid( isValid );
+               this.addItems( [ newItemWidget ] );
+       }
+};
+
+/**
+ * Remove tag by its data property.
+ *
+ * @param {string|Object} data Tag data
+ */
+OO.ui.TagMultiselectWidget.prototype.removeTagByData = function ( data ) {
+       var item = this.getItemFromData( data );
+
+       this.removeItems( [ item ] );
+};
+
+/**
+ * Construct a OO.ui.TagItemWidget (or a subclass thereof) from given label and data.
+ *
+ * @protected
+ * @param {string} data Item data
+ * @param {string} label The label text.
+ * @return {OO.ui.TagItemWidget}
+ */
+OO.ui.TagMultiselectWidget.prototype.createTagItemWidget = function ( data, label ) {
+       label = label || data;
+
+       return new OO.ui.TagItemWidget( { data: data, label: label } );
+};
+
+/**
+ * Given an item, returns the item after it. If the item is already the
+ * last item, return `this.input`. If no item is passed, returns the
+ * very first item.
+ *
+ * @protected
+ * @param {OO.ui.TagItemWidget} [item] Tag item
+ * @return {OO.ui.Widget} The next widget available.
+ */
+OO.ui.TagMultiselectWidget.prototype.getNextItem = function ( item ) {
+       var itemIndex = this.items.indexOf( item );
+
+       if ( item === undefined || itemIndex === -1 ) {
+               return this.items[ 0 ];
+       }
+
+       if ( itemIndex === this.items.length - 1 ) { // Last item
+               if ( this.hasInput ) {
+                       return this.input;
+               } else {
+                       // Return first item
+                       return this.items[ 0 ];
+               }
+       } else {
+               return this.items[ itemIndex + 1 ];
+       }
+};
+
+/**
+ * Given an item, returns the item before it. If the item is already the
+ * first item, return `this.input`. If no item is passed, returns the
+ * very last item.
+ *
+ * @protected
+ * @param {OO.ui.TagItemWidget} [item] Tag item
+ * @return {OO.ui.Widget} The previous widget available.
+ */
+OO.ui.TagMultiselectWidget.prototype.getPreviousItem = function ( item ) {
+       var itemIndex = this.items.indexOf( item );
+
+       if ( item === undefined || itemIndex === -1 ) {
+               return this.items[ this.items.length - 1 ];
+       }
+
+       if ( itemIndex === 0 ) {
+               if ( this.hasInput ) {
+                       return this.input;
+               } else {
+                       // Return the last item
+                       return this.items[ this.items.length - 1 ];
+               }
+       } else {
+               return this.items[ itemIndex - 1 ];
+       }
+};
+
+/**
+ * Update the dimensions of the text input field to encompass all available area.
+ * This is especially relevant for when the input is at the edge of a line
+ * and should get smaller. The usual operation (as an inline-block with min-width)
+ * does not work in that case, pushing the input downwards to the next line.
+ *
+ * @private
+ */
+OO.ui.TagMultiselectWidget.prototype.updateInputSize = function () {
+       var $lastItem, direction, contentWidth, currentWidth, bestWidth;
+       if ( this.inputPosition === 'inline' && !this.isDisabled() ) {
+               this.input.$input.css( 'width', '1em' );
+               $lastItem = this.$group.children().last();
+               direction = OO.ui.Element.static.getDir( this.$handle );
+
+               // Get the width of the input with the placeholder text as
+               // the value and save it so that we don't keep recalculating
+               if (
+                       this.contentWidthWithPlaceholder === undefined &&
+                       this.input.getValue() === '' &&
+                       this.input.$input.attr( 'placeholder' ) !== undefined
+               ) {
+                       this.input.setValue( this.input.$input.attr( 'placeholder' ) );
+                       this.contentWidthWithPlaceholder = this.input.$input[ 0 ].scrollWidth;
+                       this.input.setValue( '' );
+
+               }
+
+               // Always keep the input wide enough for the placeholder text
+               contentWidth = Math.max(
+                       this.input.$input[ 0 ].scrollWidth,
+                       // undefined arguments in Math.max lead to NaN
+                       ( this.contentWidthWithPlaceholder === undefined ) ?
+                               0 : this.contentWidthWithPlaceholder
+               );
+               currentWidth = this.input.$input.width();
+
+               if ( contentWidth < currentWidth ) {
+                       this.updateIfHeightChanged();
+                       // All is fine, don't perform expensive calculations
+                       return;
+               }
+
+               if ( $lastItem.length === 0 ) {
+                       bestWidth = this.$content.innerWidth();
+               } else {
+                       bestWidth = direction === 'ltr' ?
+                               this.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :
+                               $lastItem.position().left;
+               }
+
+               // Some safety margin for sanity, because I *really* don't feel like finding out where the few
+               // pixels this is off by are coming from.
+               bestWidth -= 10;
+               if ( contentWidth > bestWidth ) {
+                       // This will result in the input getting shifted to the next line
+                       bestWidth = this.$content.innerWidth() - 10;
+               }
+               this.input.$input.width( Math.floor( bestWidth ) );
+               this.updateIfHeightChanged();
+       } else {
+               this.updateIfHeightChanged();
+       }
+};
+
+/**
+ * Determine if widget height changed, and if so,
+ * emit the resize event. This is useful for when there are either
+ * menus or popups attached to the bottom of the widget, to allow
+ * them to change their positioning in case the widget moved down
+ * or up.
+ *
+ * @private
+ */
+OO.ui.TagMultiselectWidget.prototype.updateIfHeightChanged = function () {
+       var height = this.$element.height();
+       if ( height !== this.height ) {
+               this.height = height;
+               this.emit( 'resize' );
+       }
+};
+
+/**
+ * Check whether all items in the widget are valid
+ *
+ * @return {boolean} Widget is valid
+ */
+OO.ui.TagMultiselectWidget.prototype.checkValidity = function () {
+       return this.getItems().every( function ( item ) {
+               return item.isValid();
+       } );
+};
+
+/**
+ * Set the valid state of this item
+ *
+ * @param {boolean} [valid] Item is valid
+ * @fires valid
+ */
+OO.ui.TagMultiselectWidget.prototype.toggleValid = function ( valid ) {
+       valid = valid === undefined ? !this.valid : !!valid;
+
+       if ( this.valid !== valid ) {
+               this.valid = valid;
+
+               this.setFlags( { invalid: !this.valid } );
+
+               this.emit( 'valid', this.valid );
+       }
+};
+
+/**
+ * Get the current valid state of the widget
+ *
+ * @return {boolean} Widget is valid
+ */
+OO.ui.TagMultiselectWidget.prototype.isValid = function () {
+       return this.valid;
+};
+
+/**
+ * PopupTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget} intended
+ * to use a popup. The popup can be configured to have a default input to insert values into the widget.
+ *
+ * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example: A basic PopupTagMultiselectWidget.
+ *     var widget = new OO.ui.PopupTagMultiselectWidget();
+ *     $( 'body' ).append( widget.$element );
+ *
+ *     // Example: A PopupTagMultiselectWidget with an external popup.
+ *     var popupInput = new OO.ui.TextInputWidget(),
+ *         widget = new OO.ui.PopupTagMultiselectWidget( {
+ *            popupInput: popupInput,
+ *            popup: {
+ *               $content: popupInput.$element
+ *            }
+ *         } );
+ *     $( 'body' ).append( widget.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.TagMultiselectWidget
+ * @mixins OO.ui.mixin.PopupElement
+ *
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} [$overlay] An overlay for the popup
+ * @cfg {Object} [popup] Configuration options for the popup
+ * @cfg {OO.ui.InputWidget} [popupInput] An input widget inside the popup that will be
+ *  focused when the popup is opened and will be used as replacement for the
+ *  general input in the widget.
+ */
+OO.ui.PopupTagMultiselectWidget = function OoUiPopupTagMultiselectWidget( config ) {
+       var defaultInput,
+               defaultConfig = { popup: {} };
+
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.PopupTagMultiselectWidget.parent.call( this, $.extend( { inputPosition: 'none' }, config ) );
+
+       this.$overlay = config.$overlay || this.$element;
+
+       if ( !config.popup ) {
+               // For the default base implementation, we give a popup
+               // with an input widget inside it. For any other use cases
+               // the popup needs to be populated externally and the
+               // event handled to add tags separately and manually
+               defaultInput = new OO.ui.TextInputWidget();
+
+               defaultConfig.popupInput = defaultInput;
+               defaultConfig.popup.$content = defaultInput.$element;
+
+               this.$element.addClass( 'oo-ui-popupTagMultiselectWidget-defaultPopup' );
+       }
+
+       // Add overlay, and add that to the autoCloseIgnore
+       defaultConfig.popup.$overlay = this.$overlay;
+       defaultConfig.popup.$autoCloseIgnore = this.hasInput ?
+               this.input.$element.add( this.$overlay ) : this.$overlay;
+
+       // Allow extending any of the above
+       config = $.extend( defaultConfig, config );
+
+       // Mixin constructors
+       OO.ui.mixin.PopupElement.call( this, config );
+
+       if ( this.hasInput ) {
+               this.input.$input.on( 'focus', this.popup.toggle.bind( this.popup, true ) );
+       }
+
+       // Configuration options
+       this.popupInput = config.popupInput;
+       if ( this.popupInput ) {
+               this.popupInput.connect( this, {
+                       enter: 'onPopupInputEnter'
+               } );
+       }
+
+       // Events
+       this.popup.connect( this, { toggle: 'onPopupToggle' } );
+       this.$tabIndexed
+               .on( 'focus', this.focus.bind( this ) );
+
+       // Initialize
+       this.$element
+               .append( this.popup.$element )
+               .addClass( 'oo-ui-popupTagMultiselectWidget' );
+};
+
+/* Initialization */
+
+OO.inheritClass( OO.ui.PopupTagMultiselectWidget, OO.ui.TagMultiselectWidget );
+OO.mixinClass( OO.ui.PopupTagMultiselectWidget, OO.ui.mixin.PopupElement );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.PopupTagMultiselectWidget.prototype.focus = function () {
+       // Since the parent deals with input focus, only
+       // call the parent method if our input isn't in the
+       // popup
+       if ( !this.popupInput ) {
+               // Parent method
+               OO.ui.PopupTagMultiselectWidget.parent.prototype.focus.call( this );
+       }
+
+       this.popup.toggle( true );
+};
+
+/**
+ * Respond to popup toggle event
+ *
+ * @param {boolean} isVisible Popup is visible
+ */
+OO.ui.PopupTagMultiselectWidget.prototype.onPopupToggle = function ( isVisible ) {
+       if ( isVisible && this.popupInput ) {
+               this.popupInput.focus();
+       }
+};
+
+/**
+ * Respond to popup input enter event
+ */
+OO.ui.PopupTagMultiselectWidget.prototype.onPopupInputEnter = function () {
+       if ( this.popupInput ) {
+               this.addTagByPopupValue( this.popupInput.getValue() );
+               this.popupInput.setValue( '' );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.PopupTagMultiselectWidget.prototype.onTagSelect = function ( item ) {
+       if ( this.popupInput && this.allowEditTags ) {
+               this.popupInput.setValue( item.getData() );
+               this.removeItems( [ item ] );
+
+               this.popup.toggle( true );
+               this.popupInput.focus();
+       } else {
+               // Parent
+               OO.ui.PopupTagMultiselectWidget.parent.prototype.onTagSelect.call( this, item );
+       }
+};
+
+/**
+ * Add a tag by the popup value.
+ * Whatever is responsible for setting the value in the popup should call
+ * this method to add a tag, or use the regular methods like #addTag or
+ * #setValue directly.
+ *
+ * @param {string} data The value of item
+ * @param {string} [label] The label of the tag. If not given, the data is used.
+ */
+OO.ui.PopupTagMultiselectWidget.prototype.addTagByPopupValue = function ( data, label ) {
+       this.addTag( data, label );
+};
+
+/**
+ * MenuTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget} intended
+ * to use a menu of selectable options.
+ *
+ * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example: A basic MenuTagMultiselectWidget.
+ *     var widget = new OO.ui.MenuTagMultiselectWidget( {
+ *         inputPosition: 'outline',
+ *         options: [
+ *            { data: 'option1', label: 'Option 1' },
+ *            { data: 'option2', label: 'Option 2' },
+ *            { data: 'option3', label: 'Option 3' },
+ *         ],
+ *         selected: [ 'option1', 'option2' ]
+ *     } );
+ *     $( 'body' ).append( widget.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.TagMultiselectWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration object
+ * @cfg {Object} [menu] Configuration object for the menu widget
+ * @cfg {jQuery} [$overlay] An overlay for the menu
+ * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
+ */
+OO.ui.MenuTagMultiselectWidget = function OoUiMenuTagMultiselectWidget( config ) {
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.MenuTagMultiselectWidget.parent.call( this, config );
+
+       this.$overlay = config.$overlay || this.$element;
+
+       this.menu = this.createMenuWidget( $.extend( {
+               widget: this,
+               input: this.hasInput ? this.input : null,
+               $input: this.hasInput ? this.input.$input : null,
+               filterFromInput: !!this.hasInput,
+               $autoCloseIgnore: this.hasInput ?
+                       this.input.$element.add( this.$overlay ) : this.$overlay,
+               $container: this.hasInput && this.inputPosition === 'outline' ?
+                       this.input.$element : this.$element,
+               $overlay: this.$overlay,
+               disabled: this.isDisabled()
+       }, config.menu ) );
+       this.addOptions( config.options || [] );
+
+       // Events
+       this.menu.connect( this, {
+               choose: 'onMenuChoose',
+               toggle: 'onMenuToggle'
+       } );
+       if ( this.hasInput ) {
+               this.input.connect( this, { change: 'onInputChange' } );
+       }
+       this.connect( this, { resize: 'onResize' } );
+
+       // Initialization
+       this.$overlay
+               .append( this.menu.$element );
+       this.$element
+               .addClass( 'oo-ui-menuTagMultiselectWidget' );
+};
+
+/* Initialization */
+
+OO.inheritClass( OO.ui.MenuTagMultiselectWidget, OO.ui.TagMultiselectWidget );
+
+/* Methods */
+
+/**
+ * Respond to resize event
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.onResize = function () {
+       // Reposition the menu
+       this.menu.position();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.onInputFocus = function () {
+       // Parent method
+       OO.ui.MenuTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
+
+       this.menu.toggle( true );
+};
+
+/**
+ * Respond to input change event
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.onInputChange = function () {
+       this.menu.toggle( true );
+};
+
+/**
+ * Respond to menu choose event
+ *
+ * @param {OO.ui.OptionWidget} menuItem Chosen menu item
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.onMenuChoose = function ( menuItem ) {
+       // Add tag
+       this.addTag( menuItem.getData(), menuItem.getLabel() );
+};
+
+/**
+ * Respond to menu toggle event. Reset item highlights on hide.
+ *
+ * @param {boolean} isVisible The menu is visible
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
+       if ( !isVisible ) {
+               this.menu.selectItem( null );
+               this.menu.highlightItem( null );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.onTagSelect = function ( tagItem ) {
+       var menuItem = this.menu.getItemFromData( tagItem.getData() );
+       // Override the base behavior from TagMultiselectWidget; the base behavior
+       // in TagMultiselectWidget is to remove the tag to edit it in the input,
+       // but in our case, we want to utilize the menu selection behavior, and
+       // definitely not remove the item.
+
+       // Select the menu item
+       this.menu.selectItem( menuItem );
+
+       this.focus();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.addTagFromInput = function () {
+       var inputValue = this.input.getValue(),
+               highlightedItem = this.menu.getHighlightedItem(),
+               item = this.menu.getItemFromData( inputValue );
+
+       // Override the parent method so we add from the menu
+       // rather than directly from the input
+
+       // Look for a highlighted item first
+       if ( highlightedItem ) {
+               this.addTag( highlightedItem.getData(), highlightedItem.getLabel() );
+       } else if ( item ) {
+               // Look for the element that fits the data
+               this.addTag( item.getData(), item.getLabel() );
+       } else {
+               // Otherwise, add the tag - the method will only add if the
+               // tag is valid or if invalid tags are allowed
+               this.addTag( inputValue );
+       }
+};
+
+/**
+ * Return the visible items in the menu. This is mainly used for when
+ * the menu is filtering results.
+ *
+ * @return {OO.ui.MenuOptionWidget[]} Visible results
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.getMenuVisibleItems = function () {
+       return this.menu.getItems().filter( function ( menuItem ) {
+               return menuItem.isVisible();
+       } );
+};
+
+/**
+ * Create the menu for this widget. This is in a separate method so that
+ * child classes can override this without polluting the constructor with
+ * unnecessary extra objects that will be overidden.
+ *
+ * @param {Object} menuConfig Configuration options
+ * @return {OO.ui.MenuSelectWidget} Menu widget
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfig ) {
+       return new OO.ui.FloatingMenuSelectWidget( menuConfig );
+};
+
+/**
+ * Add options to the menu
+ *
+ * @param {Object[]} options Object defining options
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.addOptions = function ( menuOptions ) {
+       var widget = this,
+               items = menuOptions.map( function ( obj ) {
+                       return widget.createMenuOptionWidget( obj.data, obj.label );
+               } );
+
+       this.menu.addItems( items );
+};
+
+/**
+ * Create a menu option widget.
+ *
+ * @param {string} data Item data
+ * @param {string} [label] Item label
+ * @return {OO.ui.OptionWidget} Option widget
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label ) {
+       return new OO.ui.MenuOptionWidget( {
+               data: data,
+               label: label || data
+       } );
+};
+
+/**
+ * Get the menu
+ *
+ * @return {OO.ui.MenuSelectWidget} Menu
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.getMenu = function () {
+       return this.menu;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.isAllowedData = function ( data ) {
+       return OO.ui.MenuTagMultiselectWidget.parent.prototype.isAllowedData.call( this, data ) &&
+               !!this.menu.getItemFromData( data );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.focus = function () {
+       // Parent method
+       OO.ui.MenuTagMultiselectWidget.parent.prototype.focus.call( this );
+
+       if ( !this.isDisabled() ) {
+               this.menu.toggle( true );
+       }
+};
+
 /**
  * SelectFileWidgets allow for selecting files, using the HTML5 File API. These
  * widgets can be configured with {@link OO.ui.mixin.IconElement icons} and {@link
index 4842a46..013d52d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
   background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
   top: 1em;
   bottom: 1em;
   max-height: 100%;
-  max-height: calc(100% - 2em);
+  max-height: calc( 100% - 2em );
   border: 1px solid #ccc;
   border-radius: 0.5em;
   box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
index beca510..1cb55d6 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:41Z
+ * Date: 2017-04-11T22:51:10Z
  */
 .oo-ui-window {
   background: transparent;
index 1cbec34..b23949f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.2
+ * OOjs UI v0.21.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-30T20:34:37Z
+ * Date: 2017-04-11T22:51:05Z
  */
 ( function ( OO ) {
 
@@ -60,14 +60,6 @@ OO.ui.ActionWidget = function OoUiActionWidget( config ) {
 OO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget );
 OO.mixinClass( OO.ui.ActionWidget, OO.ui.mixin.PendingElement );
 
-/* Events */
-
-/**
- * A resize event is emitted when the size of the widget changes.
- *
- * @event resize
- */
-
 /* Methods */
 
 /**
@@ -102,90 +94,6 @@ OO.ui.ActionWidget.prototype.getModes = function () {
        return this.modes.slice();
 };
 
-/**
- * Emit a resize event if the size has changed.
- *
- * @private
- * @chainable
- */
-OO.ui.ActionWidget.prototype.propagateResize = function () {
-       var width, height;
-
-       if ( this.isElementAttached() ) {
-               width = this.$element.width();
-               height = this.$element.height();
-
-               if ( width !== this.width || height !== this.height ) {
-                       this.width = width;
-                       this.height = height;
-                       this.emit( 'resizePrivate' );
-                       if ( this.emit( 'resize' ) ) {
-                               OO.ui.warnDeprecation( 'ActionWidget: resize event is deprecated. See T129162.' );
-                       }
-               }
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.setIcon = function () {
-       // Mixin method
-       OO.ui.mixin.IconElement.prototype.setIcon.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.setLabel = function () {
-       // Mixin method
-       OO.ui.mixin.LabelElement.prototype.setLabel.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.setFlags = function () {
-       // Mixin method
-       OO.ui.mixin.FlaggedElement.prototype.setFlags.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.clearFlags = function () {
-       // Mixin method
-       OO.ui.mixin.FlaggedElement.prototype.clearFlags.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * Toggle the visibility of the action button.
- *
- * @param {boolean} [show] Show button, omit to toggle visibility
- * @chainable
- */
-OO.ui.ActionWidget.prototype.toggle = function () {
-       // Parent method
-       OO.ui.ActionWidget.parent.prototype.toggle.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
 /* eslint-disable no-unused-vars */
 /**
  * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them.
@@ -320,14 +228,6 @@ OO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ];
  * @param {OO.ui.ActionWidget} action Action that was clicked
  */
 
-/**
- * @event resize
- *
- * A 'resize' event is emitted when an action widget is resized.
- *
- * @param {OO.ui.ActionWidget} action Action that was resized
- */
-
 /**
  * @event add
  *
@@ -566,11 +466,6 @@ OO.ui.ActionSet.prototype.add = function ( actions ) {
                        click: [ 'emit', 'click', action ],
                        toggle: [ 'onActionChange' ]
                } );
-               action.on( 'resizePrivate', function ( action ) {
-                       if ( this.emit( 'resize', action ) ) {
-                               OO.ui.warnDeprecation( 'ActionSet: resize event is deprecated. See T129162.' );
-                       }
-               }, [ action ], this );
                this.list.push( action );
        }
        this.organized = false;
@@ -2842,6 +2737,7 @@ OO.ui.MessageDialog.prototype.getActionProcess = function ( action ) {
  * @param {Object} [data] Dialog opening data
  * @param {jQuery|string|Function|null} [data.title] Description of the action being confirmed
  * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence
+ * @param {string} [data.size] Symbolic name of the dialog size, see OO.ui.Window
  * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each
  *   action item
  */
@@ -2857,6 +2753,7 @@ OO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) {
                        this.message.setLabel(
                                data.message !== undefined ? data.message : this.constructor.static.message
                        );
+                       this.size = data.size !== undefined ? data.size : this.constructor.static.size;
                }, this );
 };
 
@@ -3408,6 +3305,8 @@ OO.ui.getWindowManager = function () {
  *         console.log( 'User closed the dialog.' );
  *     } );
  *
+ *     OO.ui.alert( 'Something larger happened!', { size: 'large' } );
+ *
  * @param {jQuery|string} text Message text to display
  * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
  * @return {jQuery.Promise} Promise resolved when the user closes the dialog
index 9dd3404..c194497 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
     <path d="M11 12h4V7h-4v5zm-5 2h9v-1H6v1zm0 2h9v-1H6v1zm0 2h9v-1H6v1zm4-9H6v1h4V9zm0 2H6v1h4v-1zm0-4H6v1h4V7zM4 5h13v16H7c-1.7 0-3-1.3-3-3V5z"/>
     <path d="M18 4v14h2V2H7v2" fill-rule="evenodd"/>
index b57dae2..40a9348 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
     <path d="M13 12H9V7h4v5zm5 2H9v-1h9v1zm0 2H9v-1h9v1zm0 2H9v-1h9v1zm-4-9h4v1h-4V9zm0 2h4v1h-4v-1zm0-4h4v1h-4V7zm6-2H7v16h10c1.7 0 3-1.3 3-3V5z"/>
     <path d="M6 4v14H4V2h13v2" fill-rule="evenodd"/>
index 884e55c..86b004f 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
     <path d="M11 12h4V7h-4v5zm-5 2h9v-1H6v1zm0 2h9v-1H6v1zm0 2h9v-1H6v1zm4-9H6v1h4V9zm0 2H6v1h4v-1zm0-4H6v1h4V7zM4 5h13v16H7c-1.7 0-3-1.3-3-3V5z"/>
     <path d="M18 4v14h2V2H7v2" fill-rule="evenodd"/>
index 599aa69..838655b 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
     <path d="M11 12h4V7h-4v5zm-5 2h9v-1H6v1zm0 2h9v-1H6v1zm0 2h9v-1H6v1zm4-9H6v1h4V9zm0 2H6v1h4v-1zm0-4H6v1h4V7zM4 5h13v16H7c-1.7 0-3-1.3-3-3V5z"/>
     <path d="M18 4v14h2V2H7v2" fill-rule="evenodd"/>
index 9dd3404..c194497 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
     <path d="M11 12h4V7h-4v5zm-5 2h9v-1H6v1zm0 2h9v-1H6v1zm0 2h9v-1H6v1zm4-9H6v1h4V9zm0 2H6v1h4v-1zm0-4H6v1h4V7zM4 5h13v16H7c-1.7 0-3-1.3-3-3V5z"/>
     <path d="M18 4v14h2V2H7v2" fill-rule="evenodd"/>
index 64b9181..e2793b5 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
     <path d="M13 12H9V7h4v5zm5 2H9v-1h9v1zm0 2H9v-1h9v1zm0 2H9v-1h9v1zm-4-9h4v1h-4V9zm0 2h4v1h-4v-1zm0-4h4v1h-4V7zm6-2H7v16h10c1.7 0 3-1.3 3-3V5z"/>
     <path d="M6 4v14H4V2h13v2" fill-rule="evenodd"/>
index 18799af..bf3d169 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
     <path d="M13 12H9V7h4v5zm5 2H9v-1h9v1zm0 2H9v-1h9v1zm0 2H9v-1h9v1zm-4-9h4v1h-4V9zm0 2h4v1h-4v-1zm0-4h4v1h-4V7zm6-2H7v16h10c1.7 0 3-1.3 3-3V5z"/>
     <path d="M6 4v14H4V2h13v2" fill-rule="evenodd"/>
index b57dae2..40a9348 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
     <path d="M13 12H9V7h4v5zm5 2H9v-1h9v1zm0 2H9v-1h9v1zm0 2H9v-1h9v1zm-4-9h4v1h-4V9zm0 2h4v1h-4v-1zm0-4h4v1h-4V7zm6-2H7v16h10c1.7 0 3-1.3 3-3V5z"/>
     <path d="M6 4v14H4V2h13v2" fill-rule="evenodd"/>
index 582adce..ae66af4 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down-invert.png differ
index e194d0d..b5e6144 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><g fill="#fff">
-    <g id="down">
-        <path id="arrow" d="M1 4h10L6 9 1 4"/>
-    </g>
+       <path d="M11.05 3.996l-.965-1.053-4.035 3.86-3.947-3.86L1.05 3.996l5 5 5-5"/>
 </g></svg>
index af67c7a..34f5041 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down.png differ
index f5c76f3..d3e55d1 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
-    <g id="down">
-        <path id="arrow" d="M1 4h10L6 9 1 4"/>
-    </g>
+       <path d="M11.05 3.996l-.965-1.053-4.035 3.86-3.947-3.86L1.05 3.996l5 5 5-5"/>
 </svg>
index 05578be..68bf475 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr-invert.png differ
index 9e0e569..78f4b51 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><g fill="#fff">
-    <g id="ltr">
-        <path id="arrow" d="M4 1v10l5-5-5-5"/>
-    </g>
+       <path d="M4.026 11l-1.052-.965L6.832 6 2.974 2.053 4.026 1l5 5-5 5"/>
 </g></svg>
index d7a4111..cadc38f 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr.png differ
index 059372d..e99855b 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
-    <g id="ltr">
-        <path id="arrow" d="M4 1v10l5-5-5-5"/>
-    </g>
+       <path d="M4.026 11l-1.052-.965L6.832 6 2.974 2.053 4.026 1l5 5-5 5"/>
 </svg>
index 9731658..fae56f1 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl-invert.png differ
index d032b05..bc0ff6f 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><g fill="#fff">
-    <g id="rtl">
-        <path id="arrow" d="M8 11V1L3 6l5 5"/>
-    </g>
+       <path d="M7.974 11l1.052-.965L5.168 6l3.858-3.947L7.974 1l-5 5 5 5"/>
 </g></svg>
index afceed6..5a4c0b6 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl.png differ
index c6498e8..1647501 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
-    <g id="rtl">
-        <path id="arrow" d="M8 11V1L3 6l5 5"/>
-    </g>
+       <path d="M7.974 11l1.052-.965L5.168 6l3.858-3.947L7.974 1l-5 5 5 5"/>
 </svg>
index 218a700..56eeea4 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up-invert.png differ
index 3b79abb..3c81ae5 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><g fill="#fff">
-    <g id="up">
-        <path id="arrow" d="M1 8h10L6 3 1 8"/>
-    </g>
+       <path d="M11 7.974l-.965 1.052L6 5.168 2.053 9.026 1 7.974l5-5 5 5"/>
 </g></svg>
index ee12d6e..672b7f3 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up.png and b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up.png differ
index 5eada07..ca93281 100644 (file)
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
-    <g id="up">
-        <path id="arrow" d="M1 8h10L6 3 1 8"/>
-    </g>
+       <path d="M11 7.974l-.965 1.052L6 5.168 2.053 9.026 1 7.974l5-5 5 5"/>
 </svg>
index df32417..1b99365 100644 (file)
@@ -6,18 +6,6 @@
                "invert": {
                        "color": "#fff",
                        "global": true
-               },
-               "progressive": {
-                       "color": "#36c"
-               },
-               "constructive": {
-                       "color": "#36c"
-               },
-               "destructive": {
-                       "color": "#d33"
-               },
-               "warning": {
-                       "color": "#ff5d00"
                }
        },
        "images": {