├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── codeql-analysis.yml
├── .gitignore
├── .nvmrc
├── .ruby-version
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DATA_REFRESH.md
├── LICENSE
├── PIPELINE_CHANGELOG.md
├── README.md
├── __mocks__
├── algoliasearch
│ └── src
│ │ └── browser
│ │ └── builds
│ │ └── algoliasearchLite.js
└── autocomplete.js.js
├── autocompleteDataset.js
├── babel-css.js
├── demo.gif
├── docs
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── config.rb
└── source
│ ├── api-clients.html
│ ├── bootstrap.html
│ ├── contact.html
│ ├── documentation.html
│ ├── examples.html
│ ├── images
│ ├── algoliaPlaces_demo_checkout.gif
│ ├── algoliaPlaces_demo_map.gif
│ ├── background_footer.svg
│ ├── clippy.svg
│ ├── favicon.png
│ ├── hp-demo-autocompletejs.gif
│ ├── inner-background_footer.svg
│ ├── map-demo.gif
│ ├── svg
│ │ ├── advanced-icon.svg
│ │ ├── algolia-community-badge.svg
│ │ ├── algolia-community.svg
│ │ ├── algolia-mark-white.svg
│ │ ├── background_footer.svg
│ │ ├── city-icon.svg
│ │ ├── community-badge.svg
│ │ ├── country-icon.svg
│ │ ├── form-icon.svg
│ │ ├── icon-arrow-pipe.svg
│ │ ├── icon-github.svg
│ │ ├── icon-heart-dark.svg
│ │ ├── icon-heart-light.svg
│ │ ├── icon-heart.svg
│ │ ├── icon-hover-cursor-visible.svg
│ │ ├── icon-hover-cursor.svg
│ │ ├── icon-search-white.svg
│ │ ├── iconsicon-heart.svg
│ │ ├── illus-feat-autocomplete.svg
│ │ ├── illus-feat-relevance.svg
│ │ ├── illus-feat-rocket.svg
│ │ ├── illus-feat-typo-tolerance.svg
│ │ ├── logo-algolia-dark.svg
│ │ ├── logo-algolia-light.svg
│ │ ├── logo-community.svg
│ │ ├── map-icon.svg
│ │ ├── places-illustration.svg
│ │ ├── search-everywhere-illu.svg
│ │ ├── search-icon-2.svg
│ │ └── search-icon.svg
│ ├── visual-preview-places.png
│ └── visual-preview-places_mobile.png
│ ├── index.html
│ ├── javascripts
│ ├── activateClipboard.js
│ ├── anchorableElements.js
│ ├── autoPullCredentials.js
│ ├── common.js
│ ├── docsearch.js
│ ├── documentation-layout.js
│ ├── index.js
│ ├── responsiveNavigation.js
│ ├── sidebar.js
│ └── support.js
│ ├── layouts
│ ├── bootstrap.erb
│ ├── documentation.erb
│ ├── landing.erb
│ └── layout.erb
│ ├── partials
│ ├── examples
│ │ ├── _autocomplete_dataset.html.erb
│ │ ├── _city_search.html.erb
│ │ ├── _complete_form.html.erb
│ │ ├── _country_search.html.erb
│ │ ├── _demo.html.erb
│ │ ├── _disable_styling.html.erb
│ │ ├── _dynamic_control.html.erb
│ │ ├── _dynamic_search.html.erb
│ │ ├── _instantsearch.html.erb
│ │ ├── _map.html.erb
│ │ ├── _map_paris.html.erb
│ │ ├── _postcode_search.html.erb
│ │ ├── _ranking_info.html.erb
│ │ ├── _reverse_geocoding.html.erb
│ │ ├── _simple_input.html.erb
│ │ ├── _single_country_search.html.erb
│ │ ├── _templates.html.erb
│ │ ├── _visual-helper.html.haml
│ │ └── reverse-city-search
│ │ │ ├── _code.html.erb
│ │ │ ├── _code_places.html.erb
│ │ │ └── _demo_places.html.erb
│ ├── footer.html.haml
│ ├── hero.html.haml
│ ├── marketing.html.erb
│ ├── navigation.html.haml
│ └── status
│ │ ├── CHANGELOG.md.erb
│ │ ├── DATA_REFRESH.md.erb
│ │ └── PIPELINE_CHANGELOG.md.erb
│ ├── pricing.html
│ ├── rest.html
│ ├── status.html
│ ├── stylesheets
│ ├── components
│ │ ├── _buttons.scss
│ │ ├── _clipboard.scss
│ │ ├── _code-highlight.scss
│ │ ├── _containers.scss
│ │ ├── _documentation.scss
│ │ ├── _examples-intro.scss
│ │ ├── _examples.scss
│ │ ├── _fonts.scss
│ │ ├── _footer.scss
│ │ ├── _icons.scss
│ │ ├── _inputs.scss
│ │ ├── _media.scss
│ │ ├── _navigation.scss
│ │ ├── _sidebar.scss
│ │ ├── _visual-helper.scss
│ │ └── docsearch
│ │ │ ├── _docsearch.scss
│ │ │ ├── _dropdown.scss
│ │ │ └── _searchbox.scss
│ ├── landing.css.scss
│ ├── site.css.scss
│ └── vendors
│ │ ├── _animations.scss
│ │ ├── _base.scss
│ │ ├── _functions.scss
│ │ ├── _helpers.scss
│ │ ├── _mixins.scss
│ │ ├── _normalize.scss
│ │ └── _variables.scss
│ └── support.html
├── header.png
├── index.js
├── instantsearchWidget.js
├── package.json
├── renovate.json
├── scripts
├── build-website.sh
├── build.sh
├── bump-package-version.js
├── clear-cdn-cache.sh
├── deploy-website.sh
├── dev.sh
├── finish-release.sh
├── release.sh
└── test-ci.sh
├── src
├── configure
│ └── index.js
├── createAutocompleteDataset.js
├── createAutocompleteDataset.test.js
├── createAutocompleteSource.js
├── createAutocompleteSource.test.js
├── createReverseGeocodingSource.js
├── createReverseGeocodingSource.test.js
├── defaultTemplates.js
├── errors.js
├── findCountryCode.js
├── findCountryCode.test.js
├── findType.js
├── findType.test.js
├── formatDropdownValue.js
├── formatDropdownValue.test.js
├── formatHit.js
├── formatHit.test.js
├── formatInputValue.js
├── formatInputValue.test.js
├── icons
│ ├── address.svg
│ ├── algolia.svg
│ ├── bus.svg
│ ├── city.svg
│ ├── clear.svg
│ ├── country.svg
│ ├── osm.svg
│ ├── plane.svg
│ ├── townhall.svg
│ └── train.svg
├── instantsearch
│ ├── __snapshots__
│ │ └── widget.test.js.snap
│ ├── widget.js
│ └── widget.test.js
├── navigatorLanguage.js
├── places.css
├── places.js
├── places.test.js
└── version.js
├── test
├── cdn-autocomplete-min
│ └── index.html
├── cdn-autocomplete
│ └── index.html
├── cdn-main-min
│ └── index.html
├── cdn-main
│ └── index.html
├── cdn-widget-min
│ └── index.html
├── cdn-widget
│ └── index.html
├── e2e.test.js
├── fileMock.js
├── npm-autocomplete
│ ├── import.js
│ └── index.html
├── npm-lib
│ ├── import.js
│ └── index.html
└── npm-widget
│ ├── import.js
│ └── index.html
├── typings.d.ts
├── webpack.config.docs.js
├── webpack.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "env": {
4 | "npm": {
5 | "plugins": [
6 | [
7 | "babel-plugin-inline-import",
8 | {
9 | "extensions": [
10 | ".svg",
11 | ".css"
12 | ]
13 | }
14 | ]
15 | ]
16 | }
17 | },
18 | "plugins": [
19 | "@babel/plugin-syntax-dynamic-import",
20 | "@babel/plugin-syntax-import-meta",
21 | "@babel/plugin-proposal-class-properties",
22 | "@babel/plugin-proposal-json-strings",
23 | [
24 | "@babel/plugin-proposal-decorators",
25 | {
26 | "legacy": true
27 | }
28 | ],
29 | "@babel/plugin-proposal-function-sent",
30 | "@babel/plugin-proposal-export-namespace-from",
31 | "@babel/plugin-proposal-numeric-separator",
32 | "@babel/plugin-proposal-throw-expressions"
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | docs/build/
3 | docs/vendor/
4 | test/npm-lib/
5 | test/npm-autocomplete/
6 | test/npm-widget/
7 | .eslintrc.js
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['algolia', 'algolia/jest'],
3 | settings: {
4 | jest: {
5 | version: 26
6 | }
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
7 |
8 | **Do you want to request a *feature* or report a *bug*?**
9 |
10 | **What is the current behavior?**
11 |
12 | **If the current behavior is a bug, please provide all the steps to reproduce and a minimal
13 | [JSFiddle](https://jsfiddle.net/) example or a repository on GitHub that we can `npm install`
14 | and `npm start`.**
15 |
16 | **What is the expected behavior?**
17 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | **Summary**
7 |
8 |
13 |
14 | **Result**
15 |
16 |
21 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "Code scanning - action"
2 |
3 | on:
4 | push:
5 | pull_request:
6 | schedule:
7 | - cron: '0 1 * * 3'
8 |
9 | jobs:
10 | CodeQL-Build:
11 |
12 | # CodeQL runs on ubuntu-latest and windows-latest
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout repository
17 | uses: actions/checkout@v2
18 | with:
19 | # We must fetch at least the immediate parents so that if this is
20 | # a pull request then we can checkout the head.
21 | fetch-depth: 2
22 |
23 | # If this run was triggered by a pull request event, then checkout
24 | # the head of the pull request instead of the merge commit.
25 | - run: git checkout HEAD^2
26 | if: ${{ github.event_name == 'pull_request' }}
27 |
28 | # Initializes the CodeQL tools for scanning.
29 | - name: Initialize CodeQL
30 | uses: github/codeql-action/init@v1
31 | # Override language selection by uncommenting this and choosing your languages
32 | # with:
33 | # languages: go, javascript, csharp, python, cpp, java
34 |
35 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
36 | # If this step fails, then you should remove it and run the build manually (see below)
37 | - name: Autobuild
38 | uses: github/codeql-action/autobuild@v1
39 |
40 | # ℹ️ Command-line programs to run using the OS shell.
41 | # 📚 https://git.io/JvXDl
42 |
43 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
44 | # and modify them (or add more) to build your code if your project
45 | # uses a compiled language
46 |
47 | #- run: |
48 | # make bootstrap
49 | # make release
50 |
51 | - name: Perform CodeQL Analysis
52 | uses: github/codeql-action/analyze@v1
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | npm-debug.log
4 | docs/.sass-cache/
5 | docs/.webpack/
6 | .DS_Store
7 | .coverage/
8 | .vscode/
9 | test/npm-lib/places.js
10 | test/npm-widget/places.js
11 | test/npm-autocomplete/places.js
12 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 10.24.1
2 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.7.3
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: stable
3 | before_install:
4 | - git config --global user.email "algobot@users.noreply.github.com"
5 | - git config --global user.name "algobot"
6 | - rvm install 2.7.0
7 | - rvm use 2.7.0
8 | - "(cd docs && bundle install)"
9 | script:
10 | - npm run test:ci
11 | branches:
12 | only:
13 | - master
14 | notifications:
15 | slack:
16 | rooms:
17 | secure: ksGBanrJ0rmBUpMJT8TWCvjJ6F8Rlin8a9DQNPNOa1s+bCGswp87V1a1bSybz/166JflMqSutf6ES2/qBcp8uhXS3hfKdpj3wJwUPtiWQ+Q1GRAsL7ZiPlz/OgOkACihyrONipjzTANSKhAy7NiJSGOMbSn09yUaaun+wp5iy1KJ2qcC/GRbytkyyDkzzVYDKonNV96KINeTnv3WnM+cgt/1YEzvQ6lPLExS0S90m4m/JUn+pO4CNfw0uHc1NEd3whPQi7WDr1a43qNGea7/WFg9f8yDn1PFnkLujYku77rfFrn164s1UaerUuHusEX7Qff/0BZ3Fy29LPfmQIqZzrb5RGRnsYxv+nyZwMuWw1xP/Ag2fs+GuPw8JG2JJNE61aAKL+HgbC/g4XaSckvwMzA3T/5cvJVh7aIBQmptDuB8AWygp6srBKgKtTmZxqFnpZaHm1Pz5A2C/mERQNf6YQorv/QBtT7seek9CtS5DBqlaBxogHTRN1qJ+dNZ/t1S8Tk5QT4w8Wt8L3xS4fBEakH0eaFXtKAPDO8optNMQhHesvBGUfOJ+bjaT/2626BFK9FXJg3VTlgPMZlto8QSaax6zJocmC3PGxvHOevB4cjR3j44msvmRRtgkRXIuxTK1mXamCbH2UCXLN5aVgXWSQjZY9W5uG8sqwFjnao4VZg=
18 | cache:
19 | bundler: true
20 | yarn: true
21 | env:
22 | global:
23 | secure: o9jGb6EMsAv955rn+Mu1GPLX+3aA6j5POM5rjq3X3T+zRSV5eBEnP8TiRSmUqIz+aLXmvQMKsCJsFc4oI9udjotjwBUXKvl4Zq7Ph45iVunQLi06Bp+4DaB7pSrAn/qeY5R2P38jIonN5nitjDQSf/htgxsvurC8aX0QR1Bp4TdQNVQUuedaGjHfGitBDwgGIjU7LatHwPKguJA/NnKKg9qFZNJDrZ3Wb9O9//RJyWxcnYF4JEVKztgk7I+vGXkN7a7mpCsesUxS6qjs2MRTY7qjFRXHV3HrltLEwYs6z+0ijmTJl3e6W8KO1kKj3qfQCTpkZV1R6YWDtefKpQfzW0SBFgTX8rJ/pnt+o0DxLRFzHpnUCZBcAqvtjZOzwP2qJyqI3S9LGLZ6QZ2OpqTGamBm4DLrAUmeB84jImbgj2buiRDMStY0ut2z9RURdr2zWSUouVojjJmlhbBTWvwGk6x6ZbQy1P+SZGSzjXbKn25X9c14B6OJUjv5NFdDZf4zxWdYaMhX8tum+SMvnwZjoGC57R+WyrN0M27Xu0OAO30PyEFTBpe0y3JN7bdeL1AnZxqlSJ+gX2BfRZaoLnQzdTcUW+VUIRBwRsLJCFqGo6GAATe2kDbDDZshSKkP8sJnbmbty7BY9j5PTe1tXqDwCT0l7WZtq+K6WRxFVay44xU=
24 |
--------------------------------------------------------------------------------
/DATA_REFRESH.md:
--------------------------------------------------------------------------------
1 | ### Dataset freshness
2 | - OSM Data from 2019-10-16
3 | - Geonames Data from 2019-09-30
4 | - BAN Data from 2018-09-17
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Algolia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PIPELINE_CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ### 2019-01-07
3 |
4 |
5 | #### Features
6 |
7 | * **admin-levels**
8 | * define administrative, county and city admin levels by country (#104)
9 |
10 |
11 |
12 | ### 2018-11-15
13 |
14 |
15 | #### Bug Fixes
16 |
17 | * **tests**
18 | * Update Andorra end-to-end test (#94)
19 |
20 |
21 |
22 | ### 2018-11-02
23 |
24 |
25 | #### Bug Fixes
26 |
27 | * **pt-housenumber**
28 | * put house number after streetname in Portugal (#89)
29 |
30 |
31 |
32 | ### 2018-10-31
33 |
34 |
35 | #### Bug Fixes
36 |
37 | * **district**
38 | * rank district lower than the city (#88)
39 |
40 |
41 |
42 | ### 2018-08-31
43 |
44 |
45 | #### Bug Fixes
46 |
47 | * **historic-geonames**
48 | * update alternateNames processing to handle newlines and new table format (#86)
49 |
50 |
51 |
52 | ### 2018-08-29
53 |
54 |
55 | #### Bug Fixes
56 |
57 | * **merge-geonames**
58 | * use postcodes from OSM if no postcodes in Geonames (#83)
59 |
60 |
61 |
62 | ### 2018-07-30
63 |
64 |
65 | #### Bug Fixes
66 |
67 | * **historic-geonames**
68 | * update alternateNames processing to handle newlines and new table format (#85)
69 |
70 |
71 |
72 | ### 2018-06-05
73 |
74 |
75 | #### Bug Fixes
76 |
77 | * **null-country**
78 | * use iso instead of country in PlanetOutput (#78)
79 |
80 |
81 |
82 | ### 2018-04-09
83 |
84 |
85 | #### Bug Fixes
86 |
87 | * **deploy**
88 | * remove useless dir creation which fails the rollback, data being in a wrong subdir (#74)
89 |
90 |
91 |
92 | ### 2018-01-30
93 |
94 |
95 | #### Features
96 |
97 | * **docs**
98 | * add troubleshooting for snap.rb (#60)
99 |
100 |
101 |
102 | ### 2018-01-26
103 |
104 |
105 | #### Features
106 |
107 | * **linked-places**
108 | * expose linked_place_id and linked_address in object (#44)
109 |
110 |
111 | #### Bug Fixes
112 |
113 | * **country-codes**
114 | * fix wrong country attributions (#41)
115 |
116 |
117 |
118 | ### 2018-01-02
119 |
120 |
121 | #### Features
122 |
123 | * **docs**
124 | * add a knowledge base to the repository
125 |
126 |
127 | #### Bug Fixes
128 |
129 | * **config**
130 | * add a config.example.json to use as a basis for config.json (#42)
131 |
132 |
133 |
--------------------------------------------------------------------------------
/__mocks__/algoliasearch/src/browser/builds/algoliasearchLite.js:
--------------------------------------------------------------------------------
1 | const defaultSearchStub = jest.fn(() => Promise.resolve());
2 | let searchStub = defaultSearchStub;
3 | const addAlgoliaAgent = jest.fn();
4 | const search = jest.fn((...args) => searchStub(...args));
5 | const reverse = jest.fn((...args) => searchStub(...args));
6 |
7 | const algoliasearch = {
8 | initPlaces: jest.fn(() => ({
9 | as: {
10 | addAlgoliaAgent,
11 | },
12 | search,
13 | reverse,
14 | })),
15 | };
16 |
17 | algoliasearch.__searchSpy = search;
18 | algoliasearch.__reverseSpy = reverse;
19 | algoliasearch.__addAlgoliaAgentSpy = addAlgoliaAgent;
20 | algoliasearch.__setSearchStub = (fn) => {
21 | searchStub = fn;
22 | };
23 | algoliasearch.__clearSearchStub = () => {
24 | searchStub = defaultSearchStub;
25 | };
26 |
27 | export default algoliasearch;
28 |
--------------------------------------------------------------------------------
/__mocks__/autocomplete.js.js:
--------------------------------------------------------------------------------
1 | const autocomplete = jest.fn(() => {
2 | document.querySelector('input').classList.add('ap-input');
3 | let query = 'query';
4 |
5 | const instance = {
6 | on: jest.fn(),
7 | focus: jest.fn(),
8 | val: jest.fn(() => query),
9 | autocomplete: {
10 | setVal: jest.fn(),
11 | getVal: jest.fn(),
12 | open: jest.fn(),
13 | close: jest.fn(),
14 | destroy: jest.fn(),
15 | },
16 | };
17 | autocomplete.__instance = instance;
18 | autocomplete.__setQuery = (q) => {
19 | query = q;
20 | };
21 | return instance;
22 | });
23 |
24 | export default autocomplete;
25 |
--------------------------------------------------------------------------------
/autocompleteDataset.js:
--------------------------------------------------------------------------------
1 | // we need to export using commonjs for ease of usage in all
2 | // JavaScript environments
3 |
4 | /* eslint-disable import/no-commonjs */
5 |
6 | require('./src/navigatorLanguage');
7 | const createAutocompleteDataset = require('./src/createAutocompleteDataset')
8 | .default;
9 | const css = require('./babel-css').default;
10 | const insertCss = require('insert-css');
11 | insertCss(css, { prepend: true });
12 |
13 | // must use module.exports to be commonJS compatible
14 | module.exports = createAutocompleteDataset;
15 | /* eslint-enable import/no-commonjs */
16 |
--------------------------------------------------------------------------------
/babel-css.js:
--------------------------------------------------------------------------------
1 | // this is proxy file so that babel inlines src/places.css into the css variable
2 | // since it is not a commonjs file
3 | import css from './src/places.css';
4 |
5 | export default css;
6 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/demo.gif
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile ~/.gitignore_global
6 |
7 | # Ignore bundler config
8 | /.bundle
9 |
10 | # Ignore the build directory
11 | /build
12 |
13 | # Ignore cache
14 | /.sass-cache
15 | /.cache
16 |
17 | # Ignore .DS_store file
18 | .DS_Store
19 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | # If you do not have OpenSSL installed, change
2 | # the following line to use 'http://'
3 | source 'https://rubygems.org'
4 |
5 | gem 'kramdown'
6 | gem 'kramdown-parser-gfm'
7 |
8 | # Middleman Gems
9 | gem 'middleman', '~> 4.4.0'
10 | gem 'middleman-livereload'
11 | gem 'middleman-minify-html'
12 | gem 'middleman-syntax'
13 | gem 'middleman-deploy', '~> 2.0.0-alpha'
14 | gem 'middleman-protect-emails'
15 |
--------------------------------------------------------------------------------
/docs/source/api-clients.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
12 |
--------------------------------------------------------------------------------
/docs/source/bootstrap.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
12 |
--------------------------------------------------------------------------------
/docs/source/contact.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
--------------------------------------------------------------------------------
/docs/source/documentation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
12 |
--------------------------------------------------------------------------------
/docs/source/examples.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 | `
--------------------------------------------------------------------------------
/docs/source/images/algoliaPlaces_demo_checkout.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/algoliaPlaces_demo_checkout.gif
--------------------------------------------------------------------------------
/docs/source/images/algoliaPlaces_demo_map.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/algoliaPlaces_demo_map.gif
--------------------------------------------------------------------------------
/docs/source/images/clippy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/docs/source/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/favicon.png
--------------------------------------------------------------------------------
/docs/source/images/hp-demo-autocompletejs.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/hp-demo-autocompletejs.gif
--------------------------------------------------------------------------------
/docs/source/images/inner-background_footer.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Rectangle 89
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/source/images/map-demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/map-demo.gif
--------------------------------------------------------------------------------
/docs/source/images/svg/advanced-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | advanced-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/source/images/svg/algolia-mark-white.svg:
--------------------------------------------------------------------------------
1 | algolia-new-logo copy
--------------------------------------------------------------------------------
/docs/source/images/svg/city-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | city-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/community-badge.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/source/images/svg/country-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | country-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/form-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | form-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-arrow-pipe.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Shape
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Shape
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-heart-dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Shape
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-heart-light.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Shape
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-heart.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | icon-heart
5 | Created with sketchtool.
6 |
7 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-hover-cursor-visible.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Shape
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-hover-cursor.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Shape
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/icon-search-white.svg:
--------------------------------------------------------------------------------
1 | Icons/Search
--------------------------------------------------------------------------------
/docs/source/images/svg/iconsicon-heart.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 21FAE128-B409-439B-9A26-1A68EA5F2290
5 | Created with sketchtool.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/source/images/svg/illus-feat-autocomplete.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | feature-icons/illus-feat-autocomplete
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/source/images/svg/illus-feat-typo-tolerance.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | feature-icons/illus-feat-typo-tolerance
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/source/images/svg/logo-community.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | logo/algolia-community/mark-sm
5 | Created with Sketch.
6 |
7 |
8 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/source/images/svg/map-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | map-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/places-illustration.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Geosearch
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/source/images/svg/search-icon-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | search-icon
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/svg/search-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | search-icon copy
5 | Created with sketchtool.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/source/images/visual-preview-places.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/visual-preview-places.png
--------------------------------------------------------------------------------
/docs/source/images/visual-preview-places_mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/docs/source/images/visual-preview-places_mobile.png
--------------------------------------------------------------------------------
/docs/source/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
--------------------------------------------------------------------------------
/docs/source/javascripts/activateClipboard.js:
--------------------------------------------------------------------------------
1 | /* global clippyPath */
2 |
3 | import ClipboardJS from 'clipboard';
4 |
5 | export default function activateClipboard(codeSamples) {
6 | Array.from(codeSamples).forEach((codeSample) => {
7 | const copyToClipboard = document.createElement('button');
8 | copyToClipboard.innerHTML = ` `;
9 | copyToClipboard.classList.add('clipboard');
10 | codeSample.appendChild(copyToClipboard);
11 | const clipboard = new ClipboardJS(copyToClipboard, {
12 | text: () => codeSample.textContent,
13 | });
14 |
15 | copyToClipboard.addEventListener('mouseleave', () => {
16 | copyToClipboard.removeAttribute('aria-label');
17 | copyToClipboard.classList.remove('hint--top');
18 | });
19 | clipboard.on('success', () => {
20 | copyToClipboard.classList.add('hint--top');
21 | copyToClipboard.setAttribute('aria-label', 'Copied!');
22 | });
23 | // safari: https://clipboardjs.com/#browser-support
24 | clipboard.on('error', () =>
25 | copyToClipboard.setAttribute('aria-label', 'Hit ⌘+C to copy')
26 | );
27 | });
28 | }
29 |
--------------------------------------------------------------------------------
/docs/source/javascripts/anchorableElements.js:
--------------------------------------------------------------------------------
1 | export default function anchorableElements(elements) {
2 | Array.from(elements).forEach((element) => {
3 | // duplicate id in name to benefit from css :target
4 | element.setAttribute('name', element.getAttribute('id'));
5 | const anchor = document.createElement('a');
6 | anchor.setAttribute('href', `#${element.id}`);
7 | anchor.classList.add('anchor');
8 | anchor.textContent = '#';
9 | element.appendChild(anchor);
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/docs/source/javascripts/autoPullCredentials.js:
--------------------------------------------------------------------------------
1 | function saveCredentialsForSession({ appId, apiKey }) {
2 | sessionStorage.setItem('placesAppId', appId);
3 | sessionStorage.setItem('placesApiKey', apiKey);
4 | }
5 |
6 | function getCredentialsFromSession() {
7 | const appId = sessionStorage.getItem('placesAppId');
8 | const apiKey = sessionStorage.getItem('placesApiKey');
9 |
10 | if (appId && apiKey) {
11 | return { appId, apiKey };
12 | }
13 |
14 | return null;
15 | }
16 |
17 | function getCredentialsFromAlgolia() {
18 | return fetch('https://www.algolia.com/static/current_user', {
19 | credentials: 'include',
20 | headers: {},
21 | referrer: 'https://www.algolia.com/',
22 | referrerPolicy: 'no-referrer-when-downgrade',
23 | body: null,
24 | method: 'GET',
25 | mode: 'cors',
26 | })
27 | .then((x) => x.json())
28 | .then((credentials) => {
29 | const { application_id: appId, search_api_key: apiKey } = credentials;
30 | if (appId && appId.startsWith('pl') && apiKey) {
31 | saveCredentialsForSession({ appId, apiKey });
32 | return { appId, apiKey };
33 | }
34 |
35 | return null;
36 | })
37 | .catch(() => null);
38 | }
39 |
40 | function getCredentials() {
41 | return new Promise((resolve, reject) => {
42 | const sessionCredentials = getCredentialsFromSession();
43 | if (!sessionCredentials) {
44 | getCredentialsFromAlgolia()
45 | .then((credentials) => {
46 | resolve(credentials || {});
47 | })
48 | .catch(reject);
49 | } else {
50 | resolve(sessionCredentials || {});
51 | }
52 | });
53 | }
54 |
55 | function updatePlaceholders({ appId, apiKey }) {
56 | document.querySelectorAll('.rouge-code > pre > span').forEach((elt) => {
57 | if (elt.textContent.match(/.*YOUR_PLACES_APP_ID.*/)) {
58 | if (elt.textContent.startsWith(`'`)) {
59 | // eslint-disable-next-line no-param-reassign
60 | elt.innerHTML = `'${appId}'`;
61 | } else {
62 | // eslint-disable-next-line no-param-reassign
63 | elt.innerHTML = `"${appId}"`;
64 | }
65 | }
66 |
67 | if (elt.textContent.match(/.*YOUR_PLACES_API_KEY.*/)) {
68 | if (elt.textContent.startsWith(`'`)) {
69 | // eslint-disable-next-line no-param-reassign
70 | elt.innerHTML = `'${apiKey}'`;
71 | } else {
72 | // eslint-disable-next-line no-param-reassign
73 | elt.innerHTML = `"${apiKey}"`;
74 | }
75 | }
76 | });
77 | }
78 |
79 | function noop() {}
80 |
81 | export default function autoPullCredentials() {
82 | return getCredentials()
83 | .then(({ appId, apiKey }) => {
84 | if (appId && apiKey) {
85 | updatePlaceholders({ appId, apiKey });
86 | }
87 | })
88 | .catch(noop);
89 | }
90 |
--------------------------------------------------------------------------------
/docs/source/javascripts/common.js:
--------------------------------------------------------------------------------
1 | import responsiveNavigation from './responsiveNavigation';
2 | import autoPullCredentials from './autoPullCredentials';
3 | import './docsearch';
4 | responsiveNavigation();
5 | autoPullCredentials();
6 |
--------------------------------------------------------------------------------
/docs/source/javascripts/docsearch.js:
--------------------------------------------------------------------------------
1 | import docsearch from 'docsearch.js';
2 |
3 | const search = docsearch({
4 | apiKey: '5718722ffb11e109821befd53a1d9fde',
5 | indexName: 'places',
6 | inputSelector: '#docsearch',
7 | });
8 |
9 | const form = document.querySelector('#docsearch-form');
10 | const docsearchInput = document.querySelector('#docsearch');
11 | const reset = form.querySelector('[type="reset"]');
12 | const searchbox = form.querySelector('.searchbox__input');
13 |
14 | reset.addEventListener('click', () => {
15 | searchbox.focus();
16 | reset.classList.add('hide');
17 | search.autocomplete.autocomplete.setVal('');
18 | });
19 |
20 | docsearchInput.addEventListener('keyup', () => {
21 | if (searchbox.value.length === 0) {
22 | reset.classList.add('hide');
23 | } else {
24 | reset.classList.remove('hide');
25 | }
26 | });
27 |
28 | docsearchInput.addEventListener('change', () =>
29 | docsearchInput.classList.add('filled')
30 | );
31 |
32 | docsearchInput.addEventListener('blur', () => {
33 | if (docsearchInput.value.length === 0) {
34 | docsearchInput.classList.remove('filled');
35 | }
36 | });
37 |
38 | search.autocomplete.on('autocomplete:selected', () =>
39 | reset.classList.add('hide')
40 | );
41 |
--------------------------------------------------------------------------------
/docs/source/javascripts/documentation-layout.js:
--------------------------------------------------------------------------------
1 | import sidebar from './sidebar';
2 | import activateClipboard from './activateClipboard';
3 | import anchorableElements from './anchorableElements';
4 |
5 | sidebar({
6 | headersContainer: document.querySelector('.documentation-container'),
7 | sidebarContainer: document.querySelector('#sidebar'),
8 | headerStartLevel: 2,
9 | });
10 | anchorableElements(
11 | document
12 | .querySelector('.documentation-container')
13 | .querySelectorAll('h2, h3, .api-entry')
14 | );
15 | activateClipboard(document.querySelectorAll('.rouge-code'));
16 |
--------------------------------------------------------------------------------
/docs/source/javascripts/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 | /* global places */
3 |
4 | const $input = document.querySelector('#landing-demo');
5 | const placesAutocomplete = places({
6 | appId: 'plFMJJT5O9PC',
7 | apiKey: '8b126ce956636c64b6e74c8b3f3d0e5e',
8 | container: $input,
9 | });
10 | $input.style.opacity = 1; // we initially hide the input to avoid size flickering
11 |
12 | if (process.env.NODE_ENV === 'development') {
13 | const events = ['change', 'suggestions', 'cursorchanged'];
14 | events.forEach((eventName) =>
15 | placesAutocomplete.on(eventName, (eventData) => {
16 | console.log(`Algolia Places: received event **${eventName}**`);
17 | if (typeof console.table === 'function') {
18 | Object.keys(eventData).forEach((dataKeyName) => {
19 | console.log(`data: ${dataKeyName}`);
20 | const data = eventData[dataKeyName];
21 | if (Array.isArray(data)) {
22 | console.table(data);
23 | } else {
24 | console.log(data);
25 | }
26 | });
27 | } else {
28 | console.log('event data:', eventData);
29 | }
30 | })
31 | );
32 | }
33 |
34 | const processingTime = (time) => {
35 | switch (true) {
36 | case time < 26:
37 | return 'data-highlight-fast';
38 | case time < 46:
39 | return 'data-highlight-medium';
40 | case time < 66:
41 | return 'data-highlight-slow';
42 | default:
43 | return 'data-highlight-fast';
44 | }
45 | };
46 |
47 | const $response = document.querySelector('#json-response');
48 | const $responseText = document.querySelector('#json-response-text');
49 | const $responseTiming = document.querySelector('#json-response-timing');
50 | placesAutocomplete.on('change', (e) => {
51 | let postcodes = (e.suggestion.postcodes || []).slice(0, 3);
52 | if (postcodes.length !== (e.suggestion.postcodes || []).length) {
53 | postcodes = [...postcodes, '...'];
54 | } else if (postcodes.length === 0) {
55 | postcodes = undefined;
56 | }
57 |
58 | const content = {
59 | ...e,
60 | // hide advanced API event data in demo
61 | suggestion: {
62 | ...e.suggestion,
63 | hit: undefined,
64 | hitIndex: undefined,
65 | query: undefined,
66 | rawAnswer: undefined,
67 | postcodes,
68 | },
69 | rawAnswer: undefined,
70 | suggestionIndex: undefined,
71 | };
72 | const output = JSON.stringify(content, null, 2);
73 |
74 | const regex = {
75 | key: /"(.*)"/g,
76 | value: /"(.*)":/g,
77 | float: /([-]?\d+\.\d+)/g,
78 | highlight: /((.*)<\/em>)/g,
79 | default: /[:]/g,
80 | };
81 |
82 | const codes = output
83 | .replace(regex.value, `"$1" :`)
84 | .replace(regex.key, `"$1" `)
85 | .replace(regex.float, `$1 `)
86 | .replace(
87 | regex.highlight,
88 | `<em>$1</em> `
89 | )
90 | .replace(regex.default, `: `);
91 |
92 | $responseText.innerHTML = codes;
93 | $responseTiming.innerHTML = `Computed in ${e.rawAnswer.processingTimeMS}ms `;
96 | $response.classList.add('display');
97 | });
98 | placesAutocomplete.on('clear', () => {
99 | $responseText.textContent = '';
100 | $response.classList.remove('display');
101 | });
102 |
--------------------------------------------------------------------------------
/docs/source/javascripts/responsiveNavigation.js:
--------------------------------------------------------------------------------
1 | /* global currentPath */
2 | // currentPath is computed by Middleman, inlined in layout.erb and contains
3 | // the source file name of the current page (index.html, documentation.html)
4 |
5 | export default function responsiveNavigation() {
6 | const navigation = document.querySelector('.ac-nav');
7 | const links = navigation.querySelectorAll('a');
8 | const navigationAsSelect = document.createElement('select');
9 |
10 | if (
11 | navigator.userAgent.match(/iPhone/i) ||
12 | navigator.userAgent.match(/iPod/i)
13 | ) {
14 | navigationAsSelect.classList.add('display-on-small', 'device');
15 | } else {
16 | navigationAsSelect.classList.add('display-on-small');
17 | }
18 |
19 | Array.from(links).forEach((link) => {
20 | const option = document.createElement('option');
21 | option.text = link.title;
22 | option.value = link.href;
23 | if (link.dataset.path === currentPath) {
24 | option.selected = true;
25 | }
26 | navigationAsSelect.appendChild(option);
27 | });
28 |
29 | navigation.appendChild(navigationAsSelect);
30 | navigationAsSelect.addEventListener('change', (e) => {
31 | window.location = e.target.value;
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/docs/source/javascripts/support.js:
--------------------------------------------------------------------------------
1 | const defaultIp = 'Find it on https://api.ipify.org';
2 | const defaultCoords = 'Find it on https://jsfiddle.net/qmjet97b/';
3 | const link = document.querySelector('#support-google-form');
4 | const getFormURL = (ip, coords) =>
5 | `https://docs.google.com/forms/d/13r_7B72v6u6326atqzKZpv0fs_3OUOJFR-6QDipHl3Y/viewform?entry.1560244398&entry.1894094686&entry.1809496416&entry.2029760924&entry.1442423869&entry.1714224469&entry.1070945708=${encodeURIComponent(
6 | ip
7 | )}&entry.2019626860=${encodeURIComponent(coords)}`;
8 | link.setAttribute('href', getFormURL(defaultIp, defaultCoords));
9 | link.addEventListener('click', (clickEvent) => {
10 | clickEvent.preventDefault();
11 | try {
12 | navigator.geolocation.getCurrentPosition(
13 | ({ coords }) => {
14 | // success
15 | window.location.href = getFormURL(
16 | window.userip ? `${window.userip} (detected)` : defaultIp,
17 | `${coords.latitude},${coords.longitude} (detected)`
18 | );
19 | },
20 | () => {
21 | window.location.href = clickEvent.target.href;
22 | } // error
23 | );
24 | } catch (geoNotAvailable) {
25 | window.location.href = clickEvent.target.href;
26 | }
27 | });
28 |
--------------------------------------------------------------------------------
/docs/source/layouts/bootstrap.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Algolia Places | No style test
18 | <%= javascript_include_tag config[:places_lib_url] %>
19 |
24 |
25 |
26 |
27 | <%= yield %>
28 |
29 |
30 |
--------------------------------------------------------------------------------
/docs/source/layouts/documentation.erb:
--------------------------------------------------------------------------------
1 | <% wrap_layout :layout do %>
2 |
3 |
4 |
5 |
6 | <%= yield %>
7 |
8 |
9 |
10 | <%= javascript_include_tag 'documentation-layout' %>
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/docs/source/layouts/landing.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Algolia Places <%= "| #{current_page.data.title}" if (current_page.path != 'index.html') %>
27 |
28 |
29 |
30 | <% if current_page.path == 'index.html' %>
31 |
32 | <% end %>
33 | <% if current_page.path == 'contact.html' %>
34 |
35 | <% end %>
36 |
37 | <%= stylesheet_link_tag(:landing) %>
38 | <%= auto_stylesheet_link_tag %>
39 | <%= javascript_include_tag config[:places_lib_url] %>
40 |
44 |
45 |
46 |
47 | <%= partial("/partials/navigation") %>
48 | <%= yield %>
49 | <%= partial("/partials/footer") %>
50 | <%= javascript_include_tag :common %>
51 | <%= auto_javascript_include_tag %>
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/source/layouts/layout.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Algolia Places <%= "| #{current_page.data.title}" if (current_page.path != 'index.html') %>
27 |
28 |
29 |
30 | <% if current_page.path == 'index.html' %>
31 |
32 | <% end %>
33 | <% if current_page.path == 'contact.html' %>
34 |
35 | <% end %>
36 |
37 | <%= stylesheet_link_tag :site %>
38 | <%= auto_stylesheet_link_tag %>
39 | <%= javascript_include_tag config[:places_lib_url] %>
40 |
44 |
45 |
46 |
47 | <%= partial("/partials/navigation") %>
48 | <%= partial("/partials/hero") %>
49 | <%= yield %>
50 | <%= partial "/partials/footer" %>
51 | <%= javascript_include_tag :common %>
52 | <%= auto_javascript_include_tag %>
53 |
54 |
55 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_autocomplete_dataset.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
47 | <%= javascript_include_tag config[:places_autocomplete_dataset_lib_url] %>
48 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_city_search.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= javascript_include_tag config[:places_lib_url] %>
4 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_complete_form.html.erb:
--------------------------------------------------------------------------------
1 |
19 |
20 | <%= javascript_include_tag config[:places_lib_url] %>
21 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_country_search.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= javascript_include_tag config[:places_lib_url] %>
8 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_demo.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= javascript_include_tag config[:places_lib_url] %>
4 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_disable_styling.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= javascript_include_tag config[:places_lib_url] %>
6 |
44 |
45 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_instantsearch.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 | <%= javascript_include_tag config[:instantsearch_lib_url] %>
9 | <%= javascript_include_tag config[:places_instantsearch_widget_lib_url] %>
10 | <%= javascript_include_tag config[:google_maps_lib_url] %>
11 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_map.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 | <%= javascript_include_tag config[:places_lib_url] %>
9 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_map_paris.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 | <%= javascript_include_tag config[:places_lib_url] %>
11 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_postcode_search.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= javascript_include_tag config[:places_lib_url] %>
4 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_reverse_geocoding.html.erb:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Latitude
16 |
17 |
18 |
19 | Longitude
20 |
21 |
22 |
23 | Locate me
24 |
25 |
26 |
27 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_simple_input.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | Selected: none
4 | <%= javascript_include_tag config[:places_lib_url] %>
5 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_single_country_search.html.erb:
--------------------------------------------------------------------------------
1 |
2 | Select country
3 |
4 | France
5 | United States
6 |
7 |
8 |
9 |
10 |
11 | Selected: none
12 | <%= javascript_include_tag config[:places_lib_url] %>
13 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_templates.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= javascript_include_tag config[:places_lib_url] %>
4 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/_visual-helper.html.haml:
--------------------------------------------------------------------------------
1 | %div.preview-holder.no-mobile
2 | %img{:src => "/images/visual-preview-places.png", :alt => "preview-places", :id => "visual-helper"}/
3 | .overlay
4 | .ov-input{'data-mention' => '.ap-input'}
5 | .ov-cancel{'data-mention' => '.ap-icon-[clear/pin]'}
6 | .ov-suggestions{'data-mention' => '.ap-dropdown-menu'}
7 | .ov-suggestion-cursor{'data-mention' => '.ap-suggestion.ap-cursor (on hover)'}
8 | .ov-suggestion{'data-mention' => '.ap-suggestion'}
9 | .ov-icon{'data-mention' => '.ap-suggestion-icon'}
10 | .ov-name{'data-mention' => '.ap-name'}
11 | .ov-highlight{'data-mention' => ''}
12 | .ov-address{'data-mention' => '.ap-address'}
13 |
14 | %div.preview-holder.display-on-small
15 | %img{:src => "/images/visual-preview-places_mobile.png", :alt => "preview-places", :id => "visual-helper"}/
16 |
17 | %table.api
18 | %thead
19 | %tr
20 | %th CSS Class
21 | %th Description
22 | %tbody
23 | %tr
24 | %td
25 | %div{:class => "css-class api-entry", :id => "css-class-ap-input"}
26 | .ap-input
27 |
28 | %td
29 | %p This class is the one use by the main places input
30 |
31 | %tr
32 | %td
33 | %div{:class => "css-class api-entry", :id => "css-class-ap-icon-pin"}
34 | .ap-icon-pin
35 |
36 | %td
37 | %p This is the class attached to the pin icon, which is visible when the input is on it's normal state
38 |
39 | %tr
40 | %td
41 | %div{:class => "css-class api-entry", :id => "css-class-ap-icon-clear"}
42 | .ap-icon-clear
43 |
44 | %td
45 | %p This is the class attached to the clear icon, which is visible when the input is filled, clicking it will empty the input
46 |
47 | %tr
48 | %td
49 | %div{:class => "css-class api-entry", :id => "css-class-ap-dropdown-menu"}
50 | .ap-dropdown-menu
51 |
52 | %td
53 | %p This class is the one that is on the whole suggestions wrapper
54 |
55 | %tr
56 | %td
57 | %div{:class => "css-class api-entry", :id => "css-class-ap-suggestion"}
58 | .ap-suggestion
59 |
60 | %td
61 | %p The .ap-suggestion class is the class of each dropdown suggestions
62 |
63 | %tr
64 | %td
65 | %div{:class => "css-class api-entry", :id => "css-class-ap-cursor"}
66 | .ap-cursor
67 |
68 | %td
69 | %p The .ap-cursor class is added to .ap-suggestion when the suggestion is hovered
70 |
71 | %tr
72 | %td
73 | %div{:class => "css-class api-entry", :id => "css-class-ap-suggestion-icon"}
74 | .ap-suggestion-icon
75 |
76 | %td
77 | %p The .ap-suggestion-icon is the class that is used on the left icon of each suggestions
78 |
79 | %tr
80 | %td
81 | %div{:class => "css-class api-entry", :id => "css-class-ap-name"}
82 | .ap-name
83 |
84 | %td
85 | %p The .ap-name class is the one used on the name of the place
86 |
87 | %tr
88 | %td
89 | %div{:class => "css-class api-entry", :id => "css-class-ap-address"}
90 | .ap-address
91 |
92 | %td
93 | %p The .ap-address class is the one used on the address of the place
94 |
95 | %tr
96 | %td
97 | %div{:class => "css-class api-entry", :id => "css-class-em"}
98 | <em>
99 | %td
100 | %p The <em> tag in the .ap-suggestion is the tag that is used to make an highlight on each names
101 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/reverse-city-search/_code.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
Searching around:
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/reverse-city-search/_code_places.html.erb:
--------------------------------------------------------------------------------
1 |
2 | Searching around:
3 |
4 |
5 |
6 | <%= javascript_include_tag config[:places_lib_url] %>
7 |
--------------------------------------------------------------------------------
/docs/source/partials/examples/reverse-city-search/_demo_places.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
When constructing a search UI using InstantSearch, you may want to filter your dataset to only display some of your products based on the distance to the end user. This is usually done using the aroundLatLngViaIP filter, or aroundLatLng filter if you have access to precise geolocation information. However geographical filters are hard to interpret when displayed in raw format, as noone really knows where the coordinates 48.8566, 2.34287
are.
3 |
4 |
Using Places, you can do a query to find the city in which your user is located and display that city name instead of a geolocation.
5 |
6 |
7 | Example:
8 |
9 |
10 | Searching around:
11 |
12 |
13 |
14 | <%= javascript_include_tag config[:places_lib_url] %>
15 |
--------------------------------------------------------------------------------
/docs/source/partials/footer.html.haml:
--------------------------------------------------------------------------------
1 | %section.ac-footer
2 |
3 | .ac-footer-container
4 | %p.ac-footer-links
5 | Code licensed under
6 | %a.ac-footer-link-item{:href => "https://github.com/algolia/places/blob/master/LICENSE"} MIT
7 | %br/
8 | %a.ac-footer-link-item{:href => "https://github.com/algolia/places/"} Github
9 | %a.ac-footer-link-item{:href => "https://github.com/algolia/places/issues"} Issues
10 | %a.ac-footer-link-item{:href => "https://www.algolia.com/policies/privacy"} Privacy policy
11 |
12 | .ac-footer-container.ac-footer-brand
13 | %p This project is part of
14 | %img.ac-footer-brand-icon{:src => "images/svg/community-badge.svg"}/
15 | %figure
16 | %img.ac-footer-brand-logo{:src => "https://res.cloudinary.com/hilnmyskv/image/upload/v1484219849/algolia-community-logo-words-darkbg.svg"}/
17 | %figcaption Algolia Community
18 |
19 | %a.ac-footer-btn.ac-footer-btn-cta{:href => "https://community.algolia.com/"} See More
20 | %span.ac-icon.ac-icon-love-dark
21 |
22 | %p.ac-footer-version Latest version: #{config[:places_lib_version]}
23 |
24 | .ac-footer-actions
25 | .footer-container
26 | %p Build unique search experiences with Algolia
27 | %a.ac-footer-btn.ac-footer-btn-ghost-grey{:href => "https://www.algolia.com/why?utm_medium=social-owned&utm_source=places%20website&utm_campaign=homepage&utm_term=why"}
28 | See Why
29 | %span.ac-icon-triangle
30 | = partial "/partials/marketing"
31 |
--------------------------------------------------------------------------------
/docs/source/partials/hero.html.haml:
--------------------------------------------------------------------------------
1 | %section{:class => ["hero-section", ("shrink" if current_page.path != "index.html")]}
2 | .container
3 | %div.hero-container
4 |
5 | %div.fl-left
6 | %a{href: "https://www.algolia.com/?utm_medium=social-owned&utm_source=places%20website&utm_campaign=homepage", title:"Algolia built this"}
7 | %span{class: "icon icon-algolia-small no-mobile", id: "icon-algolia"}
8 | %span{class: "display-on-small small-illustration"}
9 | %img{src: "images/svg/places-illustration.svg"}
10 | %h1= current_page.data.title
11 | - if current_page.data.subtitle
12 | %h3= current_page.data.subtitle
13 |
14 | - if current_page.path == 'index.html'
15 | %div.fl-right
16 | = partial("/images/svg/places-illustration.svg")
17 | %input{type: "search", id: "landing-demo", class: "hero-searchbar form-control", autofocus: true, placeholder: "Search a city or address", style: 'opacity: 0'}
18 |
19 | %div.relative
20 | %div#json-response
21 | %div#json-response-text
22 | %div#json-response-timing
23 |
24 | - if current_page.path == 'examples.html'
25 | %div.examples-intro
26 | %div.items-holder
27 | %div{:class => "item"}
28 | %a{:href => '#simple-input'}
29 | %span{:class => "square input"}
30 | = partial("/images/svg/search-icon-2.svg")
31 | %span.name Simple Input
32 |
33 | %div{:class => "item"}
34 | %a{:href => '#complete-form'}
35 | %span{:class => "square form"}
36 | = partial("/images/svg/form-icon.svg")
37 | %span.name Complete Form
38 |
39 | %div{:class => "item"}
40 | %a{:href => '#city-search'}
41 | %span{:class => "square city"}
42 | = partial("/images/svg/city-icon.svg")
43 | %span.name City Search
44 |
45 | %div{:class => "item"}
46 | %a{:href => '#country-search'}
47 | %span{:class => "square country"}
48 | = partial("/images/svg/country-icon.svg")
49 | %span.name Country Search
50 |
51 | %div{:class => "item"}
52 | %a{:href => '#displaying-on-a-map'}
53 | %span{:class => "square map"}
54 | = partial("/images/svg/map-icon.svg")
55 | %span.name Link to a map
56 |
57 | %div{:class => "item"}
58 | %a{:href => '#advanced'}
59 | %span{:class => "square advanced"}
60 | = partial("/images/svg/advanced-icon.svg")
61 | %span.name Advanced
62 |
--------------------------------------------------------------------------------
/docs/source/partials/marketing.html.erb:
--------------------------------------------------------------------------------
1 | <% if build? %>
2 |
3 |
5 |
10 | <% end %>
11 |
--------------------------------------------------------------------------------
/docs/source/partials/status/DATA_REFRESH.md.erb:
--------------------------------------------------------------------------------
1 | ### Dataset freshness
2 | - OSM Data from 2019-10-16
3 | - Geonames Data from 2019-09-30
4 | - BAN Data from 2018-09-17
5 |
--------------------------------------------------------------------------------
/docs/source/partials/status/PIPELINE_CHANGELOG.md.erb:
--------------------------------------------------------------------------------
1 |
2 | ### 2019-01-07
3 |
4 |
5 | ##### Features
6 |
7 | * **admin-levels**
8 | * define administrative, county and city admin levels by country (#104)
9 |
10 |
11 |
12 | ### 2018-11-15
13 |
14 |
15 | ##### Bug Fixes
16 |
17 | * **tests**
18 | * Update Andorra end-to-end test (#94)
19 |
20 |
21 |
22 | ### 2018-11-02
23 |
24 |
25 | ##### Bug Fixes
26 |
27 | * **pt-housenumber**
28 | * put house number after streetname in Portugal (#89)
29 |
30 |
31 |
32 | ### 2018-10-31
33 |
34 |
35 | ##### Bug Fixes
36 |
37 | * **district**
38 | * rank district lower than the city (#88)
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/docs/source/pricing.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
12 |
--------------------------------------------------------------------------------
/docs/source/rest.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
12 |
--------------------------------------------------------------------------------
/docs/source/status.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_buttons.scss:
--------------------------------------------------------------------------------
1 | .btn {
2 | background: $darkish-pink;
3 | color: #fff;
4 | border: 1px solid $red-pink;
5 | height: 40px;
6 | max-width: 140px;
7 | line-height: 40px;
8 | padding: 0 1em;
9 | text-align: center;
10 | display: block;
11 | text-decoration: none;
12 | border-radius: 3px;
13 | text-transform: uppercase;
14 | font-weight: 600;
15 | font-size: 12px;
16 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
17 | transition: background 0.1s ease;
18 | cursor: pointer;
19 |
20 | &:hover,
21 | &:active {
22 | background: $red-pink
23 | }
24 |
25 | &.btn-cta {
26 | max-width: 230px;
27 | margin: 32px auto;
28 | }
29 |
30 | &.btn-grey {
31 | background: $silver;
32 | border-color: $light-blue-grey;
33 | border-width: 2px;
34 | color: $grey-blue;
35 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
36 | }
37 |
38 | &.btn-black {
39 | background: $black;
40 | border-color: mix($black, #fff, 90%);
41 | }
42 |
43 |
44 | &-ghost {
45 | background: transparent;
46 | border-color: currentColor;
47 | font-weight: bold;
48 | max-width: inherit;
49 | padding: 0 32px;
50 |
51 | &-grey {
52 | color: $steel;
53 |
54 | &:hover {
55 | background: $steel;
56 | border-color: $steel;
57 | color: #fff;
58 |
59 | .ico-triangle {
60 | border-left-color: #fff
61 | }
62 | }
63 | }
64 |
65 | &-pink {
66 | color: $red-pink;
67 |
68 | &:hover {
69 | background: $red-pink;
70 | border-color: $red-pink;
71 | color: #fff;
72 | }
73 | }
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_clipboard.scss:
--------------------------------------------------------------------------------
1 | .rouge-code {
2 | position:relative;
3 |
4 | .clipboard {
5 | position: absolute;
6 | top: 0;
7 | right: 0;
8 | width: 40px;
9 | height: 39px;
10 | background-color: #f4f4f4;
11 | border: none;
12 | display: flex;
13 | box-sizing: border-box;
14 | border-bottom-left-radius: 4px;
15 | justify-content: center;
16 | align-items: center;
17 | opacity: 0;
18 | transition: opacity 150ms;
19 | }
20 |
21 | &:hover {
22 | .clipboard {
23 | opacity: 1;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_examples-intro.scss:
--------------------------------------------------------------------------------
1 | // icon - degree - colorStart - colorEnd
2 | $square-map: (
3 | (input,135, #13c4a5, #10a4b8),
4 | (form,138, #af84e3, #5071c7),
5 | (city,314, #ec4918, #e25d8d),
6 | (country,134, #fad961, #f76b1c),
7 | (map,135, #81bf30, #00bdbd),
8 | (advanced,135, #bfbfbf, #8a8a8a)
9 | );
10 |
11 | .examples-intro {
12 | margin-top: 4em;
13 | margin-bottom: 6em;
14 |
15 | float: left;
16 | width: 100%;
17 | display: none;
18 |
19 | @include small-mq {
20 | margin-bottom: 1.5em;
21 | }
22 |
23 | body.examples &{
24 | display: block;
25 | }
26 |
27 | .items-holder {
28 | margin: 2em auto 2em;
29 | display: block;
30 | max-width: 940px;
31 | padding: 0em;
32 | display: flex;
33 | flex-wrap: wrap;
34 | flex-direction: row;
35 |
36 | @include small-mq {
37 | align-items: center;
38 | margin-bottom: 0;
39 | }
40 |
41 | a {
42 | text-decoration: none;
43 | color: inherit;
44 | }
45 |
46 | .item {
47 | max-width: 120px;
48 | height: 120px;
49 | float: left;
50 | flex:1 1 auto;
51 | margin: 0 22px;
52 | text-align: center;
53 |
54 | &:first-of-type {
55 | margin-left: 0;
56 | }
57 | &:last-of-type {
58 | margin-right: 0;
59 | }
60 |
61 | @include small-mq {
62 | margin: auto auto 58px;
63 | width: 50%;
64 |
65 | &:first-of-type {
66 | margin-left: auto;
67 | }
68 | &:last-of-type {
69 | margin-right: auto;
70 | }
71 | }
72 |
73 | span.square {
74 | display: block;
75 | position: relative;
76 | max-width: 120px;
77 | height: 120px;
78 | border-radius: 16px;
79 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
80 | transition: box-shadow 0.3s ease, transform 0.1s ease;
81 |
82 | @each $class,$degrees, $color-a, $color-b in $square-map {
83 | &.#{$class} {
84 | background: linear-gradient(#{$degrees}deg, #{$color-a} 0, #{$color-b} 100%);
85 | }
86 | }
87 |
88 | &:hover {
89 | box-shadow: none;
90 | transform: scale(1.05);
91 |
92 | &~ .name {
93 | opacity: 1;
94 | }
95 | }
96 | }
97 |
98 | svg {
99 | position: absolute;
100 | top: 50%;
101 | left: 50%;
102 | transform: translate(-50%, -50%);
103 | }
104 |
105 | .name {
106 | font-family: 'Open Sans', Helvetica Neue, helvetica, sans-serif;
107 | opacity: 0.8;
108 | font-size: 16px;
109 | font-weight: 300;
110 | line-height: 52px;
111 | transition: opacity 0.3s ease;
112 | }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_examples.scss:
--------------------------------------------------------------------------------
1 | .form-control {
2 | width: 100%;
3 | box-sizing: border-box;
4 | padding-left: 16px;
5 | line-height: 40px;
6 | height: 40px;
7 | border: 1px solid #cccccc;
8 | border-radius: 3px;
9 | outline: none;
10 | }
11 |
12 | .form-group {
13 | margin-bottom: 1em;
14 | clear: both;
15 |
16 | label {
17 | display: block;
18 | font-weight: bold;
19 | font-size: .8em;
20 | }
21 | }
22 |
23 | #map-example-container,
24 | #map-example-container-paris {
25 | // trigger zindex value otherwise
26 | // map goes hover other elements (like header)
27 | position: relative;
28 | z-index: 0;
29 | }
30 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_fonts.scss:
--------------------------------------------------------------------------------
1 | p a {
2 | color: #21A4D7;
3 | text-decoration: none;
4 | }
5 |
6 | /* heading settings
7 | =======================*/
8 | h1,h2,h3,h4 {
9 | padding: 0;
10 | margin: 0;
11 | }
12 |
13 | h1 {
14 | font-size: 46px;
15 | }
16 |
17 | h3 {
18 | font-size: 20px;
19 | }
20 |
21 | h3 {
22 | font-size: 18px;
23 | }
24 |
25 | /* Paragraphs
26 | ======================*/
27 | p {
28 | font-family: 'Open Sans', Helvetica Neue, helvetica, sans-serif;
29 | font-size: 20px;
30 | line-height: 32px;
31 | color: $charcoal-grey-75;
32 |
33 | @include small-mq {
34 | font-size: 16px;
35 | }
36 |
37 | &+ul,
38 | &+ol {
39 | font-size: 20px;
40 | line-height: 32px;
41 | color: $charcoal-grey-75;
42 | }
43 | }
44 |
45 | /* Big titles
46 | ======================*/
47 | h2.title {
48 | text-align: center;
49 | width: 100%;
50 | font-size: 1.8em;
51 | color: $charcoal-grey;
52 | display: block;
53 | position: relative;
54 | margin-top: 120px;
55 | margin-bottom: 80px;
56 |
57 | &:after {
58 | content: '';
59 | position: absolute;
60 | width: 50px;
61 | height: 3px;
62 | background: $red-pink;
63 | top: 2.8em;
64 | left: 0;
65 | right: 0;
66 | margin: auto;
67 | }
68 |
69 | ~ p {
70 | color: $charcoal-grey;
71 | font-size: 1.3em;
72 | text-align: center;
73 |
74 | @include small-mq {
75 | font-size: 16px;
76 | }
77 | }
78 |
79 | @include small-mq {
80 | margin-top: 60px;
81 | font-size: 22px;
82 | }
83 | }
84 |
85 | /* Small titles
86 | ======================*/
87 | h3.title {
88 | font-size: 1.5em;
89 | color: $greyish-brown;
90 | font-weight: bold;
91 | margin: 0;
92 | padding: 0;
93 | line-height: 1.2em;
94 |
95 | ~ p {
96 | margin: 32px 0;
97 | padding: 8px 0 0;
98 | }
99 | }
100 | h4 {
101 | font-size: 18px;
102 | }
103 |
104 | /* Anchors / links
105 | ====================*/
106 | .link {
107 | text-transform: uppercase;
108 | font-size: 16px;
109 | color: $red-pink;
110 | font-weight: 600;
111 | text-decoration: none;
112 | padding: 0 8px;
113 | }
114 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_icons.scss:
--------------------------------------------------------------------------------
1 | .icon {
2 | text-indent: -99999px;
3 | color: transparent;
4 | transition: background 0.2s ease;
5 |
6 | &-love {
7 | background: url($icon-heart)no-repeat center center / contain
8 | }
9 |
10 | &-love-dark {
11 | background: url($icon-heart-dark)no-repeat center center / contain
12 | }
13 |
14 | &-algolia {
15 | background: url($icon-algolia-dark)no-repeat center center / contain
16 | }
17 |
18 | &-algolia-light {
19 | background: url($icon-algolia-light)no-repeat center bottom / contain;
20 | }
21 |
22 | &-mail {
23 | background: url($icon-mail)no-repeat 8px 7px / 70%
24 | }
25 |
26 | &-algolia-small {
27 | background: url('../images/svg/algolia-mark-white.svg')no-repeat center center / contain
28 | }
29 | }
30 |
31 | // Small css shape
32 | .ico-triangle {
33 | width: 0;
34 | height: 0;
35 | border-top: 5px solid transparent;
36 | border-bottom: 5px solid transparent;
37 | border-left: 5px solid $steel;
38 | position: relative;
39 | display: inline-block;
40 | margin-left: 8px;
41 | }
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_inputs.scss:
--------------------------------------------------------------------------------
1 | input {
2 | outline: none;
3 | border-radius: 4px;
4 |
5 | &::-webkit-search-decoration,
6 | &::-webkit-search-cancel-button,
7 | &::-webkit-search-results-button,
8 | &::-webkit-search-results-decoration {
9 | display: none !important;
10 | }
11 |
12 | &:not([type="radio"]):not([type="checkbox"]){
13 | @include appearance(none !important);
14 | }
15 | }
16 |
17 |
18 | // Style the input for the Demo page
19 | .hero-section {
20 |
21 | .algolia-places {
22 | top: 50px;
23 | font-family: 'Open Sans', helvetica Neue;
24 |
25 | &:before {
26 | content:'Try it!';
27 | position: absolute;
28 | top: -44px;
29 | left: 2px;
30 | width: 100px;
31 | height: 44px;
32 | text-align: right;
33 | font-style: italic;
34 | font-weight: 600;
35 | line-height: 44px;
36 | color: $powder-blue;
37 | background: {
38 | image: url($icon-arrow);
39 | repeat: no-repeat;
40 | position: bottom 12px left 24px;
41 | size: 24px;
42 | }
43 | }
44 |
45 | .hero-searchbar {
46 | border: solid 1px rgba(255, 255, 255, 0.5);
47 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
48 | color: #8f94ad;
49 | font-family: "Raleway", Helvetica Neue, helvetica;
50 | height: 56px;
51 | padding-left: 16px;
52 | padding-right: 48px;
53 | border-radius: 4px;
54 |
55 | @include appearance(none)
56 | }
57 |
58 | .ap-suggestion {
59 | color: #262626;
60 | text-align: left;
61 | }
62 |
63 | .ap-footer {
64 | color: #797979;
65 | }
66 | }
67 | }
68 |
69 | #form-message-success{
70 | font-size: 1.2em;
71 | background-color: #D6EAC7;
72 | padding: 30px;
73 | text-align: center;
74 | border-radius: 4px;
75 | &.hide{
76 | display: none;
77 | }
78 | }
79 |
80 | #form-contact {
81 | width: 800px;
82 | margin: 0 auto;
83 |
84 | &.hide{
85 | display: none;
86 | }
87 |
88 | .control-label{
89 | font-size: 1em;
90 | margin-bottom: 4px;
91 |
92 | &.required::after{
93 | display: inline-block;
94 | content: '*';
95 | margin-left: 4px;
96 | color: #E7486B;
97 | vertical-align: baseline;;
98 | }
99 | }
100 |
101 | textarea{
102 | height: 264px;
103 | resize: none;
104 | }
105 |
106 | .btn-cta {
107 | margin-top: 40px;
108 | width: 150px;
109 | }
110 |
111 | .row{
112 | width: 100%;
113 | }
114 |
115 | > .col-6{
116 | width: 50%;
117 | float: left;
118 |
119 | &:first-child{
120 | padding-right: 40px;
121 | }
122 | }
123 |
124 | .form-group{
125 | &:after {
126 | content: '';
127 | display: table;
128 | clear: both;
129 | }
130 | .col-6{
131 | width: 50%;
132 | float: left;
133 |
134 | &:first-child{
135 | padding-right: 8px;
136 | }
137 | }
138 | }
139 |
140 | @media (max-width: $bp-medium) {
141 | width: 100%;
142 | }
143 |
144 | @media (max-width: $bp-small) {
145 | > .col-6 ,
146 | > .col-6:first-child {
147 | width: 100%;
148 | padding: 0;
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_media.scss:
--------------------------------------------------------------------------------
1 | .media-object {
2 | display: block;
3 | width: 100%;
4 | height: 100%;
5 | float: left;
6 | padding: 0;
7 | margin: 0;
8 |
9 | img {
10 | object: {
11 | fit: cover;
12 | position: center center;
13 | }
14 | display: block;
15 | padding: 4px;
16 | line-height: 1.42857143;
17 | background-color: #fff;
18 | border: 1px solid #ddd;
19 | border-radius: 4px;
20 | width: 100%;
21 | max-width: 400px;
22 |
23 |
24 | &.gif {
25 | display: block;
26 | max-width: 100%;
27 | height: auto;
28 | padding: 4px;
29 | line-height: 1.42857143;
30 | background-color: #fff;
31 | border: 1px solid #ddd;
32 | border-radius: 4px;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/_sidebar.scss:
--------------------------------------------------------------------------------
1 | nav.sidebar {
2 | float: left;
3 | width: 100%;
4 | height: 100%;
5 | position: absolute;
6 | max-width: $sidebar-width;
7 | border-right: 1px solid #d8d8d8;
8 | padding-top: 120px;
9 |
10 | &.fixed {
11 | position: fixed;
12 | top: $navigation-height + 16px;
13 | z-index: 9;
14 | padding-top: 0;
15 | }
16 |
17 | li:hover ul {
18 | display: block;
19 | }
20 |
21 | a.active ~ ul {
22 | display: block;
23 | }
24 |
25 | ul {
26 | display: none;
27 | list-style: none;
28 | width: 100%;
29 | padding: 0;
30 | margin: 0;
31 | float: left;
32 |
33 | li {
34 | width: 100%;
35 | display: block;
36 | height: 32px;
37 | line-height: 32px;
38 |
39 | a {
40 | text-decoration: none;
41 | display: block;
42 | width: 100%;
43 | height: 100%;
44 | color: $charcoal-grey-75;
45 | font-weight: 400;
46 |
47 |
48 | &:focus,
49 | &:target {
50 | @extend %active-links;
51 | }
52 | &.active {
53 | @extend %active-links;
54 | }
55 | }
56 | }
57 | }
58 |
59 | @include small-mq {
60 | width: calc(100% + 16px);
61 | max-width: calc(100% + 16px);
62 | position: absolute;
63 | max-height: 46px;
64 | left: 0;
65 | top: 16px;
66 | border: none;
67 | padding-top: 0;
68 | display: none;
69 |
70 | select {
71 | width: calc(100% - 32px);
72 | margin: 8px 8px;
73 | visibility: hidden;
74 | }
75 |
76 | &.fixed {
77 | background: $brand-primary;
78 | color: #fff;
79 | top: 50px;
80 | display: block;
81 |
82 | select {
83 | visibility: visible;
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/components/docsearch/_docsearch.scss:
--------------------------------------------------------------------------------
1 | // SEARCHBOX
2 | $searchbox-config: (
3 | input-width: 200px,
4 | input-height: 36px,
5 | border-width: 2px,
6 | border-radius: 18px,
7 | input-border-color: rgba(#fff,.5),
8 | input-focus-border-color: rgba(#fff,.8),
9 | input-background: #000,
10 | font-size: 12px,
11 | placeholder-color: #777,
12 | icon-size: 18px,
13 | icon-position: left,
14 | icon-color: #fff,
15 | icon-background-opacity: 0,
16 | icon-clear-size: 12px
17 | ) !default;
18 |
19 | // DROPDOWN
20 | $dropdown-config: (
21 | main-color: #458EE1,
22 | layout-type: normal,
23 | layout-alignment: right,
24 | layout-width: 800,
25 | background-color: #fff,
26 | border-radius: 4,
27 | border-width: 1,
28 | border-color: #d9d9d9,
29 | box-shadow: light,
30 | branding-position: bottom,
31 | spacing: normal,
32 | include-desc: yes,
33 | background-category-header: #ffffff,
34 | font-size: normal,
35 | header-color: #33363D,
36 | title-color: #02060C,
37 | subtitle-color: #A4A7AE,
38 | text-color: #63676D,
39 | highlight-color: #3881FF
40 | ) !default;
41 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/site.css.scss:
--------------------------------------------------------------------------------
1 | @import 'vendors/normalize',
2 | 'vendors/variables',
3 | 'vendors/functions',
4 | 'vendors/mixins',
5 | 'vendors/base';
6 |
7 | @import 'components/code-highlight',
8 | 'components/icons',
9 | 'components/containers',
10 | 'components/navigation',
11 | 'components/buttons',
12 | 'components/media',
13 | 'components/inputs',
14 | 'components/fonts',
15 | 'components/sidebar',
16 | 'components/documentation',
17 | 'components/examples-intro',
18 | 'components/examples',
19 | 'components/footer',
20 | 'components/visual-helper',
21 | 'components/clipboard';
22 |
23 | @import 'vendors/helpers',
24 | 'vendors/animations';
25 |
26 | @import 'components/docsearch/docsearch';
27 | @import 'components/docsearch/dropdown';
28 | @import 'components/docsearch/searchbox';
29 |
30 | @include searchbox($searchbox-config...);
31 | @include dropdown($dropdown-config...);
32 |
33 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/vendors/_animations.scss:
--------------------------------------------------------------------------------
1 | // Hero Illustration
2 | $timingFunction: 3s ease infinite;
3 |
4 | @mixin anim($name, $p1, $p2, $p3) {
5 | @keyframes #{$name}{
6 | 0%, 20%, 80%, 100% {
7 | transform: #{$p1};
8 | }
9 | 10%, 40%, 50% {
10 | transform: #{$p2};
11 | }
12 | 60% {
13 | transform: #{$p3};
14 | }
15 | }
16 | }
17 | @mixin animEllipse($name, $p1, $p2, $p3) {
18 | @keyframes #{$name}{
19 | 0%, 20%, 80%, 100% {
20 | transform: #{$p1};
21 | }
22 | 10%, 40%, 50% {
23 | transform: #{$p2};
24 | opacity: 0.6;
25 | }
26 | 60% {
27 | transform: #{$p3};
28 | opacity: 0.6;
29 | }
30 | }
31 | }
32 |
33 | #pin {
34 | animation: bounce $timingFunction;
35 | }
36 | ellipse {
37 | transform-origin: center center;
38 | -moz-transform-origin: 50% 40%;
39 | animation: bounceShadow $timingFunction;
40 | -moz-animation: mozBounceShadow $timingFunction;
41 |
42 | }
43 | // Fix svg in FF
44 | #plan-holder {
45 | -moz-transform: translateY(10px);
46 | }
47 | #plan {
48 | -moz-transform: scale(1.1);
49 | }
50 |
51 | @include anim('bounce', 'translateY(0)', 'translateY(-5px)', 'translateY(-5px)');
52 | @include animEllipse('bounceShadow', 'scale(1) translateY(12px)', 'scale(0.75) translateY(12px) ', 'scale(0.75) translateY(12px) ');
53 | @include animEllipse('mozBounceShadow', 'scale(1) translateY(16px)', 'scale(0.75) translateY(16px) translateX(-8px) ', 'scale(0.75) translateY(16px) translateX(-8px) ');
54 |
55 | // Footer heartbeat
56 | @keyframes pulse{
57 | 0% {
58 | box-shadow: 0 0 0 0 rgba($red-pink, 0.4);
59 | }
60 | 70% {
61 |
62 | box-shadow: 0 0 0 30px rgba($red-pink, 0);
63 | }
64 | 100% {
65 |
66 | box-shadow: 0 0 0 0 rgba($red-pink, 0);
67 | }
68 | }
69 |
70 | @keyframes pulseHeart{
71 | 0% {
72 | transform: scale(1.3)
73 | }
74 | 70% {
75 |
76 | transform: scale(1.15)
77 | }
78 | 100% {
79 |
80 | transform: scale(1)
81 | }
82 | }
83 |
84 | .icon-love-dark {
85 | display: block;
86 | position: relative;
87 |
88 | &:before {
89 | content: '';
90 | display: block;
91 | width: 8px;
92 | height: 8px;
93 | position: absolute;
94 | top: 45%;
95 | bottom: 0;
96 | left: 50%;
97 | transform: translate(-50%,-50%);
98 | right: 0;
99 | z-index: -1;
100 | border-radius: 100%;
101 | }
102 | }
103 |
104 | .inner-bloc:hover .icon-love-dark{
105 | animation: pulseHeart 1s ease infinite;
106 |
107 | &:before {
108 | animation: pulse 1s ease infinite !important;
109 | }
110 | }
111 |
112 |
113 | // part of animate.css
114 | @keyframes fadeInDown {
115 | 0% {
116 | opacity: 0;
117 | transform: translate3d(0, -100%, 0);
118 | }
119 |
120 | 100% {
121 | opacity: 1;
122 | transform: none;
123 | }
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/vendors/_base.scss:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Raleway:400,500,600,700|Open+Sans:400,600,700);
2 |
3 | * {
4 | box-sizing: border-box;
5 | }
6 |
7 | :root {
8 | font-size: 14px;
9 | font-family: "Raleway", Helvetica Neue, helvetica;
10 | }
11 |
12 | figure {
13 | figcaption {
14 | text-indent: -9999px;
15 | color: transparent;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/vendors/_functions.scss:
--------------------------------------------------------------------------------
1 | $browser-context: 16; // Default
2 |
3 | @function em($pixels, $context: $browser-context) {
4 | @return #{$pixels/$context}em;
5 | }
--------------------------------------------------------------------------------
/docs/source/stylesheets/vendors/_helpers.scss:
--------------------------------------------------------------------------------
1 | $sizes: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
2 |
3 | [class*="bloc-"] {
4 | float: left;
5 | }
6 | @each $size in $sizes {
7 | .bloc-#{$size} {
8 | $size: $size*10%;
9 | width: $size;
10 | }
11 | }
12 |
13 | .relative {
14 | position: relative;
15 | overflow: hidden;
16 | }
17 |
18 | .center-text {
19 | text-align: center;
20 | }
21 |
22 | .fl-left {
23 | float: left;
24 | }
25 |
26 | .fl-right {
27 | float: right;
28 | }
29 |
30 | hr {
31 | border: none;
32 | float: left;
33 | clear: both;
34 | width: 100%;
35 | height: 1px;
36 | background: #e5e5e5;
37 | margin: 0;
38 |
39 | &:before,
40 | &:after {
41 | content: '';
42 | display: table;
43 | clear: both;
44 | }
45 | }
46 |
47 | .pipe {
48 | width: 2px;
49 | height: 20px;
50 | background: $red-pink;
51 | display: inline-block;
52 | float: left;
53 | margin: 20px 16px 0;
54 | line-height: $navigation-height;
55 |
56 | &+ span {
57 | font-weight: bold;
58 | width: 0;
59 | float: left;
60 | }
61 |
62 | body.index &{
63 | display: none;
64 |
65 | &+ span {
66 | display: none !important;
67 | }
68 | }
69 | }
70 |
71 | // The following helper classes
72 | // made responsive desing easy
73 | // - no-desktop : Only display on mobile
74 | // - no-mobile : Only display on desktop
75 | // - display-on-small : only display on smallish screen ( no mobile )
76 |
77 | .no-desktop {
78 | @include hide();
79 | @include small-mq {
80 | @include hide();
81 | }
82 |
83 | @include mobile-mq {
84 | @include unhide(block);
85 | }
86 |
87 |
88 | &.community-badge {
89 | @include mobile-mq {
90 | @include unhide(inline);
91 | }
92 | }
93 |
94 | @media screen and (orientation: landscape) {
95 | @include hide();
96 | }
97 | }
98 |
99 | .no-mobile {
100 | @include unhide(block);
101 |
102 | &.nav-icon {
103 | @include unhide(inline);
104 |
105 | @include small-mq {
106 | @include hide();
107 | }
108 | }
109 |
110 | @include small-mq {
111 | @include hide();
112 | }
113 | }
114 |
115 | .display-on-small {
116 | @include hide();
117 |
118 | @media (max-width: 960px){
119 | display: inline-block !important;
120 | visibility: visible;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/docs/source/stylesheets/vendors/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | @mixin placeholder {
3 | $placeholders: ":-webkit-input" ":-moz" "-moz" "-ms-input";
4 | @each $placeholder in $placeholders {
5 | &:#{$placeholder}-placeholder {
6 | @content;
7 | }
8 | }
9 | }
10 | @mixin better-fonts() {
11 | h1,h2,h3,h4,h5,h6,span,div,p,pre,code,a,strong,em,i {
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 | }
16 |
17 | @mixin footer-text{
18 | color: #496f92;
19 | text-transform: uppercase;
20 | font-weight: bold;
21 | font-size: 12px;
22 | margin: 0;
23 | font-family: 'Raleway', helvetica, sans-serif;
24 | font-weight: 800;
25 | float: none;
26 | }
27 |
28 | @mixin hide() {
29 | display: none !important;
30 | visibility: hidden;
31 | }
32 |
33 | @mixin unhide($type) {
34 | display: $type !important;
35 | visibility: visible;
36 | }
37 | @mixin appearance ($value) {
38 | -webkit-appearance: $value;
39 | -moz-appearance: $value;
40 | appearance: $value;
41 | }
42 |
43 | // Responsive Breakpoints
44 | @mixin big-min-mq {
45 | @media (min-width: $bp-big){
46 | @content
47 | }
48 | }
49 | @mixin huge-min-mq {
50 | @media (min-width: $bp-huge){
51 | @content
52 | }
53 | }
54 |
55 | @mixin big-mq {
56 | @media (max-width: $bp-big){
57 | @content
58 | }
59 | }
60 | @mixin medium-mq {
61 | @media (max-width: $bp-medium){
62 | @content
63 | }
64 | }
65 | @mixin small-mq {
66 | @media (max-width: $bp-medium){
67 | @content
68 | }
69 | }
70 | @mixin mobile-mq {
71 | @media (max-width: $bp-small){
72 | @content
73 | }
74 | }
75 | @mixin tablet-mq-portrait {
76 | @media only screen
77 | and (min-device-width : 768px)
78 | and (max-device-width : 1024px)
79 | and (orientation : portrait) {
80 | @content
81 | }
82 | }
83 | @mixin tablet-mq-landscape {
84 | @media only screen
85 | and (min-device-width : 768px)
86 | and (max-device-width : 1024px)
87 | and (orientation : landscape) {
88 | @content
89 | }
90 | }
91 |
92 | // Placeholders
93 |
94 |
95 | %fadeInDown {
96 | animation-name: fadeInDown;
97 | }
98 |
99 | %animated {
100 | -webkit-animation-duration: 0.3s;
101 | animation-duration: 0.3s;
102 | -webkit-animation-fill-mode: both;
103 | animation-fill-mode: both;
104 | }
105 |
106 | %active-links {
107 | color: $red-pink;
108 | box-shadow: inset -2px 0 0 0 $red-pink;
109 |
110 | @include small-mq {
111 | font-weight: bold;
112 | box-shadow: none;
113 | color: #fff;
114 | border-bottom: 2px solid $red-pink;
115 |
116 | }
117 | }
--------------------------------------------------------------------------------
/docs/source/support.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | This page has been moved to https://www.algolia.com/ref/places
11 |
--------------------------------------------------------------------------------
/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/places/e417a59765b86972a812ec28ad11ccd53f909bbb/header.png
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // we need to export using commonjs for ease of usage in all
2 | // JavaScript environments
3 | // We therefore need to import in commonjs too. see:
4 | // https://github.com/webpack/webpack/issues/4039
5 |
6 | /* eslint-disable import/no-commonjs */
7 |
8 | const places = require('./src/places');
9 | const version = require('./src/version');
10 |
11 | // must use module.exports to be commonJS compatible
12 | module.exports = places.default;
13 | module.exports.version = version.default;
14 | /* eslint-enable import/no-commonjs */
15 |
--------------------------------------------------------------------------------
/instantsearchWidget.js:
--------------------------------------------------------------------------------
1 | // we need to export using commonjs for ease of usage in all
2 | // JavaScript environments
3 | // We therefore need to import in commonjs too. see:
4 | // https://github.com/webpack/webpack/issues/4039
5 |
6 | /* eslint-disable import/no-commonjs */
7 |
8 | const widget = require('./src/instantsearch/widget');
9 | module.exports = widget.default;
10 | /* eslint-enable import/no-commonjs */
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "places.js",
3 | "version": "1.19.0",
4 | "description": "🌐 Turn any into an address autocomplete.",
5 | "main": "index.js",
6 | "types": "typings.d.ts",
7 | "jsdelivr": "dist/cdn/places.min.js",
8 | "scripts": {
9 | "build": "NODE_ENV=production ./scripts/build.sh",
10 | "dev": "./scripts/dev.sh",
11 | "docs:js:build": "webpack --mode production --config webpack.config.docs.js",
12 | "docs:js:watch": "webpack --mode production --config webpack.config.docs.js --watch",
13 | "docs:build": "./scripts/build-website.sh",
14 | "docs:deploy": "./scripts/deploy-website.sh",
15 | "doctoc": "doctoc --maxlevel 3 CONTRIBUTING.md",
16 | "js:build": "webpack --mode development",
17 | "js:watch": "webpack --mode development --watch",
18 | "lint": "eslint .",
19 | "lint:fix": "eslint . --fix",
20 | "release": "./scripts/release.sh",
21 | "test:unit": "jest --bail --no-cache --testPathIgnorePatterns=e2e",
22 | "test:watch": "jest --watch",
23 | "test:ci": "./scripts/test-ci.sh",
24 | "test:e2e": "jest e2e.test.js",
25 | "test": "npm run --scripts-prepend-node-path=auto test:unit && npm run --scripts-prepend-node-path=auto lint && npm run --scripts-prepend-node-path=auto build && npm run --scripts-prepend-node-path=auto test:e2e"
26 | },
27 | "author": "Algolia (https://www.algolia.com)",
28 | "homepage": "https://community.algolia.com/places",
29 | "bugs": "https://github.com/algolia/places/issues",
30 | "repository": "https://github.com/algolia/places",
31 | "license": "MIT",
32 | "devDependencies": {
33 | "@babel/cli": "7.16.0",
34 | "@babel/core": "7.16.0",
35 | "@babel/node": "7.16.0",
36 | "@babel/plugin-proposal-class-properties": "7.16.0",
37 | "@babel/plugin-proposal-decorators": "7.16.0",
38 | "@babel/plugin-proposal-export-namespace-from": "7.16.0",
39 | "@babel/plugin-proposal-function-sent": "7.16.0",
40 | "@babel/plugin-proposal-json-strings": "7.16.0",
41 | "@babel/plugin-proposal-numeric-separator": "7.16.0",
42 | "@babel/plugin-proposal-throw-expressions": "7.16.0",
43 | "@babel/plugin-syntax-dynamic-import": "7.8.3",
44 | "@babel/plugin-syntax-import-meta": "7.10.4",
45 | "@babel/polyfill": "7.12.1",
46 | "@babel/preset-env": "7.16.0",
47 | "algolia-aerial": "1.5.3",
48 | "algoliasearch-helper": "2.28.1",
49 | "babel-core": "7.0.0-bridge.0",
50 | "babel-eslint": "10.1.0",
51 | "babel-jest": "26.6.3",
52 | "babel-loader": "8.2.3",
53 | "babel-plugin-inline-import": "3.0.0",
54 | "clipboard": "2.0.11",
55 | "conventional-changelog-cli": "2.1.1",
56 | "docsearch.js": "2.6.3",
57 | "doctoc": "1.4.0",
58 | "eslint": "7.32.0",
59 | "eslint-config-algolia": "16.0.0",
60 | "eslint-config-prettier": "6.15.0",
61 | "eslint-import-resolver-webpack": "0.13.2",
62 | "eslint-plugin-eslint-comments": "3.2.0",
63 | "eslint-plugin-import": "2.25.2",
64 | "eslint-plugin-jest": "24.7.0",
65 | "eslint-plugin-prettier": "3.4.1",
66 | "eslint-plugin-react": "7.26.1",
67 | "jest-cli": "26.6.3",
68 | "json": "10.0.0",
69 | "prettier": "2.4.1",
70 | "pretty-bytes-cli": "2.0.0",
71 | "puppeteer": "5.5.0",
72 | "raw-loader": "4.0.2",
73 | "replace-in-file": "6.3.5",
74 | "semver": "7.3.7",
75 | "uglify-js": "3.14.3",
76 | "webpack": "4.46.0",
77 | "webpack-cli": "3.3.12"
78 | },
79 | "dependencies": {
80 | "algoliasearch": "^3.35.1",
81 | "autocomplete.js": "^0.38.0",
82 | "events": "^3.0.0",
83 | "insert-css": "^2.0.0",
84 | "pending-xhr-puppeteer": "1.0.17"
85 | },
86 | "jest": {
87 | "testRegex": "\\.test\\.js$",
88 | "coverageDirectory": ".coverage/",
89 | "moduleNameMapper": {
90 | "^.+\\.(svg)$": "/test/fileMock.js"
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:js-lib",
4 | "algolia"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/scripts/build-website.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nBuilding website\n"
6 |
7 | VERSION=`json version < package.json`
8 |
9 | mkdir -p docs/source/partials/status/
10 |
11 | # ensure DATA_REFRESH.md exists
12 | touch DATA_REFRESH.md
13 | cp DATA_REFRESH.md docs/source/partials/status/DATA_REFRESH.md.erb
14 |
15 | # ensure CHANGELOG.md exists
16 | touch CHANGELOG.md
17 | # cuts after the first 5 minor releases
18 | # changes the into and into
19 | # so that the produced markdown is well formatted for display
20 | # and remove line starting with a link (not useful for display)
21 | cat CHANGELOG.md | \
22 | awk 'BEGIN { counter=0 } /^# / {counter++} NR > 1 { print prev } { prev = $0 } counter==5 {exit}' | \
23 | sed -E 's/^### /##### /' | \
24 | sed -E 's/^# /### /' | \
25 | sed -E 's/^ docs/source/partials/status/CHANGELOG.md.erb
27 |
28 | # ensure PIPELINE_CHANGELOG.md exists
29 | touch PIPELINE_CHANGELOG.md
30 | # cuts after the first 5 minor releases
31 | # changes the into
32 | # so that the produced markdown is well formatted for display
33 | # and remove line starting with a link (not useful for display)
34 | cat PIPELINE_CHANGELOG.md | \
35 | awk 'BEGIN { counter=0 } /^### / {counter++} NR > 1 { print prev } { prev = $0 } counter==5 {exit}' | \
36 | sed -E 's/^#### /##### /' | \
37 | sed -E 's/^ docs/source/partials/status/PIPELINE_CHANGELOG.md.erb
39 |
40 | cd docs
41 | VERSION=${VERSION} NODE_ENV=production bundle exec middleman build
42 | cd ..
43 |
--------------------------------------------------------------------------------
/scripts/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error, no verbose
4 |
5 | printf "\nBuilding places.js library\n"
6 |
7 | bundles=( 'places' 'placesAutocompleteDataset' 'placesInstantsearchWidget' )
8 | license="/*! ${NAME} ${VERSION:-UNRELEASED} | © Algolia | github.com/algolia/places */"
9 | dist_dir="dist"
10 | dist_dir_cdn="dist/cdn"
11 |
12 | # clean
13 | mkdir -p "$dist_dir_cdn"
14 | rm -rf "${dist_dir:?}"/*
15 |
16 | # CDN build
17 | webpack --mode production
18 |
19 | for bundle in "${bundles[@]}"
20 | do
21 | dist_file="$dist_dir_cdn/${bundle}.js"
22 | dist_file_min="$dist_dir_cdn/${bundle}.min.js"
23 | source_map="${bundle}.js.map"
24 | source_map_min="${bundle}.min.js.map"
25 | dist_file_sourcemap="$dist_dir_cdn/${source_map}"
26 | dist_file_sourcemap_min="$dist_dir_cdn/${source_map_min}"
27 |
28 | echo "$license" | cat - "${dist_file}" > /tmp/out && mv /tmp/out "${dist_file}"
29 |
30 | uglifyjs "${dist_file}" \
31 | --source-map "content=${dist_file_sourcemap}" \
32 | --source-map "base=${dist_file_sourcemap_min}" \
33 | --source-map "url=${source_map_min}" \
34 | -b beautify=false,preamble="\"$license\"" \
35 | -c \
36 | -m \
37 | -o "${dist_file_min}"
38 |
39 | gzip_size=$(gzip -9 < "$dist_file_min" | wc -c | pretty-bytes)
40 | echo "=> $dist_file_min gzipped will weight $gzip_size"
41 | done
42 |
43 | # NPM build
44 | # We are gonna resolve webpack loaders and transpile every file into ES5
45 | # The goal is for the user to be able to require/import places without
46 | # having to import a complete build (dist/cdn), to avoid duplication of dependencies
47 | BABEL_DISABLE_CACHE=1 BABEL_ENV=npm babel index.js -o "$dist_dir/index.js"
48 | BABEL_DISABLE_CACHE=1 BABEL_ENV=npm babel babel-css.js -o "$dist_dir/babel-css.js"
49 | BABEL_DISABLE_CACHE=1 BABEL_ENV=npm babel autocompleteDataset.js -o "$dist_dir/autocompleteDataset.js"
50 | BABEL_DISABLE_CACHE=1 BABEL_ENV=npm babel instantsearchWidget.js -o "$dist_dir/instantsearchWidget.js"
51 | BABEL_DISABLE_CACHE=1 BABEL_ENV=npm babel src/ --out-dir "$dist_dir/src/" --ignore "src/**/*.test.js","src/**/__mocks__/*","src/**/__snapshots__/*"
52 |
--------------------------------------------------------------------------------
/scripts/bump-package-version.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console:0 max-len:0 */
2 | import fs from 'fs';
3 | import path from 'path';
4 |
5 | import replace from 'replace-in-file';
6 | import semver from 'semver';
7 | import currentVersion from '../src/version';
8 |
9 | if (!process.env.VERSION) {
10 | throw new Error(
11 | 'bump: Usage is VERSION=MAJOR.MINOR.PATCH scripts/bump-package-version.js'
12 | );
13 | }
14 | const newVersion = process.env.VERSION;
15 |
16 | if (!semver.valid(newVersion)) {
17 | throw new Error(
18 | `bump: Provided new version ${newVersion} is not a valid version per semver`
19 | );
20 | }
21 |
22 | if (semver.gte(currentVersion, newVersion)) {
23 | throw new Error(
24 | `bump: Provided new version is not higher than current version (${newVersion} <= ${currentVersion})`
25 | );
26 | }
27 |
28 | console.log(`Bumping ${newVersion}`);
29 |
30 | console.log('..Updating src/version.js');
31 |
32 | const versionFile = path.join(__dirname, '../src/version.js');
33 | const newContent = `export default '${newVersion}';\n`;
34 | fs.writeFileSync(versionFile, newContent);
35 |
36 | console.log('..Updating package.json');
37 |
38 | replace.sync({
39 | files: [path.join(__dirname, '..', 'package.json')],
40 | from: `"version": "${currentVersion}"`,
41 | to: `"version": "${newVersion}"`,
42 | });
43 |
44 | replace.sync({
45 | files: [path.join(__dirname, '..', 'README.md')],
46 | from: `places.js@${currentVersion}`,
47 | to: `places.js@${newVersion}`,
48 | });
49 |
--------------------------------------------------------------------------------
/scripts/clear-cdn-cache.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nClear CDN cache\n"
6 |
7 | VERSION=`json version < package.json`
8 | CDN_URL="https://cdn.jsdelivr.net/npm/places.js@$VERSION"
9 |
10 | while true; do
11 | STATUS=$(curl -L -I $CDN_URL 2>/dev/null | head -n 1 | cut -d$' ' -f2);
12 | if [ $STATUS == '200' ]; then
13 | printf "%s is now available on CDN\n" "$VERSION"
14 | break;
15 | else
16 | printf "%s is not yet published on CDN, retrying in 30s (status was $STATUS)\n" "$VERSION"
17 | fi
18 | sleep 30
19 | done
20 |
21 | # No more needed to clear the CDN cache because we advise to use specific versions
22 | # curl --silent -L $CACHE_URL > /dev/null
23 |
--------------------------------------------------------------------------------
/scripts/deploy-website.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nDeploying website website to gh-pages\n"
6 |
7 | : ${GH_TOKEN?"You need a GH_TOKEN environment variable to deploy"}
8 |
9 | VERSION=`json version < package.json`
10 |
11 | cd docs
12 | VERSION=${VERSION} NODE_ENV=production bundle exec middleman deploy &>/dev/null # hide output, we do not want github tokens to leak in stdout
13 | if [ $? -eq 0 ]
14 | then
15 | echo "\nWebsite was updated\n"
16 | else
17 | echo "\nCould not update the website\n"
18 | exit 1
19 | fi
20 |
--------------------------------------------------------------------------------
/scripts/dev.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nLaunching dev environment\n"
6 |
7 | yarn
8 |
9 | VERSION=$(json version < package.json)"-DEV"
10 |
11 | mkdir -p docs/source/partials/status/
12 |
13 | # ensure DATA_REFRESH.md exists
14 | touch DATA_REFRESH.md
15 | cp DATA_REFRESH.md docs/source/partials/status/DATA_REFRESH.md.erb
16 |
17 | # ensure CHANGELOG.md exists
18 | touch CHANGELOG.md
19 | # cuts after the first 5 minor releases
20 | # changes the into and into
21 | # so that the produced markdown is well formatted for display
22 | # and remove line starting with a link (not useful for display)
23 | cat CHANGELOG.md | \
24 | awk 'BEGIN { counter=0 } /^# / {counter++} NR > 1 { print prev } { prev = $0 } counter==5 {exit}' | \
25 | sed -E 's/^### /##### /' | \
26 | sed -E 's/^# /### /' | \
27 | sed -E 's/^ docs/source/partials/status/CHANGELOG.md.erb
29 |
30 | # ensure PIPELINE_CHANGELOG.md exists
31 | touch PIPELINE_CHANGELOG.md
32 | # cuts after the first 5 minor releases
33 | # changes the into
34 | # so that the produced markdown is well formatted for display
35 | # and remove line starting with a link (not useful for display)
36 | cat PIPELINE_CHANGELOG.md | \
37 | awk 'BEGIN { counter=0 } /^### / {counter++} NR > 1 { print prev } { prev = $0 } counter==5 {exit}' | \
38 | sed -E 's/^#### /##### /' | \
39 | sed -E 's/^ docs/source/partials/status/PIPELINE_CHANGELOG.md.erb
41 |
42 | cd docs &&
43 | bundle install &&
44 | NODE_ENV=development VERSION=$VERSION bundle exec middleman
45 |
--------------------------------------------------------------------------------
/scripts/finish-release.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nFinishing release\n"
6 |
7 | ./scripts/clear-cdn-cache.sh
8 | ./scripts/deploy-website.sh
9 |
--------------------------------------------------------------------------------
/scripts/release.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nReleasing\n"
6 |
7 | if [ "$(node -v)" != "v$(cat .nvmrc)" ]
8 | then
9 | printf "Release: Node version mismatch with .nvmrc (should be $(cat .nvmrc))\n"
10 | exit 1
11 | fi
12 |
13 | if ! npm owner ls | grep -q "$(npm whoami)"
14 | then
15 | printf "Release: Not an owner of the npm repo, ask a contributor for access\n"
16 | exit 1
17 | fi
18 |
19 | currentBranch=`git rev-parse --abbrev-ref HEAD`
20 | if [ $currentBranch != 'master' ]; then
21 | printf "Release: You must be on master\n"
22 | exit 1
23 | fi
24 |
25 | if [[ -n $(git status --porcelain) ]]; then
26 | printf "Release: Working tree is not clean (git status)\n"
27 | exit 1
28 | fi
29 |
30 | printf "\n\nRelease: update working tree"
31 | git pull origin master
32 | git fetch origin --tags
33 |
34 | printf "Release: install dependencies"
35 | yarn
36 |
37 | currentVersion=`cat package.json | json version`
38 |
39 | # header
40 | printf "\n\nRelease: current version is %s" $currentVersion
41 | printf "\nRelease: a changelog will be generated only if a fix/feat/performance/breaking token is found in git log"
42 | printf "\nRelease: you must choose a new ve.rs.ion (semver)"
43 | printf "\nRelease: press q to exit the next screen\n\n"
44 |
45 | # preview changelog
46 | read -p "=> Release: press [ENTER] to view changes since latest version.."
47 |
48 | conventional-changelog --preset angular --output-unreleased | less
49 |
50 | # choose and bump new version
51 | # printf "\n\nRelease: Please enter the new chosen version > "
52 | printf "\n=> Release: please type the new chosen version > "
53 | read -e newVersion
54 | VERSION=$newVersion babel-node ./scripts/bump-package-version.js
55 |
56 | # build new version
57 | NODE_ENV=production VERSION=$newVersion npm run build
58 |
59 | # update changelog
60 | printf "\n\nRelease: update changelog"
61 | conventional-changelog --preset angular --infile CHANGELOG.md --same-file
62 |
63 | # regenerate readme TOC
64 | printf "\n\nRelease: generate TOCS"
65 | npm run doctoc
66 |
67 | # git add and tag
68 | commitMessage="release v$newVersion
69 |
70 | See https://github.com/algolia/places/blob/master/CHANGELOG.md"
71 |
72 | printf "Release: update lock file"
73 | yarn
74 |
75 | git add src/version.js package.json CHANGELOG.md README.md CONTRIBUTING.md yarn.lock
76 | printf %s "$commitMessage" | git commit --file -
77 | git tag "v$newVersion"
78 |
79 | printf "\n\nRelease: almost done, check everything in another terminal tab.\n"
80 | read -p "=> Release: when ready, press [ENTER] to push to github and publish the package"
81 |
82 | printf "\n\nRelease: push to github, publish on npm\n"
83 | git push origin master
84 | git push origin --tags
85 |
86 | # We are gonna publish the package to npm, in a way
87 | # where only the dist cdn and npm are available
88 | cp package.json README.md LICENSE typings.d.ts dist/
89 | # jsDelivr original structure for places.js
90 | # cannot be changed easily: https://github.com/jsdelivr/jsdelivr/issues/12282
91 | mkdir dist/dist
92 | mv dist/cdn dist/dist
93 | cd dist
94 | npm publish
95 | mv dist/cdn cdn
96 | rm -rf dist
97 | rm -f package.json README.md LICENSE
98 | cd ..
99 |
100 | printf "
101 | Release:
102 | Package was published to npm.
103 | A job on travis-ci will be automatically launched to finalize the release.
104 | "
105 |
--------------------------------------------------------------------------------
/scripts/test-ci.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | printf "\nTesting\n"
6 |
7 | # try to build the library
8 | NODE_ENV=production npm run build
9 |
10 | # run tests
11 | npm run test:unit
12 | npm run lint
13 |
14 | # try to build the libray
15 | npm run build
16 |
17 | # run end-to-end tests against the libraries that were built
18 | npm run test:e2e
19 |
20 | # try to build the website
21 | ./scripts/build-website.sh
22 |
23 | # Finish release (clear CDN cache, deploy website) when building on master
24 | if [ "$TRAVIS_PULL_REQUEST" == 'false' ] && [ "$TRAVIS_BRANCH" == 'master' ]; then
25 | ./scripts/finish-release.sh
26 | fi
27 |
--------------------------------------------------------------------------------
/src/configure/index.js:
--------------------------------------------------------------------------------
1 | const extractParams = ({
2 | hitsPerPage,
3 | postcodeSearch,
4 | aroundLatLng,
5 | aroundRadius,
6 | aroundLatLngViaIP,
7 | insideBoundingBox,
8 | insidePolygon,
9 | getRankingInfo,
10 | countries,
11 | language,
12 | type,
13 | }) => {
14 | const extracted = {
15 | countries,
16 | hitsPerPage: hitsPerPage || 5,
17 | language: language || navigator.language.split('-')[0],
18 | type,
19 | };
20 |
21 | if (Array.isArray(countries)) {
22 | extracted.countries = extracted.countries.map((country) =>
23 | country.toLowerCase()
24 | );
25 | }
26 |
27 | if (typeof extracted.language === 'string') {
28 | extracted.language = extracted.language.toLowerCase();
29 | }
30 |
31 | if (aroundLatLng) {
32 | extracted.aroundLatLng = aroundLatLng;
33 | } else if (aroundLatLngViaIP !== undefined) {
34 | extracted.aroundLatLngViaIP = aroundLatLngViaIP;
35 | }
36 |
37 | if (postcodeSearch) {
38 | extracted.restrictSearchableAttributes = 'postcode';
39 | }
40 |
41 | return {
42 | ...extracted,
43 | aroundRadius,
44 | insideBoundingBox,
45 | insidePolygon,
46 | getRankingInfo,
47 | };
48 | };
49 |
50 | const extractControls = ({
51 | useDeviceLocation = false,
52 | computeQueryParams = (params) => params,
53 | formatInputValue,
54 | onHits = () => {},
55 | onError = (e) => {
56 | throw e;
57 | },
58 | onRateLimitReached,
59 | onInvalidCredentials,
60 | }) => ({
61 | useDeviceLocation,
62 | computeQueryParams,
63 | formatInputValue,
64 | onHits,
65 | onError,
66 | onRateLimitReached,
67 | onInvalidCredentials,
68 | });
69 |
70 | let params = {};
71 | let controls = {};
72 |
73 | const configure = (configuration) => {
74 | params = extractParams({ ...params, ...configuration });
75 | controls = extractControls({ ...controls, ...configuration });
76 |
77 | return { params, controls };
78 | };
79 |
80 | export default configure;
81 |
--------------------------------------------------------------------------------
/src/createAutocompleteDataset.js:
--------------------------------------------------------------------------------
1 | import createAutocompleteSource from './createAutocompleteSource';
2 | import defaultTemplates from './defaultTemplates';
3 |
4 | export default function createAutocompleteDataset(options) {
5 | const templates = {
6 | ...defaultTemplates,
7 | ...options.templates,
8 | };
9 |
10 | const source = createAutocompleteSource({
11 | ...options,
12 | formatInputValue: templates.value,
13 | templates: undefined,
14 | });
15 |
16 | return {
17 | source,
18 | templates,
19 | displayKey: 'value',
20 | name: 'places',
21 | cache: false,
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/src/createAutocompleteDataset.test.js:
--------------------------------------------------------------------------------
1 | import createAutocompleteDataset from './createAutocompleteDataset';
2 | import createAutocompleteSource from './createAutocompleteSource';
3 |
4 | jest.mock('./defaultTemplates.js', () => ({ template: 'test', value: 'test' }));
5 | jest.mock('./createAutocompleteSource.js', () => jest.fn(() => 'source'));
6 |
7 | describe('createAutocompleteDataset', () => {
8 | let dataset;
9 |
10 | beforeEach(() => createAutocompleteSource.mockClear());
11 | beforeEach(() => {
12 | dataset = createAutocompleteDataset({
13 | templates: { option: 'test' },
14 | option: 'test',
15 | });
16 | });
17 |
18 | it('returns an autocomplete.js dataset', () => {
19 | expect(dataset).toEqual({
20 | source: 'source',
21 | templates: { template: 'test', value: 'test', option: 'test' },
22 | displayKey: 'value',
23 | name: 'places',
24 | cache: false,
25 | });
26 | });
27 |
28 | it('calls createAutocompleteSource', () => {
29 | expect(createAutocompleteSource.mock.calls[0][0]).toEqual({
30 | formatInputValue: 'test',
31 | option: 'test',
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/src/createAutocompleteSource.js:
--------------------------------------------------------------------------------
1 | import configure from './configure';
2 | import formatHit from './formatHit';
3 | import version from './version';
4 |
5 | export default function createAutocompleteSource({
6 | algoliasearch,
7 | clientOptions,
8 | apiKey,
9 | appId,
10 | hitsPerPage,
11 | postcodeSearch,
12 | aroundLatLng,
13 | aroundRadius,
14 | aroundLatLngViaIP,
15 | insideBoundingBox,
16 | insidePolygon,
17 | getRankingInfo,
18 | countries,
19 | formatInputValue,
20 | computeQueryParams = (params) => params,
21 | useDeviceLocation = false,
22 | language = navigator.language.split('-')[0],
23 | onHits = () => {},
24 | onError = (e) => {
25 | throw e;
26 | },
27 | onRateLimitReached,
28 | onInvalidCredentials,
29 | type,
30 | }) {
31 | const placesClient = algoliasearch.initPlaces(appId, apiKey, clientOptions);
32 | placesClient.as.addAlgoliaAgent(`Algolia Places ${version}`);
33 |
34 | const configuration = configure({
35 | hitsPerPage,
36 | type,
37 | postcodeSearch,
38 | countries,
39 | language,
40 | aroundLatLng,
41 | aroundRadius,
42 | aroundLatLngViaIP,
43 | insideBoundingBox,
44 | insidePolygon,
45 | getRankingInfo,
46 | formatInputValue,
47 | computeQueryParams,
48 | useDeviceLocation,
49 | onHits,
50 | onError,
51 | onRateLimitReached,
52 | onInvalidCredentials,
53 | });
54 |
55 | let params = configuration.params;
56 | let controls = configuration.controls;
57 |
58 | let userCoords;
59 | let tracker = null;
60 |
61 | if (controls.useDeviceLocation) {
62 | tracker = navigator.geolocation.watchPosition(({ coords }) => {
63 | userCoords = `${coords.latitude},${coords.longitude}`;
64 | });
65 | }
66 |
67 | function searcher(query, cb) {
68 | const searchParams = {
69 | ...params,
70 | query,
71 | };
72 |
73 | if (userCoords) {
74 | searchParams.aroundLatLng = userCoords;
75 | }
76 |
77 | return placesClient
78 | .search(controls.computeQueryParams(searchParams))
79 | .then((content) => {
80 | const hits = content.hits.map((hit, hitIndex) =>
81 | formatHit({
82 | formatInputValue: controls.formatInputValue,
83 | hit,
84 | hitIndex,
85 | query,
86 | rawAnswer: content,
87 | })
88 | );
89 |
90 | controls.onHits({
91 | hits,
92 | query,
93 | rawAnswer: content,
94 | });
95 |
96 | return hits;
97 | })
98 | .then(cb)
99 | .catch((e) => {
100 | if (
101 | e.statusCode === 403 &&
102 | e.message === 'Invalid Application-ID or API key'
103 | ) {
104 | controls.onInvalidCredentials();
105 | return;
106 | } else if (e.statusCode === 429) {
107 | controls.onRateLimitReached();
108 | return;
109 | }
110 |
111 | controls.onError(e);
112 | });
113 | }
114 |
115 | searcher.configure = (partial) => {
116 | const updated = configure({ ...params, ...controls, ...partial });
117 |
118 | params = updated.params;
119 | controls = updated.controls;
120 |
121 | if (controls.useDeviceLocation && tracker === null) {
122 | tracker = navigator.geolocation.watchPosition(({ coords }) => {
123 | userCoords = `${coords.latitude},${coords.longitude}`;
124 | });
125 | } else if (!controls.useDeviceLocation && tracker !== null) {
126 | navigator.geolocation.clearWatch(tracker);
127 | tracker = null;
128 | userCoords = null;
129 | }
130 | };
131 | return searcher;
132 | }
133 |
--------------------------------------------------------------------------------
/src/createReverseGeocodingSource.js:
--------------------------------------------------------------------------------
1 | import configure from './configure';
2 | import formatHit from './formatHit';
3 | import version from './version';
4 | import defaultTemplates from './defaultTemplates';
5 |
6 | const filterApplicableParams = (params) => {
7 | const { hitsPerPage, aroundLatLng, getRankingInfo, language } = params;
8 |
9 | const filtered = {};
10 |
11 | if (typeof hitsPerPage === 'number') {
12 | filtered.hitsPerPage = hitsPerPage;
13 | }
14 |
15 | if (typeof language === 'string') {
16 | filtered.language = language;
17 | }
18 |
19 | if (typeof getRankingInfo === 'boolean') {
20 | filtered.getRankingInfo = getRankingInfo;
21 | }
22 | if (typeof aroundLatLng === 'string') {
23 | filtered.aroundLatLng = aroundLatLng;
24 | }
25 |
26 | return filtered;
27 | };
28 |
29 | const createReverseGeocodingSource = ({
30 | algoliasearch,
31 | clientOptions,
32 | apiKey,
33 | appId,
34 | hitsPerPage,
35 | aroundLatLng,
36 | getRankingInfo,
37 | formatInputValue = defaultTemplates.value,
38 | language = navigator.language.split('-')[0],
39 | onHits = () => {},
40 | onError = (e) => {
41 | throw e;
42 | },
43 | onRateLimitReached,
44 | onInvalidCredentials,
45 | }) => {
46 | const placesClient = algoliasearch.initPlaces(appId, apiKey, clientOptions);
47 | placesClient.as.addAlgoliaAgent(`Algolia Places ${version}`);
48 |
49 | const configuration = configure({
50 | apiKey,
51 | appId,
52 | hitsPerPage,
53 | aroundLatLng,
54 | getRankingInfo,
55 | language,
56 | formatInputValue,
57 | onHits,
58 | onError,
59 | onRateLimitReached,
60 | onInvalidCredentials,
61 | });
62 |
63 | let params = filterApplicableParams(configuration.params);
64 | let controls = configuration.controls;
65 |
66 | const searcher = (queryAroundLatLng, cb) => {
67 | const finalAroundLatLng = queryAroundLatLng || params.aroundLatLng;
68 |
69 | if (!finalAroundLatLng) {
70 | const error = new Error(
71 | 'A location must be provided for reverse geocoding'
72 | );
73 | return Promise.reject(error);
74 | }
75 |
76 | return placesClient
77 | .reverse({ ...params, aroundLatLng: finalAroundLatLng })
78 | .then((content) => {
79 | const hits = content.hits.map((hit, hitIndex) =>
80 | formatHit({
81 | formatInputValue: controls.formatInputValue,
82 | hit,
83 | hitIndex,
84 | query: finalAroundLatLng,
85 | rawAnswer: content,
86 | })
87 | );
88 |
89 | controls.onHits({
90 | hits,
91 | query: finalAroundLatLng,
92 | rawAnswer: content,
93 | });
94 |
95 | return hits;
96 | })
97 | .then(cb)
98 | .catch((e) => {
99 | if (
100 | e.statusCode === 403 &&
101 | e.message === 'Invalid Application-ID or API key'
102 | ) {
103 | controls.onInvalidCredentials();
104 | return;
105 | } else if (e.statusCode === 429) {
106 | controls.onRateLimitReached();
107 | return;
108 | }
109 |
110 | controls.onError(e);
111 | });
112 | };
113 |
114 | searcher.configure = (partial) => {
115 | const updated = configure({ ...params, ...controls, ...partial });
116 |
117 | params = filterApplicableParams(updated.params);
118 | controls = updated.controls;
119 |
120 | return searcher;
121 | };
122 |
123 | return searcher;
124 | };
125 |
126 | export default createReverseGeocodingSource;
127 |
--------------------------------------------------------------------------------
/src/defaultTemplates.js:
--------------------------------------------------------------------------------
1 | import value from './formatInputValue';
2 | import suggestion from './formatDropdownValue';
3 | import algoliaLogo from './icons/algolia.svg';
4 | import osmLogo from './icons/osm.svg';
5 |
6 | export default {
7 | footer: ``,
11 | value,
12 | suggestion,
13 | };
14 |
--------------------------------------------------------------------------------
/src/errors.js:
--------------------------------------------------------------------------------
1 | export default {
2 | multiContainers: `Algolia Places: 'container' must point to a single element.
3 | Example: instantiate the library twice if you want to bind two .
4 |
5 | See https://community.algolia.com/places/documentation.html#api-options-container`,
6 | badContainer: `Algolia Places: 'container' must point to an element.
7 |
8 | See https://community.algolia.com/places/documentation.html#api-options-container`,
9 | rateLimitReached: `Algolia Places: Current rate limit reached.
10 |
11 | Sign up for a free 100,000 queries/month account at
12 | https://www.algolia.com/users/sign_up/places.
13 |
14 | Or upgrade your 100,000 queries/month plan by contacting us at
15 | https://community.algolia.com/places/contact.html.`,
16 | invalidCredentials: `The APP ID or API key provided is invalid.`,
17 | invalidAppId: `Your APP ID is invalid. A Places APP ID starts with 'pl'. You must create a valid Places app first.
18 |
19 | Create a free Places app here: https://www.algolia.com/users/sign_up/places`,
20 | };
21 |
--------------------------------------------------------------------------------
/src/findCountryCode.js:
--------------------------------------------------------------------------------
1 | export default function findCountryCode(tags) {
2 | for (let tagIndex = 0; tagIndex < tags.length; tagIndex++) {
3 | const tag = tags[tagIndex];
4 | const find = tag.match(/country\/(.*)?/);
5 | if (find) {
6 | return find[1];
7 | }
8 | }
9 |
10 | return undefined;
11 | }
12 |
--------------------------------------------------------------------------------
/src/findCountryCode.test.js:
--------------------------------------------------------------------------------
1 | import findCountryCode from './findCountryCode';
2 |
3 | describe('findCountryCode', () => {
4 | const testCases = [
5 | {
6 | name: 'empty array',
7 | input: [],
8 | expected: undefined,
9 | },
10 | {
11 | name: 'match',
12 | input: ['country/us', 'country/fr'],
13 | expected: 'us',
14 | },
15 | ];
16 |
17 | testCases.forEach((testCase) =>
18 | it(`${testCase.name} test case`, () =>
19 | expect(findCountryCode(testCase.input)).toEqual(testCase.expected))
20 | );
21 | });
22 |
--------------------------------------------------------------------------------
/src/findType.js:
--------------------------------------------------------------------------------
1 | export default function findType(tags) {
2 | const types = {
3 | country: 'country',
4 | city: 'city',
5 | 'amenity/bus_station': 'busStop',
6 | 'amenity/townhall': 'townhall',
7 | 'railway/station': 'trainStation',
8 | 'aeroway/aerodrome': 'airport',
9 | 'aeroway/terminal': 'airport',
10 | 'aeroway/gate': 'airport',
11 | };
12 |
13 | for (const t in types) {
14 | if (tags.indexOf(t) !== -1) {
15 | return types[t];
16 | }
17 | }
18 |
19 | return 'address';
20 | }
21 |
--------------------------------------------------------------------------------
/src/findType.test.js:
--------------------------------------------------------------------------------
1 | import findType from './findType';
2 |
3 | describe('findType', () => {
4 | const testCases = [
5 | {
6 | name: 'empty array',
7 | input: [],
8 | expected: 'address',
9 | },
10 | {
11 | name: 'unknown',
12 | input: ['foo', 'bar'],
13 | expected: 'address',
14 | },
15 | {
16 | name: 'city',
17 | input: ['city', 'address'],
18 | expected: 'city',
19 | },
20 | {
21 | name: 'country',
22 | input: ['country', 'city'],
23 | expected: 'country',
24 | },
25 | {
26 | name: 'address',
27 | input: ['address'],
28 | expected: 'address',
29 | },
30 | {
31 | name: 'an airport',
32 | input: ['address', 'aeroway/aerodrome'],
33 | expected: 'airport',
34 | },
35 | {
36 | name: 'a bus stop',
37 | input: ['address', 'amenity/bus_station'],
38 | expected: 'busStop',
39 | },
40 | {
41 | name: 'a train station',
42 | input: ['address', 'railway/station'],
43 | expected: 'trainStation',
44 | },
45 | {
46 | name: 'a townhall',
47 | input: ['amenity/townhall', 'address'],
48 | expected: 'townhall',
49 | },
50 | ];
51 |
52 | testCases.forEach((testCase) =>
53 | it(`${testCase.name} test case`, () =>
54 | expect(findType(testCase.input)).toEqual(testCase.expected))
55 | );
56 | });
57 |
--------------------------------------------------------------------------------
/src/formatDropdownValue.js:
--------------------------------------------------------------------------------
1 | import addressIcon from './icons/address.svg';
2 | import cityIcon from './icons/city.svg';
3 | import countryIcon from './icons/country.svg';
4 | import busIcon from './icons/bus.svg';
5 | import trainIcon from './icons/train.svg';
6 | import townhallIcon from './icons/townhall.svg';
7 | import planeIcon from './icons/plane.svg';
8 |
9 | const icons = {
10 | address: addressIcon,
11 | city: cityIcon,
12 | country: countryIcon,
13 | busStop: busIcon,
14 | trainStation: trainIcon,
15 | townhall: townhallIcon,
16 | airport: planeIcon,
17 | };
18 |
19 | export default function formatDropdownValue({ type, highlight }) {
20 | const { name, administrative, city, country } = highlight;
21 |
22 | const out = `${icons[type].trim()}
23 | ${name}
24 |
25 | ${[city, administrative, country]
26 | .filter((token) => token !== undefined)
27 | .join(', ')} `.replace(/\s*\n\s*/g, ' ');
28 |
29 | return out;
30 | }
31 |
--------------------------------------------------------------------------------
/src/formatDropdownValue.test.js:
--------------------------------------------------------------------------------
1 | import formatDropdownValue from './formatDropdownValue';
2 | jest.mock('./icons/address.svg', () => 'address');
3 |
4 | describe('formatDropdownValue', () => {
5 | it('formats the address', () => {
6 | expect(
7 | formatDropdownValue({
8 | type: 'address',
9 | highlight: {
10 | name: 'Paris',
11 | administrative: 'Île-de-France',
12 | city: 'Paris',
13 | country: 'France',
14 | type: 'address',
15 | },
16 | })
17 | ).toEqual(
18 | 'address Paris Paris, Île-de-France, France '
19 | );
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/src/formatInputValue.js:
--------------------------------------------------------------------------------
1 | export default function formatInputValue({
2 | administrative,
3 | city,
4 | country,
5 | name,
6 | type,
7 | }) {
8 | const out = `${name}${type !== 'country' && country !== undefined ? ',' : ''}
9 | ${city ? `${city},` : ''}
10 | ${administrative ? `${administrative},` : ''}
11 | ${country ? country : ''}`
12 | .replace(/\s*\n\s*/g, ' ')
13 | .trim();
14 | return out;
15 | }
16 |
--------------------------------------------------------------------------------
/src/formatInputValue.test.js:
--------------------------------------------------------------------------------
1 | import formatInputValue from './formatInputValue';
2 |
3 | describe('formatInputValue', () => {
4 | const testCases = [
5 | {
6 | name: 'simple',
7 | input: {
8 | administrative: 'Île-de-France',
9 | city: 'Paris',
10 | country: 'France',
11 | name: '88 rue de Rivoli',
12 | type: 'address',
13 | },
14 | expected: '88 rue de Rivoli, Paris, Île-de-France, France',
15 | },
16 | {
17 | name: 'country',
18 | input: {
19 | name: 'France',
20 | type: 'country',
21 | },
22 | expected: 'France',
23 | },
24 | {
25 | name: 'no city',
26 | input: {
27 | administrative: 'Île-de-France',
28 | country: 'France',
29 | name: '88 rue de Rivoli',
30 | type: 'address',
31 | },
32 | expected: '88 rue de Rivoli, Île-de-France, France',
33 | },
34 | {
35 | name: 'no administrative',
36 | input: {
37 | country: 'France',
38 | name: '88 rue de Rivoli',
39 | type: 'address',
40 | },
41 | expected: '88 rue de Rivoli, France',
42 | },
43 | {
44 | name: 'no country',
45 | input: {
46 | name: '88 rue de Rivoli',
47 | type: 'address',
48 | },
49 | expected: '88 rue de Rivoli',
50 | },
51 | ];
52 |
53 | testCases.forEach((testCase) =>
54 | it(`${testCase.name} test case`, () =>
55 | expect(formatInputValue(testCase.input)).toEqual(testCase.expected))
56 | );
57 | });
58 |
--------------------------------------------------------------------------------
/src/icons/address.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/bus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/city.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/clear.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/country.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/icons/osm.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/icons/plane.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/townhall.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/train.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/navigatorLanguage.js:
--------------------------------------------------------------------------------
1 | // polyfill for navigator.language (IE <= 10)
2 | // not polyfilled by https://cdn.polyfill.io/v2/docs/
3 |
4 | // Defined: http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorlanguage
5 | // with allowable values at http://www.ietf.org/rfc/bcp/bcp47.txt
6 | // Note that the HTML spec suggests that anonymizing services return "en-US" by default for
7 | // user privacy (so your app may wish to provide a means of changing the locale)
8 | if (!('language' in navigator)) {
9 | navigator.language =
10 | // IE 10 in IE8 mode on Windows 7 uses upper-case in
11 | // navigator.userLanguage country codes but per
12 | // http://msdn.microsoft.com/en-us/library/ie/ms533052.aspx (via
13 | // http://msdn.microsoft.com/en-us/library/ie/ms534713.aspx), they
14 | // appear to be in lower case, so we bring them into harmony with navigator.language.
15 | (navigator.userLanguage &&
16 | navigator.userLanguage.replace(
17 | /-[a-z]{2}$/,
18 | String.prototype.toUpperCase
19 | )) ||
20 | 'en-US'; // Default for anonymizing services: http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorlanguage
21 | }
22 |
--------------------------------------------------------------------------------
/src/places.css:
--------------------------------------------------------------------------------
1 | .algolia-places {
2 | width: 100%;
3 | }
4 |
5 | .ap-input, .ap-hint {
6 | width: 100%;
7 | padding-right: 35px;
8 | padding-left: 16px;
9 | line-height: 40px;
10 | height: 40px;
11 | border: 1px solid #CCC;
12 | border-radius: 3px;
13 | outline: none;
14 | font: inherit;
15 | appearance: none;
16 | -webkit-appearance: none;
17 | box-sizing: border-box;
18 | }
19 |
20 | .ap-input::-webkit-search-decoration {
21 | -webkit-appearance: none;
22 | }
23 |
24 | .ap-input::-ms-clear {
25 | display: none;
26 | }
27 |
28 | .ap-input:hover ~ .ap-input-icon svg,
29 | .ap-input:focus ~ .ap-input-icon svg,
30 | .ap-input-icon:hover svg {
31 | fill: #aaaaaa;
32 | }
33 |
34 | .ap-dropdown-menu {
35 | width: 100%;
36 | background: #ffffff;
37 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
38 | border-radius: 3px;
39 | margin-top: 3px;
40 | overflow: hidden;
41 | }
42 |
43 | .ap-suggestion {
44 | cursor: pointer;
45 | height: 46px;
46 | line-height: 46px;
47 | padding-left: 18px;
48 | overflow: hidden;
49 | }
50 |
51 | .ap-suggestion em {
52 | font-weight: bold;
53 | font-style: normal;
54 | }
55 |
56 | .ap-address {
57 | font-size: smaller;
58 | margin-left: 12px;
59 | color: #aaaaaa;
60 | }
61 |
62 | .ap-suggestion-icon {
63 | margin-right: 10px;
64 | width: 14px;
65 | height: 20px;
66 | vertical-align: middle;
67 | }
68 |
69 | .ap-suggestion-icon svg {
70 | display: inherit;
71 | -webkit-transform: scale(0.9) translateY(2px);
72 | transform: scale(0.9) translateY(2px);
73 | fill: #cfcfcf;
74 | }
75 |
76 | .ap-input-icon {
77 | border: 0;
78 | background: transparent;
79 | position: absolute;
80 | top: 0;
81 | bottom: 0;
82 | right: 16px;
83 | outline: none;
84 | }
85 |
86 | .ap-input-icon.ap-icon-pin {
87 | cursor: pointer;
88 | }
89 |
90 | .ap-input-icon svg {
91 | fill: #cfcfcf;
92 | position: absolute;
93 | top: 50%;
94 | right: 0;
95 | -webkit-transform: translateY(-50%);
96 | transform: translateY(-50%);
97 | }
98 |
99 | .ap-cursor {
100 | background: #efefef;
101 | }
102 |
103 | .ap-cursor .ap-suggestion-icon svg {
104 | -webkit-transform: scale(1) translateY(2px);
105 | transform: scale(1) translateY(2px);
106 | fill: #aaaaaa;
107 | }
108 |
109 | .ap-footer {
110 | opacity: .8;
111 | text-align: right;
112 | padding: .5em 1em .5em 0;
113 | font-size: 12px;
114 | line-height: 12px;
115 | }
116 |
117 | .ap-footer a {
118 | color: inherit;
119 | text-decoration: none;
120 | }
121 |
122 | .ap-footer a svg {
123 | vertical-align: middle;
124 | }
125 |
126 | .ap-footer:hover {
127 | opacity: 1;
128 | }
129 |
--------------------------------------------------------------------------------
/src/version.js:
--------------------------------------------------------------------------------
1 | export default '1.19.0';
2 |
--------------------------------------------------------------------------------
/test/cdn-autocomplete-min/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
98 |
99 |
--------------------------------------------------------------------------------
/test/cdn-autocomplete/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
98 |
99 |
--------------------------------------------------------------------------------
/test/cdn-main-min/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/test/cdn-main/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/test/cdn-widget-min/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
32 |
33 |
--------------------------------------------------------------------------------
/test/cdn-widget/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
32 |
33 |
--------------------------------------------------------------------------------
/test/fileMock.js:
--------------------------------------------------------------------------------
1 | export default 'file';
2 |
--------------------------------------------------------------------------------
/test/npm-autocomplete/import.js:
--------------------------------------------------------------------------------
1 | const placesAutocompleteDataset = require('../../dist/autocompleteDataset');
2 |
3 | module.exports = { placesAutocompleteDataset };
4 |
--------------------------------------------------------------------------------
/test/npm-autocomplete/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
98 |
99 |
--------------------------------------------------------------------------------
/test/npm-lib/import.js:
--------------------------------------------------------------------------------
1 | const places = require('../../dist/index');
2 |
3 | module.exports = { places };
4 |
--------------------------------------------------------------------------------
/test/npm-lib/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
30 |
31 |
--------------------------------------------------------------------------------
/test/npm-widget/import.js:
--------------------------------------------------------------------------------
1 | const placesInstantsearchWidget = require('../../dist/instantsearchWidget');
2 |
3 | module.exports = { placesInstantsearchWidget };
4 |
--------------------------------------------------------------------------------
/test/npm-widget/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
32 |
33 |
--------------------------------------------------------------------------------
/webpack.config.docs.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-commonjs */
2 | const baseConfig = require('./webpack.config');
3 | const { join } = require('path');
4 |
5 | module.exports = {
6 | ...baseConfig,
7 | entry: `./docs/source/javascripts/${process.env.BUNDLE}.js`,
8 | output: {
9 | path: join(__dirname, 'docs/.webpack/js'),
10 | filename: `${process.env.BUNDLE}.js`,
11 | },
12 | };
13 | /* eslint-enable import/no-commonjs */
14 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-commonjs */
2 | const { join } = require('path');
3 |
4 | module.exports = {
5 | entry: {
6 | places: './index.js',
7 | placesAutocompleteDataset: './autocompleteDataset.js',
8 | placesInstantsearchWidget: './instantsearchWidget.js',
9 | },
10 | devtool: 'source-map',
11 | output: {
12 | path: join(__dirname, './dist/cdn'),
13 | filename: '[name].js',
14 | library: '[name]',
15 | libraryTarget: 'umd',
16 | },
17 | module: {
18 | rules: [
19 | {
20 | test: /\.js$/,
21 | exclude: /node_modules/,
22 | loader: 'babel-loader',
23 | },
24 | {
25 | test: /\.(svg|css)$/,
26 | exclude: /node_modules/,
27 | loader: 'raw-loader',
28 | },
29 | ],
30 | },
31 | optimization: {
32 | minimize: false,
33 | },
34 | };
35 | /* eslint-enable import/no-commonjs */
36 |
--------------------------------------------------------------------------------