PageSourceSearch

https://discours.netlify.app/node_modules/angular-ymaps/angular-ymaps.js

js discours.netlify.app collected 2026-10-03 10:39:44 UTC 8,132 bytes, 231 lines download raw bytes

1/*global angular*/
2angular.module('ymaps', [])
3.factory('$script', ['$q', '$rootScope', function ($q, $rootScope) {
4    "use strict";
5    //классический кроссбраузерный способ подключить внешний скрипт
6    function loadScript(path, callback) {
7        var el = document.createElement("script");
8        el.onload = el.onreadystatechange = function () {
9            if (el.readyState && el.readyState !== "complete" &&
10                el.readyState !== "loaded") {
11                return;
12            }
13            // если все загрузилось, то снимаем обработчик и выбрасываем callback
14            el.onload = el.onreadystatechange = null;
15            if(angular.isFunction(callback)) {
16                callback();
17            }
18        };
19        el.async = true;
20        el.src = path;
21        document.getElementsByTagName('body')[0].appendChild(el);
22    }
23    var loadHistory = [], //кэш загруженных файлов
24        pendingPromises = {}; //обещания на текущие загруки
25    return function(url) {
26        var deferred = $q.defer();
27        if(loadHistory.indexOf(url) !== -1) {
28            deferred.resolve();
29        }
30        else if(pendingPromises[url]) {
31            return pendingPromises[url];
32        } else {
33            loadScript(url, function() {
34                delete pendingPromises[url];
35                loadHistory.push(url);
36                //обязательно использовать `$apply`, чтобы сообщить
37                //angular о том, что что-то произошло
38                $rootScope.$apply(function() {
39                    deferred.resolve();
40                });
41            });
42            pendingPromises[url] = deferred.promise;
43        }
44        return deferred.promise;
45    };
46}])
47.factory('ymapsLoader', ['$window', '$timeout', '$script', 'ymapsConfig', function($window, $timeout, $script, ymapsConfig) {
48    "use strict";
49    var scriptPromise;
50    return {
51        ready: function(callback) {
52            if(!scriptPromise) {
53                scriptPromise = $script(ymapsConfig.apiUrl).then(function() {
54                    return $window.ymaps;
55                });
56            }
57            scriptPromise.then(function(ymaps) {
58                ymaps.ready(function() {
59                    $timeout(function() {callback(ymaps);});
60                });
61            });
62        }
63    };
64}])
65.constant('ymapsConfig', {
66    apiUrl: '//api-maps.yandex.ru/2.1/?load=package.standard,package.clusters&mode=release&lang=ru-RU&ns=ymaps',
67    mapBehaviors: ['default'],
68    mapControls: ['default'],
69    markerOptions: {
70        preset: 'islands#darkgreenIcon'
71    },
72    clusterOptions: {
73      preset: 'islands#darkGreenClusterIcons'
74    },
75    fitMarkers: true,
76    fitMarkersZoomMargin: 40,
77    clusterize: false
78})
79//brought from underscore http://underscorejs.org/#debounce
80.value('debounce', function (func, wait) {
81    "use strict";
82    var timeout = null;
83    return function () {
84        var context = this, args = arguments;
85        var later = function () {
86            timeout = null;
87            func.apply(context, args);
88        };
89        clearTimeout(timeout);
90        timeout = setTimeout(later, wait);
91    };
92})
93.controller('YmapController', ['$scope', '$element', 'ymapsLoader', 'ymapsConfig', 'debounce', function ($scope, $element, ymapsLoader, config, debounce) {
94    "use strict";
95    function initAutoFit(map, collection, ymaps) {
96        collection.events.add('boundschange', debounce(function () {
97            if(collection.getLength() > 0) {
98                var maxZoomBefore = map.options.get('maxZoom');
99                map.options.set('maxZoom', $scope.zoom);
100                map.setBounds(collection.getBounds(), {
101                    checkZoomRange: true,
102                    zoomMargin: config.fitMarkersZoomMargin
103                }).then(function () {
104                  map.options.set('maxZoom', maxZoomBefore);
105                  //we need to manually update zoom, because of http://clubs.ya.ru/mapsapi/replies.xml?item_no=59735
106                  map.setZoom(map.getZoom());
107                });
108            }
109        }, 100));
110    }
111    var self = this;
112    ymapsLoader.ready(function(ymaps) {
113        self.addMarker = function(coordinates, properties, options) {
114            var placeMark = new ymaps.Placemark(coordinates, properties, options);
115            $scope.markers.add(placeMark);
116
117            return placeMark;
118        };
119        self.removeMarker = function (marker) {
120            $scope.markers.remove(marker);
121        };
122        self.map = new ymaps.Map($element[0], {
123            center   : $scope.center || [0, 0],
124            zoom     : $scope.zoom || 0,
125            behaviors: config.mapBehaviors,
126            controls: config.mapControls
127        });
128        var collection = new ymaps.GeoObjectCollection({}, config.markerOptions);
129        if(config.clusterize) {
130          $scope.markers = new ymaps.Clusterer(config.clusterOptions);
131          collection.add($scope.markers);
132        } else {
133          $scope.markers = collection;
134        }
135        self.map.geoObjects.add(collection);
136        if(config.fitMarkers) {
137            initAutoFit(self.map, collection, ymaps);
138        }
139        var updatingBounds, moving;
140       $scope.$watch('center', function(newVal) {
141            if(updatingBounds) {
142                return;
143            }
144            moving = true;
145            self.map.panTo(newVal).always(function() {
146                moving = false;
147            });
148        }, true);
149        $scope.$watch('zoom', function(zoom) {
150            if(updatingBounds) {
151               return;
152            }
153            self.map.setZoom(zoom, {checkZoomRange: true});
154        });
155        self.map.events.add('boundschange', function(event) {
156            if(moving) {
157                return;
158            }
159            //noinspection JSUnusedAssignment
160            updatingBounds = true;
161            $scope.$apply(function() {
162                $scope.center = event.get('newCenter');
163                $scope.zoom = event.get('newZoom');
164            });
165            updatingBounds = false;
166        });
167
168    });
169}])
170.directive('yandexMap', ['ymapsLoader', function (ymapsLoader) {
171    "use strict";
172    return {
173        restrict: 'EA',
174        terminal: true,
175        transclude: true,
176        scope: {
177            center: '=',
178            zoom: '='
179        },
180        link: function($scope, element, attrs, ctrl, transcludeFn) {
181            ymapsLoader.ready(function() {
182                transcludeFn(function( copy ) {
183                    element.append(copy);
184                });
185            });
186        },
187        controller: 'YmapController'
188    };
189}])
190.directive('ymapMarker', function () {
191    "use strict";
192    return {
193        restrict: "EA",
194        require : '^yandexMap',
195        scope   : {
196            coordinates: '=',
197            index: '=',
198            properties: '=',
199            options: '='
200        },
201        link: function ($scope, elm, attr, mapCtrl) {
202            var marker;
203            function pickMarker() {
204                var coord = [
205                    parseFloat($scope.coordinates[0]),
206                    parseFloat($scope.coordinates[1])
207                ];
208                if (marker) {
209                    mapCtrl.removeMarker(marker);
210                }
211                marker = mapCtrl.addMarker(coord, angular.extend({iconContent: $scope.index}, $scope.properties), $scope.options);
212            }
213
214            $scope.$watch("index", function (newVal) {
215                if (marker) {
216                    marker.properties.set('iconContent', newVal);
217                }
218            });
219            $scope.$watch("coordinates", function (newVal) {
220                if (newVal) {
221                    pickMarker();
222                }
223            }, true);
224            $scope.$on('$destroy', function () {
225                if (marker) {
226                    mapCtrl.removeMarker(marker);
227                }
228            });
229        }
230    };
231});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.