Commit a53fbbed96fcc8f0b7c558dcaa21da58c57b1264

Authored by Renato De Donato
1 parent 0549043e

select-dataset new interface

Showing 63 changed files with 3886 additions and 886 deletions
bower_components/iron-list/.bower.json 100755 → 100644
... ... @@ -7,43 +7,52 @@
7 7 "list",
8 8 "virtual-list"
9 9 ],
10   - "version": "1.1.5",
  10 + "version": "1.2.8",
11 11 "homepage": "https://github.com/PolymerElements/iron-list",
12 12 "authors": [
13 13 "The Polymer Authors"
14 14 ],
  15 + "repository": {
  16 + "type": "git",
  17 + "url": "git://github.com/PolymerElements/iron-list"
  18 + },
15 19 "main": "iron-list.html",
16 20 "license": "http://polymer.github.io/LICENSE.txt",
17 21 "ignore": [],
18 22 "dependencies": {
19 23 "polymer": "Polymer/polymer#^1.1.0",
20   - "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0"
  24 + "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
  25 + "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0",
  26 + "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#^1.0.0"
21 27 },
22 28 "devDependencies": {
  29 + "app-layout": "PolymerLabs/app-layout#master",
23 30 "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
24 31 "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
25   - "paper-scroll-header-panel": "polymerelements/paper-scroll-header-panel#^1.0.0",
  32 + "iron-ajax": "polymerelements/iron-ajax#^1.0.0",
  33 + "iron-icon": "polymerelements/iron-icon#^1.0.0",
  34 + "iron-icons": "polymerelements/iron-icons#^1.0.0",
  35 + "iron-scroll-threshold": "polymerelements/iron-scroll-threshold#^1.0.0",
  36 + "iron-image": "polymerelements/iron-image#^1.0.0",
26 37 "paper-menu": "polymerelements/paper-menu#^1.0.0",
27 38 "paper-item": "polymerelements/paper-item#^1.0.0",
28 39 "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0",
29 40 "paper-button": "polymerelements/paper-button#^1.0.0",
30   - "iron-ajax": "polymerelements/iron-ajax#^1.0.0",
31   - "iron-icon": "polymerelements/iron-icon#^1.0.0",
32   - "iron-icons": "polymerelements/iron-icons#^1.0.0",
33 41 "paper-badge": "polymerelements/paper-badge#^1.0.0",
34   - "paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
  42 + "paper-spinner": "polymerelements/paper-spinner#^1.0.0",
35 43 "test-fixture": "polymerelements/test-fixture#^1.0.0",
36 44 "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
37 45 "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.2",
38   - "web-component-tester": "*"
  46 + "web-component-tester": "^4.0.0"
39 47 },
40   - "_release": "1.1.5",
  48 + "_release": "1.2.8",
41 49 "_resolution": {
42 50 "type": "version",
43   - "tag": "v1.1.5",
44   - "commit": "c6bf7caf1745cc3bed0769d41ac405476ef981b8"
  51 + "tag": "v1.2.8",
  52 + "commit": "4d974edf5c2eca5646846910efcc0bacbbff647f"
45 53 },
46 54 "_source": "git://github.com/PolymerElements/iron-list.git",
47   - "_target": "^1.0.0",
48   - "_originalSource": "PolymerElements/iron-list"
  55 + "_target": "~1.2.8",
  56 + "_originalSource": "PolymerElements/iron-list",
  57 + "_direct": true
49 58 }
50 59 \ No newline at end of file
... ...
bower_components/iron-list/.gitignore 100755 → 100644
bower_components/iron-list/.travis.yml 0 → 100644
  1 +language: node_js
  2 +sudo: false
  3 +before_script:
  4 + - npm install -g bower polylint web-component-tester
  5 + - bower install
  6 + - polylint
  7 +env:
  8 + global:
  9 + - secure: qC9ustzA7LUlOLi34bsHNYQRkTMd8/KLNTXGGscSgWmSTb2bgyngdWOuIjA6qVvfaHrB/CygMiy17QJn0IeKD18yfGJHu17vYxDy4WW628An3C3VIgXO4F4+LzyDFuoHfK3eQYHrBKh6M8JvG6CVU/QYdOrzuwDtcOkZIEA72N8rj5bROcPygmHZsa/0cjz7Q29lseiI1qpPxcQPMADoJfD4BvnMD7kyJJTkLyq4UDySaWmC8GT6C8PIXeZI8uLQFOc47TQqFnGJg3H6luQoOC5wQ3uv4gBWbek5pY/GAXieDNvuXAdi7cvRziCuW4oG+cYg8NYZCBI7VkMcYhEA7wNzhhcb+OPt5eOgV0YPZjyVRhXktc+ikRQYi2UU9ig66UlJFMRuNcz9al6AAKa4La5Msalv8dJnLc896qebs9eWTN5uAn4QvOJ3KHtuBNppJtJVDi1GLdIWDZgad0paklGyyln0FRwBiQauiOsuvynJBk2H97f/45l95ExEpTNPzpu3rVXkSd5xF8UYzFvw0Fb1gYQa3kNKM10leHQvr+WfQ9t1xfpGpCkPC1YOVFS9HSipBLKGmeFkl3Xa+bMSF+lrEPSHMNTN02Tq1FfIJGOlHTeRhahLldWw0REZZ5xXyzdGa8HKt7gA0aktrkYbFbJNjciN68I+bGqMt3U2KZw=
  10 + - secure: vj29+8qXACt2RY0sK0Qk1Mf8XM5pgDDeJBqzoSyNxGAYL08BQAHQvXNv/2qWfSfA4b1HxleERsN2X4+b3mOAyWpKDAOcOABptpdI3qAQsZFOC1Qslz/vqHQBqIphZhiaxd1nVg02xJgrCt6Pk3sW8k7mj2cSH0q9JorWTch3fBWq4pLtzm0b/XEgyw2AbSAM0KUj18BCg9u0hJzrI+kVpenzegdrT3oNU3LYFSz2BgfMKKsuRtaJsMbnlfBhUKNUgfwp9FenvnztGWE3h+ZCK/1zUf0FsedH6s3OWF7U6dALv4AQlgwBKH8TmwVz82bvFpHaqCjy9bhrWbW/kYG+UYCeDg2C1DOAyjr4E42iIiGB/1QKTKCuGplVf2dzYxmozOcJGf7qa440WMfuHSccp5DWH++nEDnjrog1m1uw3GltQuSpJo6LkegwP5R0jHkZxx6K7ssaJWi3VEmwItenecsxvJTDUPn9sR1CQwID82XEc3qCapzXNZIM9UGty9dir79MFmF2oOMzKZhOD9cRt+DLm3s5btM5Nn52bDDw9rZ5XtNY9rFBChszCqZeA/S4v6Iogw8LS9uliLtcY6J8wA7m9bH0ZTjZ1cSXqXsgwovGOprPyggRsmJHD8IQqjBxsslq8/IsPoh7H9ZBSipwROXVjDDYTwsCyf9Nn5/mS2c=
  11 + - CXX=g++-4.8
  12 +node_js: stable
  13 +addons:
  14 + firefox: latest
  15 + apt:
  16 + sources:
  17 + - google-chrome
  18 + - ubuntu-toolchain-r-test
  19 + packages:
  20 + - google-chrome-stable
  21 + - g++-4.8
  22 + sauce_connect: true
  23 +script:
  24 + - "xvfb-run -s '-screen 0 1024x768x24' wct"
  25 + - "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then wct -s 'default'; fi"
... ...
bower_components/iron-list/CONTRIBUTING.md 0 → 100644
  1 +
  2 +<!--
  3 +This file is autogenerated based on
  4 +https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
  5 +
  6 +If you edit that file, it will get updated everywhere else.
  7 +If you edit this file, your changes will get overridden :)
  8 +
  9 +You can however override the jsbin link with one that's customized to this
  10 +specific element:
  11 +
  12 +jsbin=https://jsbin.com/cagaye/edit?html,output
  13 +-->
  14 +# Polymer Elements
  15 +## Guide for Contributors
  16 +
  17 +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:
  18 +
  19 +### Filing Issues
  20 +
  21 +**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:
  22 +
  23 + 1. **Who will use the feature?** _“As someone filling out a form…”_
  24 + 2. **When will they use the feature?** _“When I enter an invalid value…”_
  25 + 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
  26 +
  27 +**If you are filing an issue to report a bug**, please provide:
  28 +
  29 + 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
  30 +
  31 + ```markdown
  32 + The `paper-foo` element causes the page to turn pink when clicked.
  33 +
  34 + ## Expected outcome
  35 +
  36 + The page stays the same color.
  37 +
  38 + ## Actual outcome
  39 +
  40 + The page turns pink.
  41 +
  42 + ## Steps to reproduce
  43 +
  44 + 1. Put a `paper-foo` element in the page.
  45 + 2. Open the page in a web browser.
  46 + 3. Click the `paper-foo` element.
  47 + ```
  48 +
  49 + 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).
  50 +
  51 + 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
  52 +
  53 +### Submitting Pull Requests
  54 +
  55 +**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.
  56 +
  57 +When submitting pull requests, please provide:
  58 +
  59 + 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:
  60 +
  61 + ```markdown
  62 + (For a single issue)
  63 + Fixes #20
  64 +
  65 + (For multiple issues)
  66 + Fixes #32, fixes #40
  67 + ```
  68 +
  69 + 2. **A succinct description of the design** used to fix any related issues. For example:
  70 +
  71 + ```markdown
  72 + This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
  73 + ```
  74 +
  75 + 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.
  76 +
  77 +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!
... ...
bower_components/iron-list/README.md 100755 → 100644
1   -iron-list
2   -========================
3 1  
4   -`iron-list` displays a virtual, *'infinite'* list. The template inside
  2 +<!---
  3 +
  4 +This README is automatically generated from the comments in these files:
  5 +iron-list.html
  6 +
  7 +Edit those files, and our readme bot will duplicate them over here!
  8 +Edit this file, and the bot will squash your changes :)
  9 +
  10 +The bot does some handling of markdown. Please file a bug if it does the wrong
  11 +thing! https://github.com/PolymerLabs/tedium/issues
  12 +
  13 +-->
  14 +
  15 +[![Build status](https://travis-ci.org/PolymerElements/iron-list.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-list)
  16 +
  17 +_[Demo and API docs](https://elements.polymer-project.org/elements/iron-list)_
  18 +
  19 +
  20 +##&lt;iron-list&gt;
  21 +
  22 +`iron-list` displays a virtual, 'infinite' list. The template inside
5 23 the iron-list element represents the DOM to create for each list item.
6 24 The `items` property specifies an array of list item data.
7 25  
... ... @@ -13,7 +31,7 @@ be reused with a new model at any time. Particularly, any state that may change
13 31 as the result of a user interaction with the list item must be bound to the model
14 32 to avoid view state inconsistency.
15 33  
16   -__Important:__ `iron-list` must ether be explicitly sized, or delegate scrolling to an
  34 +__Important:__ `iron-list` must either be explicitly sized, or delegate scrolling to an
17 35 explicitly sized parent. By "explicitly sized", we mean it either has an explicit
18 36 CSS `height` property set via a class or inline style, or else is sized by other
19 37 layout means (e.g. the `flex` or `fit` classes).
... ... @@ -24,10 +42,10 @@ List item templates should bind to template models of the following structure:
24 42  
25 43 ```js
26 44 {
27   - index: 0, // data index for this item
28   - item: { // user data corresponding to items[index]
29   - /* user item data */
30   - }
  45 + index: 0, // index in the item array
  46 + selected: false, // true if the current item is selected
  47 + tabIndex: -1, // a dynamically generated tabIndex for focus management
  48 + item: {} // user data corresponding to items[index]
31 49 }
32 50 ```
33 51  
... ... @@ -56,30 +74,33 @@ bound from the model object provided to the template scope):
56 74 <iron-list items="[[data]]" as="item">
57 75 <template>
58 76 <div>
59   - Name: <span>[[item.name]]</span>
  77 + Name: [[item.name]]
60 78 </div>
61 79 </template>
62 80 </iron-list>
63 81 </template>
64 82 ```
65 83  
66   -### Resizing
  84 +### Accessibility
67 85  
68   -`iron-list` lays out the items when it recives a notification via the `iron-resize` event.
69   -This event is fired by any element that implements `IronResizableBehavior`.
  86 +`iron-list` automatically manages the focus state for the items. It also provides
  87 +a `tabIndex` property within the template scope that can be used for keyboard navigation.
  88 +For example, users can press the up and down keys to move to previous and next
  89 +items in the list:
70 90  
71   -By default, elements such as `iron-pages`, `paper-tabs` or `paper-dialog` will trigger
72   -this event automatically. If you hide the list manually (e.g. you use `display: none`)
73   -you might want to implement `IronResizableBehavior` or fire this event manually right
74   -after the list became visible again. e.g.
75   -
76   -```js
77   -document.querySelector('iron-list').fire('iron-resize');
  91 +```html
  92 +<iron-list items="[[data]]" as="item">
  93 + <template>
  94 + <div tabindex$="[[tabIndex]]">
  95 + Name: [[item.name]]
  96 + </div>
  97 + </template>
  98 +</iron-list>
78 99 ```
79 100  
80 101 ### Styling
81 102  
82   -Use the `--iron-list-items-container` mixin to style the container of items, e.g.
  103 +You can use the `--iron-list-items-container` mixin to style the container of items:
83 104  
84 105 ```css
85 106 iron-list {
... ... @@ -89,8 +110,30 @@ iron-list {
89 110 }
90 111 ```
91 112  
  113 +### Resizing
  114 +
  115 +`iron-list` lays out the items when it receives a notification via the `iron-resize` event.
  116 +This event is fired by any element that implements `IronResizableBehavior`.
  117 +
  118 +By default, elements such as `iron-pages`, `paper-tabs` or `paper-dialog` will trigger
  119 +this event automatically. If you hide the list manually (e.g. you use `display: none`)
  120 +you might want to implement `IronResizableBehavior` or fire this event manually right
  121 +after the list became visible again. For example:
  122 +
  123 +```js
  124 +document.querySelector('iron-list').fire('iron-resize');
  125 +```
  126 +
92 127 ### When should `<iron-list>` be used?
93 128  
94   -`iron-list` should be used when a page has significantly more DOM nodes than the ones visible on the screen. e.g. the page has 500 nodes, but only 20 are visible at the time. This is why we refer to it as a `virtual` list. In this case, a `dom-repeat` will still create 500 nodes which could slow down the web app, but `iron-list` will only create 20.
  129 +`iron-list` should be used when a page has significantly more DOM nodes than the ones
  130 +visible on the screen. e.g. the page has 500 nodes, but only 20 are visible at the time.
  131 +This is why we refer to it as a `virtual` list. In this case, a `dom-repeat` will still
  132 +create 500 nodes which could slow down the web app, but `iron-list` will only create 20.
  133 +
  134 +However, having an `iron-list` does not mean that you can load all the data at once.
  135 +Say, you have a million records in the database, you want to split the data into pages
  136 +so you can bring a page at the time. The page could contain 500 items, and iron-list
  137 +will only render 20.
  138 +
95 139  
96   -However, having an `iron-list` does not mean that you can load all the data at once. Say, you have a million records in the database, you want to split the data into pages so you can bring a page at the time. The page could contain 500 items, and iron-list will only render 20.
... ...
bower_components/iron-list/bower.json 100755 → 100644
... ... @@ -7,34 +7,42 @@
7 7 "list",
8 8 "virtual-list"
9 9 ],
10   - "version": "1.1.5",
  10 + "version": "1.2.8",
11 11 "homepage": "https://github.com/PolymerElements/iron-list",
12 12 "authors": [
13 13 "The Polymer Authors"
14 14 ],
  15 + "repository": {
  16 + "type": "git",
  17 + "url": "git://github.com/PolymerElements/iron-list"
  18 + },
15 19 "main": "iron-list.html",
16 20 "license": "http://polymer.github.io/LICENSE.txt",
17 21 "ignore": [],
18 22 "dependencies": {
19 23 "polymer": "Polymer/polymer#^1.1.0",
20   - "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0"
  24 + "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
  25 + "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0",
  26 + "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#^1.0.0"
21 27 },
22 28 "devDependencies": {
  29 + "app-layout": "PolymerLabs/app-layout#master",
23 30 "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
24 31 "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
25   - "paper-scroll-header-panel": "polymerelements/paper-scroll-header-panel#^1.0.0",
  32 + "iron-ajax": "polymerelements/iron-ajax#^1.0.0",
  33 + "iron-icon": "polymerelements/iron-icon#^1.0.0",
  34 + "iron-icons": "polymerelements/iron-icons#^1.0.0",
  35 + "iron-scroll-threshold": "polymerelements/iron-scroll-threshold#^1.0.0",
  36 + "iron-image": "polymerelements/iron-image#^1.0.0",
26 37 "paper-menu": "polymerelements/paper-menu#^1.0.0",
27 38 "paper-item": "polymerelements/paper-item#^1.0.0",
28 39 "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0",
29 40 "paper-button": "polymerelements/paper-button#^1.0.0",
30   - "iron-ajax": "polymerelements/iron-ajax#^1.0.0",
31   - "iron-icon": "polymerelements/iron-icon#^1.0.0",
32   - "iron-icons": "polymerelements/iron-icons#^1.0.0",
33 41 "paper-badge": "polymerelements/paper-badge#^1.0.0",
34   - "paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
  42 + "paper-spinner": "polymerelements/paper-spinner#^1.0.0",
35 43 "test-fixture": "polymerelements/test-fixture#^1.0.0",
36 44 "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
37 45 "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.2",
38   - "web-component-tester": "*"
  46 + "web-component-tester": "^4.0.0"
39 47 }
40 48 }
... ...
bower_components/iron-list/demo/basic.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<!doctype html>
  12 +<html>
  13 +<head>
  14 +
  15 + <title>iron-list demo</title>
  16 +
  17 + <meta charset="utf-8">
  18 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no">
  19 + <meta name="mobile-web-app-capable" content="yes">
  20 + <meta name="apple-mobile-web-app-capable" content="yes">
  21 +
  22 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  23 +
  24 + <link rel="import" href="../../polymer/polymer.html">
  25 + <link rel="import" href="../../iron-flex-layout/iron-flex-layout.html">
  26 + <link rel="import" href="../../iron-ajax/iron-ajax.html">
  27 + <link rel="import" href="../iron-list.html">
  28 +
  29 + <style is="custom-style">
  30 +
  31 + iron-list {
  32 + @apply(--layout-fit);
  33 + }
  34 +
  35 + .item {
  36 + padding: 10px;
  37 + border-bottom: 1px solid #ccc;
  38 + }
  39 +
  40 + </style>
  41 +
  42 +</head>
  43 +<body unresolved>
  44 +
  45 + <template is="dom-bind">
  46 + <iron-ajax url="data/contacts.json" last-response="{{data}}" auto></iron-ajax>
  47 +
  48 + <iron-list items="[[data]]" as="item">
  49 + <template>
  50 + <div class="item">
  51 + <b>#[[index]] - [[item.name]]</b>
  52 + <p>[[item.longText]]</p>
  53 + </div>
  54 + </template>
  55 + </iron-list>
  56 +
  57 + </template>
  58 +
  59 +</body>
  60 +</html>
... ...
bower_components/iron-list/demo/collapse.html 100755 → 100644
... ... @@ -15,7 +15,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
15 15 <title>Collapsable items using iron-list</title>
16 16  
17 17 <meta charset="utf-8">
18   - <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  18 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no">
19 19 <meta name="mobile-web-app-capable" content="yes">
20 20 <meta name="apple-mobile-web-app-capable" content="yes">
21 21  
... ... @@ -23,13 +23,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
23 23  
24 24 <link rel="import" href="../../polymer/polymer.html">
25 25 <link rel="import" href="../../iron-flex-layout/iron-flex-layout.html">
26   - <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
27   - <link rel="import" href="../../paper-scroll-header-panel/paper-scroll-header-panel.html">
  26 + <link rel="import" href="../../app-layout/app-toolbar/app-toolbar.html">
28 27 <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
  28 + <link rel="import" href="../../paper-styles/color.html">
  29 + <link rel="import" href="../../paper-styles/typography.html">
29 30 <link rel="import" href="../../iron-ajax/iron-ajax.html">
30 31 <link rel="import" href="../../iron-icons/iron-icons.html">
  32 + <link rel="import" href="../../iron-image/iron-image.html">
31 33 <link rel="import" href="../iron-list.html">
32 34  
  35 + <style>
  36 + body {
  37 + background-color: #eee;
  38 + margin: 0;
  39 + padding: 0;
  40 + }
  41 + </style>
33 42 </head>
34 43 <body unresolved>
35 44  
... ... @@ -37,26 +46,28 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
37 46 <template>
38 47 <style>
39 48 :host {
40   - @apply(--layout-fit);
41   - @apply(--layout-vertical);
  49 + display: block;
42 50 @apply(--paper-font-common-base);
43 51 }
44 52  
45   - paper-toolbar {
46   - background: var(--google-green-700);
47   - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
  53 + app-toolbar {
  54 + background-color: var(--google-green-700);
  55 + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);
48 56 font-weight: bold;
  57 + color: white;
49 58 z-index: 1;
  59 + position: fixed;
  60 + top: 0;
  61 + left: 0;
  62 + right: 0;
50 63 }
51 64  
52   - paper-toolbar paper-icon-button {
  65 + app-toolbar paper-icon-button {
53 66 --paper-icon-button-ink-color: white;
54 67 }
55 68  
56 69 iron-list {
57   - background-color: var(--paper-grey-200, #eee);
58   - padding-top: 1px;
59   - padding-bottom: 16px;
  70 + padding-top: 64px;
60 71 --iron-list-items-container: {
61 72 max-width: 800px;
62 73 margin: auto;
... ... @@ -71,16 +82,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
71 82 padding: 20px;
72 83 background-color: white;
73 84 border: 1px solid #ddd;
74   -
75 85 cursor: pointer;
76 86 margin-bottom: 10px;
77 87 }
78 88  
79   - .item:focus {
80   - outline: 0;
81   - border-color: #666;
82   - }
83   -
84 89 .avatar {
85 90 height: 40px;
86 91 width: 40px;
... ... @@ -125,59 +130,76 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
125 130 .item.expanded:hover .longText::after {
126 131 content: ' [–]';
127 132 }
  133 +
  134 + .spacer {
  135 + @apply(--layout-flex);
  136 + }
  137 +
  138 + @media (max-width: 460px) {
  139 + paper-toolbar .bottom.title {
  140 + font-size: 14px;
  141 + }
  142 + }
128 143 </style>
  144 +
129 145 <iron-ajax url="data/contacts.json" last-response="{{items}}" auto></iron-ajax>
130   - <paper-toolbar>
131   - <paper-icon-button icon="arrow-back" alt="Back"></paper-icon-button>
132   - <div class="flex"></div>
133   - <paper-icon-button icon="search" alt="Search"></paper-icon-button>
134   - <paper-icon-button icon="more-vert" alt="More options"></paper-icon-button>
135   - <div class="bottom title">Collapsable items using iron-list</div>
136   - </paper-toolbar>
137   - <iron-list id="list" items="[[items]]" as="item">
138   - <template>
139   - <div on-tap="_collapseExpand">
140   - <div class$="[[getClassForItem(item, item.expanded)]]" tabindex="0">
141   - <img class="avatar" src="[[item.image]]">
142   - <div class="pad">
143   - <div class="primary">[[item.name]]</div>
144   - <div class="shortText">[[item.shortText]]</div>
145   - <div class="longText">[[item.longText]]</div>
146   - </div>
147   - <iron-icon icon$="[[iconForItem(item)]]"></iron-icon>
  146 +
  147 + <app-toolbar>
  148 + <div title>Collapsable items</div>
  149 + <paper-icon-button icon="search" alt="Search"></paper-icon-button>
  150 + <paper-icon-button icon="more-vert" alt="More options"></paper-icon-button>
  151 + </app-toolbar>
  152 +
  153 + <iron-list id="list" items="[[items]]" as="item" selection-enabled multi-selection>
  154 + <template>
  155 + <div>
  156 + <div class$="[[getClassForItem(item, selected)]]" tabindex$="[[tabIndex]]">
  157 + <iron-image class="avatar" sizing="contain" src="[[item.image]]"></iron-image>
  158 + <div class="pad">
  159 + <div class="primary">[[item.name]]</div>
  160 + <div class="shortText">[[item.shortText]]</div>
  161 + <div class="longText">[[item.longText]]</div>
148 162 </div>
  163 + <iron-icon icon$="[[iconForItem(item)]]"></iron-icon>
149 164 </div>
150   - </template>
151   - </iron-list>
  165 + </div>
  166 + </template>
  167 + </iron-list>
  168 +
152 169 </template>
  170 +
153 171 <script>
154   - HTMLImports.whenReady(function() {
  172 +
  173 + HTMLImports.whenReady(function() {
  174 +
155 175 Polymer({
156 176 is: 'x-collapse',
  177 +
157 178 properties: {
  179 +
158 180 items: {
159 181 type: Array
160 182 }
161   - },
162 183  
163   - _collapseExpand: function(e) {
164   - var list = this.$.list;
165   - var index = e.model.index;
166   - var isExpanded = list.items[index].expanded;
  184 + },
167 185  
168   - list.set('items.' + index + '.expanded', !isExpanded);
169   - list.updateSizeForItem(e.model.index);
  186 + attached: function() {
  187 + // Use the document element
  188 + this.$.list.scrollTarget = this.ownerDocument.documentElement;
170 189 },
171 190  
172 191 iconForItem: function(item) {
173 192 return item ? (item.integer < 50 ? 'star-border' : 'star') : '';
174 193 },
175 194  
176   - getClassForItem: function(item, expanded) {
177   - return expanded ? 'item expanded' : 'item';
  195 + getClassForItem: function(item, selected) {
  196 + return selected ? 'item expanded' : 'item';
178 197 }
  198 +
179 199 });
  200 +
180 201 });
  202 +
181 203 </script>
182 204 </dom-module>
183 205  
... ...
bower_components/iron-list/demo/data/contacts.json 100755 → 100644
bower_components/iron-list/demo/index.html 100755 → 100644
... ... @@ -9,13 +9,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
9 9 -->
10 10  
11 11 <!doctype html>
12   -<html>
  12 +<html id="html">
13 13 <head>
14 14  
15   - <title>iron-list and paper-scroll-header-panel demo</title>
  15 + <title>iron-list demo</title>
16 16  
17 17 <meta charset="utf-8">
18   - <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  18 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no">
19 19 <meta name="mobile-web-app-capable" content="yes">
20 20 <meta name="apple-mobile-web-app-capable" content="yes">
21 21  
... ... @@ -23,52 +23,77 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
23 23  
24 24 <link rel="import" href="../../polymer/polymer.html">
25 25 <link rel="import" href="../../iron-flex-layout/iron-flex-layout.html">
26   - <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
27   - <link rel="import" href="../../paper-scroll-header-panel/paper-scroll-header-panel.html">
  26 + <link rel="import" href="../../app-layout/app-header/app-header.html">
  27 + <link rel="import" href="../../app-layout/app-toolbar/app-toolbar.html">
  28 + <link rel="import" href="../../app-layout/app-scroll-effects/app-scroll-effects.html">
28 29 <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
29 30 <link rel="import" href="../../iron-ajax/iron-ajax.html">
30 31 <link rel="import" href="../../iron-icons/iron-icons.html">
  32 + <link rel="import" href="../../iron-image/iron-image.html">
31 33 <link rel="import" href="../iron-list.html">
32 34  
33 35 <style is="custom-style">
  36 + body {
  37 + @apply(--layout-fullbleed);
  38 + font-family: 'Roboto', 'Noto', sans-serif;
  39 + background-color: #eee;
  40 + }
34 41  
35   - paper-scroll-header-panel {
36   - @apply(--layout-fit);
37   - @apply(--layout-vertical);
38   - @apply(--paper-font-common-base);
  42 + app-header {
  43 + position: fixed;
  44 + top: 0;
  45 + left: 0;
  46 + right: 0;
  47 + z-index: 1;
  48 + background-color: #0b8043;
  49 + color: white;
  50 + --app-header-background-front-layer: {
  51 + background-color: #4285f4;
  52 + };
39 53 }
40 54  
41   - paper-toolbar.tall .title {
42   - font-size: 40px;
43   - margin-left: 60px;
  55 + app-header paper-icon-button {
  56 + --paper-icon-button-ink-color: white;
  57 + }
44 58  
45   - -webkit-transform-origin: left center;
46   - transform-origin: left center;
47   - overflow: visible;
  59 + [title] {
  60 + font-weight: 400;
  61 + margin: 0 0 0 50px;
48 62 }
49 63  
50   - paper-toolbar paper-icon-button {
51   - --paper-icon-button-ink-color: white;
  64 + [condensed-title] {
  65 + font-weight: 400;
  66 + margin-left: 30px;
  67 + }
  68 +
  69 + [condensed-title] i {
  70 + font-style: normal;
  71 + font-weight: 100;
  72 + }
  73 +
  74 + app-toolbar.tall {
  75 + height: 148px;
52 76 }
53 77  
54 78 iron-list {
55   - background-color: var(--paper-grey-200, #eee);
  79 + padding-top: 148px;
  80 + margin-top: 64px;
56 81 padding-bottom: 16px;
57 82 }
58 83  
59 84 .item {
60 85 @apply(--layout-horizontal);
61   -
62   - margin: 16px 16px 0 16px;
63 86 padding: 20px;
64 87 border-radius: 8px;
65 88 background-color: white;
66 89 border: 1px solid #ddd;
  90 + max-width: 800px;
  91 + margin: 16px auto 0 auto;
67 92 }
68 93  
69 94 .item:focus {
70 95 outline: 0;
71   - border-color: #666;
  96 + border-color: #333;
72 97 }
73 98  
74 99 .avatar {
... ... @@ -98,6 +123,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
98 123 color: gray;
99 124 }
100 125  
  126 + .spacer {
  127 + @apply(--layout-flex);
  128 + }
  129 +
101 130 </style>
102 131  
103 132 </head>
... ... @@ -106,47 +135,35 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
106 135 <template is="dom-bind">
107 136 <iron-ajax url="data/contacts.json" last-response="{{data}}" auto></iron-ajax>
108 137  
109   - <paper-scroll-header-panel class="fit" condenses keep-condensed-header>
110   - <paper-toolbar class="tall">
111   - <paper-icon-button icon="arrow-back" alt="Back"></paper-icon-button>
112   - <div class="flex"></div>
113   - <paper-icon-button icon="search" alt="Search"></paper-icon-button>
114   - <paper-icon-button icon="more-vert" alt="More options"></paper-icon-button>
115   - <div class="bottom title">iron-list</div>
116   - </paper-toolbar>
117   - <iron-list items="[[data]]" as="item">
  138 + <app-header condenses fixed effects="resize-title blend-background waterfall">
  139 + <app-toolbar>
  140 + <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
  141 + <h4 condensed-title>iron-list <i>&mdash; Demo</i></h4>
  142 + <paper-icon-button icon="search"></paper-icon-button>
  143 + <paper-icon-button icon="more-vert"></paper-icon-button>
  144 + </app-toolbar>
  145 + <app-toolbar class="tall">
  146 + <h1 title>iron-list</h1>
  147 + </app-toolbar>
  148 + </app-header>
  149 +
  150 + <!-- iron-list using the document scroll -->
  151 + <iron-list items="[[data]]" as="item" scroll-target="html">
118 152 <template>
119 153 <div>
120   - <div class="item">
121   - <img class="avatar" src="[[item.image]]">
  154 + <div class="item" tabindex$="[[tabIndex]]">
  155 + <iron-image class="avatar" sizing="contain" src="[[item.image]]"></iron-image>
122 156 <div class="pad">
123   - <div class="primary">[[item.name]]</div>
  157 + <div class="primary">[[item.name]] [[index]]</div>
124 158 <div class="secondary">[[item.shortText]]</div>
125 159 <div class="secondary dim">[[item.longText]]</div>
126 160 </div>
127   - <iron-icon icon$="[[iconForItem(item)]]"></iron-icon>
128 161 </div>
129 162 </div>
130 163 </template>
131 164 </iron-list>
132   - </paper-scroll-header-panel>
133   - </template>
134 165  
135   - <script>
136   -
137   - document.querySelector('template[is=dom-bind]').iconForItem = function(item) {
138   - return item ? (item.integer < 50 ? 'star-border' : 'star') : '';
139   - };
140   -
141   - document.addEventListener('paper-header-transform', function(event) {
142   - var title = this.querySelector('.title');
143   - var detail = event.detail;
144   - var deltaHeight = detail.height - detail.condensedHeight;
145   - var scale = Math.max(0.6, (deltaHeight - detail.y) / (deltaHeight / 0.4) + 0.6);
146   -
147   - Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
148   - });
  166 + </template>
149 167  
150   - </script>
151 168 </body>
152 169 </html>
... ...
bower_components/iron-list/demo/scroll-threshold.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<!doctype html>
  12 +<html id="html">
  13 +<head>
  14 +
  15 + <title>Load data using iron-scroll-threshold</title>
  16 +
  17 + <meta charset="utf-8">
  18 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no">
  19 + <meta name="mobile-web-app-capable" content="yes">
  20 + <meta name="apple-mobile-web-app-capable" content="yes">
  21 +
  22 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  23 +
  24 + <link rel="import" href="../../polymer/polymer.html">
  25 + <link rel="import" href="../../iron-flex-layout/iron-flex-layout.html">
  26 + <link rel="import" href="../../iron-scroll-threshold/iron-scroll-threshold.html">
  27 + <link rel="import" href="../../paper-styles/color.html">
  28 + <link rel="import" href="../../paper-styles/typography.html">
  29 + <link rel="import" href="../../app-layout/app-toolbar/app-toolbar.html">
  30 + <link rel="import" href="../../paper-spinner/paper-spinner.html">
  31 + <link rel="import" href="../../iron-ajax/iron-ajax.html">
  32 + <link rel="import" href="../../iron-icons/iron-icons.html">
  33 + <link rel="import" href="../iron-list.html">
  34 +
  35 + <style is="custom-style">
  36 +
  37 + body {
  38 + @apply(--paper-font-common-base);
  39 + margin: 0;
  40 + padding: 0;
  41 + background-color: #eee;
  42 + }
  43 +
  44 + app-toolbar {
  45 + position: fixed;
  46 + top: 0;
  47 + left: 0;
  48 + right: 0;
  49 + background: #F57C00;
  50 + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);
  51 + color: white;
  52 + z-index: 1;
  53 + font-weight: bold;
  54 + }
  55 +
  56 + .loadingIndicator {
  57 + text-align: center;
  58 + height: 40px;
  59 + }
  60 +
  61 + .loadingIndicator paper-spinner {
  62 + width: 20px;
  63 + height: 20px;
  64 + margin-right: 10px;
  65 + }
  66 +
  67 + iron-list {
  68 + padding-top: 64px;
  69 + padding-bottom: 16px;
  70 + --iron-list-items-container: {
  71 + max-width: 800px;
  72 + margin: auto;
  73 + margin-top: 60px;
  74 + margin-bottom: 10px;
  75 + };
  76 + }
  77 +
  78 + .personItem {
  79 + @apply(--layout-horizontal);
  80 +
  81 + margin: 16px 16px 0 16px;
  82 + padding: 20px;
  83 + border-radius: 8px;
  84 + background-color: white;
  85 + border: 1px solid #ddd;
  86 + }
  87 +
  88 + .pad {
  89 + padding: 0 16px;
  90 + @apply(--layout-flex);
  91 + @apply(--layout-vertical);
  92 + }
  93 +
  94 + .primary {
  95 + font-size: 16px;
  96 + font-weight: bold;
  97 + }
  98 +
  99 + .secondary {
  100 + font-size: 14px;
  101 + }
  102 +
  103 + .dim {
  104 + color: gray;
  105 + }
  106 +
  107 + .spacer {
  108 + @apply(--layout-flex);
  109 + }
  110 +
  111 + .index {
  112 + width: 30px;
  113 + }
  114 +
  115 + </style>
  116 +
  117 +</head>
  118 +<body unresolved>
  119 +
  120 + <template is="dom-bind" id="app">
  121 +
  122 + <iron-ajax id="ajax"
  123 + url="http://www.filltext.com/"
  124 + params='{"rows": "20", "delay": 1, "fname":"{firstName}", "lname": "{lastName}", "address": "{streetAddress}",
  125 + "city": "{city}", "state": "{usState|abb}", "zip": "{zip}", "business": "{business}", "index": "{index}"}'
  126 + handle-as="json"
  127 + loading="{{loadingPeople}}"
  128 + on-response="_didRespond">
  129 + </iron-ajax>
  130 +
  131 + <app-toolbar>
  132 + <div title>Load data using iron-scroll-threshold</div>
  133 + </app-toolbar>
  134 +
  135 + <iron-list id="list" items="[]" as="person" scroll-target="html">
  136 + <template>
  137 + <div>
  138 + <div class="personItem" tabindex$="[[tabIndex]]">
  139 + <div class="pad">
  140 + <div class="primary">[[person.fname]] [[person.lname]]</div>
  141 + <div class="secondary">[[person.address]] [[person.city]]</div>
  142 + <div class="secondary">[[person.city]], [[person.state]] [[person.zip]]</div>
  143 + <div class="secondary dim">[[person.business]]</div>
  144 + </div>
  145 + <iron-icon icon$="[[_iconForPerson(person)]]"></iron-icon>
  146 + </div>
  147 + </div>
  148 + </template>
  149 + </iron-list>
  150 +
  151 + <div class="loadingIndicator">
  152 + <paper-spinner active="{{loadingPeople}}"></paper-spinner> Fetching data
  153 + </div>
  154 +
  155 + <!-- this element will load more data when the user scrolls down and reached the lower threshold -->
  156 + <iron-scroll-threshold id="scrollTheshold"
  157 + lower-threshold="500"
  158 + on-lower-threshold="_loadMoreData"
  159 + scroll-target="html">
  160 + </iron-scroll-threshold>
  161 +
  162 + </template>
  163 +
  164 + <script>
  165 +
  166 + (function(scope) {
  167 +
  168 + scope._iconForPerson = function(person) {
  169 + return person.integer < 50 ? 'star-border' : 'star';
  170 + };
  171 +
  172 + scope._loadMoreData = function() {
  173 + scope.$.ajax.generateRequest();
  174 + };
  175 +
  176 + scope._didRespond = function(e) {
  177 + var people = e.detail.response;
  178 +
  179 + people.forEach(function(person) {
  180 + scope.$.list.push('items', person);
  181 + });
  182 + // Clear the lower threshold so we can load more data when the user scrolls down again.
  183 + scope.$.scrollTheshold.clearTriggers();
  184 + };
  185 +
  186 + })(document.querySelector('#app'));
  187 +
  188 + </script>
  189 +
  190 +</body>
  191 +</html>
... ...
bower_components/iron-list/demo/selection.html 100755 → 100644
... ... @@ -12,7 +12,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
12 12 <html>
13 13 <head>
14 14  
15   - <title>Selection</title>
  15 + <title>Select contacts</title>
16 16  
17 17 <meta charset="utf-8">
18 18 <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
... ... @@ -27,7 +27,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
27 27 <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
28 28 <link rel="import" href="../../iron-icon/iron-icon.html">
29 29 <link rel="import" href="../../iron-icons/iron-icons.html">
30   - <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
  30 + <link rel="import" href="../../paper-styles/color.html">
  31 + <link rel="import" href="../../paper-styles/typography.html">
  32 + <link rel="import" href="../../app-layout/app-toolbar/app-toolbar.html">
31 33 <link rel="import" href="../../paper-menu/paper-menu.html">
32 34 <link rel="import" href="../../paper-item/paper-item.html">
33 35 <link rel="import" href="../../paper-badge/paper-badge.html">
... ... @@ -36,27 +38,32 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
36 38 <dom-module id="x-app">
37 39  
38 40 <style>
39   -
40 41 :host {
41 42 @apply(--layout-fit);
42 43 @apply(--layout-vertical);
43 44 @apply(--paper-font-common-base);
44   -
45   - display: block;
46 45 font-family: sans-serif;
47 46 }
48 47  
49   - .toolbar {
  48 + app-toolbar {
50 49 background: var(--paper-pink-500);
51   - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
52   - font-weight: bold;
  50 + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);
  51 + color: white;
  52 + z-index: 1;
  53 + color: white;
  54 + --paper-toolbar-title: {
  55 + font-size: 16px;
  56 + line-height: 16px;
  57 + font-weight: bold;
  58 + margin-left: 0;
  59 + };
53 60 }
54 61  
55   - .toolbar paper-icon-button {
  62 + app-toolbar paper-icon-button {
56 63 --paper-icon-button-ink-color: white;
57 64 }
58 65  
59   - #itemsList,
  66 + #itemsList,
60 67 #selectedItemsList {
61 68 @apply(--layout-flex);
62 69 }
... ... @@ -78,8 +85,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
78 85 color: var(--paper-blue-600);
79 86 }
80 87  
81   - .item.selected:not(:focus) {
82   - background-color: var(--google-grey-100);
  88 + .item.selected {
  89 + background-color: var(--google-grey-300);
  90 + border-bottom: 1px solid #ccc;
83 91 }
84 92  
85 93 .avatar {
... ... @@ -87,7 +95,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
87 95 width: 40px;
88 96 border-radius: 20px;
89 97 box-sizing: border-box;
90   - background-color: #DDD;
  98 + background-color: #ddd;
91 99 }
92 100  
93 101 .pad {
... ... @@ -135,11 +143,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
135 143 position: relative;
136 144 }
137 145  
138   - paper-item:focus {
139   - outline: 0;
140   - background-color: #ddd;
141   - }
142   -
143 146 paper-item:hover::after {
144 147 content: "-";
145 148 width: 16px;
... ... @@ -164,48 +167,56 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
164 167 line-height: 50px;
165 168 }
166 169  
  170 + .twoColumns {
  171 + @apply(--layout-flex);
  172 + @apply(--layout-horizontal);
  173 + overflow: hidden;
  174 + }
  175 +
  176 + #starredView {
  177 + @apply(--layout-vertical);
  178 + }
  179 +
167 180 </style>
168 181  
169 182 <template>
170 183 <iron-ajax url="data/contacts.json" last-response="{{data}}" auto></iron-ajax>
171 184  
172   - <paper-toolbar class="toolbar">
173   - <div class="flex">Inbox</div>
174   - <div style="position: relative;">
  185 + <app-toolbar>
  186 + <div title>Selection using iron-list</div>
  187 + <div>
175 188 <paper-icon-button icon="icons:star" alt="Starred" on-tap="_toggleStarredView"></paper-icon-button>
176 189 <paper-badge label$="[[selectedItems.length]]"></paper-badge>
177 190 </div>
178   - </paper-toolbar>
179   - <div class="flex horizontal layout">
180   - <div class="flex vertical layout">
181   - <!-- Main List for the items -->
182   - <iron-list id="itemsList" items="[[data]]" selected-items="{{selectedItems}}" selection-enabled multi-selection>
183   - <template>
184   - <div>
185   - <div tabindex="0" aria-label$="[[_getAriaLabel(item, selected)]]" class$="[[_computedClass(selected)]]">
186   - <img class="avatar" src="[[item.image]]">
187   - <div class="pad">
188   - <div class="primary">
189   - <span>[[index]]</span>
190   - <span>[[item.name]]</span>
191   - </div>
192   - <div class="secondary dim">[[item.shortText]]</div>
  191 + </app-toolbar>
  192 +
  193 + <div class="twoColumns">
  194 + <!-- Main List for the items -->
  195 + <iron-list id="itemsList" items="[[data]]" selected-items="{{selectedItems}}" selection-enabled multi-selection>
  196 + <template>
  197 + <div>
  198 + <div tabindex$="[[tabIndex]]" aria-label$="Select/Deselect [[item.name]]" class$="[[_computedClass(selected)]]">
  199 + <img class="avatar" src="[[item.image]]">
  200 + <div class="pad">
  201 + <div class="primary">
  202 + [[item.name]]
193 203 </div>
194   - <iron-icon icon$="[[iconForItem(selected)]]" class="star"></iron-icon>
  204 + <div class="secondary dim">[[item.shortText]]</div>
195 205 </div>
196   - <div class="border"></div>
  206 + <iron-icon icon$="[[iconForItem(selected)]]" class="star"></iron-icon>
197 207 </div>
198   - </template>
199   - </iron-list>
200   - </div>
201   - <div id="starredView" class="vertical layout" hidden$="[[!showSelection]]">
  208 + <div class="border"></div>
  209 + </div>
  210 + </template>
  211 + </iron-list>
  212 + <div id="starredView" hidden$="[[!showSelection]]">
202 213 <template is="dom-if" if="[[!selectedItems.length]]">
203 214 <div class="noSelection">Select a contact</div>
204 215 </template>
205 216 <!-- List for the selected items -->
206 217 <iron-list id="selectedItemsList" items="[[selectedItems]]" hidden$="[[!selectedItems.length]]">
207 218 <template>
208   - <paper-item on-tap="_unselect" tabindex="0">[[item.name]]</paper-item>
  219 + <paper-item tabindex$="[[tabIndex]]" on-tap="_unselect" aria-label$="Deselect [[item.name]]">[[item.name]]</paper-item>
209 220 </template>
210 221 </iron-list>
211 222 </div>
... ... @@ -255,10 +266,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
255 266  
256 267 _showSelectionChanged: function() {
257 268 this.$.selectedItemsList.fire('resize');
258   - },
259   -
260   - _getAriaLabel: function(item, selected) {
261   - return selected ? 'Deselect ' + item.name : 'Select ' + item.name;
262 269 }
263 270 });
264 271  
... ... @@ -267,6 +274,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
267 274 </script>
268 275  
269 276 </head>
  277 +<style is="custom-style">
  278 + body {
  279 + @apply(--layout-fullbleed);
  280 + }
  281 +</style>
270 282 <body unresolved>
271 283  
272 284 <x-app></x-app>
... ...
bower_components/iron-list/index.html 100755 → 100644
bower_components/iron-list/iron-list.html 100755 → 100644
... ... @@ -10,6 +10,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
10 10  
11 11 <link rel="import" href="../polymer/polymer.html">
12 12 <link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
  13 +<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
  14 +<link rel="import" href="../iron-scroll-target-behavior/iron-scroll-target-behavior.html">
13 15  
14 16 <!--
15 17  
... ... @@ -25,7 +27,7 @@ be reused with a new model at any time. Particularly, any state that may change
25 27 as the result of a user interaction with the list item must be bound to the model
26 28 to avoid view state inconsistency.
27 29  
28   -__Important:__ `iron-list` must ether be explicitly sized, or delegate scrolling to an
  30 +__Important:__ `iron-list` must either be explicitly sized, or delegate scrolling to an
29 31 explicitly sized parent. By "explicitly sized", we mean it either has an explicit
30 32 CSS `height` property set via a class or inline style, or else is sized by other
31 33 layout means (e.g. the `flex` or `fit` classes).
... ... @@ -34,12 +36,14 @@ layout means (e.g. the `flex` or `fit` classes).
34 36  
35 37 List item templates should bind to template models of the following structure:
36 38  
37   - {
38   - index: 0, // data index for this item
39   - item: { // user data corresponding to items[index]
40   - /* user item data */
41   - }
42   - }
  39 +```js
  40 +{
  41 + index: 0, // index in the item array
  42 + selected: false, // true if the current item is selected
  43 + tabIndex: -1, // a dynamically generated tabIndex for focus management
  44 + item: {} // user data corresponding to items[index]
  45 +}
  46 +```
43 47  
44 48 Alternatively, you can change the property name used as data index by changing the
45 49 `indexAs` property. The `as` property defines the name of the variable to add to the binding
... ... @@ -49,54 +53,93 @@ For example, given the following `data` array:
49 53  
50 54 ##### data.json
51 55  
52   - [
53   - {"name": "Bob"},
54   - {"name": "Tim"},
55   - {"name": "Mike"}
56   - ]
  56 +```js
  57 +[
  58 + {"name": "Bob"},
  59 + {"name": "Tim"},
  60 + {"name": "Mike"}
  61 +]
  62 +```
57 63  
58 64 The following code would render the list (note the name and checked properties are
59 65 bound from the model object provided to the template scope):
60 66  
61   - <template is="dom-bind">
62   - <iron-ajax url="data.json" last-response="{{data}}" auto></iron-ajax>
63   - <iron-list items="[[data]]" as="item">
64   - <template>
65   - <div>
66   - Name: <span>[[item.name]]</span>
67   - </div>
68   - </template>
69   - </iron-list>
  67 +```html
  68 +<template is="dom-bind">
  69 + <iron-ajax url="data.json" last-response="{{data}}" auto></iron-ajax>
  70 + <iron-list items="[[data]]" as="item">
  71 + <template>
  72 + <div>
  73 + Name: [[item.name]]
  74 + </div>
70 75 </template>
  76 + </iron-list>
  77 +</template>
  78 +```
  79 +
  80 +### Accessibility
  81 +
  82 +`iron-list` automatically manages the focus state for the items. It also provides
  83 +a `tabIndex` property within the template scope that can be used for keyboard navigation.
  84 +For example, users can press the up and down keys to move to previous and next
  85 +items in the list:
  86 +
  87 +```html
  88 +<iron-list items="[[data]]" as="item">
  89 + <template>
  90 + <div tabindex$="[[tabIndex]]">
  91 + Name: [[item.name]]
  92 + </div>
  93 + </template>
  94 +</iron-list>
  95 +```
71 96  
72 97 ### Styling
73 98  
74   -Use the `--iron-list-items-container` mixin to style the container of items, e.g.
  99 +You can use the `--iron-list-items-container` mixin to style the container of items:
75 100  
76   - iron-list {
77   - --iron-list-items-container: {
78   - margin: auto;
79   - };
80   - }
  101 +```css
  102 +iron-list {
  103 + --iron-list-items-container: {
  104 + margin: auto;
  105 + };
  106 +}
  107 +```
81 108  
82 109 ### Resizing
83 110  
84   -`iron-list` lays out the items when it recives a notification via the `iron-resize` event.
  111 +`iron-list` lays out the items when it receives a notification via the `iron-resize` event.
85 112 This event is fired by any element that implements `IronResizableBehavior`.
86 113  
87 114 By default, elements such as `iron-pages`, `paper-tabs` or `paper-dialog` will trigger
88 115 this event automatically. If you hide the list manually (e.g. you use `display: none`)
89 116 you might want to implement `IronResizableBehavior` or fire this event manually right
90   -after the list became visible again. e.g.
  117 +after the list became visible again. For example:
91 118  
92   - document.querySelector('iron-list').fire('iron-resize');
  119 +```js
  120 +document.querySelector('iron-list').fire('iron-resize');
  121 +```
93 122  
  123 +### When should `<iron-list>` be used?
  124 +
  125 +`iron-list` should be used when a page has significantly more DOM nodes than the ones
  126 +visible on the screen. e.g. the page has 500 nodes, but only 20 are visible at the time.
  127 +This is why we refer to it as a `virtual` list. In this case, a `dom-repeat` will still
  128 +create 500 nodes which could slow down the web app, but `iron-list` will only create 20.
  129 +
  130 +However, having an `iron-list` does not mean that you can load all the data at once.
  131 +Say, you have a million records in the database, you want to split the data into pages
  132 +so you can bring a page at the time. The page could contain 500 items, and iron-list
  133 +will only render 20.
94 134  
95 135 @group Iron Element
96 136 @element iron-list
97   -@demo demo/index.html Simple list
98   -@demo demo/selection.html Selection of items
  137 +@demo demo/index.html List of cards
  138 +@demo demo/selection.html Items selection
99 139 @demo demo/collapse.html Collapsable items
  140 +@demo demo/scroll-threshold.html Scroll thesholds
  141 +@demo demo/basic.html Basic list
  142 +
100 143 -->
101 144  
102 145 <dom-module id="iron-list">
... ... @@ -104,14 +147,13 @@ after the list became visible again. e.g.
104 147 <style>
105 148 :host {
106 149 display: block;
  150 + position: relative;
107 151 }
108 152  
109   - :host(.has-scroller) {
110   - overflow: auto;
111   - }
112   -
113   - :host(:not(.has-scroller)) {
114   - position: relative;
  153 + @media only screen and (-webkit-max-device-pixel-ratio: 1) {
  154 + :host {
  155 + will-change: transform;
  156 + }
115 157 }
116 158  
117 159 #items {
... ... @@ -145,8 +187,9 @@ after the list became visible again. e.g.
145 187  
146 188 var IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/);
147 189 var IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8;
148   - var DEFAULT_PHYSICAL_COUNT = 20;
  190 + var DEFAULT_PHYSICAL_COUNT = 3;
149 191 var MAX_PHYSICAL_COUNT = 500;
  192 + var HIDDEN_Y = '-10000px';
150 193  
151 194 Polymer({
152 195  
... ... @@ -232,16 +275,21 @@ after the list became visible again. e.g.
232 275 observers: [
233 276 '_itemsChanged(items.*)',
234 277 '_selectionEnabledChanged(selectionEnabled)',
235   - '_multiSelectionChanged(multiSelection)'
  278 + '_multiSelectionChanged(multiSelection)',
  279 + '_setOverflow(scrollTarget)'
236 280 ],
237 281  
238 282 behaviors: [
239 283 Polymer.Templatizer,
240   - Polymer.IronResizableBehavior
  284 + Polymer.IronResizableBehavior,
  285 + Polymer.IronA11yKeysBehavior,
  286 + Polymer.IronScrollTargetBehavior
241 287 ],
242 288  
243   - listeners: {
244   - 'iron-resize': '_resizeHandler'
  289 + keyBindings: {
  290 + 'up': '_didMoveUp',
  291 + 'down': '_didMoveDown',
  292 + 'enter': '_didEnter'
245 293 },
246 294  
247 295 /**
... ... @@ -251,13 +299,7 @@ after the list became visible again. e.g.
251 299 _ratio: 0.5,
252 300  
253 301 /**
254   - * The element that controls the scroll
255   - * @type {?Element}
256   - */
257   - _scroller: null,
258   -
259   - /**
260   - * The padding-top value of the `scroller` element
  302 + * The padding-top value for the list.
261 303 */
262 304 _scrollerPaddingTop: 0,
263 305  
... ... @@ -267,27 +309,12 @@ after the list became visible again. e.g.
267 309 _scrollPosition: 0,
268 310  
269 311 /**
270   - * The number of tiles in the DOM.
271   - */
272   - _physicalCount: 0,
273   -
274   - /**
275   - * The k-th tile that is at the top of the scrolling list.
276   - */
277   - _physicalStart: 0,
278   -
279   - /**
280   - * The k-th tile that is at the bottom of the scrolling list.
281   - */
282   - _physicalEnd: 0,
283   -
284   - /**
285 312 * The sum of the heights of all the tiles in the DOM.
286 313 */
287 314 _physicalSize: 0,
288 315  
289 316 /**
290   - * The average `offsetHeight` of the tiles observed till now.
  317 + * The average `F` of the tiles observed till now.
291 318 */
292 319 _physicalAverage: 0,
293 320  
... ... @@ -308,11 +335,6 @@ after the list became visible again. e.g.
308 335 _virtualCount: 0,
309 336  
310 337 /**
311   - * The n-th item rendered in the `_physicalStart` tile.
312   - */
313   - _virtualStartVal: 0,
314   -
315   - /**
316 338 * A map between an item key and its physical item index
317 339 */
318 340 _physicalIndexForKey: null,
... ... @@ -328,7 +350,7 @@ after the list became visible again. e.g.
328 350 _scrollHeight: 0,
329 351  
330 352 /**
331   - * The size of the viewport
  353 + * The height of the list. This is referred as the viewport in the context of list.
332 354 */
333 355 _viewportSize: 0,
334 356  
... ... @@ -345,13 +367,20 @@ after the list became visible again. e.g.
345 367 _physicalSizes: null,
346 368  
347 369 /**
348   - * A cached value for the visible index.
  370 + * A cached value for the first visible index.
349 371 * See `firstVisibleIndex`
350 372 * @type {?number}
351 373 */
352 374 _firstVisibleIndexVal: null,
353 375  
354 376 /**
  377 + * A cached value for the last visible index.
  378 + * See `lastVisibleIndex`
  379 + * @type {?number}
  380 + */
  381 + _lastVisibleIndexVal: null,
  382 +
  383 + /**
355 384 * A Polymer collection for the items.
356 385 * @type {?Polymer.Collection}
357 386 */
... ... @@ -364,6 +393,38 @@ after the list became visible again. e.g.
364 393 _itemsRendered: false,
365 394  
366 395 /**
  396 + * The page that is currently rendered.
  397 + */
  398 + _lastPage: null,
  399 +
  400 + /**
  401 + * The max number of pages to render. One page is equivalent to the height of the list.
  402 + */
  403 + _maxPages: 3,
  404 +
  405 + /**
  406 + * The currently focused physical item.
  407 + */
  408 + _focusedItem: null,
  409 +
  410 + /**
  411 + * The index of the `_focusedItem`.
  412 + */
  413 + _focusedIndex: -1,
  414 +
  415 + /**
  416 + * The the item that is focused if it is moved offscreen.
  417 + * @private {?TemplatizerNode}
  418 + */
  419 + _offscreenFocusedItem: null,
  420 +
  421 + /**
  422 + * The item that backfills the `_offscreenFocusedItem` in the physical items
  423 + * list when that item is moved offscreen.
  424 + */
  425 + _focusBackfillItem: null,
  426 +
  427 + /**
367 428 * The bottom of the physical content.
368 429 */
369 430 get _physicalBottom() {
... ... @@ -381,7 +442,21 @@ after the list became visible again. e.g.
381 442 * The n-th item rendered in the last physical item.
382 443 */
383 444 get _virtualEnd() {
384   - return this._virtualStartVal + this._physicalCount - 1;
  445 + return this._virtualStart + this._physicalCount - 1;
  446 + },
  447 +
  448 + /**
  449 + * The height of the physical content that isn't on the screen.
  450 + */
  451 + get _hiddenContentSize() {
  452 + return this._physicalSize - this._viewportSize;
  453 + },
  454 +
  455 + /**
  456 + * The maximum scroll top value.
  457 + */
  458 + get _maxScrollTop() {
  459 + return this._estScrollHeight - this._viewportSize + this._scrollerPaddingTop;
385 460 },
386 461  
387 462 /**
... ... @@ -397,35 +472,53 @@ after the list became visible again. e.g.
397 472 },
398 473  
399 474 /**
400   - * The height of the physical content that isn't on the screen.
  475 + * The n-th item rendered in the `_physicalStart` tile.
401 476 */
402   - get _hiddenContentSize() {
403   - return this._physicalSize - this._viewportSize;
  477 + _virtualStartVal: 0,
  478 +
  479 + set _virtualStart(val) {
  480 + this._virtualStartVal = Math.min(this._maxVirtualStart, Math.max(this._minVirtualStart, val));
  481 + },
  482 +
  483 + get _virtualStart() {
  484 + return this._virtualStartVal || 0;
404 485 },
405 486  
406 487 /**
407   - * The maximum scroll top value.
  488 + * The k-th tile that is at the top of the scrolling list.
408 489 */
409   - get _maxScrollTop() {
410   - return this._estScrollHeight - this._viewportSize;
  490 + _physicalStartVal: 0,
  491 +
  492 + set _physicalStart(val) {
  493 + this._physicalStartVal = val % this._physicalCount;
  494 + if (this._physicalStartVal < 0) {
  495 + this._physicalStartVal = this._physicalCount + this._physicalStartVal;
  496 + }
  497 + this._physicalEnd = (this._physicalStart + this._physicalCount - 1) % this._physicalCount;
  498 + },
  499 +
  500 + get _physicalStart() {
  501 + return this._physicalStartVal || 0;
411 502 },
412 503  
413 504 /**
414   - * Sets the n-th item rendered in `_physicalStart`
  505 + * The number of tiles in the DOM.
415 506 */
416   - set _virtualStart(val) {
417   - // clamp the value so that _minVirtualStart <= val <= _maxVirtualStart
418   - this._virtualStartVal = Math.min(this._maxVirtualStart, Math.max(this._minVirtualStart, val));
419   - this._physicalStart = this._virtualStartVal % this._physicalCount;
  507 + _physicalCountVal: 0,
  508 +
  509 + set _physicalCount(val) {
  510 + this._physicalCountVal = val;
420 511 this._physicalEnd = (this._physicalStart + this._physicalCount - 1) % this._physicalCount;
421 512 },
422 513  
  514 + get _physicalCount() {
  515 + return this._physicalCountVal;
  516 + },
  517 +
423 518 /**
424   - * Gets the n-th item rendered in `_physicalStart`
  519 + * The k-th tile that is at the bottom of the scrolling list.
425 520 */
426   - get _virtualStart() {
427   - return this._virtualStartVal;
428   - },
  521 + _physicalEnd: 0,
429 522  
430 523 /**
431 524 * An optimal physical size such that we will have enough physical items
... ... @@ -435,14 +528,14 @@ after the list became visible again. e.g.
435 528 * to a viewport of physical items above and below the user's viewport.
436 529 */
437 530 get _optPhysicalSize() {
438   - return this._viewportSize * 3;
  531 + return this._viewportSize * this._maxPages;
439 532 },
440 533  
441 534 /**
442 535 * True if the current list is visible.
443 536 */
444 537 get _isVisible() {
445   - return this._scroller && Boolean(this._scroller.offsetWidth || this._scroller.offsetHeight);
  538 + return this.scrollTarget && Boolean(this.scrollTarget.offsetWidth || this.scrollTarget.offsetHeight);
446 539 },
447 540  
448 541 /**
... ... @@ -451,68 +544,67 @@ after the list became visible again. e.g.
451 544 * @type {number}
452 545 */
453 546 get firstVisibleIndex() {
454   - var physicalOffset;
455   -
456 547 if (this._firstVisibleIndexVal === null) {
457   - physicalOffset = this._physicalTop;
  548 + var physicalOffset = this._physicalTop + this._scrollerPaddingTop;
458 549  
459 550 this._firstVisibleIndexVal = this._iterateItems(
460 551 function(pidx, vidx) {
461 552 physicalOffset += this._physicalSizes[pidx];
462   -
463 553 if (physicalOffset > this._scrollPosition) {
464 554 return vidx;
465 555 }
466 556 }) || 0;
467 557 }
468   -
469 558 return this._firstVisibleIndexVal;
470 559 },
471 560  
472   - ready: function() {
473   - if (IOS_TOUCH_SCROLLING) {
474   - this._scrollListener = function() {
475   - requestAnimationFrame(this._scrollHandler.bind(this));
476   - }.bind(this);
477   - } else {
478   - this._scrollListener = this._scrollHandler.bind(this);
479   - }
480   - },
481   -
482 561 /**
483   - * When the element has been attached to the DOM tree.
  562 + * Gets the index of the last visible item in the viewport.
  563 + *
  564 + * @type {number}
484 565 */
485   - attached: function() {
486   - // delegate to the parent's scroller
487   - // e.g. paper-scroll-header-panel
488   - var el = Polymer.dom(this);
  566 + get lastVisibleIndex() {
  567 + if (this._lastVisibleIndexVal === null) {
  568 + var physicalOffset = this._physicalTop;
489 569  
490   - var parentNode = /** @type {?{scroller: ?Element}} */ (el.parentNode);
491   - if (parentNode && parentNode.scroller) {
492   - this._scroller = parentNode.scroller;
493   - } else {
494   - this._scroller = this;
495   - this.classList.add('has-scroller');
496   - }
  570 + this._iterateItems(function(pidx, vidx) {
  571 + physicalOffset += this._physicalSizes[pidx];
497 572  
498   - if (IOS_TOUCH_SCROLLING) {
499   - this._scroller.style.webkitOverflowScrolling = 'touch';
  573 + if (physicalOffset <= this._scrollBottom) {
  574 + this._lastVisibleIndexVal = vidx;
  575 + }
  576 + });
500 577 }
  578 + return this._lastVisibleIndexVal;
  579 + },
  580 +
  581 + get _defaultScrollTarget() {
  582 + return this;
  583 + },
501 584  
502   - this._scroller.addEventListener('scroll', this._scrollListener);
  585 + ready: function() {
  586 + this.addEventListener('focus', this._didFocus.bind(this), true);
  587 + },
503 588  
  589 + attached: function() {
504 590 this.updateViewportBoundaries();
505 591 this._render();
  592 + // `iron-resize` is fired when the list is attached if the event is added
  593 + // before attached causing unnecessary work.
  594 + this.listen(this, 'iron-resize', '_resizeHandler');
506 595 },
507 596  
508   - /**
509   - * When the element has been removed from the DOM tree.
510   - */
511 597 detached: function() {
512 598 this._itemsRendered = false;
513   - if (this._scroller) {
514   - this._scroller.removeEventListener('scroll', this._scrollListener);
515   - }
  599 + this.unlisten(this, 'iron-resize', '_resizeHandler');
  600 + },
  601 +
  602 + /**
  603 + * Set the overflow property if this element has its own scrolling region
  604 + */
  605 + _setOverflow: function(scrollTarget) {
  606 + this.style.webkitOverflowScrolling = scrollTarget === this ? 'touch' : '';
  607 + this.style.overflow = scrollTarget === this ? 'auto' : '';
516 608 },
517 609  
518 610 /**
... ... @@ -522,23 +614,22 @@ after the list became visible again. e.g.
522 614 * @method updateViewportBoundaries
523 615 */
524 616 updateViewportBoundaries: function() {
525   - var scrollerStyle = window.getComputedStyle(this._scroller);
526   - this._scrollerPaddingTop = parseInt(scrollerStyle['padding-top'], 10);
527   - this._viewportSize = this._scroller.offsetHeight;
  617 + this._scrollerPaddingTop = this.scrollTarget === this ? 0 :
  618 + parseInt(window.getComputedStyle(this)['padding-top'], 10);
  619 +
  620 + this._viewportSize = this._scrollTargetHeight;
528 621 },
529 622  
530 623 /**
531 624 * Update the models, the position of the
532 625 * items in the viewport and recycle tiles as needed.
533 626 */
534   - _refresh: function() {
  627 + _scrollHandler: function() {
535 628 // clamp the `scrollTop` value
536   - // IE 10|11 scrollTop may go above `_maxScrollTop`
537   - // iOS `scrollTop` may go below 0 and above `_maxScrollTop`
538   - var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scroller.scrollTop));
539   - var tileHeight, tileTop, kth, recycledTileSet, scrollBottom;
540   - var ratio = this._ratio;
  629 + var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scrollTop));
541 630 var delta = scrollTop - this._scrollPosition;
  631 + var tileHeight, tileTop, kth, recycledTileSet, scrollBottom, physicalBottom;
  632 + var ratio = this._ratio;
542 633 var recycledTiles = 0;
543 634 var hiddenContentSize = this._hiddenContentSize;
544 635 var currentRatio = ratio;
... ... @@ -547,10 +638,12 @@ after the list became visible again. e.g.
547 638 // track the last `scrollTop`
548 639 this._scrollPosition = scrollTop;
549 640  
550   - // clear cached visible index
  641 + // clear cached visible indexes
551 642 this._firstVisibleIndexVal = null;
  643 + this._lastVisibleIndexVal = null;
552 644  
553 645 scrollBottom = this._scrollBottom;
  646 + physicalBottom = this._physicalBottom;
554 647  
555 648 // random access
556 649 if (Math.abs(delta) > this._physicalSize) {
... ... @@ -561,7 +654,6 @@ after the list became visible again. e.g.
561 654 else if (delta < 0) {
562 655 var topSpace = scrollTop - this._physicalTop;
563 656 var virtualStart = this._virtualStart;
564   - var physicalBottom = this._physicalBottom;
565 657  
566 658 recycledTileSet = [];
567 659  
... ... @@ -593,7 +685,7 @@ after the list became visible again. e.g.
593 685 }
594 686 // scroll down
595 687 else if (delta > 0) {
596   - var bottomSpace = this._physicalBottom - scrollBottom;
  688 + var bottomSpace = physicalBottom - scrollBottom;
597 689 var virtualEnd = this._virtualEnd;
598 690 var lastVirtualItemIndex = this._virtualCount-1;
599 691  
... ... @@ -625,31 +717,29 @@ after the list became visible again. e.g.
625 717 }
626 718  
627 719 if (recycledTiles === 0) {
628   - // If the list ever reach this case, the physical average is not significant enough
629   - // to create all the items needed to cover the entire viewport.
630   - // e.g. A few items have a height that differs from the average by serveral order of magnitude.
631   - if (this._increasePoolIfNeeded()) {
632   - // yield and set models to the new items
633   - this.async(this._update);
  720 + // Try to increase the pool if the list's client height isn't filled up with physical items
  721 + if (physicalBottom < scrollBottom || this._physicalTop > scrollTop) {
  722 + this._increasePoolIfNeeded();
634 723 }
635 724 } else {
636 725 this._virtualStart = this._virtualStart + recycledTiles;
  726 + this._physicalStart = this._physicalStart + recycledTiles;
637 727 this._update(recycledTileSet, movingUp);
638 728 }
639 729 },
640 730  
641 731 /**
642   - * Update the list of items, starting from the `_virtualStartVal` item.
  732 + * Update the list of items, starting from the `_virtualStart` item.
643 733 * @param {!Array<number>=} itemSet
644 734 * @param {!Array<number>=} movingUp
645 735 */
646 736 _update: function(itemSet, movingUp) {
  737 + // manage focus
  738 + this._manageFocus();
647 739 // update models
648 740 this._assignModels(itemSet);
649   -
650 741 // measure heights
651 742 this._updateMetrics(itemSet);
652   -
653 743 // adjust offset after measuring
654 744 if (movingUp) {
655 745 while (movingUp.length) {
... ... @@ -658,15 +748,10 @@ after the list became visible again. e.g.
658 748 }
659 749 // update the position of the items
660 750 this._positionItems();
661   -
662 751 // set the scroller size
663 752 this._updateScrollerSize();
664   -
665   - // increase the pool of physical items if needed
666   - if (this._increasePoolIfNeeded()) {
667   - // yield set models to the new items
668   - this.async(this._update);
669   - }
  753 + // increase the pool of physical items
  754 + this._increasePoolIfNeeded();
670 755 },
671 756  
672 757 /**
... ... @@ -679,53 +764,64 @@ after the list became visible again. e.g.
679 764  
680 765 for (var i = 0; i < size; i++) {
681 766 var inst = this.stamp(null);
682   -
683 767 // First element child is item; Safari doesn't support children[0]
684 768 // on a doc fragment
685 769 physicalItems[i] = inst.root.querySelector('*');
686 770 Polymer.dom(this).appendChild(inst.root);
687 771 }
688   -
689 772 return physicalItems;
690 773 },
691 774  
692 775 /**
693 776 * Increases the pool of physical items only if needed.
694   - * This function will allocate additional physical items
695   - * (limited by `MAX_PHYSICAL_COUNT`) if the content size is shorter than
696   - * `_optPhysicalSize`
697 777 *
698   - * @return boolean
  778 + * @return {boolean} True if the pool was increased.
699 779 */
700 780 _increasePoolIfNeeded: function() {
701   - if (this._physicalAverage === 0) {
  781 + // Base case 1: the list has no size.
  782 + if (this._viewportSize === 0) {
702 783 return false;
703 784 }
704   - if (this._physicalBottom < this._scrollBottom || this._physicalTop > this._scrollPosition) {
705   - return this._increasePool(1);
  785 + // Base case 2: If the physical size is optimal and the list's client height is full
  786 + // with physical items, don't increase the pool.
  787 + var isClientHeightFull = this._physicalBottom >= this._scrollBottom && this._physicalTop <= this._scrollPosition;
  788 + if (this._physicalSize >= this._optPhysicalSize && isClientHeightFull) {
  789 + return false;
706 790 }
707   - if (this._physicalSize < this._optPhysicalSize) {
708   - return this._increasePool(Math.round((this._optPhysicalSize - this._physicalSize) * 1.2 / this._physicalAverage));
  791 + // this value should range between [0 <= `currentPage` <= `_maxPages`]
  792 + var currentPage = Math.floor(this._physicalSize / this._viewportSize);
  793 +
  794 + if (currentPage === 0) {
  795 + // fill the first page
  796 + this._debounceTemplate(this._increasePool.bind(this, Math.round(this._physicalCount * 0.5)));
  797 + } else if (this._lastPage !== currentPage && isClientHeightFull) {
  798 + // paint the page and defer the next increase
  799 + // wait 16ms which is rough enough to get paint cycle.
  800 + Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', this._increasePool.bind(this, 1), 16));
  801 + } else {
  802 + // fill the rest of the pages
  803 + this._debounceTemplate(this._increasePool.bind(this, 1));
709 804 }
710   - return false;
  805 +
  806 + this._lastPage = currentPage;
  807 +
  808 + return true;
711 809 },
712 810  
713 811 /**
714 812 * Increases the pool size.
715 813 */
716 814 _increasePool: function(missingItems) {
717   - // limit the size
718 815 var nextPhysicalCount = Math.min(
719 816 this._physicalCount + missingItems,
720   - this._virtualCount,
  817 + this._virtualCount - this._virtualStart,
721 818 MAX_PHYSICAL_COUNT
722 819 );
723   -
724 820 var prevPhysicalCount = this._physicalCount;
725 821 var delta = nextPhysicalCount - prevPhysicalCount;
726 822  
727 823 if (delta <= 0) {
728   - return false;
  824 + return;
729 825 }
730 826  
731 827 [].push.apply(this._physicalItems, this._createPool(delta));
... ... @@ -733,7 +829,15 @@ after the list became visible again. e.g.
733 829  
734 830 this._physicalCount = prevPhysicalCount + delta;
735 831  
736   - return true;
  832 + // update the physical start if we need to preserve the model of the focused item.
  833 + // In this situation, the focused item is currently rendered and its model would
  834 + // have changed after increasing the pool if the physical start remained unchanged.
  835 + if (this._physicalStart > this._physicalEnd &&
  836 + this._isIndexRendered(this._focusedIndex) &&
  837 + this._getPhysicalIndex(this._focusedIndex) < this._physicalEnd) {
  838 + this._physicalStart = this._physicalStart + delta;
  839 + }
  840 + this._update();
737 841 },
738 842  
739 843 /**
... ... @@ -743,7 +847,8 @@ after the list became visible again. e.g.
743 847 _render: function() {
744 848 var requiresUpdate = this._virtualCount > 0 || this._physicalCount > 0;
745 849  
746   - if (this.isAttached && !this._itemsRendered && this._isVisible && requiresUpdate) {
  850 + if (this.isAttached && !this._itemsRendered && this._isVisible && requiresUpdate) {
  851 + this._lastPage = 0;
747 852 this._update();
748 853 this._itemsRendered = true;
749 854 }
... ... @@ -756,11 +861,11 @@ after the list became visible again. e.g.
756 861 if (!this.ctor) {
757 862 // Template instance props that should be excluded from forwarding
758 863 var props = {};
759   -
760 864 props.__key__ = true;
761 865 props[this.as] = true;
762 866 props[this.indexAs] = true;
763 867 props[this.selectedAs] = true;
  868 + props.tabIndex = true;
764 869  
765 870 this._instanceProps = props;
766 871 this._userTemplate = Polymer.dom(this).querySelector('template');
... ... @@ -820,23 +925,36 @@ after the list became visible again. e.g.
820 925  
821 926 /**
822 927 * Called as a side effect of a host items.<key>.<path> path change,
823   - * responsible for notifying item.<path> changes to row for key.
  928 + * responsible for notifying item.<path> changes.
824 929 */
825 930 _forwardItemPath: function(path, value) {
826   - if (this._physicalIndexForKey) {
827   - var dot = path.indexOf('.');
828   - var key = path.substring(0, dot < 0 ? path.length : dot);
829   - var idx = this._physicalIndexForKey[key];
830   - var row = this._physicalItems[idx];
831   - if (row) {
832   - var inst = row._templateInstance;
833   - if (dot >= 0) {
834   - path = this.as + '.' + path.substring(dot+1);
835   - inst.notifyPath(path, value, true);
836   - } else {
837   - inst[this.as] = value;
838   - }
839   - }
  931 + if (!this._physicalIndexForKey) {
  932 + return;
  933 + }
  934 + var inst;
  935 + var dot = path.indexOf('.');
  936 + var key = path.substring(0, dot < 0 ? path.length : dot);
  937 + var idx = this._physicalIndexForKey[key];
  938 + var el = this._physicalItems[idx];
  939 +
  940 +
  941 + if (idx === this._focusedIndex && this._offscreenFocusedItem) {
  942 + el = this._offscreenFocusedItem;
  943 + }
  944 + if (!el) {
  945 + return;
  946 + }
  947 +
  948 + inst = el._templateInstance;
  949 +
  950 + if (inst.__key__ !== key) {
  951 + return;
  952 + }
  953 + if (dot >= 0) {
  954 + path = this.as + '.' + path.substring(dot+1);
  955 + inst.notifyPath(path, value, true);
  956 + } else {
  957 + inst[this.as] = value;
840 958 }
841 959 },
842 960  
... ... @@ -846,18 +964,15 @@ after the list became visible again. e.g.
846 964 */
847 965 _itemsChanged: function(change) {
848 966 if (change.path === 'items') {
849   - // render the new set
850   - this._itemsRendered = false;
851   -
852   - // update the whole set
853   - this._virtualStartVal = 0;
  967 + // reset items
  968 + this._virtualStart = 0;
854 969 this._physicalTop = 0;
855 970 this._virtualCount = this.items ? this.items.length : 0;
856 971 this._collection = this.items ? Polymer.Collection.get(this.items) : null;
857 972 this._physicalIndexForKey = {};
858 973  
859   - // scroll to the top
860 974 this._resetScrollPosition(0);
  975 + this._removeFocusedItem();
861 976  
862 977 // create the initial physical items
863 978 if (!this._physicalItems) {
... ... @@ -866,48 +981,50 @@ after the list became visible again. e.g.
866 981 this._physicalSizes = new Array(this._physicalCount);
867 982 }
868 983  
869   - this.debounce('refresh', this._render);
  984 + this._physicalStart = 0;
870 985  
871 986 } else if (change.path === 'items.splices') {
872   - // render the new set
873   - this._itemsRendered = false;
874   -
875 987 this._adjustVirtualIndex(change.value.indexSplices);
876 988 this._virtualCount = this.items ? this.items.length : 0;
877 989  
878   - this.debounce('refresh', this._render);
879   -
880 990 } else {
881 991 // update a single item
882 992 this._forwardItemPath(change.path.split('.').slice(1).join('.'), change.value);
  993 + return;
883 994 }
  995 +
  996 + this._itemsRendered = false;
  997 + this._debounceTemplate(this._render);
884 998 },
885 999  
886 1000 /**
887 1001 * @param {!Array<!PolymerSplice>} splices
888 1002 */
889 1003 _adjustVirtualIndex: function(splices) {
890   - var i, splice, idx;
891   -
892   - for (i = 0; i < splices.length; i++) {
893   - splice = splices[i];
894   -
  1004 + splices.forEach(function(splice) {
895 1005 // deselect removed items
896   - splice.removed.forEach(this.$.selector.deselect, this.$.selector);
897   -
898   - idx = splice.index;
  1006 + splice.removed.forEach(this._removeItem, this);
899 1007 // We only need to care about changes happening above the current position
900   - if (idx >= this._virtualStartVal) {
901   - break;
902   - }
  1008 + if (splice.index < this._virtualStart) {
  1009 + var delta = Math.max(
  1010 + splice.addedCount - splice.removed.length,
  1011 + splice.index - this._virtualStart);
903 1012  
904   - this._virtualStart = this._virtualStart +
905   - Math.max(splice.addedCount - splice.removed.length, idx - this._virtualStartVal);
906   - }
  1013 + this._virtualStart = this._virtualStart + delta;
  1014 +
  1015 + if (this._focusedIndex >= 0) {
  1016 + this._focusedIndex = this._focusedIndex + delta;
  1017 + }
  1018 + }
  1019 + }, this);
907 1020 },
908 1021  
909   - _scrollHandler: function() {
910   - this._refresh();
  1022 + _removeItem: function(item) {
  1023 + this.$.selector.deselect(item);
  1024 + // remove the current focused item
  1025 + if (this._focusedItem && this._focusedItem._templateInstance[this.as] === item) {
  1026 + this._removeFocusedItem();
  1027 + }
911 1028 },
912 1029  
913 1030 /**
... ... @@ -924,9 +1041,9 @@ after the list became visible again. e.g.
924 1041 for (i = 0; i < itemSet.length; i++) {
925 1042 pidx = itemSet[i];
926 1043 if (pidx >= this._physicalStart) {
927   - vidx = this._virtualStartVal + (pidx - this._physicalStart);
  1044 + vidx = this._virtualStart + (pidx - this._physicalStart);
928 1045 } else {
929   - vidx = this._virtualStartVal + (this._physicalCount - this._physicalStart) + pidx;
  1046 + vidx = this._virtualStart + (this._physicalCount - this._physicalStart) + pidx;
930 1047 }
931 1048 if ((rtn = fn.call(this, pidx, vidx)) != null) {
932 1049 return rtn;
... ... @@ -934,17 +1051,14 @@ after the list became visible again. e.g.
934 1051 }
935 1052 } else {
936 1053 pidx = this._physicalStart;
937   - vidx = this._virtualStartVal;
  1054 + vidx = this._virtualStart;
938 1055  
939 1056 for (; pidx < this._physicalCount; pidx++, vidx++) {
940 1057 if ((rtn = fn.call(this, pidx, vidx)) != null) {
941 1058 return rtn;
942 1059 }
943 1060 }
944   -
945   - pidx = 0;
946   -
947   - for (; pidx < this._physicalStart; pidx++, vidx++) {
  1061 + for (pidx = 0; pidx < this._physicalStart; pidx++, vidx++) {
948 1062 if ((rtn = fn.call(this, pidx, vidx)) != null) {
949 1063 return rtn;
950 1064 }
... ... @@ -962,19 +1076,18 @@ after the list became visible again. e.g.
962 1076 var inst = el._templateInstance;
963 1077 var item = this.items && this.items[vidx];
964 1078  
965   - if (item) {
  1079 + if (item != null) {
966 1080 inst[this.as] = item;
967 1081 inst.__key__ = this._collection.getKey(item);
968   - inst[this.selectedAs] =
969   - /** @type {!ArraySelectorElement} */ (this.$.selector).isSelected(item);
  1082 + inst[this.selectedAs] = /** @type {!ArraySelectorElement} */ (this.$.selector).isSelected(item);
970 1083 inst[this.indexAs] = vidx;
971   - el.removeAttribute('hidden');
  1084 + inst.tabIndex = this._focusedIndex === vidx ? 0 : -1;
972 1085 this._physicalIndexForKey[inst.__key__] = pidx;
  1086 + el.removeAttribute('hidden');
973 1087 } else {
974 1088 inst.__key__ = null;
975 1089 el.setAttribute('hidden', '');
976 1090 }
977   -
978 1091 }, itemSet);
979 1092 },
980 1093  
... ... @@ -984,23 +1097,26 @@ after the list became visible again. e.g.
984 1097 * @param {!Array<number>=} itemSet
985 1098 */
986 1099 _updateMetrics: function(itemSet) {
  1100 + // Make sure we distributed all the physical items
  1101 + // so we can measure them
  1102 + Polymer.dom.flush();
  1103 +
987 1104 var newPhysicalSize = 0;
988 1105 var oldPhysicalSize = 0;
989 1106 var prevAvgCount = this._physicalAverageCount;
990 1107 var prevPhysicalAvg = this._physicalAverage;
991   - // Make sure we distributed all the physical items
992   - // so we can measure them
993   - Polymer.dom.flush();
994 1108  
995 1109 this._iterateItems(function(pidx, vidx) {
  1110 +
996 1111 oldPhysicalSize += this._physicalSizes[pidx] || 0;
997 1112 this._physicalSizes[pidx] = this._physicalItems[pidx].offsetHeight;
998 1113 newPhysicalSize += this._physicalSizes[pidx];
999 1114 this._physicalAverageCount += this._physicalSizes[pidx] ? 1 : 0;
  1115 +
1000 1116 }, itemSet);
1001 1117  
1002 1118 this._physicalSize = this._physicalSize + newPhysicalSize - oldPhysicalSize;
1003   - this._viewportSize = this._scroller.offsetHeight;
  1119 + this._viewportSize = this._scrollTargetHeight;
1004 1120  
1005 1121 // update the average if we measured something
1006 1122 if (this._physicalAverageCount !== prevAvgCount) {
... ... @@ -1019,10 +1135,8 @@ after the list became visible again. e.g.
1019 1135 var y = this._physicalTop;
1020 1136  
1021 1137 this._iterateItems(function(pidx) {
1022   -
1023   - this.transform('translate3d(0, ' + y + 'px, 0)', this._physicalItems[pidx]);
  1138 + this.translate3d(0, y + 'px', 0, this._physicalItems[pidx]);
1024 1139 y += this._physicalSizes[pidx];
1025   -
1026 1140 });
1027 1141 },
1028 1142  
... ... @@ -1030,15 +1144,14 @@ after the list became visible again. e.g.
1030 1144 * Adjusts the scroll position when it was overestimated.
1031 1145 */
1032 1146 _adjustScrollPosition: function() {
1033   - var deltaHeight = this._virtualStartVal === 0 ? this._physicalTop :
  1147 + var deltaHeight = this._virtualStart === 0 ? this._physicalTop :
1034 1148 Math.min(this._scrollPosition + this._physicalTop, 0);
1035 1149  
1036 1150 if (deltaHeight) {
1037 1151 this._physicalTop = this._physicalTop - deltaHeight;
1038   -
1039 1152 // juking scroll position during interial scrolling on iOS is no bueno
1040 1153 if (!IOS_TOUCH_SCROLLING) {
1041   - this._resetScrollPosition(this._scroller.scrollTop - deltaHeight);
  1154 + this._resetScrollPosition(this._scrollTop - deltaHeight);
1042 1155 }
1043 1156 }
1044 1157 },
... ... @@ -1047,9 +1160,9 @@ after the list became visible again. e.g.
1047 1160 * Sets the position of the scroll.
1048 1161 */
1049 1162 _resetScrollPosition: function(pos) {
1050   - if (this._scroller) {
1051   - this._scroller.scrollTop = pos;
1052   - this._scrollPosition = this._scroller.scrollTop;
  1163 + if (this.scrollTarget) {
  1164 + this._scrollTop = pos;
  1165 + this._scrollPosition = this._scrollTop;
1053 1166 }
1054 1167 },
1055 1168  
... ... @@ -1060,7 +1173,7 @@ after the list became visible again. e.g.
1060 1173 */
1061 1174 _updateScrollerSize: function(forceUpdate) {
1062 1175 this._estScrollHeight = (this._physicalBottom +
1063   - Math.max(this._virtualCount - this._physicalCount - this._virtualStartVal, 0) * this._physicalAverage);
  1176 + Math.max(this._virtualCount - this._physicalCount - this._virtualStart, 0) * this._physicalAverage);
1064 1177  
1065 1178 forceUpdate = forceUpdate || this._scrollHeight === 0;
1066 1179 forceUpdate = forceUpdate || this._scrollPosition >= this._estScrollHeight - this._physicalSize;
... ... @@ -1071,7 +1184,6 @@ after the list became visible again. e.g.
1071 1184 this._scrollHeight = this._estScrollHeight;
1072 1185 }
1073 1186 },
1074   -
1075 1187 /**
1076 1188 * Scroll to a specific item in the virtual list regardless
1077 1189 * of the physical items in the DOM tree.
... ... @@ -1084,20 +1196,19 @@ after the list became visible again. e.g.
1084 1196 return;
1085 1197 }
1086 1198  
1087   - var firstVisible = this.firstVisibleIndex;
  1199 + Polymer.dom.flush();
1088 1200  
1089 1201 idx = Math.min(Math.max(idx, 0), this._virtualCount-1);
1090   -
1091   - // start at the previous virtual item
1092   - // so we have a item above the first visible item
1093   - this._virtualStart = idx - 1;
1094   -
  1202 + // update the virtual start only when needed
  1203 + if (!this._isIndexRendered(idx) || idx >= this._maxVirtualStart) {
  1204 + this._virtualStart = idx - 1;
  1205 + }
  1206 + // manage focus
  1207 + this._manageFocus();
1095 1208 // assign new models
1096 1209 this._assignModels();
1097   -
1098 1210 // measure the new sizes
1099 1211 this._updateMetrics();
1100   -
1101 1212 // estimate new physical offset
1102 1213 this._physicalTop = this._virtualStart * this._physicalAverage;
1103 1214  
... ... @@ -1107,28 +1218,22 @@ after the list became visible again. e.g.
1107 1218 var hiddenContentSize = this._hiddenContentSize;
1108 1219  
1109 1220 // scroll to the item as much as we can
1110   - while (currentVirtualItem !== idx && targetOffsetTop < hiddenContentSize) {
  1221 + while (currentVirtualItem < idx && targetOffsetTop < hiddenContentSize) {
1111 1222 targetOffsetTop = targetOffsetTop + this._physicalSizes[currentTopItem];
1112 1223 currentTopItem = (currentTopItem + 1) % this._physicalCount;
1113 1224 currentVirtualItem++;
1114 1225 }
1115   -
1116 1226 // update the scroller size
1117 1227 this._updateScrollerSize(true);
1118   -
1119 1228 // update the position of the items
1120 1229 this._positionItems();
1121   -
1122 1230 // set the new scroll position
1123   - this._resetScrollPosition(this._physicalTop + targetOffsetTop + 1);
1124   -
  1231 + this._resetScrollPosition(this._physicalTop + this._scrollerPaddingTop + targetOffsetTop);
1125 1232 // increase the pool of physical items if needed
1126   - if (this._increasePoolIfNeeded()) {
1127   - // yield set models to the new items
1128   - this.async(this._update);
1129   - }
  1233 + this._increasePoolIfNeeded();
1130 1234 // clear cached visible index
1131 1235 this._firstVisibleIndexVal = null;
  1236 + this._lastVisibleIndexVal = null;
1132 1237 },
1133 1238  
1134 1239 /**
... ... @@ -1144,21 +1249,30 @@ after the list became visible again. e.g.
1144 1249 * when the element is resized.
1145 1250 */
1146 1251 _resizeHandler: function() {
1147   - this.debounce('resize', function() {
1148   - this._render();
1149   - if (this._itemsRendered && this._physicalItems && this._isVisible) {
1150   - this._resetAverage();
1151   - this.updateViewportBoundaries();
1152   - this.scrollToIndex(this.firstVisibleIndex);
1153   - }
1154   - });
  1252 + // iOS fires the resize event when the address bar slides up
  1253 + if (IOS && Math.abs(this._viewportSize - this._scrollTargetHeight) < 100) {
  1254 + return;
  1255 + }
  1256 + // In Desktop Safari 9.0.3, if the scroll bars are always shown,
  1257 + // changing the scroll position from a resize handler would result in
  1258 + // the scroll position being reset. Waiting 1ms fixes the issue.
  1259 + Polymer.dom.addDebouncer(this.debounce('_debounceTemplate',
  1260 + function() {
  1261 + this._render();
  1262 +
  1263 + if (this._itemsRendered && this._physicalItems && this._isVisible) {
  1264 + this._resetAverage();
  1265 + this.updateViewportBoundaries();
  1266 + this.scrollToIndex(this.firstVisibleIndex);
  1267 + }
  1268 + }.bind(this), 1));
1155 1269 },
1156 1270  
1157 1271 _getModelFromItem: function(item) {
1158 1272 var key = this._collection.getKey(item);
1159 1273 var pidx = this._physicalIndexForKey[key];
1160 1274  
1161   - if (pidx !== undefined) {
  1275 + if (pidx != null) {
1162 1276 return this._physicalItems[pidx]._templateInstance;
1163 1277 }
1164 1278 return null;
... ... @@ -1170,12 +1284,14 @@ after the list became visible again. e.g.
1170 1284 * @param {(Object|number)} item The item object or its index
1171 1285 */
1172 1286 _getNormalizedItem: function(item) {
1173   - if (typeof item === 'number') {
1174   - item = this.items[item];
1175   - if (!item) {
1176   - throw new RangeError('<item> not found');
  1287 + if (this._collection.getKey(item) === undefined) {
  1288 + if (typeof item === 'number') {
  1289 + item = this.items[item];
  1290 + if (!item) {
  1291 + throw new RangeError('<item> not found');
  1292 + }
  1293 + return item;
1177 1294 }
1178   - } else if (this._collection.getKey(item) === undefined) {
1179 1295 throw new TypeError('<item> should be a valid item');
1180 1296 }
1181 1297 return item;
... ... @@ -1198,6 +1314,7 @@ after the list became visible again. e.g.
1198 1314 model[this.selectedAs] = true;
1199 1315 }
1200 1316 this.$.selector.select(item);
  1317 + this.updateSizeForItem(item);
1201 1318 },
1202 1319  
1203 1320 /**
... ... @@ -1215,6 +1332,7 @@ after the list became visible again. e.g.
1215 1332 model[this.selectedAs] = false;
1216 1333 }
1217 1334 this.$.selector.deselect(item);
  1335 + this.updateSizeForItem(item);
1218 1336 },
1219 1337  
1220 1338 /**
... ... @@ -1260,20 +1378,15 @@ after the list became visible again. e.g.
1260 1378 * it will remove the listener otherwise.
1261 1379 */
1262 1380 _selectionEnabledChanged: function(selectionEnabled) {
1263   - if (selectionEnabled) {
1264   - this.listen(this, 'tap', '_selectionHandler');
1265   - this.listen(this, 'keypress', '_selectionHandler');
1266   - } else {
1267   - this.unlisten(this, 'tap', '_selectionHandler');
1268   - this.unlisten(this, 'keypress', '_selectionHandler');
1269   - }
  1381 + var handler = selectionEnabled ? this.listen : this.unlisten;
  1382 + handler.call(this, this, 'tap', '_selectionHandler');
1270 1383 },
1271 1384  
1272 1385 /**
1273 1386 * Select an item from an event object.
1274 1387 */
1275 1388 _selectionHandler: function(e) {
1276   - if (e.type !== 'keypress' || e.keyCode === 13) {
  1389 + if (this.selectionEnabled) {
1277 1390 var model = this.modelForElement(e.target);
1278 1391 if (model) {
1279 1392 this.toggleSelectionForItem(model[this.as]);
... ... @@ -1297,10 +1410,179 @@ after the list became visible again. e.g.
1297 1410 var key = this._collection.getKey(item);
1298 1411 var pidx = this._physicalIndexForKey[key];
1299 1412  
1300   - if (pidx !== undefined) {
  1413 + if (pidx != null) {
1301 1414 this._updateMetrics([pidx]);
1302 1415 this._positionItems();
1303 1416 }
  1417 + },
  1418 +
  1419 + /**
  1420 + * Creates a temporary backfill item in the rendered pool of physical items
  1421 + * to replace the main focused item. The focused item has tabIndex = 0
  1422 + * and might be currently focused by the user.
  1423 + *
  1424 + * This dynamic replacement helps to preserve the focus state.
  1425 + */
  1426 + _manageFocus: function() {
  1427 + var fidx = this._focusedIndex;
  1428 +
  1429 + if (fidx >= 0 && fidx < this._virtualCount) {
  1430 + // if it's a valid index, check if that index is rendered
  1431 + // in a physical item.
  1432 + if (this._isIndexRendered(fidx)) {
  1433 + this._restoreFocusedItem();
  1434 + } else {
  1435 + this._createFocusBackfillItem();
  1436 + }
  1437 + } else if (this._virtualCount > 0 && this._physicalCount > 0) {
  1438 + // otherwise, assign the initial focused index.
  1439 + this._focusedIndex = this._virtualStart;
  1440 + this._focusedItem = this._physicalItems[this._physicalStart];
  1441 + }
  1442 + },
  1443 +
  1444 + _isIndexRendered: function(idx) {
  1445 + return idx >= this._virtualStart && idx <= this._virtualEnd;
  1446 + },
  1447 +
  1448 + _isIndexVisible: function(idx) {
  1449 + return idx >= this.firstVisibleIndex && idx <= this.lastVisibleIndex;
  1450 + },
  1451 +
  1452 + _getPhysicalIndex: function(idx) {
  1453 + return this._physicalIndexForKey[this._collection.getKey(this._getNormalizedItem(idx))];
  1454 + },
  1455 +
  1456 + _focusPhysicalItem: function(idx) {
  1457 + if (idx < 0 || idx >= this._virtualCount) {
  1458 + return;
  1459 + }
  1460 + this._restoreFocusedItem();
  1461 + // scroll to index to make sure it's rendered
  1462 + if (!this._isIndexRendered(idx)) {
  1463 + this.scrollToIndex(idx);
  1464 + }
  1465 +
  1466 + var physicalItem = this._physicalItems[this._getPhysicalIndex(idx)];
  1467 + var SECRET = ~(Math.random() * 100);
  1468 + var model = physicalItem._templateInstance;
  1469 + var focusable;
  1470 +
  1471 + // set a secret tab index
  1472 + model.tabIndex = SECRET;
  1473 + // check if focusable element is the physical item
  1474 + if (physicalItem.tabIndex === SECRET) {
  1475 + focusable = physicalItem;
  1476 + }
  1477 + // search for the element which tabindex is bound to the secret tab index
  1478 + if (!focusable) {
  1479 + focusable = Polymer.dom(physicalItem).querySelector('[tabindex="' + SECRET + '"]');
  1480 + }
  1481 + // restore the tab index
  1482 + model.tabIndex = 0;
  1483 + // focus the focusable element
  1484 + this._focusedIndex = idx;
  1485 + focusable && focusable.focus();
  1486 + },
  1487 +
  1488 + _removeFocusedItem: function() {
  1489 + if (this._offscreenFocusedItem) {
  1490 + Polymer.dom(this).removeChild(this._offscreenFocusedItem);
  1491 + }
  1492 + this._offscreenFocusedItem = null;
  1493 + this._focusBackfillItem = null;
  1494 + this._focusedItem = null;
  1495 + this._focusedIndex = -1;
  1496 + },
  1497 +
  1498 + _createFocusBackfillItem: function() {
  1499 + var pidx, fidx = this._focusedIndex;
  1500 + if (this._offscreenFocusedItem || fidx < 0) {
  1501 + return;
  1502 + }
  1503 + if (!this._focusBackfillItem) {
  1504 + // create a physical item, so that it backfills the focused item.
  1505 + var stampedTemplate = this.stamp(null);
  1506 + this._focusBackfillItem = stampedTemplate.root.querySelector('*');
  1507 + Polymer.dom(this).appendChild(stampedTemplate.root);
  1508 + }
  1509 + // get the physical index for the focused index
  1510 + pidx = this._getPhysicalIndex(fidx);
  1511 +
  1512 + if (pidx != null) {
  1513 + // set the offcreen focused physical item
  1514 + this._offscreenFocusedItem = this._physicalItems[pidx];
  1515 + // backfill the focused physical item
  1516 + this._physicalItems[pidx] = this._focusBackfillItem;
  1517 + // hide the focused physical
  1518 + this.translate3d(0, HIDDEN_Y, 0, this._offscreenFocusedItem);
  1519 + }
  1520 + },
  1521 +
  1522 + _restoreFocusedItem: function() {
  1523 + var pidx, fidx = this._focusedIndex;
  1524 +
  1525 + if (!this._offscreenFocusedItem || this._focusedIndex < 0) {
  1526 + return;
  1527 + }
  1528 + // assign models to the focused index
  1529 + this._assignModels();
  1530 + // get the new physical index for the focused index
  1531 + pidx = this._getPhysicalIndex(fidx);
  1532 +
  1533 + if (pidx != null) {
  1534 + // flip the focus backfill
  1535 + this._focusBackfillItem = this._physicalItems[pidx];
  1536 + // restore the focused physical item
  1537 + this._physicalItems[pidx] = this._offscreenFocusedItem;
  1538 + // reset the offscreen focused item
  1539 + this._offscreenFocusedItem = null;
  1540 + // hide the physical item that backfills
  1541 + this.translate3d(0, HIDDEN_Y, 0, this._focusBackfillItem);
  1542 + }
  1543 + },
  1544 +
  1545 + _didFocus: function(e) {
  1546 + var targetModel = this.modelForElement(e.target);
  1547 + var focusedModel = this._focusedItem ? this._focusedItem._templateInstance : null;
  1548 + var hasOffscreenFocusedItem = this._offscreenFocusedItem !== null;
  1549 + var fidx = this._focusedIndex;
  1550 +
  1551 + if (!targetModel || !focusedModel) {
  1552 + return;
  1553 + }
  1554 + if (focusedModel === targetModel) {
  1555 + // if the user focused the same item, then bring it into view if it's not visible
  1556 + if (!this._isIndexVisible(fidx)) {
  1557 + this.scrollToIndex(fidx);
  1558 + }
  1559 + } else {
  1560 + this._restoreFocusedItem();
  1561 + // restore tabIndex for the currently focused item
  1562 + focusedModel.tabIndex = -1;
  1563 + // set the tabIndex for the next focused item
  1564 + targetModel.tabIndex = 0;
  1565 + fidx = targetModel[this.indexAs];
  1566 + this._focusedIndex = fidx;
  1567 + this._focusedItem = this._physicalItems[this._getPhysicalIndex(fidx)];
  1568 +
  1569 + if (hasOffscreenFocusedItem && !this._offscreenFocusedItem) {
  1570 + this._update();
  1571 + }
  1572 + }
  1573 + },
  1574 +
  1575 + _didMoveUp: function() {
  1576 + this._focusPhysicalItem(this._focusedIndex - 1);
  1577 + },
  1578 +
  1579 + _didMoveDown: function() {
  1580 + this._focusPhysicalItem(this._focusedIndex + 1);
  1581 + },
  1582 +
  1583 + _didEnter: function(e) {
  1584 + this._focusPhysicalItem(this._focusedIndex);
  1585 + this._selectionHandler(e.detail.keyboardEvent);
1304 1586 }
1305 1587 });
1306 1588  
... ...
bower_components/iron-list/test/basic.html 100755 → 100644
... ... @@ -16,9 +16,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19  
21   - <link rel="import" href="../../test-fixture/test-fixture.html">
22 20 <link rel="import" href="helpers.html">
23 21 <link rel="import" href="x-list.html">
24 22 </head>
... ... @@ -41,9 +39,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
41 39 });
42 40  
43 41 test('defaults', function() {
44   - assert.equal(list.items, null);
45   - assert.equal(list.as, 'item');
46   - assert.equal(list.indexAs, 'index');
  42 + assert.equal(list.items, null, 'items');
  43 + assert.equal(list.as, 'item', 'as');
  44 + assert.equal(list.indexAs, 'index', 'indexAs');
  45 + assert.equal(list.selectedAs, 'selected', 'selectedAs');
  46 + assert.equal(list.scrollTarget, list, 'scrollTarget');
  47 + assert.isFalse(list.selectionEnabled, 'selectionEnabled');
  48 + assert.isFalse(list.multiSelection, 'multiSelection');
47 49 });
48 50  
49 51 test('check items length', function(done) {
... ... @@ -84,7 +86,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
84 86  
85 87 flush(function() {
86 88 var setSize = list.items.length;
87   - var rowHeight = list._physicalItems[0].offsetHeight;
  89 + var rowHeight = container.itemHeight;
88 90 var viewportHeight = list.offsetHeight;
89 91 var scrollToItem;
90 92  
... ... @@ -93,31 +95,39 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
93 95 assert.equal(getFirstItemFromList(list).textContent, scrollToItem);
94 96 }
95 97  
  98 + function checkLastVisible() {
  99 + var visibleItemsCount = Math.floor(viewportHeight / rowHeight);
  100 + assert.equal(list.lastVisibleIndex, scrollToItem + visibleItemsCount - 1);
  101 + assert.equal(getLastItemFromList(list).textContent, scrollToItem + visibleItemsCount - 1);
  102 + }
  103 +
96 104 function doneScrollDown() {
97 105 checkFirstVisible();
98   -
  106 + checkLastVisible();
99 107 scrollToItem = 1;
100   -
101 108 flush(function() {
102 109 simulateScroll({
103 110 list: list,
104 111 contribution: rowHeight,
105   - target: scrollToItem*rowHeight
106   - }, doneScrollUp);
  112 + target: scrollToItem*rowHeight,
  113 + onScrollEnd: doneScrollUp
  114 + });
107 115 });
108 116 }
109 117  
110 118 function doneScrollUp() {
111 119 checkFirstVisible();
  120 + checkLastVisible();
112 121 done();
113 122 }
114   -
115 123 scrollToItem = 50;
  124 +
116 125 simulateScroll({
117 126 list: list,
118 127 contribution: 50,
119   - target: scrollToItem*rowHeight
120   - }, doneScrollDown);
  128 + target: scrollToItem*rowHeight,
  129 + onScrollEnd: doneScrollDown
  130 + });
121 131  
122 132 });
123 133 });
... ... @@ -125,7 +135,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
125 135 test('scroll to index', function(done) {
126 136 list.items = buildDataSet(100);
127 137  
128   - flush(function() {
  138 + setTimeout(function() {
129 139 list.scrollToIndex(30);
130 140 assert.equal(list.firstVisibleIndex, 30);
131 141  
... ... @@ -148,25 +158,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
148 158 assert.equal(list.firstVisibleIndex, 99);
149 159 done();
150 160 }, 100);
151   -
152   - });
  161 + }, 100);
153 162 });
154 163  
155 164 test('reset items', function(done) {
156 165 list.items = buildDataSet(100);
157 166  
158 167 flush(function() {
159   - var firstItem = getFirstItemFromList(list);
160   - assert.equal(firstItem.textContent, '0');
  168 + assert.equal(getFirstItemFromList(list).textContent, '0');
161 169  
162 170 list.items = null;
163 171  
164 172 flush(function() {
165   - assert.notEqual(getFirstItemFromList(list), firstItem);
  173 + assert.notEqual(getFirstItemFromList(list).textContent, '0');
166 174 list.items = buildDataSet(100);
167 175  
168 176 flush(function() {
169   - assert.equal(getFirstItemFromList(list), firstItem);
  177 + assert.equal(getFirstItemFromList(list).textContent, '0');
170 178 done();
171 179 });
172 180 });
... ...
bower_components/iron-list/test/different-heights.html 100755 → 100644
... ... @@ -16,11 +16,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19 <script src="../../iron-test-helpers/mock-interactions.js"></script>
21 20  
22   - <link rel="import" href="../../test-fixture/test-fixture.html">
23   - <link rel="import" href="../../paper-styles/paper-styles.html">
24 21 <link rel="import" href="helpers.html">
25 22 <link rel="import" href="x-list.html">
26 23  
... ... @@ -60,16 +57,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
60 57 {index: 8, height: 51}
61 58 );
62 59  
63   - list.addEventListener('scroll', function() {
64   - assert.isTrue(isFullOfItems(list));
65   - });
66   -
67 60 simulateScroll({
68 61 list: list,
69   - contribution: 15,
70   - target: 100000
71   - }, function() {
72   - done();
  62 + contribution: 20,
  63 + target: 100000,
  64 + onScrollEnd: done,
  65 + onScroll: function() {
  66 + list.debounce('scroll', function() {
  67 + assert.isTrue(isFullOfItems(list));
  68 + });
  69 + }
73 70 });
74 71 });
75 72 });
... ... @@ -84,16 +81,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
84 81 list.items = items;
85 82  
86 83 flush(function() {
87   - list.addEventListener('scroll', function() {
88   - assert.isTrue(isFullOfItems(list));
89   - });
90   -
91 84 simulateScroll({
92 85 list: list,
93 86 contribution: 20,
94   - target: 100000
95   - }, function() {
96   - done();
  87 + target: 100000,
  88 + onScrollEnd: done,
  89 + onScroll: function() {
  90 + list.debounce('scroll', function() {
  91 + assert.equal(isFullOfItems(list), true);
  92 + });
  93 + }
97 94 });
98 95 });
99 96 });
... ... @@ -106,16 +103,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
106 103 });
107 104  
108 105 flush(function() {
109   - list.addEventListener('scroll', function() {
110   - assert.isTrue(isFullOfItems(list));
111   - });
112   -
113 106 simulateScroll({
114 107 list: list,
115 108 contribution: 20,
116   - target: 100000
117   - }, function() {
118   - done();
  109 + target: 100000,
  110 + onScrollEnd: done,
  111 + onScroll: function() {
  112 + list.debounce('scroll', function() {
  113 + assert.isTrue(isFullOfItems(list));
  114 + });
  115 + }
119 116 });
120 117 });
121 118 });
... ...
bower_components/iron-list/test/dynamic-item-size.html 100755 → 100644
... ... @@ -16,11 +16,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19 <script src="../../iron-test-helpers/mock-interactions.js"></script>
21 20  
22   - <link rel="import" href="../../test-fixture/test-fixture.html">
23   - <link rel="import" href="../../paper-styles/paper-styles.html">
24 21 <link rel="import" href="helpers.html">
25 22 <link rel="import" href="x-list.html">
26 23  
... ... @@ -85,7 +82,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
85 82 list.items = buildDataSet(100);
86 83  
87 84 flush(function() {
88   - list.updateSizeForItem(list.items[list._physicalCount + 1]);
  85 + list.updateSizeForItem(list.items[list.items.length - 1]);
89 86 done();
90 87 });
91 88 });
... ...
bower_components/iron-list/test/focus.html 0 → 100644
  1 +<!doctype html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
  10 +-->
  11 +<html>
  12 +<head>
  13 + <meta charset="UTF-8">
  14 + <title>iron-list test</title>
  15 + <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
  16 +
  17 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  18 + <script src="../../iron-test-helpers/mock-interactions.js"></script>
  19 + <script src="../../web-component-tester/browser.js"></script>
  20 +
  21 + <link rel="import" href="helpers.html">
  22 + <link rel="import" href="x-list.html">
  23 +</head>
  24 +<body>
  25 +
  26 + <test-fixture id="trivialList">
  27 + <template>
  28 + <x-list></x-list>
  29 + </template>
  30 + </test-fixture>
  31 +
  32 +<script>
  33 +
  34 + suite('basic features', function() {
  35 + var list, container;
  36 +
  37 + setup(function() {
  38 + container = fixture('trivialList');
  39 + list = container.list;
  40 + });
  41 +
  42 + test('first item should be focusable', function(done) {
  43 + container.data = buildDataSet(100);
  44 +
  45 + flush(function() {
  46 + console.log(getFirstItemFromList(list));
  47 + assert.notEqual(getFirstItemFromList(list).tabIndex, -1);
  48 + done();
  49 + });
  50 + });
  51 +
  52 + test('focus the first item and then reset the items', function(done) {
  53 + list.items = buildDataSet(100);
  54 +
  55 + flush(function() {
  56 + getFirstItemFromList(list).focus();
  57 +
  58 + simulateScroll({
  59 + list: list,
  60 + contribution: 200,
  61 + target: 3000,
  62 + onScrollEnd: function() {
  63 + list.items = [];
  64 + flush(function() {
  65 + done();
  66 + });
  67 + }
  68 + });
  69 + });
  70 + });
  71 +
  72 + test('focus the first item and then splice all the items', function(done) {
  73 + list.items = buildDataSet(100);
  74 +
  75 + flush(function() {
  76 + getFirstItemFromList(list).focus();
  77 +
  78 + simulateScroll({
  79 + list: list,
  80 + contribution: 200,
  81 + target: 3000,
  82 + onScrollEnd: function() {
  83 + list.splice('items', 0, list.items.length);
  84 + flush(function() {
  85 + done();
  86 + });
  87 + }
  88 + });
  89 + });
  90 + });
  91 +
  92 + test('should not hide the list', function(done) {
  93 + list.items = buildDataSet(100);
  94 +
  95 + flush(function() {
  96 + // this index isn't rendered yet
  97 + list._focusedIndex = list.items.length-1;
  98 + list.scrollTarget.addEventListener('scroll', function() {
  99 + var rect = list.getBoundingClientRect();
  100 + assert.isTrue(rect.top + rect.height > 0);
  101 + done();
  102 + });
  103 + // trigger the scroll event
  104 + list._scrollTop = 1000;
  105 + });
  106 + });
  107 +
  108 + });
  109 +
  110 +</script>
  111 +
  112 +</body>
  113 +</html>
... ...
bower_components/iron-list/test/helpers.html 100755 → 100644
... ... @@ -36,41 +36,48 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
36 36 return data;
37 37 }
38 38  
39   - function simulateScroll(config, fn) {
  39 + function simulateScroll(config) {
40 40 var list = config.list;
41 41 var target = config.target;
42 42 var delay = config.delay || 1;
43   - var contribution = config.contribution || 10;
44   -
45   - function scroll(dir, prevVal) {
46   - if ((dir > 0 && list.scrollTop >= target) ||
47   - (dir < 0 && list.scrollTop <= target) ||
48   - list.scrollTop === prevVal
49   - ){
50   - list.scrollTop = target;
51   - setTimeout(fn.bind(null, list.scrollTop), 100);
52   - return;
53   - }
54   - prevVal = list.scrollTop;
55   - list.scrollTop = list.scrollTop + dir;
56   - setTimeout(scroll.bind(null, dir, prevVal), delay);
  43 + var contribution = Math.abs(config.contribution) || 10;
  44 + // scroll back up
  45 + if (target < list.scrollTop) {
  46 + contribution = -contribution;
57 47 }
58 48  
59   - if (list.scrollTop < target) {
60   - scroll(Math.abs(contribution), -1);
61   - } else if (list.scrollTop > target) {
62   - scroll(-Math.abs(contribution), -1);
  49 + function scrollHandler() {
  50 + setTimeout(function() {
  51 + var minScrollTop = 0;
  52 + var maxScrollTop = list.scrollHeight - list.offsetHeight;
  53 +
  54 + config.onScroll && config.onScroll();
  55 +
  56 + if (list.scrollTop < target && contribution > 0 && list.scrollTop < maxScrollTop) {
  57 + list.scrollTop = Math.min(maxScrollTop, list.scrollTop + contribution);
  58 +
  59 + } else if (list.scrollTop > target && contribution < 0 && list.scrollTop > minScrollTop) {
  60 + list.scrollTop = Math.max(minScrollTop, list.scrollTop + contribution);
  61 +
  62 + } else {
  63 + list.removeEventListener('scroll', scrollHandler);
  64 + list.scrollTop = target;
  65 + config.onScrollEnd && config.onScrollEnd();
  66 + }
  67 + }, delay);
63 68 }
  69 + list.addEventListener('scroll', scrollHandler);
  70 + scrollHandler();
64 71 }
65 72  
66 73 function getFirstItemFromList(list) {
67 74 var listRect = list.getBoundingClientRect();
68   - return document.elementFromPoint(listRect.left + 1, listRect.top + 1);
  75 + return document.elementFromPoint(listRect.left + 100, listRect.top + 1);
69 76 }
70 77  
71 78 function getLastItemFromList(list) {
72 79 var listRect = list.getBoundingClientRect();
73   - return document.elementFromPoint(listRect.left + 1, listRect.top + listRect.height - 1);
  80 + return document.elementFromPoint(listRect.left + 100, listRect.top + listRect.height - 1);
74 81 }
75 82  
76 83 function isFullOfItems(list) {
... ... @@ -80,15 +87,39 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
80 87 // IE 10 & 11 doesn't render propertly :(
81 88 var badPixels = 0;
82 89 while (y < listHeight) {
83   - item = document.elementFromPoint(listRect.left + 1, y);
84   - if (item.parentNode && !item.parentNode._templateInstance) {
  90 + item = document.elementFromPoint(listRect.left + 100, y);
  91 + if (!item || (item.parentNode && !item.parentNode._templateInstance)) {
85 92 badPixels++;
86 93 }
87   - if (badPixels > 3) {
  94 + y++;
  95 + if (badPixels > 2) {
88 96 return false;
89 97 }
90   - y += 2;
91 98 }
92 99 return true;
93 100 }
  101 +
  102 + function checkRepeatedItems(list) {
  103 + var listRect = list.getBoundingClientRect();
  104 + var listHeight = list.offsetHeight;
  105 + var listItems = {};
  106 +
  107 + return function() {
  108 + var itemKey;
  109 + var y = listRect.top;
  110 + while (y < listHeight) {
  111 + item = document.elementFromPoint(listRect.left + 100, y + 2);
  112 + itemKey = item.textContent || item.innerText;
  113 +
  114 + if (item.parentNode && item.parentNode._templateInstance) {
  115 + if (listItems[itemKey] && listItems[itemKey] != item) {
  116 + return true;
  117 + }
  118 + listItems[itemKey] = item;
  119 + }
  120 + y += item.offsetHeight;
  121 + }
  122 + return false;
  123 + };
  124 + }
94 125 </script>
... ...
bower_components/iron-list/test/hidden-list.html 100755 → 100644
... ... @@ -16,10 +16,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19  
21   - <link rel="import" href="../../test-fixture/test-fixture.html">
22   - <link rel="import" href="../../paper-styles/paper-styles.html">
23 20 <link rel="import" href="helpers.html">
24 21 <link rel="import" href="x-list.html">
25 22  
... ... @@ -54,7 +51,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
54 51 test('iron-resize', function(done) {
55 52 list.items = buildDataSet(100);
56 53 list.fire('iron-resize');
57   -
  54 +
58 55 assert.notEqual(getFirstItemFromList(list).textContent, '0');
59 56 Polymer.RenderStatus.whenReady(function() {
60 57 container.removeAttribute('hidden');
... ...
bower_components/iron-list/test/index.html 100755 → 100644
... ... @@ -19,6 +19,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
19 19 <script>
20 20 WCT.loadSuites([
21 21 'basic.html',
  22 + 'focus.html',
22 23 'mutations.html',
23 24 'physical-count.html',
24 25 'hidden-list.html',
... ...
bower_components/iron-list/test/mutations.html 100755 → 100644
... ... @@ -16,9 +16,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19  
21   - <link rel="import" href="../../test-fixture/test-fixture.html">
22 20 <link rel="import" href="helpers.html">
23 21 <link rel="import" href="x-list.html">
24 22 </head>
... ... @@ -30,9 +28,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
30 28 </template>
31 29 </test-fixture>
32 30  
  31 + <test-fixture id="trivialListPrimitiveItem">
  32 + <template>
  33 + <x-list primitive></x-list>
  34 + </template>
  35 + </test-fixture>
  36 +
33 37 <script>
34 38  
35   - suite('mutations to items', function() {
  39 + suite('mutations to the collection of items', function() {
36 40 var list, container;
37 41  
38 42 setup(function() {
... ... @@ -63,26 +67,26 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
63 67 function scrollBackUp() {
64 68 simulateScroll({
65 69 list: list,
66   - contribution: 100,
67   - target: 0
68   - }, function() {
69   - flush(function() {
70   - assert.equal(getFirstItemFromList(list).textContent, phrase);
71   - done();
72   - });
  70 + contribution: 200,
  71 + target: 0,
  72 + onScrollEnd: function() {
  73 + assert.equal(getFirstItemFromList(list).textContent, phrase);
  74 + done();
  75 + }
73 76 });
74 77 }
75 78  
76 79 flush(function() {
77   - var rowHeight = list._physicalItems[0].offsetHeight;
  80 + var rowHeight = getFirstItemFromList(list).offsetHeight;
78 81 // scroll down
79 82 simulateScroll({
80 83 list: list,
81   - contribution: 100,
82   - target: setSize*rowHeight
83   - }, function() {
84   - list.set('items.0.index', phrase);
85   - flush(scrollBackUp);
  84 + contribution: 200,
  85 + target: setSize*rowHeight,
  86 + onScrollEnd: function() {
  87 + list.set('items.0.index', phrase);
  88 + scrollBackUp();
  89 + }
86 90 });
87 91 });
88 92 });
... ... @@ -105,38 +109,60 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
105 109  
106 110 simulateScroll({
107 111 list: list,
108   - contribution: rowHeight,
109   - target: list.items.length*rowHeight
110   - }, function() {
111   - assert.equal(getFirstItemFromList(list).textContent,
  112 + contribution: 200,
  113 + target: list.items.length*rowHeight,
  114 + onScrollEnd: function() {
  115 + assert.equal(getFirstItemFromList(list).textContent,
112 116 list.items.length - itemsPerViewport);
113   - done();
  117 + done();
  118 + }
114 119 });
115 120 })
116 121 });
117 122  
  123 + test('push and scroll to bottom', function(done) {
  124 + list.items = [buildItem(0)];
  125 +
  126 + flush(function() {
  127 + var rowHeight = getFirstItemFromList(list).offsetHeight;
  128 + var viewportHeight = list.offsetHeight;
  129 + var itemsPerViewport = Math.floor(viewportHeight/rowHeight);
  130 +
  131 + while (list.items.length < 200) {
  132 + list.push('items', buildItem(list.items.length));
  133 + }
  134 +
  135 + list.scrollToIndex(list.items.length - 1);
  136 + assert.isTrue(isFullOfItems(list));
  137 + assert.equal(getFirstItemFromList(list).textContent.trim(),
  138 + list.items.length - itemsPerViewport);
  139 + done();
  140 + });
  141 + });
  142 +
118 143 test('pop', function(done) {
119 144 var setSize = 100;
120 145 list.items = buildDataSet(setSize);
121 146  
122 147 flush(function() {
123   - var rowHeight = list._physicalItems[0].offsetHeight;
  148 + var rowHeight = getFirstItemFromList(list).offsetHeight;
124 149  
125 150 simulateScroll({
126 151 list: list,
127   - contribution: rowHeight,
128   - target: setSize*rowHeight
129   - }, function() {
130   - var viewportHeight = list.offsetHeight;
131   - var itemsPerViewport = Math.floor(viewportHeight/rowHeight);
132   -
133   - list.pop('items');
134   -
135   - flush(function() {
136   - assert.equal(list.items.length, setSize-1);
137   - assert.equal(getFirstItemFromList(list).textContent, setSize - 3 - 1);
138   - done();
139   - });
  152 + contribution: 200,
  153 + target: setSize*rowHeight,
  154 + onScrollEnd: function() {
  155 + var viewportHeight = list.offsetHeight;
  156 + var itemsPerViewport = Math.floor(viewportHeight/rowHeight);
  157 +
  158 + list.pop('items');
  159 +
  160 + flush(function() {
  161 + assert.equal(list.items.length, setSize-1);
  162 + assert.equal(getFirstItemFromList(list).textContent, setSize - 3 - 1);
  163 + done();
  164 + });
  165 + }
140 166 });
141 167 });
142 168 });
... ... @@ -168,7 +194,98 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
168 194 }
169 195 });
170 196  
  197 + test('reassign items', function(done) {
  198 + list.items = buildDataSet(100);
  199 + container.itemHeight = 'auto';
  200 +
  201 + flush(function() {
  202 + var itemHeight = getFirstItemFromList(list).offsetHeight;
  203 + var hasRepeatedItems = checkRepeatedItems(list);
  204 +
  205 + simulateScroll({
  206 + list: list,
  207 + contribution: 200,
  208 + target: itemHeight * list.items.length,
  209 + onScrollEnd: function() {
  210 + list.items = list.items.slice(0);
  211 + simulateScroll({
  212 + list: list,
  213 + contribution: itemHeight,
  214 + target: itemHeight * list.items.length,
  215 + onScroll: function() {
  216 + assert.isFalse(hasRepeatedItems(), 'List should not have repeated items');
  217 + },
  218 + onScrollEnd: done
  219 + });
  220 + }
  221 + });
  222 + });
  223 + });
  224 +
  225 + test('empty items array', function(done) {
  226 + list.items = buildDataSet(100);
  227 +
  228 + flush(function() {
  229 + list.items = [];
  230 + flush(function() {
  231 + assert.notEqual(getFirstItemFromList(list).textContent, '0');
  232 + done();
  233 + });
  234 + });
  235 + });
  236 +
  237 + test('should notify path to the right physical item', function(done) {
  238 + list.items = buildDataSet(100);
  239 + flush(function() {
  240 + var idx = list._physicalCount + 1;
  241 +
  242 + list.scrollToIndex(idx);
  243 + list.notifyPath('items.1.index', 'bad');
  244 + assert.equal(getFirstItemFromList(list).textContent, idx);
  245 + done();
  246 + });
  247 + });
  248 + });
  249 +
  250 + suite('mutations of primitive type items', function() {
  251 + var container, list;
  252 +
  253 + setup(function() {
  254 + container = fixture('trivialListPrimitiveItem');
  255 + list = container.list;
  256 + });
  257 +
  258 + test('push item = polymer', function(done) {
  259 + list.items = [];
  260 + list.push('items', 'polymer');
  261 +
  262 + flush(function() {
  263 + assert.equal(getFirstItemFromList(list).textContent, 'polymer');
  264 + done();
  265 + });
  266 + });
  267 +
  268 + test('push item = 0', function(done) {
  269 + list.items = [];
  270 + list.push('items', 0);
  271 +
  272 + flush(function() {
  273 + assert.equal(getFirstItemFromList(list).textContent, '0');
  274 + done();
  275 + });
  276 + });
  277 +
  278 + test('push item = false', function(done) {
  279 + list.items = [];
  280 + list.push('items', false);
  281 +
  282 + flush(function() {
  283 + assert.equal(getFirstItemFromList(list).textContent, 'false');
  284 + done();
  285 + });
  286 + });
171 287 });
  288 +
172 289 </script>
173 290  
174 291 </body>
... ...
bower_components/iron-list/test/physical-count.html 100755 → 100644
... ... @@ -16,10 +16,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19  
21   - <link rel="import" href="../../test-fixture/test-fixture.html">
22   - <link rel="import" href="../../paper-styles/paper-styles.html">
23 20 <link rel="import" href="helpers.html">
24 21 <link rel="import" href="x-list.html">
25 22  
... ... @@ -28,7 +25,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
28 25  
29 26 <test-fixture id="trivialList">
30 27 <template>
31   - <x-list item-height="2" list-height="300"></x-list>
  28 + <x-list list-height="100" item-height="2"></x-list>
  29 + </template>
  30 + </test-fixture>
  31 +
  32 + <test-fixture id="trivialListSmall">
  33 + <template>
  34 + <x-list list-height="2" item-height="2"></x-list>
32 35 </template>
33 36 </test-fixture>
34 37  
... ... @@ -40,38 +43,45 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
40 43 setup(function() {
41 44 container = fixture('trivialList');
42 45 list = container.list;
  46 + list.items = buildDataSet(200);
43 47 });
44 48  
45 49 test('increase pool size', function(done) {
46   - list.items = buildDataSet(1000);
  50 + setTimeout(function() {
  51 + list.scrollTop = 0;
47 52  
48   - flush(function() {
49 53 var lastItem = getLastItemFromList(list);
50 54 var lastItemHeight = lastItem.offsetHeight;
51   - var expectedFinalItem = list.offsetHeight/lastItemHeight;
  55 + var expectedFinalItem = container.listHeight/lastItemHeight - 1;
52 56  
  57 + assert.equal(list.offsetHeight, container.listHeight);
53 58 assert.equal(lastItemHeight, 2);
54   - assert.equal(getLastItemFromList(list).textContent, expectedFinalItem);
  59 + assert.isTrue(isFullOfItems(list));
  60 + assert.equal(lastItem.textContent, expectedFinalItem);
55 61 done();
56   - });
  62 + }, 100);
57 63 });
  64 + });
58 65  
59   - test('increase pool size on resize', function(done) {
60   - list.items = buildDataSet(1000);
  66 + suite('iron-resize', function() {
  67 + var list, container;
61 68  
  69 + setup(function() {
  70 + container = fixture('trivialListSmall');
  71 + list = container.list;
  72 + list.style.display = 'none';
  73 + list.items = buildDataSet(200);
  74 + });
  75 +
  76 + test('increase pool size after resizing the list', function(done) {
62 77 flush(function() {
63   - // change the height of the list
64   - container.listHeight = 500;
65   - // resize
  78 + list.style.display = '';
  79 + assert.notEqual(getFirstItemFromList(list).textContent, '0', 'Item should not be rendered');
  80 +
66 81 list.fire('iron-resize');
67 82  
68 83 flush(function() {
69   - var lastItem = getLastItemFromList(list);
70   - var lastItemHeight = lastItem.offsetHeight;
71   - var expectedFinalItem = list.offsetHeight/lastItemHeight;
72   -
73   - assert.equal(lastItemHeight, 2);
74   - assert.equal(getLastItemFromList(list).textContent, expectedFinalItem);
  84 + assert.equal(getFirstItemFromList(list).textContent, '0', 'Item should be rendered');
75 85 done();
76 86 });
77 87 });
... ...
bower_components/iron-list/test/selection.html 100755 → 100644
... ... @@ -16,11 +16,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
16 16  
17 17 <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18 18 <script src="../../web-component-tester/browser.js"></script>
19   - <script src="../../test-fixture/test-fixture-mocha.js"></script>
20 19 <script src="../../iron-test-helpers/mock-interactions.js"></script>
21 20  
22   - <link rel="import" href="../../test-fixture/test-fixture.html">
23   - <link rel="import" href="../../paper-styles/paper-styles.html">
24 21 <link rel="import" href="helpers.html">
25 22 <link rel="import" href="x-list.html">
26 23  
... ... @@ -29,7 +26,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
29 26  
30 27 <test-fixture id="trivialList">
31 28 <template>
32   - <x-list></x-list>
  29 + <x-list item-height="10"></x-list>
33 30 </template>
34 31 </test-fixture>
35 32  
... ... @@ -321,7 +318,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
321 318 assert.isFalse(list._physicalItems[0]._templateInstance.selected);
322 319 assert.isTrue(list._physicalItems[10]._templateInstance.selected);
323 320  
324   -
325 321 done();
326 322 });
327 323 });
... ...
bower_components/iron-list/test/smoke/avg-worst-case.html 100755 → 100644
... ... @@ -22,11 +22,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
22 22 <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
23 23  
24 24 <link rel="import" href="../../../polymer/polymer.html">
25   - <link rel="import" href="../../../paper-styles/paper-styles.html">
26 25 <link rel="import" href="../../iron-list.html">
27 26  
28 27 <style is="custom-style">
29   -
  28 + body {
  29 + @apply(--layout-fullbleed);
  30 + }
  31 +
30 32 iron-list {
31 33 width: 500px;
32 34 height: 400px;
... ... @@ -36,35 +38,35 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
36 38  
37 39 .item {
38 40 background-color: green;
39   - border-bottom: 1px solid white;
  41 + border-bottom: 1px solid white;
40 42 }
41 43  
42 44 </style>
43 45  
44 46 </head>
45   -<body class="fullbleed" unresolved>
  47 +<body unresolved>
46 48  
47 49 <template is="dom-bind">
48   -
49   - <h1>The physical avarage is not useful in this situations</h1>
  50 +
  51 + <h1>The physical average is not useful in this situations</h1>
50 52 <p>The list is correct if it can render all the items without empty spaces.</p>
51 53 <iron-list id="list" items="[791, 671]" as="item" style="width: 300px; height: 300px;">
52 54 <template>
53   - <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
  55 + <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
54 56 </div>
55 57 </template>
56 58 </iron-list>
57 59  
58 60 <iron-list id="list2" items="[791, 671]" as="item" style="width: 710px; height: 453px;">
59 61 <template>
60   - <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
  62 + <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
61 63 </div>
62 64 </template>
63 65 </iron-list>
64 66  
65 67 <iron-list items="[512, 256, 128, 64, 16, 16, 16, 16, 16, 16, 8, 4]" as="item" style="height: 256px;">
66 68 <template>
67   - <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
  69 + <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
68 70 </div>
69 71 </template>
70 72 </iron-list>
... ...
bower_components/iron-list/test/smoke/dummy-data.html 100755 → 100644
bower_components/iron-list/test/smoke/index.html 100755 → 100644
... ... @@ -20,6 +20,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
20 20 <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
21 21  
22 22 <link rel="import" href="../../../polymer/polymer.html">
  23 + <link rel="import" href="../../../paper-styles/paper-styles.html">
  24 +
23 25 <link rel="import" href="../../../iron-flex-layout/iron-flex-layout.html">
24 26 <link rel="import" href="../../iron-list.html">
25 27 <link rel="import" href="dummy-data.html">
... ... @@ -35,6 +37,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
35 37  
36 38 iron-list {
37 39 @apply(--layout-flex);
  40 + height: 100%;
38 41 }
39 42  
40 43 .item {
... ... @@ -188,7 +191,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
188 191 </script>
189 192  
190 193 <style is="custom-style">
191   - x-app {
  194 + body, x-app {
192 195 @apply(--layout-fit);
193 196 }
194 197 </style>
... ... @@ -196,7 +199,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
196 199 </head>
197 200 <body unresolved>
198 201  
199   - <x-app class="flex"></x-app>
  202 + <x-app></x-app>
200 203  
201 204 </body>
202 205 </html>
... ...
bower_components/iron-list/test/smoke/physical-count.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<!doctype html>
  12 +<html>
  13 +<head>
  14 +
  15 + <title>physical count</title>
  16 +
  17 + <meta charset="utf-8">
  18 + <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  19 + <meta name="mobile-web-app-capable" content="yes">
  20 + <meta name="apple-mobile-web-app-capable" content="yes">
  21 +
  22 + <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
  23 +
  24 + <link rel="import" href="../../../polymer/polymer.html">
  25 + <link rel="import" href="../../../paper-button/paper-button.html">
  26 +
  27 + <link rel="import" href="../../iron-list.html">
  28 +
  29 + <style is="custom-style">
  30 + body {
  31 + @apply(--layout-fullbleed);
  32 + }
  33 +
  34 + .item {
  35 + background-color: green;
  36 + border-bottom: 1px solid white;
  37 + overflow:hidden;
  38 + }
  39 +
  40 + .wrapper {
  41 + position: relative;
  42 + margin: 10px;
  43 + }
  44 +
  45 + .wrapper .count {
  46 + background-color: red;
  47 + position: absolute;
  48 + top: 0;
  49 + right: 0;
  50 + z-index: 1;
  51 + }
  52 + .wrapper .stats {
  53 + background-color: red;
  54 + position: absolute;
  55 + top: 20px;
  56 + right: 0;
  57 + z-index: 1;
  58 + }
  59 +
  60 + .wrapper iron-list {
  61 + position: absolute;
  62 + top: 0;
  63 + left: 0;
  64 + right: 0;
  65 + bottom: 0;
  66 + }
  67 +
  68 + .group {
  69 + float: left;
  70 + }
  71 +
  72 + </style>
  73 +
  74 +</head>
  75 +<body unresolved>
  76 +
  77 + <template is="dom-bind">
  78 +
  79 + <h1>Physical count</h1>
  80 + <p>In red you can see the last physical count values</p>
  81 + <div class="group">
  82 + <p>100 items, 50px tall</p>
  83 + <div class="wrapper" style="width: 300px; height: 300px;">
  84 + <iron-list id="list1" as="item">
  85 + <template>
  86 + <div class="item" style$="[[_getStyle(item)]]"><span>[[index]]</span> height: <span>[[item]]</span>
  87 + <div>
  88 + <paper-button raised>Test</paper-button>
  89 + <paper-button raised>Test</paper-button>
  90 + <paper-button raised>Test</paper-button>
  91 + <paper-button raised>Test</paper-button>
  92 + </div>
  93 + </div>
  94 + </template>
  95 + </iron-list>
  96 + </div>
  97 + </div>
  98 +<!--
  99 + <div class="group">
  100 + <p>100 items, 300px tall</p>
  101 + <div class="wrapper" style="width: 300px; height: 300px;">
  102 + <iron-list id="list2" as="item">
  103 + <template>
  104 + <div class="item" style$="[[_getStyle(item)]]">
  105 + <span>[[index]]</span> height: <span>[[item]]</span>
  106 + </div>
  107 + </template>
  108 + </iron-list>
  109 + </div>
  110 +</div>
  111 +<div class="group">
  112 + <p>1000 items, 2px tall</p>
  113 + <div class="wrapper" style="width: 300px; height: 300px;">
  114 + <iron-list id="list3" as="item">
  115 + <template>
  116 + <div class="item" style$="[[_getStyle(item)]]">
  117 + <span>[[index]]</span> height: <span>[[item]]</span>
  118 + </div>
  119 + </template>
  120 + </iron-list>
  121 + </div>
  122 +</div>
  123 +<div class="group">
  124 + <p>First two items: 2px tall, next 100 items are 300px tall</p>
  125 + <div class="wrapper" style="width: 300px; height: 300px;">
  126 + <iron-list id="list4" as="item">
  127 + <template>
  128 + <div class="item" style$="[[_getStyle(item)]]">
  129 + <span>[[index]]</span> height: <span>[[item]]</span>
  130 + </div>
  131 + </template>
  132 + </iron-list>
  133 + </div>
  134 +</div>
  135 +<div class="group">
  136 + <p>100 items, 600px tall</p>
  137 + <div class="wrapper" style="width: 300px; height: 300px;">
  138 + <iron-list id="list5" as="item">
  139 + <template>
  140 + <div class="item" style$="[[_getStyle(item)]]">
  141 + <span>[[index]]</span> height: <span>[[item]]</span>
  142 + </div>
  143 + </template>
  144 + </iron-list>
  145 + </div>
  146 +</div>
  147 +<div class="group">
  148 + <p>1 item that is 2px tall, <br /> and then add 100 items async with different heights </p>
  149 + <div class="wrapper" style="width: 300px; height: 300px;">
  150 + <iron-list id="list6" as="item">
  151 + <template>
  152 + <div class="item" style$="[[_getStyle(item)]]">
  153 + <span>[[index]]</span> height: <span>[[item]]</span>
  154 + </div>
  155 + </template>
  156 + </iron-list>
  157 + </div>
  158 +</div>
  159 +
  160 +<div class="group">
  161 + <p>200 items with random heights</p>
  162 + <div class="wrapper" style="width: 300px; height: 300px;">
  163 + <iron-list id="list7" as="item">
  164 + <template>
  165 + <div class="item" style$="[[_getStyle(item)]]">
  166 + <span>[[index]]</span> height: <span>[[item]]</span>
  167 + </div>
  168 + </template>
  169 + </iron-list>
  170 + </div>
  171 +</div>
  172 +
  173 +
  174 +<div class="group">
  175 + <p>200 items async with random heights</p>
  176 + <div class="wrapper" style="width: 300px; height: 300px;">
  177 + <iron-list id="list8" as="item">
  178 + <template>
  179 + <div class="item" style$="[[_getStyle(item)]]">
  180 + <span>[[index]]</span> height: <span>[[item]]</span>
  181 + </div>
  182 + </template>
  183 + </iron-list>
  184 + </div>
  185 +</div> -->
  186 +</template>
  187 +
  188 + <script>
  189 + HTMLImports.whenReady(function() {
  190 + function observePhysicalCount(list) {
  191 + var div = document.createElement('div');
  192 + var stats = document.createElement('div');
  193 + var values = [];
  194 + var timer;
  195 + div.classList.add('count');
  196 + stats.classList.add('stats');
  197 +
  198 + Object.observe(list, function(changes) {
  199 + var physicalCount = list._physicalCount;
  200 + changes.forEach(function(change) {
  201 +
  202 + if (change.name === '_physicalCount') {
  203 + values.pop();
  204 + values.push(change.oldValue);
  205 + values.push(list._physicalCount);
  206 + div.innerText = values.join(' -> ');
  207 + } else if (change.name === '_lastPage') {
  208 + if (list._lastPage === 0) {
  209 + timer = Date.now();
  210 + } else if (list._lastPage === 1) {
  211 + stats.innerText = 'First paint: ' + (Date.now() - timer) + 'ms';
  212 + } else if (list._lastPage === list._maxPages) {
  213 + stats.innerText = stats.innerText + ' total: ' + (Date.now() - timer) + 'ms';
  214 + }
  215 + }
  216 + });
  217 + });
  218 +
  219 + values.push(list._physicalCount);
  220 + div.innerText = list._physicalCount;
  221 + stats.innerText = 'Waiting for stats...';
  222 +
  223 + Polymer.dom(list.parentNode).appendChild(div);
  224 + Polymer.dom(list.parentNode).appendChild(stats);
  225 + }
  226 +
  227 + function arrayFill(size, value) {
  228 + return (new Array(size)).fill(value, 0, size);
  229 + }
  230 +
  231 + function randomArrayFill(size, min, max) {
  232 + var a = [];
  233 + while (a.length < size) {
  234 + a.push(parseInt(Math.random() * (max-min+1)) + min);
  235 + }
  236 + return a;
  237 + }
  238 +
  239 + function asyncJob(fn) {
  240 + if (fn()) {
  241 + setTimeout(asyncJob.bind(null, fn), 1);
  242 + }
  243 + }
  244 +
  245 + document.querySelector('template[is=dom-bind]')._getStyle = function(item) {
  246 + return 'height:' + item + 'px; ';
  247 + };
  248 +
  249 + setTimeout(function() {
  250 + var list1 = document.querySelector('#list1');
  251 + var list2 = document.querySelector('#list2');
  252 + var list3 = document.querySelector('#list3');
  253 + var list4 = document.querySelector('#list4');
  254 + var list5 = document.querySelector('#list5');
  255 + var list6 = document.querySelector('#list6');
  256 + var list7 = document.querySelector('#list7');
  257 + var list8 = document.querySelector('#list8');
  258 + var items = randomArrayFill(100, 1, 200);
  259 +
  260 + list1.items = arrayFill(100, 50);
  261 + observePhysicalCount(list1);
  262 +
  263 + // list2.items = arrayFill(100, 300);
  264 + // list3.items = arrayFill(1000, 2);
  265 + // list4.items = arrayFill(2, 2).concat(arrayFill(100, 300));
  266 + // list5.items = arrayFill(100, 600);
  267 + // list6.items = [2];
  268 +
  269 + // setTimeout(function() {
  270 + // list6.push.apply(list6,
  271 + // ['items'].concat([512, 256, 128, 64, 16, 16, 16, 16, 16, 16, 8, 4])
  272 + // );
  273 + // }, 100);
  274 +
  275 + // list7.items = randomArrayFill(100, 1, 200);
  276 + // list8.items = [];
  277 +
  278 + // asyncJob(function() {
  279 + // list8.push('items', items.pop());
  280 + // return items.length > 0;
  281 + // });
  282 +
  283 + // observePhysicalCount(list2);
  284 + // observePhysicalCount(list3);
  285 + // observePhysicalCount(list4);
  286 + // observePhysicalCount(list5);
  287 + // observePhysicalCount(list6);
  288 + // observePhysicalCount(list7);
  289 + // observePhysicalCount(list8);
  290 +
  291 + }, 0);
  292 +
  293 + });
  294 + </script>
  295 +</body>
  296 +</html>
... ...
bower_components/iron-list/test/x-list.html 100755 → 100644
... ... @@ -33,13 +33,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
33 33 .item:nth-child(even) {
34 34 background-color: red;
35 35 }
  36 +
  37 + iron-list {
  38 + overflow: hidden;
  39 + }
36 40 </style>
37 41  
38 42 <template>
39 43 <iron-list style$="[[_computedListHeight(listHeight)]]" items="[[data]]" as="item" id="list">
40 44 <template>
41 45 <div class="item">
42   - <div style$="[[_computedItemHeight(item)]]">[[item.index]]</div>
  46 + <div style$="[[_computedItemHeight(item)]]" tabindex$="[[tabIndex]]" hidden$="[[primitive]]">[[item.index]]</div>
  47 + <div style$="[[_computedItemHeight(item)]]" tabindex$="[[tabIndex]]" hidden$="[[!primitive]]">[[item]]</div>
43 48 </div>
44 49 </template>
45 50 </iron-list>
... ... @@ -68,6 +73,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
68 73  
69 74 pre: {
70 75 type: Boolean
  76 + },
  77 +
  78 + primitive: {
  79 + value: false,
  80 + type: Boolean
71 81 }
72 82 },
73 83  
... ... @@ -86,7 +96,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
86 96 },
87 97  
88 98 _computedListHeight: function(listHeight) {
89   - return 'height: ' + (listHeight) + 'px';
  99 + return 'height: ' + (listHeight) + 'px;';
90 100 }
91 101 });
92 102 </script>
... ...
bower_components/iron-scroll-target-behavior/.bower.json 0 → 100644
  1 +{
  2 + "name": "iron-scroll-target-behavior",
  3 + "version": "1.0.6",
  4 + "description": "Allows to define a scroller target",
  5 + "private": true,
  6 + "license": "http://polymer.github.io/LICENSE.txt",
  7 + "main": "iron-scroll-target-behavior.html",
  8 + "authors": [
  9 + "The Polymer Authors"
  10 + ],
  11 + "keywords": [
  12 + "web-components",
  13 + "polymer",
  14 + "scroll"
  15 + ],
  16 + "repository": {
  17 + "type": "git",
  18 + "url": "git://github.com/PolymerElements/iron-scroll-target-behavior.git"
  19 + },
  20 + "homepage": "https://github.com/PolymerElements/iron-scroll-target-behavior",
  21 + "ignore": [],
  22 + "dependencies": {
  23 + "polymer": "Polymer/polymer#^1.0.0"
  24 + },
  25 + "devDependencies": {
  26 + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
  27 + "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
  28 + "web-component-tester": "^4.0.0",
  29 + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
  30 + },
  31 + "_release": "1.0.6",
  32 + "_resolution": {
  33 + "type": "version",
  34 + "tag": "v1.0.6",
  35 + "commit": "33d5864e0557212eb530dbac280bfc4b4d923880"
  36 + },
  37 + "_source": "git://github.com/PolymerElements/iron-scroll-target-behavior.git",
  38 + "_target": "^1.0.0",
  39 + "_originalSource": "PolymerElements/iron-scroll-target-behavior"
  40 +}
0 41 \ No newline at end of file
... ...
bower_components/iron-scroll-target-behavior/.github/ISSUE_TEMPLATE.md 0 → 100644
  1 +<!-- Instructions: https://github.com/PolymerElements/iron-scroll-target-behavior/CONTRIBUTING.md#filing-issues -->
  2 +### Description
  3 +<!-- Example: The `paper-foo` element causes the page to turn pink when clicked. -->
  4 +
  5 +### Expected outcome
  6 +
  7 +<!-- Example: The page stays the same color. -->
  8 +
  9 +### Actual outcome
  10 +
  11 +<!-- Example: The page turns pink. -->
  12 +
  13 +### Live Demo
  14 +<!-- Example: https://jsbin.com/cagaye/edit?html,output -->
  15 +
  16 +### Steps to reproduce
  17 +
  18 +<!-- Example
  19 +1. Put a `paper-foo` element in the page.
  20 +2. Open the page in a web browser.
  21 +3. Click the `paper-foo` element.
  22 +-->
  23 +
  24 +### Browsers Affected
  25 +<!-- Check all that apply -->
  26 +- [ ] Chrome
  27 +- [ ] Firefox
  28 +- [ ] Safari 9
  29 +- [ ] Safari 8
  30 +- [ ] Safari 7
  31 +- [ ] Edge
  32 +- [ ] IE 11
  33 +- [ ] IE 10
... ...
bower_components/iron-scroll-target-behavior/.gitignore 0 → 100644
  1 +bower_components
  2 +
... ...
bower_components/iron-scroll-target-behavior/.travis.yml 0 → 100644
  1 +language: node_js
  2 +node_js: stable
  3 +addons:
  4 + firefox: latest
  5 + sauce_connect: true
  6 + apt:
  7 + sources:
  8 + - google-chrome
  9 + - ubuntu-toolchain-r-test
  10 + packages:
  11 + - google-chrome-stable
  12 + - g++-4.8
  13 +before_script:
  14 +- npm install -g bower polylint web-component-tester
  15 +- bower install
  16 +- polylint
  17 +script:
  18 +- xvfb-run wct
  19 +- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct -s 'default'; fi
  20 +env:
  21 + global:
  22 + - CXX=g++-4.8
  23 + - secure: V9/FfFlrGgmgHI8icv3zjSn2bupGJs3FG2KlCqBwK5irWVU3Kcshl8XnXordLIfu2UF4Q/Aa4PkD2jKNuX/jSgGPpAfAi7aOruURSMZCzPErzKTQRg8iqHovhqDyJ2d5TypCRPCYDp+nO1ZQdPT5GQ1/8EZgilZFNVNTZ9twUJIYqPEcyQ7eAlxynDgjKxhMLa04UnUXzHVZ200x09gqGXByAK6tHvzf/W3BtjmjX7BZp0CWWk7tBgiH9gBsqwaYwHG7hg+hCVsnywN6G2WsUpPM4tBu3iyiVuNDuhY07MrV1uxEW9NCjyK8GUpHuCVN9A4CxeeDJM4xR8A3JUaVvWRwhES6KJ4YEdjfU6W759o2e05Sw3q3k4YQD96xiRz5YXYrnqLvm75trLY75pWqzIQkh+6g/C/ZBxRndh/n1VrV35GtAN+KEPE733PLvE8+yUWSiSAo052GyiYqt82joZv8+a1E38jg+bWRAYGuKcYxB5zS7xCEfkoztCuBT80yR+daQGyv0q61jmDrCUgl4B2m3xNf0+C08hYhR7KPHrMzIov3LTgJhHt6oonFs21Oa9cO8moMgaXP7Az8Y4c4Bg/BXaUe6lKkZ19kyzuDbF7hFKY0ABt1SwwkHZkEJ/Bk95CJigauFOuR3rq4TW4+M1DyqebvoyzjF4H1rHBY+lo=
  24 + - secure: x0Lq3topCMeNImNyY7nKiVPUEaQHjmywaen23pqH5/slsYrmMEFUEME+2sigGDuSacmhfka7DZuXs7jZuk6DlZN5HoueW+xwF6MxnGJRibTw6yFj6g3MJ0dDD6wu3w9TVERNiWCJ5drnTH41QwvUjGMtBrJuHw6qaiCuuLzbwqCxkRynEjssOXzsYY4JlC3EgM2/BVZQ1H2lyWH+elmRXOGDADzm8BVGQkJWCj644HROvGc45j2cOP+vq5MvL1SEA4IDdRRYGOhcc9lGZUY/qOfsai2K0LzgIvMQbjAdt8kbcvz8cnCVJHreIJKQfNe7VAWFiXhNbbzGrYH4DGe52MRSM6c22oLWqzgctqF1YDYAPAoF+6Cj6HqzHmMyNAe4RkpAGnXw5V4HjX013BFYCdImMHF6Am8I2RW2q+buWWW9fZVFjKGD0woz3ay5W4jw6Z//V73J6p/jDiVgq0MT2S4Q8hCEh8QaqK69v9eS+Vxbh1KRUvFaBJvgDYfTnTQ4niuT/Y7TV0ZQ/DMAZ/kBfyMLAmyU5XWuGAnmg6uydE5JtHJHKYb+BKyZ++uImhyfM+bQkp6PxWRNxKsgNt8dcYn50/ppNnkHjXpoQxAlR5kjjiHsVmo4ZLOxkckjyr074Kb/nmDOqMxbRzdTlsBBqycJZjKtm4YX+GkrQXsEbg8=
... ...
bower_components/iron-scroll-target-behavior/CONTRIBUTING.md 0 → 100644
  1 +
  2 +<!--
  3 +This file is autogenerated based on
  4 +https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
  5 +
  6 +If you edit that file, it will get updated everywhere else.
  7 +If you edit this file, your changes will get overridden :)
  8 +
  9 +You can however override the jsbin link with one that's customized to this
  10 +specific element:
  11 +
  12 +jsbin=https://jsbin.com/cagaye/edit?html,output
  13 +-->
  14 +# Polymer Elements
  15 +## Guide for Contributors
  16 +
  17 +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:
  18 +
  19 +### Filing Issues
  20 +
  21 +**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:
  22 +
  23 + 1. **Who will use the feature?** _“As someone filling out a form…”_
  24 + 2. **When will they use the feature?** _“When I enter an invalid value…”_
  25 + 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
  26 +
  27 +**If you are filing an issue to report a bug**, please provide:
  28 +
  29 + 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
  30 +
  31 + ```markdown
  32 + The `paper-foo` element causes the page to turn pink when clicked.
  33 +
  34 + ## Expected outcome
  35 +
  36 + The page stays the same color.
  37 +
  38 + ## Actual outcome
  39 +
  40 + The page turns pink.
  41 +
  42 + ## Steps to reproduce
  43 +
  44 + 1. Put a `paper-foo` element in the page.
  45 + 2. Open the page in a web browser.
  46 + 3. Click the `paper-foo` element.
  47 + ```
  48 +
  49 + 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).
  50 +
  51 + 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
  52 +
  53 +### Submitting Pull Requests
  54 +
  55 +**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.
  56 +
  57 +When submitting pull requests, please provide:
  58 +
  59 + 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:
  60 +
  61 + ```markdown
  62 + (For a single issue)
  63 + Fixes #20
  64 +
  65 + (For multiple issues)
  66 + Fixes #32, fixes #40
  67 + ```
  68 +
  69 + 2. **A succinct description of the design** used to fix any related issues. For example:
  70 +
  71 + ```markdown
  72 + This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
  73 + ```
  74 +
  75 + 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.
  76 +
  77 +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!
... ...
bower_components/iron-scroll-target-behavior/README.md 0 → 100644
  1 +
  2 +<!---
  3 +
  4 +This README is automatically generated from the comments in these files:
  5 +iron-scroll-target-behavior.html
  6 +
  7 +Edit those files, and our readme bot will duplicate them over here!
  8 +Edit this file, and the bot will squash your changes :)
  9 +
  10 +The bot does some handling of markdown. Please file a bug if it does the wrong
  11 +thing! https://github.com/PolymerLabs/tedium/issues
  12 +
  13 +-->
  14 +
  15 +[![Build status](https://travis-ci.org/PolymerElements/iron-scroll-target-behavior.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-scroll-target-behavior)
  16 +
  17 +_[Demo and API docs](https://elements.polymer-project.org/elements/iron-scroll-target-behavior)_
  18 +
  19 +
  20 +##Polymer.IronScrollTargetBehavior
  21 +
  22 +`Polymer.IronScrollTargetBehavior` allows an element to respond to scroll events from a
  23 +designated scroll target.
  24 +
  25 +Elements that consume this behavior can override the `_scrollHandler`
  26 +method to add logic on the scroll event.
  27 +
  28 +
... ...
bower_components/iron-scroll-target-behavior/bower.json 0 → 100644
  1 +{
  2 + "name": "iron-scroll-target-behavior",
  3 + "version": "1.0.6",
  4 + "description": "Allows to define a scroller target",
  5 + "private": true,
  6 + "license": "http://polymer.github.io/LICENSE.txt",
  7 + "main": "iron-scroll-target-behavior.html",
  8 + "authors": [
  9 + "The Polymer Authors"
  10 + ],
  11 + "keywords": [
  12 + "web-components",
  13 + "polymer",
  14 + "scroll"
  15 + ],
  16 + "repository": {
  17 + "type": "git",
  18 + "url": "git://github.com/PolymerElements/iron-scroll-target-behavior.git"
  19 + },
  20 + "homepage": "https://github.com/PolymerElements/iron-scroll-target-behavior",
  21 + "ignore": [],
  22 + "dependencies": {
  23 + "polymer": "Polymer/polymer#^1.0.0"
  24 + },
  25 + "devDependencies": {
  26 + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
  27 + "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
  28 + "web-component-tester": "^4.0.0",
  29 + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
  30 + }
  31 +}
... ...
bower_components/iron-scroll-target-behavior/demo/document.html 0 → 100644
  1 +<!doctype html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  10 +-->
  11 +
  12 +<html>
  13 + <head>
  14 +
  15 + <title>iron-scroll-target-behavior using the document scrolling</title>
  16 +
  17 + <meta charset="utf-8">
  18 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19 +
  20 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  21 +
  22 + <link rel="import" href="../iron-scroll-target-behavior.html">
  23 + <link rel="import" href="x-scrollable.html">
  24 +
  25 + <style>
  26 +
  27 + body {
  28 + margin: 0;
  29 + padding: 0;
  30 + }
  31 +
  32 + </style>
  33 + </head>
  34 + <body unresolved>
  35 +
  36 + <x-scrollable scroll-target="document"></x-scrollable>
  37 +
  38 + </body>
  39 +</html>
... ...
bower_components/iron-scroll-target-behavior/demo/scrolling-region.html 0 → 100644
  1 +<!doctype html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  10 +-->
  11 +
  12 +<html>
  13 + <head>
  14 +
  15 + <title>iron-scroll-target-behavior using a scrolling region</title>
  16 +
  17 + <meta charset="utf-8">
  18 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19 +
  20 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  21 +
  22 + <link rel="import" href="../iron-scroll-target-behavior.html">
  23 + <link rel="import" href="x-scrollable.html">
  24 +
  25 + <style>
  26 +
  27 + body {
  28 + margin: 0;
  29 + padding: 0;
  30 + }
  31 +
  32 + #region {
  33 + height: 50vh;
  34 + overflow: auto;
  35 + position: absolute;
  36 + top: 25vh;
  37 + left: 25vh;
  38 + right: 25vh;
  39 + box-shadow: 0 0 60px rgba(0,0,0,0.5);
  40 + }
  41 +
  42 + </style>
  43 + </head>
  44 + <body unresolved>
  45 +
  46 + <div id="region">
  47 + <x-scrollable scroll-target="region"></x-scrollable>
  48 + </div>
  49 +
  50 + </body>
  51 +</html>
... ...
bower_components/iron-scroll-target-behavior/demo/x-scrollable.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<link rel="import" href="../../polymer/polymer.html">
  12 +<link rel="import" href="../iron-scroll-target-behavior.html">
  13 +
  14 +<dom-module id="x-scrollable">
  15 +
  16 + <style>
  17 +
  18 + :host {
  19 + display: block;
  20 + font: 14px arial;
  21 + }
  22 +
  23 + .scrollState {
  24 + border-left: 1px solid #ccc;
  25 + border-right: 1px solid #ccc;
  26 + border-bottom: 1px solid #ccc;
  27 + font-weight: bold;
  28 + background-color: #eee;
  29 + position: fixed;
  30 + top: 0;
  31 + left: calc(50% - 100px);
  32 + padding: 10px;
  33 + width: 220px;
  34 + text-align: center;
  35 + }
  36 +
  37 + .item {
  38 + border-bottom: 1px solid #ccc;
  39 + background-color: white;
  40 + padding: 20px;
  41 + width: 200%;
  42 + }
  43 +
  44 + </style>
  45 +
  46 + <template>
  47 +
  48 + <div class="scrollState">scrollTop: [[xScrollTop]] - scrollLeft: [[xScrollLeft]]</div>
  49 +
  50 + <template is="dom-repeat" items="[[_getItems(itemCount)]]">
  51 + <div class="item">[[index]]</div>
  52 + </template>
  53 +
  54 + </template>
  55 +
  56 +</dom-module>
  57 +
  58 +<script>
  59 + Polymer({
  60 +
  61 + is: 'x-scrollable',
  62 +
  63 + properties: {
  64 +
  65 + xScrollTop: {
  66 + type: Number,
  67 + readOnly: true,
  68 + value: 0
  69 + },
  70 +
  71 + xScrollLeft: {
  72 + type: Number,
  73 + readOnly: true,
  74 + value: 0
  75 + },
  76 +
  77 + itemCount: {
  78 + type: Number,
  79 + value: 200
  80 + }
  81 +
  82 + },
  83 +
  84 + behaviors: [
  85 + Polymer.IronScrollTargetBehavior
  86 + ],
  87 +
  88 + attached: function() {
  89 + this._scrollHandler();
  90 + },
  91 +
  92 + _scrollHandler: function() {
  93 + this._setXScrollTop(this._scrollTop);
  94 + this._setXScrollLeft(this._scrollLeft);
  95 + },
  96 +
  97 + _getItems: function(itemCount) {
  98 + var items = new Array(itemCount);
  99 + while (itemCount > 0) {
  100 + items[--itemCount] = true;
  101 + }
  102 + return items;
  103 + }
  104 + });
  105 +</script>
... ...
bower_components/iron-scroll-target-behavior/index.html 0 → 100644
  1 +<!doctype html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  10 +-->
  11 +
  12 +<html>
  13 +<head>
  14 +
  15 + <title>iron-scroll-target-behavior</title>
  16 + <meta charset="utf-8">
  17 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  18 +
  19 + <script src="../webcomponentsjs/webcomponents-lite.js"></script>
  20 + <link rel="import" href="../iron-component-page/iron-component-page.html">
  21 +
  22 +</head>
  23 +<body>
  24 +
  25 + <iron-component-page></iron-component-page>
  26 +
  27 +</body>
  28 +</html>
... ...
bower_components/iron-scroll-target-behavior/iron-scroll-target-behavior.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<link rel="import" href="../polymer/polymer.html">
  12 +
  13 +<script>
  14 +
  15 + /**
  16 + * `Polymer.IronScrollTargetBehavior` allows an element to respond to scroll events from a
  17 + * designated scroll target.
  18 + *
  19 + * Elements that consume this behavior can override the `_scrollHandler`
  20 + * method to add logic on the scroll event.
  21 + *
  22 + * @demo demo/scrolling-region.html Scrolling Region
  23 + * @demo demo/document.html Document Element
  24 + * @polymerBehavior
  25 + */
  26 + Polymer.IronScrollTargetBehavior = {
  27 +
  28 + properties: {
  29 +
  30 + /**
  31 + * Specifies the element that will handle the scroll event
  32 + * on the behalf of the current element. This is typically a reference to an element,
  33 + * but there are a few more posibilities:
  34 + *
  35 + * ### Elements id
  36 + *
  37 + *```html
  38 + * <div id="scrollable-element" style="overflow: auto;">
  39 + * <x-element scroll-target="scrollable-element">
  40 + * <!-- Content-->
  41 + * </x-element>
  42 + * </div>
  43 + *```
  44 + * In this case, the `scrollTarget` will point to the outer div element.
  45 + *
  46 + * ### Document scrolling
  47 + *
  48 + * For document scrolling, you can use the reserved word `document`:
  49 + *
  50 + *```html
  51 + * <x-element scroll-target="document">
  52 + * <!-- Content -->
  53 + * </x-element>
  54 + *```
  55 + *
  56 + * ### Elements reference
  57 + *
  58 + *```js
  59 + * appHeader.scrollTarget = document.querySelector('#scrollable-element');
  60 + *```
  61 + *
  62 + * @type {HTMLElement}
  63 + */
  64 + scrollTarget: {
  65 + type: HTMLElement,
  66 + value: function() {
  67 + return this._defaultScrollTarget;
  68 + }
  69 + }
  70 + },
  71 +
  72 + observers: [
  73 + '_scrollTargetChanged(scrollTarget, isAttached)'
  74 + ],
  75 +
  76 + _scrollTargetChanged: function(scrollTarget, isAttached) {
  77 + var eventTarget;
  78 +
  79 + if (this._oldScrollTarget) {
  80 + eventTarget = this._oldScrollTarget === this._doc ? window : this._oldScrollTarget;
  81 + eventTarget.removeEventListener('scroll', this._boundScrollHandler);
  82 + this._oldScrollTarget = null;
  83 + }
  84 +
  85 + if (!isAttached) {
  86 + return;
  87 + }
  88 + // Support element id references
  89 + if (scrollTarget === 'document') {
  90 +
  91 + this.scrollTarget = this._doc;
  92 +
  93 + } else if (typeof scrollTarget === 'string') {
  94 +
  95 + this.scrollTarget = this.domHost ? this.domHost.$[scrollTarget] :
  96 + Polymer.dom(this.ownerDocument).querySelector('#' + scrollTarget);
  97 +
  98 + } else if (this._isValidScrollTarget()) {
  99 +
  100 + eventTarget = scrollTarget === this._doc ? window : scrollTarget;
  101 + this._boundScrollHandler = this._boundScrollHandler || this._scrollHandler.bind(this);
  102 + this._oldScrollTarget = scrollTarget;
  103 +
  104 + eventTarget.addEventListener('scroll', this._boundScrollHandler);
  105 + }
  106 + },
  107 +
  108 + /**
  109 + * Runs on every scroll event. Consumer of this behavior may override this method.
  110 + *
  111 + * @protected
  112 + */
  113 + _scrollHandler: function scrollHandler() {},
  114 +
  115 + /**
  116 + * The default scroll target. Consumers of this behavior may want to customize
  117 + * the default scroll target.
  118 + *
  119 + * @type {Element}
  120 + */
  121 + get _defaultScrollTarget() {
  122 + return this._doc;
  123 + },
  124 +
  125 + /**
  126 + * Shortcut for the document element
  127 + *
  128 + * @type {Element}
  129 + */
  130 + get _doc() {
  131 + return this.ownerDocument.documentElement;
  132 + },
  133 +
  134 + /**
  135 + * Gets the number of pixels that the content of an element is scrolled upward.
  136 + *
  137 + * @type {number}
  138 + */
  139 + get _scrollTop() {
  140 + if (this._isValidScrollTarget()) {
  141 + return this.scrollTarget === this._doc ? window.pageYOffset : this.scrollTarget.scrollTop;
  142 + }
  143 + return 0;
  144 + },
  145 +
  146 + /**
  147 + * Gets the number of pixels that the content of an element is scrolled to the left.
  148 + *
  149 + * @type {number}
  150 + */
  151 + get _scrollLeft() {
  152 + if (this._isValidScrollTarget()) {
  153 + return this.scrollTarget === this._doc ? window.pageXOffset : this.scrollTarget.scrollLeft;
  154 + }
  155 + return 0;
  156 + },
  157 +
  158 + /**
  159 + * Sets the number of pixels that the content of an element is scrolled upward.
  160 + *
  161 + * @type {number}
  162 + */
  163 + set _scrollTop(top) {
  164 + if (this.scrollTarget === this._doc) {
  165 + window.scrollTo(window.pageXOffset, top);
  166 + } else if (this._isValidScrollTarget()) {
  167 + this.scrollTarget.scrollTop = top;
  168 + }
  169 + },
  170 +
  171 + /**
  172 + * Sets the number of pixels that the content of an element is scrolled to the left.
  173 + *
  174 + * @type {number}
  175 + */
  176 + set _scrollLeft(left) {
  177 + if (this.scrollTarget === this._doc) {
  178 + window.scrollTo(left, window.pageYOffset);
  179 + } else if (this._isValidScrollTarget()) {
  180 + this.scrollTarget.scrollLeft = left;
  181 + }
  182 + },
  183 +
  184 + /**
  185 + * Scrolls the content to a particular place.
  186 + *
  187 + * @method scroll
  188 + * @param {number} left The left position
  189 + * @param {number} top The top position
  190 + */
  191 + scroll: function(left, top) {
  192 + if (this.scrollTarget === this._doc) {
  193 + window.scrollTo(left, top);
  194 + } else if (this._isValidScrollTarget()) {
  195 + this.scrollTarget.scrollLeft = left;
  196 + this.scrollTarget.scrollTop = top;
  197 + }
  198 + },
  199 +
  200 + /**
  201 + * Gets the width of the scroll target.
  202 + *
  203 + * @type {number}
  204 + */
  205 + get _scrollTargetWidth() {
  206 + if (this._isValidScrollTarget()) {
  207 + return this.scrollTarget === this._doc ? window.innerWidth : this.scrollTarget.offsetWidth;
  208 + }
  209 + return 0;
  210 + },
  211 +
  212 + /**
  213 + * Gets the height of the scroll target.
  214 + *
  215 + * @type {number}
  216 + */
  217 + get _scrollTargetHeight() {
  218 + if (this._isValidScrollTarget()) {
  219 + return this.scrollTarget === this._doc ? window.innerHeight : this.scrollTarget.offsetHeight;
  220 + }
  221 + return 0;
  222 + },
  223 +
  224 + /**
  225 + * Returns true if the scroll target is a valid HTMLElement.
  226 + *
  227 + * @return {boolean}
  228 + */
  229 + _isValidScrollTarget: function() {
  230 + return this.scrollTarget instanceof HTMLElement;
  231 + }
  232 + };
  233 +
  234 +</script>
... ...
bower_components/iron-scroll-target-behavior/test/basic.html 0 → 100644
  1 +<!doctype html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
  10 +-->
  11 +<html>
  12 +<head>
  13 + <meta charset="UTF-8">
  14 + <title>iron-scroll-target-behavior test</title>
  15 + <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
  16 +
  17 + <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  18 + <script src="../../web-component-tester/browser.js"></script>
  19 +
  20 + <link rel="import" href="x-scrollable.html">
  21 + <link rel="import" href="x-nested-scrollable.html">
  22 +
  23 + <style>
  24 + #temporaryScrollingRegion,
  25 + #region {
  26 + overflow: auto;
  27 + width: 100px;
  28 + height: 100px;
  29 + }
  30 + </style>
  31 +</head>
  32 +<body>
  33 +
  34 + <test-fixture id="trivialScrollable">
  35 + <template>
  36 + <div id="temporaryScrollingRegion">
  37 + <x-scrollable></x-scrollable>
  38 + </div>
  39 + </template>
  40 + </test-fixture>
  41 +
  42 + <test-fixture id="trivialScrollingRegion">
  43 + <template>
  44 + <div id="region">
  45 + <x-scrollable scroll-target="region"></x-scrollable>
  46 + </div>
  47 + </template>
  48 + </test-fixture>
  49 +
  50 + <test-fixture id="trivialNestedScrollingRegion">
  51 + <template>
  52 + <x-nested-scrollable id="nestedScrollingRegion"></x-nested-scrollable>
  53 + </template>
  54 + </test-fixture>
  55 +
  56 +
  57 + <test-fixture id="trivialDocumentScroll">
  58 + <template>
  59 + <x-scrollable scroll-target="document"></x-scrollable>
  60 + </template>
  61 + </test-fixture>
  62 +
  63 + <script>
  64 +
  65 + suite('basic features', function() {
  66 + var scrollingRegion, xScroll;
  67 +
  68 + setup(function() {
  69 + scrollingRegion = fixture('trivialScrollable');
  70 + xScroll = Polymer.dom(scrollingRegion).querySelector('x-scrollable');
  71 + });
  72 +
  73 + test('default', function() {
  74 + assert.equal(xScroll._scrollTop, 0, '_scrollTop');
  75 + assert.equal(xScroll._scrollLeft, 0, '_scrollLeft');
  76 + assert.equal(xScroll._scrollTargetWidth, 0, '_scrollTargetWidth');
  77 + assert.equal(xScroll._scrollTargetHeight, 0, '_scrollTargetHeight');
  78 + assert.equal(xScroll.scrollTarget, null, 'scrollTarget');
  79 + assert.equal(xScroll._defaultScrollTarget, xScroll.scrollTarget, '_defaultScrollTarget');
  80 + });
  81 +
  82 + test('invalid `scrollTarget` selector', function(done) {
  83 + flush(function() {
  84 + xScroll.scrollTarget = 'invalid-id';
  85 + assert.equal(xScroll.scrollTarget, null);
  86 + done();
  87 + });
  88 + });
  89 +
  90 + test('valid `scrollTarget` selector', function(done) {
  91 + flush(function() {
  92 + xScroll.scrollTarget = 'temporaryScrollingRegion';
  93 + assert.equal(xScroll.scrollTarget, scrollingRegion);
  94 + done();
  95 + });
  96 + });
  97 + });
  98 +
  99 + suite('scrolling region', function() {
  100 + var scrollingRegion, xScrollable;
  101 +
  102 + setup(function() {
  103 + scrollingRegion = fixture('trivialScrollingRegion');
  104 + xScrollable = Polymer.dom(scrollingRegion).querySelector('x-scrollable');
  105 + });
  106 +
  107 + teardown(function() {
  108 + xScrollable._scrollTop = 0;
  109 + xScrollable._scrollLeft = 0;
  110 + });
  111 +
  112 + test('scrollTarget reference', function(done) {
  113 + flush(function() {
  114 + assert.equal(xScrollable.scrollTarget, scrollingRegion);
  115 + done();
  116 + });
  117 + });
  118 +
  119 + test('invalid scrollTarget', function(done) {
  120 + flush(function() {
  121 + assert.equal(xScrollable.scrollTarget, scrollingRegion);
  122 + done();
  123 + });
  124 + });
  125 +
  126 + test('setters', function(done) {
  127 + flush(function() {
  128 + xScrollable._scrollTop = 100;
  129 + xScrollable._scrollLeft = 100;
  130 +
  131 + assert.equal(scrollingRegion.scrollTop, 100);
  132 + assert.equal(scrollingRegion.scrollLeft, 100);
  133 +
  134 + done();
  135 + });
  136 + });
  137 +
  138 + test('getters', function(done) {
  139 + flush(function() {
  140 + scrollingRegion.scrollTop = 50;
  141 + scrollingRegion.scrollLeft = 50;
  142 +
  143 + assert.equal(xScrollable._scrollTop, 50, '_scrollTop');
  144 + assert.equal(xScrollable._scrollLeft, 50, '_scrollLeft');
  145 + assert.equal(xScrollable._scrollTargetWidth, scrollingRegion.offsetWidth, '_scrollTargetWidth');
  146 + assert.equal(xScrollable._scrollTargetHeight, scrollingRegion.offsetHeight, '_scrollTargetHeight');
  147 +
  148 + done();
  149 + });
  150 + });
  151 +
  152 + test('scroll method', function(done) {
  153 + flush(function() {
  154 + xScrollable.scroll(110, 110);
  155 +
  156 + assert.equal(xScrollable._scrollTop, 110);
  157 + assert.equal(xScrollable._scrollLeft, 110);
  158 +
  159 + xScrollable.scroll(0, 0);
  160 +
  161 + assert.equal(xScrollable._scrollTop, 0);
  162 + assert.equal(xScrollable._scrollLeft, 0);
  163 +
  164 + done();
  165 + });
  166 + });
  167 + });
  168 +
  169 + suite('document scroll', function() {
  170 + var xScrollable;
  171 +
  172 + setup(function() {
  173 + xScrollable = fixture('trivialDocumentScroll');
  174 + });
  175 +
  176 + teardown(function() {
  177 + xScrollable._scrollTop = 0;
  178 + xScrollable._scrollLeft = 0;
  179 + });
  180 +
  181 + test('scrollTarget reference', function(done) {
  182 + flush(function() {
  183 + assert.equal(xScrollable.scrollTarget, document.documentElement);
  184 + done();
  185 + });
  186 + });
  187 +
  188 + test('setters', function(done) {
  189 + flush(function() {
  190 + xScrollable._scrollTop = 100;
  191 + xScrollable._scrollLeft = 100;
  192 +
  193 + assert.equal(window.pageXOffset, 100);
  194 + assert.equal(window.pageYOffset, 100);
  195 +
  196 + done();
  197 + });
  198 + });
  199 +
  200 + test('getters', function(done) {
  201 + flush(function() {
  202 + window.scrollTo(50, 50);
  203 +
  204 + assert.equal(xScrollable._scrollTop, 50, '_scrollTop');
  205 + assert.equal(xScrollable._scrollLeft, 50, '_scrollLeft');
  206 + assert.equal(xScrollable._scrollTargetWidth, window.innerWidth, '_scrollTargetWidth');
  207 + assert.equal(xScrollable._scrollTargetHeight, window.innerHeight, '_scrollTargetHeight');
  208 +
  209 + done();
  210 + });
  211 + });
  212 +
  213 + test('scroll method', function(done) {
  214 + flush(function() {
  215 +
  216 + xScrollable.scroll(1, 2);
  217 +
  218 + assert.equal(xScrollable._scrollLeft, 1);
  219 + assert.equal(xScrollable._scrollTop, 2);
  220 +
  221 + xScrollable.scroll(3, 4);
  222 +
  223 + assert.equal(xScrollable._scrollLeft, 3);
  224 + assert.equal(xScrollable._scrollTop, 4);
  225 +
  226 + done();
  227 + });
  228 + });
  229 + });
  230 +
  231 + suite('nested scrolling region', function() {
  232 + var xScrollingRegion;
  233 + var xScrollable;
  234 +
  235 + setup(function() {
  236 + var nestedScrollingRegion = fixture('trivialNestedScrollingRegion');
  237 + xScrollable = nestedScrollingRegion.$.xScrollable;
  238 + xScrollingRegion = nestedScrollingRegion.$.xRegion;
  239 + });
  240 +
  241 + teardown(function() {
  242 + xScrollable._scrollTop = 0;
  243 + xScrollable._scrollLeft = 0;
  244 + });
  245 +
  246 + test('scrollTarget reference', function(done) {
  247 + flush(function() {
  248 + assert.equal(xScrollable.scrollTarget, xScrollingRegion);
  249 + done();
  250 + });
  251 + });
  252 +
  253 + test('setters', function(done) {
  254 + flush(function() {
  255 + xScrollable._scrollTop = 10;
  256 + xScrollable._scrollLeft = 20;
  257 +
  258 + assert.equal(xScrollingRegion.scrollTop, 10);
  259 + assert.equal(xScrollingRegion.scrollLeft, 20);
  260 +
  261 + done();
  262 + });
  263 + });
  264 +
  265 + test('getters', function(done) {
  266 + flush(function() {
  267 + xScrollable._scrollTop = 10;
  268 + xScrollable._scrollLeft = 20;
  269 +
  270 + assert.equal(xScrollable._scrollTop, 10, '_scrollTop');
  271 + assert.equal(xScrollable._scrollLeft, 20, '_scrollLeft');
  272 +
  273 + done();
  274 + });
  275 + });
  276 +
  277 + test('scroll method', function(done) {
  278 + flush(function() {
  279 +
  280 + xScrollable.scroll(1, 2);
  281 +
  282 + assert.equal(xScrollable._scrollLeft, 1);
  283 + assert.equal(xScrollable._scrollTop, 2);
  284 +
  285 + xScrollable.scroll(3, 4);
  286 +
  287 + assert.equal(xScrollable._scrollLeft, 3);
  288 + assert.equal(xScrollable._scrollTop, 4);
  289 +
  290 + done();
  291 + });
  292 + });
  293 + });
  294 +
  295 + </script>
  296 +
  297 +</body>
  298 +</html>
... ...
bower_components/iron-scroll-target-behavior/test/index.html 0 → 100644
  1 +<!doctype html>
  2 +<!--
  3 +@license
  4 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  5 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  6 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  7 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  8 +Code distributed by Google as part of the polymer project is also
  9 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  10 +-->
  11 +
  12 +<html>
  13 +<head>
  14 +
  15 + <meta charset="utf-8">
  16 + <title>Tests</title>
  17 + <script src="../../web-component-tester/browser.js"></script>
  18 +
  19 +</head>
  20 +<body>
  21 +
  22 + <script>
  23 +
  24 + WCT.loadSuites([
  25 + 'basic.html',
  26 + 'basic.html?dom=shadow'
  27 + ]);
  28 +
  29 + </script>
  30 +
  31 +</body>
  32 +</html>
... ...
bower_components/iron-scroll-target-behavior/test/x-nested-scrollable.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<link rel="import" href="../../polymer/polymer.html">
  12 +<link rel="import" href="x-scrollable.html">
  13 +
  14 +<dom-module id="x-nested-scrollable">
  15 +
  16 + <style>
  17 +
  18 + :host {
  19 + display: block;
  20 + }
  21 +
  22 + #xRegion {
  23 + width: 100px;
  24 + height: 100px;
  25 + overflow: auto;
  26 + }
  27 +
  28 + </style>
  29 +
  30 + <template>
  31 + <div id="xRegion">
  32 + <x-scrollable id="xScrollable" scroll-target="xRegion"></x-scrollable>
  33 + </div>
  34 + </template>
  35 +
  36 +</dom-module>
  37 +
  38 +<script>
  39 + Polymer({
  40 + is: 'x-nested-scrollable'
  41 + });
  42 +</script>
... ...
bower_components/iron-scroll-target-behavior/test/x-scrollable.html 0 → 100644
  1 +<!--
  2 +@license
  3 +Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  4 +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  5 +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  6 +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  7 +Code distributed by Google as part of the polymer project is also
  8 +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9 +-->
  10 +
  11 +<link rel="import" href="../../polymer/polymer.html">
  12 +<link rel="import" href="../iron-scroll-target-behavior.html">
  13 +
  14 +<dom-module id="x-scrollable">
  15 +
  16 + <style>
  17 +
  18 + :host {
  19 + display: block;
  20 + font: 14px arial;
  21 + }
  22 +
  23 + .item {
  24 + border-bottom: 1px solid #ccc;
  25 + background-color: white;
  26 + padding: 20px;
  27 + width: 200%;
  28 + }
  29 +
  30 + </style>
  31 +
  32 + <template>
  33 + <template is="dom-repeat" items="[[_getItems(itemCount)]]">
  34 + <div class="item">[[index]]</div>
  35 + </template>
  36 + </template>
  37 +
  38 +</dom-module>
  39 +
  40 +<script>
  41 + Polymer({
  42 +
  43 + is: 'x-scrollable',
  44 +
  45 + properties: {
  46 +
  47 + itemCount: {
  48 + type: Number,
  49 + value: 200
  50 + }
  51 +
  52 + },
  53 +
  54 + behaviors: [
  55 + Polymer.IronScrollTargetBehavior
  56 + ],
  57 +
  58 + _defaultScrollTarget: null,
  59 +
  60 + _getItems: function(itemCount) {
  61 + var items = new Array(itemCount);
  62 + while (itemCount > 0) {
  63 + items[--itemCount] = true;
  64 + }
  65 + return items;
  66 + }
  67 + });
  68 +</script>
... ...
controllets/animated-button-container-controllet/animated-button-container-controllet.html
... ... @@ -62,6 +62,7 @@
62 62 .toolbar {
63 63 background: #2196F3;
64 64 height: 48px;
  65 + padding: 4px 0px 0px 0px;
65 66 }
66 67  
67 68 paper-fab.close {
... ...
controllets/data-sevc-controllet/data-sevc-controllet.html
... ... @@ -6,10 +6,13 @@
6 6 <link rel="import" href="../../bower_components/polymer/polymer.html">
7 7  
8 8 <link rel="import" href="../page-slider-controllet/page-slider-controllet.html">
9   -<link rel="import" href="../dataset-selection-controllet/dataset-selection-controllet.html">
  9 +
  10 +<!--<link rel="import" href="../dataset-selection-controllet/dataset-selection-controllet.html">-->
  11 +<link rel="import" href="../select-dataset-controllet/select-dataset-controllet.html">
10 12 <link rel="import" href="../select-data-controllet/select-data-controllet.html" />
11 13 <link rel="import" href="../select-visualization-controllet/select-visualization-controllet.html" />
12   -<!--<link rel="import" href="../datalet-selection-controllet/datalet-selection-controllet.html">-->
  14 +
  15 +
13 16  
14 17 <dom-module id="data-sevc-controllet">
15 18  
... ... @@ -20,7 +23,8 @@
20 23 <neon-animatable>
21 24  
22 25 <template is="dom-if" if={{!modify}}>
23   - <dataset-selection-controllet id="select_dataset" data={{data}} datasets={{datasets}} suggested-datasets={{suggestedDatasets}}></dataset-selection-controllet>
  26 + <!--<dataset-selection-controllet id="select_dataset" data={{data}} datasets={{datasets}} suggested-datasets={{suggestedDatasets}}></dataset-selection-controllet>-->
  27 + <select-dataset-controllet id="select_dataset" data={{data}} datasets={{datasets}} suggested-datasets={{suggestedDatasets}}></select-dataset-controllet>
24 28 </template>
25 29  
26 30 </neon-animatable>
... ... @@ -33,7 +37,6 @@
33 37  
34 38 <neon-animatable>
35 39  
36   - <!--<datalet-selection-controllet id="select_visualization" deep-url={{deepUrl}} datalets-list-url={{dataletsListUrl}} data-url={{dataUrl}} preselected-datalet={{selectedDatalet}} datalet-preset={{dataletPreset}}></datalet-selection-controllet>-->
37 40 <select-visualization-controllet id="select_visualization" deep-url={{deepUrl}} datalets-list-url={{dataletsListUrl}} data-url={{dataUrl}} preselected-datalet={{selectedDatalet}} datalet-preset={{dataletPreset}}></select-visualization-controllet>
38 41  
39 42 </neon-animatable>
... ... @@ -140,22 +143,32 @@
140 143 slider.chevronLeft(true);
141 144 }
142 145 slider.chevronRight(false);
143   - this.$.select_data.ready();
144   -// this.async(function () {this.dataletPreset["filters"] = undefined;}, 1000);
145   - this._allowThirdStep({detail: {fields: select_data.getFlatFields()}});
146 146 this._allowThirdStep({detail: {fields: select_data.getFlatFields()}});
  147 + if(this.modify){
  148 + this.$.select_visualization.setFields(select_data.getFlatFields());
  149 + this.$.select_visualization.setFilters(select_data.getFilters());
  150 + }
147 151 break;
148 152 case 2:
149 153 slider.setTitle(ln["slide3Title_" + this.localization], ln["slide3Subtitle_" + this.localization]);
150 154 slider.chevronLeft(true);
151 155 slider.chevronRight("invisible");
  156 +
152 157 this.$.select_visualization.setFields(select_data.getFlatFields());
153 158 this.$.select_visualization.setFilters(select_data.getFilters());
154   - this.$.select_visualization.ready();
  159 + if(this.modify) {
  160 + this.$.select_visualization.show();//resize
  161 + }
155 162 }
156 163 },
157 164  
158 165 _allowSecondStep : function(e){
  166 + if(e.detail.url == "") {
  167 + slider.chevronRight(false);
  168 + select_dataset.$.selected_url.invalid = false;
  169 + return;
  170 + }
  171 +
159 172 this.dataUrl = e.detail.url;
160 173  
161 174 $.ajax({
... ...
controllets/filters-controllet/demo/index.html
... ... @@ -7,6 +7,8 @@
7 7  
8 8 <link rel="import" href="../filters-controllet.html" />
9 9  
  10 + <script src="../../../locales/controllet_ln.js"></script>
  11 +
10 12 <script src="../../shared_js/perfect-scrollbar/js/min/perfect-scrollbar.jquery.min.js"></script>
11 13 <link rel="stylesheet" href="../../shared_js/perfect-scrollbar/css/perfect-scrollbar.min.css">
12 14 </head>
... ... @@ -31,6 +33,7 @@
31 33 </div>
32 34  
33 35 <script>
  36 + ln["localization"] = "en";
34 37  
35 38 var fields = ["result,records,Lat","result,records,Lng", "Sbiricos"];
36 39  
... ...
controllets/generic-cards-container-controllet/generic-cards-container-controllet.html
... ... @@ -132,7 +132,6 @@ Example:
132 132 var cards = document.querySelectorAll('paper-card-controllet');
133 133  
134 134 // if(cards.length == 0){
135   -//
136 135 // this.$.card_grid.innerHTML += "<div class='empty'>There is nothing to show.</div>";
137 136 // }
138 137  
... ... @@ -161,11 +160,9 @@ Example:
161 160 if(e.detail.id == "search_from_animated_button_container") {
162 161 var cards = document.querySelectorAll('.card');
163 162 for (var i = 0; i < cards.length; i++) {
164   - var title = cards[i].cardTitle;
165   - var comment = cards[i].comment;
166   - var type = cards[i].cardType;
167   -
168   - var searchFlag = title.indexOf(e.detail.searchKey) == -1 && comment.indexOf(e.detail.searchKey) == -1 && type.indexOf(e.detail.searchKey) == -1;
  163 + var title = cards[i].cardTitle ? cards[i].cardTitle : "";
  164 + var comment = cards[i].comment ? cards[i].comment : "";
  165 + var searchFlag = title.indexOf(e.detail.searchKey) == -1 && comment.indexOf(e.detail.searchKey) == -1;
169 166  
170 167 if (!searchFlag || e.detail.searchKey == "") {
171 168 cards[i].style.display = "inline-block";
... ...
controllets/items-vslider-controllet/items-vslider-controllet.html
... ... @@ -201,6 +201,8 @@
201 201 }
202 202 this.selectedDatalet = undefined;
203 203 this.filter = "";
  204 +
  205 + this.fire('items-vslider-controllet_selected-datalet', {datalet: undefined});
204 206 },
205 207  
206 208 _translate : function(){
... ...
controllets/search-panel-controllet/search-panel-controllet.html
... ... @@ -66,9 +66,8 @@ Example:
66 66 --paper-input-container-focus-color: #ffffff;
67 67 --paper-input-container-color: #ffffff;
68 68 position: absolute;
69   - /*top: -12px;*/
70   - /*width: 20vw;*/
71   - width: 392px;
  69 + width: 340px;
  70 + margin-left: -5px;
72 71 }
73 72  
74 73 paper-icon-button
... ... @@ -171,7 +170,7 @@ Example:
171 170 _valueChanged : function(oldvalue, newValue){
172 171 var t = this;
173 172 clearTimeout(this.timer);
174   - this.timer = setTimeout(function(){t.fire('search-panel-controllet_content-changed', {searchKey: t.searchKey, id : t.id})}, 500);
  173 + this.timer = setTimeout(function(){t.fire('search-panel-controllet_content-changed', {searchKey: t.searchKey, id : t.id})}, 0);
175 174 },
176 175 /**
177 176 * It returns the value in text area
... ...
controllets/select-data-controllet/select-data-controllet.html
... ... @@ -87,7 +87,7 @@
87 87  
88 88 filters : {
89 89 type : Array,
90   - value : undefined
  90 + value : []
91 91 },
92 92  
93 93 },
... ... @@ -99,23 +99,25 @@
99 99  
100 100 ready : function() {
101 101 $(this.$.material_tree_view).perfectScrollbar();
102   -
103   - if(this.filters == undefined){
104   - if(this.dataletPreset && this.dataletPreset["filters"] != undefined)
105   - this.filters = JSON.parse(this.dataletPreset["filters"]);
106   - else
107   - this.filters = [];
108   - }
109   -
110   - this.$.filters.filters = this.filters;
111   - this.$.multi_table.filters = this.filters;
112   - this._refreshTables();
113 102 },
114 103  
115 104 attached : function(){
116 105 this._resize();
117 106 var that = this;
118 107 window.addEventListener("resize", function() { that._resize(); });
  108 +
  109 + if(this.dataletPreset && this.dataletPreset["filters"] != undefined)
  110 + this._preselectFilters();
  111 + },
  112 +
  113 + _preselectFilters : function() {
  114 + this.async(function() {
  115 + this.filters = JSON.parse(this.dataletPreset["filters"]);
  116 + this.dataletPreset["filters"] = undefined;
  117 + this.$.filters.filters = this.filters;
  118 + this.$.multi_table.filters = this.filters;
  119 + this._refreshTables();
  120 + }, 1);
119 121 },
120 122  
121 123 getFilters : function() {
... ...
controllets/select-dataset-controllet/demo/index.html
... ... @@ -21,19 +21,24 @@
21 21 <style>
22 22  
23 23 .container {
24   - height: calc(90px * 5 - 8px);
25   - width: 50%;
26   - /*width: 400px;*/
  24 + /*height: calc(56px * 5 + 24px);*/
  25 + /*width: 50%;*/
  26 + width: 1652px;
27 27 position: relative;
28   - top: 100px;
29   - left:25%;
  28 + /*top: 100px;*/
  29 + left:5%;
30 30 /*background-color: red;*/
31 31 }
32 32  
33 33 </style>
34 34  
35 35 <div class="container">
36   - <select-dataset-controllet id="ds"></select-dataset-controllet>
  36 + <!--<select-dataset-controllet id="ds" datasets="we"></select-dataset-controllet>-->
  37 +
  38 + <select-dataset-controllet id="ds" datasets='{"result":{"providers":{"1":{"title":"CKAN","api_url":"http:\/\/ckan.routetopa.eu","image_hash":"11","id":"1"}},"datasets":[{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 2","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b056c5e6-76af-4526-a35d-7dee664fb6ee\/download\/isislab.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","resource_name":"First year (2015) ROUTE-TO-PA Dissemination","url":"http:\/\/ckan.routetopa.eu\/dataset\/d81d451d-8b3d-47f4-b57f-e295e8f51da0\/resource\/818c2edb-0cb7-4288-b340-e4dd1933d817\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link-Upd.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","resource_name":"First year (2015) ROUTE-TO-PA Dissemination - dl","url":"http:\/\/ckan.routetopa.eu\/dataset\/d81d451d-8b3d-47f4-b57f-e295e8f51da0\/resource\/fd8c4d6f-315d-4aa0-b7bd-4fdde7bf641b\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link-Upd.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","resource_name":"First year (2015) dissemination of ROUTE-TO-PA project","url":"http:\/\/ckan.routetopa.eu\/dataset\/d81d451d-8b3d-47f4-b57f-e295e8f51da0\/resource\/b0ef6017-8c64-4e11-8046-7e51a8561856\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link-Upd.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"test dissemination with link","resource_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","url":"http:\/\/ckan.routetopa.eu\/dataset\/ba5054af-7561-4f99-9504-76ea004a1e85\/resource\/4cc2349d-bf7b-4bbe-a7ca-db5312bb6c94\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Dissemination activity of the first year","resource_name":"Dissemination activity of the first year (2015)","url":"http:\/\/ckan.routetopa.eu\/dataset\/61f07087-210a-4c35-9606-2aafe183633b\/resource\/5f9d8d8b-1c41-45f7-9dbb-61b9a7bcd076\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"City of the Hague Municipality","package_name":"Test 3- Buurten","resource_name":"Test Buurten - 3","url":"http:\/\/ckan.routetopa.eu\/dataset\/1248d447-2901-4beb-91ae-c2f249fd8a99\/resource\/1fdbc765-8945-4271-8dce-9c7eba45a67d\/download\/Test-3-Compare.csv","metas":"{\"organization\":\"City of the Hague Municipality\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"}]}}'
  39 + suggested-datasets='[{"resource_name":"SUGGESTED 1","url":"noUrl.csv","metas":"{\"description\":\"noDescriione\"}"},{"resource_name":"SUGGESTED 2","url":"noUrl.csv","metas":"{\"description\":\"noDescriione\"}"},{"resource_name":"SUGGESTED 3","url":"noUrl.csv","metas":"{\"description\":\"noDescriione\"}"}]'
  40 + ></select-dataset-controllet>
  41 + <!--<select-dataset-controllet id="ds" datasets='{"result":{"providers":{"1":{"title":"CKAN","api_url":"http:\/\/ckan.routetopa.eu","image_hash":"11","id":"1"}},"datasets":[{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"}]}}'></select-dataset-controllet>-->
37 42 </div>
38 43  
39 44 <script>
... ... @@ -61,8 +66,9 @@
61 66 var datasets = [dataset1, dataset2, dataset3];
62 67 var datasets = [dataset1, dataset2, dataset3, dataset1, dataset2, dataset3, dataset1, dataset2, dataset3, dataset1, dataset2, dataset3, dataset1, dataset2, dataset3];
63 68  
64   - var ds = document.getElementById('ds');
65   - ds.setAttribute("items", JSON.stringify(datasets));
  69 +// var ds = document.getElementById('ds');
  70 +// ds.setAttribute("items", JSON.stringify(datasets));
  71 +// ds.setAttribute("items", a);
66 72  
67 73 </script>
68 74  
... ...
controllets/select-dataset-controllet/demo/test.json
  1 +"{"result":{"providers":{"1":{"title":"CKAN","api_url":"http:\/\/ckan.routetopa.eu","image_hash":"11","id":"1"}},"datasets":[{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 1","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b3d3d9ff-291e-47ca-a0d2-a15deef81737\/download\/isislab2.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"Dublin","package_name":"isislab DATA","resource_name":"Resource 2","url":"http:\/\/ckan.routetopa.eu\/dataset\/566c2867-ea89-45a2-bd7a-30ae82606007\/resource\/b056c5e6-76af-4526-a35d-7dee664fb6ee\/download\/isislab.csv","metas":"{\"organization\":\"Dublin\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","resource_name":"First year (2015) ROUTE-TO-PA Dissemination","url":"http:\/\/ckan.routetopa.eu\/dataset\/d81d451d-8b3d-47f4-b57f-e295e8f51da0\/resource\/818c2edb-0cb7-4288-b340-e4dd1933d817\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link-Upd.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","resource_name":"First year (2015) ROUTE-TO-PA Dissemination - dl","url":"http:\/\/ckan.routetopa.eu\/dataset\/d81d451d-8b3d-47f4-b57f-e295e8f51da0\/resource\/fd8c4d6f-315d-4aa0-b7bd-4fdde7bf641b\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link-Upd.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","resource_name":"First year (2015) dissemination of ROUTE-TO-PA project","url":"http:\/\/ckan.routetopa.eu\/dataset\/d81d451d-8b3d-47f4-b57f-e295e8f51da0\/resource\/b0ef6017-8c64-4e11-8046-7e51a8561856\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link-Upd.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"test dissemination with link","resource_name":"Year 1 Dissemination of the ROUTE-TO-PA project (2015)","url":"http:\/\/ckan.routetopa.eu\/dataset\/ba5054af-7561-4f99-9504-76ea004a1e85\/resource\/4cc2349d-bf7b-4bbe-a7ca-db5312bb6c94\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New---Link.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"ROUTE-TO-PA","package_name":"Dissemination activity of the first year","resource_name":"Dissemination activity of the first year (2015)","url":"http:\/\/ckan.routetopa.eu\/dataset\/61f07087-210a-4c35-9606-2aafe183633b\/resource\/5f9d8d8b-1c41-45f7-9dbb-61b9a7bcd076\/download\/ROUTE-TO-PA-Individual-Dissemination-Activity-Report-Form-Responses-New.csv","metas":"{\"organization\":\"ROUTE-TO-PA\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"},{"w":1,"provider_name":"p:1","organization_name":"City of the Hague Municipality","package_name":"Test 3- Buurten","resource_name":"Test Buurten - 3","url":"http:\/\/ckan.routetopa.eu\/dataset\/1248d447-2901-4beb-91ae-c2f249fd8a99\/resource\/1fdbc765-8945-4271-8dce-9c7eba45a67d\/download\/Test-3-Compare.csv","metas":"{\"organization\":\"City of the Hague Municipality\",\"description\":\"\",\"format\":\"\",\"last_modified\":\"\",\"name\":\"\",\"created\":\"\"}"}]}}"
0 2 \ No newline at end of file
... ...
controllets/select-dataset-controllet/select-dataset-controllet.html
1 1 <link rel="import" href="../../bower_components/polymer/polymer.html">
  2 +
  3 +<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
  4 +<link rel="import" href="../../bower_components/paper-tabs/paper-tab.html">
  5 +
  6 +<link rel="import" href="../../bower_components/neon-animation/neon-animation.html">
  7 +<link rel="import" href="../../bower_components/neon-animation/neon-animatable.html">
  8 +<link rel="import" href="../../bower_components/neon-animation/neon-animations.html">
  9 +
2 10 <link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
3 11 <!--<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">-->
4 12 <link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
... ... @@ -9,177 +17,328 @@
9 17 <link rel="import" href="../../bower_components/iron-image/iron-image.html">
10 18 <link rel="import" href="../../bower_components/iron-list/iron-list.html">
11 19  
  20 +<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
  21 +<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
  22 +<link rel="import" href="../../bower_components/paper-item/paper-item.html">
  23 +
  24 +<link rel="import" href="../../bower_components/paper-input/paper-input.html">
  25 +
  26 +<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
  27 +
  28 +<link rel="import" href="../../bower_components/paper-material/paper-material.html" />
  29 +
  30 +<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
  31 +<link rel="import" href="../../bower_components/iron-icons/hardware-icons.html">
  32 +<!--<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">-->
  33 +
  34 +<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
  35 +
  36 +<link rel="import" href="../../datalets/datasetexplorer-datalet/datasetexplorer-datalet.html">
12 37  
13 38 <dom-module id="select-dataset-controllet">
14 39 <template>
15 40 <style>
16   - /*:host {*/
17   - /*display: block;*/
18   - /*@apply(--paper-font-common-base);*/
19   - /*}*/
20   - /*app-toolbar {*/
21   - /*background-color: var(--google-green-700);*/
22   - /*box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);*/
23   - /*font-weight: bold;*/
24   - /*color: white;*/
25   - /*z-index: 1;*/
26   - /*position: fixed;*/
27   - /*top: 0;*/
28   - /*left: 0;*/
29   - /*right: 0;*/
30   - /*}*/
31   - /*app-toolbar paper-icon-button {*/
32   - /*--paper-icon-button-ink-color: white;*/
33   - /*}*/
34   - /*iron-list {*/
35   - /*padding-top: 64px;*/
36   - /*--iron-list-items-container: {*/
37   - /*max-width: 800px;*/
38   - /*margin: auto;*/
39   - /*margin-top: 60px;*/
40   - /*margin-bottom: 60px;*/
41   - /*border-bottom: 1px solid #ddd;*/
  41 + :host {
  42 + --paper-dropdown-menu-icon: {
  43 + color: #000000;
  44 + };
  45 + --paper-dropdown-menu-ripple: {
  46 + color: #FFFFFF;
  47 + };
  48 + /*--paper-tab-ink: {*/
  49 + /*color: #FFFFFF;*/
42 50 /*};*/
43   - /*}*/
  51 + }
  52 +
  53 + iron-list {
  54 + --iron-list-items-container: {
  55 + margin:16px 16px 8px 16px;
  56 + };
  57 + }
  58 +
  59 + paper-textarea {
  60 + width: 100%;
  61 + --paper-input-container-focus-color: #2196F3;
  62 + }
  63 +
  64 + paper-input {
  65 + --paper-input-container-focus-color: #2196F3;
  66 + }
  67 + paper-dropdown-menu {
  68 + width: 100%;
  69 + --paper-input-container-focus-color: #2196F3;
  70 + }
  71 +
  72 + paper-item.iron-selected {
  73 + background-color: #2196F3;
  74 + color: #FFFFFF;
  75 + }
  76 +
  77 + paper-checkbox {
  78 + height: 24px;
  79 + /*margin-top: 8px*/
  80 + --paper-checkbox-checked-color: #2196F3;
  81 + --paper-checkbox-checked-ink-color: #FFFFFF;
  82 + --paper-checkbox-unchecked-color: #000000;
  83 + --paper-checkbox-unchecked-ink-color: #FFFFFF;
  84 + --paper-checkbox-label-color: #000000;
  85 + }
  86 +
  87 + paper-icon-button{
  88 + height: 48px;
  89 + width: 48px;
  90 + padding: 0px;
  91 + --paper-icon-button-ink-color: #FFFFFF;
  92 + }
  93 +
  94 + paper-icon-button:hover{
  95 + color: #2196F3;
  96 + }
  97 +
  98 + paper-icon-button[disabled]{
  99 + color: #B6B6B6;
  100 + }
  101 +
  102 + paper-icon-button.clear {
  103 + width: 24px;
  104 + height: 24px;
  105 + padding: 0px 4px;
  106 + color: #F44336;
  107 + --paper-icon-button-ink-color: #FFFFFF;
  108 + }
  109 +
  110 + paper-tabs {
  111 + font-weight: bold;
  112 + }
  113 +
  114 + paper-tab {
  115 + transition: all 1.0s;
  116 + }
  117 +
  118 + paper-tab.iron-selected {
  119 + background-color: #2196F3;
  120 + color: #FFFFFF;
  121 + }
  122 +
  123 + paper-tab:not(.iron-selected):hover {
  124 + color: #2196F3;
  125 + }
  126 +
44 127 .item {
45   - @apply(--layout-horizontal);
46   - padding: 16px;
47   - background-color: #FFFFFF;
48   - border: 1px solid #B6B6B6;/*2196F3*/
  128 + /*@apply(--layout-horizontal);*/
  129 + display: flex;
  130 + padding: 11px;
  131 + border: 1px solid #B6B6B6;
49 132 cursor: pointer;
50 133 margin-bottom: 8px;
51   - /*border-radius: 8px;*/
  134 + background-color: #E0E0E0;
52 135 }
53 136  
54   - /*.avatar {*/
55   - /*height: 40px;*/
56   - /*width: 40px;*/
57   - /*border-radius: 20px;*/
58   - /*box-sizing: border-box;*/
59   - /*background-color: #DDD;*/
60   - /*}*/
61 137 .pad {
62   - /*padding: 0 16px;*/
63   - @apply(--layout-flex);
64   - @apply(--layout-vertical);
  138 + @apply(--layout-flex);
  139 + /*@apply(--layout-vertical);*/
65 140 }
  141 +
66 142 .primary {
67   - /*font-size: 16px;*/
68 143 font-weight: bold;
69   - /*padding-top: 5px;*/
70 144 }
71   - .shortText/*, .longText*/ {
72   - font-size: 16px;
  145 +
  146 + .item.expanded .primary {
  147 + color: #2196F3;
73 148 }
  149 +
74 150 .longText {
75   - color: gray;
76 151 display: none;
77 152 }
78   - .item:hover .shortText::after {
79   - content: ' [+]';
80   - color: gray;
81   - }
82   - .item.expanded:hover .shortText::after {
83   - content: '';
84   - }
  153 +
85 154 .item.expanded .longText {
86 155 display: block;
87 156 }
88   - .item.expanded:hover .longText::after {
89   - content: ' [–]';
90   - }
91   - /*.spacer {*/
92   - /*@apply(--layout-flex);*/
93   - /*}*/
94   - /*@media (max-width: 460px) {*/
95   - /*paper-toolbar .bottom.title {*/
96   - /*font-size: 14px;*/
97   - /*}*/
98   - /*}*/
99 157  
100   - /*.item.selected {*/
101   - /*border: 1px solid #2196F3;/!**!/*/
102   - /*}*/
103   -
104   - #list_container {
105   - /*background-color: #ccc;*/
106   - height: 100%;
107   - width: calc(100% - 16px);
108   - /*overflow: scroll;*/
109   - position: relative;
  158 + #select_dataset_container {
  159 + margin-top: 8px;
  160 + }
110 161  
  162 + #select_dataset_container * {
111 163 font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
112 164 font-size: 16px;
113   - line-height: 24px;/*???*/
  165 + line-height: 24px;
  166 + }
114 167  
115   - margin: 8px;
  168 + #select_dataset_container #neon_container {
  169 + height: calc(100% - 172px);
  170 + width: calc(100% - 8px);
  171 + }
116 172  
  173 + #select_dataset_container #list_container {
  174 + /*height: calc(100% - 244px);*/
  175 + /*width: calc(100% - 8px);*/
  176 + height: calc(100% - 48px);
  177 + width: 100%;
  178 + border: 4px solid #B6B6B6;
  179 + border-top: 0px;
  180 + border-bottom: 0px;
  181 + position: relative;
117 182 }
118 183  
119   - #select_dataset_container {
120   - /*padding: 8px;*/
121   - /*background-color: #B6B6B6;*/
122   - border: 4px solid #B6B6B6;/*2196F3*/
  184 + #select_dataset_container #treemap_container {
  185 + /*height: calc(100% - 244px);*/
  186 + /*width: calc(100% - 8px);*/
  187 + height: calc(100% - 48px);
  188 + width: 100%;
  189 + border: 4px solid #B6B6B6;
  190 + border-top: 0px;
  191 + border-bottom: 0px;
  192 + position: relative;
123 193 }
124 194  
125   - #toolbar {
126   - /*padding: 8px;*/
127   - /*background-color: #B6B6B6;*/
128   - width: calc(100% - 12px);
129   - height: 20px;
  195 + #select_dataset_container #header {
130 196 background-color: #B6B6B6;
  197 + display: flex;
  198 + padding: 0px 4px;
  199 + }
131 200  
132   - font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
133   - font-size: 16px;
134   - font-weight: bold;
135   - /*line-height: 24px;*/
136   - padding-left: 12px;
137   - padding-top: 12px;
138   - padding-bottom: 12px;
  201 + #select_dataset_container #footer_list,
  202 + #select_dataset_container #footer_treemap {
  203 + width: 100%;
  204 + background-color: #B6B6B6;
  205 + display: flex;
  206 + padding: 0px 4px;
  207 + }
  208 +
  209 + #select_dataset_container #url {
  210 + height: 76px;/*100*/
  211 + border: 4px solid #B6B6B6;
  212 + border-top: 0px;
  213 + padding: 0px 16px;
  214 + margin-top: -4px;
139 215 }
140   - .ssssssssseeeel {
141   - background-color: red;
  216 +
  217 + #header .header_block {
  218 + width: 20%;
  219 + height: 40px;
  220 + padding: 4px 16px 4px 16px;
  221 + }
  222 +
  223 + /*.header_block:nth-child(2), .header_block:nth-child(3), .header_block:nth-child(3), .header_block:nth-child(4){*/
  224 + /*visibility: hidden;*/
  225 + /*}*/
  226 +
  227 + #header .header_block:nth-child(4) {
  228 + text-align: center;
142 229 }
143 230  
  231 + .footer_block {
  232 + width: calc((100% - 0px) / 3);
  233 + height: 24px;
  234 + padding: 12px 8px 12px 8px;
  235 + text-align: center;
  236 + }
  237 +
  238 + .footer_block:nth-child(2) {
  239 + height: 48px;
  240 + padding: 0px 8px;
  241 + }
  242 +
  243 + #suggested_div {
  244 + visibility: hidden;
  245 + }
144 246 </style>
145 247  
146   - <div id="select_dataset_container">
  248 + <paper-material id="select_dataset_container" elevation="5">
147 249  
148   - <div id="toolbar">
149   - AVAILABLE DATASETS
  250 + <paper-tabs selected="{{selected}}" no-bar>
  251 + <paper-tab noink on-tap="_refreshList"><span id="listView"></span></paper-tab>
  252 + <!--<paper-tab noink ><span id="listView"></span></paper-tab>-->
  253 + <paper-tab noink><span id="treeMapView"></span></paper-tab>
  254 + </paper-tabs>
150 255  
  256 + <div id="header">
  257 + <div class="header_block">
  258 + <paper-dropdown-menu id="ddl_provider" label="" no-label-float>
  259 + <paper-menu class="dropdown-content" selected="0">
  260 + <paper-item id="0" on-tap="_filter"></paper-item>
  261 + <template is="dom-repeat" items={{_toArray(providers)}} as="provider">
  262 + <!--<paper-item id={{provider.value.id}} style$="background: {{_getProviderColor(provider.value.id)}};">{{provider.value.title}}</paper-item>-->
  263 + <paper-item id={{provider.value.id}} on-tap="_filter">{{provider.value.title}}</paper-item>
  264 + </template>
  265 + </paper-menu>
  266 + </paper-dropdown-menu>
  267 + </div>
  268 + <div class="header_block">
  269 + </div>
  270 + <div class="header_block">
  271 + </div>
  272 + <div class="header_block">
  273 + </div>
  274 + <div class="header_block">
  275 + <paper-input id="datasets_filter" value={{filter}} no-label-float label="">
  276 + <iron-icon class="search" icon="search" prefix></iron-icon>
  277 + <paper-icon-button class="clear" suffix on-click="_clearInput" icon="clear" tabindex="0"></paper-icon-button>
  278 + </paper-input>
  279 + </div>
151 280 </div>
152 281  
153   - <div id="list_container">
154   -
155   - <!--<iron-ajax url="data/contacts.json" last-response="{{items}}" auto></iron-ajax>-->
156   -
157   - <!--<app-toolbar>-->
158   - <!--<div title>Collapsable items</div>-->
159   - <!--<paper-icon-button icon="search" alt="Search"></paper-icon-button>-->
160   - <!--<paper-icon-button icon="more-vert" alt="More options"></paper-icon-button>-->
161   - <!--</app-toolbar>-->
162   -
163   - <iron-list id="list" items="[[items]]" as="item" selection-enabled><!--multi-selection-->
164   - <template>
165   - <div>
166   - <div class$="[[getClassForItem(item, selected)]]" tabindex$="[[tabIndex]]" on-tap="_prova">
167   - <!--<iron-image class="avatar" sizing="contain" src="[[item.image]]"></iron-image>-->
168   - <div class="pad">
169   - <div class="primary">[[item.name]]</div>
170   - <!--<div class="shortText">[[item.url]]</div>-->
171   - <!--substring description-->
172   - <div class="longText">[[item.description]]</div>
  282 + <neon-animated-pages id="neon_container" selected="{{selected}}" entry-animation="fade-in-animation" exit-animation="fade-out-animation">
  283 +
  284 + <neon-animatable>
  285 + <div id="list_container">
  286 + <iron-list id="list" items="{{shownDatasets}}" selection-enabled><!--multi-selection-->
  287 + <template>
  288 + <div>
  289 + <div class$="{{getClassForItem(selected)}}" on-tap="_selectDataUrl" style$="background: {{_getColorForItem(item)}};">
  290 + <!--<div class$="{{getClassForItem(selected)}}" on-tap="_selectDataUrl">-->
  291 + <span style="display:none;">{{item.url}}</span>
  292 + <div class="pad">
  293 + <div class="primary">{{item.resource_name}}</div>
  294 + <!--<div class="shortText" style="display:none;">{{item.url}}</div>-->
  295 + <div class="longText">
  296 + <template is="dom-repeat" items="{{_stringToArray(item.metas)}}" as="mata">
  297 + <b>{{mata.name}}:</b>
  298 + <span inner-h-t-m-l="{{mata.value}}"></span> <br>
  299 + </template>
  300 + </div>
  301 + </div>
  302 + <!--<iron-icon icon$="[[iconForItem(item)]]"></iron-icon>-->
  303 + <!--<iron-icon icon="bookmark" style$="color: {{_getColorForItem(item)}};"></iron-icon>-->
  304 + <iron-icon icon$="{{_getIconForItem(item)}}" style$="color: {{_getColorForIcon(item)}};"></iron-icon>
  305 + </div>
173 306 </div>
174   - <iron-icon icon$="[[iconForItem(item)]]"></iron-icon>
175   - </div>
  307 + </template>
  308 + </iron-list>
  309 + </div>
  310 +
  311 + <div id="footer_list">
  312 + <div class="footer_block"><span id="showing"></span> {{shownPrev}} <span id="to"></span> {{shownNext}} <span id="of"></span> {{length}} <span id="datasets"></span></div>
  313 + <div class="footer_block">
  314 + <paper-icon-button id="slider_chevron_left" class="chevron-left" on-click="_onPrevClick" icon="chevron-left"></paper-icon-button>
  315 + <paper-icon-button id="slider_chevron_right" class="chevron-right" on-click="_onNextClick" icon="chevron-right"></paper-icon-button>
  316 + </div>
  317 + <div id="suggested_div" class="footer_block">
  318 + <!--<template is="dom-if" if={{suggestedDatasets}}>-->
  319 + <paper-checkbox checked on-change="showSuggested"><span id="suggested_datasets"></span></paper-checkbox>
  320 + <!--</template>-->
176 321 </div>
177   - </template>
178   - </iron-list>
  322 + </div>
  323 + </neon-animatable>
  324 +
  325 + <neon-animatable>
  326 + <div id="treemap_container"></div>
  327 +
  328 + <div id="footer_treemap">
  329 + <div class="footer_block"><span id="showing2"></span> {{tLength}} <span id="datasets2"></span></div>
  330 + <div class="footer_block"></div>
  331 + <div class="footer_block"></div>
  332 + </div>
  333 + </neon-animatable>
179 334  
  335 + </neon-animated-pages>
  336 +
  337 + <div id="url">
  338 + <paper-textarea id="selected_url" label="" value={{dataUrl}} error-message={{errorMessage}}></paper-textarea>
180 339 </div>
181 340  
182   - </div>
  341 + </paper-material>
183 342  
184 343 </template>
185 344  
... ... @@ -188,34 +347,353 @@
188 347 Polymer({
189 348 is: 'select-dataset-controllet',
190 349 properties: {
191   - items: {
192   - type: Array,
193   - value: [
194   -// {"name": "Bob"},
195   -// {"name": "Tim"},
196   -// {"name": "Mike"}
197   - ]
  350 + datasets: {
  351 + type: Object,
  352 + value: undefined
  353 + },
  354 + filteredDatasets : {
  355 + type : Array,
  356 + value : undefined
  357 + },
  358 + shownDatasets : {
  359 + type : Array,
  360 + value : undefined
  361 + },
  362 + suggestedDatasets : {
  363 + type : Array,
  364 + value : undefined
  365 + },
  366 +
  367 + providers : {
  368 + type : Array,
  369 + value : undefined
  370 + },
  371 + dataUrl : {
  372 + type : String,
  373 + value : undefined,
  374 + observer : '_fireDataUrl'
  375 + },
  376 + filter : {
  377 + type : String,
  378 + value : "",
  379 + observer : '_filter'
  380 + },
  381 + selected : {
  382 + type : Number,
  383 + value : 0
  384 + },
  385 + prev : {type : Number, value : undefined},
  386 + next : {type : Number, value : undefined},
  387 + shownPrev : {type : Number, value : undefined},
  388 + shownNext : {type : Number, value : undefined},
  389 + length : {type : Number, value : undefined},
  390 + tLength : {type : Number, computed : 'treemapLength(length)'},
  391 + step : {type : Number, value : 20},
  392 + colors : {
  393 + type : Array,
  394 + value : ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"]
198 395 }
199 396 },
  397 +
  398 + listeners: {
  399 + 'datasetexplorer-datalet_data-url': '_selectDataUrl_treeMap'
  400 + },
  401 +
200 402 ready : function() {
201 403 $(this.$.list_container).perfectScrollbar();
202   - },
203   - _prova : function(e) {
204   -// console.log(e.target);
205   -// e.target.style.background = "#B6B6B6";
  404 +
  405 +// this.$.selected_url.invalid = true;
206 406 },
207 407  
208 408 attached: function() {
209   - // Use the document element
  409 + this._resize();
  410 + var that = this;
  411 + window.addEventListener("resize", function() { that._resize(); });
  412 +
  413 + this.providers = this.datasets["result"]["providers"];
  414 + this.datasets = this.datasets["result"]["datasets"];
  415 +
  416 + if(this.suggestedDatasets) {
  417 + this.tempDatasets = this.datasets;
  418 + this.datasets = this.suggestedDatasets.concat(this.datasets);
  419 + this.$.suggested_div.style.visibility = "visible";
  420 + }
  421 +
  422 + this.filteredDatasets = this.datasets;
  423 +
  424 + this.prev = 1;
  425 + this.next = this.step;
  426 + this.length = this.filteredDatasets.length;
  427 +
  428 + this.shownPrev = Math.min(this.prev, this.length);
  429 + this.shownNext = Math.min(this.next, this.length);
  430 + this.shownDatasets = this.filteredDatasets.slice(this.prev-1, this.next);
  431 +
210 432 this.$.list.scrollTarget = this.ownerDocument.documentElement;
  433 +
  434 + this._translate();
  435 +
  436 + this._loadTreeMap();
  437 + },
  438 +
  439 + _translate : function(){
  440 + this.$.listView.innerHTML = ln["listView_" + ln["localization"]];
  441 + this.$.treeMapView.innerHTML = ln["treeMapView_" + ln["localization"]];
  442 +
  443 + this.$.ddl_provider.setAttribute("label", ln["provider_" + ln["localization"]]);
  444 + this.$.datasets_filter.setAttribute("label", ln["search_" + ln["localization"]]);
  445 +
  446 + this.$.suggested_datasets.innerHTML = ln["suggestedDatasets_" + ln["localization"]];
  447 +
  448 + this.$.showing.innerHTML = ln["showing_" + ln["localization"]];
  449 + this.$.showing2.innerHTML = ln["showing_" + ln["localization"]];
  450 + this.$.to.innerHTML = ln["to_" + ln["localization"]];
  451 + this.$.of.innerHTML = ln["of_" + ln["localization"]];
  452 + this.$.datasets.innerHTML = ln["datasets_" + ln["localization"]];
  453 + this.$.datasets2.innerHTML = ln["datasets_" + ln["localization"]];
  454 +
  455 + this.$.selected_url.setAttribute("label", ln["selectedUrl_" + ln["localization"]]);
  456 + this.errorMessage = ln["wrongUrl_" + ln["localization"]];
211 457 },
212   - iconForItem: function(item) {
213   - return item ? (item.integer < 50 ? 'star-border' : 'info-outline') : '';
  458 +
  459 + showSuggested : function(e) {
  460 + if(e.target.checked)
  461 + this.datasets = this.suggestedDatasets.concat(this.tempDatasets);
  462 + else
  463 + this.datasets = this.tempDatasets;
  464 + this._filter();
  465 + },
  466 +
  467 + _loadTreeMap : function(){
  468 + var h = $("#neon_container").height() - 48;
  469 + var w = $("#neon_container").width();
  470 +
  471 + var data = JSON.stringify({result : {providers: this.providers, datasets: this.filteredDatasets}}).replace(/'/g, "");
  472 +
  473 + if(this.filteredDatasets.length > 0)
  474 + this.$.treemap_container.innerHTML = "<datasetexplorer-datalet data='"+data+"' width=\""+w+"\" height=\""+h+"\" fields='[\"result,datasets,provider_name\",\"result,datasets,organization_name\",\"result,datasets,package_name\",\"result,datasets,resource_name\",\"result,datasets,url\",\"result,datasets,w\",\"result,datasets,metas\"]'></datasetexplorer-datalet>";
  475 + else
  476 + this.$.treemap_container.innerHTML = "";
  477 + },
  478 +
  479 + _filter : function() {
  480 + if(this.filteredDatasets) {
  481 + this.async(function () {
  482 + var ddl_provider = $(this.$.ddl_provider).find("paper-menu")[0].selectedItem;
  483 + var name = ddl_provider.innerHTML.trim();
  484 + var id = this._getIdByProviderName(name);
  485 + this.prev = 1;
  486 + this.next = this.step;
  487 + if (id) {
  488 + //filtered by provider name
  489 + this.filteredDatasets = this.datasets.filter(function (el) {
  490 + return el.provider_name == "p:" + id;
  491 + });
  492 + }
  493 + else {
  494 + this.filteredDatasets = this.datasets;
  495 + }
  496 +
  497 + //filtered by filter
  498 + var filter = this.filter;
  499 + this.filteredDatasets = this.filteredDatasets.filter(function (el) {
  500 + return el.resource_name.toLowerCase().indexOf(filter.toLowerCase()) > -1;
  501 + });
  502 +
  503 + this.length = this.filteredDatasets.length;
  504 +
  505 + this.shownPrev = Math.min(this.prev, this.length);
  506 + this.shownNext = Math.min(this.next, this.length);
  507 + this.shownDatasets = this.filteredDatasets.slice(this.prev - 1, this.next);
  508 +
  509 + $("#list_container").animate({scrollTop: 0}, 0);
  510 +
  511 + this._loadTreeMap();
  512 + }, 0);
  513 + }
  514 + },
  515 +
  516 + _refreshList : function() {
  517 + this.shownDatasets = this.filteredDatasets.slice(this.prev - 1, this.next);
  518 + },
  519 +
  520 + _clearInput : function() {
  521 + this.$.datasets_filter.value = "";
214 522 },
215   - getClassForItem: function(item, selected) {
216   - console.log(item);
217   - console.log(selected);
  523 +
  524 + _getIdByProviderName : function(name) {
  525 + for(var id in this.providers) {
  526 + if (this.providers[id].title == name)
  527 + return this.providers[id].id;
  528 + }
  529 + },
  530 +
  531 +// iconForItem: function(item) {
  532 +// return item ? (item.integer < 50 ? 'star-border' : 'info-outline') : '';
  533 +// },
  534 +
  535 + treemapLength : function(length) {
  536 + var ddl_provider = $(this.$.ddl_provider).find("paper-menu")[0].selectedItem;
  537 + var name = ddl_provider.innerHTML.trim();
  538 + var id = this._getIdByProviderName(name);
  539 +
  540 + if(this.suggestedDatasets && !id)
  541 + return Math.max(length - this.suggestedDatasets.length, 0);
  542 + return length;
  543 + },
  544 +
  545 + _getColorForIcon : function(item) {
  546 + var ddl_provider = $(this.$.ddl_provider).find("paper-menu")[0].selectedItem;
  547 + var name = ddl_provider.innerHTML.trim();
  548 + var id = this._getIdByProviderName(name);
  549 + if (id) {
  550 + return this.colors[0];
  551 + }
  552 + if(!item.provider_name) {
  553 + return "#00BCD4";
  554 + }
  555 + var id = item.provider_name.substring(2, item.provider_name.length);
  556 + var i = this.getProviderById(id) % this.colors.length;
  557 + return this.colors[i];
  558 + },
  559 +
  560 + _getColorForItem : function(item) {
  561 +// var ddl_provider = $(this.$.ddl_provider).find("paper-menu")[0].selectedItem;
  562 +// var name = ddl_provider.innerHTML.trim();
  563 +// var id = this._getIdByProviderName(name);
  564 +// if (id) {
  565 +// return this.colors[0];
  566 +// }
  567 + if(!item.provider_name) {
  568 + return "#FFEB3B";
  569 + }
  570 +// var id = item.provider_name.substring(2, item.provider_name.length);
  571 +// var i = this.getProviderById(id) % this.colors.length;
  572 +// return this.colors[i];
  573 + },
  574 +
  575 + _getIconForItem : function(item) {
  576 + return item.provider_name ? 'bookmark' : 'star';
  577 + },
  578 +
  579 +// _getProviderColor: function(id) {
  580 +// var i = this.getProviderById(id) % this.colors.length;
  581 +// return this.colors[i];
  582 +// },
  583 +
  584 + getClassForItem: function(selected) {
218 585 return selected ? 'item expanded' : 'item';
  586 + },
  587 +
  588 + getProviderById: function(providerId) {
  589 + var i = 0;
  590 + for(var id in this.providers){
  591 + if(this.providers[id].id == providerId)
  592 + return i;
  593 + i++;
  594 + }
  595 + },
  596 +
  597 + _onPrevClick : function(){
  598 + if(this.prev != 1) {
  599 + this.prev -= this.step;
  600 + this.next -= this.step;
  601 +
  602 + this.shownPrev = Math.min(this.prev, this.length);
  603 + this.shownNext = Math.min(this.next, this.length);
  604 + this.shownDatasets = this.filteredDatasets.slice(this.prev - 1, this.next);
  605 + }
  606 + $("#list_container").animate({ scrollTop: 0}, 0);
  607 + },
  608 +
  609 + _onNextClick : function(){
  610 + if(this.next < this.length) {
  611 + this.prev += this.step;
  612 + this.next += this.step;
  613 +
  614 + this.shownPrev = Math.min(this.prev, this.length);
  615 + this.shownNext = Math.min(this.next, this.length);
  616 + this.shownDatasets = this.filteredDatasets.slice(this.prev - 1, this.next);
  617 + }
  618 + $("#list_container").animate({ scrollTop: 0}, 0);
  619 + },
  620 +
  621 + _stringToArray: function(obj) {
  622 + obj = JSON.parse(obj);
  623 + return Object.keys(obj).map(function(key) {
  624 + return {
  625 + name: key,
  626 + value: obj[key]
  627 + };
  628 + });
  629 + },
  630 +
  631 + _toArray: function(obj) {
  632 + return Object.keys(obj).map(function(key) {
  633 + return {
  634 + name: key,
  635 + value: obj[key]
  636 + };
  637 + });
  638 + },
  639 +
  640 + _selectDataUrl : function(){
  641 + this.async(function () {
  642 + if(this.$.list.selectedItem) {
  643 + var url = this.$.list.selectedItem.url;
  644 +
  645 + // Check if CKAN
  646 + var strDatasetPos = url.indexOf('/dataset/');
  647 + var strResourcePos = (strDatasetPos >= 0) ? url.indexOf('/resource/') : -1;
  648 + if (strDatasetPos >= 0 && strResourcePos > strDatasetPos) {
  649 + var urlSegment1 = url.substring(0, strDatasetPos);
  650 + var urlResourceEnd = url.indexOf('/', strResourcePos + 10);
  651 + var resourceId = url.substring(strResourcePos + 10, urlResourceEnd);
  652 + url = urlSegment1 + "/api/action/datastore_search?resource_id=" + resourceId;
  653 + }
  654 +
  655 + // Check if OPENDATASOFT
  656 + var strExploreDatasetPos = url.indexOf('/explore/dataset/');
  657 + if (strExploreDatasetPos >= 0) {
  658 + var urlSegment1 = url.substring(0, strExploreDatasetPos);
  659 + var datasetEnd = url.indexOf(strExploreDatasetPos + 17, '/');
  660 + var datasetId = url.substring(strExploreDatasetPos + 17, datasetEnd >= 0 ? datasetEnd : url.length);
  661 + url = urlSegment1 + '/api/records/1.0/search?dataset=' + datasetId;
  662 + }
  663 +
  664 + this.dataUrl = this._addlimitUrl(url);
  665 + }
  666 + else {
  667 + this.dataUrl = "";
  668 + }
  669 + }, 0);
  670 + },
  671 +
  672 + _selectDataUrl_treeMap : function(e) {
  673 + this.dataUrl = this._addlimitUrl(e.detail.url);
  674 + },
  675 +
  676 + _fireDataUrl : function(){
  677 + this.fire('dataset-selection-controllet_data-url', {url: this.dataUrl});
  678 + },
  679 +
  680 + _addlimitUrl : function(url){
  681 + //CKAN --> action no limit
  682 + if((url.indexOf("api/action") > -1) && !(url.indexOf("limit") > -1))
  683 + {
  684 + url += "&limit=99999";
  685 + }
  686 + //OpenDataSoft --> action no limit
  687 + if((url.indexOf("api/records") > -1) && !(url.indexOf("rows") > -1)){
  688 + url += "&rows=10000";
  689 + }
  690 + return url;
  691 + },
  692 +
  693 + _resize : function(){
  694 + var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - 16;
  695 + h = h - 64 - 8; //height with page scroller
  696 + $("#select_dataset_container").height(h);
219 697 }
220 698 });
221 699 });
... ...
controllets/select-visualization-controllet/select-datalet-inputs.html
... ... @@ -186,6 +186,18 @@
186 186 this._translate();
187 187 },
188 188  
  189 + _preselectInputs : function(fields, aggregators, orders) {
  190 + var ddls = this.$.inputs_container.querySelectorAll("paper-dropdown-menu");
  191 +
  192 +// this.async(function () {
  193 + for (var i = 0; i < fields.length; i++) {
  194 + var menu = $(ddls[i]).find("paper-menu")[0];
  195 + menu.select(i+1);
  196 + }
  197 + this.selectedFields = this._copy(fields);
  198 +// }, 2);
  199 + },
  200 +
189 201 getSelectedFields : function () {
190 202 return this.selectedFields.filter(function(field){ return field != "" });
191 203 },
... ... @@ -201,11 +213,12 @@
201 213 setFields : function(fields) {
202 214 var temp = this._copy(fields);
203 215 temp.unshift("");
204   - this.fields = this._copy(temp);
205   -
206   - this.$.expert_header.style.display = "block";
207 216  
208   - this._reset();
  217 + if (JSON.stringify(this.fields) != JSON.stringify(temp)) {
  218 + this.fields = this._copy(temp);
  219 + this.$.expert_header.style.display = "block";
  220 + this._reset();
  221 + }
209 222 },
210 223  
211 224 setInputs : function(inputs) {
... ...
controllets/select-visualization-controllet/select-datalet-inputs_series.html
... ... @@ -187,6 +187,18 @@
187 187 this._translate();
188 188 },
189 189  
  190 + _preselectInputs : function(fields, aggregators, orders) {
  191 + var ddls = this.$.inputs_series_container.querySelectorAll("paper-dropdown-menu");
  192 +
  193 +// this.async(function () {
  194 + for (var i = 0; i < fields.length; i++) {
  195 + var menu = $(ddls[i]).find("paper-menu")[0];
  196 + menu.select(i+1);
  197 + }
  198 + this.selectedFields = this._copy(fields);
  199 +// }, 0);
  200 + },
  201 +
190 202 getSelectedFields : function () {
191 203 var gb_menu = $(this.$.group_by).find("paper-menu")[0];
192 204 var c_menu = $("#calculate_0").find("paper-menu")[0];
... ... @@ -210,9 +222,11 @@
210 222 setFields : function(fields) {
211 223 var temp = this._copy(fields);
212 224 temp.unshift("");
213   - this.fields = this._copy(temp);
214 225  
215   - this._reset();
  226 + if (JSON.stringify(this.fields) != JSON.stringify(temp)) {
  227 + this.fields = this._copy(temp);
  228 + this._reset();
  229 + }
216 230 },
217 231  
218 232 setInputs : function(inputs) {
... ...
controllets/select-visualization-controllet/select-datalet-options.html
... ... @@ -195,6 +195,28 @@
195 195 this._translate();
196 196 },
197 197  
  198 + _preselectOptions : function(params) {
  199 + var textarea = this.$.select_datalet_options_container.querySelectorAll("paper-textarea");
  200 + textarea[0].value = params["description"];
  201 +
  202 + var inputs = this.$.select_datalet_options_container.querySelectorAll("paper-input");
  203 + inputs[0].value = params["title"];
  204 +
  205 + for (var i = 1; i < inputs.length; i++)
  206 + if(params[this.options[i - 1].name])
  207 + inputs[i].value = params[this.options[i - 1].name];
  208 +
  209 + this._updateParams();
  210 +
  211 +// var menus = this.$.select_datalet_options_container.querySelectorAll("paper-menu");
  212 +// var ddls = this.$.select_datalet_options_container.querySelectorAll("paper-dropdown-menu");
  213 +// for (var i = 0; i < ddls.length; i++) {
  214 +// var menu = $(ddls[i]).find("paper-menu")[0];
  215 +// if(params[ddls[i].label])
  216 +// menu.select(1);//select item con nome params[ddls[i].label]
  217 +// }
  218 + },
  219 +
198 220 setOptions : function(options) {
199 221 this.options = [];
200 222 this.params = [];
... ...
controllets/select-visualization-controllet/select-visualization-controllet.html
... ... @@ -205,10 +205,7 @@
205 205  
206 206 $(this.$.datalet_selection_datalet).perfectScrollbar();
207 207  
208   - this.params = {'data-url' : this.dataUrl};
209   -
210   - if(this.preselectedDatalet)
211   - this._preselectDatalet();
  208 +// this.params = {'data-url' : this.dataUrl};//not here
212 209 },
213 210  
214 211 attached : function() {
... ... @@ -224,17 +221,27 @@
224 221 },
225 222  
226 223 setFields : function(fields) {
  224 + if (this.fields.length > 0 && JSON.stringify(this.fields) != JSON.stringify(fields))
  225 + this.reset();
  226 +
227 227 this.fields = this._copy(fields);
228 228  
229 229 var inputs = this._getInputs();
230   - if(inputs)
  230 + if (inputs)
231 231 inputs.setFields(this.fields);
232 232 },
233 233  
234 234 reset : function() {
235 235 this.$.vslider._reset();
236   - this.type = "";
237   - this.$.datalet_selection_datalet_placeholder.innerHTML = "";
  236 + },
  237 +
  238 + show : function() {//show --> preselect
  239 + if(this.preselectedDatalet)
  240 + this._preselectDatalet();
  241 +// if (this.$.datalet_selection_datalet_placeholder.innerHTML == "") {
  242 +// var inputs = this._getInputs();
  243 +// inputs.fireReady();
  244 +// }
238 245 },
239 246  
240 247 _translate : function(){
... ... @@ -264,25 +271,6 @@
264 271 }
265 272 },
266 273  
267   - _preselectDatalet : function() {
268   -// console.log("_preselectDatalet to implement");
269   -// console.log(this.preselectedDatalet);
270   -// console.log(this.fields);
271   -// console.log(this.dataletPreset);
272   -
273   - var dataletParams ={
274   - component : this.preselectedDatalet+"-datalet",
275   - params : this.dataletPreset,
276   - fields : this.fields,
277   - placeHolder : this.$.datalet_selection_datalet_placeholder
278   - };
279   -
280   - ComponentService.deep_url = this.deepUrl;
281   - ComponentService.getComponent(dataletParams);
282   -
283   - this.$.add_button.removeAttribute("disabled");
284   - },
285   -
286 274 _handleSelectedDatalet : function(e){
287 275  
288 276 if(this.type != e.detail.response.type) {
... ... @@ -305,6 +293,23 @@
305 293 var inputs = this._getInputs();
306 294 inputs.fireReady();
307 295 }, 0);
  296 +
  297 +// this.async(function () {
  298 +// if(this.preselectedDatalet)
  299 +// this._preselectDatalet();
  300 +// }, 1);
  301 + },
  302 +
  303 + _preselectDatalet : function() {
  304 + var inputs = this._getInputs();
  305 + inputs._preselectInputs(this.fields, this.dataletPreset["aggregators"], this.dataletPreset["orders"]);
  306 + this.$.options._preselectOptions(this.dataletPreset);
  307 + this.dataletPreset = undefined;
  308 +
  309 +// this.async(function () {
  310 +// var inputs = this._getInputs();
  311 +// inputs.fireReady();
  312 +// }, 500);
308 313 },
309 314  
310 315 _tryLoadDatalet : function(){
... ... @@ -322,6 +327,8 @@
322 327  
323 328 this.selectedFields = inputs.getSelectedFields();
324 329  
  330 + this.params = {'data-url' : this.dataUrl};
  331 +
325 332 this.params["filters"] = JSON.stringify(this.filters);
326 333 this.params["aggregators"] = JSON.stringify(inputs.getAggregators());
327 334 this.params["orders"] = JSON.stringify(inputs.getOrders());
... ...
datalets/datasetexplorer-datalet/datasetexplorer-datalet.html
... ... @@ -164,7 +164,7 @@ Example:
164 164 this.map.children = [];
165 165  
166 166 for(var i = 0; i < treemapData.length; i++){
167   - this.checkAggragationField(treemapData[i], this._component.fields.length - 1, this._component.fields.length - 1);
  167 + this.checkAggragationField(treemapData[i], this._component.fields.length - 2, this._component.fields.length - 2);
168 168 }
169 169  
170 170 var json = JSON.stringify(this.map);
... ... @@ -204,6 +204,7 @@ Example:
204 204 var xyz = function(url) {
205 205 me.selectResource(url);
206 206 }
  207 + this.map.name = this._component.name;
207 208 build2(this.map, this.meta, this._component.$.treemap_placeholder, xyz, this._component.width, this._component.height);
208 209 },
209 210  
... ... @@ -262,6 +263,11 @@ Example:
262 263 value : {}
263 264 },
264 265  
  266 + name : {
  267 + type : String,
  268 + value: ""
  269 + },
  270 +
265 271 width : {
266 272 type : Number,
267 273 value: 968
... ...
datalets/datasetexplorer-datalet/js/buildtreemap2.js
... ... @@ -148,17 +148,13 @@ function build2(root, meta, place_holder, select_listener, width, height) {
148 148 // FIRST LVL
149 149 data[0] = "first";
150 150 data[1] = meta[id]['title'];
151   - var key = (typeof OW == 'undefined') ? "" : OW.getLanguageText('openwall', 'provider_'+id);
152   - //data[3] = key;
153   - data[3] = datasetexplorer_ln[key+"_"+datasetexplorer_ln["ln"]];
154   - //data[4] = ((typeof ODE == 'undefined') ? parent.ODE.THEME_IMAGES_URL : ODE.THEME_IMAGES_URL) + "/logos/"+id+".png";//meta[id]['logo_url'];
155   - data[4] = "/ow_static/themes/spod_theme_matter/images/logos/"+id+".png";//meta[id]['logo_url'];
156   - //data[5] = d.value;
  151 + data[3] = meta[id]['description'];
  152 + data[4] = "/ow_static/themes/spod_theme_matter/images/logos/"+id+".png";
  153 + //data[4] = "/ow_static/themes/spod_theme_matter/images/logos/"+meta[id]['logo_png'];
157 154 } else if (d._children && !d._children[0]._children) {
158 155 // LAST LVL
159 156 data[0] = "last";
160 157 data[6] = d._children[0].name;
161   - //data[6] = "datasert url";
162 158 } else {
163 159 // MIDDLE LVL
164 160 data[0] = "middle";
... ... @@ -346,7 +342,7 @@ function build2(root, meta, place_holder, select_listener, width, height) {
346 342  
347 343 function name(d) {
348 344 return d.parent
349   - ? name(d.parent) + " >> " + checkProviderName(d.name)
  345 + ? name(d.parent) + "." + checkProviderName(d.name)
350 346 : checkProviderName(d.name);
351 347 }
352 348  
... ...
locales/controllet_ln.js
... ... @@ -4,7 +4,7 @@ var ln = [];
4 4  
5 5 //PAGE SLIDER
6 6 ln["slide1Title_en"] = "SELECT DATASET";
7   -ln["slide1Subtitle_en"] = "Search or copy and paste the url of dataset.";
  7 +ln["slide1Subtitle_en"] = "Select a dataset from the list or copy and paste the url of dataset.";
8 8 ln["slide2Title_en"] = "SELECT DATA";
9 9 ln["slide2Subtitle_en"] = "Select the fields from tree-view. The multi-table will show the values related to the selected fields.";
10 10 ln["slide3Title_en"] = "SELECT VISUALIZATION";
... ... @@ -15,7 +15,12 @@ ln[&quot;forward_en&quot;] = &quot;Forward&quot;;
15 15 //SELECT DATASET
16 16 ln["listView_en"] = "LIST VIEW";
17 17 ln["treeMapView_en"] = "TREE MAP VIEW";
18   -ln["availableDatasets_en"] = "Available datasets";
  18 +ln["provider_en"] = "Provider";
  19 +ln["showing_en"] = "Showing";
  20 +ln["to_en"] = "to";
  21 +ln["of_en"] = "of";
  22 +ln["datasets_en"] = "datasets";
  23 +//ln["availableDatasets_en"] = "Available datasets";
19 24 ln["suggestedDatasets_en"] = "Suggested datasets";
20 25 ln["selectedUrl_en"] = "Selected url";
21 26 ln["wrongUrl_en"] = "Invalid url or data provider not supported yet.";
... ... @@ -112,7 +117,7 @@ ln[&quot;donut_description_en&quot;] = &quot;If &#39;true&#39; Pie will become Donut! :)&quot;;
112 117  
113 118 //PAGE SLIDER
114 119 ln["slide1Title_it"] = "SELEZIONA IL DATASET";
115   -ln["slide1Subtitle_it"] = "Ricerca o copia e incolla la url del dataset.";
  120 +ln["slide1Subtitle_it"] = "Seleziona il dataset dalla lista o copia e incolla la url del dataset.";
116 121 ln["slide2Title_it"] = "SELEZIONA I DATI";
117 122 ln["slide2Subtitle_it"] = "Seleziona i campi dalla struttura ad albero. Nella tabella saranno mostrati i valori dei campi selezionati.";
118 123 ln["slide3Title_it"] = "SELEZIONA LA VISUALIZZAZIONE";
... ... @@ -123,7 +128,12 @@ ln[&quot;forward_it&quot;] = &quot;Avanti&quot;;
123 128 //SELECT DATASET
124 129 ln["listView_it"] = "ELENCO";
125 130 ln["treeMapView_it"] = "GRAFICO AD ALBERO";
126   -ln["availableDatasets_it"] = "Dataset disponibili";
  131 +ln["provider_it"] = "Provider";
  132 +ln["showing_it"] = "Visualizzati";
  133 +ln["to_it"] = "a";
  134 +ln["of_it"] = "di";
  135 +ln["datasets_it"] = "datasets";
  136 +//ln["availableDatasets_it"] = "Dataset disponibili";
127 137 ln["suggestedDatasets_it"] = "Dataset suggeriti";
128 138 ln["selectedUrl_it"] = "Url selezionata";
129 139 ln["wrongUrl_it"] = "Url invalido o data provider non ancora supportato.";
... ... @@ -231,7 +241,12 @@ ln[&quot;forward_fr&quot;] = &quot;AVANT&quot;;
231 241 //SELECT DATASET
232 242 ln["listView_fr"] = "VUE EN LISTE";
233 243 ln["treeMapView_fr"] = "VUE EN ARBORESCENCE";
234   -ln["availableDatasets_fr"] = "Jeux de données disponibles";
  244 +ln["provider_fr"] = "Provider";
  245 +ln["showing_fr"] = "Showing";
  246 +ln["to_fr"] = "to";
  247 +ln["of_fr"] = "of";
  248 +ln["datasets_fr"] = "datasets";
  249 +//ln["availableDatasets_fr"] = "Jeux de données disponibles";
235 250 ln["suggestedDatasets_fr"] = "Jeux de données suggérés";
236 251 ln["selectedUrl_fr"] = "Sélectionner URL";
237 252 ln["wrongUrl_fr"] = "Invalid url or data provider not supported yet.";
... ... @@ -339,7 +354,12 @@ ln[&quot;forward_nl&quot;] = &quot;VOOTUIT&quot;;
339 354 //SELECT DATASET
340 355 ln["listView_nl"] = "LIJSTWEERGAVE";
341 356 ln["treeMapView_nl"] = "BOOMSTRUCTUUR WEEERGAVE";
342   -ln["availableDatasets_nl"] = "Beschikbare datasets";
  357 +ln["provider_nl"] = "Provider";
  358 +ln["showing_nl"] = "Showing";
  359 +ln["to_nl"] = "to";
  360 +ln["of_nl"] = "of";
  361 +ln["datasets_nl"] = "datasets";
  362 +//ln["availableDatasets_nl"] = "Beschikbare datasets";
343 363 ln["suggestedDatasets_nl"] = "Voeg aanbevolen datasets";
344 364 ln["selectedUrl_nl"] = "Selecteer url";
345 365 ln["wrongUrl_nl"] = "Ongeldige url of data provider nog niet ondersteund.";
... ...
locales/datasetexplorer_ln.js
... ... @@ -3,47 +3,11 @@ datasetexplorer_ln = [];
3 3 /*EN*/
4 4 datasetexplorer_ln["ode+back_en"] = "<< Click to navigate back to the top level.";
5 5  
6   -//datasetexplorer_ln["openwall+provider_1_en"] = "Example CKAN with data from out pilots (Pratos - Groiningen - Den Haag)";
7   -//datasetexplorer_ln["openwall+provider_2_en"] = "data.issy.com (from OpenDataSoft France)";
8   -//datasetexplorer_ln["openwall+provider_3_en"] = "Open data Regione Lazio (Italy)";
9   -//datasetexplorer_ln["openwall+provider_4_en"] = "data.gov.uk (UK)";
10   -//datasetexplorer_ln["openwall+provider_5_en"] = "Dataportaal van de Nederlandse overheid (Netherland)";
11   -//datasetexplorer_ln["openwall+provider_6_en"] = "French Open Data Portal (France)";
12   -//datasetexplorer_ln["openwall+provider_7_en"] = "Ireland\\'s Open Data Portal (Ireland)";
13   -//datasetexplorer_ln["openwall+provider_8_en"] = "TET v.0.1 @ Galway (Ireland)";
14   -
15 6 /*IT*/
16 7 datasetexplorer_ln["ode+back_it"] = "<< Clicca qui per tornare al livello precedente.";
17 8  
18   -//datasetexplorer_ln["openwall+provider_1_it"] = "Example CKAN with data from out pilots (Pratos - Groiningen - Den Haag)";
19   -//datasetexplorer_ln["openwall+provider_2_it"] = "data.issy.com (from OpenDataSoft France)";
20   -//datasetexplorer_ln["openwall+provider_3_it"] = "Open data Regione Lazio (Italy)";
21   -//datasetexplorer_ln["openwall+provider_4_it"] = "data.gov.uk (UK)";
22   -//datasetexplorer_ln["openwall+provider_5_it"] = "Dataportaal van de Nederlandse overheid (Netherland)";
23   -//datasetexplorer_ln["openwall+provider_6_it"] = "French Open Data Portal (France)";
24   -//datasetexplorer_ln["openwall+provider_7_it"] = "Ireland\\'s Open Data Portal (Ireland)";
25   -//datasetexplorer_ln["openwall+provider_8_it"] = "TET v.0.1 @ Galway (Ireland)";
26   -
27 9 /*FR*/
28 10 datasetexplorer_ln["ode+back_fr"] = "<< Click to navigate back to the top level.";
29 11  
30   -//datasetexplorer_ln["openwall+provider_1_fr"] = "Example CKAN with data from out pilots (Pratos - Groiningen - Den Haag)";
31   -//datasetexplorer_ln["openwall+provider_2_fr"] = "data.issy.com (from OpenDataSoft France)";
32   -//datasetexplorer_ln["openwall+provider_3_fr"] = "Open data Regione Lazio (Italy)";
33   -//datasetexplorer_ln["openwall+provider_4_fr"] = "data.gov.uk (UK)";
34   -//datasetexplorer_ln["openwall+provider_5_fr"] = "Dataportaal van de Nederlandse overheid (Netherland)";
35   -//datasetexplorer_ln["openwall+provider_6_fr"] = "French Open Data Portal (France)";
36   -//datasetexplorer_ln["openwall+provider_7_fr"] = "Ireland\\'s Open Data Portal (Ireland)";
37   -//datasetexplorer_ln["openwall+provider_8_fr"] = "TET v.0.1 @ Galway (Ireland)";
38   -
39 12 /*NL*/
40 13 datasetexplorer_ln["ode+back_nl"] = "<< Click to navigate back to the top level.";
41   -
42   -//datasetexplorer_ln["openwall+provider_1_nl"] = "Example CKAN with data from out pilots (Pratos - Groiningen - Den Haag)";
43   -//datasetexplorer_ln["openwall+provider_2_nl"] = "data.issy.com (from OpenDataSoft France)";
44   -//datasetexplorer_ln["openwall+provider_3_nl"] = "Open data Regione Lazio (Italy)";
45   -//datasetexplorer_ln["openwall+provider_4_nl"] = "data.gov.uk (UK)";
46   -//datasetexplorer_ln["openwall+provider_5_nl"] = "Dataportaal van de Nederlandse overheid (Netherland)";
47   -//datasetexplorer_ln["openwall+provider_6_nl"] = "French Open Data Portal (France)";
48   -//datasetexplorer_ln["openwall+provider_7_nl"] = "Ireland\\'s Open Data Portal (Ireland)";
49   -//datasetexplorer_ln["openwall+provider_8_nl"] = "TET v.0.1 @ Galway (Ireland)";
... ...