leaflet-rails 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -2,3 +2,7 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+
6
+ /.rspec
7
+ /coverage/
8
+ /log/
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - jruby-19mode
5
+ - rbx-19mode
6
+ - ruby-head
7
+ - jruby-head
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: jruby-19mode
11
+ - rvm: rbx-19mode
12
+ - rvm: ruby-head
13
+ - rvm: jruby-head
14
+ notifications:
15
+ email: false
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ #ruby=1.9.3-p374
4
+ #ruby-gemset=leaflet-rails
5
+
3
6
  # Specify your gem's dependencies in leaflet-rails.gemspec
4
7
  gemspec
data/LICENSE CHANGED
@@ -1,4 +1,6 @@
1
- Copyright (c) 2010-2012, CloudMade, Vladimir Agafonkin, Akshay Joshi
1
+ Copyright (c) 2010-2013, Vladimir Agafonkin
2
+ Copyright (c) 2010-2011, CloudMade
3
+ Copyright (c) 2012-2013, Akshay Joshi
2
4
  All rights reserved.
3
5
 
4
6
  Redistribution and use in source and binary forms, with or without modification, are
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.org/axyjo/leaflet-rails.png?branch=master)](https://travis-ci.org/axyjo/leaflet-rails)
2
+
1
3
  Quickstart Guide
2
4
  ================
3
5
 
@@ -7,7 +9,7 @@ First, add the following code to your `Gemfile`.
7
9
 
8
10
  ```ruby
9
11
  gem 'leaflet-rails'
10
- ```
12
+ ```
11
13
 
12
14
  Then, run `bundle install` from within your project to download the necessary files. Following that, open your application-wide CSS file (`app/assets/stylesheets/application.css`) and add the following line as a comment:
13
15
 
@@ -28,3 +30,80 @@ After that, open your application-wide Javascript file (typically `app/assets/ja
28
30
  ```
29
31
 
30
32
  At this point, you may skip the first two steps of the [Leaflet Quick Start guide](http://leafletjs.com/examples/quick-start.html) and start at the third step (adding the map `div` to a view).
33
+
34
+ Helpers
35
+ =======
36
+
37
+ To get you up and running quickly, you can also use the gem's helper. To get started, add the following lines to a file called `leaflet.rb` in `config/initializers`:
38
+
39
+ ```ruby
40
+ Leaflet.tile_layer = "http://{s}.tile.cloudmade.com/YOUR-CLOUDMADE-API-KEY/997/256/{z}/{x}/{y}.png"
41
+ # You can also use any other tile layer here if you don't want to use Cloudmade - see http://leafletjs.com/reference.html#tilelayer for more
42
+ Leaflet.attribution = "Your attribution statement"
43
+ Leaflet.max_zoom = 18
44
+ ```
45
+
46
+ You will then be able to call the helper in a view like so:
47
+ ```ruby
48
+ map(:center => {
49
+ :latlng => [51.52238797921441, -0.08366235665359283],
50
+ :zoom => 18
51
+ })
52
+ ```
53
+
54
+ You can also add any number of markers like so:
55
+ ```ruby
56
+ map(:center => {
57
+ :latlng => [51.52238797921441, -0.08366235665359283],
58
+ :zoom => 18
59
+ },
60
+ :markers => [
61
+ {
62
+ :latlng => [51.52238797921441, -0.08366235665359283],
63
+ }
64
+ ]
65
+ )
66
+ ```
67
+
68
+ Adding a `:popup` element to a marker hash will also generate a popup for a maker:
69
+
70
+ ```ruby
71
+ map(:center => {
72
+ :latlng => [51.52238797921441, -0.08366235665359283],
73
+ :zoom => 18
74
+ },
75
+ :markers => [
76
+ {
77
+ :latlng => [51.52238797921441, -0.08366235665359283],
78
+ :popup => "Hello!"
79
+ }
80
+ ]
81
+ )
82
+ ```
83
+
84
+ If you want to override the map settings you have set in the initializer, you can also add them to the helper:
85
+
86
+ ```ruby
87
+ map(:center => {
88
+ :latlng => [51.52238797921441, -0.08366235665359283],
89
+ :zoom => 18
90
+ },
91
+ :tile_layer => "http://{s}.somedomain.com/somepath/{z}/{x}/{y}.png",
92
+ :attribution => "Some other attribution text",
93
+ :max_zoom => 4
94
+ )
95
+ ```
96
+
97
+ If you want to have multiple maps on same page , you should add unique container_id in helper for each map:
98
+
99
+ ```ruby
100
+ map(:container_id => "first_map", :center => {
101
+ :latlng => [51.52238797921441, -0.08366235665359283],
102
+ :zoom => 18
103
+ })
104
+
105
+ map(:container_id => "second_map", :center => {
106
+ :latlng => [51.52238797921441, -0.08366235665359283],
107
+ :zoom => 18
108
+ })
109
+ ```
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -7,9 +7,10 @@ Gem::Specification.new do |s|
7
7
  s.version = Leaflet::Rails::VERSION
8
8
  s.authors = ["Akshay Joshi"]
9
9
  s.email = ["joshi.a@gmail.com"]
10
+ s.license = "BSD"
10
11
  s.homepage = ""
11
- s.summary = %q{Use leaflet.js with Rails 3.}
12
- s.description = %q{This gem provides the leaflet.js map display library for your Rails 3 application.}
12
+ s.summary = %q{Use leaflet.js with Rails 3/4.}
13
+ s.description = %q{This gem provides the leaflet.js map display library for your Rails 3/4 application.}
13
14
 
14
15
  s.rubyforge_project = "leaflet-rails"
15
16
 
@@ -18,7 +19,10 @@ Gem::Specification.new do |s|
18
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
20
  s.require_paths = ["lib"]
20
21
 
21
- # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
23
- # s.add_runtime_dependency "rest-client"
22
+ s.add_development_dependency "rspec"
23
+ s.add_development_dependency "simplecov-rcov"
24
+ s.add_development_dependency "actionpack", '>= 3.2.0'
25
+ s.add_development_dependency "activesupport", '>= 3.2.0'
26
+ s.add_development_dependency "activemodel", '>= 3.2.0'
27
+ s.add_development_dependency "railties", '>= 3.2.0'
24
28
  end
data/lib/leaflet-rails.rb CHANGED
@@ -1,9 +1,20 @@
1
1
  require "leaflet-rails/version"
2
+ require "leaflet-rails/view_helpers"
2
3
 
3
4
  module Leaflet
5
+ mattr_accessor :tile_layer
6
+ mattr_accessor :attribution
7
+ mattr_accessor :max_zoom
8
+
4
9
  module Rails
5
10
  class Engine < ::Rails::Engine
6
- # Rails -> use vendor directory.
11
+ initializer 'leaflet-rails.precompile' do |app|
12
+ app.config.assets.precompile += %w(layers-2x.png layers.png marker-icon-2x.png marker-icon.png marker-shadow.png)
13
+ end
14
+
15
+ initializer 'leaflet-rails.helpers' do
16
+ ActionView::Base.send :include, Leaflet::ViewHelpers
17
+ end
7
18
  end
8
19
  end
9
20
  end
@@ -1,5 +1,5 @@
1
1
  module Leaflet
2
2
  module Rails
3
- VERSION = "0.6.2"
3
+ VERSION = "0.6.3"
4
4
  end
5
5
  end
@@ -0,0 +1,33 @@
1
+ module Leaflet
2
+ module ViewHelpers
3
+
4
+ def map(options)
5
+ options[:tile_layer] ||= Leaflet.tile_layer
6
+ options[:attribution] ||= Leaflet.attribution
7
+ options[:max_zoom] ||= Leaflet.max_zoom
8
+ options[:container_id] ||= 'map'
9
+
10
+ output = []
11
+ output << "<div id='#{options[:container_id]}'></div>"
12
+ output << "<script>"
13
+ output << "var map = L.map('#{options[:container_id]}')"
14
+ output << "map.setView([#{options[:center][:latlng][0]}, #{options[:center][:latlng][1]}], #{options[:center][:zoom]})"
15
+ if options[:markers]
16
+ options[:markers].each do |marker|
17
+ output << "marker = L.marker([#{marker[:latlng][0]}, #{marker[:latlng][1]}]).addTo(map)"
18
+ if marker[:popup]
19
+ output << "marker.bindPopup('#{marker[:popup]}')"
20
+ end
21
+ end
22
+ end
23
+ output << "L.tileLayer('#{options[:tile_layer]}', {
24
+ attribution: '#{options[:attribution]}',
25
+ maxZoom: #{options[:max_zoom]}
26
+ }).addTo(map)"
27
+ output << "</script>"
28
+ output.join("\n").html_safe
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,43 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'simplecov'
9
+ require 'simplecov-rcov'
10
+
11
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
12
+ SimpleCov.start
13
+
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+
17
+ ENV["RAILS_ENV"] ||= 'test'
18
+
19
+ require "action_controller/railtie"
20
+ require "rails/test_unit/railtie"
21
+
22
+ require "leaflet-rails"
23
+
24
+ module Test
25
+ class Application < ::Rails::Application
26
+ # configuration here if needed
27
+ config.active_support.deprecation = :stderr
28
+ end
29
+ end
30
+
31
+ Test::Application.initialize!
32
+
33
+ RSpec.configure do |config|
34
+ config.treat_symbols_as_metadata_keys_with_true_values = true
35
+ config.run_all_when_everything_filtered = true
36
+ config.filter_run :focus
37
+
38
+ # Run specs in random order to surface order dependencies. If you find an
39
+ # order dependency and want to debug it, you can fix the order by providing
40
+ # the seed, which is printed after each run.
41
+ # --seed 1234
42
+ config.order = 'random'
43
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe Leaflet::ViewHelpers do
4
+
5
+ class TestView < ActionView::Base
6
+ end
7
+
8
+ before :all do
9
+ Leaflet.tile_layer = "http://{s}.somedomain.com/blabla/{z}/{x}/{y}.png"
10
+ Leaflet.attribution = "Some attribution statement"
11
+ Leaflet.max_zoom = 18
12
+
13
+ @view = TestView.new
14
+ end
15
+
16
+ it 'should mix in view helpers on initialization' do
17
+ @view.should respond_to(:map)
18
+ end
19
+
20
+ it 'should set the method configuration options' do
21
+ result = @view.map(:center => {
22
+ :latlng => [51.52238797921441, -0.08366235665359283],
23
+ :zoom => 18
24
+ })
25
+
26
+ result.should match(/L.tileLayer\('http:\/\/{s}.somedomain\.com\/blabla\/{z}\/{x}\/{y}\.png'/)
27
+ result.should match(/attribution: 'Some attribution statement'/)
28
+ result.should match(/maxZoom: 18/)
29
+ end
30
+
31
+ it 'should generate a basic map with the correct latitude, longitude and zoom' do
32
+ result = @view.map(:center => {
33
+ :latlng => [51.52238797921441, -0.08366235665359283],
34
+ :zoom => 18
35
+ })
36
+ result.should match(/map\.setView\(\[51.52238797921441, -0.08366235665359283\], 18\)/)
37
+ end
38
+
39
+ it 'should generate a marker' do
40
+ result = @view.map(:center => {
41
+ :latlng => [51.52238797921441, -0.08366235665359283],
42
+ :zoom => 18
43
+ },
44
+ :markers => [
45
+ {
46
+ :latlng => [51.52238797921441, -0.08366235665359283],
47
+ }
48
+ ])
49
+ result.should match(/marker = L\.marker\(\[51.52238797921441, -0.08366235665359283\]\).addTo\(map\)/)
50
+ end
51
+
52
+ it 'should generate a marker with a popup' do
53
+ result = @view.map(:center => {
54
+ :latlng => [51.52238797921441, -0.08366235665359283],
55
+ :zoom => 18
56
+ },
57
+ :markers => [
58
+ {
59
+ :latlng => [51.52238797921441, -0.08366235665359283],
60
+ :popup => "Hello!"
61
+ }
62
+ ])
63
+ result.should match(/marker = L\.marker\(\[51.52238797921441, -0.08366235665359283\]\).addTo\(map\)/)
64
+ result.should match(/marker\.bindPopup\('Hello!'\)/)
65
+ end
66
+
67
+ it 'should override the method configuration options if set' do
68
+ result = @view.map(:center => {
69
+ :latlng => [51.52238797921441, -0.08366235665359283],
70
+ :zoom => 18
71
+ },
72
+ :tile_layer => "http://{s}.someotherdomain.com/blabla/{z}/{x}/{y}.png",
73
+ :attribution => "Some other attribution text",
74
+ :max_zoom => 4
75
+ )
76
+
77
+ result.should match(/L.tileLayer\('http:\/\/{s}.someotherdomain\.com\/blabla\/{z}\/{x}\/{y}\.png'/)
78
+ result.should match(/attribution: 'Some other attribution text'/)
79
+ result.should match(/maxZoom: 4/)
80
+ end
81
+
82
+ it 'should have multiple map on single page' do
83
+ result = @view.map(:container_id => "first_map", :center => {
84
+ :latlng => [51.52238797921441, -0.08366235665359283],
85
+ })
86
+
87
+ result1 = @view.map(:container_id => "second_map", :center => {
88
+ :latlng => [51.62238797921441, -0.08366235665359284],
89
+ })
90
+
91
+ result.should match(/id=\'first_map'/)
92
+ result.should match(/L.map\('first_map'/)
93
+
94
+ result1.should match(/id=\'second_map'/)
95
+ result1.should match(/L.map\('second_map'/)
96
+
97
+ end
98
+
99
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -7,7 +7,7 @@
7
7
  var oldL = window.L,
8
8
  L = {};
9
9
 
10
- L.version = '0.6.2';
10
+ L.version = '0.6.3';
11
11
 
12
12
  // define Leaflet for Node module pattern loaders, including Browserify
13
13
  if (typeof module === 'object' && typeof module.exports === 'object') {
@@ -1092,46 +1092,30 @@ L.DomUtil.TRANSITION_END =
1092
1092
  var userSelectProperty = L.DomUtil.testProp(
1093
1093
  ['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
1094
1094
 
1095
- var userDragProperty = L.DomUtil.testProp(
1096
- ['userDrag', 'WebkitUserDrag', 'OUserDrag', 'MozUserDrag', 'msUserDrag']);
1097
-
1098
1095
  L.extend(L.DomUtil, {
1099
1096
  disableTextSelection: function () {
1097
+ L.DomEvent.on(window, 'selectstart', L.DomEvent.preventDefault);
1100
1098
  if (userSelectProperty) {
1101
1099
  var style = document.documentElement.style;
1102
1100
  this._userSelect = style[userSelectProperty];
1103
1101
  style[userSelectProperty] = 'none';
1104
- } else {
1105
- L.DomEvent.on(window, 'selectstart', L.DomEvent.stop);
1106
1102
  }
1107
1103
  },
1108
1104
 
1109
1105
  enableTextSelection: function () {
1106
+ L.DomEvent.off(window, 'selectstart', L.DomEvent.preventDefault);
1110
1107
  if (userSelectProperty) {
1111
1108
  document.documentElement.style[userSelectProperty] = this._userSelect;
1112
1109
  delete this._userSelect;
1113
- } else {
1114
- L.DomEvent.off(window, 'selectstart', L.DomEvent.stop);
1115
1110
  }
1116
1111
  },
1117
1112
 
1118
1113
  disableImageDrag: function () {
1119
- if (userDragProperty) {
1120
- var style = document.documentElement.style;
1121
- this._userDrag = style[userDragProperty];
1122
- style[userDragProperty] = 'none';
1123
- } else {
1124
- L.DomEvent.on(window, 'dragstart', L.DomEvent.stop);
1125
- }
1114
+ L.DomEvent.on(window, 'dragstart', L.DomEvent.preventDefault);
1126
1115
  },
1127
1116
 
1128
1117
  enableImageDrag: function () {
1129
- if (userDragProperty) {
1130
- document.documentElement.style[userDragProperty] = this._userDrag;
1131
- delete this._userDrag;
1132
- } else {
1133
- L.DomEvent.off(window, 'dragstart', L.DomEvent.stop);
1134
- }
1118
+ L.DomEvent.off(window, 'dragstart', L.DomEvent.preventDefault);
1135
1119
  }
1136
1120
  });
1137
1121
  })();
@@ -1629,7 +1613,7 @@ L.Map = L.Class.extend({
1629
1613
  return this.fire('moveend');
1630
1614
  },
1631
1615
 
1632
- setMaxBounds: function (bounds) {
1616
+ setMaxBounds: function (bounds, options) {
1633
1617
  bounds = L.latLngBounds(bounds);
1634
1618
 
1635
1619
  this.options.maxBounds = bounds;
@@ -1646,7 +1630,7 @@ L.Map = L.Class.extend({
1646
1630
 
1647
1631
  if (this._loaded) {
1648
1632
  if (this._zoom < minZoom) {
1649
- this.setView(bounds.getCenter(), minZoom);
1633
+ this.setView(bounds.getCenter(), minZoom, options);
1650
1634
  } else {
1651
1635
  this.panInsideBounds(bounds);
1652
1636
  }
@@ -1724,10 +1708,14 @@ L.Map = L.Class.extend({
1724
1708
 
1725
1709
  if (this._loaded) {
1726
1710
  layer.onRemove(this);
1727
- this.fire('layerremove', {layer: layer});
1728
1711
  }
1729
1712
 
1730
1713
  delete this._layers[id];
1714
+
1715
+ if (this._loaded) {
1716
+ this.fire('layerremove', {layer: layer});
1717
+ }
1718
+
1731
1719
  if (this._zoomBoundLayers[id]) {
1732
1720
  delete this._zoomBoundLayers[id];
1733
1721
  this._updateZoomLevels();
@@ -1856,18 +1844,15 @@ L.Map = L.Class.extend({
1856
1844
  },
1857
1845
 
1858
1846
  getMinZoom: function () {
1859
- var z1 = this.options.minZoom || 0,
1860
- z2 = this._layersMinZoom || 0,
1861
- z3 = this._boundsMinZoom || 0;
1862
-
1863
- return Math.max(z1, z2, z3);
1847
+ var z1 = this._layersMinZoom === undefined ? -Infinity : this._layersMinZoom,
1848
+ z2 = this._boundsMinZoom === undefined ? -Infinity : this._boundsMinZoom;
1849
+ return this.options.minZoom === undefined ? Math.max(z1, z2) : this.options.minZoom;
1864
1850
  },
1865
1851
 
1866
1852
  getMaxZoom: function () {
1867
- var z1 = this.options.maxZoom === undefined ? Infinity : this.options.maxZoom,
1868
- z2 = this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom;
1869
-
1870
- return Math.min(z1, z2);
1853
+ return this.options.maxZoom === undefined ?
1854
+ (this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) :
1855
+ this.options.maxZoom;
1871
1856
  },
1872
1857
 
1873
1858
  getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
@@ -2187,16 +2172,15 @@ L.Map = L.Class.extend({
2187
2172
  },
2188
2173
 
2189
2174
  _onMouseClick: function (e) {
2190
- // jshint camelcase: false
2191
- if (!this._loaded || (!e._simulated && this.dragging && this.dragging.moved()) || e._leaflet_stop) { return; }
2175
+ if (!this._loaded || (!e._simulated && this.dragging && this.dragging.moved()) ||
2176
+ L.DomEvent._skipped(e)) { return; }
2192
2177
 
2193
2178
  this.fire('preclick');
2194
2179
  this._fireMouseEvent(e);
2195
2180
  },
2196
2181
 
2197
2182
  _fireMouseEvent: function (e) {
2198
- // jshint camelcase: false
2199
- if (!this._loaded || e._leaflet_stop) { return; }
2183
+ if (!this._loaded || L.DomEvent._skipped(e)) { return; }
2200
2184
 
2201
2185
  var type = e.type;
2202
2186
 
@@ -3046,6 +3030,11 @@ L.TileLayer.Canvas = L.TileLayer.extend({
3046
3030
  },
3047
3031
 
3048
3032
  redraw: function () {
3033
+ if (this._map) {
3034
+ this._reset({hard: true});
3035
+ this._update();
3036
+ }
3037
+
3049
3038
  for (var i in this._tiles) {
3050
3039
  this._redrawTile(this._tiles[i]);
3051
3040
  }
@@ -3360,16 +3349,14 @@ L.Icon.Default = L.Icon.extend({
3360
3349
  }
3361
3350
 
3362
3351
  if (L.Browser.retina && name === 'icon') {
3363
- name += '-2x';
3352
+ return "<%= asset_path('marker-icon-2x.png') %>";
3364
3353
  }
3365
3354
 
3366
- var path = L.Icon.Default.imagePath;
3367
-
3368
- if (!path) {
3369
- throw new Error('Couldn\'t autodetect L.Icon.Default.imagePath, set it manually.');
3355
+ if (name == 'shadow') {
3356
+ return "<%= asset_path('marker-shadow.png') %>";
3357
+ } else {
3358
+ return "<%= asset_path('marker-icon.png') %>";
3370
3359
  }
3371
-
3372
- return path + '/marker-' + name + '.png';
3373
3360
  }
3374
3361
  });
3375
3362
 
@@ -3535,10 +3522,10 @@ L.Marker = L.Class.extend({
3535
3522
  if (newShadow !== this._shadow) {
3536
3523
  this._removeShadow();
3537
3524
  addShadow = true;
3525
+ }
3538
3526
 
3539
- if (newShadow) {
3540
- L.DomUtil.addClass(newShadow, classToAdd);
3541
- }
3527
+ if (newShadow) {
3528
+ L.DomUtil.addClass(newShadow, classToAdd);
3542
3529
  }
3543
3530
  this._shadow = newShadow;
3544
3531
 
@@ -3676,6 +3663,8 @@ L.Marker = L.Class.extend({
3676
3663
  if (this._map) {
3677
3664
  this._updateOpacity();
3678
3665
  }
3666
+
3667
+ return this;
3679
3668
  },
3680
3669
 
3681
3670
  _updateOpacity: function () {
@@ -3901,6 +3890,7 @@ L.Popup = L.Class.extend({
3901
3890
 
3902
3891
  this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper);
3903
3892
  L.DomEvent.on(this._contentNode, 'mousewheel', L.DomEvent.stopPropagation);
3893
+ L.DomEvent.on(this._contentNode, 'MozMousePixelScroll', L.DomEvent.stopPropagation);
3904
3894
  L.DomEvent.on(wrapper, 'contextmenu', L.DomEvent.stopPropagation);
3905
3895
  this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container', container);
3906
3896
  this._tip = L.DomUtil.create('div', prefix + '-tip', this._tipContainer);
@@ -4301,6 +4291,9 @@ L.FeatureGroup = L.LayerGroup.extend({
4301
4291
  },
4302
4292
 
4303
4293
  removeLayer: function (layer) {
4294
+ if (!this.hasLayer(layer)) {
4295
+ return this;
4296
+ }
4304
4297
  if (layer in this._layers) {
4305
4298
  layer = this._layers[layer];
4306
4299
  }
@@ -4370,9 +4363,11 @@ L.Path = L.Class.extend({
4370
4363
  // how much to extend the clip area around the map view
4371
4364
  // (relative to its size, e.g. 0.5 is half the screen in each direction)
4372
4365
  // set it so that SVG element doesn't exceed 1280px (vectors flicker on dragend if it is)
4373
- CLIP_PADDING: L.Browser.mobile ?
4374
- Math.max(0, Math.min(0.5,
4375
- (1280 / Math.max(window.innerWidth, window.innerHeight) - 1) / 2)) : 0.5
4366
+ CLIP_PADDING: (function () {
4367
+ var max = L.Browser.mobile ? 1280 : 2000,
4368
+ target = (max / Math.max(window.outerWidth, window.outerHeight) - 1) / 2;
4369
+ return Math.max(0, Math.min(0.5, target));
4370
+ })()
4376
4371
  },
4377
4372
 
4378
4373
  options: {
@@ -5632,6 +5627,16 @@ L.polygon = function (latlngs, options) {
5632
5627
  }
5633
5628
 
5634
5629
  return this;
5630
+ },
5631
+
5632
+ getLatLngs: function () {
5633
+ var latlngs = [];
5634
+
5635
+ this.eachLayer(function (layer) {
5636
+ latlngs.push(layer.getLatLngs());
5637
+ });
5638
+
5639
+ return latlngs;
5635
5640
  }
5636
5641
  });
5637
5642
  }
@@ -5933,12 +5938,13 @@ L.GeoJSON = L.FeatureGroup.extend({
5933
5938
 
5934
5939
  addData: function (geojson) {
5935
5940
  var features = L.Util.isArray(geojson) ? geojson : geojson.features,
5936
- i, len;
5941
+ i, len, feature;
5937
5942
 
5938
5943
  if (features) {
5939
5944
  for (i = 0, len = features.length; i < len; i++) {
5940
5945
  // Only add this if geometry or geometries are set and not null
5941
- if (features[i].geometries || features[i].geometry || features[i].features) {
5946
+ feature = features[i];
5947
+ if (feature.geometries || feature.geometry || feature.features || feature.coordinates) {
5942
5948
  this.addData(features[i]);
5943
5949
  }
5944
5950
  }
@@ -6316,13 +6322,30 @@ L.DomEvent = {
6316
6322
 
6317
6323
  getMousePosition: function (e, container) {
6318
6324
 
6319
- var body = document.body,
6325
+ var ie7 = L.Browser.ie7,
6326
+ body = document.body,
6320
6327
  docEl = document.documentElement,
6321
- x = e.pageX ? e.pageX : e.clientX + body.scrollLeft + docEl.scrollLeft,
6322
- y = e.pageY ? e.pageY : e.clientY + body.scrollTop + docEl.scrollTop,
6323
- pos = new L.Point(x, y);
6328
+ x = e.pageX ? e.pageX - body.scrollLeft - docEl.scrollLeft: e.clientX,
6329
+ y = e.pageY ? e.pageY - body.scrollTop - docEl.scrollTop: e.clientY,
6330
+ pos = new L.Point(x, y),
6331
+ rect = container.getBoundingClientRect(),
6332
+ left = rect.left - container.clientLeft,
6333
+ top = rect.top - container.clientTop;
6334
+
6335
+ // webkit (and ie <= 7) handles RTL scrollLeft different to everyone else
6336
+ // https://code.google.com/p/closure-library/source/browse/trunk/closure/goog/style/bidi.js
6337
+ if (!L.DomUtil.documentIsLtr() && (L.Browser.webkit || ie7)) {
6338
+ left += container.scrollWidth - container.clientWidth;
6339
+
6340
+ // ie7 shows the scrollbar by default and provides clientWidth counting it, so we
6341
+ // need to add it back in if it is visible; scrollbar is on the left as we are RTL
6342
+ if (ie7 && L.DomUtil.getStyle(container, 'overflow-y') !== 'hidden' &&
6343
+ L.DomUtil.getStyle(container, 'overflow') !== 'hidden') {
6344
+ left += 17;
6345
+ }
6346
+ }
6324
6347
 
6325
- return (container ? pos._subtract(L.DomUtil.getViewportOffset(container)) : pos);
6348
+ return pos._subtract(new L.Point(left, top));
6326
6349
  },
6327
6350
 
6328
6351
  getWheelDelta: function (e) {
@@ -6338,10 +6361,18 @@ L.DomEvent = {
6338
6361
  return delta;
6339
6362
  },
6340
6363
 
6341
- _fakeStop: function stop(e) {
6342
- // fakes stopPropagation by setting a special event flag checked in Map mouse events handler
6343
- // jshint camelcase: false
6344
- e._leaflet_stop = true;
6364
+ _skipEvents: {},
6365
+
6366
+ _fakeStop: function (e) {
6367
+ // fakes stopPropagation by setting a special event flag, checked/reset with L.DomEvent._skipped(e)
6368
+ L.DomEvent._skipEvents[e.type] = true;
6369
+ },
6370
+
6371
+ _skipped: function (e) {
6372
+ var skipped = this._skipEvents[e.type];
6373
+ // reset when checking, as it's only used in map container and propagates outside of the map
6374
+ this._skipEvents[e.type] = false;
6375
+ return skipped;
6345
6376
  },
6346
6377
 
6347
6378
  // check if element really left/entered the event target (for mouseenter/mouseleave)
@@ -6603,6 +6634,8 @@ L.Map.Drag = L.Handler.extend({
6603
6634
  if (map.options.worldCopyJump) {
6604
6635
  this._draggable.on('predrag', this._onPreDrag, this);
6605
6636
  map.on('viewreset', this._onViewReset, this);
6637
+
6638
+ this._onViewReset();
6606
6639
  }
6607
6640
  }
6608
6641
  this._draggable.enable();
@@ -8337,9 +8370,14 @@ L.PosAnimation = L.Class.extend({
8337
8370
  },
8338
8371
 
8339
8372
  _onStep: function () {
8373
+ var stepPos = this._getPos();
8374
+ if (!stepPos) {
8375
+ this._onTransitionEnd();
8376
+ return;
8377
+ }
8340
8378
  // jshint camelcase: false
8341
8379
  // make L.DomUtil.getPosition return intermediate position value during animation
8342
- this._el._leaflet_pos = this._getPos();
8380
+ this._el._leaflet_pos = stepPos;
8343
8381
 
8344
8382
  this.fire('step');
8345
8383
  },
@@ -8356,8 +8394,9 @@ L.PosAnimation = L.Class.extend({
8356
8394
 
8357
8395
  if (L.Browser.any3d) {
8358
8396
  matches = style[L.DomUtil.TRANSFORM].match(this._transformRe);
8359
- left = matches ? parseFloat(matches[1]) : 0;
8360
- top = matches ? parseFloat(matches[2]) : 0;
8397
+ if (!matches) { return; }
8398
+ left = parseFloat(matches[1]);
8399
+ top = parseFloat(matches[2]);
8361
8400
  } else {
8362
8401
  left = parseFloat(style.left);
8363
8402
  top = parseFloat(style.top);
@@ -8587,6 +8626,10 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
8587
8626
  }
8588
8627
  },
8589
8628
 
8629
+ _nothingToAnimate: function () {
8630
+ return !this._container.getElementsByClassName('leaflet-zoom-animated').length;
8631
+ },
8632
+
8590
8633
  _tryAnimatedZoom: function (center, zoom, options) {
8591
8634
 
8592
8635
  if (this._animatingZoom) { return true; }
@@ -8594,7 +8637,7 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
8594
8637
  options = options || {};
8595
8638
 
8596
8639
  // don't animate if disabled, not supported or zoom difference is too large
8597
- if (!this._zoomAnimated || options.animate === false ||
8640
+ if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() ||
8598
8641
  Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; }
8599
8642
 
8600
8643
  // offset is the pixel coords of the zoom origin relative to the current center
@@ -8847,7 +8890,7 @@ L.Map.include({
8847
8890
 
8848
8891
  var data = {
8849
8892
  latlng: latlng,
8850
- bounds: bounds,
8893
+ bounds: bounds
8851
8894
  };
8852
8895
 
8853
8896
  for (var i in pos.coords) {
@@ -378,11 +378,11 @@
378
378
 
379
379
  .leaflet-touch .leaflet-control-attribution,
380
380
  .leaflet-touch .leaflet-control-layers,
381
- .leaflet-touch .leaflet-control-zoom {
381
+ .leaflet-touch .leaflet-bar {
382
382
  box-shadow: none;
383
383
  }
384
384
  .leaflet-touch .leaflet-control-layers,
385
- .leaflet-touch .leaflet-control-zoom {
385
+ .leaflet-touch .leaflet-bar {
386
386
  border: 4px solid rgba(0,0,0,0.3);
387
387
  }
388
388
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leaflet-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,9 +9,105 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-16 00:00:00.000000000 Z
13
- dependencies: []
14
- description: This gem provides the leaflet.js map display library for your Rails 3
12
+ date: 2013-11-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: simplecov-rcov
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: actionpack
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 3.2.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: activesupport
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 3.2.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 3.2.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: activemodel
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 3.2.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 3.2.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: railties
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 3.2.0
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 3.2.0
110
+ description: This gem provides the leaflet.js map display library for your Rails 3/4
15
111
  application.
16
112
  email:
17
113
  - joshi.a@gmail.com
@@ -20,6 +116,7 @@ extensions: []
20
116
  extra_rdoc_files: []
21
117
  files:
22
118
  - .gitignore
119
+ - .travis.yml
23
120
  - CHANGELOG.md
24
121
  - Gemfile
25
122
  - LICENSE
@@ -28,6 +125,9 @@ files:
28
125
  - leaflet-rails.gemspec
29
126
  - lib/leaflet-rails.rb
30
127
  - lib/leaflet-rails/version.rb
128
+ - lib/leaflet-rails/view_helpers.rb
129
+ - spec/spec_helper.rb
130
+ - spec/view_helpers_spec.rb
31
131
  - vendor/assets/images/layers-2x.png
32
132
  - vendor/assets/images/layers.png
33
133
  - vendor/assets/images/marker-icon-2x.png
@@ -37,7 +137,8 @@ files:
37
137
  - vendor/assets/stylesheets/leaflet.css.erb
38
138
  - vendor/assets/stylesheets/leaflet.ie.css
39
139
  homepage: ''
40
- licenses: []
140
+ licenses:
141
+ - BSD
41
142
  post_install_message:
42
143
  rdoc_options: []
43
144
  require_paths:
@@ -59,5 +160,7 @@ rubyforge_project: leaflet-rails
59
160
  rubygems_version: 1.8.23
60
161
  signing_key:
61
162
  specification_version: 3
62
- summary: Use leaflet.js with Rails 3.
63
- test_files: []
163
+ summary: Use leaflet.js with Rails 3/4.
164
+ test_files:
165
+ - spec/spec_helper.rb
166
+ - spec/view_helpers_spec.rb