├── .gitignore ├── .vscode └── settings.json ├── demo ├── hljs │ ├── styles │ │ ├── pojoaque.jpg │ │ ├── school-book.png │ │ ├── brown-papersq.png │ │ ├── darkula.css │ │ ├── ascetic.css │ │ ├── mono-blue.css │ │ ├── dark.css │ │ ├── androidstudio.css │ │ ├── codepen-embed.css │ │ ├── brown-paper.css │ │ ├── vs.css │ │ ├── far.css │ │ ├── arta.css │ │ ├── ir-black.css │ │ ├── color-brewer.css │ │ ├── magula.css │ │ ├── github-gist.css │ │ ├── monokai.css │ │ ├── darcula.css │ │ ├── tomorrow.css │ │ ├── zenburn.css │ │ ├── school-book.css │ │ ├── ocean.css │ │ ├── paraiso-dark.css │ │ ├── paraiso-light.css │ │ ├── dracula.css │ │ ├── qtcreator_dark.css │ │ ├── qtcreator_light.css │ │ ├── rainbow.css │ │ ├── kimbie.dark.css │ │ ├── kimbie.light.css │ │ ├── atelier-dune-dark.css │ │ ├── monokai-sublime.css │ │ ├── atelier-dune-light.css │ │ ├── atelier-heath-dark.css │ │ ├── atelier-heath-light.css │ │ ├── atelier-forest-dark.css │ │ ├── atelier-forest-light.css │ │ ├── tomorrow-night-bright.css │ │ ├── tomorrow-night-eighties.css │ │ ├── atelier-seaside-dark.css │ │ ├── atelier-seaside-light.css │ │ ├── hopscotch.css │ │ ├── atelier-lakeside-dark.css │ │ ├── atelier-lakeside-light.css │ │ ├── arduino-light.css │ │ ├── googlecode.css │ │ ├── xt256.css │ │ ├── atelier-sulphurpool-dark.css │ │ ├── atelier-sulphurpool-light.css │ │ ├── obsidian.css │ │ ├── foundation.css │ │ ├── tomorrow-night.css │ │ ├── xcode.css │ │ ├── tomorrow-night-blue.css │ │ ├── pojoaque.css │ │ ├── solarized-dark.css │ │ ├── solarized-light.css │ │ ├── docco.css │ │ ├── idea.css │ │ ├── atelier-cave-dark.css │ │ ├── atelier-cave-light.css │ │ ├── atelier-estuary-dark.css │ │ ├── atelier-plateau-dark.css │ │ ├── atelier-savanna-dark.css │ │ ├── github.css │ │ ├── atelier-estuary-light.css │ │ ├── atelier-plateau-light.css │ │ ├── atelier-savanna-light.css │ │ ├── atom-one-dark.css │ │ ├── default.css │ │ ├── atom-one-light.css │ │ ├── sunburst.css │ │ ├── railscasts.css │ │ ├── routeros.css │ │ ├── agate.css │ │ ├── hybrid.css │ │ ├── gruvbox-dark.css │ │ ├── gruvbox-light.css │ │ ├── vs2015.css │ │ ├── grayscale.css │ │ └── purebasic.css │ ├── LICENSE │ ├── README.ru.md │ ├── README.md │ └── highlight.pack.js ├── index.html ├── demo-pip.js └── demo-show-object.js ├── index.html ├── paper-input-place-icons.js ├── LICENSE ├── package.json ├── README.md └── paper-input-place.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | .vscode 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /demo/hljs/styles/pojoaque.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlisook/paper-input-place/HEAD/demo/hljs/styles/pojoaque.jpg -------------------------------------------------------------------------------- /demo/hljs/styles/school-book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlisook/paper-input-place/HEAD/demo/hljs/styles/school-book.png -------------------------------------------------------------------------------- /demo/hljs/styles/brown-papersq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlisook/paper-input-place/HEAD/demo/hljs/styles/brown-papersq.png -------------------------------------------------------------------------------- /demo/hljs/styles/darkula.css: -------------------------------------------------------------------------------- 1 | /* 2 | Deprecated due to a typo in the name and left here for compatibility purpose only. 3 | Please use darcula.css instead. 4 | */ 5 | 6 | @import url('darcula.css'); 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |41 | The control requires a valid Google API key to provide the Places Autocomplete service. To view the demo, enter your API Key below and click Set Key. 42 |
43 |`, попытавшись
20 | автоматически определить язык. Когда автоопределение не срабатывает, можно явно
21 | указать язык в атрибуте class:
22 |
23 | ```html
24 | ...
25 | ```
26 |
27 | Список поддерживаемых классов языков доступен в [справочнике по классам][2].
28 | Класс также можно предварить префиксами `language-` или `lang-`.
29 |
30 | Чтобы отключить подсветку для какого-то блока, используйте класс `nohighlight`:
31 |
32 | ```html
33 | ...
34 | ```
35 |
36 | ## Инициализация вручную
37 |
38 | Чтобы иметь чуть больше контроля за инициализацией подсветки, вы можете
39 | использовать функции [`highlightBlock`][3] и [`configure`][4]. Таким образом
40 | можно управлять тем, *что* и *когда* подсвечивать.
41 |
42 | Вот пример инициализации, эквивалентной вызову [`initHighlightingOnLoad`][1], но
43 | с использованием jQuery:
44 |
45 | ```javascript
46 | $(document).ready(function() {
47 | $('pre code').each(function(i, block) {
48 | hljs.highlightBlock(block);
49 | });
50 | });
51 | ```
52 |
53 | Вы можете использовать любые теги разметки вместо ``. Если
54 | используете контейнер, не сохраняющий переводы строк, вам нужно сказать
55 | highlight.js использовать для них тег `
`:
56 |
57 | ```javascript
58 | hljs.configure({useBR: true});
59 |
60 | $('div.code').each(function(i, block) {
61 | hljs.highlightBlock(block);
62 | });
63 | ```
64 |
65 | Другие опции можно найти в документации функции [`configure`][4].
66 |
67 |
68 | ## Web Workers
69 |
70 | Подсветку можно запустить внутри web worker'а, чтобы окно
71 | браузера не подтормаживало при работе с большими кусками кода.
72 |
73 | В основном скрипте:
74 |
75 | ```javascript
76 | addEventListener('load', function() {
77 | var code = document.querySelector('#code');
78 | var worker = new Worker('worker.js');
79 | worker.onmessage = function(event) { code.innerHTML = event.data; }
80 | worker.postMessage(code.textContent);
81 | })
82 | ```
83 |
84 | В worker.js:
85 |
86 | ```javascript
87 | onmessage = function(event) {
88 | importScripts('/highlight.pack.js');
89 | var result = self.hljs.highlightAuto(event.data);
90 | postMessage(result.value);
91 | }
92 | ```
93 |
94 |
95 | ## Установка библиотеки
96 |
97 | Highlight.js можно использовать в браузере прямо с CDN хостинга или скачать
98 | индивидуальную сборку, а также установив модуль на сервере. На
99 | [странице загрузки][5] подробно описаны все варианты.
100 |
101 | **Не подключайте GitHub напрямую.** Библиотека не предназначена для
102 | использования в виде исходного кода, а требует отдельной сборки. Если вам не
103 | подходит ни один из готовых вариантов, читайте [документацию по сборке][6].
104 |
105 | **Файл на CDN содержит не все языки.** Иначе он будет слишком большого размера.
106 | Если нужного вам языка нет в [категории "Common"][5], можно дообавить его
107 | вручную:
108 |
109 | ```html
110 |
111 | ```
112 |
113 | **Про Almond.** Нужно задать имя модуля в оптимизаторе, например:
114 |
115 | ```
116 | r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js
117 | ```
118 |
119 |
120 | ## Лицензия
121 |
122 | Highlight.js распространяется под лицензией BSD. Подробнее читайте файл
123 | [LICENSE][7].
124 |
125 |
126 | ## Ссылки
127 |
128 | Официальный сайт билиотеки расположен по адресу .
129 |
130 | Более подробная документация по API и другим темам расположена на
131 | .
132 |
133 | Авторы и контрибьюторы перечислены в файле [AUTHORS.ru.txt][8] file.
134 |
135 | [1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload
136 | [2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html
137 | [3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block
138 | [4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options
139 | [5]: https://highlightjs.org/download/
140 | [6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html
141 | [7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE
142 | [8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.ru.txt
143 |
--------------------------------------------------------------------------------
/demo/hljs/README.md:
--------------------------------------------------------------------------------
1 | # Highlight.js
2 |
3 | [](https://travis-ci.org/isagalaev/highlight.js)
4 |
5 | Highlight.js is a syntax highlighter written in JavaScript. It works in
6 | the browser as well as on the server. It works with pretty much any
7 | markup, doesn’t depend on any framework and has automatic language
8 | detection.
9 |
10 | ## Getting Started
11 |
12 | The bare minimum for using highlight.js on a web page is linking to the
13 | library along with one of the styles and calling
14 | [`initHighlightingOnLoad`][1]:
15 |
16 | ```html
17 |
18 |
19 |
20 | ```
21 |
22 | This will find and highlight code inside of `` tags; it tries
23 | to detect the language automatically. If automatic detection doesn’t
24 | work for you, you can specify the language in the `class` attribute:
25 |
26 | ```html
27 | ...
28 | ```
29 |
30 | The list of supported language classes is available in the [class
31 | reference][2]. Classes can also be prefixed with either `language-` or
32 | `lang-`.
33 |
34 | To disable highlighting altogether use the `nohighlight` class:
35 |
36 | ```html
37 | ...
38 | ```
39 |
40 | ## Custom Initialization
41 |
42 | When you need a bit more control over the initialization of
43 | highlight.js, you can use the [`highlightBlock`][3] and [`configure`][4]
44 | functions. This allows you to control *what* to highlight and *when*.
45 |
46 | Here’s an equivalent way to calling [`initHighlightingOnLoad`][1] using
47 | jQuery:
48 |
49 | ```javascript
50 | $(document).ready(function() {
51 | $('pre code').each(function(i, block) {
52 | hljs.highlightBlock(block);
53 | });
54 | });
55 | ```
56 |
57 | You can use any tags instead of `` to mark up your code. If
58 | you don't use a container that preserve line breaks you will need to
59 | configure highlight.js to use the `
` tag:
60 |
61 | ```javascript
62 | hljs.configure({useBR: true});
63 |
64 | $('div.code').each(function(i, block) {
65 | hljs.highlightBlock(block);
66 | });
67 | ```
68 |
69 | For other options refer to the documentation for [`configure`][4].
70 |
71 |
72 | ## Web Workers
73 |
74 | You can run highlighting inside a web worker to avoid freezing the browser
75 | window while dealing with very big chunks of code.
76 |
77 | In your main script:
78 |
79 | ```javascript
80 | addEventListener('load', function() {
81 | var code = document.querySelector('#code');
82 | var worker = new Worker('worker.js');
83 | worker.onmessage = function(event) { code.innerHTML = event.data; }
84 | worker.postMessage(code.textContent);
85 | })
86 | ```
87 |
88 | In worker.js:
89 |
90 | ```javascript
91 | onmessage = function(event) {
92 | importScripts('/highlight.pack.js');
93 | var result = self.hljs.highlightAuto(event.data);
94 | postMessage(result.value);
95 | }
96 | ```
97 |
98 |
99 | ## Getting the Library
100 |
101 | You can get highlight.js as a hosted, or custom-build, browser script or
102 | as a server module. Right out of the box the browser script supports
103 | both AMD and CommonJS, so if you wish you can use RequireJS or
104 | Browserify without having to build from source. The server module also
105 | works perfectly fine with Browserify, but there is the option to use a
106 | build specific to browsers rather than something meant for a server.
107 | Head over to the [download page][5] for all the options.
108 |
109 | **Don't link to GitHub directly.** The library is not supposed to work straight
110 | from the source, it requires building. If none of the pre-packaged options
111 | work for you refer to the [building documentation][6].
112 |
113 | **The CDN-hosted package doesn't have all the languages.** Otherwise it'd be
114 | too big. If you don't see the language you need in the ["Common" section][5],
115 | it can be added manually:
116 |
117 | ```html
118 |
119 | ```
120 |
121 | **On Almond.** You need to use the optimizer to give the module a name. For
122 | example:
123 |
124 | ```
125 | r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js
126 | ```
127 |
128 |
129 | ## License
130 |
131 | Highlight.js is released under the BSD License. See [LICENSE][7] file
132 | for details.
133 |
134 | ## Links
135 |
136 | The official site for the library is at .
137 |
138 | Further in-depth documentation for the API and other topics is at
139 | .
140 |
141 | Authors and contributors are listed in the [AUTHORS.en.txt][8] file.
142 |
143 | [1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload
144 | [2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html
145 | [3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block
146 | [4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options
147 | [5]: https://highlightjs.org/download/
148 | [6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html
149 | [7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE
150 | [8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.en.txt
151 |
--------------------------------------------------------------------------------
/demo/demo-show-object.js:
--------------------------------------------------------------------------------
1 | import {
2 | html,
3 | PolymerElement
4 | } from '@polymer/polymer/polymer-element.js';
5 |
6 | /**
7 | * `demo-show-object`
8 | *
9 | */
10 | class DemoShowObject extends PolymerElement {
11 | static get template() {
12 | return html `
13 |
18 |
112 |
113 |
114 | `;
115 | }
116 | static get properties() {
117 | return {
118 | showObject: {
119 | type: Object,
120 | notify: true,
121 | observer: "_objChanged"
122 | },
123 | displayObj: {
124 | type: String,
125 | notify: true,
126 | value: ""
127 | }
128 | };
129 | }
130 |
131 | _objChanged(newValue, oldValue) {
132 | var src = newValue && newValue !== {} ? hljs.highlight('json', this._formatJson(JSON.stringify(newValue))).value : "";
133 | this.$.codearea.innerHTML = src.replace(/span class="hljs/g, 'span class="demo-show-object hljs');
134 | }
135 |
136 | _realTypeOf(indent, v) {
137 | if (typeof (v) == "object") {
138 | if (v === null) return "null";
139 | if (v.constructor == (new Array).constructor) return "array";
140 | if (v.constructor == (new Date).constructor) return "date";
141 | if (v.constructor == (new RegExp).constructor) return "regex";
142 | return "object";
143 | }
144 | return typeof (v);
145 | }
146 |
147 | _repeat(s, count) {
148 | return new Array(count + 1).join(s);
149 | }
150 |
151 | _formatJson(json) {
152 | var i = 0,
153 | il = 0,
154 | tab = " ",
155 | newJson = "",
156 | indentLevel = 0,
157 | inString = false,
158 | currentChar = null;
159 |
160 | for (i = 0, il = json.length; i < il; i += 1) {
161 | currentChar = json.charAt(i);
162 |
163 | switch (currentChar) {
164 | case '{':
165 | case '[':
166 | if (!inString) {
167 | newJson += currentChar + "\n" + this._repeat(tab, indentLevel + 1);
168 | indentLevel += 1;
169 | } else {
170 | newJson += currentChar;
171 | }
172 | break;
173 | case '}':
174 | case ']':
175 | if (!inString) {
176 | indentLevel -= 1;
177 | newJson += "\n" + this._repeat(tab, indentLevel) + currentChar;
178 | } else {
179 | newJson += currentChar;
180 | }
181 | break;
182 | case ',':
183 | if (!inString) {
184 | newJson += ",\n" + this._repeat(tab, indentLevel);
185 | } else {
186 | newJson += currentChar;
187 | }
188 | break;
189 | case ':':
190 | if (!inString) {
191 | newJson += ": ";
192 | } else {
193 | newJson += currentChar;
194 | }
195 | break;
196 | case ' ':
197 | case "\n":
198 | case "\t":
199 | if (inString) {
200 | newJson += currentChar;
201 | }
202 | break;
203 | case '"':
204 | if (i > 0 && json.charAt(i - 1) !== '\\') {
205 | inString = !inString;
206 | }
207 | newJson += currentChar;
208 | break;
209 | default:
210 | newJson += currentChar;
211 | break;
212 | }
213 | }
214 |
215 | return newJson;
216 | }
217 | }
218 |
219 | window.customElements.define('demo-show-object', DemoShowObject);
--------------------------------------------------------------------------------
/demo/hljs/highlight.pack.js:
--------------------------------------------------------------------------------
1 | /*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */
2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/
/g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C=" ",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/,r:0,c:[{cN:"attr",b:e,r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+e.IR+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:e.IR},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:["self",e.CLCM,e.CBCM]}]}]}],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/%/,r:0},{bK:"constructor",e:/\{/,eE:!0,c:["self",{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}]},{b:/module\./,k:{built_in:"module"},r:0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/,e:/(\/\w+|\w+\/)>/,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # paper-input-place
2 |
3 | [](https://vaadin.com/directory/component/mlisookpaper-input-place)
4 | [](https://vaadin.com/directory/component/mlisookpaper-input-place)
5 |
6 | Google Places Autocomplete styled as a paper-input, providing a convenient material design input for places.
7 |
8 | The element is available as a Polymer 3.0 class based module or as a Polymer 2 hybrid supporting Polymer 2.x and 1.x projects.
9 |
10 | Try it on the [Live Demos](https://mlisook.github.io/paper-input-place/) page.
11 |
12 | ## Contents
13 | * [Installation](#installation)
14 | * [Basic Use](#basic-use)
15 | * [Properties](#additional-properties)
16 | * [Methods](#methods)
17 | * [Styling](#styling)
18 | * [Support / Issues](#support)
19 | * [Contributing](#contributing)
20 | * [License](#license)
21 |
22 |
23 | ## Installation
24 | ### For Polymer 3.x Projects
25 | Use `npm` or `yarn` to install:
26 | ```
27 | npm i --save paper-input-place
28 | // or using yarn
29 | yarn add paper-input-place
30 | ```
31 |
32 | ### For Polymer 1.x or 2.x projects
33 | Use bower to install. ***Important*** - the polymer 1.x/2.x versions are 1.9.xxx
34 |
35 | ```
36 | bower install --save paper-input-place#^1.9.12
37 | ```
38 |
39 | ## Basic use
40 |
41 | ```html
42 |
44 | ```
45 | The `value` property is an object:
46 |
47 | ```js
48 | {
49 | "search": "Guggenheim Museum, 5th Avenue, New York, NY, United States",
50 | "place_id": "ChIJmZ5emqJYwokRuDz79o0coAQ",
51 | "latLng": {
52 | "lat": 40.7829796,
53 | "lng": -73.95897059999999
54 | }
55 | }
56 | ```
57 | Basic use with validation:
58 |
59 | ```html
60 |
61 | ```
62 | Basic use with a country code specified (use ISO Alpha-2 code):
63 | ```html
64 |
66 |
67 | ```
68 |
69 |
70 | ## Additional Properties
71 | ### apiLoaded
72 | A _read only_ boolean property (notifies) that indicates if the google api is
73 | loaded and ready to provide place suggestions and geocoding services.
74 |
75 | The control also fires an event, `api-loaded`, when the google api is ready
76 | and attached to the input control.
77 |
78 | ### errorMessage
79 | `errorMessage` / `error-message` allows customization of the error message display.
80 | ```html
81 |
84 | Save
85 | ```
86 |
87 | ### hideError
88 | If specified the element doesn't display an error message and doesn't turn red.
89 | Set `hide-error` in the markup to suppress validation.
90 |
91 | ### hideIcon
92 |
93 | If true (`hide-icon` attribute present) the element will not display the "place" icon
94 | in the prefix position of the `paper-input`.
95 |
96 | ### invalid
97 | `invalid` is a _read only_ property which indicates if the control has a valid place.
98 | ```html
99 |
102 | Save
103 | ```
104 | ### label
105 | The floating label for the paper-input.
106 | ### latLng
107 | `latLng` is a _read only_ property which returns an object after the user selects a place from the prompt.
108 | ```html
109 |
112 | ```
113 | ```js
114 | {
115 | "lat": 40.7829796,
116 | "lng": -73.95897059999999
117 | }
118 | ```
119 | ### place
120 | `place` is a _read only_ property which returns an object with detailed information after the user selects a place:
121 | ```html
122 |
125 | ```
126 | ```js
127 | {
128 | "place_id": "ChIJmZ5emqJYwokRuDz79o0coAQ",
129 | "formatted_address": "1071 5th Ave, New York, NY 10128, USA",
130 | "search": "Guggenheim Museum, 5th Avenue, New York, NY, United States",
131 | "latLng": {
132 | "lat": 40.7829796,
133 | "lng": -73.95897059999999
134 | },
135 | "basic": {
136 | "name": "Solomon R. Guggenheim Museum",
137 | "address": "1071 5th Avenue",
138 | "city": "New York",
139 | "state": "New York",
140 | "stateCode": "NY",
141 | "postalCode": "10128",
142 | "country": "United States",
143 | "countryCode": "US",
144 | "streetNumber": "1071",
145 | "route": "5th Avenue",
146 | "phone": "(212) 423-3500"
147 | },
148 | "placeDetails": {
149 | "address_components": [
150 | {
151 | "long_name": "1071",
152 | "short_name": "1071",
153 | "types": [
154 | "street_number"
155 | ]
156 | },
157 | {
158 | "long_name": "5th Avenue",
159 | "short_name": "5th Ave",
160 | "types": [
161 | "route"
162 | ]
163 | },
164 | {
165 | "long_name": "Upper East Side",
166 | "short_name": "UES",
167 | "types": [
168 | "neighborhood",
169 | "political"
170 | ]
171 | },
172 | {
173 | "long_name": "Manhattan",
174 | "short_name": "Manhattan",
175 | "types": [
176 | "sublocality_level_1",
177 | "sublocality",
178 | "political"
179 | ]
180 | },
181 | {
182 | "long_name": "New York",
183 | "short_name": "New York",
184 | "types": [
185 | "locality",
186 | "political"
187 | ]
188 | },
189 | {
190 | "long_name": "New York County",
191 | "short_name": "New York County",
192 | "types": [
193 | "administrative_area_level_2",
194 | "political"
195 | ]
196 | },
197 | {
198 | "long_name": "New York",
199 | "short_name": "NY",
200 | "types": [
201 | "administrative_area_level_1",
202 | "political"
203 | ]
204 | },
205 | {
206 | "long_name": "United States",
207 | "short_name": "US",
208 | "types": [
209 | "country",
210 | "political"
211 | ]
212 | },
213 | {
214 | "long_name": "10128",
215 | "short_name": "10128",
216 | "types": [
217 | "postal_code"
218 | ]
219 | }
220 | ],
221 | "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/museum-71.png",
222 | "international_phone_number": "+1 212-423-3500",
223 | "permanently_closed": false,
224 | "types": [
225 | "museum",
226 | "point_of_interest",
227 | "establishment"
228 | ],
229 | "website": "http://www.guggenheim.org/new-york",
230 | "url": "https://maps.google.com/?cid=333297768485043384",
231 | "utc_offset": -240
232 | }
233 | }
234 | ```
235 | #### A Note About Handling Addresses
236 | If you need the address and are working with a global scope you should be aware that not all countries will have a street name and number system you can rely on. For example in Japan (except in Kyoto and some Hokkaidō cities) most streets do not have names. In Ghana most rural places don't have numbers. You may want to consider testing `place` result properties and using `formatted_address` where needed.
237 |
238 | ### placeholder
239 | Sets the `placeholder` of the underlying `input` element.
240 |
241 | ### required
242 | Indicates to the control that selection of a place is mandatory and that an empty input is not valid.
243 |
244 | ### Search Bias Properties - searchCountryCode, searchBounds, searchType
245 | These properties can be used to limit the autocomplete search results by country, a bounding geographic rectangle and/or by type of result.
246 |
247 | #### searchCountryCode
248 | You can provide an [ISO Alpha-2 Country](http://www.nationsonline.org/oneworld/country_code_list.htm) code to limit results to the given country.
249 |
250 | #### searchBounds
251 | `searchBounds` takes an object of the form:
252 | ```js
253 | {
254 | east: number, // East longitude in degrees.
255 | west: number, // West longitude in degrees.
256 | north: number, // North latitude in degrees.
257 | south: number, // South latitude in degrees.
258 | }
259 | ```
260 | For example, this area
261 | ```
262 | { north: 39.144342, east: 1.672126, south: 38.810722, west: 1.164008}
263 | ```
264 | includes the island of Ibiza, Spain.
265 |
266 | #### searchType
267 | Limits results to a given result type. Valid types are:
268 | * address
269 | * geocode
270 | * establishment
271 | * (regions)
272 | * (cities)
273 |
274 | #### language
275 | Sets the input and autocomplete list preferred language. The default is the user's preferred language setting in the browser (see [Google Maps Api Localizing](https://developers.google.com/maps/documentation/javascript/localization)).
276 |
277 | Specify the language as a [supported language code](https://developers.google.com/maps/faq#languagesupport).
278 |
279 | It should also be noted that Google does not have a translation for every place name in the world in every supported language.
280 |
281 | If you use this attribute you must set it when the element is initialized or at least before the `apiKey` is set.
282 |
283 | If you use this attribute you must also set the `language` attribute to the same value on any other element that may load the Google Maps API (e.g. `google-map`) or you will generate API loaded twice errors.
284 |
285 | #### minimizeApi
286 | If true, the element does not load the drawing, geometry or visualization libraries, slightly reducing payload size.
287 |
288 | Do not set this attribute if your page includes other elements that use the Google Maps Javascript API (e.g. `google-map`) as those elements will attempt to load all libraries, generating API loaded twice errors.
289 |
290 | The default value, `false`, is compatible with the api set used by the Google Elements collection.
291 |
292 | If you use this attribute you must set it when the element is initialized or at least before the `apiKey` is set.
293 |
294 | ## Methods
295 |
296 | ### focus()
297 | Sets the focus to the input field.
298 |
299 | ### Convenience Functions
300 | While not needed for the main purpose, the user entering a place, you may have existing data you
301 | need to geocode for use in the element. We make these functions available here since the Google
302 | API is already loaded.
303 |
304 | #### geocode(address)
305 | The `geocode` function takes an address as its parameter and returns a _promise_ for a result which is a _place object_ as described in the place property above. Note that this does not have any effect on the control's properties (but, of course one could turn around and set the value property with information from the place detail returned).
306 | ```js
307 | this.$$('paper-input-place').geocode(address).then(
308 | function(result) {
309 | // do something with result (a place object)
310 | }.bind(this),
311 | function(status) {
312 | // do something with status - the reason the geocode did not work
313 | }.bind(this)
314 | );
315 | ```
316 | #### reverseGeocode(latLng)
317 | The `reverseGeocode` function takes a latLng object as it's parameter and returns a _promise_ for a result which is a _place object_ as described in the place property above. Note that this does not have any effect on the control's properties (but, of course one could turn around and set the value property with information from the place detail returned).
318 | ```js
319 | this.$$('paper-input-place').reverseGeocode(latlng).then(
320 | function(result) {
321 | // do something with result (a place object)
322 | }.bind(this),
323 | function(status) {
324 | // do something with status - the reason the geocode did not work
325 | }.bind(this)
326 | );
327 | ```
328 | #### putPlace(place)
329 | The `putPlace` function takes a place object and updates the control to reflect that place.
330 | ```js
331 | this.$$('paper-input-place').geocode('Qualcomm Stadium').then(
332 | function(result) {
333 | // set the control to this place
334 | this.$$('paper-input-place').putPlace(result);
335 | }.bind(this),
336 | function(status) {
337 | // do something with status - the reason the geocode did not work
338 | }.bind(this)
339 | );
340 | ```
341 |
342 | ## Styling
343 | ### Custom Properties
344 |
345 | The following custom properties and mixins are available for styling:
346 |
347 | Custom property | Description | Default
348 | ----------------|-------------|----------
349 | `--paper-input-place-icon-mixin` | Mixin applied to all icons | `{}`
350 | `--paper-input-place-prefix-icon-mixin` | Mixin applied to the prefix icon | `{}`
351 | `--paper-input-place-postfix-icon-mixin` | Mixin applied to the postfix icon | `{}`
352 |
353 | ### Paper Input Mixins and Variables
354 | You can style the `paper-input-place` element as you would any `paper-input` element - use the mixins and variables
355 | of `paper-input-container` documented on the [paper-input-container api page](https://www.webcomponents.org/element/PolymerElements/paper-input/elements/paper-input-container). Apply the style to the `paper-input-place` element.
356 |
357 | Example: make the `paper-input-place` more green:
358 |
359 | ```html
360 |
361 |
394 |
395 |
396 | ```
397 | ### Styling the Autocomplete Items List
398 | The list is provided by Google Places Autocomplete and can be styled by CSS classes described [here](https://google-developers.appspot.com/maps/documentation/javascript/places-autocomplete#style_autocomplete). The trick is the styles must be in the document level (not within a custom element).
399 |
400 | Example: Make the list garish:
401 |
402 | index.html
403 | ```
404 |
417 | ```
418 |
419 | ## Support
420 | Support is available for both the Polymer 2.x/1.x version and the Polymer 3.x version of `paper-input-place'. You may submit issues in the [github repository](https://github.com/mlisook/paper-input-place). I strive to address issues within one day.
421 |
422 | ## Contributing
423 | Contributions via pull request are certainly welcome and appreciated.
424 |
425 | ## License
426 | MIT
427 |
--------------------------------------------------------------------------------
/paper-input-place.js:
--------------------------------------------------------------------------------
1 | /**
2 | `paper-input-place`
3 |
4 | Google Places Autocomplete attached to paper-input.
5 |
6 | This release is a Polymer 2.0 hybrid element so it will work in 1.x or 2.0 Polymer applications.
7 |
8 | Basic use:
9 |
10 | ```html
11 |
13 | ```
14 | The `value` property is an object:
15 |
16 | ```js
17 | {
18 | "search": "Guggenheim Museum, 5th Avenue, New York, NY, United States",
19 | "place_id": "ChIJmZ5emqJYwokRuDz79o0coAQ",
20 | "latLng": {
21 | "lat": 40.7829796,
22 | "lng": -73.95897059999999
23 | }
24 | }
25 | ```
26 | Basic use with validation:
27 |
28 | ```html
29 |
30 | ```
31 |
32 | ### Styling
33 |
34 | The following custom properties and mixins are available for styling:
35 |
36 | Custom property | Description | Default
37 | ----------------|-------------|----------
38 | `--paper-input-place-icon-mixin` | Mixin applied to all icons | `{}`
39 | `--paper-input-place-prefix-icon-mixin` | Mixin applied to the prefix icon | `{}`
40 | `--paper-input-place-postfix-icon-mixin` | Mixin applied to the postfix icon | `{}`
41 |
42 | See README.MD for more use examples, styling, api and a link to a live demo page.
43 |
44 |
45 | @demo demo/index.html
46 |
47 | @version 1.9.3
48 | */
49 | /*
50 | FIXME(polymer-modulizer): the above comments were extracted
51 | from HTML and may be out of place here. Review them and
52 | then delete this comment!
53 | */
54 | import {
55 | html,
56 | PolymerElement
57 | } from '@polymer/polymer/polymer-element.js';
58 | import '@polymer/paper-input/paper-input.js';
59 | import '@polymer/iron-jsonp-library/iron-jsonp-library.js';
60 | import '@polymer/iron-icon/iron-icon.js';
61 | import './paper-input-place-icons.js';
62 | import { GestureEventListeners } from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
63 |
64 | class PaperInputPlace extends GestureEventListeners(PolymerElement) {
65 |
66 | static get template() {
67 | return html `
68 |
159 |
160 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 | [[errorMessage]]
188 |
189 |
190 | `;
191 | }
192 |
193 | static get properties() {
194 | return {
195 | /**
196 | * Required: A Maps API key. To obtain an API key, see developers.google.com/maps/documentation/javascript/tutorial#api_key.
197 | */
198 | apiKey: {
199 | type: String,
200 | notify: true
201 | },
202 | /**
203 | * Indicates the Google API is loaded and that Autocomplete suggestions and geocoding functions are available
204 | */
205 | apiLoaded: {
206 | type: Boolean,
207 | notify: true,
208 | value: false,
209 | readOnly: true
210 | },
211 | /**
212 | * Whether to hide the error message
213 | * If true, the control does not validate that the value is complete (lat/lng, search term, place_id)
214 | * and has been chosen from the places drop down.
215 | */
216 | hideError: {
217 | type: Boolean,
218 | value: false
219 | },
220 | /**
221 | * Whether to hide the place icon
222 | * If true, the control does not show the place icon in the input box.
223 | */
224 | hideIcon: {
225 | type: Boolean,
226 | value: false
227 | },
228 | /**
229 | * true if the control is disabled
230 | */
231 | disabled: {
232 | type: Boolean,
233 | notify: true,
234 | value: false
235 | },
236 | /** @private */
237 | _geocoder: {
238 | type: Object
239 | },
240 |
241 | /*
242 | * region bias options
243 | */
244 |
245 | /**
246 | * bias search results to a country code (ISO 3166-1 Alpha-2 country code, case insensitive).
247 | */
248 | searchCountryCode: {
249 | type: String,
250 | value: ""
251 | },
252 | /**
253 | * bias search results to a bounding rectangle.
254 | * object properties (all are required):
255 | * {
256 | * east: number, // East longitude in degrees.
257 | * west: number, // West longitude in degrees.
258 | * north: number, // North latitude in degrees.
259 | * south: number, // South latitude in degrees.
260 | * }
261 | *
262 | */
263 | searchBounds: {
264 | type: Object
265 | },
266 |
267 | /**
268 | * bias search results by type
269 | * permitted values:
270 | * address
271 | * geocode
272 | * establishment
273 | * (regions)
274 | * (cities)
275 | */
276 | searchType: {
277 | type: String,
278 | value: ""
279 | },
280 | /**
281 | * error message to display if place is invalid (and hideError is false).
282 | * Default value is "Invalid - please select a place".
283 | */
284 | errorMessage: {
285 | type: String,
286 | value: "Invalid - please select a place",
287 | notify: true
288 | },
289 | /**
290 | * True if the entered text is not valid - i.e. not a selected place and not previously geocoded
291 | */
292 | invalid: {
293 | type: Boolean,
294 | notify: true,
295 | readOnly: true,
296 | value: false
297 | },
298 | /**
299 | * Internal representation of invalid, True if the entered text is not valid - i.e. not a selected place and not previously geocoded
300 | */
301 | _invalid: {
302 | type: Boolean,
303 | value: false
304 | },
305 | /**
306 | * Floating label for paper-input
307 | * @type {String}
308 | */
309 | label: {
310 | type: String,
311 | notify: true,
312 | value: ""
313 | },
314 | /**
315 | * Placeholder for paper-input
316 | * @type {String}
317 | */
318 | placeholder: {
319 | type: String,
320 | notify: true,
321 | value: ""
322 | },
323 | /**
324 | * an object - { lat: number, lng: number } - representing the geolocation of the
325 | * entered / selected place
326 | */
327 | latLng: {
328 | type: Object,
329 | notify: true,
330 | readOnly: true,
331 | value: function () {
332 | return {
333 | lat: 0,
334 | lng: 0
335 | }
336 | }
337 | },
338 | /**
339 | * An object containing the place selected or geocoded:
340 | * ```
341 | * place_id
342 | * formatted_address
343 | * latLng { lat: lng: }
344 | * search
345 | * basic:
346 | * name
347 | * address
348 | * city
349 | * state
350 | * stateCode
351 | * postalCode
352 | * country
353 | * countryCode
354 | * phone
355 | * placeDetails: additional properties from the google place result
356 | *```
357 | */
358 | place: {
359 | type: Object,
360 | notify: true,
361 | readOnly: true,
362 | value: function () {
363 | return {};
364 | }
365 | },
366 | /** @private */
367 | _places: {
368 | type: Object
369 | },
370 | /**
371 | * true if the entry is a required field
372 | */
373 | required: {
374 | type: Boolean,
375 | notify: true,
376 | value: false
377 | },
378 | /**
379 | * Sets the desired language for the input and the autocomplete list.
380 | * Normally, Google Places Autocomplete defaults to the browser default language.
381 | * This value allows the language to be set to a desired language regardless of the browser default.
382 | *
383 | * For a list of language codes supported see https://developers.google.com/maps/faq#languagesupport
384 | *
385 | * *** the value should not be modified after the element is loaded ***
386 | */
387 | language: {
388 | type: String,
389 | value: ""
390 | },
391 | /**
392 | * If true, the element does not load the drawing, geometry or visualization libraries, slightly
393 | * reducing overall payload size.
394 | *
395 | * Important: Do not use this option if the page contains other elements that make usef
396 | * of the Google Maps Javascript API (e.g. google-map). This can cause the maps API to be loaded
397 | * more than once generating errors.
398 | *
399 | * Do not change this value after the element is loaded
400 | *
401 | */
402 | minimizeApi: {
403 | type: Boolean,
404 | value: false
405 | },
406 | /**
407 | * An object representing the initial or returned value of the control.
408 | * ```
409 | * Properties:
410 | * search: string - the search string
411 | * place_id: string - the google maps place_id
412 | * latLng: object {lat: number, lng: number} - latitude/Longitude
413 | *```
414 | */
415 | value: {
416 | type: Object,
417 | notify: true,
418 | observer: '_valueChanged'
419 | },
420 | /** @private */
421 | _value: {
422 | type: String,
423 | notify: true,
424 | value: "",
425 | observer: '_svalChanged'
426 | },
427 | /**
428 | * @private
429 | * The url for the google maps api
430 | */
431 | _gmapApiUrl: {
432 | type: String,
433 | notify: true,
434 | computed: '_computeUrl(apiKey,language,minimizeApi)'
435 | }
436 | };
437 | }
438 |
439 | static get observers() {
440 | return [
441 | '_searchBiasChanged(searchCountryCode,searchBounds,searchBoundsStrict,searchType)'
442 | ];
443 | }
444 |
445 | ready() {
446 | super.ready();
447 | var apiElement = this.querySelector('iron-jsonp-library');
448 | if (apiElement && apiElement.libraryLoaded) {
449 | this._mapsApiLoaded();
450 | }
451 | }
452 |
453 | _computeUrl(akey, lang, minApi) {
454 | return akey ? ("https://maps.googleapis.com/maps/api/js?callback=%%callback%%&v=3.exp&libraries=" +
455 | (minApi ? "places" : "drawing,geometry,places,visualization") +
456 | "&key=" + akey + (lang ? "&language=" + lang : "")) : "";
457 | }
458 |
459 | _mapsApiLoaded() {
460 | if (!this._geocoder && !this._places && this.$.locationsearch && this.$.nativeInput) {
461 | this._geocoder = new google.maps.Geocoder();
462 | this._places = new google.maps.places.Autocomplete(this.$.nativeInput, {});
463 | google.maps.event.addListener(this._places, 'place_changed', this._onChangePlace.bind(this));
464 | this._setApiLoaded(true);
465 | this._searchBiasChanged();
466 | this.dispatchEvent(new CustomEvent('api-loaded', {
467 | detail: {
468 | text: 'Google api is ready'
469 | }
470 | }));
471 | }
472 | }
473 |
474 | /**
475 | * observer for changes to search bias
476 | */
477 | _searchBiasChanged(searchCountryCode, searchBounds, searchBoundsStrict, searchType) {
478 | if (this.apiLoaded) {
479 |
480 | if (this.searchBounds &&
481 | this.searchBounds.hasOwnProperty('east') &&
482 | this.searchBounds.hasOwnProperty('west') &&
483 | this.searchBounds.hasOwnProperty('north') &&
484 | this.searchBounds.hasOwnProperty('south')
485 | ) {
486 | this._places.setBounds(this.searchBounds);
487 | } else {
488 | this._places.setBounds();
489 | }
490 | if (this.searchCountryCode && this.searchCountryCode.length == 2) {
491 | this._places.setComponentRestrictions({
492 | country: this.searchCountryCode.toString()
493 | });
494 | } else {
495 | this._places.setComponentRestrictions();
496 | }
497 | if (this.searchType && ['address', 'geocode', 'establishment', '(regions)', '(cities)'].includes(this.searchType)) {
498 | this._places.setTypes([this.searchType.toString()]);
499 | } else {
500 | this._places.setTypes([]);
501 | }
502 | }
503 | }
504 |
505 | _valueChanged(newValue, oldValue) {
506 | // update the search term and the invalid flag if the value is being set for the first time,
507 | // or if the value has changed and is not the same as the search term
508 | if (!oldValue || (newValue.search !== oldValue.search || newValue.search !== this._value)) {
509 | this._value = newValue && newValue.search ? newValue.search : "";
510 | this._invalid = !newValue || !(newValue.place_id && newValue.latLng && newValue.latLng.lat && newValue.latLng
511 | .lng);
512 | if (!this.hideError) {
513 | this._setInvalid(this.required ? this._invalid : this._invalid && (newValue && newValue.search));
514 | }
515 | }
516 | }
517 |
518 | _svalChanged(newValue, oldValue) {
519 | // reset the invalid property if the user has typed in the input field
520 |
521 | // if the newValue matches the selected place, which could happen if
522 | // the user types after selecting a place, then deletes the typing
523 | if (newValue && this.place && this.place.search && newValue == this.place.search) {
524 | this.value = {
525 | place_id: this.place.place_id,
526 | search: newValue,
527 | latLng: {
528 | lat: this.place.latLng.lat,
529 | lng: this.place.latLng.lng
530 | }
531 | };
532 | this._invalid = false;
533 | this._setInvalid(false);
534 | return;
535 | }
536 | // if blank and not a required input
537 | if (!newValue && !this.required) {
538 | this.value = {
539 | place_id: "",
540 | search: "",
541 | latLng: {
542 | lat: 0,
543 | lng: 0
544 | }
545 | };
546 | this._setPlace({});
547 | this._invalid = true;
548 | if (!this.hideError) {
549 | this._setInvalid(false);
550 | }
551 | return;
552 | }
553 | // if the new _value matches the value.search, which could happen if
554 | // the value is changed externally (possibly through data binding) which
555 | // causes _value to be changed triggering this function _svalChanged()
556 | if (newValue && this.value && this.value.search && newValue == this.value.search) {
557 | // nothing has really changed, just return
558 | return;
559 | }
560 | // if the existing value is blank, and the new value is not
561 | if ((!this.value || !this.value.search) && newValue) {
562 | this.value = {
563 | place_id: "",
564 | search: newValue,
565 | latLng: {
566 | lat: 0,
567 | lng: 0
568 | }
569 | };
570 | this._setPlace({});
571 | this._invalid = true;
572 | if (!this.hideError) {
573 | this._setInvalid(true);
574 | }
575 | return;
576 | }
577 | // otherwise, the value is invalid
578 | this.value = {
579 | place_id: "",
580 | search: newValue,
581 | latLng: {
582 | lat: 0,
583 | lng: 0
584 | }
585 | };
586 | this._setPlace({});
587 | this._invalid = true;
588 | if (!this.hideError) {
589 | this._setInvalid(true);
590 | }
591 | return;
592 |
593 | }
594 |
595 | _clearLocation(e) {
596 | this._value = "";
597 | }
598 |
599 | /**
600 | * Geocodes an address
601 | * @param {string} address address to be geocoded
602 | * @param {object} options Optional - Geocoder Request options
603 | * @return {Promise} A promise for a place object or a status on failure
604 | */
605 | geocode(address, options) {
606 | return new Promise((resolve, reject) => {
607 | if (!this._geocoder) {
608 | reject('Geocoder not ready.');
609 | } else {
610 | var opts = options ? options : {};
611 | opts.address = address ? address : "";
612 | this._geocoder.geocode(opts, (results, status) => {
613 | if (status == google.maps.GeocoderStatus.OK && results && results[0]) {
614 | var p = this._extractPlaceInfo(results[0], opts.address);
615 | resolve(p);
616 | } else {
617 | reject(status);
618 | }
619 | });
620 | }
621 | });
622 | }
623 |
624 | /**
625 | * Reverse Geocodes a latLng
626 | * @param {object} latlng latitude/Longitude {lat: , lng: } to be reverse geocoded
627 | * @param {object} options Optional - Geocoder Request options
628 | * @return {Promise} A promise for a place object or a status on failure
629 | */
630 | reverseGeocode(latlng, options) {
631 | return new Promise((resolve, reject) => {
632 | if (!this._geocoder) {
633 | reject('Geocoder not ready.');
634 | } else {
635 | var opts = options ? options : {};
636 | if (latlng) {
637 | opts.location = latlng;
638 | }
639 | this._geocoder.geocode(opts, (results, status) => {
640 | if (status == google.maps.GeocoderStatus.OK && results && results[0]) {
641 | var p = this._extractPlaceInfo(results[0], "");
642 | resolve(p);
643 | } else {
644 | reject(status);
645 | }
646 | });
647 | }
648 | });
649 | }
650 |
651 | _onChangePlace(e) {
652 | var pl = this._places.getPlace();
653 | if (pl.geometry) {
654 | var p = this._extractPlaceInfo(pl, this.$.nativeInput.value);
655 | this._setPlace(p);
656 | this._invalid = false;
657 | this._setInvalid(false);
658 | this._setLatLng({
659 | lat: p.latLng.lat,
660 | lng: p.latLng.lng
661 | });
662 | this._value = this.$.nativeInput.value;
663 | this.value = {
664 | search: this.$.nativeInput.value,
665 | place_id: p.place_id,
666 | latLng: {
667 | lat: p.latLng.lat,
668 | lng: p.latLng.lng
669 | }
670 | };
671 | }
672 | }
673 |
674 | /**
675 | * extracts and simplifies a google place result
676 | * @param PlaceResult pl google place result
677 | * @return place
678 | */
679 | _extractPlaceInfo(pl, searchTerm) {
680 |
681 | var p = {
682 | place_id: pl.place_id,
683 | formatted_address: pl.formatted_address,
684 | search: searchTerm ? searchTerm : pl.formatted_address,
685 | latLng: {
686 | lat: pl.geometry.location.lat(),
687 | lng: pl.geometry.location.lng()
688 | },
689 | basic: {
690 | name: pl.name || "",
691 | address: "",
692 | city: "",
693 | state: "",
694 | stateCode: "",
695 | postalCode: "",
696 | country: "",
697 | countryCode: "",
698 | phone: pl.formatted_phone_number || ""
699 | },
700 | placeDetails: {
701 | address_components: [],
702 | icon: pl.icon,
703 | international_phone_number: pl.international_phone_number || "",
704 | permanently_closed: pl.permanently_closed || false,
705 | types: pl.types ? JSON.parse(JSON.stringify(pl.types)) : [],
706 | website: pl.website || "",
707 | url: pl.url || "",
708 | utc_offset: pl.utc_offset
709 | }
710 | };
711 | // extract address components
712 | var address = {
713 | street_number: "",
714 | route: ""
715 | };
716 | for (var i = 0; i < pl.address_components.length; i++) {
717 | p.placeDetails.address_components.push(JSON.parse(JSON.stringify(pl.address_components[i])));
718 | switch (pl.address_components[i].types[0]) {
719 | case "locality":
720 | p.basic["city"] = pl.address_components[i].long_name;
721 | break;
722 | case "administrative_area_level_1":
723 | p.basic["stateCode"] = pl.address_components[i].short_name;
724 | p.basic["state"] = pl.address_components[i].long_name;
725 | break;
726 | case "country":
727 | p.basic["country"] = pl.address_components[i].long_name;
728 | p.basic["countryCode"] = pl.address_components[i].short_name;
729 | break;
730 | case "postal_code":
731 | p.basic["postalCode"] = pl.address_components[i].long_name;
732 | break;
733 | case "street_number":
734 | address.street_number = pl.address_components[i].short_name;
735 | p.basic.address = address.street_number + " " + address.route;
736 | p.basic.streetNumber = address.street_number;
737 | break;
738 | case "route":
739 | address.route = pl.address_components[i].long_name;
740 | p.basic.address = address.street_number + " " + address.route;
741 | p.basic.route = address.route;
742 | break;
743 | default:
744 | address[pl.address_components[i].types[0]] = pl.address_components[i].long_name;
745 | }
746 | }
747 |
748 | return p;
749 |
750 | }
751 |
752 | /**
753 | * Updates the current place, value and latLng with the place provided
754 | * @param IpipPlace newPlace the new place
755 | */
756 | putPlace(newPlace) {
757 | if (newPlace && newPlace.place_id && newPlace.latLng) {
758 | this._setPlace(JSON.parse(JSON.stringify(newPlace)));
759 | this._setLatLng({
760 | lat: newPlace.latLng.lat,
761 | lng: newPlace.latLng.lng
762 | });
763 | this.value = {
764 | place_id: newPlace.place_id,
765 | search: newPlace.search,
766 | latLng: {
767 | lat: newPlace.latLng.lat,
768 | lng: newPlace.latLng.lng
769 | }
770 | };
771 | this._value = newPlace.search;
772 | }
773 | }
774 |
775 | /**
776 | * sets the focus to the input field
777 | */
778 | focus() {
779 | this.$.nativeInput.focus();
780 | }
781 |
782 | _onChange(event) {
783 | // In the Shadow DOM, the `change` event is not leaked into the
784 | // ancestor tree, so we must do this manually.
785 | // See https://w3c.github.io/webcomponents/spec/shadow/#events-that-are-not-leaked-into-ancestor-trees.
786 | if (this.shadowRoot) {
787 | this.dispatchEvent(new CustomEvent('input-change', {
788 | bubbles: true,
789 | cancelable: event.cancelable,
790 | detail: {
791 | text: this.$.nativeInput.value
792 | }
793 | }));
794 | }
795 | };
796 | /**
797 | Fired when the google maps api has loaded.
798 |
799 | The api is now available to provide
800 | geocoding and place suggestions.
801 |
802 | @event api-loaded
803 | */
804 | }
805 |
806 | window.customElements.define('paper-input-place', PaperInputPlace);
--------------------------------------------------------------------------------