diff options
Diffstat (limited to 'catapult/third_party/polymer/components/paper-input')
27 files changed, 3614 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/paper-input/.bower.json b/catapult/third_party/polymer/components/paper-input/.bower.json new file mode 100644 index 00000000..cfd146db --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/.bower.json @@ -0,0 +1,60 @@ +{ + "name": "paper-input", + "version": "1.1.24", + "description": "Material design text fields", + "authors": [ + "The Polymer Authors" + ], + "keywords": [ + "web-components", + "polymer", + "input" + ], + "main": [ + "paper-input.html", + "paper-textarea.html", + "paper-input-behavior.html", + "paper-input-container.html", + "paper-input-error.html", + "paper-input-addon-behavior.html", + "paper-input-char-counter.html" + ], + "private": true, + "repository": { + "type": "git", + "url": "git://github.com/PolymerElements/paper-input.git" + }, + "license": "http://polymer.github.io/LICENSE.txt", + "homepage": "https://github.com/PolymerElements/paper-input", + "ignore": [], + "dependencies": { + "polymer": "Polymer/polymer#^1.2.0", + "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0", + "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0", + "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0", + "iron-input": "PolymerElements/iron-input#^1.0.0", + "paper-styles": "PolymerElements/paper-styles#^1.1.4", + "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0" + }, + "devDependencies": { + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", + "iron-demo-helpers": "PolymerElements/iron-demo-helpers#^1.0.0", + "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0", + "iron-icon": "PolymerElements/iron-icon#^1.0.0", + "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0", + "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0", + "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0", + "test-fixture": "PolymerElements/test-fixture#^1.0.0", + "web-component-tester": "^4.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + }, + "_release": "1.1.24", + "_resolution": { + "type": "version", + "tag": "v1.1.24", + "commit": "881f532e82699f1eb93fd1170e0bb7ff4b3db0cd" + }, + "_source": "https://github.com/PolymerElements/paper-input.git", + "_target": "^1.0.0", + "_originalSource": "PolymerElements/paper-input" +}
\ No newline at end of file diff --git a/catapult/third_party/polymer/components/paper-input/.github/ISSUE_TEMPLATE.md b/catapult/third_party/polymer/components/paper-input/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..99b9301c --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,33 @@ +<!-- Instructions: https://github.com/PolymerElements/paper-input/CONTRIBUTING.md#filing-issues --> +### Description +<!-- Example: The `paper-foo` element causes the page to turn pink when clicked. --> + +### Expected outcome + +<!-- Example: The page stays the same color. --> + +### Actual outcome + +<!-- Example: The page turns pink. --> + +### Live Demo +<!-- Example: https://jsbin.com/cagaye/edit?html,output --> + +### Steps to reproduce + +<!-- Example +1. Put a `paper-foo` element in the page. +2. Open the page in a web browser. +3. Click the `paper-foo` element. +--> + +### Browsers Affected +<!-- Check all that apply --> +- [ ] Chrome +- [ ] Firefox +- [ ] Safari 9 +- [ ] Safari 8 +- [ ] Safari 7 +- [ ] Edge +- [ ] IE 11 +- [ ] IE 10 diff --git a/catapult/third_party/polymer/components/paper-input/.gitignore b/catapult/third_party/polymer/components/paper-input/.gitignore new file mode 100644 index 00000000..8d4ae253 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/.gitignore @@ -0,0 +1 @@ +bower_components diff --git a/catapult/third_party/polymer/components/paper-input/.travis.yml b/catapult/third_party/polymer/components/paper-input/.travis.yml new file mode 100644 index 00000000..b24d7f73 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/.travis.yml @@ -0,0 +1,24 @@ +language: node_js +sudo: required +before_script: + - npm install -g bower polylint web-component-tester + - bower install + - polylint +env: + global: + - secure: >- + Hg2KIEhKqOw0J8ZW2C3Pdgp5N4HD/f9jhdluH0tiYRCU4I/jf5grQuA3ohqsbqnJKV5l06gWVIDCdxBDwDEH0h8v9uUG5z/i2diiuLQc94SLQu8kWKkUPDOx+pUyXmfRKj6KnaRTotTLFrwlyuKDi9OfGjQbLZWTvmJUWoFwh4g= + - secure: >- + U6/Hp/V0ezT/yxeP2bv4S99LSLScKEaOfYwQUbe0+v5dPbN5XZaCUS6iSbNP2K8Mtb1UQUEyL8uN6Zn+khFlJ8/KJshppJ6HJi235CykahBhh9/Cv7EapgDUoss14ntE8EKpm6Ijo4LvVyPVmhgqKk9wP5ykDFtvhoKD4C3guVU= +node_js: '6' +addons: + firefox: latest + apt: + sources: + - google-chrome + packages: + - google-chrome-stable +script: + - xvfb-run wct + - 'if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct -s ''default''; fi' +dist: trusty diff --git a/catapult/third_party/polymer/components/paper-input/CONTRIBUTING.md b/catapult/third_party/polymer/components/paper-input/CONTRIBUTING.md new file mode 100644 index 00000000..093090d4 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/CONTRIBUTING.md @@ -0,0 +1,77 @@ +<!-- +This file is autogenerated based on +https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md + +If you edit that file, it will get updated everywhere else. +If you edit this file, your changes will get overridden :) + +You can however override the jsbin link with one that's customized to this +specific element: + +jsbin=https://jsbin.com/cagaye/edit?html,output +--> + +# Polymer Elements +## Guide for Contributors + +Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines: + +### Filing Issues + +**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions: + + 1. **Who will use the feature?** _“As someone filling out a form…”_ + 2. **When will they use the feature?** _“When I enter an invalid value…”_ + 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_ + +**If you are filing an issue to report a bug**, please provide: + + 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug: + + ```markdown + The `paper-foo` element causes the page to turn pink when clicked. + + ## Expected outcome + + The page stays the same color. + + ## Actual outcome + + The page turns pink. + + ## Steps to reproduce + + 1. Put a `paper-foo` element in the page. + 2. Open the page in a web browser. + 3. Click the `paper-foo` element. + ``` + + 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [https://jsbin.com/cagaye/edit?html,output](https://jsbin.com/cagaye/edit?html,output). + + 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers. + +### Submitting Pull Requests + +**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request. + +When submitting pull requests, please provide: + + 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues in the pull request description using the following syntax: + + ```markdown + (For a single issue) + Fixes #20 + + (For multiple issues) + Fixes #32, fixes #40 + ``` + + 2. **A succinct description of the design** used to fix any related issues. For example: + + ```markdown + This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked. + ``` + + 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered. + +If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that! diff --git a/catapult/third_party/polymer/components/paper-input/README.md b/catapult/third_party/polymer/components/paper-input/README.md new file mode 100644 index 00000000..80c6bc33 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/README.md @@ -0,0 +1,38 @@ +[![Build status](https://travis-ci.org/PolymerElements/paper-input.svg?branch=master)](https://travis-ci.org/PolymerElements/paper-input) +[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://beta.webcomponents.org/element/PolymerElements/paper-input) + +## <paper-input> + +Material design: [Text fields](https://www.google.com/design/spec/components/text-fields.html) + +`<paper-input>` is a single-line text field with Material Design styling. + +<!--- +``` +<custom-element-demo> + <template> + <script src="../webcomponentsjs/webcomponents-lite.js"></script> + <link rel="import" href="paper-input.html"> + <link rel="import" href="../iron-icons/iron-icons.html"> + <style> + paper-input { + max-width: 400px; + margin: auto; + } + iron-icon, div[suffix] { + color: hsl(0, 0%, 50%); + margin-right: 12px; + } + </style> + <next-code-block></next-code-block> + </template> +</custom-element-demo> +``` +--> +```html +<paper-input always-float-label label="Floating label"></paper-input> +<paper-input label="username"> + <iron-icon icon="mail" prefix></iron-icon> + <div suffix>@email.com</div> +</paper-input> +``` diff --git a/catapult/third_party/polymer/components/paper-input/all-imports.html b/catapult/third_party/polymer/components/paper-input/all-imports.html new file mode 100644 index 00000000..0f457718 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/all-imports.html @@ -0,0 +1,12 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="paper-input.html"> +<link rel="import" href="paper-textarea.html"> diff --git a/catapult/third_party/polymer/components/paper-input/bower.json b/catapult/third_party/polymer/components/paper-input/bower.json new file mode 100644 index 00000000..84a2e99d --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/bower.json @@ -0,0 +1,51 @@ +{ + "name": "paper-input", + "version": "1.1.24", + "description": "Material design text fields", + "authors": [ + "The Polymer Authors" + ], + "keywords": [ + "web-components", + "polymer", + "input" + ], + "main": [ + "paper-input.html", + "paper-textarea.html", + "paper-input-behavior.html", + "paper-input-container.html", + "paper-input-error.html", + "paper-input-addon-behavior.html", + "paper-input-char-counter.html" + ], + "private": true, + "repository": { + "type": "git", + "url": "git://github.com/PolymerElements/paper-input.git" + }, + "license": "http://polymer.github.io/LICENSE.txt", + "homepage": "https://github.com/PolymerElements/paper-input", + "ignore": [], + "dependencies": { + "polymer": "Polymer/polymer#^1.2.0", + "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0", + "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0", + "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0", + "iron-input": "PolymerElements/iron-input#^1.0.0", + "paper-styles": "PolymerElements/paper-styles#^1.1.4", + "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0" + }, + "devDependencies": { + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", + "iron-demo-helpers": "PolymerElements/iron-demo-helpers#^1.0.0", + "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0", + "iron-icon": "PolymerElements/iron-icon#^1.0.0", + "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0", + "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0", + "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0", + "test-fixture": "PolymerElements/test-fixture#^1.0.0", + "web-component-tester": "^4.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + } +} diff --git a/catapult/third_party/polymer/components/paper-input/demo/index.html b/catapult/third_party/polymer/components/paper-input/demo/index.html new file mode 100644 index 00000000..f84799de --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/demo/index.html @@ -0,0 +1,155 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> + + <title>paper-input demo</title> + + <script src="../../webcomponentsjs/webcomponents-lite.js"></script> + + <link rel="import" href="../../iron-demo-helpers/demo-pages-shared-styles.html"> + <link rel="import" href="../../iron-demo-helpers/demo-snippet.html"> + <link rel="import" href="../../iron-icon/iron-icon.html"> + <link rel="import" href="../../iron-icons/iron-icons.html"> + <link rel="import" href="../../iron-input/iron-input.html"> + <link rel="import" href="../../paper-icon-button/paper-icon-button.html"> + <link rel="import" href="../../paper-styles/color.html"> + <link rel="import" href="../paper-input-container.html"> + <link rel="import" href="../paper-input-error.html"> + <link rel="import" href="../paper-input.html"> + <link rel="import" href="../paper-textarea.html"> + <link rel="import" href="ssn-input.html"> + + <style is="custom-style" include="demo-pages-shared-styles"> + paper-input { + display: block; + } + + demo-snippet.horizontal { + --demo-snippet-demo: { + @apply(--layout-horizontal); + @apply(--layout-justified); + @apply(--layout-wrap); + } + } + demo-snippet.horizontal paper-input { + display: inline-block; + } + + button { + width: 70px; + } + + #inputForValidation { + display: inline-block; + width: calc(100% - 75px); + } + + .vertical-section-container { + max-width: 600px; + } + + paper-icon-button { + color: var(--paper-red-300); + --paper-icon-button-ink-color: var(--paper-red-a100); + width: 23px; /* 15px + 2*4px for padding */ + height: 23px; + padding: 0px 4px; + } + + iron-icon { + padding-right: 5px; + } + </style> +</head> +<body unresolved> + <div class="vertical-section-container centered"> + <h3>Inputs can have different types, and be disabled</h3> + <demo-snippet> + <template> + <paper-input label="text input"></paper-input> + <paper-textarea label="autoresizing textarea input"></paper-textarea> + <paper-input label="password input" type="password"></paper-input> + <paper-input label="disabled input" disabled></paper-input> + </template> + </demo-snippet> + + <h3>Inputs can have character counters</h3> + <demo-snippet> + <template> + <paper-input label="simple character counter" char-counter></paper-input> + <paper-input label="input with at most 10 characters" char-counter maxlength="10"></paper-input> + </template> + </demo-snippet> + + <h3>The label can have different floating states</h3> + <demo-snippet> + <template> + <paper-input label="this label floats after typing"></paper-input> + <paper-input label="this label is always floating" always-float-label></paper-input> + <paper-input label="this label never floats" no-label-float></paper-input> + <paper-input label="this label is always floating" always-float-label placeholder="placeholder text"></paper-input> + </template> + </demo-snippet> + + <h3>Inputs can validate automatically or on demand, and can have custom error messages</h3> + <demo-snippet> + <template> + <paper-input label="this input requires some text" required auto-validate error-message="needs some text!"></paper-input> + <paper-input label="this input requires letters only" auto-validate pattern="[a-zA-Z]*" error-message="letters only!"></paper-input> + <paper-input label="this input will only let you type letters" auto-validate allowed-pattern="[a-zA-Z]"></paper-input> + <paper-input id="inputForValidation" required label="this input is manually validated" pattern="[a-zA-Z]*" error-message="letters only!"></paper-input> + <button onclick="validate()">Validate!</button> + </template> + </demo-snippet> + + <h3>Inputs can have prefixes and suffixes</h3> + <demo-snippet class="horizontal"> + <template> + <paper-input label="total" type="number"> + <div prefix>$</div> + </paper-input> + <paper-input label="username" id="inputWithButton"> + <iron-icon icon="mail" prefix></iron-icon> + <div suffix>@email.com</div> + <paper-icon-button suffix onclick="clearInput()" + icon="clear" alt="clear" title="clear"> + </paper-icon-button> + </paper-input> + </template> + </demo-snippet> + + <h3>Inputs can have custom logic</h3> + <demo-snippet> + <template> + <paper-input-container always-float-label auto-validate attr-for-value="value"> + <label>Social Security Number</label> + <ssn-input class="paper-input-input"></ssn-input> + <paper-input-error>SSN invalid!</paper-input-error> + </paper-input-container> + </template> + </demo-snippet> + </div> + + <script> + function validate() { + document.getElementById('inputForValidation').validate(); + } + + function clearInput() { + document.getElementById('inputWithButton').value = ''; + } + </script> +</body> +</html> diff --git a/catapult/third_party/polymer/components/paper-input/demo/ssn-input.html b/catapult/third_party/polymer/components/paper-input/demo/ssn-input.html new file mode 100644 index 00000000..c7ab51dd --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/demo/ssn-input.html @@ -0,0 +1,96 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<link rel="import" href="../../polymer/polymer.html"> +<link rel="import" href="../../iron-input/iron-input.html"> +<link rel="import" href="../../iron-flex-layout/iron-flex-layout.html"> +<link rel="import" href="ssn-validator.html"> + +<dom-module id="ssn-input"> + <template> + + <style> + :host { + display: inline-block; + } + + :host([hidden]) { + display: none !important; + } + + input[is="iron-input"] { + font: inherit; + outline: none; + box-shadow: none; + border: none; + width: auto; + text-align: center; + } + + .container { + @apply(--layout-horizontal); + } + </style> + + <ssn-validator></ssn-validator> + + <div class="container"> + + <input is="iron-input" maxlength="3" bind-value="{{_ssn1}}" size="3" aria-label="First 3 digits of social security number"> + - + <input is="iron-input" maxlength="2" bind-value="{{_ssn2}}" size="2" aria-label="Middle 2 digits of social security number"> + - + <input is="iron-input" maxlength="4" bind-value="{{_ssn3}}" size="4" aria-label="Last 4 digits of social security number"> + + </div> + + </template> +</dom-module> + +<script> + Polymer({ + is: 'ssn-input', + + behaviors: [ + Polymer.IronValidatableBehavior + ], + + properties: { + value: { + notify: true, + type: String + }, + + _ssn1: { + type: String + }, + + _ssn2: { + type: String + }, + + _ssn3: { + type: String + }, + + validator: { + type: String, + value: 'ssn-validator' + } + }, + + observers: [ + '_computeValue(_ssn1,_ssn2,_ssn3)' + ], + + _computeValue: function(ssn1, ssn2, ssn3) { + this.value = ssn1.trim() + '-' + ssn2.trim() + '-' + ssn3.trim(); + } + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/demo/ssn-validator.html b/catapult/third_party/polymer/components/paper-input/demo/ssn-validator.html new file mode 100644 index 00000000..e45365b5 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/demo/ssn-validator.html @@ -0,0 +1,27 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../../polymer/polymer.html"> +<link rel="import" href="../../iron-validator-behavior/iron-validator-behavior.html"> + +<script> + Polymer({ + is: 'ssn-validator', + + behaviors: [ + Polymer.IronValidatorBehavior + ], + + validate: function(value) { + // this regex validates incomplete ssn's (by design) + return !value || value.match(/^[0-9]{0,3}-[0-9]{0,2}-[0-9]{0,4}$/); + } + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/hero.svg b/catapult/third_party/polymer/components/paper-input/hero.svg new file mode 100755 index 00000000..e72ebd30 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/hero.svg @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="49" y="53" width="2" height="18"/>
+ <path d="M188,78H37V44h151V78z M39,76h147V46H39V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/catapult/third_party/polymer/components/paper-input/index.html b/catapult/third_party/polymer/components/paper-input/index.html new file mode 100644 index 00000000..e6c9fadc --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/index.html @@ -0,0 +1,28 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + + <title>paper-input</title> + + <script src="../webcomponentsjs/webcomponents-lite.js"></script> + <link rel="import" href="../iron-component-page/iron-component-page.html"> + +</head> +<body> + + <iron-component-page src="all-imports.html"></iron-component-page> + +</body> +</html> diff --git a/catapult/third_party/polymer/components/paper-input/paper-input-addon-behavior.html b/catapult/third_party/polymer/components/paper-input/paper-input-addon-behavior.html new file mode 100644 index 00000000..41081c71 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-input-addon-behavior.html @@ -0,0 +1,47 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> + +<script> + + /** + * Use `Polymer.PaperInputAddonBehavior` to implement an add-on for `<paper-input-container>`. A + * add-on appears below the input, and may display information based on the input value and + * validity such as a character counter or an error message. + * @polymerBehavior + */ + Polymer.PaperInputAddonBehavior = { + + hostAttributes: { + 'add-on': '' + }, + + attached: function() { + this.fire('addon-attached'); + }, + + /** + * The function called by `<paper-input-container>` when the input value or validity changes. + * @param {{ + * inputElement: (Element|undefined), + * value: (string|undefined), + * invalid: boolean + * }} state - + * inputElement: The input element. + * value: The input value. + * invalid: True if the input value is invalid. + */ + update: function(state) { + } + + }; + +</script> diff --git a/catapult/third_party/polymer/components/paper-input/paper-input-behavior.html b/catapult/third_party/polymer/components/paper-input/paper-input-behavior.html new file mode 100644 index 00000000..33e2a2db --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-input-behavior.html @@ -0,0 +1,569 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> +<link rel="import" href="../iron-behaviors/iron-control-state.html"> + +<script> + + // Generate unique, monotonically increasing IDs for labels (needed by + // aria-labelledby) and add-ons. + Polymer.PaperInputHelper = {}; + Polymer.PaperInputHelper.NextLabelID = 1; + Polymer.PaperInputHelper.NextAddonID = 1; + + /** + * Use `Polymer.PaperInputBehavior` to implement inputs with `<paper-input-container>`. This + * behavior is implemented by `<paper-input>`. It exposes a number of properties from + * `<paper-input-container>` and `<input is="iron-input">` and they should be bound in your + * template. + * + * The input element can be accessed by the `inputElement` property if you need to access + * properties or methods that are not exposed. + * @polymerBehavior Polymer.PaperInputBehavior + */ + Polymer.PaperInputBehaviorImpl = { + + properties: { + /** + * Fired when the input changes due to user interaction. + * + * @event change + */ + + /** + * The label for this input. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * `<label>`'s content and `hidden` property, e.g. + * `<label hidden$="[[!label]]">[[label]]</label>` in your `template` + */ + label: { + type: String + }, + + /** + * The value for this input. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<input is="iron-input">`'s `bindValue` + * property, or the value property of your input that is `notify:true`. + */ + value: { + notify: true, + type: String + }, + + /** + * Set to true to disable this input. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * both the `<paper-input-container>`'s and the input's `disabled` property. + */ + disabled: { + type: Boolean, + value: false + }, + + /** + * Returns true if the value is invalid. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to both the + * `<paper-input-container>`'s and the input's `invalid` property. + * + * If `autoValidate` is true, the `invalid` attribute is managed automatically, + * which can clobber attempts to manage it manually. + */ + invalid: { + type: Boolean, + value: false, + notify: true + }, + + /** + * Set to true to prevent the user from entering invalid input. If you're + * using PaperInputBehavior to implement your own paper-input-like element, + * bind this to `<input is="iron-input">`'s `preventInvalidInput` property. + */ + preventInvalidInput: { + type: Boolean + }, + + /** + * Set this to specify the pattern allowed by `preventInvalidInput`. If + * you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `allowedPattern` + * property. + */ + allowedPattern: { + type: String + }, + + /** + * The type of the input. The supported types are `text`, `number` and `password`. + * If you're using PaperInputBehavior to implement your own paper-input-like element, + * bind this to the `<input is="iron-input">`'s `type` property. + */ + type: { + type: String + }, + + /** + * The datalist of the input (if any). This should match the id of an existing `<datalist>`. + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `list` property. + */ + list: { + type: String + }, + + /** + * A pattern to validate the `input` with. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<input is="iron-input">`'s `pattern` property. + */ + pattern: { + type: String + }, + + /** + * Set to true to mark the input as required. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<input is="iron-input">`'s `required` property. + */ + required: { + type: Boolean, + value: false + }, + + /** + * The error message to display when the input is invalid. If you're using + * PaperInputBehavior to implement your own paper-input-like element, + * bind this to the `<paper-input-error>`'s content, if using. + */ + errorMessage: { + type: String + }, + + /** + * Set to true to show a character counter. + */ + charCounter: { + type: Boolean, + value: false + }, + + /** + * Set to true to disable the floating label. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<paper-input-container>`'s `noLabelFloat` property. + */ + noLabelFloat: { + type: Boolean, + value: false + }, + + /** + * Set to true to always float the label. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<paper-input-container>`'s `alwaysFloatLabel` property. + */ + alwaysFloatLabel: { + type: Boolean, + value: false + }, + + /** + * Set to true to auto-validate the input value. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<paper-input-container>`'s `autoValidate` property. + */ + autoValidate: { + type: Boolean, + value: false + }, + + /** + * Name of the validator to use. If you're using PaperInputBehavior to + * implement your own paper-input-like element, bind this to + * the `<input is="iron-input">`'s `validator` property. + */ + validator: { + type: String + }, + + // HTMLInputElement attributes for binding if needed + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `autocomplete` property. + */ + autocomplete: { + type: String, + value: 'off' + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `autofocus` property. + */ + autofocus: { + type: Boolean, + observer: '_autofocusChanged' + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `inputmode` property. + */ + inputmode: { + type: String + }, + + /** + * The minimum length of the input value. + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `minlength` property. + */ + minlength: { + type: Number + }, + + /** + * The maximum length of the input value. + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `maxlength` property. + */ + maxlength: { + type: Number + }, + + /** + * The minimum (numeric or date-time) input value. + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `min` property. + */ + min: { + type: String + }, + + /** + * The maximum (numeric or date-time) input value. + * Can be a String (e.g. `"2000-01-01"`) or a Number (e.g. `2`). + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `max` property. + */ + max: { + type: String + }, + + /** + * Limits the numeric or date-time increments. + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `step` property. + */ + step: { + type: String + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `name` property. + */ + name: { + type: String + }, + + /** + * A placeholder string in addition to the label. If this is set, the label will always float. + */ + placeholder: { + type: String, + // need to set a default so _computeAlwaysFloatLabel is run + value: '' + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `readonly` property. + */ + readonly: { + type: Boolean, + value: false + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `size` property. + */ + size: { + type: Number + }, + + // Nonstandard attributes for binding if needed + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `autocapitalize` property. + */ + autocapitalize: { + type: String, + value: 'none' + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `autocorrect` property. + */ + autocorrect: { + type: String, + value: 'off' + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `autosave` property, + * used with type=search. + */ + autosave: { + type: String + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `results` property, + * used with type=search. + */ + results: { + type: Number + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the `<input is="iron-input">`'s `accept` property, + * used with type=file. + */ + accept: { + type: String + }, + + /** + * If you're using PaperInputBehavior to implement your own paper-input-like + * element, bind this to the`<input is="iron-input">`'s `multiple` property, + * used with type=file. + */ + multiple: { + type: Boolean + }, + + _ariaDescribedBy: { + type: String, + value: '' + }, + + _ariaLabelledBy: { + type: String, + value: '' + } + + }, + + listeners: { + 'addon-attached': '_onAddonAttached', + }, + + keyBindings: { + 'shift+tab:keydown': '_onShiftTabDown' + }, + + hostAttributes: { + tabindex: 0 + }, + + /** + * Returns a reference to the input element. + */ + get inputElement() { + return this.$.input; + }, + + /** + * Returns a reference to the focusable element. + */ + get _focusableElement() { + return this.inputElement; + }, + + registered: function() { + // These types have some default placeholder text; overlapping + // the label on top of it looks terrible. Auto-float the label in this case. + this._typesThatHaveText = ["date", "datetime", "datetime-local", "month", + "time", "week", "file"]; + }, + + attached: function() { + this._updateAriaLabelledBy(); + + if (this.inputElement && + this._typesThatHaveText.indexOf(this.inputElement.type) !== -1) { + this.alwaysFloatLabel = true; + } + }, + + _appendStringWithSpace: function(str, more) { + if (str) { + str = str + ' ' + more; + } else { + str = more; + } + return str; + }, + + _onAddonAttached: function(event) { + var target = event.path ? event.path[0] : event.target; + if (target.id) { + this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, target.id); + } else { + var id = 'paper-input-add-on-' + Polymer.PaperInputHelper.NextAddonID++; + target.id = id; + this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, id); + } + }, + + /** + * Validates the input element and sets an error style if needed. + * + * @return {boolean} + */ + validate: function() { + return this.inputElement.validate(); + }, + + /** + * Forward focus to inputElement. Overriden from IronControlState. + */ + _focusBlurHandler: function(event) { + Polymer.IronControlState._focusBlurHandler.call(this, event); + + // Forward the focus to the nested input. + if (this.focused && !this._shiftTabPressed) + this._focusableElement.focus(); + }, + + /** + * Handler that is called when a shift+tab keypress is detected by the menu. + * + * @param {CustomEvent} event A key combination event. + */ + _onShiftTabDown: function(event) { + var oldTabIndex = this.getAttribute('tabindex'); + this._shiftTabPressed = true; + this.setAttribute('tabindex', '-1'); + this.async(function() { + this.setAttribute('tabindex', oldTabIndex); + this._shiftTabPressed = false; + }, 1); + }, + + /** + * If `autoValidate` is true, then validates the element. + */ + _handleAutoValidate: function() { + if (this.autoValidate) + this.validate(); + }, + + /** + * Restores the cursor to its original position after updating the value. + * @param {string} newValue The value that should be saved. + */ + updateValueAndPreserveCaret: function(newValue) { + // Not all elements might have selection, and even if they have the + // right properties, accessing them might throw an exception (like for + // <input type=number>) + try { + var start = this.inputElement.selectionStart; + this.value = newValue; + + // The cursor automatically jumps to the end after re-setting the value, + // so restore it to its original position. + this.inputElement.selectionStart = start; + this.inputElement.selectionEnd = start; + } catch (e) { + // Just set the value and give up on the caret. + this.value = newValue; + } + }, + + _computeAlwaysFloatLabel: function(alwaysFloatLabel, placeholder) { + return placeholder || alwaysFloatLabel; + }, + + _updateAriaLabelledBy: function() { + var label = Polymer.dom(this.root).querySelector('label'); + if (!label) { + this._ariaLabelledBy = ''; + return; + } + var labelledBy; + if (label.id) { + labelledBy = label.id; + } else { + labelledBy = 'paper-input-label-' + Polymer.PaperInputHelper.NextLabelID++; + label.id = labelledBy; + } + this._ariaLabelledBy = labelledBy; + }, + + _onChange:function(event) { + // In the Shadow DOM, the `change` event is not leaked into the + // ancestor tree, so we must do this manually. + // See https://w3c.github.io/webcomponents/spec/shadow/#events-that-are-not-leaked-into-ancestor-trees. + if (this.shadowRoot) { + this.fire(event.type, {sourceEvent: event}, { + node: this, + bubbles: event.bubbles, + cancelable: event.cancelable + }); + } + }, + + _autofocusChanged: function() { + // Firefox doesn't respect the autofocus attribute if it's applied after + // the page is loaded (Chrome/WebKit do respect it), preventing an + // autofocus attribute specified in markup from taking effect when the + // element is upgraded. As a workaround, if the autofocus property is set, + // and the focus hasn't already been moved elsewhere, we take focus. + if (this.autofocus && this._focusableElement) { + + // In IE 11, the default document.activeElement can be the page's + // outermost html element, but there are also cases (under the + // polyfill?) in which the activeElement is not a real HTMLElement, but + // just a plain object. We identify the latter case as having no valid + // activeElement. + var activeElement = document.activeElement; + var isActiveElementValid = activeElement instanceof HTMLElement; + + // Has some other element has already taken the focus? + var isSomeElementActive = isActiveElementValid && + activeElement !== document.body && + activeElement !== document.documentElement; /* IE 11 */ + if (!isSomeElementActive) { + // No specific element has taken the focus yet, so we can take it. + this._focusableElement.focus(); + } + } + } + }; + + /** @polymerBehavior */ + Polymer.PaperInputBehavior = [ + Polymer.IronControlState, + Polymer.IronA11yKeysBehavior, + Polymer.PaperInputBehaviorImpl + ]; +</script> diff --git a/catapult/third_party/polymer/components/paper-input/paper-input-char-counter.html b/catapult/third_party/polymer/components/paper-input/paper-input-char-counter.html new file mode 100644 index 00000000..1a09a06d --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-input-char-counter.html @@ -0,0 +1,99 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../paper-styles/typography.html"> +<link rel="import" href="paper-input-addon-behavior.html"> + +<!-- +`<paper-input-char-counter>` is a character counter for use with `<paper-input-container>`. It +shows the number of characters entered in the input and the max length if it is specified. + + <paper-input-container> + <input is="iron-input" maxlength="20"> + <paper-input-char-counter></paper-input-char-counter> + </paper-input-container> + +### Styling + +The following mixin is available for styling: + +Custom property | Description | Default +----------------|-------------|---------- +`--paper-input-char-counter` | Mixin applied to the element | `{}` +--> + +<dom-module id="paper-input-char-counter"> + <template> + <style> + :host { + display: inline-block; + float: right; + + @apply(--paper-font-caption); + @apply(--paper-input-char-counter); + } + + :host([hidden]) { + display: none !important; + } + + :host-context([dir="rtl"]) { + float: left; + } + </style> + + <span>[[_charCounterStr]]</span> + </template> +</dom-module> + +<script> + Polymer({ + is: 'paper-input-char-counter', + + behaviors: [ + Polymer.PaperInputAddonBehavior + ], + + properties: { + _charCounterStr: { + type: String, + value: '0' + } + }, + + /** + * This overrides the update function in PaperInputAddonBehavior. + * @param {{ + * inputElement: (Element|undefined), + * value: (string|undefined), + * invalid: boolean + * }} state - + * inputElement: The input element. + * value: The input value. + * invalid: True if the input value is invalid. + */ + update: function(state) { + if (!state.inputElement) { + return; + } + + state.value = state.value || ''; + + var counter = state.value.toString().length.toString(); + + if (state.inputElement.hasAttribute('maxlength')) { + counter += '/' + state.inputElement.getAttribute('maxlength'); + } + + this._charCounterStr = counter; + } + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/paper-input-container.html b/catapult/third_party/polymer/components/paper-input/paper-input-container.html new file mode 100644 index 00000000..2ef06efa --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-input-container.html @@ -0,0 +1,653 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../iron-flex-layout/iron-flex-layout.html"> +<link rel="import" href="../paper-styles/default-theme.html"> +<link rel="import" href="../paper-styles/typography.html"> + +<!-- +`<paper-input-container>` is a container for a `<label>`, an `<input is="iron-input">` or +`<textarea>` and optional add-on elements such as an error message or character +counter, used to implement Material Design text fields. + +For example: + + <paper-input-container> + <label>Your name</label> + <input is="iron-input"> + </paper-input-container> + +Do not wrap `<paper-input-container>` around elements that already include it, such as `<paper-input>`. +Doing so may cause events to bounce infintely between the container and its contained element. + +### Listening for input changes + +By default, it listens for changes on the `bind-value` attribute on its children nodes and perform +tasks such as auto-validating and label styling when the `bind-value` changes. You can configure +the attribute it listens to with the `attr-for-value` attribute. + +### Using a custom input element + +You can use a custom input element in a `<paper-input-container>`, for example to implement a +compound input field like a social security number input. The custom input element should have the +`paper-input-input` class, have a `notify:true` value property and optionally implements +`Polymer.IronValidatableBehavior` if it is validatable. + + <paper-input-container attr-for-value="ssn-value"> + <label>Social security number</label> + <ssn-input class="paper-input-input"></ssn-input> + </paper-input-container> + + +If you're using a `<paper-input-container>` imperatively, it's important to make sure +that you attach its children (the `iron-input` and the optional `label`) before you +attach the `<paper-input-container>` itself, so that it can be set up correctly. + +### Validation + +If the `auto-validate` attribute is set, the input container will validate the input and update +the container styling when the input value changes. + +### Add-ons + +Add-ons are child elements of a `<paper-input-container>` with the `add-on` attribute and +implements the `Polymer.PaperInputAddonBehavior` behavior. They are notified when the input value +or validity changes, and may implement functionality such as error messages or character counters. +They appear at the bottom of the input. + +### Prefixes and suffixes +These are child elements of a `<paper-input-container>` with the `prefix` +or `suffix` attribute, and are displayed inline with the input, before or after. + + <paper-input-container> + <div prefix>$</div> + <label>Total</label> + <input is="iron-input"> + <paper-icon-button suffix icon="clear"></paper-icon-button> + </paper-input-container> + +### Styling + +The following custom properties and mixins are available for styling: + +Custom property | Description | Default +----------------|-------------|---------- +`--paper-input-container-color` | Label and underline color when the input is not focused | `--secondary-text-color` +`--paper-input-container-focus-color` | Label and underline color when the input is focused | `--primary-color` +`--paper-input-container-invalid-color` | Label and underline color when the input is is invalid | `--error-color` +`--paper-input-container-input-color` | Input foreground color | `--primary-text-color` +`--paper-input-container` | Mixin applied to the container | `{}` +`--paper-input-container-disabled` | Mixin applied to the container when it's disabled | `{}` +`--paper-input-container-label` | Mixin applied to the label | `{}` +`--paper-input-container-label-focus` | Mixin applied to the label when the input is focused | `{}` +`--paper-input-container-label-floating` | Mixin applied to the label when floating | `{}` +`--paper-input-container-input` | Mixin applied to the input | `{}` +`--paper-input-container-input-focus` | Mixin applied to the input when focused | `{}` +`--paper-input-container-input-invalid` | Mixin applied to the input when invalid | `{}` +`--paper-input-container-input-webkit-spinner` | Mixin applied to the webkit spinner | `{}` +`--paper-input-container-input-webkit-clear` | Mixin applied to the webkit clear button | `{}` +`--paper-input-container-ms-clear` | Mixin applied to the Internet Explorer clear button | `{}` +`--paper-input-container-underline` | Mixin applied to the underline | `{}` +`--paper-input-container-underline-focus` | Mixin applied to the underline when the input is focused | `{}` +`--paper-input-container-underline-disabled` | Mixin applied to the underline when the input is disabled | `{}` +`--paper-input-prefix` | Mixin applied to the input prefix | `{}` +`--paper-input-suffix` | Mixin applied to the input suffix | `{}` + +This element is `display:block` by default, but you can set the `inline` attribute to make it +`display:inline-block`. +--> + +<dom-module id="paper-input-container"> + <template> + <style> + :host { + display: block; + padding: 8px 0; + + @apply(--paper-input-container); + } + + :host([inline]) { + display: inline-block; + } + + :host([disabled]) { + pointer-events: none; + opacity: 0.33; + + @apply(--paper-input-container-disabled); + } + + :host([hidden]) { + display: none !important; + } + + .floated-label-placeholder { + @apply(--paper-font-caption); + } + + .underline { + height: 2px; + position: relative; + } + + .focused-line { + @apply(--layout-fit); + + border-bottom: 2px solid var(--paper-input-container-focus-color, --primary-color); + + -webkit-transform-origin: center center; + transform-origin: center center; + -webkit-transform: scale3d(0,1,1); + transform: scale3d(0,1,1); + + @apply(--paper-input-container-underline-focus); + } + + .underline.is-highlighted .focused-line { + -webkit-transform: none; + transform: none; + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s; + + @apply(--paper-transition-easing); + } + + .underline.is-invalid .focused-line { + border-color: var(--paper-input-container-invalid-color, --error-color); + -webkit-transform: none; + transform: none; + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s; + + @apply(--paper-transition-easing); + } + + .unfocused-line { + @apply(--layout-fit); + + border-bottom: 1px solid var(--paper-input-container-color, --secondary-text-color); + + @apply(--paper-input-container-underline); + } + + :host([disabled]) .unfocused-line { + border-bottom: 1px dashed; + border-color: var(--paper-input-container-color, --secondary-text-color); + + @apply(--paper-input-container-underline-disabled); + } + + .label-and-input-container { + @apply(--layout-flex-auto); + @apply(--layout-relative); + + width: 100%; + max-width: 100%; + } + + .input-content { + @apply(--layout-horizontal); + @apply(--layout-center); + + position: relative; + } + + .input-content ::content label, + .input-content ::content .paper-input-label { + position: absolute; + top: 0; + right: 0; + left: 0; + width: 100%; + font: inherit; + color: var(--paper-input-container-color, --secondary-text-color); + -webkit-transition: -webkit-transform 0.25s, width 0.25s; + transition: transform 0.25s, width 0.25s; + -webkit-transform-origin: left top; + transform-origin: left top; + + @apply(--paper-font-common-nowrap); + @apply(--paper-font-subhead); + @apply(--paper-input-container-label); + @apply(--paper-transition-easing); + } + + .input-content.label-is-floating ::content label, + .input-content.label-is-floating ::content .paper-input-label { + -webkit-transform: translateY(-75%) scale(0.75); + transform: translateY(-75%) scale(0.75); + + /* Since we scale to 75/100 of the size, we actually have 100/75 of the + original space now available */ + width: 133%; + + @apply(--paper-input-container-label-floating); + } + + :host-context([dir="rtl"]) .input-content.label-is-floating ::content label, + :host-context([dir="rtl"]) .input-content.label-is-floating ::content .paper-input-label { + /* TODO(noms): Figure out why leaving the width at 133% before the animation + * actually makes + * it wider on the right side, not left side, as you would expect in RTL */ + width: 100%; + -webkit-transform-origin: right top; + transform-origin: right top; + } + + .input-content.label-is-highlighted ::content label, + .input-content.label-is-highlighted ::content .paper-input-label { + color: var(--paper-input-container-focus-color, --primary-color); + + @apply(--paper-input-container-label-focus); + } + + .input-content.is-invalid ::content label, + .input-content.is-invalid ::content .paper-input-label { + color: var(--paper-input-container-invalid-color, --error-color); + } + + .input-content.label-is-hidden ::content label, + .input-content.label-is-hidden ::content .paper-input-label { + visibility: hidden; + } + + .input-content ::content input, + .input-content ::content textarea, + .input-content ::content iron-autogrow-textarea, + .input-content ::content .paper-input-input { + position: relative; /* to make a stacking context */ + outline: none; + box-shadow: none; + padding: 0; + width: 100%; + max-width: 100%; + background: transparent; + border: none; + color: var(--paper-input-container-input-color, --primary-text-color); + -webkit-appearance: none; + text-align: inherit; + vertical-align: bottom; + + @apply(--paper-font-subhead); + @apply(--paper-input-container-input); + } + + .input-content.focused ::content input, + .input-content.focused ::content textarea, + .input-content.focused ::content iron-autogrow-textarea, + .input-content.focused ::content .paper-input-input { + @apply(--paper-input-container-input-focus); + } + + .input-content.is-invalid ::content input, + .input-content.is-invalid ::content textarea, + .input-content.is-invalid ::content iron-autogrow-textarea, + .input-content.is-invalid ::content .paper-input-input { + @apply(--paper-input-container-input-invalid); + } + + .input-content ::content input::-webkit-outer-spin-button, + .input-content ::content input::-webkit-inner-spin-button { + @apply(--paper-input-container-input-webkit-spinner); + } + + ::content [prefix] { + @apply(--paper-font-subhead); + + @apply(--paper-input-prefix); + @apply(--layout-flex-none); + } + + ::content [suffix] { + @apply(--paper-font-subhead); + + @apply(--paper-input-suffix); + @apply(--layout-flex-none); + } + + /* Firefox sets a min-width on the input, which can cause layout issues */ + .input-content ::content input { + min-width: 0; + } + + .input-content ::content textarea { + resize: none; + } + + .add-on-content { + position: relative; + } + + .add-on-content.is-invalid ::content * { + color: var(--paper-input-container-invalid-color, --error-color); + } + + .add-on-content.is-highlighted ::content * { + color: var(--paper-input-container-focus-color, --primary-color); + } + </style> + + <template is="dom-if" if="[[!noLabelFloat]]"> + <div class="floated-label-placeholder" aria-hidden="true"> </div> + </template> + + <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]"> + <content select="[prefix]" id="prefix"></content> + + <div class="label-and-input-container" id="labelAndInputContainer"> + <content select=":not([add-on]):not([prefix]):not([suffix])"></content> + </div> + + <content select="[suffix]"></content> + </div> + + <div class$="[[_computeUnderlineClass(focused,invalid)]]"> + <div class="unfocused-line"></div> + <div class="focused-line"></div> + </div> + + <div class$="[[_computeAddOnContentClass(focused,invalid)]]"> + <content id="addOnContent" select="[add-on]"></content> + </div> + </template> +</dom-module> + +<script> + Polymer({ + is: 'paper-input-container', + + properties: { + /** + * Set to true to disable the floating label. The label disappears when the input value is + * not null. + */ + noLabelFloat: { + type: Boolean, + value: false + }, + + /** + * Set to true to always float the floating label. + */ + alwaysFloatLabel: { + type: Boolean, + value: false + }, + + /** + * The attribute to listen for value changes on. + */ + attrForValue: { + type: String, + value: 'bind-value' + }, + + /** + * Set to true to auto-validate the input value when it changes. + */ + autoValidate: { + type: Boolean, + value: false + }, + + /** + * True if the input is invalid. This property is set automatically when the input value + * changes if auto-validating, or when the `iron-input-validate` event is heard from a child. + */ + invalid: { + observer: '_invalidChanged', + type: Boolean, + value: false + }, + + /** + * True if the input has focus. + */ + focused: { + readOnly: true, + type: Boolean, + value: false, + notify: true + }, + + _addons: { + type: Array + // do not set a default value here intentionally - it will be initialized lazily when a + // distributed child is attached, which may occur before configuration for this element + // in polyfill. + }, + + _inputHasContent: { + type: Boolean, + value: false + }, + + _inputSelector: { + type: String, + value: 'input,textarea,.paper-input-input' + }, + + _boundOnFocus: { + type: Function, + value: function() { + return this._onFocus.bind(this); + } + }, + + _boundOnBlur: { + type: Function, + value: function() { + return this._onBlur.bind(this); + } + }, + + _boundOnInput: { + type: Function, + value: function() { + return this._onInput.bind(this); + } + }, + + _boundValueChanged: { + type: Function, + value: function() { + return this._onValueChanged.bind(this); + } + } + }, + + listeners: { + 'addon-attached': '_onAddonAttached', + 'iron-input-validate': '_onIronInputValidate' + }, + + get _valueChangedEvent() { + return this.attrForValue + '-changed'; + }, + + get _propertyForValue() { + return Polymer.CaseMap.dashToCamelCase(this.attrForValue); + }, + + get _inputElement() { + return Polymer.dom(this).querySelector(this._inputSelector); + }, + + get _inputElementValue() { + return this._inputElement[this._propertyForValue] || this._inputElement.value; + }, + + ready: function() { + if (!this._addons) { + this._addons = []; + } + this.addEventListener('focus', this._boundOnFocus, true); + this.addEventListener('blur', this._boundOnBlur, true); + }, + + attached: function() { + if (this.attrForValue) { + this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged); + } else { + this.addEventListener('input', this._onInput); + } + + // Only validate when attached if the input already has a value. + if (this._inputElementValue != '') { + this._handleValueAndAutoValidate(this._inputElement); + } else { + this._handleValue(this._inputElement); + } + }, + + _onAddonAttached: function(event) { + if (!this._addons) { + this._addons = []; + } + var target = event.target; + if (this._addons.indexOf(target) === -1) { + this._addons.push(target); + if (this.isAttached) { + this._handleValue(this._inputElement); + } + } + }, + + _onFocus: function() { + this._setFocused(true); + }, + + _onBlur: function() { + this._setFocused(false); + this._handleValueAndAutoValidate(this._inputElement); + }, + + _onInput: function(event) { + this._handleValueAndAutoValidate(event.target); + }, + + _onValueChanged: function(event) { + this._handleValueAndAutoValidate(event.target); + }, + + _handleValue: function(inputElement) { + var value = this._inputElementValue; + + // type="number" hack needed because this.value is empty until it's valid + if (value || value === 0 || (inputElement.type === 'number' && !inputElement.checkValidity())) { + this._inputHasContent = true; + } else { + this._inputHasContent = false; + } + + this.updateAddons({ + inputElement: inputElement, + value: value, + invalid: this.invalid + }); + }, + + _handleValueAndAutoValidate: function(inputElement) { + if (this.autoValidate) { + var valid; + if (inputElement.validate) { + valid = inputElement.validate(this._inputElementValue); + } else { + valid = inputElement.checkValidity(); + } + this.invalid = !valid; + } + + // Call this last to notify the add-ons. + this._handleValue(inputElement); + }, + + _onIronInputValidate: function(event) { + this.invalid = this._inputElement.invalid; + }, + + _invalidChanged: function() { + if (this._addons) { + this.updateAddons({invalid: this.invalid}); + } + }, + + /** + * Call this to update the state of add-ons. + * @param {Object} state Add-on state. + */ + updateAddons: function(state) { + for (var addon, index = 0; addon = this._addons[index]; index++) { + addon.update(state); + } + }, + + _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) { + var cls = 'input-content'; + if (!noLabelFloat) { + var label = this.querySelector('label'); + + if (alwaysFloatLabel || _inputHasContent) { + cls += ' label-is-floating'; + // If the label is floating, ignore any offsets that may have been + // applied from a prefix element. + this.$.labelAndInputContainer.style.position = 'static'; + + if (invalid) { + cls += ' is-invalid'; + } else if (focused) { + cls += " label-is-highlighted"; + } + } else { + // When the label is not floating, it should overlap the input element. + if (label) { + this.$.labelAndInputContainer.style.position = 'relative'; + } + if (invalid) { + cls += ' is-invalid'; + } + } + } else { + if (_inputHasContent) { + cls += ' label-is-hidden'; + } + if (invalid) { + cls += ' is-invalid'; + } + } + if (focused) { + cls += ' focused'; + } + return cls; + }, + + _computeUnderlineClass: function(focused, invalid) { + var cls = 'underline'; + if (invalid) { + cls += ' is-invalid'; + } else if (focused) { + cls += ' is-highlighted' + } + return cls; + }, + + _computeAddOnContentClass: function(focused, invalid) { + var cls = 'add-on-content'; + if (invalid) { + cls += ' is-invalid'; + } else if (focused) { + cls += ' is-highlighted' + } + return cls; + } + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/paper-input-error.html b/catapult/third_party/polymer/components/paper-input/paper-input-error.html new file mode 100644 index 00000000..645f1e72 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-input-error.html @@ -0,0 +1,94 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../paper-styles/default-theme.html"> +<link rel="import" href="../paper-styles/typography.html"> +<link rel="import" href="paper-input-addon-behavior.html"> + +<!-- +`<paper-input-error>` is an error message for use with `<paper-input-container>`. The error is +displayed when the `<paper-input-container>` is `invalid`. + + <paper-input-container> + <input is="iron-input" pattern="[0-9]*"> + <paper-input-error>Only numbers are allowed!</paper-input-error> + </paper-input-container> + +### Styling + +The following custom properties and mixins are available for styling: + +Custom property | Description | Default +----------------|-------------|---------- +`--paper-input-container-invalid-color` | The foreground color of the error | `--error-color` +`--paper-input-error` | Mixin applied to the error | `{}` +--> + +<dom-module id="paper-input-error"> + <template> + <style> + :host { + display: inline-block; + visibility: hidden; + + color: var(--paper-input-container-invalid-color, --error-color); + + @apply(--paper-font-caption); + @apply(--paper-input-error); + position: absolute; + left:0; + right:0; + } + + :host([invalid]) { + visibility: visible; + }; + </style> + + <content></content> + </template> +</dom-module> + +<script> + Polymer({ + is: 'paper-input-error', + + behaviors: [ + Polymer.PaperInputAddonBehavior + ], + + properties: { + /** + * True if the error is showing. + */ + invalid: { + readOnly: true, + reflectToAttribute: true, + type: Boolean + } + }, + + /** + * This overrides the update function in PaperInputAddonBehavior. + * @param {{ + * inputElement: (Element|undefined), + * value: (string|undefined), + * invalid: boolean + * }} state - + * inputElement: The input element. + * value: The input value. + * invalid: True if the input value is invalid. + */ + update: function(state) { + this._setInvalid(state.invalid); + } + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/paper-input.html b/catapult/third_party/polymer/components/paper-input/paper-input.html new file mode 100644 index 00000000..3eb0024e --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-input.html @@ -0,0 +1,183 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html"> +<link rel="import" href="../iron-input/iron-input.html"> +<link rel="import" href="paper-input-behavior.html"> +<link rel="import" href="paper-input-char-counter.html"> +<link rel="import" href="paper-input-container.html"> +<link rel="import" href="paper-input-error.html"> + +<!-- +Material design: [Text fields](https://www.google.com/design/spec/components/text-fields.html) + +`<paper-input>` is a single-line text field with Material Design styling. + + <paper-input label="Input label"></paper-input> + +It may include an optional error message or character counter. + + <paper-input error-message="Invalid input!" label="Input label"></paper-input> + <paper-input char-counter label="Input label"></paper-input> + +It can also include custom prefix or suffix elements, which are displayed +before or after the text input itself. In order for an element to be +considered as a prefix, it must have the `prefix` attribute (and similarly +for `suffix`). + + <paper-input label="total"> + <div prefix>$</div> + <paper-icon-button suffix icon="clear"></paper-icon-button> + </paper-input> + +A `paper-input` can use the native `type=search` or `type=file` features. +However, since we can't control the native styling of the input (search icon, +file button, date placeholder, etc.), in these cases the label will be +automatically floated. The `placeholder` attribute can still be used for +additional informational text. + + <paper-input label="search!" type="search" + placeholder="search for cats" autosave="test" results="5"> + </paper-input> + +See `Polymer.PaperInputBehavior` for more API docs. + +### Focus + +To focus a paper-input, you can call the native `focus()` method as long as the +paper input has a tab index. + +### Styling + +See `Polymer.PaperInputContainer` for a list of custom properties used to +style this element. + + +@group Paper Elements +@element paper-input +@hero hero.svg +@demo demo/index.html +--> + +<dom-module id="paper-input"> + <template> + <style> + :host { + display: block; + } + + :host([focused]) { + outline: none; + } + + :host([hidden]) { + display: none !important; + } + + input::-webkit-outer-spin-button, + input::-webkit-inner-spin-button { + @apply(--paper-input-container-input-webkit-spinner); + } + + input::-webkit-clear-button { + @apply(--paper-input-container-input-webkit-clear); + } + + input::-webkit-input-placeholder { + color: var(--paper-input-container-color, --secondary-text-color); + } + + input:-moz-placeholder { + color: var(--paper-input-container-color, --secondary-text-color); + } + + input::-moz-placeholder { + color: var(--paper-input-container-color, --secondary-text-color); + } + + input::-ms-clear { + @apply(--paper-input-container-ms-clear); + } + + input:-ms-input-placeholder { + color: var(--paper-input-container-color, --secondary-text-color); + } + + label { + pointer-events: none; + } + </style> + + <paper-input-container no-label-float="[[noLabelFloat]]" always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]" invalid="[[invalid]]"> + + <content select="[prefix]"></content> + + <label hidden$="[[!label]]" aria-hidden="true" for="input">[[label]]</label> + + <input is="iron-input" id="input" + aria-labelledby$="[[_ariaLabelledBy]]" + aria-describedby$="[[_ariaDescribedBy]]" + disabled$="[[disabled]]" + title$="[[title]]" + bind-value="{{value}}" + invalid="{{invalid}}" + prevent-invalid-input="[[preventInvalidInput]]" + allowed-pattern="[[allowedPattern]]" + validator="[[validator]]" + type$="[[type]]" + pattern$="[[pattern]]" + required$="[[required]]" + autocomplete$="[[autocomplete]]" + autofocus$="[[autofocus]]" + inputmode$="[[inputmode]]" + minlength$="[[minlength]]" + maxlength$="[[maxlength]]" + min$="[[min]]" + max$="[[max]]" + step$="[[step]]" + name$="[[name]]" + placeholder$="[[placeholder]]" + readonly$="[[readonly]]" + list$="[[list]]" + size$="[[size]]" + autocapitalize$="[[autocapitalize]]" + autocorrect$="[[autocorrect]]" + on-change="_onChange" + tabindex$="[[tabindex]]" + autosave$="[[autosave]]" + results$="[[results]]" + accept$="[[accept]]" + multiple$="[[multiple]]"> + + <content select="[suffix]"></content> + + <template is="dom-if" if="[[errorMessage]]"> + <paper-input-error aria-live="assertive">[[errorMessage]]</paper-input-error> + </template> + + <template is="dom-if" if="[[charCounter]]"> + <paper-input-char-counter></paper-input-char-counter> + </template> + + </paper-input-container> + </template> +</dom-module> + +<script> + Polymer({ + is: 'paper-input', + + behaviors: [ + Polymer.IronFormElementBehavior, + Polymer.PaperInputBehavior + ] + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/paper-textarea.html b/catapult/third_party/polymer/components/paper-input/paper-textarea.html new file mode 100644 index 00000000..cfc06520 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/paper-textarea.html @@ -0,0 +1,145 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../iron-autogrow-textarea/iron-autogrow-textarea.html"> +<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html"> +<link rel="import" href="paper-input-behavior.html"> +<link rel="import" href="paper-input-char-counter.html"> +<link rel="import" href="paper-input-container.html"> +<link rel="import" href="paper-input-error.html"> + +<!-- +`<paper-textarea>` is a multi-line text field with Material Design styling. + + <paper-textarea label="Textarea label"></paper-textarea> + +See `Polymer.PaperInputBehavior` for more API docs. + +### Validation + +Currently only `required` and `maxlength` validation is supported. + +### Styling + +See `Polymer.PaperInputContainer` for a list of custom properties used to +style this element. +--> + +<dom-module id="paper-textarea"> + <template> + <style> + :host { + display: block; + } + + :host([hidden]) { + display: none !important; + } + + label { + pointer-events: none; + } + </style> + + <paper-input-container no-label-float$="[[noLabelFloat]]" always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]" invalid="[[invalid]]"> + + <label hidden$="[[!label]]" aria-hidden="true">[[label]]</label> + + <iron-autogrow-textarea id="input" class="paper-input-input" + bind-value="{{value}}" + invalid="{{invalid}}" + validator$="[[validator]]" + disabled$="[[disabled]]" + autocomplete$="[[autocomplete]]" + autofocus$="[[autofocus]]" + inputmode$="[[inputmode]]" + name$="[[name]]" + placeholder$="[[placeholder]]" + readonly$="[[readonly]]" + required$="[[required]]" + minlength$="[[minlength]]" + maxlength$="[[maxlength]]" + autocapitalize$="[[autocapitalize]]" + rows$="[[rows]]" + max-rows$="[[maxRows]]" + on-change="_onChange"></iron-autogrow-textarea> + + <template is="dom-if" if="[[errorMessage]]"> + <paper-input-error>[[errorMessage]]</paper-input-error> + </template> + + <template is="dom-if" if="[[charCounter]]"> + <paper-input-char-counter></paper-input-char-counter> + </template> + + </paper-input-container> + </template> +</dom-module> + +<script> + Polymer({ + is: 'paper-textarea', + + behaviors: [ + Polymer.PaperInputBehavior, + Polymer.IronFormElementBehavior + ], + + properties: { + _ariaLabelledBy: { + observer: '_ariaLabelledByChanged', + type: String + }, + + _ariaDescribedBy: { + observer: '_ariaDescribedByChanged', + type: String + }, + + /** + * The initial number of rows. + * + * @attribute rows + * @type number + * @default 1 + */ + rows: { + type: Number, + value: 1 + }, + + /** + * The maximum number of rows this element can grow to until it + * scrolls. 0 means no maximum. + * + * @attribute maxRows + * @type number + * @default 0 + */ + maxRows: { + type: Number, + value: 0 + } + }, + + _ariaLabelledByChanged: function(ariaLabelledBy) { + this.$.input.textarea.setAttribute('aria-labelledby', ariaLabelledBy); + }, + + _ariaDescribedByChanged: function(ariaDescribedBy) { + this.$.input.textarea.setAttribute('aria-describedby', ariaDescribedBy); + }, + + get _focusableElement() { + return this.$.input.textarea; + }, + }); +</script> diff --git a/catapult/third_party/polymer/components/paper-input/test/index.html b/catapult/third_party/polymer/components/paper-input/test/index.html new file mode 100644 index 00000000..48aa82fd --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/index.html @@ -0,0 +1,32 @@ +<!DOCTYPE html><!-- +@license +Copyright (c) 2014 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--><html><head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> + <title>paper-input tests</title> + <script src="../../web-component-tester/browser.js"></script> +</head> +<body> + <script> + WCT.loadSuites([ + 'paper-input.html', + 'paper-textarea.html', + 'paper-input-container.html', + 'paper-input-error.html', + 'paper-input-char-counter.html', + 'paper-input.html?dom=shadow', + 'paper-textarea.html?dom=shadow', + 'paper-input-container.html?dom=shadow', + 'paper-input-error.html?dom=shadow', + 'paper-input-char-counter.html?dom=shadow' + ]); + </script> + + +</body></html> diff --git a/catapult/third_party/polymer/components/paper-input/test/letters-only.html b/catapult/third_party/polymer/components/paper-input/test/letters-only.html new file mode 100644 index 00000000..bfc301c3 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/letters-only.html @@ -0,0 +1,30 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<link rel="import" href="../../polymer/polymer.html"> +<link rel="import" href="../../iron-validator-behavior/iron-validator-behavior.html"> + +<script> + + Polymer({ + + is: 'letters-only', + + behaviors: [ + Polymer.IronValidatorBehavior + ], + + validate: function(value) { + return !value || value.match(/^[a-zA-Z]*$/) !== null; + } + + }); + +</script> diff --git a/catapult/third_party/polymer/components/paper-input/test/paper-input-char-counter.html b/catapult/third_party/polymer/components/paper-input/test/paper-input-char-counter.html new file mode 100644 index 00000000..65d2d140 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/paper-input-char-counter.html @@ -0,0 +1,109 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + + <title>paper-input-counter tests</title> + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> + + <script src="../../webcomponentsjs/webcomponents-lite.js"></script> + + <script src="../../web-component-tester/browser.js"></script> + <script src="../../iron-test-helpers/test-helpers.js"></script> + + <link rel="import" href="../../iron-input/iron-input.html"> + <link rel="import" href="../paper-input-container.html"> + <link rel="import" href="../paper-input-char-counter.html"> + <link rel="import" href="../paper-textarea.html"> + +</head> +<body> + + <test-fixture id="counter"> + <template> + <paper-input-container> + <label id="l">label</label> + <input id="i" value="foobar"> + <paper-input-char-counter id="c"></paper-input-char-counter> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="counter-with-max"> + <template> + <paper-input-container> + <label id="l">label</label> + <input id="i" value="foobar" maxlength="10"> + <paper-input-char-counter id="c"></paper-input-char-counter> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="textarea"> + <template> + <paper-textarea char-counter value="foobar"></paper-textarea> + </template> + </test-fixture> + + <test-fixture id="textarea-with-max"> + <template> + <paper-textarea char-counter value="foobar" maxlength="100"></paper-textarea> + </template> + </test-fixture> + + <script> + + suite('basic', function() { + + test('character counter shows the value length', function() { + var container = fixture('counter'); + var input = Polymer.dom(container).querySelector('#i'); + var counter = Polymer.dom(container).querySelector('#c'); + assert.equal(counter._charCounterStr, input.value.length, 'character counter shows input value length'); + }); + + test('character counter shows the value length with maxlength', function() { + var container = fixture('counter-with-max'); + var input = Polymer.dom(container).querySelector('#i'); + var counter = Polymer.dom(container).querySelector('#c'); + assert.equal(counter._charCounterStr, input.value.length + '/' + input.maxLength, 'character counter shows input value length and maxLength'); + }); + + test('character counter shows the value length with maxlength', function() { + var input = fixture('textarea-with-max'); + forceXIfStamp(input); + + var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter'); + assert.ok(counter, 'paper-input-char-counter exists'); + + assert.equal(counter._charCounterStr, input.value.length + '/' + input.inputElement.textarea.getAttribute('maxlength'), 'character counter shows input value length and maxLength'); + }); + + test('character counter counts new lines in textareas correctly', function() { + var input = fixture('textarea'); + input.value = 'foo\nbar'; + forceXIfStamp(input); + + var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter') + assert.ok(counter, 'paper-input-char-counter exists'); + + assert.equal(counter._charCounterStr, input.value.length, 'character counter shows the value length'); + }); + + }); + + </script> + +</body> +</html> diff --git a/catapult/third_party/polymer/components/paper-input/test/paper-input-container.html b/catapult/third_party/polymer/components/paper-input/test/paper-input-container.html new file mode 100644 index 00000000..6af730d2 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/paper-input-container.html @@ -0,0 +1,333 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + + <title>paper-input-container tests</title> + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> + + <script src="../../webcomponentsjs/webcomponents-lite.js"></script> + + <script src="../../web-component-tester/browser.js"></script> + <script src="../../iron-test-helpers/mock-interactions.js"></script> + + <link rel="import" href="../../iron-input/iron-input.html"> + <link rel="import" href="../paper-input-container.html"> + <link rel="import" href="letters-only.html"> + +</head> +<body> + + <test-fixture id="basic"> + <template> + <paper-input-container> + <label id="l">label</label> + <input id="i"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="prefix"> + <template> + <paper-input-container> + <div prefix>$</div> + <label id="l">label</label> + <input is="iron-input" id="i"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="prefix-has-value"> + <template> + <paper-input-container> + <div prefix>$</div> + <label id="l">label</label> + <input is="iron-input" id="i" value="foo"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="has-value"> + <template> + <paper-input-container> + <label id="l">label</label> + <input id="i" value="value"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="no-float-has-value"> + <template> + <paper-input-container no-label-float> + <label id="l">label</label> + <input id="i" value="value"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="always-float"> + <template> + <paper-input-container always-float-label> + <label id="l">label</label> + <input id="i" value="value"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="auto-validate-numbers"> + <template> + <paper-input-container auto-validate> + <label id="l">label</label> + <input is="iron-input" id="i" pattern="[0-9]*"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="manual-validate-numbers"> + <template> + <paper-input-container> + <label id="l">label</label> + <input is="iron-input" id="i" pattern="[0-9]*"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="required-validate"> + <template> + <paper-input-container> + <label id="l">label</label> + <input is="iron-input" id="i" required> + </paper-input-container> + </template> + </test-fixture> + + <letters-only></letters-only> + + <test-fixture id="auto-validate-validator"> + <template> + <paper-input-container auto-validate> + <label id="l">label</label> + <input is="iron-input" id="i" pattern="[0-9]*" validator="letters-only"> + </paper-input-container> + </template> + </test-fixture> + + <test-fixture id="auto-validate-validator-has-invalid-value"> + <template> + <paper-input-container auto-validate> + <label id="l">label</label> + <input is="iron-input" id="i" validator="letters-only" value="123123"> + </paper-input-container> + </template> + </test-fixture> + + <script> + + function getTransform(node) { + var style = getComputedStyle(node); + return style.transform || style.webkitTransform; + } + + suite('basic', function() { + test('can be created imperatively', function() { + var container = document.createElement('paper-input-container'); + var input = document.createElement('input', 'iron-input'); + input.className = 'paper-input-input'; + input.id = 'input'; + + var label = document.createElement('label'); + label.innerHTML = 'label'; + + Polymer.dom(container).appendChild(label); + Polymer.dom(container).appendChild(input); + + document.body.appendChild(container); + assert.isOk(container); + document.body.removeChild(container); + }); + }); + + suite('label position', function() { + + test('label is visible by default', function() { + var container = fixture('basic'); + assert.equal(getComputedStyle(container.querySelector('#l')).visibility, 'visible', 'label has visibility:visible'); + }); + + test('label is floated if value is initialized to not null', function(done) { + var container = fixture('has-value'); + requestAnimationFrame(function() { + assert.notEqual(getTransform(container.querySelector('#l')), 'none', 'label has transform'); + done(); + }); + }); + + test('label is invisible if no-label-float and value is initialized to not null', function() { + var container = fixture('no-float-has-value'); + assert.equal(getComputedStyle(container.querySelector('#l')).visibility, 'hidden', 'label has visibility:hidden'); + }); + + test('label is floated if always-float-label is true', function() { + var container = fixture('always-float'); + assert.notEqual(getTransform(container.querySelector('#l')), 'none', 'label has transform'); + }); + + test('label is floated correctly with a prefix', function(done) { + var container = fixture('prefix'); + var label = Polymer.dom(container).querySelector('#l'); + var input = Polymer.dom(container).querySelector('#i'); + + // Label is initially visible. + assert.equal(getComputedStyle(label).visibility, 'visible', 'label has visibility:visible'); + + // After entering text, the label floats, and it is not indented. + input.bindValue = 'foobar'; + requestAnimationFrame(function() { + assert.notEqual(getTransform(label), 'none', 'label has transform'); + assert.equal(label.getBoundingClientRect().left, container.getBoundingClientRect().left); + done(); + }); + }); + + test('label is floated correctly with a prefix and prefilled value', function(done) { + var container = fixture('prefix-has-value'); + var label = Polymer.dom(container).querySelector('#l'); + + // The label floats, and it is not indented. + requestAnimationFrame(function() { + assert.notEqual(getTransform(label), 'none', 'label has transform'); + assert.equal(label.getBoundingClientRect().left, container.getBoundingClientRect().left); + done(); + }); + }); + + }); + + suite('focused styling', function() { + + test('label is colored when input is focused and has value', function(done) { + var container = fixture('has-value'); + var label = Polymer.dom(container).querySelector('#l'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + MockInteractions.focus(input); + requestAnimationFrame(function() { + assert.isTrue(container.focused, 'focused is true'); + assert.isTrue(inputContent.classList.contains('label-is-highlighted'), 'label is highlighted when input has focus'); + done(); + }); + }); + + test('label is not colored when input is focused and has null value', function(done) { + var container = fixture('basic'); + var label = Polymer.dom(container).querySelector('#l'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + MockInteractions.focus(input); + requestAnimationFrame(function() { + assert.isFalse(inputContent.classList.contains('label-is-highlighted'), 'label is not highlighted when input has focus and has null value'); + done(); + }); + }); + + test('underline is colored when input is focused', function(done) { + var container = fixture('basic'); + var input = Polymer.dom(container).querySelector('#i'); + var line = Polymer.dom(container.root).querySelector('.underline'); + assert.isFalse(line.classList.contains('is-highlighted'), 'line is not highlighted when input is not focused'); + MockInteractions.focus(input); + requestAnimationFrame(function() { + assert.isTrue(line.classList.contains('is-highlighted'), 'line is highlighted when input is focused'); + done(); + }); + }); + + test('focused class added to input content', function(done) { + var container = fixture('basic'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + assert.isFalse(inputContent.classList.contains('focused'), 'input content does not have class "focused" when input is not focused'); + MockInteractions.focus(input); + requestAnimationFrame(function() { + assert.isTrue(inputContent.classList.contains('focused'), 'input content has class "focused" when input is focused'); + done(); + }); + }); + + }); + + suite('validation', function() { + + test('styled when the input is set to an invalid value with auto-validate', function() { + var container = fixture('auto-validate-numbers'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + var line = Polymer.dom(container.root).querySelector('.underline'); + + input.bindValue = 'foobar'; + + assert.isTrue(container.invalid, 'invalid is true'); + assert.isTrue(inputContent.classList.contains('is-invalid'), 'label has invalid styling when input is invalid'); + assert.isTrue(line.classList.contains('is-invalid'), 'underline has invalid styling when input is invalid'); + }); + + test('styled when the input is set to an invalid value with auto-validate, with validator', function() { + var container = fixture('auto-validate-validator'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + var line = Polymer.dom(container.root).querySelector('.underline'); + + input.bindValue = '123123'; + + assert.isTrue(container.invalid, 'invalid is true'); + assert.isTrue(inputContent.classList.contains('is-invalid'), 'label has invalid styling when input is invalid'); + assert.isTrue(line.classList.contains('is-invalid'), 'underline has invalid styling when input is invalid'); + }); + + test('styled when the input is set initially to an invalid value with auto-validate, with validator', function() { + var container = fixture('auto-validate-validator-has-invalid-value'); + assert.isTrue(container.invalid, 'invalid is true'); + assert.isTrue(Polymer.dom(container.root).querySelector('.underline').classList.contains('is-invalid'), 'underline has is-invalid class'); + }); + + test('styled when the input is set to an invalid value with manual validation', function() { + var container = fixture('manual-validate-numbers'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + var line = Polymer.dom(container.root).querySelector('.underline'); + + input.bindValue = 'foobar'; + input.validate(); + + assert.isTrue(container.invalid, 'invalid is true'); + assert.isTrue(inputContent.classList.contains('is-invalid'), 'label has invalid styling when input is invalid'); + assert.isTrue(line.classList.contains('is-invalid'), 'underline has invalid styling when input is invalid'); + }); + + test('styled when the input is manually validated and required', function() { + var container = fixture('required-validate'); + var input = Polymer.dom(container).querySelector('#i'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + assert.isFalse(container.invalid, 'invalid is false'); + input.validate(); + assert.isTrue(container.invalid, 'invalid is true'); + assert.isTrue(inputContent.classList.contains('is-invalid'), 'input content has is-invalid class'); + }); + + }); + + </script> + +</body> +</html> diff --git a/catapult/third_party/polymer/components/paper-input/test/paper-input-error.html b/catapult/third_party/polymer/components/paper-input/test/paper-input-error.html new file mode 100644 index 00000000..9337a95e --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/paper-input-error.html @@ -0,0 +1,68 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + + <title>paper-input-error tests</title> + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> + + <script src="../../webcomponentsjs/webcomponents-lite.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <link rel="import" href="../../iron-input/iron-input.html"> + <link rel="import" href="../paper-input-container.html"> + <link rel="import" href="../paper-input-error.html"> + +</head> +<body> + + <paper-input-container id="container"> + <input is="iron-input"> + <paper-input-error>error</paper-input-error> + </paper-input-container> + + <test-fixture id="auto-validate-numbers"> + <template> + <paper-input-container auto-validate attr-for-value="bind-value"> + <label id="l">label</label> + <input is="iron-input" id="i" pattern="[0-9]*"> + <paper-input-error id="e">error</paper-input-error> + </paper-input-container> + </template> + </test-fixture> + + <script> + + suite('basic', function() { + + test('error message only appears when input is invalid', function() { + var container = fixture('auto-validate-numbers'); + var input = Polymer.dom(container).querySelector('#i'); + var error = Polymer.dom(container).querySelector('#e'); + assert.equal(getComputedStyle(error).visibility, 'hidden', 'error is visibility:hidden'); + input.bindValue = 'foobar'; + assert.notEqual(getComputedStyle(error).visibility, 'hidden', 'error is not visibility:hidden'); + }); + + test('error message add on is registered', function() { + var container = document.getElementById('container'); + assert.isTrue(container._addons && container._addons.length === 1, 'add on is registered'); + }); + + }); + + </script> + +</body> +</html> diff --git a/catapult/third_party/polymer/components/paper-input/test/paper-input.html b/catapult/third_party/polymer/components/paper-input/test/paper-input.html new file mode 100644 index 00000000..77f68c58 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/paper-input.html @@ -0,0 +1,398 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + + <title>paper-input tests</title> + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> + + <script src="../../webcomponentsjs/webcomponents-lite.js"></script> + + <script src="../../web-component-tester/browser.js"></script> + <script src="../../iron-test-helpers/test-helpers.js"></script> + <script src="../../iron-test-helpers/mock-interactions.js"></script> + + <link rel="import" href="../paper-input.html"> + <link rel="import" href="letters-only.html"> + +</head> +<body> + + <test-fixture id="basic"> + <template> + <paper-input></paper-input> + </template> + </test-fixture> + + <test-fixture id="has-tabindex"> + <template> + <paper-input tabindex="0"></paper-input> + </template> + </test-fixture> + + <test-fixture id="label"> + <template> + <paper-input label="foo"></paper-input> + </template> + </test-fixture> + + <test-fixture id="label-has-value"> + <template> + <paper-input label="foo" value="bar"></paper-input> + </template> + </test-fixture> + + <test-fixture id="error"> + <template> + <paper-input auto-validate pattern="[0-9]*" value="foobar" error-message="error"></paper-input> + </template> + </test-fixture> + + <test-fixture id="required"> + <template> + <paper-input auto-validate required error-message="error"></paper-input> + </template> + </test-fixture> + + <test-fixture id="required-no-auto-validate"> + <template> + <paper-input required error-message="error"></paper-input> + </template> + </test-fixture> + + <test-fixture id="required-char-counter"> + <template> + <paper-input auto-validate char-counter required error-message="error"></paper-input> + </template> + </test-fixture> + + <test-fixture id="char-counter"> + <template> + <paper-input char-counter value="foobar"></paper-input> + </template> + </test-fixture> + + <test-fixture id="type-number-char-counter"> + <template> + <paper-input type="number" char-counter value="1138"></paper-input> + </template> + </test-fixture> + + <test-fixture id="always-float-label"> + <template> + <paper-input always-float-label label="foo"></paper-input> + </template> + </test-fixture> + + <test-fixture id="placeholder"> + <template> + <paper-input label="foo" placeholder="bar"></paper-input> + </template> + </test-fixture> + + <test-fixture id="date"> + <template> + <paper-input label="foo" type="date"></paper-input> + </template> + </test-fixture> + + <letters-only></letters-only> + + <test-fixture id="validator"> + <template> + <paper-input value="123123" validator="letters-only" auto-validate></paper-input> + </template> + </test-fixture> + + <test-fixture id="multiple-inputs"> + <template> + <paper-input label="one"></paper-input> + <paper-input label="two"></paper-input> + <paper-input label="three"></paper-input> + <paper-input label="four"></paper-input> + </template> + </test-fixture> + + <script> + + suite('basic', function() { + + test('setting value sets the input value', function() { + var input = fixture('basic'); + input.value = 'foobar'; + assert.equal(input.inputElement.value, input.value, 'inputElement.value equals input.value'); + }); + + test('placeholder does not overlap label', function() { + var input = fixture('placeholder'); + assert.equal(input.inputElement.placeholder, input.placeholder, 'inputElement.placeholder equals input.placeholder'); + assert.equal(input.noLabelFloat, false); + var floatingLabel = Polymer.dom(Polymer.dom(input.root).querySelector('paper-input-container').root).querySelector('.label-is-floating'); + assert.ok(floatingLabel); + }); + + test('special types autofloat the label', function() { + var input = fixture('date'); + // Browsers that don't support special <input> types like `date` fallback + // to `text`, so make sure to only test if type is still preserved after + // the element is attached. + if (input.inputElement.type === "date") { + assert.equal(input.alwaysFloatLabel, true); + var floatingLabel = Polymer.dom(Polymer.dom(input.root).querySelector('paper-input-container').root).querySelector('.label-is-floating'); + assert.ok(floatingLabel); + } + }); + + test('always-float-label attribute works without placeholder', function() { + var input = fixture('always-float-label'); + var container = Polymer.dom(input.root).querySelector('paper-input-container'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + assert.isTrue(inputContent.classList.contains('label-is-floating'), 'label is floating'); + }); + + test('label does not receive pointer events', function() { + var input = fixture('always-float-label'); + var label = Polymer.dom(input.root).querySelector('label'); + assert.equal(getComputedStyle(label).pointerEvents, 'none'); + }); + + test('error message is displayed', function() { + var input = fixture('error'); + forceXIfStamp(input); + var error = Polymer.dom(input.root).querySelector('paper-input-error'); + assert.ok(error, 'paper-input-error exists'); + assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none'); + }); + + test('empty required input shows error', function() { + var input = fixture('required'); + forceXIfStamp(input); + var error = Polymer.dom(input.root).querySelector('paper-input-error'); + assert.ok(error, 'paper-input-error exists'); + assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none'); + }); + + test('character counter is displayed', function() { + var input = fixture('char-counter'); + forceXIfStamp(input); + var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter') + assert.ok(counter, 'paper-input-char-counter exists'); + assert.equal(counter._charCounterStr, input.value.length, 'character counter shows the value length'); + }); + + test('character counter is correct for type=number', function() { + var input = fixture('type-number-char-counter'); + forceXIfStamp(input); + var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter') + assert.ok(counter, 'paper-input-char-counter exists'); + assert.equal(counter._charCounterStr, input.value.toString().length, 'character counter shows the value length'); + }); + + test('validator is used', function() { + var input = fixture('validator'); + assert.ok(input.inputElement.invalid, 'input is invalid'); + }); + + test('caret position is preserved', function() { + var input = fixture('basic'); + var ironInput = Polymer.dom(input.root).querySelector('input[is="iron-input"]'); + input.value = 'nananana'; + ironInput.selectionStart = 2; + ironInput.selectionEnd = 2; + + input.updateValueAndPreserveCaret('nanananabatman'); + + assert.equal(ironInput.selectionStart, 2, 'selectionStart is preserved'); + assert.equal(ironInput.selectionEnd, 2, 'selectionEnd is preserved'); + }); + + test('setting autofocus to true implictly acquires focus', function(done) { + var input = fixture('basic'); + var inputFocusSpy = sinon.spy(input.inputElement, 'focus'); + window.setTimeout(function() { + assert(inputFocusSpy.called); + done(); + }, 50); + input.autofocus = true; + }); + + test('autofocus doesn\'t grab focus if another element already has it', function(done) { + var inputs = fixture('multiple-inputs'); + var inputFocusSpies = inputs.map(function(input) { + return sinon.spy(input.inputElement, 'focus'); + }); + window.setTimeout(function() { + assert(inputFocusSpies[0].called, 'first autofocus input with grabbed focus'); + assert(!inputFocusSpies[1].called, 'second autofocus input let first input keep focus'); + done(); + }, 50); + inputs[0].autofocus = true; + inputs[1].autofocus = true; // Shouldn't cause focus to change + }); + + }); + + suite('focus/blur events', function() { + var input; + + setup(function() { + input = fixture('basic'); + }); + + // At the moment, it is very hard to correctly fire exactly + // one focus/blur events on a paper-input. This is because + // when a paper-input is focused, it needs to focus + // its underlying native input, which will also fire a `blur` + // event. + test('focus events fired on host element', function() { + input.addEventListener('focus', function(event) { + assert(input.focused, 'input is focused'); + }); + MockInteractions.focus(input); + }); + + test('focus events fired on host element if nested element is focused', function() { + input.addEventListener('focus', function(event) { + assert(input.focused, 'input is focused'); + }); + MockInteractions.focus(input.inputElement); + }); + + test('blur events fired on host element', function() { + MockInteractions.focus(input); + input.addEventListener('blur', function(event) { + assert(!input.focused, 'input is blurred'); + }); + MockInteractions.blur(input); + }); + + test('blur events fired on host element nested element is blurred', function() { + MockInteractions.focus(input); + input.addEventListener('blur', function(event) { + assert(!input.focused, 'input is blurred'); + }); + MockInteractions.blur(input.inputElement); + }); + + test('focusing then bluring sets the focused attribute correctly', function() { + MockInteractions.focus(input); + assert(input.focused, 'input is focused'); + MockInteractions.blur(input); + assert(!input.focused, 'input is blurred'); + MockInteractions.focus(input.inputElement); + assert(input.focused, 'input is focused'); + MockInteractions.blur(input.inputElement); + assert(!input.focused, 'input is blurred'); + }); + + test('focusing then bluring with shift-tab removes the focused attribute correctly', function() { + MockInteractions.focus(input); + assert(input.focused, 'input is focused'); + + // Fake a shift-tab induced blur by forcing the flag. + input._shiftTabPressed = true; + MockInteractions.blur(input.inputElement); + assert(!input.focused, 'input is blurred'); + }); + }); + + suite('focused styling (integration test)', function() { + + test('underline is colored when input is focused', function(done) { + var input = fixture('basic'); + var container = Polymer.dom(input.root).querySelector('paper-input-container'); + var line = Polymer.dom(container.root).querySelector('.underline'); + assert.isFalse(line.classList.contains('is-highlighted'), 'line is not highlighted when input is not focused'); + MockInteractions.focus(input.inputElement); + requestAnimationFrame(function() { + assert.isTrue(line.classList.contains('is-highlighted'), 'line is highlighted when input is focused'); + done(); + }); + }); + + }); + + suite('validation', function() { + + test('invalid attribute updated after calling validate()', function() { + var input = fixture('required-no-auto-validate'); + forceXIfStamp(input); + input.validate(); + var error = Polymer.dom(input.root).querySelector('paper-input-error'); + assert.ok(error, 'paper-input-error exists'); + assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none'); + assert.isTrue(input.invalid, 'invalid is true'); + }); + + }); + + suite('a11y', function() { + test('has aria-labelledby, which is monotonically increasing', function() { + var inputs = fixture('multiple-inputs'); + + // Find the first index of the input in this fixture. Since the label + // ids monotonically increase every time a new input is created, and + // this fixture isn't the first one in the document, we're going to start + // at an ID > 1. + var firstLabel = Polymer.dom(inputs[0].root).querySelector('label').id; + var index = parseInt(firstLabel.substr(firstLabel.lastIndexOf('-') + 1)); + + for (var i = 0; i < inputs.length; i++ ) { + var input = inputs[i].inputElement; + var label = Polymer.dom(inputs[i].root).querySelector('label').id; + + assert.isTrue(input.hasAttribute('aria-labelledby')); + assert.equal(label, 'paper-input-label-' + (index++)); + assert.equal(input.getAttribute('aria-labelledby'), label); + } + }); + + test('has aria-describedby for error message', function() { + var input = fixture('required'); + forceXIfStamp(input); + assert.isTrue(input.inputElement.hasAttribute('aria-describedby')); + assert.equal(input.inputElement.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id, 'aria-describedby points to the error message'); + }); + + test('has aria-describedby for character counter', function() { + var input = fixture('char-counter'); + forceXIfStamp(input); + assert.isTrue(input.inputElement.hasAttribute('aria-describedby')); + assert.equal(input.inputElement.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the character counter'); + }); + + test('has aria-describedby for character counter and error', function() { + var input = fixture('required-char-counter'); + forceXIfStamp(input); + assert.isTrue(input.inputElement.hasAttribute('aria-describedby')); + assert.equal(input.inputElement.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id + ' ' + Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the error message and character counter'); + }); + + test('focus an input with tabindex', function(done) { + var input = fixture('has-tabindex'); + flush(function() { + MockInteractions.focus(input); + flush(function() { + assert.equal(input.shadowRoot ? input.shadowRoot.activeElement : + document.activeElement, input._focusableElement); + done(); + }); + }); + }); + }); + + </script> + +</body> +</html> diff --git a/catapult/third_party/polymer/components/paper-input/test/paper-textarea.html b/catapult/third_party/polymer/components/paper-input/test/paper-textarea.html new file mode 100644 index 00000000..f69e4ee7 --- /dev/null +++ b/catapult/third_party/polymer/components/paper-input/test/paper-textarea.html @@ -0,0 +1,233 @@ +<!doctype html> +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<html> +<head> + + <title>paper-textarea tests</title> + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> + + <script src="../../webcomponentsjs/webcomponents-lite.js"></script> + + <script src="../../web-component-tester/browser.js"></script> + <script src="../../iron-test-helpers/test-helpers.js"></script> + <script src="../../iron-test-helpers/mock-interactions.js"></script> + + <link rel="import" href="../paper-textarea.html"> +</head> +<body> + + <test-fixture id="basic"> + <template> + <paper-textarea></paper-textarea> + </template> + </test-fixture> + + <test-fixture id="label"> + <template> + <paper-textarea label="foo"></paper-textarea> + </template> + </test-fixture> + + <test-fixture id="char-counter"> + <template> + <paper-textarea char-counter></paper-textarea> + </template> + </test-fixture> + + <test-fixture id="required"> + <template> + <paper-textarea auto-validate required error-message="error"></paper-textarea> + </template> + </test-fixture> + + <test-fixture id="required-char-counter"> + <template> + <paper-textarea auto-validate char-counter required error-message="error"></paper-textarea> + </template> + </test-fixture> + + <test-fixture id="always-float-label"> + <template> + <paper-textarea always-float-label label="label"></paper-textarea> + </template> + </test-fixture> + + <script> + + suite('basic', function() { + + test('setting value sets the input value', function() { + var input = fixture('basic'); + input.value = 'foobar'; + assert.equal(input.inputElement.bindValue, input.value, 'inputElement value equals input.value'); + }); + + test('empty required input shows error', function() { + var input = fixture('required'); + forceXIfStamp(input); + var error = Polymer.dom(input.root).querySelector('paper-input-error'); + assert.ok(error, 'paper-input-error exists'); + assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none'); + }); + + test('caret position is preserved', function() { + var input = fixture('basic'); + var ironTextarea = Polymer.dom(input.root).querySelector('iron-autogrow-textarea'); + input.value = 'nananana'; + ironTextarea.selectionStart = 2; + ironTextarea.selectionEnd = 2; + + input.updateValueAndPreserveCaret('nanananabatman'); + + assert.equal(ironTextarea.selectionStart, 2, 'selectionStart is preserved'); + assert.equal(ironTextarea.selectionEnd, 2, 'selectionEnd is preserved'); + }); + + test('input attributes are bound to textarea', function() { + var input = fixture('basic'); + var attrs = { + 'autocomplete': 'true', + 'autofocus': true, + 'inputmode': 'number', + 'name': 'foo', + 'placeholder': 'bar', + 'readonly': true, + 'required': true, + 'maxlength': 3 + }; + for (var attr in attrs) { + input[attr] = attrs[attr]; + } + for (var attr in attrs) { + var inputAttr = input.inputElement.getAttribute(attr); + if (typeof attrs[attr] === 'boolean') { + assert.equal(inputAttr !== null, attrs[attr], 'attribute "' + attr + '" is equal to property (' + attrs[attr] + ', ' + inputAttr !== null + ')'); + } else { + assert.equal(inputAttr, attrs[attr], 'attribute "' + attr + '" is equal to property (' + attrs[attr] + ', ' + inputAttr + ')'); + } + } + }); + + test('always-float-label attribute works', function() { + var input = fixture('always-float-label'); + var container = Polymer.dom(input.root).querySelector('paper-input-container'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + assert.isTrue(inputContent.classList.contains('label-is-floating'), 'label is floating'); + }); + + test('label does not receive pointer events', function() { + var input = fixture('always-float-label'); + var label = Polymer.dom(input.root).querySelector('label'); + assert.equal(getComputedStyle(label).pointerEvents, 'none'); + }); + + test('no extra space between input and underline', function() { + var input = fixture('label'); + var container = Polymer.dom(input.root).querySelector('paper-input-container'); + var inputContent = Polymer.dom(container.root).querySelector('.input-content'); + var ironTextarea = Polymer.dom(input.root).querySelector('iron-autogrow-textarea'); + assert.equal(inputContent.clientHeight,ironTextarea.clientHeight, 'container and textarea are same height'); + }); + }); + + suite('focus/blur events', function() { + var input; + + setup(function() { + input = fixture('basic'); + }); + + // At the moment, it is very hard to correctly fire exactly + // one focus/blur events on a paper-textarea. This is because + // when a paper-textarea is focused, it needs to focus + // its underlying native textarea, which will also fire a `blur` + // event. + test('focus events fired on host element', function() { + input.addEventListener('focus', function(event) { + assert(input.focused, 'input is focused'); + }); + MockInteractions.focus(input); + }); + + test('focus events fired on host element if nested element is focused', function() { + input.addEventListener('focus', function(event) { + assert(input.focused, 'input is focused'); + }); + MockInteractions.focus(input.inputElement.textarea); + }); + + test('blur events fired on host element', function() { + MockInteractions.focus(input); + input.addEventListener('blur', function(event) { + assert(!input.focused, 'input is blurred'); + }); + MockInteractions.blur(input); + }); + + test('blur events fired on host element nested element is blurred', function() { + MockInteractions.focus(input); + input.addEventListener('blur', function(event) { + assert(!input.focused, 'input is blurred'); + }); + MockInteractions.blur(input.inputElement.textarea); + }); + + test('focusing then bluring sets the focused attribute correctly', function() { + MockInteractions.focus(input); + assert(input.focused, 'input is focused'); + MockInteractions.blur(input); + assert(!input.focused, 'input is blurred'); + MockInteractions.focus(input.inputElement.textarea); + assert(input.focused, 'input is focused'); + MockInteractions.blur(input.inputElement.textarea); + assert(!input.focused, 'input is blurred'); + }); + }); + + suite('a11y', function() { + + test('has aria-labelledby', function() { + var input = fixture('label'); + assert.isTrue(input.inputElement.textarea.hasAttribute('aria-labelledby')) + assert.equal(input.inputElement.textarea.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label'); + }); + + test('has aria-describedby for error message', function() { + var input = fixture('required'); + forceXIfStamp(input); + assert.isTrue(input.inputElement.textarea.hasAttribute('aria-describedby')); + assert.equal(input.inputElement.textarea.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id, 'aria-describedby points to the error message'); + }); + + test('has aria-describedby for character counter', function() { + var input = fixture('char-counter'); + forceXIfStamp(input); + assert.isTrue(input.inputElement.textarea.hasAttribute('aria-describedby')); + assert.equal(input.inputElement.textarea.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the character counter'); + }); + + test('has aria-describedby for character counter and error', function() { + var input = fixture('required-char-counter'); + forceXIfStamp(input); + assert.isTrue(input.inputElement.textarea.hasAttribute('aria-describedby')); + assert.equal(input.inputElement.textarea.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id + ' ' + Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the error message and character counter'); + }); + + }); + + + </script> + +</body> +</html> |