519 lines
21 KiB
JavaScript
519 lines
21 KiB
JavaScript
CKEDITOR.dialog.add('leaflet', function(editor) {
|
|
var autocomplete;
|
|
var mapContainer = '';
|
|
|
|
// Access the current translation file.
|
|
var pluginTranslation = editor.lang.leaflet;
|
|
|
|
// Use the core translation file. Used mainly for the `Alignment` values.
|
|
var commonTranslation = editor.lang.common;
|
|
|
|
// Dialog's function callback for the Leaflet Map Widget.
|
|
return {
|
|
title: pluginTranslation.dialogTitle,
|
|
minWidth: 320,
|
|
minHeight: 125,
|
|
|
|
contents: [{
|
|
// Create a Location tab.
|
|
id: 'location_tab',
|
|
label: pluginTranslation.locationTabLabel,
|
|
elements: [
|
|
// {
|
|
// id: 'map_geocode',
|
|
// className: 'geocode',
|
|
// type: 'text',
|
|
// label: pluginTranslation.googleSearchFieldLabel,
|
|
// style: 'margin-top: -7px;',
|
|
//
|
|
// setup: function(widget) {
|
|
// this.setValue('');
|
|
// },
|
|
//
|
|
// onLoad: function (widget) {
|
|
// // Get the DOM reference for the Search field.
|
|
// var input = this.getInputElement().$;
|
|
//
|
|
// // Set a diffused/default text for better user experience.
|
|
// // This will override the Google's default placeholder text:
|
|
// // 'Enter a location'.
|
|
// jQuery('.geocode input').attr('placeholder', pluginTranslation.googleSearchFieldHint);
|
|
//
|
|
// var config = editor.config;
|
|
//
|
|
// // Default value, but eventually will reach its quota if many users
|
|
// // will just utilize this key instead of creating their own.
|
|
// var googleApiKey = 'AIzaSyA9ySM6msnGm0qQB1L1cLTMBdKEUKPySmQ';
|
|
//
|
|
// if (typeof config.leaflet_maps_google_api_key != 'undefined' && config.leaflet_maps_google_api_key != '') {
|
|
// googleApiKey = config.leaflet_maps_google_api_key;
|
|
// }
|
|
//
|
|
// // Execute only once, and not every dialog pop-up.
|
|
// if (typeof google == 'undefined') {
|
|
// // Load other needed external library.
|
|
// // Wait for the script to finish loading before binding
|
|
// // the autocomplete mechanism to prevent rendering issue.
|
|
// CKEDITOR.scriptLoader.load('//maps.googleapis.com/maps/api/js?libraries=places&callback=dummy&key=' + googleApiKey, function() {
|
|
// // Bind the Search field to the Autocomplete widget.
|
|
// autocomplete = new google.maps.places.Autocomplete(input);
|
|
// });
|
|
// } else {
|
|
// autocomplete = new google.maps.places.Autocomplete(input);
|
|
// }
|
|
//
|
|
// // Fix for the Google's type-ahead search displaying behind
|
|
// // the widgets dialog window.
|
|
// // Basically, we want to override the z-index of the
|
|
// // Seach Autocomplete list, in which the styling is being set
|
|
// // in real-time by Google.
|
|
// // Make a new DOM element.
|
|
// var stylesheet = jQuery('<style type="text/css" />');
|
|
//
|
|
// // Set the inner HTML. Include also the vertical alignment
|
|
// // adjustment for the MiniMap checkbox.
|
|
// stylesheet.html('.pac-container { z-index: 100000 !important;} input.minimap { margin-top: 18px !important; }');
|
|
//
|
|
// // Append to the main document's Head section.
|
|
// jQuery('head').append(stylesheet);
|
|
// },
|
|
// },
|
|
|
|
{ // Dummy element serving as label/text container only.
|
|
type: 'html',
|
|
id: 'map_label',
|
|
className: 'label',
|
|
style: 'margin-bottom: -10px;',
|
|
html: '<p>' + pluginTranslation.manualCoordinatesFieldLabel + '</p>'
|
|
},
|
|
|
|
{
|
|
// Create a new horizontal group.
|
|
type: 'hbox',
|
|
// Set the relative widths of Latitude, Longitude and Zoom fields.
|
|
widths: [ '50%', '50%' ],
|
|
children: [
|
|
{
|
|
id: 'map_latitude',
|
|
className: 'latitude',
|
|
type: 'text',
|
|
label: pluginTranslation.manualLatitudeFieldLabel,
|
|
|
|
setup: function(widget) {
|
|
// Set the Lat values if widget has previous value.
|
|
if (widget.element.data('lat') !== '') {
|
|
// Update the data-lat based on the map lat in iframe.
|
|
// Make sure that mapContainer is set.
|
|
// Also avoids setting it again since zoom/longitude
|
|
// might already computed/set this object.
|
|
if (mapContainer === '') {
|
|
mapContainer = widget.element.getChild(0).$.contentDocument.getElementById('map_container');
|
|
}
|
|
|
|
var currentLat = mapContainer.getAttribute('data-lat');
|
|
|
|
this.setValue(currentLat);
|
|
}
|
|
},
|
|
},
|
|
|
|
{
|
|
id: 'map_longitude',
|
|
className: 'longitude',
|
|
type: 'text',
|
|
label: pluginTranslation.manualLongitudeFieldLabel,
|
|
|
|
setup: function(widget) {
|
|
// Set the Lon values if widget has previous value.
|
|
if (widget.element.data('lat') !== '') {
|
|
// Update the data-lon based on the map lon in iframe.
|
|
// Make sure that mapContainer is set.
|
|
// Also avoids setting it again since zoom/latitude
|
|
// might already computed/set this object.
|
|
if (mapContainer === '') {
|
|
mapContainer = widget.element.getChild(0).$.contentDocument.getElementById('map_container');
|
|
}
|
|
|
|
var currentLon = mapContainer.getAttribute('data-lon');
|
|
|
|
this.setValue(currentLon);
|
|
}
|
|
},
|
|
},
|
|
]
|
|
},
|
|
|
|
{
|
|
id: 'popup_text',
|
|
className: 'popup-text',
|
|
type: 'text',
|
|
label: pluginTranslation.popupTextFieldLabel,
|
|
style: 'margin-bottom: 8px;',
|
|
|
|
setup: function(widget) {
|
|
// Set the Lat values if widget has previous value.
|
|
if (widget.element.data('popup-text') != '') {
|
|
this.setValue(widget.element.data('popup-text'));
|
|
}
|
|
|
|
else {
|
|
// Set a diffused/default text for better user experience.
|
|
this.getInputElement().setAttribute('placeholder', pluginTranslation.popupTextFieldHint)
|
|
}
|
|
},
|
|
},
|
|
]
|
|
},
|
|
|
|
{
|
|
// Create an Options tab.
|
|
id: 'options_tab',
|
|
label: pluginTranslation.optionsTabLabel,
|
|
elements: [
|
|
{
|
|
// Create a new horizontal group.
|
|
type: 'hbox',
|
|
style: 'margin-top: -7px;',
|
|
// Set the relative widths of Latitude, Longitude and Zoom fields.
|
|
widths: [ '38%', '38%', '24%' ],
|
|
children: [
|
|
{
|
|
id: 'width',
|
|
className: 'map_width',
|
|
type: 'text',
|
|
label: pluginTranslation.mapWidthFieldLabel,
|
|
|
|
setup: function(widget) {
|
|
// Set a diffused/default text for better user experience.
|
|
this.getInputElement().setAttribute('placeholder', '400')
|
|
|
|
// Set the map width value if widget has a previous value.
|
|
if (widget.element.data('width') != '') {
|
|
this.setValue(widget.element.data('width'));
|
|
}
|
|
},
|
|
},
|
|
|
|
{
|
|
id: 'height',
|
|
className: 'map_height',
|
|
type: 'text',
|
|
label: pluginTranslation.mapHeightFieldLabel,
|
|
|
|
setup: function(widget) {
|
|
// Set a diffused/default text for better user experience.
|
|
this.getInputElement().setAttribute('placeholder', '400');
|
|
|
|
// Set the map height value if widget has a previous value.
|
|
if (widget.element.data('height') != '') {
|
|
this.setValue(widget.element.data('height'));
|
|
}
|
|
},
|
|
},
|
|
|
|
{
|
|
// Create a select list for Zoom Levels.
|
|
// 'className' attribute is used for targeting this element in jQuery.
|
|
id: 'map_zoom',
|
|
className: 'zoom',
|
|
type: 'select',
|
|
label: pluginTranslation.mapZoomLevelFieldLabel,
|
|
width: '70px',
|
|
items: [['1'], ['2'], ['3'], ['4'],['5'], ['6'], ['7'], ['8'], ['9'], ['10'], ['11'], ['12'], ['13'], ['14'], ['15'], ['16'], ['17'], ['18'], ['19'], ['20']],
|
|
|
|
// This will execute also every time you edit/double-click the widget.
|
|
setup: function(widget) {
|
|
// Set this Zoom Level's select list when
|
|
// the current location has been initialized and set previously.
|
|
if (widget.element.data('zoom') != '') {
|
|
// Update the data-zoom based on the map zoom level in iframe.
|
|
// Make sure that mapContainer is set.
|
|
// Also avoids setting it again since latitude/longitude
|
|
// might already computed/set this object.
|
|
if (mapContainer === '') {
|
|
mapContainer = widget.element.getChild(0).$.contentDocument.getElementById('map_container');
|
|
}
|
|
|
|
var currentZoom = mapContainer.getAttribute('data-zoom');
|
|
|
|
this.setValue(currentZoom);
|
|
}
|
|
|
|
// Set the Default Zoom Level value.
|
|
else {
|
|
this.setValue('10');
|
|
}
|
|
},
|
|
}
|
|
]
|
|
},
|
|
|
|
{
|
|
// Create a new horizontal group.
|
|
type: 'hbox',
|
|
// Set the relative widths for the tile and overview map fields.
|
|
widths: [ '50%', '50%' ],
|
|
children: [
|
|
{
|
|
// Create a select list for map tiles.
|
|
// 'className' attribute is used for targeting this element in jQuery.
|
|
type: 'select',
|
|
id: 'map_tile',
|
|
className: 'tile',
|
|
label: pluginTranslation.baseMapTileLabel,
|
|
items: [['OpenStreetMap.Mapnik'], ['OpenStreetMap.DE'], ['OpenStreetMap.HOT'], ['Esri.DeLorme'], ['Esri.NatGeoWorldMap'], ['Esri.WorldPhysical'], ['Esri.WorldTopoMap'], ['Thunderforest.OpenCycleMap'], ['Thunderforest.Landscape'], ['Stamen.Watercolor']],
|
|
|
|
// This will execute also every time you edit/double-click the widget.
|
|
setup: function(widget) {
|
|
var restrictedTiles = ['MapQuestOpen.Aerial', 'MapQuestOpen.OSM'];
|
|
|
|
var tile = widget.element.data('tile');
|
|
|
|
// Set the Tile data attribute.
|
|
// Must not be the restricted, MapQuest tiles.
|
|
if ( tile != '' && restrictedTiles.indexOf(tile) == -1 ) {
|
|
this.setValue(tile);
|
|
}
|
|
|
|
else {
|
|
// Set the default value.
|
|
// Includes the case for existing MapQuest tiles.
|
|
this.setValue('OpenStreetMap.Mapnik');
|
|
}
|
|
},
|
|
|
|
// This will execute every time you click the Dialog's OK button.
|
|
// It will inject a map iframe in the CKEditor page.
|
|
commit: function(widget) {
|
|
var dialog = this.getDialog();
|
|
|
|
// Remove the iframe if it has one.
|
|
widget.element.setHtml('');
|
|
|
|
// Retrieve the value in the Search field.
|
|
var geocode = ''; //dialog.getContentElement('location_tab','map_geocode').getValue();
|
|
var latitude, longitude;
|
|
|
|
if (geocode != '') {
|
|
// No need to call the encodeURIComponent().
|
|
var geocodingRequest = '//maps.googleapis.com/maps/api/geocode/json?address=' + geocode + '&sensor=false';
|
|
|
|
// Disable the asynchoronous behavior temporarily so that
|
|
// waiting for results will happen before proceeding
|
|
// to the next statements.
|
|
jQuery.ajaxSetup({
|
|
async: false
|
|
});
|
|
|
|
// Geocode the retrieved place name.
|
|
jQuery.getJSON(geocodingRequest, function(data) {
|
|
if (data['status'] != 'ZERO_RESULTS') {
|
|
// Get the Latitude and Longitude object in the
|
|
// returned JSON object.
|
|
latitude = data.results[0].geometry.location.lat;
|
|
longitude = data.results[0].geometry.location.lng;
|
|
}
|
|
|
|
// Handle queries with no results or have some
|
|
// malformed parameters.
|
|
else {
|
|
alert('The Place could not be Geocoded properly. Kindly choose another one.')
|
|
}
|
|
});
|
|
}
|
|
|
|
// Get the Lat/Lon values from the corresponding fields.
|
|
var latInput = dialog.getContentElement('location_tab','map_latitude').getValue();
|
|
var lonInput = dialog.getContentElement('location_tab','map_longitude').getValue();
|
|
|
|
// Get the data-lat and data-lon values.
|
|
// It is empty for yet to be created widgets.
|
|
var latSaved = widget.element.data('lat');
|
|
var lonSaved = widget.element.data('lon');
|
|
|
|
// Used the inputted values if it's not empty or
|
|
// not equal to the previously saved values.
|
|
// latSaved and lonSaved are initially empty also
|
|
// for widgets that are yet to be created.
|
|
// Or if the user edited an existing map, and did not edit
|
|
// the lat/lon fields, and the Search field is empty.
|
|
if ((latInput != '' && lonInput != '') && ((latInput != latSaved && lonInput != lonSaved) || geocode == '')) {
|
|
latitude = latInput;
|
|
longitude = lonInput;
|
|
}
|
|
|
|
var width = dialog.getContentElement('options_tab','width').getValue() || '400';
|
|
var height = dialog.getContentElement('options_tab','height').getValue() || '400';
|
|
var zoom = dialog.getContentElement('options_tab','map_zoom').getValue();
|
|
var popUpText = dialog.getContentElement('location_tab','popup_text').getValue();
|
|
var tile = dialog.getContentElement('options_tab','map_tile').getValue();
|
|
var alignment = dialog.getContentElement('options_tab','map_alignment').getValue();
|
|
|
|
// Returns 'on' or 'off'.
|
|
var minimap = dialog.getContentElement('options_tab','map_mini').getValue()?'on':'off';
|
|
|
|
// Get a unique timestamp:
|
|
var milliseconds = new Date().getTime();
|
|
|
|
// Set/Update the widget's data attributes.
|
|
widget.element.setAttribute('id', 'leaflet_div-' + milliseconds);
|
|
|
|
widget.element.data('lat', latitude);
|
|
widget.element.data('lon', longitude);
|
|
widget.element.data('width', width);
|
|
widget.element.data('height', height);
|
|
widget.element.data('zoom', zoom);
|
|
widget.element.data('popup-text', popUpText);
|
|
widget.element.data('tile', tile);
|
|
widget.element.data('minimap', minimap);
|
|
widget.element.data('alignment', alignment);
|
|
|
|
// Remove the previously set alignment class.
|
|
// Only one alignment class is set per map.
|
|
widget.element.removeClass('align-left');
|
|
widget.element.removeClass('align-right');
|
|
widget.element.removeClass('align-center');
|
|
|
|
// Set the alignment for this map.
|
|
widget.element.addClass('align-' + alignment);
|
|
|
|
// Returns 'on' or 'off'.
|
|
var responsive = dialog.getContentElement('options_tab','map_responsive').getValue()?'on':'off';
|
|
|
|
// Use 'off' if the Responsive checkbox is unchecked.
|
|
if (responsive === 'off') {
|
|
// Remove the previously set responsive map class,
|
|
// if there's any.
|
|
widget.element.removeClass('responsive-map');
|
|
}
|
|
|
|
else {
|
|
// Add a class for styling.
|
|
widget.element.addClass('responsive-map');
|
|
}
|
|
|
|
// Set the 'responsive' data attribute.
|
|
widget.element.data('responsive', responsive);
|
|
|
|
// Build the full path to the map renderer.
|
|
mapParserPathFull = mapParserPath + '?lat=' + latitude + '&lon=' + longitude + '&width=' + width + '&height=' + height + '&zoom=' + zoom + '&text=' + popUpText + '&tile=' + tile + '&minimap=' + minimap + '&responsive=' + responsive;
|
|
|
|
// Create a new CKEditor DOM's iFrame.
|
|
var iframe = new CKEDITOR.dom.element('iframe');
|
|
|
|
// Setup the iframe characteristics.
|
|
iframe.setAttributes({
|
|
'scrolling': 'no',
|
|
'id': 'leaflet_iframe-' + milliseconds,
|
|
'class': 'leaflet_iframe',
|
|
'width': width + 'px',
|
|
'height': height + 'px',
|
|
'frameborder': 0,
|
|
'allowTransparency': true,
|
|
'src': mapParserPathFull,
|
|
'data-cke-saved-src': mapParserPathFull
|
|
});
|
|
|
|
// If map is responsive.
|
|
if (responsive == 'on') {
|
|
// Add a class for styling.
|
|
iframe.setAttribute('class', 'leaflet_iframe responsive-map-iframe');
|
|
}
|
|
|
|
// Insert the iframe to the widget's DIV element.
|
|
widget.element.append(iframe);
|
|
},
|
|
},
|
|
|
|
{
|
|
type: 'checkbox',
|
|
id: 'map_mini',
|
|
className: 'minimap',
|
|
label: pluginTranslation.minimapCheckboxLabel,
|
|
|
|
// This will execute also every time you edit/double-click the widget.
|
|
setup: function(widget) {
|
|
// Set the MiniMap check button.
|
|
if (widget.element.data('minimap') != '' && widget.element.data('minimap') != 'on') {
|
|
this.setValue('');
|
|
}
|
|
|
|
else {
|
|
// Set the default value.
|
|
this.setValue('true');
|
|
}
|
|
},
|
|
}
|
|
]
|
|
},
|
|
|
|
{
|
|
// Create a new horizontal group.
|
|
type: 'hbox',
|
|
// Set the relative widths for alignment and responsive options.
|
|
widths: [ '50%', '50%' ],
|
|
children: [
|
|
{
|
|
// Create a select list for Map Alignment.
|
|
// 'className' attribute is used for targeting this element in jQuery.
|
|
id: 'map_alignment',
|
|
className: 'alignment',
|
|
type: 'select',
|
|
label: commonTranslation.align,
|
|
items: [[commonTranslation.alignLeft, 'left'], [commonTranslation.alignRight, 'right'], [commonTranslation.alignCenter, 'center']],
|
|
style: 'margin-bottom: 4px;',
|
|
|
|
// This will execute also every time you edit/double-click the widget.
|
|
setup: function(widget) {
|
|
// Set this map alignment's select list when
|
|
// the current map has been initialized and set previously.
|
|
if (widget.element.data('alignment') != '') {
|
|
// Set the alignment.
|
|
this.setValue(widget.element.data('alignment'));
|
|
}
|
|
|
|
// Set the Default alignment value.
|
|
else {
|
|
this.setValue('left');
|
|
}
|
|
},
|
|
},
|
|
|
|
{
|
|
type: 'checkbox',
|
|
id: 'map_responsive',
|
|
className: 'responsive',
|
|
label: pluginTranslation.responsiveMapCheckboxLabel,
|
|
// style: 'margin-top: 18px;',
|
|
|
|
// This will execute also every time you edit/double-click the widget.
|
|
setup: function(widget) {
|
|
// Set the Responsive check button, when editing widget.
|
|
if (widget.element.data('responsive') != '') {
|
|
if (widget.element.data('responsive') == 'on') {
|
|
this.setValue('true');
|
|
}
|
|
|
|
else {
|
|
this.setValue('');
|
|
}
|
|
}
|
|
|
|
// Set the default value for new ones.
|
|
else {
|
|
this.setValue('');
|
|
}
|
|
},
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}],
|
|
onHide: function(){
|
|
// Reset/clear the map iframe/DOM object reference.
|
|
// Fixes bug with lon/lat/zoom artifact values when closing dialog by pressing anything except ok.
|
|
mapContainer = '';
|
|
}
|
|
};
|
|
});
|