├── .gitignore ├── .jshintrc ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bower.json ├── demo ├── demo.css ├── demo.html └── demo.js ├── gruntFile.js ├── package.json ├── publish.js ├── src └── ui-map.js └── test ├── googlemaps.js ├── karma.conf.js └── mapSpec.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | dist 4 | out -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "browser": true, 4 | "eqnull": true, 5 | "expr": true, 6 | "globalstrict": true, 7 | "immed": true, 8 | "laxbreak": true, 9 | "loopfunc": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "noempty": true, 13 | "nonew": true, 14 | "quotmark": true, 15 | "smarttabs": true, 16 | "sub": true, 17 | "trailing": true, 18 | "undef": true, 19 | "unused": true, 20 | "globals": { 21 | "angular": false 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | - '0.10' 5 | before_install: 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start 8 | - npm install -qg bower grunt-cli 9 | - npm install -q 10 | - bower install --force 11 | - bower install --force 12 | after_success: 13 | - "./node_modules/angular-ui-publisher/travis/authentication.sh || exit 0" 14 | - "grunt dist build:gh-pages publish:gh-pages build:bower publish:bower" 15 | script: grunt 16 | env: 17 | global: 18 | - REPO="git@github.com:angular-ui/ui-map.git" 19 | - secure: ! 'Ggzx5RFlcrU4HGtp43dfikwDEyAz5KyMd5IHZOmqh+fsE0XHHyRSUHKXBwLw 20 | 21 | XIdERDdDgcx/Uy/gG07hdc3bm9uBCebtf2TUiC10Morv4X4gYq9fmNEiqYFs 22 | 23 | ZuMam+e9j8iyFa8zV0ptDPUfiwtMc4sbc8Yj2MniNsi0t602mNc=' 24 | - secure: ! 'axLcS6fl7aKTiklqZ0f9hg64iY8MZqSXN+DOoIEZCyCGSzPk0B58wd1HoA/D 25 | 26 | T2WhbZIA7TMVFRWywtYv8kaTvaqjO5PJClwxhx/vR3KbQniMG2pbzubmTVsJ 27 | 28 | sW53c2rcl4cSlFGRbNWvogRjRB1mv/yrFiYCzL0KUHq+OoOtgXU=' 29 | - secure: ! 'BwNIIBaStT8EUb8DEon0jZLTHv7cEMtAoFaS6zZx2/hsBxhKrX5yQZIgEaKS 30 | 31 | yXR57p/X7MDfgbud9NdwlhlMb6hOCmtYab1totNNabYkXNkh7kdgIewHSuTF 32 | 33 | CmXqnIJ/Cl6tw9R0nI/ulnGuAN8fSRbRmouLWJ02JpjUP2Q55v8=' 34 | - secure: ! 'LQOSYEr8LUFhTKwlxwZDDXPSudiBsH3pr8gPLacnb9Up4OHYwosI4f5oaZGi 35 | 36 | UQW7ND90+hymsyFyPOx6NfRvIOaMVKHBvSoWPQfjigmTL6yz45191STr8YvI 37 | 38 | Pv5+h++RVf0KOhm3zfzu2NK8A0Q2Ccwl78yVEpyB8wT3sG5z4zc=' 39 | - secure: ! 'Ur52cHqL1QvTCGL5+PBWpTDWIrkWB8nf3MJN+AFvhY+NODIRcosX4N2na8Wx 40 | 41 | ULwkYeJ5BlnTjdueAEOy5GN24Kd2xTlenmbl/1jIbYNehaoyeWRSOJrMgLtl 42 | 43 | YwUwd8X8CLakPvp/oSUM8m3Safm6lByJUsVjucg7Ee+Wvv0HJGE=' 44 | - secure: ! 'TBJHdn/zWfQDWF3YWOQ0fgZwPCM5IjHmHypFD5Ks/XRyXgDIn1YWT8dXAcl3 45 | 46 | zNmZ6lXp4Xqkuisy8ENAnhCdWMW2bgDTAT+EkzFfqd9IZnKKi3eEEoL8R7sr 47 | 48 | DzprJnksZJXNY7H71NPhav3aWNtA4Lw6t5njLhIvmOk9hd/meg4=' 49 | - secure: ! 'RsseeP4xur86aPPYOgxRoVpDAEs77x2d3MvZiC8ZMyW68+vw7BBzuz5KaN5J 50 | 51 | YXAXUoe83P4q0e0RpCI8qN+Q5P7hIsTdypoKnO4zKDEoiE0DIR+JcKAd6mvi 52 | 53 | pGhcabdItqxuPYZt9GWX3yZSug5o/hNXRmwxdpR5QCGdJsGFCvY=' 54 | - secure: ! 'DeIGQ2ZOE5q0WC6EhLODgTSBzSKWxgb+7+AuAln4uVFmG9whdXo2HHrkluih 55 | 56 | 3Dxld6Z+60eNSQJqSl94rDFe6yyz5+r3CnyrUWDCoz6EimXJQJ8sLgf0T36A 57 | 58 | e5q0vlCobikomCJV1EeNrUKWFVcw58im8f5KSkmxGkZkpW8Ex80=' 59 | - secure: ! 'VhNk8nAkf3eBOkH2LxVshBFldn9BrhR66AXu9MXGSjMmxk4QyM+OStgeN4Ta 60 | 61 | iA5j2buDVU9GcW0cHydonUoP9OvV8/muMuXTRuNocEhFwvmoIvIxndxkbR7Y 62 | 63 | pjZtP5KfRqnk0iQ8EXNJY8HpaNkKlE/U+KJKjaH+6Jl32vYkF7E=' 64 | - secure: ! 'bUHhuQ7gYxLPCn4TyimL1wAhSJVdBuoor8l3Z6LiCP4fDkD3hFK9i3e6SbVy 65 | 66 | qrXXjOHbr3/ghs9nuIy8Wmj1jTR6TanhxeAZ1dyR1ohlHKxwgoNCmjES3F8l 67 | 68 | 2j7NXQL1HCMkCR05BZgfr3tpSvSDMlS4q1K0cZVE1CimKA22U/k=' 69 | - secure: ! 'fxRO9CnicxrLOFu/rv+KpwTHglgz/XnE9GI3iWEziURXPnWQvemPggODdALt 70 | 71 | a4lpASNh6KKD+lRV0i0ul710U/TFpkJk8uNqoeAtaLqpqx/Kc8e2HuKVJQHL 72 | 73 | wpLpOjwtD8niOYGliyz0oOuj7XhOHvB7hWSaBdw+LJjP2LuouKw=' 74 | - secure: ! 'Uk4YG1mrgscEWV9f126X46D1RcblWan/9TcmKiCQsyYPVDj7erCLc59E7Ndm 75 | 76 | /3TPfileWzImY/NZfrJau00insmq/OMhPKHX72CdrKNyaKo8y+bUx1Z/4CCV 77 | 78 | 1sh/Z+pZ5x9gx/KRbTrQH+fvR/31/OJSzBZIuhuh8+/Qb/9TJ9Q=' 79 | - secure: ! 'Fox77OixFE0y98/dEzHVxtkbbTf4zpwLF5/T3ZOLFwl8W+XT7fYFrZ0kKUTf 80 | 81 | 0hlZvXlpIKj1A94sKAUCRlh03LJGFmn+ZvKMXnnCK0rp4ZRnIreUh9+bUKsV 82 | 83 | KfzLUXzbSt7PSBih9XnPxsWyL4kL7yOrX3eSV+EmxGsnp8JPpLg=' 84 | - secure: ! 'G6dkglxW/y+SLk3zEdAs/RTnZNAHjNHx3qAZmcYuDwGH9742zeQiyiZ87Vbm 85 | 86 | d/MbYz/dW5EerLWXoIcHfbpxntSObp7qClUHewDqaFCuN3nbQseiDpLNK0TY 87 | 88 | 7LI1iAaDI/sY2tstX3FIK8wJJedawU7jUBBpoff5+yhpt48XZro=' 89 | - secure: ! 'eecQmGE+09JuVNCj86Ce47NWmOTewNQbfVlpjeHa6Im7mHMai0+eaHEcKAjw 90 | 91 | qVcSYjpbc9qhhfUprc2MWf8HyYmBGSYq0b2xOgXVd2gHRhc2ICeQrEOz7f8b 92 | 93 | 73OSRPnCDrg8avjZTy6sJec2VwMY4L/Hz1C2+LpNjvXMt5Ltb+A=' 94 | - secure: ! 'JB8YGDVta+qdMSsSCK67/1TNokZl4pE82ka/ED2KB3jChFN5252FVjwFUlxx 95 | 96 | DfWqyEpzm3HtOGXIX9B+sM+vFKT/GIReOx14iSiZEoZ0+MJIZplRsDN2PgiO 97 | 98 | 1l+HVxiDFFTBPd/0lfkl+cvBJ7vHuV8fKIq5QcWC4W8fyw7BO/U=' 99 | - secure: ! 'b4xVLXL58muqBhZzYznwXrsdPzEBONMaXtulg74NcaTA357GTleKkPfLD/lQ 100 | 101 | xR7SN9wAH395xR1CxqeUgILG4h/PANjGfTxf+YBaNybu+pkjiCACePE/rgPV 102 | 103 | oa6HftkvU7unPg1Qsy89w9+TO3RbLObl2LgmABdKXAni3cHTfJE=' 104 | - secure: ! 'ScGiDn76Ewnk/JaSe7xORoMloAle1jQKRcdMi3oEJpKTboMrqhJEybJ3lfhX 105 | 106 | F/IdDVaneTAqXe2X2Dtutj6RN146/xyJiE1wLwzRTv6OifZVDBRhbZzdhrtb 107 | 108 | Dyb5OE7G8/cEwhD/ZSLgOBugWSsi+74TJCQeymM22MhDClWd+sY=' 109 | - secure: ! 'SKSDcZb4Z0tRz54VIweY8HheagPFrEp14EdKX+MUSDKl3orWK9NyX5ZF1Acz 110 | 111 | tiYDG+PhXysYVXq4iCs9odGxy5UyQyGvwkf8vKFG/4Q5LF0OQOpWC7btrzie 112 | 113 | +sdWbFizB6FxCBFhsUocnmtvD4+oZWcu4KMxztKPdPdPv7r70cw=' 114 | - secure: ! 'KhcTRrGY8763gw9Lxy0E5iDp2a2tTS7CO/z9gX3kvw2uWIPnggaAxdsrDMae 115 | 116 | rdFDAE2zNpDRxM67pPmeVrisRCRmdgJBz9RW6dTrRM5o5WJktEO5vYQRsibB 117 | 118 | bHvhr/2q7qS8ynCTyD4UDi0PMlyy2pEI6mmAyCwiU9yj0viwWFo=' 119 | - secure: ! 'NYWbuzljMVP3rMIa2XwSAdNo+d4M8hkLnTleERyseH7F+/7FwTawylq+58aC 120 | 121 | ejN34Xg1gAB2Ci33eFTIp4NKN7MzqGQRZNpD6J0QqO+s32PNJDDymCe40W++ 122 | 123 | Tv+mBlICsZ+7wmY2MenzcoLXj8YWMPI9dZ5AgkjqA3Qn7Cf0caM=' 124 | - secure: ! 'YO1+kO5biLPAczwVZe7hDSh5XbYHVhv9nL4yETljaHT65ou8euZfgqs/DwV/ 125 | 126 | O94cnYi2B6CXMS6IdbIBjxns1yTF2e5fymrtmqGyZh6APBXc+VItSht3Oapd 127 | 128 | oz/QGN2jriGOyhr4DgT5SQMH89gFaodpnDCQep7mlOGkx31vLeA=' 129 | - secure: ! 'JiFeeeu4Z1KrXuEGotp/4/anTuN33Eo9NPSNrvo7yrRv1B3IJshUlMwbfqHo 130 | 131 | xFvluSnmkT48hcbSUN4eXHwtOhjCGZxjMeJsHPzrwNQTzJWRSKn8Nqs9ZxMj 132 | 133 | jKp/vvb4c3Hf33TmgMHdqrOGbvf+tmghzkrXgZ/zRmAU6PUgk0k=' 134 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## v0.5.0 (2013-12-28) 3 | 4 | 5 | #### Bug Fixes 6 | 7 | * **demo:** add $params to .addMarker() arguments ([f5de0579](http://github.com/angular-ui/ui-map/commit/f5de0579d4164fe67c0a5d1842ffba08863d70d6), closes [#22](http://github.com/angular-ui/ui-map/issues/22)) 8 | * **grunt:** add forgotten publish.js file ([c75650b5](http://github.com/angular-ui/ui-map/commit/c75650b5bc3ed62e43591a737435d764e5fdcf29)) 9 | * **travis:** use angular-ui-publisher ([f51d575a](http://github.com/angular-ui/ui-map/commit/f51d575a595b4d78facd887640a9b8162c2ab93a)) 10 | 11 | 12 | #### Features 13 | 14 | * **grunt:** 15 | * add connect tasks ([444e51c7](http://github.com/angular-ui/ui-map/commit/444e51c77adf906620f149965e117020060a86ac)) 16 | * add serve task ([cee68085](http://github.com/angular-ui/ui-map/commit/cee6808598e5bd40ba1b245805f4cc3a5187ab23)) 17 | * add ngmin ([51f4e98d](http://github.com/angular-ui/ui-map/commit/51f4e98d100f30b7ac8da8755459abc88b7b00ea)) 18 | * add build and publish tasks ([057ef2cc](http://github.com/angular-ui/ui-map/commit/057ef2cce1d3a17546599224dc2fb7298dcae1ae)) 19 | 20 | 21 | 22 | ## v0.4.0 23 | * **Validate directive** has been upgraded 24 | * **API BREAKING CHANGE!** now takes expressions instead of function references 25 | * You must explicitly specify the $value variable, but you no longer need to create a function 26 | * **NEW FEATURE** uiValidateWatch allows you to re-fire a validation rule (or all rules) when a related model changes (confirm_password) 27 | * **CodeMirror directive** has been updated 28 | * Now works with v3.02 29 | * **NEW FEATURE** uiRefresh lets you specify an expression to watch for changes to refresh codemirror (useful for modals) 30 | * **Mask directive** has many new fixes 31 | * Fixes for **uiDate** 32 | * **DateFormat directive** can now be declared in **uiConfig** 33 | * **uiJq Passthru directive** has upgrades to support a wider variety of directives 34 | * Now fires asyncronously post-angular-rendering of the view (**uiDefer** option is now always true) 35 | * New **uiRefresh** lets you specify an expression to watch to re-fire the plugin (call $(elm).focus() when a modal opens) 36 | * **Select2 directive** now adds support for setting the selected item by specifying a simple ID 37 | * FINALLY have unit-tests for Select2! 38 | * **IEShiv** has been simplified and stripped of browser-sniffing code (just use conditional comments) 39 | * **Calendar directive** now performs better watching of events data 40 | * Added optional equalsTracker attr (increment to force update from scope) 41 | * **Sortable directive** now properly supports connectWith option 42 | * New **route directive** that sets a boolean based on a pattern match of the current route (useful for tabs/navigation) 43 | * Refactored **If directive** to be tidier 44 | * **API BREAKING CHANGE!** **Modal directive** has been completely removed (if you still need it, grab the files from v0.3.x) 45 | 46 | ## v0.3.0 47 | * New **format** filter 48 | * Lots of cleanup! Consistent indentation, linting 49 | * Custom builds via grunt (soon to be leveraged via builder) 50 | * uiDate now watches options 51 | * Rewrote ui-keypress (API is not backwards-compatible) 52 | * **ui-**keypress has been expanded into **ui-keyup**, **ui-keydown** and **ui-keypress** 53 | * The **ui-keypress** can now be used to `$event.preventDefault()` as expected 54 | * Multiple combinations are separated by spaces, while multi-key combos are separated by dashes: `'enter alt-space 13-shift':'whatever()'` 55 | * The string-notation (__a and be or c and d__) has been dropped completely 56 | * Can now pass (or globally define) the value uiReset resets to 57 | 58 | ## v0.2.0 59 | * Unit tests. Unit tests. Unit tests. 60 | * New **inflector** filter (previously named **prettifier**) 61 | * Added 2 alternative modes, now contains: humanize, underscore and variable 62 | * **Passthrough directive** (uiJq) now fixes common ngModel problems due to trigger(change). Can optionally be disabled 63 | * Removed **Length Filter** (you can instead do {{ ( myArray | filter: { gender:'m' } ).length }}) 64 | * Added **validate directive**, allows you to pass validation functions 65 | * **Sortable directive** 66 | * Fixed **unique filter** 67 | * **Highlight filter** has had bug fixes 68 | * **Event directive** has been refactored / improved 69 | * **Keypress directive** has been refactored / improved 70 | * New **if-directive** instead of **remove directive** (removed) 71 | * New **google maps directive** 72 | * New **animate directive** that transitions the injection of new DOM elements (transitioning the removal of DOM is still not supported yet) 73 | * Improvements to **scrollfix directive** 74 | 75 | ## v0.1.0 76 | * New folder structure 77 | * Too many to list 78 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | CONTRIBUTING 2 | ============ 3 | 4 | * Open a [Pull Request (PR)](https://github.com/angular-ui/angular-ui/pull/new/master) 5 | * Make sure your PR is on a **new branch** you created off of the latest version of master 6 | * Do **not** open a PR from your master branch 7 | * Open a PR to start a discussion even if the code isn't finished (easier to collect feedback this way) 8 | * Do **NOT** commit your changes to the [build files](https://github.com/angular-ui/angular-ui/tree/master/build) 9 | * Make sure all previous tests pass and add new tests for added behaviors 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UI.Map [![Build Status](https://secure.travis-ci.org/angular-ui/ui-map.png)](http://travis-ci.org/angular-ui/ui-map) 2 | 3 | This directive allows you to add [Google Maps Javascript API](https://developers.google.com/maps/) elements. 4 | 5 | ## Requirements 6 | 7 | - AngularJS 8 | - [UI.Event](https://github.com/angular-ui/ui-event) 9 | - [Google Maps Javascript API 3.x](https://developers.google.com/maps/documentation/javascript/) 10 | 11 | ## Usage 12 | 13 | You can get it from [Bower](http://bower.io/) 14 | 15 | ```sh 16 | bower install angular-ui-map 17 | ``` 18 | 19 | This will copy the UI.Map files into a `bower_components` folder, along with its dependencies. Load the script files in your application: 20 | 21 | ```html 22 | 23 | 24 | 25 | 26 | ``` 27 | 28 | __Make sure to listen to the [callback parameter when loading the Google Maps API](https://developers.google.com/maps/documentation/javascript/examples/map-simple-async) ! 29 | The API must be fully loaded before this module !__ 30 | Here we name this callback `onGoogleReady`. To load your angular app after the Google Maps API you can start it with [angular.bootstrap](http://docs.angularjs.org/api/angular.bootstrap). 31 | 32 | ```javascript 33 | function onGoogleReady() { 34 | angular.bootstrap(document.getElementById("map"), ['app.ui-map']); 35 | } 36 | ``` 37 | 38 | Add the UI.Map module as a dependency to your application module : 39 | 40 | ```javascript 41 | var myAppModule = angular.module('app.ui-map', ['ui.map']); 42 | ``` 43 | 44 | Finally, add the directive to your html: 45 | 46 | ```html 47 |
48 |
49 |
50 | ``` 51 | Note that `myMap` will be a [google.maps.Map class](https://developers.google.com/maps/documentation/javascript/reference#Map), and `mapOptions` a [google.maps.MapOptions object](https://developers.google.com/maps/documentation/javascript/reference#MapOptions) (see [below](#options)). 52 | 53 | To see something it's better to add some CSS, like 54 | 55 | ```css 56 | .map-canvas { height: 400px; } 57 | ``` 58 | 59 | ## Options 60 | 61 | [google.maps.MapOptions object](https://developers.google.com/maps/documentation/javascript/reference#MapOptions) can be passed through the main directive attribute`ui-map`. 62 | 63 | ```javascript 64 | myAppModule.controller('MapCtrl', ['$scope', function ($scope) { 65 | $scope.mapOptions = { 66 | center: new google.maps.LatLng(35.784, -78.670), 67 | zoom: 15, 68 | mapTypeId: google.maps.MapTypeId.ROADMAP 69 | }; 70 | }]); 71 | ``` 72 | 73 | ### UI.Event 74 | 75 | [UI.Event](https://github.com/angular-ui/ui-event) allows you to specify custom behavior over user events. You just need to prefix the official event by __map-__ to bind a callback to it. 76 | 77 | For example, the _click_ or *zoom_changed* event of the [google.maps.Map class](https://developers.google.com/maps/documentation/javascript/reference#Map) can be used through the UI.Event object keys __map-click__ and **map-zoom_changed** : 78 | 79 | ```html 80 |
81 |
84 |
85 | ``` 86 | 87 | 88 | ## Testing 89 | 90 | We use Karma and jshint to ensure the quality of the code. The easiest way to run these checks is to use grunt: 91 | 92 | ```sh 93 | npm install -g grunt-cli 94 | npm install && bower install 95 | grunt 96 | ``` 97 | 98 | The karma task will try to open Firefox and Chrome as browser in which to run the tests. Make sure this is available or change the configuration in `test\karma.conf.js` 99 | 100 | 101 | ### Grunt Serve 102 | 103 | We have one task to serve them all ! 104 | 105 | ```sh 106 | grunt serve 107 | ``` 108 | 109 | It's equal to run separately: 110 | 111 | * `grunt connect:server` : giving you a development server at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). 112 | 113 | * `grunt karma:server` : giving you a Karma server to run tests (at [http://localhost:9876/](http://localhost:9876/) by default). You can force a test on this server with `grunt karma:unit:run`. 114 | 115 | * `grunt watch` : will automatically test your code and build your demo. You can demo generation with `grunt build:gh-pages`. 116 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "AngularUI", 3 | "name": "angular-ui-map", 4 | "version": "0.5.0", 5 | "homepage": "http://angular-ui.github.com", 6 | "keywords": [ 7 | "angular", 8 | "angularui", 9 | "map" 10 | ], 11 | "main": "./ui-map.js", 12 | "dependencies": { 13 | "angular": "1.x", 14 | "angular-ui-event": "~1.0.0" 15 | }, 16 | "devDependencies": { 17 | "angular-mocks": "1.x" 18 | } 19 | } -------------------------------------------------------------------------------- /demo/demo.css: -------------------------------------------------------------------------------- 1 | .map { 2 | height: 400px; 3 | width: 600px; 4 | margin: auto; 5 | } -------------------------------------------------------------------------------- /demo/demo.html: -------------------------------------------------------------------------------- 1 | 3 | 4 |
5 | 8 |
9 |
10 |
11 |

Click to add a marker!

12 |

{{zoomMessage}}

13 | 20 | 21 | 23 |
25 |
26 | 27 |
28 |

Marker

29 | Lat: , Lng: 30 | Set Position 31 |
32 |
33 | 34 | 36 |
39 |
40 |
41 |
42 |

How?

43 | 44 | 45 |
46 | 47 | 48 | 49 |
50 |
<section id="map">
 51 | <h4>Click to add a marker!</h4>
 52 | <p>{{zoomMessage}}</p>
 53 | <ul>
 54 |   <li ng-repeat="marker in myMarkers">
 55 |     <a ng-click="myMap.panTo(marker.getPosition())">Pan to Marker {{$index}}</a>
 56 |   </li>
 57 | </ul>
 58 | 
 59 | <!-- this is the confusing part. we have to point the map marker directive
 60 |   at an existing google.maps.Marker object, so it can hook up events -->
 61 | <div ng-repeat="marker in myMarkers" ui-map-marker="myMarkers[$index]"
 62 |   ui-event="{'map-click': 'openMarkerInfo(marker)'}">
 63 | </div>
 64 | 
 65 | <div ui-map-info-window="myInfoWindow">
 66 |   <h1>Marker</h1>
 67 |   Lat: <input ng-model="currentMarkerLat">, Lng: <input ng-model="currentMarkerLng">
 68 |   <a ng-click="setMarkerPosition(currentMarker, currentMarkerLat, currentMarkerLng)">Set Position</a>
 69 | </div>
 70 | 
 71 | <!-- Giving the div an id="map_canvas" fix problems with twitter bootstrap affecting
 72 | google maps -->
 73 | <div id="map_canvas" ui-map="myMap" class="map"
 74 |   ui-event="{'map-click': 'addMarker($event, $params)', 'map-zoom_changed': 'setZoomMessage(myMap.getZoom())' }"
 75 |   ui-options="mapOptions">
 76 | </div>
 77 | </section>
78 |
79 |
80 |
81 | 82 |
83 |
.map {
 84 |   height: 400px;
 85 |   width: 600px;
 86 |   margin: auto;
 87 | }
88 |
89 |
90 |
91 | 92 |
93 |
function initCall() {
 94 |   console.log('Google maps api initialized.');
 95 |   angular.bootstrap(document.getElementById('map'), ['doc.ui-map']);
 96 | }
 97 | 
 98 | app.controller('MapCtrl', ['$scope', function($scope) {
 99 | 
100 | $scope.myMarkers = [];
101 | 
102 | $scope.mapOptions = {
103 |   center: new google.maps.LatLng(35.784, -78.670),
104 |   zoom: 15,
105 |   mapTypeId: google.maps.MapTypeId.ROADMAP
106 | };
107 | 
108 | $scope.addMarker = function($event, $params) {
109 |   $scope.myMarkers.push(new google.maps.Marker({
110 |     map: $scope.myMap,
111 |     position: $params[0].latLng
112 |   }));
113 | };
114 | 
115 | $scope.setZoomMessage = function(zoom) {
116 |   $scope.zoomMessage = 'You just zoomed to '+zoom+'!';
117 |   console.log(zoom,'zoomed')
118 | };
119 | 
120 | $scope.openMarkerInfo = function(marker) {
121 |   $scope.currentMarker = marker;
122 |   $scope.currentMarkerLat = marker.getPosition().lat();
123 |   $scope.currentMarkerLng = marker.getPosition().lng();
124 |   $scope.myInfoWindow.open($scope.myMap, marker);
125 | };
126 | 
127 | $scope.setMarkerPosition = function(marker, lat, lng) {
128 |   marker.setPosition(new google.maps.LatLng(lat, lng));
129 | };
130 | }]);
131 |
132 |
133 |
134 |
135 |

Remember that you can pass a variable containing an object to ui-event

136 | 137 |
138 | -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | /* global console:false, google:false */ 2 | /*jshint unused:false */ 3 | 'use strict'; 4 | 5 | function initCall() { 6 | console.log('Google maps api initialized.'); 7 | angular.bootstrap(document.getElementById('map'), ['doc.ui-map']); 8 | } 9 | 10 | angular.module('doc.ui-map', ['ui.map', 'prettifyDirective', 'ui.bootstrap', 'plunker' ]) 11 | .controller('MapCtrl', ['$scope', function ($scope) { 12 | 13 | $scope.myMarkers = []; 14 | 15 | $scope.mapOptions = { 16 | center: new google.maps.LatLng(35.784, -78.670), 17 | zoom: 15, 18 | mapTypeId: google.maps.MapTypeId.ROADMAP 19 | }; 20 | 21 | $scope.addMarker = function ($event, $params) { 22 | $scope.myMarkers.push(new google.maps.Marker({ 23 | map: $scope.myMap, 24 | position: $params[0].latLng 25 | })); 26 | }; 27 | 28 | $scope.setZoomMessage = function (zoom) { 29 | $scope.zoomMessage = 'You just zoomed to ' + zoom + '!'; 30 | console.log(zoom, 'zoomed'); 31 | }; 32 | 33 | $scope.openMarkerInfo = function (marker) { 34 | $scope.currentMarker = marker; 35 | $scope.currentMarkerLat = marker.getPosition().lat(); 36 | $scope.currentMarkerLng = marker.getPosition().lng(); 37 | $scope.myInfoWindow.open($scope.myMap, marker); 38 | }; 39 | 40 | $scope.setMarkerPosition = function (marker, lat, lng) { 41 | marker.setPosition(new google.maps.LatLng(lat, lng)); 42 | }; 43 | }]) 44 | ; -------------------------------------------------------------------------------- /gruntFile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (grunt) { 4 | 5 | require('load-grunt-tasks')(grunt); 6 | 7 | // Default task. 8 | grunt.registerTask('default', ['jshint', 'karma:unit']); 9 | grunt.registerTask('serve', ['karma:continuous', 'dist', 'build:gh-pages', 'connect:continuous', 'watch']); 10 | grunt.registerTask('dist', ['ngmin', 'uglify']); 11 | // 12 | 13 | 14 | // HACK TO ACCESS TO THE COMPONENT-PUBLISHER 15 | function fakeTargetTask(prefix){ 16 | return function(){ 17 | 18 | if (this.args.length !== 1) return grunt.log.fail('Just give the name of the ' + prefix + ' you want like :\ngrunt ' + prefix + ':bower'); 19 | 20 | var done = this.async(); 21 | var spawn = require('child_process').spawn; 22 | spawn('./node_modules/.bin/gulp', [ prefix, '--branch='+this.args[0] ].concat(grunt.option.flags()), { 23 | cwd : './node_modules/angular-ui-publisher', 24 | stdio: 'inherit' 25 | }).on('close', done); 26 | }; 27 | } 28 | 29 | grunt.registerTask('build', fakeTargetTask('build')); 30 | grunt.registerTask('publish', fakeTargetTask('publish')); 31 | // 32 | 33 | 34 | // HACK TO MAKE TRAVIS WORK 35 | var testConfig = function (configFile, customOptions) { 36 | var options = { configFile: configFile, singleRun: true }; 37 | var travisOptions = process.env.TRAVIS && { browsers: [ 'Firefox', 'PhantomJS'], reporters: ['dots'] }; 38 | return grunt.util._.extend(options, customOptions, travisOptions); 39 | }; 40 | // 41 | 42 | 43 | // Project configuration. 44 | grunt.initConfig({ 45 | bower: 'bower_components', 46 | dist: '<%= bower %>/angular-ui-docs', 47 | pkg: grunt.file.readJSON('package.json'), 48 | meta: { 49 | banner: ['/**', 50 | ' * <%= pkg.name %> - <%= pkg.description %>', 51 | ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>', 52 | ' * @link <%= pkg.homepage %>', 53 | ' * @license <%= pkg.license %>', 54 | ' */', 55 | ''].join('\n') 56 | }, 57 | 58 | watch: { 59 | src: { 60 | files: ['src/*'], 61 | tasks: ['jshint:src', 'karma:unit:run', 'dist', 'build:gh-pages'] 62 | }, 63 | test: { 64 | files: ['test/*.js'], 65 | tasks: ['jshint:test', 'karma:unit:run'] 66 | }, 67 | demo: { 68 | files: ['demo/*', 'publish.js'], 69 | tasks: ['jshint', 'build:gh-pages'] 70 | }, 71 | livereload: { 72 | files: ['out/built/gh-pages/**/*'], 73 | options: { livereload: true } 74 | } 75 | }, 76 | 77 | karma: { 78 | unit: testConfig('test/karma.conf.js'), 79 | server: {configFile: 'test/karma.conf.js'}, 80 | continuous: {configFile: 'test/karma.conf.js', background: true } 81 | }, 82 | 83 | connect: { 84 | options: { 85 | base : 'out/built/gh-pages', 86 | open: true, 87 | livereload: true 88 | }, 89 | server: { options: { keepalive: true } }, 90 | continuous: { options: { keepalive: false } } 91 | }, 92 | 93 | jshint: { 94 | src: { 95 | files:{ src : ['src/*.js', 'demo/**/*.js'] }, 96 | options: { jshintrc: '.jshintrc' } 97 | }, 98 | test: { 99 | files:{ src : [ 'test/*.spec.js', 'gruntFile.js'] }, 100 | options: grunt.util._.extend({}, grunt.file.readJSON('.jshintrc'), { 101 | node: true, 102 | globals: { 103 | angular: false, 104 | inject: false, 105 | jQuery: false, 106 | 107 | jasmine: false, 108 | afterEach: false, 109 | beforeEach: false, 110 | ddescribe: false, 111 | describe: false, 112 | expect: false, 113 | iit: false, 114 | it: false, 115 | spyOn: false, 116 | xdescribe: false, 117 | xit: false 118 | } 119 | }) 120 | } 121 | }, 122 | 123 | uglify: { 124 | options: {banner: '<%= meta.banner %>'}, 125 | build: { 126 | expand: true, 127 | cwd: 'dist', 128 | src: ['*.js'], 129 | ext: '.min.js', 130 | dest: 'dist' 131 | } 132 | }, 133 | 134 | ngmin: { 135 | main: { 136 | expand: true, 137 | cwd: 'src', 138 | src: ['*.js'], 139 | dest: 'dist' 140 | } 141 | }, 142 | 143 | changelog: { 144 | options: { 145 | dest: 'CHANGELOG.md' 146 | } 147 | } 148 | }); 149 | 150 | }; 151 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-ui-map", 3 | "version": "0.5.0", 4 | "description": "This directive allows you to add map elements.", 5 | "author": "https://github.com/angular-ui/ui-map/graphs/contributors", 6 | "license": "MIT", 7 | "homepage": "http://angular-ui.github.com", 8 | "main": "./ui-map.js", 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "angular-ui-publisher": "1.2.x", 12 | "grunt": "0.4.x", 13 | "grunt-contrib-connect": "0.5.x", 14 | "grunt-contrib-jshint": "0.8.x", 15 | "grunt-contrib-uglify": "0.2.x", 16 | "grunt-contrib-watch": "0.5.x", 17 | "grunt-conventional-changelog": "1.x", 18 | "grunt-karma": "0.6.x", 19 | "grunt-ngmin": "0.0.x", 20 | "karma": "0.10.x", 21 | "karma-chrome-launcher": "0.1.x", 22 | "karma-coffee-preprocessor": "0.1.x", 23 | "karma-firefox-launcher": "0.1.x", 24 | "karma-html2js-preprocessor": "0.1.x", 25 | "karma-jasmine": "0.1.x", 26 | "karma-phantomjs-launcher": "0.1.x", 27 | "karma-requirejs": "0.2.x", 28 | "karma-script-launcher": "0.1.x", 29 | "load-grunt-tasks": "0.2.x", 30 | "requirejs": "2.1.x" 31 | }, 32 | "scripts": {}, 33 | "repository": { 34 | "type": "git", 35 | "url": "git://github.com/angular-ui/ui-map.git" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /publish.js: -------------------------------------------------------------------------------- 1 | /* jshint node:true */ 2 | 3 | 'use strict'; 4 | 5 | var fs = require('fs'); 6 | 7 | module.exports = function() { 8 | 9 | var js_dependencies = [ 10 | 'https://cdn.rawgit.com/angular-ui/ui-event/master/dist/event.min.js', 11 | 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initCall' 12 | ]; 13 | 14 | return { 15 | humaName : 'UI.Map', 16 | repoName : 'ui-map', 17 | inlineHTML : fs.readFileSync(__dirname + '/demo/demo.html'), 18 | inlineJS : fs.readFileSync(__dirname + '/demo/demo.js'), 19 | css: ['demo/demo.css'], 20 | js : js_dependencies.concat(['dist/ui-map.min.js']) 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /src/ui-map.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function () { 4 | var app = angular.module('ui.map', ['ui.event']); 5 | 6 | //Setup map events from a google map object to trigger on a given element too, 7 | //then we just use ui-event to catch events from an element 8 | function bindMapEvents(scope, eventsStr, googleObject, element) { 9 | angular.forEach(eventsStr.split(' '), function (eventName) { 10 | //Prefix all googlemap events with 'map-', so eg 'click' 11 | //for the googlemap doesn't interfere with a normal 'click' event 12 | window.google.maps.event.addListener(googleObject, eventName, function (event) { 13 | element.triggerHandler('map-' + eventName, event); 14 | //We create an $apply if it isn't happening. we need better support for this 15 | //We don't want to use timeout because tons of these events fire at once, 16 | //and we only need one $apply 17 | if (!scope.$$phase){ scope.$apply();} 18 | }); 19 | }); 20 | } 21 | 22 | app.value('uiMapConfig', {}).directive('uiMap', 23 | ['uiMapConfig', '$parse', function (uiMapConfig, $parse) { 24 | 25 | var mapEvents = 'bounds_changed center_changed click dblclick drag dragend ' + 26 | 'dragstart heading_changed idle maptypeid_changed mousemove mouseout ' + 27 | 'mouseover projection_changed resize rightclick tilesloaded tilt_changed ' + 28 | 'zoom_changed'; 29 | var options = uiMapConfig || {}; 30 | 31 | return { 32 | restrict: 'A', 33 | //doesn't work as E for unknown reason 34 | link: function (scope, elm, attrs) { 35 | var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions)); 36 | var map = new window.google.maps.Map(elm[0], opts); 37 | var model = $parse(attrs.uiMap); 38 | 39 | //Set scope variable for the map 40 | model.assign(scope, map); 41 | 42 | bindMapEvents(scope, mapEvents, map, elm); 43 | } 44 | }; 45 | }]); 46 | 47 | app.value('uiMapInfoWindowConfig', {}).directive('uiMapInfoWindow', 48 | ['uiMapInfoWindowConfig', '$parse', '$compile', function (uiMapInfoWindowConfig, $parse, $compile) { 49 | 50 | var infoWindowEvents = 'closeclick content_change domready ' + 51 | 'position_changed zindex_changed'; 52 | var options = uiMapInfoWindowConfig || {}; 53 | 54 | return { 55 | link: function (scope, elm, attrs) { 56 | var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions)); 57 | opts.content = elm[0]; 58 | var model = $parse(attrs.uiMapInfoWindow); 59 | var infoWindow = model(scope); 60 | 61 | if (!infoWindow) { 62 | infoWindow = new window.google.maps.InfoWindow(opts); 63 | model.assign(scope, infoWindow); 64 | } 65 | 66 | bindMapEvents(scope, infoWindowEvents, infoWindow, elm); 67 | 68 | /* The info window's contents dont' need to be on the dom anymore, 69 | google maps has them stored. So we just replace the infowindow element 70 | with an empty div. (we don't just straight remove it from the dom because 71 | straight removing things from the dom can mess up angular) */ 72 | elm.replaceWith('
'); 73 | 74 | //Decorate infoWindow.open to $compile contents before opening 75 | var _open = infoWindow.open; 76 | infoWindow.open = function open(a1, a2, a3, a4, a5, a6) { 77 | $compile(elm.contents())(scope); 78 | _open.call(infoWindow, a1, a2, a3, a4, a5, a6); 79 | }; 80 | } 81 | }; 82 | }]); 83 | 84 | /* 85 | * Map overlay directives all work the same. Take map marker for example 86 | * will $watch 'myMarker' and each time it changes, 87 | * it will hook up myMarker's events to the directive dom element. Then 88 | * ui-event will be able to catch all of myMarker's events. Super simple. 89 | */ 90 | function mapOverlayDirective(directiveName, events) { 91 | app.directive(directiveName, [function () { 92 | return { 93 | restrict: 'A', 94 | link: function (scope, elm, attrs) { 95 | scope.$watch(attrs[directiveName], function (newObject) { 96 | if (newObject) { 97 | bindMapEvents(scope, events, newObject, elm); 98 | } 99 | }); 100 | } 101 | }; 102 | }]); 103 | } 104 | 105 | mapOverlayDirective('uiMapMarker', 106 | 'animation_changed click clickable_changed cursor_changed ' + 107 | 'dblclick drag dragend draggable_changed dragstart flat_changed icon_changed ' + 108 | 'mousedown mouseout mouseover mouseup position_changed rightclick ' + 109 | 'shadow_changed shape_changed title_changed visible_changed zindex_changed'); 110 | 111 | mapOverlayDirective('uiMapPolyline', 112 | 'click dblclick mousedown mousemove mouseout mouseover mouseup rightclick'); 113 | 114 | mapOverlayDirective('uiMapPolygon', 115 | 'click dblclick mousedown mousemove mouseout mouseover mouseup rightclick'); 116 | 117 | mapOverlayDirective('uiMapRectangle', 118 | 'bounds_changed click dblclick mousedown mousemove mouseout mouseover ' + 119 | 'mouseup rightclick'); 120 | 121 | mapOverlayDirective('uiMapCircle', 122 | 'center_changed click dblclick mousedown mousemove ' + 123 | 'mouseout mouseover mouseup radius_changed rightclick'); 124 | 125 | mapOverlayDirective('uiMapGroundOverlay', 126 | 'click dblclick'); 127 | 128 | })(); 129 | -------------------------------------------------------------------------------- /test/googlemaps.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | function getScript(src) { 3 | document.write('<' + 'script src="' + src + '"' + 4 | ' type="text/javascript"><' + '/script>'); 5 | } 6 | 7 | getScript("http://maps.googleapis.com/maps/api/js?sensor=false"); 8 | })(); -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Sat Dec 28 2013 18:07:39 GMT+0100 (CET) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path, that will be used to resolve files and exclude 8 | basePath: '..', 9 | 10 | 11 | // frameworks to use 12 | frameworks: ['jasmine'], 13 | 14 | 15 | // list of files / patterns to load in the browser 16 | files: [ 17 | 'bower_components/angular/angular.js', 18 | 'bower_components/angular-mocks/angular-mocks.js', 19 | 'bower_components/angular-ui-event/dist/event.min.js', 20 | 'src/*', 21 | 'test/googlemaps.js', 22 | 'test/*Spec.js' 23 | ], 24 | 25 | 26 | // list of files to exclude 27 | exclude: [ 28 | 29 | ], 30 | 31 | 32 | // test results reporter to use 33 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 34 | reporters: ['progress'], 35 | 36 | 37 | // web server port 38 | port: 9876, 39 | 40 | 41 | // enable / disable colors in the output (reporters and logs) 42 | colors: true, 43 | 44 | 45 | // level of logging 46 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 47 | logLevel: config.LOG_INFO, 48 | 49 | 50 | // enable / disable watching file and executing tests whenever any file changes 51 | autoWatch: true, 52 | 53 | 54 | // Start these browsers, currently available: 55 | // - Chrome 56 | // - ChromeCanary 57 | // - Firefox 58 | // - Opera (has to be installed with `npm install karma-opera-launcher`) 59 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) 60 | // - PhantomJS 61 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) 62 | browsers: ['Chrome', 'Firefox', 'PhantomJS'], 63 | 64 | 65 | // If browser does not capture in given timeout [ms], kill it 66 | captureTimeout: 60000, 67 | 68 | 69 | // Continuous Integration mode 70 | // if true, it capture browsers, run tests and exit 71 | singleRun: false 72 | }); 73 | }; 74 | -------------------------------------------------------------------------------- /test/mapSpec.js: -------------------------------------------------------------------------------- 1 | describe('uiMap', function () { 2 | var scope, $rootScope, $compile; 3 | 4 | beforeEach(module('ui.map')); 5 | beforeEach(inject(function (_$compile_, _$rootScope_) { 6 | $rootScope = _$rootScope_; 7 | $compile = _$compile_; 8 | })); 9 | 10 | function createMap(options, events) { 11 | scope.gmapOptions = options || {}; 12 | scope.gmapEvents = events || {}; 13 | $compile("
")(scope); 15 | } 16 | 17 | function createWindow(options, events, inner) { 18 | scope.gOptions = options || {}; 19 | scope.gEvents = events || {}; 20 | var elm = angular.element("
"); 22 | if (inner){ 23 | elm.children().append(inner); 24 | } 25 | $compile(elm)(scope); 26 | } 27 | 28 | describe('test', function () { 29 | beforeEach(function () { 30 | scope = $rootScope.$new(); 31 | }); 32 | 33 | it('should bind google map object to scope', function () { 34 | createMap(); 35 | expect(scope.gmap).toBeTruthy(); 36 | }); 37 | 38 | it('should create google map with given options', function () { 39 | var center = new google.maps.LatLng(40, 40); 40 | createMap({center: center}); 41 | expect(scope.gmap.getCenter()).toBe(center); 42 | }); 43 | 44 | it('should pass events to the element as "map-eventname"', function () { 45 | scope.zoomy = false; 46 | scope.county = 0; 47 | createMap({}, { 48 | 'map-zoom_changed': 'zoomy = true', 49 | 'map-dblclick map-dragend': 'county = county + 1' 50 | }); 51 | google.maps.event.trigger(scope.gmap, 'zoom_changed'); 52 | expect(scope.zoomy).toBeTruthy(); 53 | google.maps.event.trigger(scope.gmap, 'dblclick'); 54 | expect(scope.county).toBe(1); 55 | google.maps.event.trigger(scope.gmap, 'dragend'); 56 | expect(scope.county).toBe(2); 57 | }); 58 | }); 59 | 60 | describe('test infoWindow', function () { 61 | beforeEach(function () { 62 | scope = $rootScope.$new(); 63 | }); 64 | 65 | it('should bind info window to scope', function () { 66 | createWindow(); 67 | expect(scope.ginfo).toBeTruthy(); 68 | }); 69 | 70 | it('should create info window with given options & content', function () { 71 | var content = angular.element('

Hi

'); 72 | createWindow({ zIndex: 5 }, {}, content); 73 | expect(scope.ginfo.getZIndex()).toBe(5); 74 | expect(scope.ginfo.getContent().innerHTML) 75 | .toBe(angular.element('
').append(content).html()); 76 | }); 77 | 78 | it('should $compile content and recognize scope changes', function () { 79 | var inner = angular.element(''); 80 | createWindow({}, {}, inner); 81 | createMap(); 82 | scope.$apply(function () { 83 | scope.myVal = 'initial'; 84 | }); 85 | scope.ginfo.open(scope.gmap, scope.gmap.getCenter()); 86 | expect(inner.val()).toBe('initial'); 87 | scope.$apply(function () { 88 | scope.myVal = 'final'; 89 | }); 90 | expect(inner.val()).toBe('final'); 91 | }); 92 | 93 | /* 94 | FAIL ON Firefox 21.0 (Linux) => Expected undefined to be true. 95 | 96 | it('should recognize infowindow events in ui-event as "map-eventname"', function () { 97 | expect(scope.closed).toBeUndefined(); 98 | createWindow({}, { 99 | 'map-closeclick': 'closed = true' 100 | }); 101 | createMap(); 102 | google.maps.event.trigger(scope.ginfo, 'closeclick'); 103 | expect(scope.closed).toBe(true); 104 | }); 105 | */ 106 | }); 107 | 108 | }); --------------------------------------------------------------------------------