Jforrester has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/223482

Change subject: Update OOjs UI to v0.11.8
......................................................................

Update OOjs UI to v0.11.8

Release notes:
 https://git.wikimedia.org/blob/oojs%2Fui.git/v0.11.8/History.md

Change-Id: I701c504acf0d527916f1925bbf49177cc9c0d883
---
M composer.json
M composer.lock
M composer/installed.json
M oojs/oojs-ui/.gitignore
M oojs/oojs-ui/AUTHORS.txt
M oojs/oojs-ui/Gruntfile.js
M oojs/oojs-ui/History.md
M oojs/oojs-ui/README.md
M oojs/oojs-ui/bin/generate-JSPHP-for-karma.php
M oojs/oojs-ui/build/tasks/typos.js
M oojs/oojs-ui/composer.json
M oojs/oojs-ui/demos/demo.js
M oojs/oojs-ui/demos/index.html
M oojs/oojs-ui/demos/pages/toolbars.js
M oojs/oojs-ui/demos/pages/widgets.js
M oojs/oojs-ui/demos/widgets.php
M oojs/oojs-ui/i18n/fa.json
M oojs/oojs-ui/i18n/lt.json
M oojs/oojs-ui/i18n/pa.json
M oojs/oojs-ui/i18n/ps.json
M oojs/oojs-ui/i18n/ru.json
M oojs/oojs-ui/i18n/yi.json
M oojs/oojs-ui/i18n/yue.json
M oojs/oojs-ui/package.json
M oojs/oojs-ui/php/Tag.php
M oojs/oojs-ui/php/widgets/DropdownInputWidget.php
M oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php
M oojs/oojs-ui/php/widgets/TextInputWidget.php
M oojs/oojs-ui/src/Element.js
M oojs/oojs-ui/src/styles/common.less
M oojs/oojs-ui/src/themes/apex/icons-editing-core.json
M oojs/oojs-ui/src/themes/apex/windows.less
M oojs/oojs-ui/src/themes/mediawiki/elements.less
M oojs/oojs-ui/src/themes/mediawiki/tools.less
M oojs/oojs-ui/src/widgets/DropdownInputWidget.js
M oojs/oojs-ui/src/widgets/RadioSelectInputWidget.js
M oojs/oojs-ui/src/widgets/TextInputWidget.js
M oojs/oojs-ui/tests/JSPHP.test.karma.js
38 files changed, 340 insertions(+), 190 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vendor 
refs/changes/82/223482/1

diff --git a/composer.json b/composer.json
index 28b0680..1b29488 100644
--- a/composer.json
+++ b/composer.json
@@ -9,7 +9,7 @@
                "mediawiki/at-ease": "1.0.0",
                "monolog/monolog": "1.14.0",
                "ruflin/elastica": "1.3.0.0",
-               "oojs/oojs-ui": "0.11.7",
+               "oojs/oojs-ui": "0.11.8",
                "wikimedia/cdb": "1.0.1",
                "wikimedia/ip-set": "1.0.0",
                "wikimedia/assert": "0.2.2",
diff --git a/composer.lock b/composer.lock
index e8264ba..b7e4831 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at 
https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file";,
         "This file is @generated automatically"
     ],
-    "hash": "3ea8bfa5bc62fdc11043e06e2bf29b40",
+    "hash": "698d01963a7a8e0ec2d5107672b6ddb0",
     "packages": [
         {
             "name": "cssjanus/cssjanus",
@@ -287,19 +287,20 @@
         },
         {
             "name": "oojs/oojs-ui",
-            "version": "v0.11.7",
+            "version": "v0.11.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/wikimedia/oojs-ui.git";,
-                "reference": "6b0f7ec2c918db5029f697d0a3bc152991dbfc98"
+                "reference": "0f86f7fd72cdccd2a2b18a18db13da00c91938c5"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/wikimedia/oojs-ui/zipball/6b0f7ec2c918db5029f697d0a3bc152991dbfc98";,
-                "reference": "6b0f7ec2c918db5029f697d0a3bc152991dbfc98",
+                "url": 
"https://api.github.com/repos/wikimedia/oojs-ui/zipball/0f86f7fd72cdccd2a2b18a18db13da00c91938c5";,
+                "reference": "0f86f7fd72cdccd2a2b18a18db13da00c91938c5",
                 "shasum": ""
             },
             "require": {
+                "mediawiki/at-ease": "1.0.0",
                 "php": ">=5.3.3"
             },
             "require-dev": {
@@ -319,7 +320,7 @@
             ],
             "description": "Provides library of common widgets, layouts, and 
windows.",
             "homepage": "https://www.mediawiki.org/wiki/OOjs_UI";,
-            "time": "2015-07-01 18:19:38"
+            "time": "2015-07-08 01:19:00"
         },
         {
             "name": "psr/log",
diff --git a/composer/installed.json b/composer/installed.json
index f7054ea..518b015 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -674,44 +674,6 @@
         "homepage": "https://github.com/wikimedia/IPSet";
     },
     {
-        "name": "oojs/oojs-ui",
-        "version": "v0.11.7",
-        "version_normalized": "0.11.7.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/wikimedia/oojs-ui.git";,
-            "reference": "6b0f7ec2c918db5029f697d0a3bc152991dbfc98"
-        },
-        "dist": {
-            "type": "zip",
-            "url": 
"https://api.github.com/repos/wikimedia/oojs-ui/zipball/6b0f7ec2c918db5029f697d0a3bc152991dbfc98";,
-            "reference": "6b0f7ec2c918db5029f697d0a3bc152991dbfc98",
-            "shasum": ""
-        },
-        "require": {
-            "php": ">=5.3.3"
-        },
-        "require-dev": {
-            "jakub-onderka/php-parallel-lint": "0.9",
-            "mediawiki/mediawiki-codesniffer": "0.3.0",
-            "phpunit/phpunit": "~4.5"
-        },
-        "time": "2015-07-01 18:19:38",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "php/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/";,
-        "license": [
-            "MIT"
-        ],
-        "description": "Provides library of common widgets, layouts, and 
windows.",
-        "homepage": "https://www.mediawiki.org/wiki/OOjs_UI";
-    },
-    {
         "name": "wikimedia/composer-merge-plugin",
         "version": "v1.2.1",
         "version_normalized": "1.2.1.0",
@@ -759,5 +721,44 @@
             }
         ],
         "description": "Composer plugin to merge multiple composer.json files"
+    },
+    {
+        "name": "oojs/oojs-ui",
+        "version": "v0.11.8",
+        "version_normalized": "0.11.8.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/wikimedia/oojs-ui.git";,
+            "reference": "0f86f7fd72cdccd2a2b18a18db13da00c91938c5"
+        },
+        "dist": {
+            "type": "zip",
+            "url": 
"https://api.github.com/repos/wikimedia/oojs-ui/zipball/0f86f7fd72cdccd2a2b18a18db13da00c91938c5";,
+            "reference": "0f86f7fd72cdccd2a2b18a18db13da00c91938c5",
+            "shasum": ""
+        },
+        "require": {
+            "mediawiki/at-ease": "1.0.0",
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "jakub-onderka/php-parallel-lint": "0.9",
+            "mediawiki/mediawiki-codesniffer": "0.3.0",
+            "phpunit/phpunit": "~4.5"
+        },
+        "time": "2015-07-08 01:19:00",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "classmap": [
+                "php/"
+            ]
+        },
+        "notification-url": "https://packagist.org/downloads/";,
+        "license": [
+            "MIT"
+        ],
+        "description": "Provides library of common widgets, layouts, and 
windows.",
+        "homepage": "https://www.mediawiki.org/wiki/OOjs_UI";
     }
 ]
diff --git a/oojs/oojs-ui/.gitignore b/oojs/oojs-ui/.gitignore
index 7f4bdf0..bab5022 100644
--- a/oojs/oojs-ui/.gitignore
+++ b/oojs/oojs-ui/.gitignore
@@ -8,3 +8,8 @@
 tests/JSPHP.test.js
 vendor
 composer.lock
+/demos/composer.json
+/demos/node_modules
+/demos/dist
+/demos/php
+
diff --git a/oojs/oojs-ui/AUTHORS.txt b/oojs/oojs-ui/AUTHORS.txt
index f15754d..cc0970d 100644
--- a/oojs/oojs-ui/AUTHORS.txt
+++ b/oojs/oojs-ui/AUTHORS.txt
@@ -2,7 +2,7 @@
 
 Bartosz Dziewoński <matma....@gmail.com>
 Ed Sanders <esand...@wikimedia.org>
-James D. Forrester  <jforres...@wikimedia.org>
+James D. Forrester <jforres...@wikimedia.org>
 Kirsten Menger-Anderson <kmen...@wikimedia.org>
 Roan Kattouw <r...@wikimedia.org>
 Rob Moen <rm...@wikimedia.org>
diff --git a/oojs/oojs-ui/Gruntfile.js b/oojs/oojs-ui/Gruntfile.js
index 331f41f..1e62f8c 100644
--- a/oojs/oojs-ui/Gruntfile.js
+++ b/oojs/oojs-ui/Gruntfile.js
@@ -239,6 +239,19 @@
                                src: '{dist,node_modules/{' + Object.keys( 
pgk.dependencies ).join( ',' ) + '}}/**/*',
                                dest: 'docs/',
                                expand: true
+                       },
+                       demos: {
+                               // Make sure you update this if dependencies 
are added
+                               src: 
'{node_modules/{jquery,oojs}/dist/**/*,composer.json,dist/**/*,php/**/*}',
+                               dest: 'demos/',
+                               expand: true
+                       },
+                       // Copys the necessary vendor/ files for demos without 
running "composer install"
+                       fastcomposerdemos: {
+                               // Make sure you update this if PHP 
dependencies are added
+                               src: 
'vendor/{autoload.php,composer,mediawiki/at-ease}',
+                               dest: 'demos/',
+                               expand: true
                        }
                },
                colorizeSvg: colorizeSvgFiles,
@@ -270,6 +283,7 @@
                        dev: [
                                '*.js',
                                '{build,demos,src,tests}/**/*.js',
+                               '!demos/{dist,node_modules,vendor}/**/*.js',
                                '!tests/JSPHP.test.js'
                        ]
                },
@@ -308,8 +322,11 @@
                                command: 'ruby bin/testsuitegenerator.rb src 
php > tests/JSPHP-suite.json'
                        },
                        phpGenerateJSPHPForKarma: {
-                               command: 'php 
../bin/generate-JSPHP-for-karma.php > JSPHP.test.js',
-                               cwd: './tests'
+                               command: 'composer update && php 
bin/generate-JSPHP-for-karma.php > tests/JSPHP.test.js'
+                       },
+                       demos: {
+                               command: 'composer update --no-dev',
+                               cwd: 'demos'
                        }
                },
                karma: {
@@ -358,7 +375,7 @@
                }
        } );
 
-       grunt.registerTask( 'pre-test', function () {
+       grunt.registerTask( 'enable-source-maps', function () {
                // Only create Source maps when doing a git-build for testing 
and local
                // development. Distributions for export should not, as the map 
would
                // be pointing at "../src".
@@ -388,9 +405,12 @@
        ] );
        grunt.registerTask( 'build-i18n', [ 'copy:i18n' ] );
        grunt.registerTask( 'build-tests', [ 'exec:rubyTestSuiteGenerator', 
'exec:phpGenerateJSPHPForKarma' ] );
-       grunt.registerTask( 'build', [ 'clean:build', 'fileExists', 'typos', 
'build-code', 'build-styling', 'build-i18n', 'build-tests', 'clean:tmp' ] );
+       grunt.registerTask( 'build', [
+               'clean:build', 'fileExists', 'typos', 'build-code', 
'build-styling', 'build-i18n',
+               'clean:tmp', 'demos'
+       ] );
 
-       grunt.registerTask( 'git-build', [ 'pre-git-build', 'build' ] );
+       grunt.registerTask( 'git-build', [ 'enable-source-maps', 
'pre-git-build', 'build' ] );
 
        // Quickly build a no-frills vector-only ltr-only version for 
development
        grunt.registerTask( 'quick-build', [
@@ -398,11 +418,12 @@
                'concat:js',
                'colorizeSvg', 'less:distVector', 'concat:css',
                'copy:imagesCommon', 'copy:imagesApex', 'copy:imagesMediaWiki',
-               'build-i18n'
+               'build-i18n', 'copy:demos', 'copy:fastcomposerdemos'
        ] );
 
        grunt.registerTask( 'lint', [ 'jshint', 'jscs', 'csslint', 'jsonlint', 
'banana' ] );
-       grunt.registerTask( 'test', [ 'lint', 'pre-test', 'git-build', 
'karma:main', 'karma:other' ] );
+       grunt.registerTask( 'test', [ 'lint', 'git-build', 'build-tests', 
'karma:main', 'karma:other' ] );
+       grunt.registerTask( 'demos', [ 'copy:demos', 'exec:demos' ] );
 
        grunt.registerTask( 'default', 'test' );
 };
diff --git a/oojs/oojs-ui/History.md b/oojs/oojs-ui/History.md
index 86287ce..bd6652d 100644
--- a/oojs/oojs-ui/History.md
+++ b/oojs/oojs-ui/History.md
@@ -1,13 +1,36 @@
 # OOjs UI Release History
 
+## v0.11.8 / 2015-07-07
+### Features
+* DropdownInputWidget, RadioSelectInputWidget: Consistently call #cleanUpValue 
(Bartosz Dziewoński)
+* TextInputWidget: Allow setting the HTML autocomplete attribute (Florian)
+* TextInputWidget: Support 'rows' option when in multiline mode (Kunal Mehta)
+* Make scroll into view work in scrollable divs in Firefox (Roan Kattouw)
+
+### Styles
+* MediaWiki theme: Remove support for frameless primary buttons (Bartosz 
Dziewoński)
+
+### Code
+* Use at-ease instead of PHP's @ (Kunal Mehta)
+* Use composer's autoloader in exec:phpGenerateJSPHPForKarma (Kunal Mehta)
+* build: Don't lint demos/{dist,node_modules,vendor} (Kunal Mehta)
+* build: Build demos as part of `grunt build` too (Kunal Mehta)
+* build: Build demos as part of `grunt quick-build` (Kunal Mehta)
+* build: Only build test files (`build-tests` task) when going to run tests 
(Bartosz Dziewoński)
+* demos: Make self-contained in demos/ directory (Kunal Mehta)
+* tests: Provide better output when running infusion test under Karma (Bartosz 
Dziewoński)
+
 ## v0.11.7 / 2015-07-01
+### Features
 * Element.php: Strip all namespaces from infused PHP widgets (Kunal Mehta)
 * OptionWidget: Explicitly set aria-selected to 'false' on init (Bartosz 
Dziewoński)
 
+### Styles
 * MediaWiki theme: Add support for frameless primary buttons (Ed Sanders)
 * MediaWiki theme: Align and center the advanced icon (Roan Kattouw)
 * MediaWiki, Apex themes: Fix styling for frameless process dialog actions (Ed 
Sanders)
 
+### Code
 * Element.php: Add test case to verify class name in infused widgets (Kunal 
Mehta)
 * Element.php: Only variables may be passed by reference (Kunal Mehta)
 * Theme.php: Actually make abstract in PHP (Kunal Mehta)
@@ -15,79 +38,89 @@
 * documentation: Use bold in comments instead of h4 (Ed Sanders)
 
 ## v0.11.6 / 2015-06-23
+### Features
 * NumberInputWidget: Don't use `Math.sign()` (Brad Jorsch)
 * SelectWidget: Fix invalid escape sequence '`\s`' (Roan Kattouw)
 
+### Styles
 * DropdownWidget: Add white background in MediaWiki theme (Prateek Saxena)
 * SelectFileWidget: Add white background in MediaWiki theme (Prateek Saxena)
 * MediaWiki theme: Add constructive variants for star and unStar icons (Roan 
Kattouw)
 * MediaWiki theme: Add invert variant to all icons (Roan Kattouw)
 * MediaWiki theme: Add progressive variant to ongoingConversation icon 
(Stephane Bisson)
 
+### Code
 * Use `.parent` instead of `.super` (Stephane Bisson)
 * build: Updating development dependencies (Kunal Mehta)
 
 ## v0.11.5 / 2015-06-16
+### Features
 * ButtonInputWidget: Render frameless button correctly (Bartosz Dziewoński)
 * ComboBoxWidget: Add a getter method for text inputs (Mr. Stradivarius)
 * FieldsetLayout: Make rule for disabled label color more precise (Bartosz 
Dziewoński)
 * MenuSelectWidget: Explain what the widget config option is for (Roan Kattouw)
 * RadioSelectInputWidget: Unbreak form submission in JS version (Bartosz 
Dziewoński)
 
+### Styles
 * MediaWiki theme: Add destructive variant to check icon (Matthew Flaschen)
 * MediaWiki, Apex themes: Add ongoingConversation icon (Matthew Flaschen)
 
+### Code
 * build: Configure jsonlint (Kunal Mehta)
 
 ## v0.11.4 / 2015-06-09
+### Deprecations
 * [DEPRECATING CHANGE] Introduce oo.ui.mixin namespace for mixins, and put 
them src/mixins (C. Scott Ananian)
 
+### Features
 * ActionFieldLayout: Add PHP version (Bartosz Dziewoński)
-* ActionFieldLayout: Dead code removal and cleanup (Bartosz Dziewoński)
-* BarToolGroup: Add description and example (Kirsten Menger-Anderson)
-* ButtonInputWidget and TextInputWidget: Document and enforce allowed types 
(Bartosz Dziewoński)
 * ButtonWidget: Fix not having tabindex updated when enabled/disabled (Brad 
Jorsch)
 * ClippableElement: Fix behavior of clippables in nested scrollables (Bartosz 
Dziewoński)
 * ClippableElement: Fix behavior of long clippables (Bartosz Dziewoński)
 * Dialog: Label in aria terms (Prateek Saxena)
-* DropdownInputWidget: Tweak documentation (Bartosz Dziewoński)
 * DropdownWidget: Adjust height to other widgets (Bartosz Dziewoński)
 * DropdownWidget: Blank widget when no item is selected (Brad Jorsch)
 * Element#reconsiderScrollbars: Preserve scroll position (Bartosz Dziewoński)
 * GroupElement: pass correct event name to disconnect() from aggregate() (Roan 
Kattouw)
-* InputWidget#getInputElement: Mark as `@protected`, not `@private` (Bartosz 
Dziewoński)
-* ListToolGroup: Add description and example (Kirsten Menger-Anderson)
-* MenuToolGroup: Add description, example and mark private method (Kirsten 
Menger-Anderson)
-* MessageDialog: Remove unintentional action button margin (Bartosz Dziewoński)
 * NumberInputWidget: Create, for numeric input (Brad Jorsch)
 * NumberInputWidget: Use keydown, not keypress (Brad Jorsch)
-* PendingElement: Add description (Kirsten Menger-Anderson)
-* PopupTool: Add description and example (Kirsten Menger-Anderson)
-* PopupToolGroup: Add description and mark protected methods (Kirsten 
Menger-Anderson)
 * ProcessDialog: Don't center the title label if there's not enough space 
(Bartosz Dziewoński)
 * RadioOptionWidget: Control focus more strictly (Bartosz Dziewoński)
 * RadioSelectInputWidget: Create (Bartosz Dziewoński)
 * SelectFileWidget: Create (Brad Jorsch)
 * SelectWidget: Listen to keypresses and jump to matching items (Brad Jorsch)
 * TextInputWidget: Adjust height to other widgets (Bartosz Dziewoński)
-* Tool: Add description (Kirsten Menger-Anderson)
-* ToolFactory: Add description (Kirsten Menger-Anderson)
-* ToolGroup: Add description and mark protected methods (Kirsten 
Menger-Anderson)
-* ToolGroupFactory: Add description (Kirsten Menger-Anderson)
-* ToolGroupTool: Add description and example (Kirsten Menger-Anderson)
-* Toolbar: Add description (Kirsten Menger-Anderson)
 * Widget: Add `#supportsSimpleLabel` static property to control <label> usage 
(Bartosz Dziewoński)
 * Window: Clear margins for actions in horizontal/vertical groups (Ed Sanders)
-* `OOUI\Element::mixins`: Improve doc comment (Kunal Mehta)
-* `OOUI\Tag`: Add basic phpunit tests (Kunal Mehta)
 * `OOUI\Tag`: Avoid 'Potentially unsafe "href" attribute value' exceptions for 
relative URLs (Bartosz Dziewoński)
 
+### Styles
+* MessageDialog: Remove unintentional action button margin (Bartosz Dziewoński)
 * styles: Change gradient mixin syntax to W3C standards' syntax (Volker E)
 * styles: Remove obsolete "-ms-linear-gradient" declaration (Volker E)
 * Apex theme: Use matching 'lock' and 'unLock' icons (Bartosz Dziewoński)
 * MediaWiki and Apex themes: Force background color of <select> to white (Ed 
Sanders)
 * MediaWiki and Apex themes: Re-crush SVG files (James D. Forrester)
 
+### Code
+* ActionFieldLayout: Dead code removal and cleanup (Bartosz Dziewoński)
+* BarToolGroup: Add description and example (Kirsten Menger-Anderson)
+* ButtonInputWidget and TextInputWidget: Document and enforce allowed types 
(Bartosz Dziewoński)
+* DropdownInputWidget: Tweak documentation (Bartosz Dziewoński)
+* InputWidget#getInputElement: Mark as `@protected`, not `@private` (Bartosz 
Dziewoński)
+* ListToolGroup: Add description and example (Kirsten Menger-Anderson)
+* MenuToolGroup: Add description, example and mark private method (Kirsten 
Menger-Anderson)
+* PendingElement: Add description (Kirsten Menger-Anderson)
+* PopupTool: Add description and example (Kirsten Menger-Anderson)
+* PopupToolGroup: Add description and mark protected methods (Kirsten 
Menger-Anderson)
+* Tool: Add description (Kirsten Menger-Anderson)
+* ToolFactory: Add description (Kirsten Menger-Anderson)
+* ToolGroup: Add description and mark protected methods (Kirsten 
Menger-Anderson)
+* ToolGroupFactory: Add description (Kirsten Menger-Anderson)
+* ToolGroupTool: Add description and example (Kirsten Menger-Anderson)
+* Toolbar: Add description (Kirsten Menger-Anderson)
+* `OOUI\Element::mixins`: Improve doc comment (Kunal Mehta)
+* `OOUI\Tag`: Add basic phpunit tests (Kunal Mehta)
 * build: Update MediaWiki codesniffer to 0.2.0 (Kunal Mehta)
 * build: Updating development dependencies (James D. Forrester)
 * demo: Add 'layout' variable to the consoles (Bartosz Dziewoński)
@@ -97,10 +130,13 @@
 * test: Use -p option to phpcs instead of -v (Kunal Mehta)
 
 ## v0.11.3 / 2015-05-12
+### Features
 * BarToolGroup: Don't use "pointer" cursor for disabled tools in enabled 
toolgroups (Bartosz Dziewoński)
 * Tool: Support icon+label in bar tool groups (Bartosz Dziewoński)
 * ToolGroupTool: Correct opacity of disabled nested tool group handle (Bartosz 
Dziewoński)
 * ToolGroupTool: Synchronize inner ToolGroup disabledness state (Bartosz 
Dziewoński)
+
+### Styles
 * MediaWiki theme: Add a powerful default text color for tools (Trevor Parscal)
 * MediaWiki theme: Adjust quotes icon to match other icons (nirzar)
 * MediaWiki theme: Give names to some more toolbar colours (Bartosz Dziewoński)
@@ -111,33 +147,36 @@
 * MediaWiki theme: Update button specification (nirzar)
 
 ## v0.11.2 / 2015-05-11
+### Features
 * Don't select lookup items on initialize (Ed Sanders)
 * ListToolGroup, MenuToolGroup: Set accelTooltips = false (Bartosz Dziewoński)
 * PopupWidget: Add setAlignment (Moriel Schottlender)
-* SelectWidget: Mark as @abstract, which it is (Bartosz Dziewoński)
 * Simplify default action prevention in buttons and forms (Bartosz Dziewoński)
-* TabOptionWidget: Fix disabled styles to not react to hover/select (Ed 
Sanders)
 * TextInputWidget: Allow override of #setValidityFlag (Ed Sanders)
 * TextInputWidget: Use aria-required along with the required attribute 
(Prateek Saxena)
+
+### Styles
+* TabOptionWidget: Fix disabled styles to not react to hover/select (Ed 
Sanders)
 * Toolbar: Fix shadow styling (Bartosz Dziewoński)
-* Toolbar: Move some tweaks from demo to actual implementation (Bartosz 
Dziewoński)
 * Toolbar: Remove some useless code from the example (Bartosz Dziewoński)
 * Toolbar: Rework example and add 'menu' tool group example (Bartosz 
Dziewoński)
 * MediaWiki theme: Change highlight color for selected menu option (nirzar)
 * MediaWiki theme: Polish the toolbar design (nirzar)
 * MediaWiki theme: Remove accidentally duplicated styles for SelectWidget 
(Bartosz Dziewoński)
 
+### Code
+* SelectWidget: Mark as @abstract, which it is (Bartosz Dziewoński)
+* Toolbar: Move some tweaks from demo to actual implementation (Bartosz 
Dziewoński)
+
 ## v0.11.1 / 2015-05-04
+### Features
 * Add IndexLayout (Trevor Parscal)
-* CardLayout: Fix typo (Kirsten Menger-Anderson)
-* LabelElement: Document that label config option can take an HtmlSnippet 
(Roan Kattouw)
-* PopupButtonWidget: Update align config in example (Kirsten Menger-Anderson)
-* Remove GridLayout remnants (Bartosz Dziewoński)
 * SelectWidget: Add #selectItemByData method (Moriel Schottlender)
-* TabOptionWidget: Change link to card layout (Kirsten Menger-Anderson)
 * TextInputWidget: Annotate input validation with aria-invalid (Prateek Saxena)
 * TextInputWidget: Don't set 'invalid' flag on first focus, even if invalid 
(Bartosz Dziewoński)
 * TextInputWidget: Support 'required' config option in PHP (Bartosz Dziewoński)
+
+### Styles
 * MediaWiki theme: Add 'destructive' variant to block icon (Moriel 
Schottlender)
 * MediaWiki theme: Better vertical alignment of 'search' icon (Ed Sanders)
 * MediaWiki theme: Tweak 'search' icon size (Ed Sanders)
@@ -146,19 +185,33 @@
 * MediaWiki theme: radio/checkbox: Use variable for transition time and easing 
function (Prateek Saxena)
 * MediaWiki, Apex themes: Switch icons: clear → cancel, closeInput → clear 
(Bartosz Dziewoński)
 * MediaWiki, Apex themes: Switch over 'magnifyingGlass' icon to be 'search' 
(James D. Forrester)
+
+### Code
+* CardLayout: Fix typo (Kirsten Menger-Anderson)
+* LabelElement: Document that label config option can take an HtmlSnippet 
(Roan Kattouw)
+* PopupButtonWidget: Update align config in example (Kirsten Menger-Anderson)
+* Remove GridLayout remnants (Bartosz Dziewoński)
+* TabOptionWidget: Change link to card layout (Kirsten Menger-Anderson)
 * build: Add clean:doc task (Bartosz Dziewoński)
 * build: Bump grunt-jscs to latest version (James D. Forrester)
 * core: Add OO.ui.debounce() utility (Roan Kattouw)
 * demo: Add icons with variants to icons demo (Bartosz Dziewoński)
 
 ## v0.11.0 / 2015-04-29
+### Breaking changes
 * [BREAKING CHANGE] Do not set font-size: 0.8em anywhere in the library 
(Bartosz Dziewoński)
 
+### Deprecations
 * [DEPRECATING CHANGE] Create rtl-ready alignments in PopupWidget (Moriel 
Schottlender)
 
+### Features
 * MediaWiki theme: Adding variants to several icons (Moriel Schottlender)
 * TextInputWidget: Allow functions to be passed as 'validate' config option 
(Bartosz Dziewoński)
+
+### Styles
 * TextInputWidget: Styles for 'invalid' flag (Bartosz Dziewoński)
+
+### Code
 * Update OOjs to v1.1.7 (James D. Forrester)
 * Update jQuery from v1.11.1 to v1.11.3 (James D. Forrester)
 * build: Use jquery and oojs from npm instead of embedded lib (Timo Tijhof)
diff --git a/oojs/oojs-ui/README.md b/oojs/oojs-ui/README.md
index 8969947..8e5581b 100644
--- a/oojs/oojs-ui/README.md
+++ b/oojs/oojs-ui/README.md
@@ -23,6 +23,8 @@
 
 1. You can now copy the distribution files from the dist directory into your 
project.
 
+1. You can see a suite of demos in `/demos` by executing:<br/>`$ npm 
run-script demos`
+
 
 Versioning
 ----------
diff --git a/oojs/oojs-ui/bin/generate-JSPHP-for-karma.php 
b/oojs/oojs-ui/bin/generate-JSPHP-for-karma.php
index 1cf55de..2cee51e 100644
--- a/oojs/oojs-ui/bin/generate-JSPHP-for-karma.php
+++ b/oojs/oojs-ui/bin/generate-JSPHP-for-karma.php
@@ -1,18 +1,8 @@
 <?php
 
-// Quick and dirty autoloader to make it possible to run without Composer.
-spl_autoload_register( function ( $class ) {
-       $class = preg_replace( '/^OOUI\\\\/', '', $class );
-       foreach ( array( 'mixins', 'layouts', 'themes', 'widgets', '.' ) as 
$dir ) {
-               $path = "../php/$dir/$class.php";
-               if ( file_exists( $path ) ) {
-                       require_once $path;
-                       return;
-               }
-       }
-} );
+require_once __DIR__ . '/../vendor/autoload.php';
 
-$testSuiteJSON = file_get_contents( 'JSPHP-suite.json' );
+$testSuiteJSON = file_get_contents( __DIR__ . '/../tests/JSPHP-suite.json' );
 $testSuite = json_decode( $testSuiteJSON, true );
 $testSuiteOutput = array();
 
@@ -51,4 +41,4 @@
 
 echo "var testSuiteConfigs = $testSuiteJSON;\n\n";
 echo "var testSuitePHPOutput = $testSuiteOutputJSON;\n\n";
-echo file_get_contents( 'JSPHP.test.karma.js' );
+echo file_get_contents( __DIR__ . '/../tests/JSPHP.test.karma.js' );
diff --git a/oojs/oojs-ui/build/tasks/typos.js 
b/oojs/oojs-ui/build/tasks/typos.js
index 6c0bb4e..df14547 100644
--- a/oojs/oojs-ui/build/tasks/typos.js
+++ b/oojs/oojs-ui/build/tasks/typos.js
@@ -33,13 +33,13 @@
 
                if ( typosData.caseSensitive.length ) {
                        typosCSRegExp = new RegExp(
-                               '(' + typosData.caseSensitive.map( patternMap 
).join( '|' )  + ')', 'g'
+                               '(' + typosData.caseSensitive.map( patternMap 
).join( '|' ) + ')', 'g'
                        );
                }
 
                if ( typosData.caseInsensitive.length ) {
                        typosCIRegExp = new RegExp(
-                               '(' + typosData.caseInsensitive.map( patternMap 
).join( '|' )  + ')', 'gi'
+                               '(' + typosData.caseInsensitive.map( patternMap 
).join( '|' ) + ')', 'gi'
                        );
                }
 
diff --git a/oojs/oojs-ui/composer.json b/oojs/oojs-ui/composer.json
index c53c6fa..486b0b9 100644
--- a/oojs/oojs-ui/composer.json
+++ b/oojs/oojs-ui/composer.json
@@ -4,6 +4,7 @@
        "homepage": "https://www.mediawiki.org/wiki/OOjs_UI";,
        "license": "MIT",
        "require": {
+               "mediawiki/at-ease": "1.0.0",
                "php": ">=5.3.3"
        },
        "require-dev": {
diff --git a/oojs/oojs-ui/demos/demo.js b/oojs/oojs-ui/demos/demo.js
index 9e67c99..018bcf2 100644
--- a/oojs/oojs-ui/demos/demo.js
+++ b/oojs/oojs-ui/demos/demo.js
@@ -337,9 +337,9 @@
        } );
 
        // Theme styles
-       urls.push( '../dist/oojs-ui' + fragments.slice( 1 ).join( '' ) + '.css' 
);
+       urls.push( 'dist/oojs-ui' + fragments.slice( 1 ).join( '' ) + '.css' );
        for ( i = 0, len = suffixes.length; i < len; i++ ) {
-               urls.push( '../dist/oojs-ui' + fragments[1] + suffixes[i] + 
fragments.slice( 2 ).join( '' ) + '.css' );
+               urls.push( 'dist/oojs-ui' + fragments[1] + suffixes[i] + 
fragments.slice( 2 ).join( '' ) + '.css' );
        }
 
        // Demo styles
diff --git a/oojs/oojs-ui/demos/index.html b/oojs/oojs-ui/demos/index.html
index 35ccc69..93c8a86 100644
--- a/oojs/oojs-ui/demos/index.html
+++ b/oojs/oojs-ui/demos/index.html
@@ -7,11 +7,11 @@
        <meta name="viewport" content="width=device-width, user-scalable=no">
 </head>
 <body>
-       <script src="../node_modules/jquery/dist/jquery.js"></script>
-       <script src="../node_modules/oojs/dist/oojs.jquery.js"></script>
-       <script src="../dist/oojs-ui.js"></script>
-       <script src="../dist/oojs-ui-apex.js"></script>
-       <script src="../dist/oojs-ui-mediawiki.js"></script>
+       <script src="node_modules/jquery/dist/jquery.js"></script>
+       <script src="node_modules/oojs/dist/oojs.jquery.js"></script>
+       <script src="dist/oojs-ui.js"></script>
+       <script src="dist/oojs-ui-apex.js"></script>
+       <script src="dist/oojs-ui-mediawiki.js"></script>
        <script src="demo.js"></script>
        <script src="pages/dialogs.js"></script>
        <script src="pages/icons.js"></script>
diff --git a/oojs/oojs-ui/demos/pages/toolbars.js 
b/oojs/oojs-ui/demos/pages/toolbars.js
index 4a58a33..9d257e0 100644
--- a/oojs/oojs-ui/demos/pages/toolbars.js
+++ b/oojs/oojs-ui/demos/pages/toolbars.js
@@ -217,8 +217,8 @@
                }
        ] );
 
-       saveButton = new OO.ui.ButtonWidget( { label: 'Save', framed: false, 
flags: [ 'progressive', 'primary' ] } );
-       deleteButton = new OO.ui.ButtonWidget( { label: 'Delete', framed: 
false, flags: [ 'destructive' ] } );
+       saveButton = new OO.ui.ButtonWidget( { label: 'Save', flags: [ 
'progressive', 'primary' ] } );
+       deleteButton = new OO.ui.ButtonWidget( { label: 'Delete', flags: [ 
'destructive' ] } );
        actionButton = new OO.ui.ButtonWidget( { label: 'Action' } );
        actionButtonDisabled = new OO.ui.ButtonWidget( { label: 'Disabled', 
disabled: true } );
        toolbars[ 1 ].$actions
diff --git a/oojs/oojs-ui/demos/pages/widgets.js 
b/oojs/oojs-ui/demos/pages/widgets.js
index d4880b5..74a0497 100644
--- a/oojs/oojs-ui/demos/pages/widgets.js
+++ b/oojs/oojs-ui/demos/pages/widgets.js
@@ -418,18 +418,6 @@
                                new OO.ui.FieldLayout(
                                        new OO.ui.ButtonWidget( {
                                                framed: false,
-                                               flags: [ 'progressive', 
'primary' ],
-                                               icon: 'check',
-                                               label: 'Primary'
-                                       } ),
-                                       {
-                                               label: 'ButtonWidget 
(frameless, primary, progressive)\u200E',
-                                               align: 'top'
-                                       }
-                               ),
-                               new OO.ui.FieldLayout(
-                                       new OO.ui.ButtonWidget( {
-                                               framed: false,
                                                flags: [ 'warning' ],
                                                icon: 'alert',
                                                label: 'Warning'
@@ -839,6 +827,17 @@
                                new OO.ui.FieldLayout(
                                        new OO.ui.TextInputWidget( {
                                                multiline: true,
+                                               rows: 15,
+                                               value: 'Multiline\nMultiline'
+                                       } ),
+                                       {
+                                               label: 'TextInputWidget 
(multiline, rows=15)\u200E',
+                                               align: 'top'
+                                       }
+                               ),
+                               new OO.ui.FieldLayout(
+                                       new OO.ui.TextInputWidget( {
+                                               multiline: true,
                                                autosize: true,
                                                value: 
'Autosize\nAutosize\nAutosize\nAutosize'
                                        } ),
@@ -849,6 +848,18 @@
                                ),
                                new OO.ui.FieldLayout(
                                        new OO.ui.TextInputWidget( {
+                                               multiline: true,
+                                               rows: 10,
+                                               autosize: true,
+                                               value: 
'Autosize\nAutosize\nAutosize\nAutosize'
+                                       } ),
+                                       {
+                                               label: 'TextInputWidget 
(autosize, rows=10)\u200E',
+                                               align: 'top'
+                                       }
+                               ),
+                               new OO.ui.FieldLayout(
+                                       new OO.ui.TextInputWidget( {
                                                icon: 'tag',
                                                indicator: 'alert',
                                                value: 'Text input with label',
diff --git a/oojs/oojs-ui/demos/widgets.php b/oojs/oojs-ui/demos/widgets.php
index f512827..64ade93 100644
--- a/oojs/oojs-ui/demos/widgets.php
+++ b/oojs/oojs-ui/demos/widgets.php
@@ -1,5 +1,5 @@
 <?php
-       $autoload = '../vendor/autoload.php';
+       $autoload = __DIR__ . '/vendor/autoload.php';
        if ( !file_exists( $autoload ) ) {
                echo '<h1>Did you forget to run <code>composer 
install</code>?</h1>';
                exit();
@@ -35,7 +35,7 @@
 <head>
        <meta charset="UTF-8">
        <title>OOjs UI Widget Demo</title>
-       <link rel="stylesheet" href="../dist/<?php echo $styleFileName; ?>">
+       <link rel="stylesheet" href="dist/<?php echo $styleFileName; ?>">
        <link rel="stylesheet" href="styles/demo<?php echo $directionSuffix; 
?>.css">
 </head>
 <body class="oo-ui-<?php echo $direction; ?>">
@@ -619,6 +619,17 @@
                                                        )
                                                ),
                                                new OOUI\FieldLayout(
+                                                       new 
OOUI\TextInputWidget( array(
+                                                               'multiline' => 
true,
+                                                               'rows' => 15,
+                                                               'value' => 
"Multiline\nMultiline"
+                                                       ) ),
+                                                       array(
+                                                               'label' => 
"TextInputWidget (multiline, rows=15)\xE2\x80\x8E",
+                                                               'align' => 'top'
+                                                       )
+                                               ),
+                                               new OOUI\FieldLayout(
                                                        new 
OOUI\DropdownInputWidget( array(
                                                                'options' => 
array(
                                                                        array(
@@ -916,10 +927,10 @@
        </div>
 
        <!-- Demonstrate JavaScript "infusion" of PHP widgets -->
-       <script src="../node_modules/jquery/dist/jquery.js"></script>
-       <script src="../node_modules/oojs/dist/oojs.jquery.js"></script>
-       <script src="../dist/oojs-ui.js"></script>
-       <script src="../dist/oojs-ui-<?php echo $theme; ?>.js"></script>
-       <script src="./infusion.js"></script>
+       <script src="node_modules/jquery/dist/jquery.js"></script>
+       <script src="node_modules/oojs/dist/oojs.jquery.js"></script>
+       <script src="dist/oojs-ui.js"></script>
+       <script src="dist/oojs-ui-<?php echo $theme; ?>.js"></script>
+       <script src="infusion.js"></script>
 </body>
 </html>
diff --git a/oojs/oojs-ui/i18n/fa.json b/oojs/oojs-ui/i18n/fa.json
index 7cfcfa2..62198f4 100644
--- a/oojs/oojs-ui/i18n/fa.json
+++ b/oojs/oojs-ui/i18n/fa.json
@@ -11,7 +11,8 @@
                        "Taha",
                        "درفش کاویانی",
                        "Armin1392",
-                       "Alirezaaa"
+                       "Alirezaaa",
+                       "Leyth"
                ]
        },
        "ooui-outline-control-move-down": "انتقال مورد به پایین",
@@ -25,5 +26,7 @@
        "ooui-dialog-process-error": "مشکلی وجود دارد",
        "ooui-dialog-process-dismiss": "نپذیرفتن",
        "ooui-dialog-process-retry": "دوباره امتحان کن",
-       "ooui-dialog-process-continue": "ادامه"
+       "ooui-dialog-process-continue": "ادامه",
+       "ooui-selectfile-not-supported": "انتخاب پرونده پشتیبانی نمی‌شود",
+       "ooui-selectfile-placeholder": "هیچ پرونده‌ای انتخاب نشده‌است"
 }
diff --git a/oojs/oojs-ui/i18n/lt.json b/oojs/oojs-ui/i18n/lt.json
index ecd06a8..4334efb 100644
--- a/oojs/oojs-ui/i18n/lt.json
+++ b/oojs/oojs-ui/i18n/lt.json
@@ -3,8 +3,22 @@
                "authors": [
                        "Audriusa",
                        "Eitvys200",
-                       "Mantak111"
+                       "Mantak111",
+                       "Albertas"
                ]
        },
-       "ooui-outline-control-remove": "Šalinti elementus"
+       "ooui-outline-control-move-down": "Perkelti elementą žemyn",
+       "ooui-outline-control-move-up": "Perkelti elementą aukštyn",
+       "ooui-outline-control-remove": "Šalinti elementus",
+       "ooui-toolbar-more": "Daugiau",
+       "ooui-toolgroup-expand": "Daugiau",
+       "ooui-toolgroup-collapse": "Mažiau",
+       "ooui-dialog-message-accept": "Gerai",
+       "ooui-dialog-message-reject": "Atšaukti",
+       "ooui-dialog-process-error": "Kažkas nutiko ne taip",
+       "ooui-dialog-process-dismiss": "Paslėpti",
+       "ooui-dialog-process-retry": "Bandykite dar kartą",
+       "ooui-dialog-process-continue": "Tęsti",
+       "ooui-selectfile-not-supported": "Failų pasirinkimas nepalaikomas",
+       "ooui-selectfile-placeholder": "Nėra pasirinktų failų"
 }
diff --git a/oojs/oojs-ui/i18n/pa.json b/oojs/oojs-ui/i18n/pa.json
index 8c7a1e7..0661b3f 100644
--- a/oojs/oojs-ui/i18n/pa.json
+++ b/oojs/oojs-ui/i18n/pa.json
@@ -12,7 +12,7 @@
        "ooui-outline-control-move-up": "ਉੱਤੇ ਲੈਕੇ ਜਾਓ",
        "ooui-toolbar-more": "ਹੋਰ",
        "ooui-toolgroup-expand": "ਹੋਰ",
-       "ooui-toolgroup-collapse": "ਥੋੜੇ",
+       "ooui-toolgroup-collapse": "ਥੋੜ੍ਹੇ",
        "ooui-dialog-message-accept": "ਠੀਕ ਹੈ",
        "ooui-dialog-message-reject": "ਰੱਦ ਕਰੋ",
        "ooui-dialog-process-error": "ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ",
diff --git a/oojs/oojs-ui/i18n/ps.json b/oojs/oojs-ui/i18n/ps.json
index ebffe53..c371bbc 100644
--- a/oojs/oojs-ui/i18n/ps.json
+++ b/oojs/oojs-ui/i18n/ps.json
@@ -14,5 +14,8 @@
        "ooui-dialog-message-reject": "ناگارل",
        "ooui-dialog-process-error": "يوه ستونزه رامنځ ته شوه",
        "ooui-dialog-process-dismiss": "تړل",
-       "ooui-dialog-process-retry": "بيا هڅه"
+       "ooui-dialog-process-retry": "بيا هڅه",
+       "ooui-dialog-process-continue": "پرله پورې",
+       "ooui-selectfile-not-supported": "د دوتنې د ټاکنې ملاتړ نه دی شوی",
+       "ooui-selectfile-placeholder": "کومه دوتنه نه ده ټاکل شوې"
 }
diff --git a/oojs/oojs-ui/i18n/ru.json b/oojs/oojs-ui/i18n/ru.json
index 129dd6a..f5674b3 100644
--- a/oojs/oojs-ui/i18n/ru.json
+++ b/oojs/oojs-ui/i18n/ru.json
@@ -30,5 +30,6 @@
        "ooui-dialog-process-error": "Что-то пошло не так",
        "ooui-dialog-process-dismiss": "Закрыть",
        "ooui-dialog-process-retry": "Попробовать ещё раз",
-       "ooui-dialog-process-continue": "Продолжить"
+       "ooui-dialog-process-continue": "Продолжить",
+       "ooui-selectfile-not-supported": "Выбор файла не поддерживается"
 }
diff --git a/oojs/oojs-ui/i18n/yi.json b/oojs/oojs-ui/i18n/yi.json
index a850fce..f206a72 100644
--- a/oojs/oojs-ui/i18n/yi.json
+++ b/oojs/oojs-ui/i18n/yi.json
@@ -10,9 +10,14 @@
        "ooui-outline-control-move-up": "רוקן עלעמענט ארויף",
        "ooui-outline-control-remove": "אַראָפנעמען איינס",
        "ooui-toolbar-more": "נאך",
+       "ooui-toolgroup-expand": "נאך",
+       "ooui-toolgroup-collapse": "ווייניגער",
        "ooui-dialog-message-accept": "יאָ",
        "ooui-dialog-message-reject": "אַנולירן",
        "ooui-dialog-process-error": "עפעס איז דורכגעפאלן",
        "ooui-dialog-process-dismiss": "צומאַכן",
-       "ooui-dialog-process-retry": "פרובירט נאכאמאל"
+       "ooui-dialog-process-retry": "פרובירט נאכאמאל",
+       "ooui-dialog-process-continue": "פֿארזעצן",
+       "ooui-selectfile-not-supported": "טעקע אויסווייל נישט געשטיצט",
+       "ooui-selectfile-placeholder": "קיין טעקע נישט אויסגעוויילט"
 }
diff --git a/oojs/oojs-ui/i18n/yue.json b/oojs/oojs-ui/i18n/yue.json
index d328e6e..7d4e710 100644
--- a/oojs/oojs-ui/i18n/yue.json
+++ b/oojs/oojs-ui/i18n/yue.json
@@ -2,13 +2,14 @@
        "@metadata": {
                "authors": [
                        "Deryck Chan",
-                       "William915"
+                       "William915",
+                       "Shinjiman"
                ]
        },
        "ooui-outline-control-move-down": "向下搬",
        "ooui-outline-control-move-up": "向上搬",
        "ooui-outline-control-remove": "拎走",
-       "ooui-toolbar-more": "仲有...",
+       "ooui-toolbar-more": "仲有",
        "ooui-toolgroup-expand": "更多",
        "ooui-dialog-message-accept": "好",
        "ooui-dialog-message-reject": "取消",
diff --git a/oojs/oojs-ui/package.json b/oojs/oojs-ui/package.json
index 4ea4c75..f0dd113 100644
--- a/oojs/oojs-ui/package.json
+++ b/oojs/oojs-ui/package.json
@@ -1,6 +1,6 @@
 {
   "name": "oojs-ui",
-  "version": "0.11.7",
+  "version": "0.11.8",
   "description": "User interface classes built on the OOjs framework.",
   "keywords": [
     "oojs-plugin",
@@ -22,7 +22,8 @@
     "predoc": "grunt build",
     "doc": "jsduck",
     "postdoc": "grunt copy:jsduck",
-    "prepublish": "grunt build"
+    "prepublish": "grunt build",
+    "demos": "grunt demos"
   },
   "dependencies": {
     "jquery": "1.11.3",
diff --git a/oojs/oojs-ui/php/Tag.php b/oojs/oojs-ui/php/Tag.php
index 3d3ad6f..173f29e 100644
--- a/oojs/oojs-ui/php/Tag.php
+++ b/oojs/oojs-ui/php/Tag.php
@@ -307,9 +307,9 @@
                                        $scheme = '(protocol-relative)';
                                } else {
                                        // Must suppress warnings when the 
value is not a valid URL. parse_url() returns false then.
-                                       // @codingStandardsIgnoreStart
-                                       $scheme = @parse_url( $value, 
PHP_URL_SCHEME );
-                                       // @codingStandardsIgnoreEnd
+                                       \MediaWiki\suppressWarnings();
+                                       $scheme = parse_url( $value, 
PHP_URL_SCHEME );
+                                       \MediaWiki\restoreWarnings();
                                        if ( $scheme === null || ( !$scheme && 
substr( $value, 0, 1 ) === '/' ) ) {
                                                $scheme = '(relative)';
                                        }
diff --git a/oojs/oojs-ui/php/widgets/DropdownInputWidget.php 
b/oojs/oojs-ui/php/widgets/DropdownInputWidget.php
index ae541a6..1e099a2 100644
--- a/oojs/oojs-ui/php/widgets/DropdownInputWidget.php
+++ b/oojs/oojs-ui/php/widgets/DropdownInputWidget.php
@@ -60,11 +60,12 @@
                // Rebuild the dropdown menu
                $this->input->clearContent();
                foreach ( $options as $opt ) {
+                       $optValue = $this->cleanUpValue( $opt['data'] );
                        $option = new Tag( 'option' );
-                       $option->setAttributes( array( 'value' => $opt['data'] 
) );
-                       $option->appendContent( isset( $opt['label'] ) ? 
$opt['label'] : $opt['data'] );
+                       $option->setAttributes( array( 'value' => $optValue ) );
+                       $option->appendContent( isset( $opt['label'] ) ? 
$opt['label'] : $optValue );
 
-                       if ( $value === $opt['data'] ) {
+                       if ( $value === $optValue ) {
                                $isValueAvailable = true;
                        }
 
diff --git a/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php 
b/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php
index 7d9f2c8..923578d 100644
--- a/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php
+++ b/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php
@@ -71,19 +71,20 @@
                // Need a unique name, otherwise more than one radio will be 
selectable
                $name = $this->name ?: 'oo-ui-radioSelectInputWidget' . 
mt_rand();
                foreach ( $options as $opt ) {
+                       $optValue = $this->cleanUpValue( $opt['data'] );
                        $field = new FieldLayout(
                                new RadioInputWidget( array(
                                        'name' => $name,
-                                       'value' => $opt['data'],
+                                       'value' => $optValue,
                                        'disabled' => $this->isDisabled(),
                                ) ),
                                array(
-                                       'label' => isset( $opt['label'] ) ? 
$opt['label'] : $opt['data'],
+                                       'label' => isset( $opt['label'] ) ? 
$opt['label'] : $optValue,
                                        'align' => 'inline',
                                )
                        );
 
-                       if ( $value === $opt['data'] ) {
+                       if ( $value === $optValue ) {
                                $isValueAvailable = true;
                        }
 
diff --git a/oojs/oojs-ui/php/widgets/TextInputWidget.php 
b/oojs/oojs-ui/php/widgets/TextInputWidget.php
index e930790..7305521 100644
--- a/oojs/oojs-ui/php/widgets/TextInputWidget.php
+++ b/oojs/oojs-ui/php/widgets/TextInputWidget.php
@@ -33,7 +33,10 @@
         * @param boolean $config['readOnly'] Prevent changes (default: false)
         * @param number $config['maxLength'] Maximum allowed number of 
characters to input
         * @param boolean $config['multiline'] Allow multiple lines of text 
(default: false)
+        * @param int $config['rows'] If multiline, number of visible lines in 
textarea
         * @param boolean $config['required'] Mark the field as required 
(default: false)
+        * @param boolean $config['autocomplete'] If the field should support 
autocomplete
+        *   or not (default: true)
         */
        public function __construct( array $config = array() ) {
                // Config initialization
@@ -42,6 +45,7 @@
                        'readOnly' => false,
                        'autofocus' => false,
                        'required' => false,
+                       'autocomplete' => true,
                ), $config );
 
                // Parent constructor
@@ -70,6 +74,12 @@
                }
                if ( $config['required'] ) {
                        $this->input->setAttributes( array( 'required' => 
'required', 'aria-required' => 'true' ) );
+               }
+               if ( !$config['autocomplete'] ) {
+                       $this->input->setAttributes( array( 'autocomplete' => 
'off' ) );
+               }
+               if ( $this->multiline && isset( $config['rows'] ) ) {
+                       $this->input->setAttributes( array( 'rows' => 
$config['rows'] ) );
                }
        }
 
@@ -124,6 +134,10 @@
        public function getConfig( &$config ) {
                if ( $this->isMultiline() ) {
                        $config['multiline'] = true;
+                       $rows = $this->input->getAttribute( 'rows' );
+                       if ( $rows !== null ) {
+                               $config['rows'] = $rows;
+                       }
                } else {
                        $type = $this->input->getAttribute( 'type' );
                        if ( $type !== 'text' ) {
@@ -150,6 +164,10 @@
                if ( ( $required !== null ) || ( $ariarequired !== null ) ) {
                        $config['required'] = true;
                }
+               $autocomplete = $this->input->getAttribute( 'autocomplete' );
+               if ( $autocomplete !== null ) {
+                       $config['autocomplete'] = false;
+               }
                return parent::getConfig( $config );
        }
 }
diff --git a/oojs/oojs-ui/src/Element.js b/oojs/oojs-ui/src/Element.js
index 014b75a..9f0d555 100644
--- a/oojs/oojs-ui/src/Element.js
+++ b/oojs/oojs-ui/src/Element.js
@@ -460,11 +460,12 @@
  */
 OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension 
) {
        var i, val,
-               props = [ 'overflow' ],
+               // props = [ 'overflow' ] doesn't work due to 
https://bugzilla.mozilla.org/show_bug.cgi?id=889091
+               props = [ 'overflow-x', 'overflow-y' ],
                $parent = $( el ).parent();
 
        if ( dimension === 'x' || dimension === 'y' ) {
-               props.push( 'overflow-' + dimension );
+               props = [ 'overflow-' + dimension ];
        }
 
        while ( $parent.length ) {
diff --git a/oojs/oojs-ui/src/styles/common.less 
b/oojs/oojs-ui/src/styles/common.less
index 16c2df0..83324af 100644
--- a/oojs/oojs-ui/src/styles/common.less
+++ b/oojs/oojs-ui/src/styles/common.less
@@ -63,8 +63,8 @@
 
 .oo-ui-box-sizing( @type: border-box ) {
        -webkit-box-sizing: @type;
-       -moz-box-sizing:    @type;
-       box-sizing:         @type;
+       -moz-box-sizing: @type;
+       box-sizing: @type;
 }
 
 .oo-ui-vertical-gradient( @start: #EEE, @stop: #FFF ) {
diff --git a/oojs/oojs-ui/src/themes/apex/icons-editing-core.json 
b/oojs/oojs-ui/src/themes/apex/icons-editing-core.json
index 95e8358..ceb3199 100644
--- a/oojs/oojs-ui/src/themes/apex/icons-editing-core.json
+++ b/oojs/oojs-ui/src/themes/apex/icons-editing-core.json
@@ -17,7 +17,7 @@
                "link": { "file": "images/icons/link.svg" },
                "linkExternal": { "file": {
                        "ltr": "images/icons/external-link-ltr.svg",
-                       "rtl":  "images/icons/external-link-rtl.svg"
+                       "rtl": "images/icons/external-link-rtl.svg"
                } },
                "linkSecure": { "file": "images/icons/secure-link.svg" }
        }
diff --git a/oojs/oojs-ui/src/themes/apex/windows.less 
b/oojs/oojs-ui/src/themes/apex/windows.less
index de5437f..3f1a906 100644
--- a/oojs/oojs-ui/src/themes/apex/windows.less
+++ b/oojs/oojs-ui/src/themes/apex/windows.less
@@ -304,7 +304,7 @@
                        /* Fade window overlay */
                        opacity: 1;
 
-                       > .oo-ui-window-frame  {
+                       > .oo-ui-window-frame {
                                /* Fade frame */
                                opacity: 1;
                                .oo-ui-transform(scale(1));
diff --git a/oojs/oojs-ui/src/themes/mediawiki/elements.less 
b/oojs/oojs-ui/src/themes/mediawiki/elements.less
index fa1b9d7..edf944b 100644
--- a/oojs/oojs-ui/src/themes/mediawiki/elements.less
+++ b/oojs/oojs-ui/src/themes/mediawiki/elements.less
@@ -29,7 +29,7 @@
                height: @icon-size;
        }
 
-       &-frameless:not( .oo-ui-flaggedElement-primary ) {
+       &-frameless {
                > .oo-ui-buttonElement-button {
                        &:focus {
                                box-shadow: inset 0 0 0 1px rgba(0,0,0,0.2), 0 
0 0 1px rgba(0,0,0,0.2);
@@ -98,25 +98,6 @@
                        margin: 0.1em 0;
                        padding: 0.2em 0.8em;
                        border-radius: @border-radius;
-               }
-
-               // Support <input/> from ButtonInputWidget
-               > input.oo-ui-buttonElement-button,
-               &.oo-ui-labelElement > .oo-ui-buttonElement-button > 
.oo-ui-labelElement-label {
-                       line-height: @icon-size;
-               }
-
-               &.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-                       border: 1px solid @disabled-background;
-               }
-
-               &.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-                       border: @neutral-button-border;
-               }
-       }
-
-       &-framed, &-frameless.oo-ui-flaggedElement-primary {
-               > .oo-ui-buttonElement-button {
 
                        &:hover,
                        &:focus {
@@ -130,6 +111,11 @@
                        );
                }
 
+               // Support <input/> from ButtonInputWidget
+               > input.oo-ui-buttonElement-button,
+               &.oo-ui-labelElement > .oo-ui-buttonElement-button > 
.oo-ui-labelElement-label {
+                       line-height: @icon-size;
+               }
 
                &.oo-ui-iconElement {
                        > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon 
{
@@ -159,12 +145,14 @@
                &.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
                        color: @disabled-framed-text;
                        background: @disabled-background;
+                       border: 1px solid @disabled-background;
                }
 
                &.oo-ui-widget-enabled {
                        > .oo-ui-buttonElement-button {
                                color: @text;
                                background-color: @background;
+                               border: @neutral-button-border;
 
                                &:hover {
                                        background-color: 
darken(@background,8%);
diff --git a/oojs/oojs-ui/src/themes/mediawiki/tools.less 
b/oojs/oojs-ui/src/themes/mediawiki/tools.less
index 9112c1a..060d1a6 100644
--- a/oojs/oojs-ui/src/themes/mediawiki/tools.less
+++ b/oojs/oojs-ui/src/themes/mediawiki/tools.less
@@ -24,19 +24,18 @@
        }
 
        &-actions {
-               > .oo-ui-buttonElement-framed,
-               > .oo-ui-buttonElement-framed:last-child {
-                       margin-top: 0.25em;
-                       margin-bottom: 0.25em;
-                       margin-right: 0.5em;
-               }
-
-               > .oo-ui-buttonElement-frameless.oo-ui-labelElement {
+               > .oo-ui-buttonElement.oo-ui-labelElement {
                        margin: 0;
+
                        > .oo-ui-buttonElement-button {
+                               border: 0;
+                               border-radius: 0;
+                               margin: 0;
                                padding: 1.0546875em 0.3125em;
+
                                > .oo-ui-labelElement-label {
                                        margin: 0 1em;
+                                       line-height: inherit;
                                }
                        }
                }
diff --git a/oojs/oojs-ui/src/widgets/DropdownInputWidget.js 
b/oojs/oojs-ui/src/widgets/DropdownInputWidget.js
index fc6ab4b..bf08b3b 100644
--- a/oojs/oojs-ui/src/widgets/DropdownInputWidget.js
+++ b/oojs/oojs-ui/src/widgets/DropdownInputWidget.js
@@ -78,6 +78,7 @@
  * @inheritdoc
  */
 OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) {
+       value = this.cleanUpValue( value );
        this.dropdownWidget.getMenu().selectItemByData( value );
        OO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value );
        return this;
@@ -99,15 +100,18 @@
  * @chainable
  */
 OO.ui.DropdownInputWidget.prototype.setOptions = function ( options ) {
-       var value = this.getValue();
+       var
+               value = this.getValue(),
+               widget = this;
 
        // Rebuild the dropdown menu
        this.dropdownWidget.getMenu()
                .clearItems()
                .addItems( options.map( function ( opt ) {
+                       var optValue = widget.cleanUpValue( opt.data );
                        return new OO.ui.MenuOptionWidget( {
-                               data: opt.data,
-                               label: opt.label !== undefined ? opt.label : 
opt.data
+                               data: optValue,
+                               label: opt.label !== undefined ? opt.label : 
optValue
                        } );
                } ) );
 
diff --git a/oojs/oojs-ui/src/widgets/RadioSelectInputWidget.js 
b/oojs/oojs-ui/src/widgets/RadioSelectInputWidget.js
index f0c3adb..64258e0 100644
--- a/oojs/oojs-ui/src/widgets/RadioSelectInputWidget.js
+++ b/oojs/oojs-ui/src/widgets/RadioSelectInputWidget.js
@@ -78,6 +78,7 @@
  * @inheritdoc
  */
 OO.ui.RadioSelectInputWidget.prototype.setValue = function ( value ) {
+       value = this.cleanUpValue( value );
        this.radioSelectWidget.selectItemByData( value );
        OO.ui.RadioSelectInputWidget.parent.prototype.setValue.call( this, 
value );
        return this;
@@ -99,15 +100,18 @@
  * @chainable
  */
 OO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) {
-       var value = this.getValue();
+       var
+               value = this.getValue(),
+               widget = this;
 
        // Rebuild the radioSelect menu
        this.radioSelectWidget
                .clearItems()
                .addItems( options.map( function ( opt ) {
+                       var optValue = widget.cleanUpValue( opt.data );
                        return new OO.ui.RadioOptionWidget( {
-                               data: opt.data,
-                               label: opt.label !== undefined ? opt.label : 
opt.data
+                               data: optValue,
+                               label: opt.label !== undefined ? opt.label : 
optValue
                        } );
                } ) );
 
diff --git a/oojs/oojs-ui/src/widgets/TextInputWidget.js 
b/oojs/oojs-ui/src/widgets/TextInputWidget.js
index 123a13b..8347371 100644
--- a/oojs/oojs-ui/src/widgets/TextInputWidget.js
+++ b/oojs/oojs-ui/src/widgets/TextInputWidget.js
@@ -34,12 +34,16 @@
  * @cfg {boolean} [readOnly=false] Prevent changes to the value of the text 
input.
  * @cfg {number} [maxLength] Maximum number of characters allowed in the input.
  * @cfg {boolean} [multiline=false] Allow multiple lines of text
+ * @cfg {number} [rows] If multiline, number of visible lines in textarea. If 
used with `autosize`,
+ *  specifies minimum number of rows to display.
  * @cfg {boolean} [autosize=false] Automatically resize the text input to fit 
its content.
  *  Use the #maxRows config to specify a maximum number of displayed rows.
- * @cfg {boolean} [maxRows=10] Maximum number of rows to display when 
#autosize is set to true.
+ * @cfg {boolean} [maxRows] Maximum number of rows to display when #autosize 
is set to true.
+ *  Defaults to the maximum of `10` and `2 * rows`, or `10` if `rows` isn't 
provided.
  * @cfg {string} [labelPosition='after'] The position of the inline label 
relative to that of
  *  the value or placeholder text: `'before'` or `'after'`
  * @cfg {boolean} [required=false] Mark the field as required
+ * @cfg {boolean} [autocomplete=true] Should the browser support autocomplete 
for this field
  * @cfg {RegExp|Function|string} [validate] Validation pattern: when string, a 
symbolic name of a
  *  pattern defined by the class: 'non-empty' (the value cannot be an empty 
string) or 'integer'
  *  (the value must contain only numbers); when RegExp, a regular expression 
that must match the
@@ -50,8 +54,7 @@
        // Configuration initialization
        config = $.extend( {
                type: 'text',
-               labelPosition: 'after',
-               maxRows: 10
+               labelPosition: 'after'
        }, config );
 
        // Parent constructor
@@ -67,7 +70,8 @@
        this.readOnly = false;
        this.multiline = !!config.multiline;
        this.autosize = !!config.autosize;
-       this.maxRows = config.maxRows;
+       this.minRows = config.rows !== undefined ? config.rows : '';
+       this.maxRows = config.maxRows || Math.max( 2 * ( this.minRows || 0 ), 
10 );
        this.validate = null;
 
        // Clone for resizing
@@ -112,6 +116,12 @@
        if ( config.required ) {
                this.$input.attr( 'required', 'required' );
                this.$input.attr( 'aria-required', 'true' );
+       }
+       if ( config.autocomplete === false ) {
+               this.$input.attr( 'autocomplete', 'off' );
+       }
+       if ( this.multiline && config.rows ) {
+               this.$input.attr( 'rows', config.rows );
        }
        if ( this.label || config.autosize ) {
                this.installParentChangeDetector();
@@ -323,7 +333,7 @@
        if ( this.multiline && this.autosize && this.$input.val() !== 
this.valCache ) {
                this.$clone
                        .val( this.$input.val() )
-                       .attr( 'rows', '' )
+                       .attr( 'rows', this.minRows )
                        // Set inline height property to 0 to measure scroll 
height
                        .css( 'height', 0 );
 
diff --git a/oojs/oojs-ui/tests/JSPHP.test.karma.js 
b/oojs/oojs-ui/tests/JSPHP.test.karma.js
index 1a1473c..5e181c0 100644
--- a/oojs/oojs-ui/tests/JSPHP.test.karma.js
+++ b/oojs/oojs-ui/tests/JSPHP.test.karma.js
@@ -40,7 +40,7 @@
                                infused = OO.ui.infuse( $fromPhp[ 0 ] );
                                infused.debouncedUpdateThemeClasses();
 
-                               assert.equalDomElement( instance.$element[ 0 ], 
infused.$element[ 0 ], testName + ' (infuse)' );
+                               assert.equalDomElement( instance.$element[ 0 ], 
infused.$element[ 0 ], testName + ' (infuse)', true );
                                instance.$element.add( infused.$element 
).detach();
                        }
                } );

-- 
To view, visit https://gerrit.wikimedia.org/r/223482
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I701c504acf0d527916f1925bbf49177cc9c0d883
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vendor
Gerrit-Branch: master
Gerrit-Owner: Jforrester <jforres...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to