123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>JSDoc: Source: services/attr2_options.js</title>
- <script src="scripts/prettify/prettify.js"> </script>
- <script src="scripts/prettify/lang-css.js"> </script>
- <!--[if lt IE 9]>
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
- <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
- <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
- </head>
- <body>
- <div id="main">
- <h1 class="page-title">Source: services/attr2_options.js</h1>
-
-
- <section>
- <article>
- <pre class="prettyprint source linenums"><code>/**
- * @ngdoc service
- * @name Attr2Options
- * @description
- * Converts tag attributes to options used by google api v3 objects, map, marker, polygon, circle, etc.
- */
- /*jshint -W030*/
- ngMap.service('Attr2Options', ['$parse', 'NavigatorGeolocation', 'GeoCoder', function($parse, NavigatorGeolocation, GeoCoder) {
- var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
- var MOZ_HACK_REGEXP = /^moz([A-Z])/;
- var orgAttributes = function(el) {
- (el.length > 0) && (el = el[0]);
- var orgAttributes = {};
- for (var i=0; i<el.attributes.length; i++) {
- var attr = el.attributes[i];
- orgAttributes[attr.name] = attr.value;
- }
- return orgAttributes;
- }
- var camelCase = function(name) {
- return name.
- replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
- return offset ? letter.toUpperCase() : letter;
- }).
- replace(MOZ_HACK_REGEXP, 'Moz$1');
- }
- var JSONize = function(str) {
- try { // if parsable already, return as it is
- JSON.parse(str);
- return str;
- } catch(e) { // if not parsable, change little
- return str
- // wrap keys without quote with valid double quote
- .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":'})
- // replacing single quote wrapped ones to double quote
- .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"'})
- }
- }
- var toOptionValue = function(input, options) {
- var output, key=options.key, scope=options.scope;
- try { // 1. Number?
- var num = Number(input);
- if (isNaN(num)) {
- throw "Not a number";
- } else {
- output = num;
- }
- } catch(err) {
- try { // 2.JSON?
- if (input.match(/^[\+\-]?[0-9\.]+,[ ]*\ ?[\+\-]?[0-9\.]+$/)) { // i.e "-1.0, 89.89"
- input = "["+input+"]";
- }
- output = JSON.parse(JSONize(input));
- if (output instanceof Array) {
- var t1stEl = output[0];
- if (t1stEl.constructor == Object) { // [{a:1}] : not lat/lng ones
- } else if (t1stEl.constructor == Array) { // [[1,2],[3,4]]
- output = output.map(function(el) {
- return new google.maps.LatLng(el[0], el[1]);
- });
- } else if(!isNaN(parseFloat(t1stEl)) && isFinite(t1stEl)) {
- return new google.maps.LatLng(output[0], output[1]);
- }
- }
- } catch(err2) {
- // 3. Object Expression. i.e. LatLng(80,-49)
- if (input.match(/^[A-Z][a-zA-Z0-9]+\(.*\)$/)) {
- try {
- var exp = "new google.maps."+input;
- output = eval(exp); // TODO, still eval
- } catch(e) {
- output = input;
- }
- // 4. Object Expression. i.e. MayTypeId.HYBRID
- } else if (input.match(/^([A-Z][a-zA-Z0-9]+)\.([A-Z]+)$/)) {
- try {
- var matches = input.match(/^([A-Z][a-zA-Z0-9]+)\.([A-Z]+)$/);
- output = google.maps[matches[1]][matches[2]];
- } catch(e) {
- output = input;
- }
- // 5. Object Expression. i.e. HYBRID
- } else if (input.match(/^[A-Z]+$/)) {
- try {
- var capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
- if (key.match(/temperatureUnit|windSpeedUnit|labelColor/)) {
- capitalizedKey = capitalizedKey.replace(/s$/,"");
- output = google.maps.weather[capitalizedKey][input];
- } else {
- output = google.maps[capitalizedKey][input];
- }
- } catch(e) {
- output = input;
- }
- } else {
- output = input;
- }
- } // catch(err2)
- } // catch(err)
- return output;
- };
- var setDelayedGeoLocation = function(object, method, param, options) {
- options = options || {};
- var centered = object.centered || options.centered;
- var errorFunc = function() {
- console.log('error occurred while', object, method, param, options);
- var fallbackLocation = options.fallbackLocation || new google.maps.LatLng(0,0);
- object[method](fallbackLocation);
- };
- if (!param || param.match(/^current/i)) { // sensored position
- NavigatorGeolocation.getCurrentPosition().then(
- function(position) { // success
- var lat = position.coords.latitude;
- var lng = position.coords.longitude;
- var latLng = new google.maps.LatLng(lat,lng);
- object[method](latLng);
- if (centered) {
- object.map.setCenter(latLng);
- }
- options.callback && options.callback.apply(object);
- },
- errorFunc
- );
- } else { //assuming it is address
- GeoCoder.geocode({address: param}).then(
- function(results) { // success
- object[method](results[0].geometry.location);
- if (centered) {
- object.map.setCenter(results[0].geometry.location);
- }
- },
- errorFunc
- );
- }
- };
- var getAttrsToObserve = function(attrs) {
- var attrsToObserve = [];
- if (attrs["ng-repeat"] || attrs.ngRepeat) { // if element is created by ng-repeat, don't observe any
- } else {
- for (var attrName in attrs) {
- var attrValue = attrs[attrName];
- if (attrValue && attrValue.match(/\{\{.*\}\}/)) { // if attr value is {{..}}
- console.log('setting attribute to observe', attrName, camelCase(attrName), attrValue);
- attrsToObserve.push(camelCase(attrName));
- }
- }
- }
- return attrsToObserve;
- };
- var observeAttrSetObj = function(orgAttrs, attrs, obj) {
- var attrsToObserve = getAttrsToObserve(orgAttrs);
- if (Object.keys(attrsToObserve).length) {
- console.log(obj, "attributes to observe", attrsToObserve);
- }
- for (var i=0; i<attrsToObserve.length; i++) {
- observeAndSet(attrs, attrsToObserve[i], obj);
- }
- }
- var observeAndSet = function(attrs, attrName, object) {
- attrs.$observe(attrName, function(val) {
- if (val) {
- console.log('observing ', object, attrName, val);
- var setMethod = camelCase('set-'+attrName);
- var optionValue = toOptionValue(val, {key: attrName});
- console.log('setting ', object, attrName, 'with value', optionValue);
- if (object[setMethod]) { //if set method does exist
- /* if an location is being observed */
- if (attrName.match(/center|position/) &&
- typeof optionValue == 'string') {
- setDelayedGeoLocation(object, setMethod, optionValue);
- } else {
- object[setMethod](optionValue);
- }
- }
- }
- });
- };
- return {
- /**
- * filters attributes by skipping angularjs methods $.. $$..
- * @memberof Attr2Options
- * @param {Hash} attrs tag attributes
- * @returns {Hash} filterd attributes
- */
- filter: function(attrs) {
- var options = {};
- for(var key in attrs) {
- if (key.match(/^\$/) || key.match(/^ng[A-Z]/)) {
- } else {
- options[key] = attrs[key];
- }
- }
- return options;
- },
- /**
- * converts attributes hash to Google Maps API v3 options
- * ```
- * . converts numbers to number
- * . converts class-like string to google maps instance
- * i.e. `LatLng(1,1)` to `new google.maps.LatLng(1,1)`
- * . converts constant-like string to google maps constant
- * i.e. `MapTypeId.HYBRID` to `google.maps.MapTypeId.HYBRID`
- * i.e. `HYBRID"` to `google.maps.MapTypeId.HYBRID`
- * ```
- * @memberof Attr2Options
- * @param {Hash} attrs tag attributes
- * @param {scope} scope angularjs scope
- * @returns {Hash} options converted attributess
- */
- getOptions: function(attrs, scope) {
- var options = {};
- for(var key in attrs) {
- if (attrs[key]) {
- if (key.match(/^on[A-Z]/)) { //skip events, i.e. on-click
- continue;
- } else if (key.match(/ControlOptions$/)) { // skip controlOptions
- continue;
- } else {
- options[key] = toOptionValue(attrs[key], {scope:scope, key: key});
- }
- } // if (attrs[key])
- } // for(var key in attrs)
- return options;
- },
- /**
- * converts attributes hash to scope-specific event function
- * @memberof Attr2Options
- * @param {scope} scope angularjs scope
- * @param {Hash} attrs tag attributes
- * @returns {Hash} events converted events
- */
- getEvents: function(scope, attrs) {
- var events = {};
- var toLowercaseFunc = function($1){
- return "_"+$1.toLowerCase();
- };
- var eventFunc = function(attrValue) {
- var matches = attrValue.match(/([^\(]+)\(([^\)]*)\)/);
- var funcName = matches[1];
- var argsStr = matches[2].replace(/event[ ,]*/,''); //remove string 'event'
-
- var args = scope.$eval("["+argsStr+"]");
- return function(event) {
- function index(obj,i) {return obj[i]}
- f = funcName.split('.').reduce(index, scope)
- f.apply(this, [event].concat(args));
- scope.$apply();
- }
- }
- for(var key in attrs) {
- if (attrs[key]) {
- if (!key.match(/^on[A-Z]/)) { //skip if not events
- continue;
- }
-
- //get event name as underscored. i.e. zoom_changed
- var eventName = key.replace(/^on/,'');
- eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);
- eventName = eventName.replace(/([A-Z])/g, toLowercaseFunc);
- var attrValue = attrs[key];
- events[eventName] = new eventFunc(attrValue);
- }
- }
- return events;
- },
- /**
- * control means map controls, i.e streetview, pan, etc, not a general control
- * @memberof Attr2Options
- * @param {Hash} filtered filtered tag attributes
- * @returns {Hash} Google Map options
- */
- getControlOptions: function(filtered) {
- var controlOptions = {};
- if (typeof filtered != 'object')
- return false;
- for (var attr in filtered) {
- if (filtered[attr]) {
- if (!attr.match(/(.*)ControlOptions$/)) {
- continue; // if not controlOptions, skip it
- }
- //change invalid json to valid one, i.e. {foo:1} to {"foo": 1}
- var orgValue = filtered[attr];
- var newValue = orgValue.replace(/'/g, '"');
- newValue = newValue.replace(/([^"]+)|("[^"]+")/g, function($0, $1, $2) {
- if ($1) {
- return $1.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
- } else {
- return $2;
- }
- });
- try {
- var options = JSON.parse(newValue);
- for (var key in options) { //assign the right values
- if (options[key]) {
- var value = options[key];
- if (typeof value === 'string') {
- value = value.toUpperCase();
- } else if (key === "mapTypeIds") {
- value = value.map( function(str) {
- if (str.match(/^[A-Z]+$/)) { // if constant
- return google.maps.MapTypeId[str.toUpperCase()];
- } else { // else, custom map-type
- return str;
- }
- });
- }
-
- if (key === "style") {
- var str = attr.charAt(0).toUpperCase() + attr.slice(1);
- var objName = str.replace(/Options$/,'')+"Style";
- options[key] = google.maps[objName][value];
- } else if (key === "position") {
- options[key] = google.maps.ControlPosition[value];
- } else {
- options[key] = value;
- }
- }
- }
- controlOptions[attr] = options;
- } catch (e) {
- console.error('invald option for', attr, newValue, e, e.stack);
- }
- }
- } // for
- return controlOptions;
- }, // function
- toOptionValue: toOptionValue,
- camelCase: camelCase,
- setDelayedGeoLocation: setDelayedGeoLocation,
- getAttrsToObserve: getAttrsToObserve,
- observeAndSet: observeAndSet,
- observeAttrSetObj: observeAttrSetObj,
- orgAttributes: orgAttributes
- }; // return
- }]);
- </code></pre>
- </article>
- </section>
- </div>
- <nav>
- <h2><a href="index.html">Index</a></h2><h3>service</h3><ul><li><a href="Attr2Options.html">Attr2Options</a></li><li><a href="GeoCoder.html">GeoCoder</a></li><li><a href="NavigatorGeolocation.html">NavigatorGeolocation</a></li><li><a href="StreetView.html">StreetView</a></li></ul><h3>directive</h3><ul><li><a href="bicycling-layer.html">bicycling-layer</a></li><li><a href="cloud-layer.html">cloud-layer</a></li><li><a href="custom-control.html">custom-control</a></li><li><a href="drawing-manager.html">drawing-manager</a></li><li><a href="dynamic-maps-engine-layer.html">dynamic-maps-engine-layer</a></li><li><a href="fusion-tables-layer.html">fusion-tables-layer</a></li><li><a href="heatmap-layer.html">heatmap-layer</a></li><li><a href="info-window.html">info-window</a></li><li><a href="kml-layer.html">kml-layer</a></li><li><a href="lazy-load.html">lazy-load</a></li><li><a href="map.html">map</a></li><li><a href="map-data.html">map-data</a></li><li><a href="map-type.html">map-type</a></li><li><a href="MapController.html">MapController</a></li><li><a href="maps-engine-layer.html">maps-engine-layer</a></li><li><a href="marker.html">marker</a></li><li><a href="overlay-map-type.html">overlay-map-type</a></li><li><a href="shape.html">shape</a></li><li><a href="traffic-layer.html">traffic-layer</a></li><li><a href="transit-layer.html">transit-layer</a></li><li><a href="weather-layer.html">weather-layer</a></li></ul>
- </nav>
- <br clear="both">
- <footer>
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha9</a>
- and <a href="https://github.com/allenhwkim/angular-jsdoc">angular-jsdoc</a>
- </footer>
- <script> prettyPrint(); </script>
- <script src="scripts/linenumber.js"> </script>
- <script>
- var href=window.location.href.match(/\/([^\/]+$)/)[1];
- document.querySelector("nav a[href='"+href+"']").scrollIntoView(true);
- if (window.location.hash == "")
- document.querySelector("body").scrollIntoView(true);
- </script>
- </body>
- </html>
|