From 2acaa3117841c905b84fef9aede31fc9774ba7bd Mon Sep 17 00:00:00 2001
From: Riadh Habbachi <riadh@angrycactus.biz>
Date: Tue, 8 Sep 2015 15:55:03 +0100
Subject: [PATCH 1/7] Improve tabs implementation for leaflet widget

---
 js/draw.js            | 448 ++++++++++++++++++++++--------------------
 leaflet_widget.module |   1 +
 2 files changed, 241 insertions(+), 208 deletions(-)

diff --git a/js/draw.js b/js/draw.js
index 1a817ad..b95f2c4 100644
--- a/js/draw.js
+++ b/js/draw.js
@@ -1,244 +1,276 @@
 (function ($) {
 
-    Drupal.leaflet_widget = Drupal.leaflet_widget || {};
-
-    Drupal.behaviors.geofield_widget = {
-        attach: attach
-    };
-
-    function attach(context, settings) {
-        $('.leaflet-widget').once().each(function(i, item) {
-            var id = $(item).attr('id'),
-            options = settings.leaflet_widget_widget[id];
-            if (options.toggle) {
-              $('#' + id + '-input').before('<div class="map btn btn-default" style="cursor: pointer;" id="' + id + '-geojson-toggle">GEOJSON</div>');
-              $('#' + id + '-input').before('<div class="map btn btn-default" style="cursor: pointer;" id="' + id + '-point-toggle">POINT</div></br><input type="text" id="manual-' + id + '-point-input" name="manual-point">');
-                $('#manual-' + id + '-point-input').hide();
-              $('#' + id + '-geojson-toggle').click(function () {
-                $(item).toggle();
-                if ($(this).hasClass('map')) {
-                  $(this).text('Use map');
-                  $(this).removeClass('map');
-                  $('#' + id + '-input').get(0).type = 'text';
-
-                  //Hide select geographic areas if is enable.
-                  if (options.geographic_areas) {
-                    $('.geographic_areas_desc').hide();
-                  }
-                }
-                else {
-                  $(this).text('GEOJSON');
-                  $('#' + id + '-input').get(0).type = 'hidden';
-                  $(this).addClass('map');
-
-                  //Show select geographic areas if is enable.
-                  if (options.geographic_areas) {
-                    $('.geographic_areas_desc').show();
-                  }
-                }
-              });
+  Drupal.leaflet_widget = Drupal.leaflet_widget || {};
 
-               $('#' + id + '-point-toggle').click(function () {
-                $(item).toggle();
-                $('#manual-' + id + '-point-input').toggle();
+  Drupal.behaviors.geofield_widget = {
+    attach: attach
+  };
 
-                if ($(this).hasClass('map')) {
-                  $(this).text('Use map');
-                  $(this).removeClass('map');
-                  $('#manual-' + id + '-point-input').get(0).type = 'text';
+  function attach(context, settings) {
+    $('.leaflet-widget').once().each(function(i, item) {
+      var id = $(item).attr('id'),
+        options = settings.leaflet_widget_widget[id];
 
-                  //Hide select geographic areas if is enable.
-                  if (options.geographic_areas) {
-                    $('.geographic_areas_desc').hide();
-                  }
-                }
-                else {
-                  $(this).text('POINT');
-                  $('#' + id + '-input').get(0).type = 'hidden';
-                  $(this).addClass('map');
-                  var point_string = $('#manual-' + id + '-point-input').val();
-
-                  if (point_string) {
-                      var point_array = point_string.split(',');
-                      var geojsonFeature = {
-                        "type": "Feature",
-                        "properties": {},
-                        "geometry": {
-                            "type": "Point",
-                            "coordinates": [point_array[0], point_array[1]]
-                        }
-                    };
-                    L.geoJson(geojsonFeature).addTo(map);
-                    leafletWidgetFormWrite(map._layers, id);
-                  }
+      var map = L.map(id, options.map);
 
-                  //Show select geographic areas if is enable.
-                  if (options.geographic_areas) {
-                    $('.geographic_areas_desc').show();
-                  }
-                }
-              });
+      L.tileLayer(options.map.base_url).addTo(map);
 
-            }
-            if (options.geographic_areas) {
-              var json_data = {};
-              var selectList = "<div class='geographic_areas_desc'><p></br>Select a state to add into the map:</p><select id='geographic_areas' name='area'>";
-              selectList += "<option value='0'>" + Drupal.t('-none-') + "</option>";
-
-              for (i = 0; i < options.areas.length; i++) {
-                json_data = jQuery.parseJSON(options.areas[i]);
-                $.each(json_data.features, function (index, item) {
-                    selectList += "<option value='" + item.id + "'>" + item.properties.name + "</option>";
-                });
-              }
-              selectList += "</select></div></br>";
-              $('#' + id + '-input').before(selectList);
-
-              $('#geographic_areas').change(function() {
-                var area = $(this).val();
-
-                for (i = 0; i < options.areas.length; i++) {
-                  json_data = jQuery.parseJSON(options.areas[i]);
-                  $.each(json_data.features, function (index, item) {
-                    if (item.id == area) {
-                      L.geoJson(item).addTo(map);
-                      leafletWidgetFormWrite(map._layers, id);
-                    }
-                  });
-                }
-              });
-            }
-            var map = L.map(id, options.map);
-
-            L.tileLayer(options.map.base_url).addTo(map);
-
-            var current = $('#' + id + '-input').val();
-            current = JSON.parse(current);
-            var layers = Array();
-            if (current.features.length) {
-              var geojson = L.geoJson(current)
-              for (var key in geojson._layers) {
-                layers.push(geojson._layers[key]);
-               }
-            }
+      // Get initial geojson value
+      var current = $('#' + id + '-input').val();
+      current = JSON.parse(current);
+      var layers = Array();
+      if (current.features.length) {
+        var geojson = L.geoJson(current)
+        for (var key in geojson._layers) {
+          layers.push(geojson._layers[key]);
+        }
+      }
+
+      var Items = new L.FeatureGroup(layers).addTo(map);
+
+      // Autocenter if that's cool.
+      if (options.map.auto_center) {
+        if (current.features.length) {
+          map.fitBounds(Items.getBounds());
+        }
+      }
+
+      // Add controles to the map
+      var drawControl = new L.Control.Draw({
+        autocenter: true,
+        draw: {
+          position: 'topleft',
+          polygon: options.draw.tools.polygon,
+          circle: options.draw.tools.circle,
+          marker: options.draw.tools.marker,
+          rectangle: options.draw.tools.rectangle,
+          polyline: options.draw.tools.polyline
+        },
+        edit: {
+          featureGroup: Items
+        }
+      });
+
+      map.addControl(drawControl);
+
+      map.on('draw:created', function (e) {
+        var type = e.layerTypee,
+          layer = e.layer;
+        // Remove already created layers. We only want to save one
+        // per field.
+        leafletWidgetLayerRemove(map._layers, Items);
+        // Add new layer.
+        Items.addLayer(layer);
+      });
+
+      $(item).parents('form').submit(function(event){
+        if ($('#' + id + '-toggle').hasClass('map')) {
+          leafletWidgetFormWrite(map._layers, id)
+        }
+      });
+
+      Drupal.leaflet_widget[id] = map;
+
+      if (options.toggle) {
+        $('#' + id).before('<ul class="ui-tabs-nav leaflet-widget">' +
+                           '<li><a href="#' + id + '">Map</a></li>' +
+                           '<li><a href="#' + id + '-geojson' + '">GeoJSON</a></li>' +
+                           '<li><a href="#' + id + '-points' + '">Points</a></li>' +
+                           '</ul>');
+
+        $('#' + id).after('<div id="' + id + '-geojson">' +
+                          '<label for="' + id + '-geojson-textarea">' + Drupal.t('Enter GeoJSON:') + '</label>' +
+                          '<textarea class="text-full form-control form-textarea" id="' + id + '-geojson-textarea" cols="60" rows="10"></textarea>' +
+                          '</div>');
+
+        // Set placeholder
+        $('#' + id + '-geojson-textarea').attr('placeholder', JSON.stringify({"type":"FeatureCollection","features":[]}));
+
+        // Update field's input when geojson input is updated.
+        // @TODO validate before sync
+        $('#' + id + '-geojson-textarea').on('input', function(e) {
+          if(!$('#' + id + '-geojson-textarea').val()) {
+            $('#' + id + '-input').val(JSON.stringify({"type":"FeatureCollection","features":[]}));
+          } else {
+            $('#' + id + '-input').val($('#' + id + '-geojson-textarea').val());
+          }
+        });
 
-            var Items = new L.FeatureGroup(layers).addTo(map);
-            // Autocenter if that's cool.
-            if (options.map.auto_center) {
+        $('#' + id).after('<div id="' + id + '-points" class="">' +
+                          '<label for="' + id + '-points">' + Drupal.t('Point') + '</label>' +
+                          '<input class="text-full form-control form-text" type="text" id="' + id + '-points-input" " placeholder="longitude,latitude" "size="60" maxlength="255">' +
+                          '</div>');
+
+        // Update field's input when geojson input is updated.
+        $('#' + id + '-points-input').on('input', function(e) {
+          var latlng = L.latLng($('#' + id + '-points-input').val().split(','));
+          var coordinates = LatLngToCoords(latlng);
+          var write = JSON.stringify(
+            {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":coordinates},"properties":[]}]}
+          );
+          $('#' + id + '-input').val(write);
+        });
+
+        // Set parent as JQuery UI element and update on selection
+        $('#' + id).parent().tabs({
+          // Default tab is the map tab.
+          selected: 0,
+          select: function(event, ui){
+            switch(ui.index) {
+              case 0:
+                // Map tab is selected
+                // Clear previous layers
+                leafletWidgetLayerRemove(map._layers, Items);
+              var current = $('#' + id + '-input').val();
+              current = JSON.parse(current);
               if (current.features.length) {
+                var geojson = L.geoJson(current)
+                for (var key in geojson._layers) {
+                  // Add new layer.
+                  Items.addLayer(geojson._layers[key]);
+                }
                 map.fitBounds(Items.getBounds());
               }
+              break;
+
+              case 1:
+                // GeoJSON tab is selected
+                // Sync from field's input
+                $('#' + id + '-geojson-textarea').val($('#' + id + '-input').val());
+              break;
+
+              case 2:
+                // Points tab is selected
+                // Reset value and error message and classes (if any).
+                $('#' + id + '-points-input').val('');
+                $('#' + id + '-points-input').parent().removeClass('has-error');
+              $('#' + id + '-points-input').prop('disabled', false)
+              .removeClass('error');
+              $('#' + id + '-points .help-block').remove();
+
+              var current = $('#' + id + '-input').val();
+              current = JSON.parse(current);
+              // Make this unavailable if more then single point.
+              if (current.features.length == 0) {
+                // Empty. Nothing to do
+              } else if (current.features.length == 1
+                  && current.features[0].geometry.type == 'Point') {
+                    $('#' + id + '-points-input').val(current.features[0].geometry.coordinates.toString());
+                  } else {
+                    $('#' + id + '-points-input').parent().addClass('has-error');
+                    $('#' + id + '-points-input').prop('disabled', true)
+                    .addClass('error')
+                    .after('<span class="help-block">Current data cannot be converted to a single point!</span>');
+                  }
+                  break;
             }
+          }
+        });
+      }
 
-            var drawControl = new L.Control.Draw({
-                autocenter: true,
-                draw: {
-                  position: 'topleft',
-                  polygon: options.draw.tools.polygon,
-                  circle: options.draw.tools.circle,
-                  marker: options.draw.tools.marker,
-                  rectangle: options.draw.tools.rectangle,
-                  polyline: options.draw.tools.polyline
-                },
-                edit: {
-                  featureGroup: Items
-                }
-
-              });
+      if (options.geographic_areas) {
+        var json_data = {};
+        var selectList = "<div class='geographic_areas_desc'><p></br>Select a state to add into the map:</p><select id='geographic_areas' name='area'>";
+        selectList += "<option value='0'>" + Drupal.t('-none-') + "</option>";
 
-              map.addControl(drawControl);
+        for (i = 0; i < options.areas.length; i++) {
+          json_data = jQuery.parseJSON(options.areas[i]);
+          $.each(json_data.features, function (index, item) {
+            selectList += "<option value='" + item.id + "'>" + item.properties.name + "</option>";
+          });
+        }
 
-              map.on('draw:created', function (e) {
-                var type = e.layerTypee,
-                  layer = e.layer;
-                // Remove already created layers. We only want to save one
-                // per field.
-                leafletWidgetLayerRemove(map._layers, Items);
-                // Add new layer.
-                Items.addLayer(layer);
-              });
+        selectList += "</select></div></br>";
+        $('#' + id + '-input').before(selectList);
 
-              $(item).parents('form').submit(function(event){
-                if ($('#' + id + '-toggle').hasClass('map')) {
-                  leafletWidgetFormWrite(map._layers, id)
-                }
-              });
+        $('#geographic_areas').change(function() {
+          var area = $(this).val();
 
-            Drupal.leaflet_widget[id] = map;
+          for (i = 0; i < options.areas.length; i++) {
+            json_data = jQuery.parseJSON(options.areas[i]);
+            $.each(json_data.features, function (index, item) {
+              if (item.id == area) {
+                L.geoJson(item).addTo(map);
+                leafletWidgetFormWrite(map._layers, id);
+              }
+            });
+          }
         });
-    }
-
-    /**
-     * Writes layer to input field if there is a layer to write.
-     */
-    function leafletWidgetFormWrite(layers, id) {
-      var write  = Array();
-      for (var key in layers) {
-        if (layers[key]._latlngs || layers[key]._latlng) {
-          write.push(layerToGeometry(layers[key]));
-        }
       }
-      // If no value then provide empty collection.
-      if (!write.length) {
-        write = JSON.stringify({"type":"FeatureCollection","features":[]});
+    });
+  }
+
+  /**
+   * Writes layer to input field if there is a layer to write.
+   */
+  function leafletWidgetFormWrite(layers, id) {
+    var write  = Array();
+    for (var key in layers) {
+      if (layers[key]._latlngs || layers[key]._latlng) {
+        write.push(layerToGeometry(layers[key]));
       }
-      $('#' + id + '-input').val('{"type":"FeatureCollection", "features":[' + write + ']}');
     }
-
-    /**
-     * Removes layers that are already on the map.
-     */
-    function leafletWidgetLayerRemove(layers, Items) {
-      for (var key in layers) {
-        if (layers[key]._latlngs || layers[key]._latlng) {
-          Items.removeLayer(layers[key]);
-        }
+    // If no value then provide empty collection.
+    if (!write.length) {
+      write = JSON.stringify({"type":"FeatureCollection","features":[]});
+    }
+    $('#' + id + '-input').val('{"type":"FeatureCollection", "features":[' + write + ']}');
+  }
+
+  /**
+   * Removes layers that are already on the map.
+   */
+  function leafletWidgetLayerRemove(layers, Items) {
+    for (var key in layers) {
+      if (layers[key]._latlngs || layers[key]._latlng) {
+        Items.removeLayer(layers[key]);
       }
     }
+  }
 
-    // This will all go away once this gets into leaflet main branch:
-    // https://github.com/jfirebaugh/Leaflet/commit/4bc36d4c1926d7c68c966264f3cbf179089bd998
-    var layerToGeometry = function(layer) {
-      var json, type, latlng, latlngs = [], i;
+  // This will all go away once this gets into leaflet main branch:
+  // https://github.com/jfirebaugh/Leaflet/commit/4bc36d4c1926d7c68c966264f3cbf179089bd998
+  var layerToGeometry = function(layer) {
+    var json, type, latlng, latlngs = [], i;
 
-      if (L.Marker && (layer instanceof L.Marker)) {
-        type = 'Point';
-        latlng = LatLngToCoords(layer._latlng);
-        return JSON.stringify({"type": type, "coordinates": latlng});
+    if (L.Marker && (layer instanceof L.Marker)) {
+      type = 'Point';
+      latlng = LatLngToCoords(layer._latlng);
+      return JSON.stringify({"type": type, "coordinates": latlng});
 
-      } else if (L.Polygon && (layer instanceof L.Polygon)) {
-        type = 'Polygon';
-        latlngs = LatLngsToCoords(layer._latlngs, 1);
-        return JSON.stringify({"type": type, "coordinates": [latlngs]});
+    } else if (L.Polygon && (layer instanceof L.Polygon)) {
+      type = 'Polygon';
+      latlngs = LatLngsToCoords(layer._latlngs, 1);
+      return JSON.stringify({"type": type, "coordinates": [latlngs]});
 
-      } else if (L.Polyline && (layer instanceof L.Polyline)) {
-        type = 'LineString';
-        latlngs = LatLngsToCoords(layer._latlngs);
-        return JSON.stringify({"type": type, "coordinates": latlngs});
+    } else if (L.Polyline && (layer instanceof L.Polyline)) {
+      type = 'LineString';
+      latlngs = LatLngsToCoords(layer._latlngs);
+      return JSON.stringify({"type": type, "coordinates": latlngs});
 
-      }
     }
+  }
 
-    var LatLngToCoords = function (LatLng, reverse) { // (LatLng, Boolean) -> Array
-      var lat = parseFloat(reverse ? LatLng.lng : LatLng.lat),
-        lng = parseFloat(reverse ? LatLng.lat : LatLng.lng);
-
-      return [lng,lat];
-    }
+  var LatLngToCoords = function (LatLng, reverse) { // (LatLng, Boolean) -> Array
+    var lat = parseFloat(reverse ? LatLng.lng : LatLng.lat),
+      lng = parseFloat(reverse ? LatLng.lat : LatLng.lng);
 
-    var LatLngsToCoords = function (LatLngs, levelsDeep, reverse) { // (LatLngs, Number, Boolean) -> Array
-      var coord,
-        coords = [],
-        i, len;
+    return [lng,lat];
+  }
 
-      for (i = 0, len = LatLngs.length; i < len; i++) {
-          coord = levelsDeep ?
-                  LatLngToCoords(LatLngs[i], levelsDeep - 1, reverse) :
-                  LatLngToCoords(LatLngs[i], reverse);
-          coords.push(coord);
-      }
+  var LatLngsToCoords = function (LatLngs, levelsDeep, reverse) { // (LatLngs, Number, Boolean) -> Array
+    var coord,
+    coords = [],
+      i, len;
 
-      return coords;
+    for (i = 0, len = LatLngs.length; i < len; i++) {
+      coord = levelsDeep ?
+        LatLngToCoords(LatLngs[i], levelsDeep - 1, reverse) :
+        LatLngToCoords(LatLngs[i], reverse);
+      coords.push(coord);
     }
 
+    return coords;
+  }
+
 }(jQuery));
diff --git a/leaflet_widget.module b/leaflet_widget.module
index 127b148..842f589 100644
--- a/leaflet_widget.module
+++ b/leaflet_widget.module
@@ -172,6 +172,7 @@ function leaflet_widget_field_widget_form(&$form, &$form_state, $field, $instanc
 
       // Include javascript.
       $widget['#attached']['library'][] = array('leaflet_widget', 'draw');
+      $widget['#attached']['library'][] = array('system', 'ui.tabs');
 
       //Check if we need to add geographic areas
       if (isset($settings['geographic_areas']) && $settings['geographic_areas']) {

From 5dd2e4eb4f44280d5db0299b22c75ce17bd11d43 Mon Sep 17 00:00:00 2001
From: Riadh Habbachi <riadh@angrycactus.biz>
Date: Tue, 8 Sep 2015 19:23:47 +0100
Subject: [PATCH 2/7] Update the field's input when updating the map.

* Fix missing geojson propreties.
---
 js/draw.js | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/js/draw.js b/js/draw.js
index b95f2c4..8c442e9 100644
--- a/js/draw.js
+++ b/js/draw.js
@@ -61,12 +61,9 @@
         leafletWidgetLayerRemove(map._layers, Items);
         // Add new layer.
         Items.addLayer(layer);
-      });
 
-      $(item).parents('form').submit(function(event){
-        if ($('#' + id + '-toggle').hasClass('map')) {
-          leafletWidgetFormWrite(map._layers, id)
-        }
+        // Update the field input.
+        leafletWidgetFormWrite(Items._layers, id)
       });
 
       Drupal.leaflet_widget[id] = map;
@@ -207,7 +204,8 @@
     var write  = Array();
     for (var key in layers) {
       if (layers[key]._latlngs || layers[key]._latlng) {
-        write.push(layerToGeometry(layers[key]));
+        var feature = '{ "type": "Feature","geometry":' + layerToGeometry(layers[key]) + '}';
+        write.push(feature);
       }
     }
     // If no value then provide empty collection.

From d02020d1276c55e36e2c995d5d4b4711cb02c55f Mon Sep 17 00:00:00 2001
From: Jacinto capote Robles <jacintocapote@gmail.com>
Date: Thu, 10 Sep 2015 22:01:38 +0200
Subject: [PATCH 3/7] Fixed problem deleting items after use the new interface
 with the select regions

---
 js/draw.js | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/js/draw.js b/js/draw.js
index 8c442e9..62b33dc 100644
--- a/js/draw.js
+++ b/js/draw.js
@@ -47,7 +47,7 @@
           polyline: options.draw.tools.polyline
         },
         edit: {
-          featureGroup: Items
+          featureGroup: Items,
         }
       });
 
@@ -60,7 +60,7 @@
         // per field.
         leafletWidgetLayerRemove(map._layers, Items);
         // Add new layer.
-        Items.addLayer(layer);
+          Items.addLayer(layer);
 
         // Update the field input.
         leafletWidgetFormWrite(Items._layers, id)
@@ -187,7 +187,12 @@
             json_data = jQuery.parseJSON(options.areas[i]);
             $.each(json_data.features, function (index, item) {
               if (item.id == area) {
-                L.geoJson(item).addTo(map);
+                  var geojson = L.geoJson(item, {
+                      onEachFeature: function (feature, layer) {
+                          Items.addLayer(layer);
+
+                      }
+                  });
                 leafletWidgetFormWrite(map._layers, id);
               }
             });

From 535f6b155d10a9154f6fa7ff819f6d05411b7464 Mon Sep 17 00:00:00 2001
From: Jacinto capote Robles <jacintocapote@gmail.com>
Date: Thu, 10 Sep 2015 22:05:16 +0200
Subject: [PATCH 4/7] Fixed label to use region instead state

---
 js/draw.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/js/draw.js b/js/draw.js
index 62b33dc..d148ed3 100644
--- a/js/draw.js
+++ b/js/draw.js
@@ -167,7 +167,7 @@
 
       if (options.geographic_areas) {
         var json_data = {};
-        var selectList = "<div class='geographic_areas_desc'><p></br>Select a state to add into the map:</p><select id='geographic_areas' name='area'>";
+        var selectList = "<div class='geographic_areas_desc'><p></br>Select a region to add into the map:</p><select id='geographic_areas' name='area'>";
         selectList += "<option value='0'>" + Drupal.t('-none-') + "</option>";
 
         for (i = 0; i < options.areas.length; i++) {

From 67c4e01dd6349adae73857edc9ec5f5462edfb23 Mon Sep 17 00:00:00 2001
From: Jacinto capote Robles <jacintocapote@gmail.com>
Date: Fri, 11 Sep 2015 22:07:28 +0200
Subject: [PATCH 5/7] Fixed problem deleting and saving a polygon

---
 js/draw.js | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/js/draw.js b/js/draw.js
index d148ed3..ab29110 100644
--- a/js/draw.js
+++ b/js/draw.js
@@ -66,6 +66,10 @@
         leafletWidgetFormWrite(Items._layers, id)
       });
 
+      map.on('draw:deleted', function (e) {
+        $('#' + id + '-input').val('');
+      });
+
       Drupal.leaflet_widget[id] = map;
 
       if (options.toggle) {
@@ -189,6 +193,9 @@
               if (item.id == area) {
                   var geojson = L.geoJson(item, {
                       onEachFeature: function (feature, layer) {
+                          // Remove already created layers. We only want to save one
+                          // per field.
+                          leafletWidgetLayerRemove(map._layers, Items);
                           Items.addLayer(layer);
 
                       }

From 1e785275c816e7f57ed0ff3fc1e60e6be30c980d Mon Sep 17 00:00:00 2001
From: Aaron Couch <acinternets@gmail.com>
Date: Mon, 28 Sep 2015 16:42:40 -0500
Subject: [PATCH 6/7] Update leaflet_widget.module

Fixes for https
---
 leaflet_widget.module | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/leaflet_widget.module b/leaflet_widget.module
index 842f589..623be6a 100644
--- a/leaflet_widget.module
+++ b/leaflet_widget.module
@@ -335,7 +335,7 @@ function leaflet_widget_geojson_feature($wkt, $properties = array()) {
  */
 function leaflet_widget_leaflet_widget_base_layers() {
   return array(
-    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' => 'OSM Mapnik',
+    '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' => 'OSM Mapnik',
   );
 }
 

From 5ae229a01a9f2ac94c63fedfcd91da88b97a7bc5 Mon Sep 17 00:00:00 2001
From: Riadh Habbachi <riadh@angrycactus.biz>
Date: Wed, 4 Nov 2015 12:11:59 +0100
Subject: [PATCH 7/7] Add test based on NuCivic/leaflet_draw_widget#8

* Better travis file copied from other repo.
* Use dkanextension.
* Fixes for leaflet_widget.feature
---
 .travis.yml                                | 73 ++++++++++++++++++++++
 test/.gitignore                            |  4 ++
 test/behat.yml                             | 49 +++++++++++++++
 test/composer.json                         |  8 +++
 test/features/bootstrap/FeatureContext.php | 20 ++++++
 test/features/leaflet_widget.feature       | 21 +++++++
 6 files changed, 175 insertions(+)
 create mode 100644 .travis.yml
 create mode 100644 test/.gitignore
 create mode 100644 test/behat.yml
 create mode 100644 test/composer.json
 create mode 100644 test/features/bootstrap/FeatureContext.php
 create mode 100644 test/features/leaflet_widget.feature

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..7756401
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,73 @@
+language: php
+
+php:
+  - 5.5
+
+mysql:
+  database: leaflet_draw_widget_test
+  username: root
+  encoding: utf8
+
+install:
+  - cd test
+  - composer install
+  - mysql -e 'create database leaflet_draw_widget_test;'
+  - sudo apt-get update > /dev/null
+  - sudo apt-get --quiet=2 install php5-cgi php5-curl php5-gd php5-mysql > /dev/null
+
+  # Install latest Drush 7.
+  - export PATH="$HOME/.composer/vendor/bin:$PATH"
+  - composer global require --no-interaction drush/drush:dev-master
+  - composer global require --no-interaction youngj/httpserver:*
+  - drush dl registry_rebuild
+  # Disable sendmail
+  - echo sendmail_path=`which true` >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
+
+before_script:
+  # Navigate out of TRAVIS_BUILD_DIR to prevent blown stack by recursive module lookup
+  - cd ../..
+  # Grab dkan
+  - git clone --branch 7.x-1.x https://github.com/NuCivic/dkan.git
+  # Prepare install
+  - mkdir drupal
+  - cd drupal
+  - cp ../dkan/drupal-org-core.make ./
+  - drush make --prepare-install drupal-org-core.make --yes
+  - cp -R ../dkan profiles/
+  - cd profiles/dkan
+  - drush -y make --no-core --contrib-destination=./ drupal-org.make --no-recursion
+  - cd ../..
+  # Create Nucivic Directory and Copy working copy to proper dir
+  - mkdir sites/all/modules/nucivic
+  - cp -r $TRAVIS_BUILD_DIR sites/all/modules/nucivic/leaflet_draw_widget
+  - drush -y make --no-core sites/all/modules/nucivic/leaflet_draw_widget/leaflet_widget.make --no-recursion
+  # Go back to TRAVIS_BUILD_DIR and move drupal build inside the test folder
+  - cd $TRAVIS_BUILD_DIR/test
+  - mv ../../drupal ./
+  # Install dkan
+  - cd drupal
+  - drush si dkan --sites-subdir=default --db-url=mysql://root:@127.0.0.1:3306/leaflet_draw_widget_test --account-name=admin --account-pass=admin  --site-name="DKAN" install_configure_form.update_status_module='array(FALSE,FALSE)' --yes
+  # Enable module
+  - drush -y en leaflet_widget
+  - drush rr all
+  - drush ev 'node_access_rebuild();'
+  # Clear cache and run webserver
+  - drush cc all --yes
+  - drush --quiet --yes --root=$PWD runserver :8888 > /dev/null 2>&1 &
+  - sleep 4
+  # Setup display for selenium
+  - export DISPLAY=:99.0
+  - sh -e /etc/init.d/xvfb start
+  - sleep 3
+  # Download and run selenium
+  - cd ..
+  - wget http://selenium-release.storage.googleapis.com/2.42/selenium-server-standalone-2.42.2.jar
+  - java -jar selenium-server-standalone-2.42.2.jar -quiet -p 4444 -log shut_up_selenium &
+  - sleep 5
+
+script:
+  - bin/behat features/leaflet_draw_widget.feature
+
+notifications:
+  slack:
+    rooms:
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..ac83d63
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,4 @@
+bin/
+vendor
+composer.lock
+.idea
diff --git a/test/behat.yml b/test/behat.yml
new file mode 100644
index 0000000..f785ff6
--- /dev/null
+++ b/test/behat.yml
@@ -0,0 +1,49 @@
+# behat.yml
+
+default:
+  suites:
+    default:
+      contexts:
+          - FeatureContext
+          # Load the Drupal Context from DrupalExtension
+          - Drupal\DrupalExtension\Context\DrupalContext
+          # Load the generic DKAN context
+          - Drupal\DKANExtension\Context\DKANContext
+          # Load DKAN Groups functionality
+          - Drupal\DKANExtension\Context\GroupContext
+          # Load DKAN Page functionality
+          - Drupal\DKANExtension\Context\PageContext
+          # Load DKAN Page functionality
+          - Drupal\DKANExtension\Context\DatasetContext
+      gherkin:
+        filters:
+          tags: ~@wip
+      formatters:
+        pretty: true
+      extensions:
+        Behat\MinkExtension:
+          base_url: http://127.0.0.1
+      selenium2: ~
+      goutte: ~
+      show_cmd: firefox %s
+      Drupal\DrupalExtension:
+        blackbox: ~
+      drupal:
+        drupal_root: %paths.base%/drupal
+      drush:
+        alias: @self
+      api_driver: 'drupal'
+        # @todo fixup these regions for use on hhs
+      region_map:
+        navigation: '.region-navigation'
+        breadcrumb: '.breadcrumb'
+        left_sidebar: '.panel-col-first'
+        search_area: '.panel-col-last'
+        dropdown_links: '.comment-main .links.inline.dropdown-menu'
+        comment: '.comment-main'
+      selectors:
+        message_selector: '.alert'
+        error_message_selector: '.alert.alert-error'
+        success_message_selector: '.alert.alert-success'
+
+
diff --git a/test/composer.json b/test/composer.json
new file mode 100644
index 0000000..b96d3a9
--- /dev/null
+++ b/test/composer.json
@@ -0,0 +1,8 @@
+{
+  "require": {
+    "nucivic/dkanextension": "dev-master"
+  },
+  "config": {
+    "bin-dir": "bin/"
+  }
+}
diff --git a/test/features/bootstrap/FeatureContext.php b/test/features/bootstrap/FeatureContext.php
new file mode 100644
index 0000000..ac2ecb2
--- /dev/null
+++ b/test/features/bootstrap/FeatureContext.php
@@ -0,0 +1,20 @@
+<?php
+
+use Drupal\DKANExtension\Context\RawDKANContext;
+
+/**
+ * Defines application features from the specific context.
+ */
+class FeatureContext extends RawDKANContext {
+
+  /**
+   * Initializes context.
+   *
+   * Every scenario gets its own context instance.
+   * You can also pass arbitrary arguments to the
+   * context constructor through behat.yml.
+   */
+  public function __construct() {
+  }
+
+}
diff --git a/test/features/leaflet_widget.feature b/test/features/leaflet_widget.feature
new file mode 100644
index 0000000..8266682
--- /dev/null
+++ b/test/features/leaflet_widget.feature
@@ -0,0 +1,21 @@
+Feature: Leaflet Widget Tests.
+
+  Scenario: Authenticated users should be able to use the Leaflet Widget to input GeoJson data.
+    Given datasets:
+      | title        | description            |
+      | test dataset | this is a test dataset |
+
+    Given I am a user with the "authenticated user" role
+    When I edit "Test Dataset"
+    Then I should see "Select a state to add into the map"
+    When I select "Georgia" from "#geographic_areas"
+    And I click "edit-submit"
+    Then I should see "POLYGON ((-83.109191 35.00118" or Then I should see the geojson for "Georgia"
+
+  Scenario: Authenticated users should be able to input GeoJson data manually.
+    Given I am a user with the "authenticated user" role
+    When I edit "Test Dataset"
+    And I click "Add Data Manually"
+    And I enter "invalid json" in ".geofield_wkt"
+    And I click "Submit"
+    Then I should see "Invalid Geojson"