@@ -33,10 +33,12 @@ angular.module('ngMap', []);
33
33
var Attr2MapOptions ;
34
34
35
35
var __MapController = function (
36
- $scope , $element , $attrs , $parse , _Attr2MapOptions_ , NgMap , NgMapPool
36
+ $scope , $element , $attrs , $parse , $interpolate , _Attr2MapOptions_ , NgMap , NgMapPool , escapeRegExp
37
37
) {
38
38
Attr2MapOptions = _Attr2MapOptions_ ;
39
39
var vm = this ;
40
+ var exprStartSymbol = $interpolate . startSymbol ( ) ;
41
+ var exprEndSymbol = $interpolate . endSymbol ( ) ;
40
42
41
43
vm . mapOptions ; /** @memberof __MapController */
42
44
vm . mapEvents ; /** @memberof __MapController */
@@ -196,8 +198,10 @@ angular.module('ngMap', []);
196
198
// set options
197
199
mapOptions . zoom = mapOptions . zoom || 15 ;
198
200
var center = mapOptions . center ;
201
+ var exprRegExp = new RegExp ( escapeRegExp ( exprStartSymbol ) + '.*' + escapeRegExp ( exprEndSymbol ) ) ;
202
+
199
203
if ( ! mapOptions . center ||
200
- ( ( typeof center === 'string' ) && center . match ( / \{ \{ . * \} \} / ) )
204
+ ( ( typeof center === 'string' ) && center . match ( exprRegExp ) )
201
205
) {
202
206
mapOptions . center = new google . maps . LatLng ( 0 , 0 ) ;
203
207
} else if ( ( typeof center === 'string' ) && center . match ( / [ 0 - 9 . - ] * , [ 0 - 9 . - ] * / ) ) {
@@ -245,14 +249,14 @@ angular.module('ngMap', []);
245
249
$parse ( $attrs . mapInitialized ) ( $scope , { map : vm . map } ) ;
246
250
}
247
251
} ) ;
248
-
252
+
249
253
//add maximum zoom listeners if zoom-to-include-markers and and maximum-zoom are valid attributes
250
254
if ( mapOptions . zoomToIncludeMarkers && mapOptions . maximumZoom ) {
251
255
google . maps . event . addListener ( vm . map , 'zoom_changed' , function ( ) {
252
256
if ( vm . enableMaximumZoomCheck == true ) {
253
257
vm . enableMaximumZoomCheck = false ;
254
- google . maps . event . addListenerOnce ( vm . map , 'bounds_changed' , function ( ) {
255
- vm . map . setZoom ( Math . min ( mapOptions . maximumZoom , vm . map . getZoom ( ) ) ) ;
258
+ google . maps . event . addListenerOnce ( vm . map , 'bounds_changed' , function ( ) {
259
+ vm . map . setZoom ( Math . min ( mapOptions . maximumZoom , vm . map . getZoom ( ) ) ) ;
256
260
} ) ;
257
261
}
258
262
} ) ;
@@ -279,11 +283,11 @@ angular.module('ngMap', []);
279
283
280
284
if ( options . lazyInit ) { // allows controlled initialization
281
285
// parse angular expression for dynamic ids
282
- if ( ! ! $attrs . id &&
286
+ if ( ! ! $attrs . id &&
283
287
// starts with, at position 0
284
- $attrs . id . indexOf ( "{{" , 0 ) === 0 &&
288
+ $attrs . id . indexOf ( exprStartSymbol , 0 ) === 0 &&
285
289
// ends with
286
- $attrs . id . indexOf ( "}}" , $attrs . id . length - "}}" . length ) !== - 1 ) {
290
+ $attrs . id . indexOf ( exprEndSymbol , $attrs . id . length - exprEndSymbol . length ) !== - 1 ) {
287
291
var idExpression = $attrs . id . slice ( 2 , - 2 ) ;
288
292
var mapId = $parse ( idExpression ) ( $scope ) ;
289
293
} else {
@@ -307,7 +311,7 @@ angular.module('ngMap', []);
307
311
} ; // __MapController
308
312
309
313
__MapController . $inject = [
310
- '$scope' , '$element' , '$attrs' , '$parse' , 'Attr2MapOptions' , 'NgMap' , 'NgMapPool'
314
+ '$scope' , '$element' , '$attrs' , '$parse' , '$interpolate' , ' Attr2MapOptions', 'NgMap' , 'NgMapPool' , 'escapeRegexpFilter '
311
315
] ;
312
316
angular . module ( 'ngMap' ) . controller ( '__MapController' , __MapController ) ;
313
317
} ) ( ) ;
@@ -522,7 +526,7 @@ angular.module('ngMap', []);
522
526
_this . el . style . top = y + "px" ;
523
527
_this . el . style . visibility = "visible" ;
524
528
} ;
525
- if ( _this . el . offsetWidth && _this . el . offsetHeight ) {
529
+ if ( _this . el . offsetWidth && _this . el . offsetHeight ) {
526
530
setPosition ( ) ;
527
531
} else {
528
532
//delayed left/top calculation when width/height are not set instantly
@@ -634,29 +638,33 @@ angular.module('ngMap', []);
634
638
635
639
636
640
var customMarkerDirective = function (
637
- _$timeout_ , _$compile_ , Attr2MapOptions , _NgMap_
641
+ _$timeout_ , _$compile_ , $interpolate , Attr2MapOptions , _NgMap_ , escapeRegExp
638
642
) {
639
643
parser = Attr2MapOptions ;
640
644
$timeout = _$timeout_ ;
641
645
$compile = _$compile_ ;
642
646
NgMap = _NgMap_ ;
643
647
648
+ var exprStartSymbol = $interpolate . startSymbol ( ) ;
649
+ var exprEndSymbol = $interpolate . endSymbol ( ) ;
650
+ var exprRegExp = new RegExp ( escapeRegExp ( exprStartSymbol ) + '([^' + exprEndSymbol . substring ( 0 , 1 ) + ']+)' + escapeRegExp ( exprEndSymbol ) , 'g' ) ;
651
+
644
652
return {
645
653
restrict : 'E' ,
646
654
require : [ '?^map' , '?^ngMap' ] ,
647
655
compile : function ( element ) {
648
656
setCustomMarker ( ) ;
649
657
element [ 0 ] . style . display = 'none' ;
650
658
var orgHtml = element . html ( ) ;
651
- var matches = orgHtml . match ( / { { ( [ ^ } ] + ) } } / g ) ;
659
+ var matches = orgHtml . match ( exprRegExp ) ;
652
660
var varsToWatch = [ ] ;
653
661
//filter out that contains '::', 'this.'
654
662
( matches || [ ] ) . forEach ( function ( match ) {
655
- var toWatch = match . replace ( '{{' , '' ) . replace ( '}}' , '' ) ;
663
+ var toWatch = match . replace ( exprStartSymbol , '' ) . replace ( exprEndSymbol , '' ) ;
656
664
if ( match . indexOf ( '::' ) == - 1 &&
657
665
match . indexOf ( 'this.' ) == - 1 &&
658
666
varsToWatch . indexOf ( toWatch ) == - 1 ) {
659
- varsToWatch . push ( match . replace ( '{{' , '' ) . replace ( '}}' , '' ) ) ;
667
+ varsToWatch . push ( match . replace ( exprStartSymbol , '' ) . replace ( exprEndSymbol , '' ) ) ;
660
668
}
661
669
} ) ;
662
670
@@ -665,7 +673,7 @@ angular.module('ngMap', []);
665
673
} ; // return
666
674
} ; // function
667
675
customMarkerDirective . $inject =
668
- [ '$timeout' , '$compile' , 'Attr2MapOptions' , 'NgMap' ] ;
676
+ [ '$timeout' , '$compile' , '$interpolate' , ' Attr2MapOptions', 'NgMap' , 'escapeRegexpFilter '] ;
669
677
670
678
angular . module ( 'ngMap' ) . directive ( 'customMarker' , customMarkerDirective ) ;
671
679
} ) ( ) ;
@@ -2317,6 +2325,26 @@ angular.module('ngMap', []);
2317
2325
angular . module ( 'ngMap' ) . filter ( 'camelCase' , camelCaseFilter ) ;
2318
2326
} ) ( ) ;
2319
2327
2328
+ /**
2329
+ * @ngdoc filter
2330
+ * @name escape-regex
2331
+ * @description
2332
+ * Escapes all regex special characters in a string
2333
+ */
2334
+ ( function ( ) {
2335
+ 'use strict' ;
2336
+
2337
+
2338
+
2339
+ var escapeRegexpFilter = function ( ) {
2340
+ return function ( string ) {
2341
+ return string . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ; // $& means the whole matched string
2342
+ } ;
2343
+ } ;
2344
+
2345
+ angular . module ( 'ngMap' ) . filter ( 'escapeRegexp' , escapeRegexpFilter ) ;
2346
+ } ) ( ) ;
2347
+
2320
2348
/**
2321
2349
* @ngdoc filter
2322
2350
* @name jsonize
@@ -2367,10 +2395,13 @@ angular.module('ngMap', []);
2367
2395
/ ^ ( \d { 4 } \- \d \d \- \d \d ( [ t T ] [ \d : \. ] * ) ? ) ( [ z Z ] | ( [ + \- ] ) ( \d \d ) : ? ( \d \d ) ) ? $ / ;
2368
2396
2369
2397
var Attr2MapOptions = function (
2370
- $parse , $timeout , $log , NavigatorGeolocation , GeoCoder ,
2371
- camelCaseFilter , jsonizeFilter
2398
+ $parse , $timeout , $log , $interpolate , NavigatorGeolocation , GeoCoder ,
2399
+ camelCaseFilter , jsonizeFilter , escapeRegExp
2372
2400
) {
2373
2401
2402
+ var exprStartSymbol = $interpolate . startSymbol ( ) ;
2403
+ var exprEndSymbol = $interpolate . endSymbol ( ) ;
2404
+
2374
2405
/**
2375
2406
* Returns the attributes of an element as hash
2376
2407
* @memberof Attr2MapOptions
@@ -2468,9 +2499,9 @@ angular.module('ngMap', []);
2468
2499
output = input ;
2469
2500
}
2470
2501
// 7. evaluate dynamically bound values
2471
- } else if ( input . match ( / ^ { / ) && options . scope ) {
2502
+ } else if ( input . match ( new RegExp ( '^' + escapeRegExp ( exprStartSymbol ) ) ) && options . scope ) {
2472
2503
try {
2473
- var expr = input . replace ( / { { / , '' ) . replace ( / } } / g , '' ) ;
2504
+ var expr = input . replace ( new RegExp ( escapeRegExp ( exprStartSymbol ) ) , '' ) . replace ( new RegExp ( escapeRegExp ( exprEndSymbol ) , 'g' ) , '' ) ;
2474
2505
output = options . scope . $eval ( expr ) ;
2475
2506
} catch ( err ) {
2476
2507
output = input ;
@@ -2525,11 +2556,12 @@ angular.module('ngMap', []);
2525
2556
2526
2557
var getAttrsToObserve = function ( attrs ) {
2527
2558
var attrsToObserve = [ ] ;
2559
+ var exprRegExp = new RegExp ( escapeRegExp ( exprStartSymbol ) + '.*' + escapeRegExp ( exprEndSymbol ) , 'g' ) ;
2528
2560
2529
2561
if ( ! attrs . noWatcher ) {
2530
2562
for ( var attrName in attrs ) { //jshint ignore:line
2531
2563
var attrValue = attrs [ attrName ] ;
2532
- if ( attrValue && attrValue . match ( / \{ \{ . * \} \} / ) ) { // if attr value is {{..}}
2564
+ if ( attrValue && attrValue . match ( exprRegExp ) ) { // if attr value is {{..}}
2533
2565
attrsToObserve . push ( camelCaseFilter ( attrName ) ) ;
2534
2566
}
2535
2567
}
@@ -2601,7 +2633,7 @@ angular.module('ngMap', []);
2601
2633
} ;
2602
2634
2603
2635
/**
2604
- * converts attributes hash to scope-specific event function
2636
+ * converts attributes hash to scope-specific event function
2605
2637
* @memberof Attr2MapOptions
2606
2638
* @param {scope } scope angularjs scope
2607
2639
* @param {Hash } attrs tag attributes
@@ -2725,8 +2757,8 @@ angular.module('ngMap', []);
2725
2757
2726
2758
} ;
2727
2759
Attr2MapOptions . $inject = [
2728
- '$parse' , '$timeout' , '$log' , 'NavigatorGeolocation' , 'GeoCoder' ,
2729
- 'camelCaseFilter' , 'jsonizeFilter'
2760
+ '$parse' , '$timeout' , '$log' , '$interpolate' , ' NavigatorGeolocation', 'GeoCoder' ,
2761
+ 'camelCaseFilter' , 'jsonizeFilter' , 'escapeRegexpFilter'
2730
2762
] ;
2731
2763
2732
2764
angular . module ( 'ngMap' ) . service ( 'Attr2MapOptions' , Attr2MapOptions ) ;
0 commit comments