178 lines
4.4 KiB
JavaScript
Executable File
178 lines
4.4 KiB
JavaScript
Executable File
var $ = require('jquery');
|
|
var _ = require('underscore');
|
|
var CoreView = require('backbone/core-view');
|
|
var template = require('./enter-url.tpl');
|
|
var CustomBaselayerModel = require('builder/data/custom-baselayer-model');
|
|
var TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
|
|
|
|
/**
|
|
* Represents the XYZ tab content.
|
|
*/
|
|
|
|
module.exports = CoreView.extend({
|
|
|
|
className: 'XYZPanel',
|
|
|
|
events: {
|
|
'click .js-tms': '_changeTMS',
|
|
'keydown .js-url': '_onKeydown',
|
|
'paste .js-url': '_onPaste'
|
|
},
|
|
|
|
initialize: function (opts) {
|
|
if (!opts.submitButton) throw new Error('submitButton is required');
|
|
|
|
this._submitButton = opts.submitButton;
|
|
this._lastCallSeq = 0;
|
|
this._debouncedUpdate = _.debounce(this._update.bind(this), 150);
|
|
|
|
this._initBinds();
|
|
},
|
|
|
|
render: function () {
|
|
this.clearSubViews();
|
|
|
|
this._updateOkBtn();
|
|
this._disableOkBtn(true);
|
|
|
|
this.$el.html(
|
|
template()
|
|
);
|
|
|
|
this._initViews();
|
|
|
|
return this;
|
|
},
|
|
|
|
_initViews: function () {
|
|
// Add TMS tooltip
|
|
var tooltip = new TipsyTooltipView({
|
|
el: this.$('.js-tms'),
|
|
title: function () {
|
|
return $(this).data('title');
|
|
}
|
|
});
|
|
this.addView(tooltip);
|
|
},
|
|
|
|
_onKeydown: function (e) {
|
|
e.stopPropagation();
|
|
this._debouncedUpdate();
|
|
},
|
|
|
|
_onPaste: function (e) {
|
|
e.stopPropagation();
|
|
this._debouncedUpdate();
|
|
},
|
|
|
|
_initBinds: function () {
|
|
this.model.bind('change:tms', this._setTMSCheckbox, this);
|
|
},
|
|
|
|
_update: function () {
|
|
this._disableOkBtn(true);
|
|
this._indicateIsValidating(true);
|
|
var layer;
|
|
var urlErrorMsg;
|
|
|
|
var url = this.$('.js-url').val();
|
|
var tms = this.model.get('tms');
|
|
|
|
if (url) {
|
|
try {
|
|
layer = this._byCustomURL(url, tms);
|
|
} catch (e) {
|
|
urlErrorMsg = _t('components.modals.add-basemap.xyz.not-valid');
|
|
}
|
|
}
|
|
|
|
this.model.set('layer', layer);
|
|
|
|
if (layer) {
|
|
var self = this;
|
|
// Make sure only the last call made is the one that defines view change,
|
|
// avoids laggy responses to indicate wrong state
|
|
var thisCallSeq = ++this._lastCallSeq;
|
|
layer.validateTemplateURL({
|
|
success: function () {
|
|
if (thisCallSeq === self._lastCallSeq) {
|
|
self._disableOkBtn(false);
|
|
self._indicateIsValidating(false);
|
|
self._updateError();
|
|
}
|
|
},
|
|
error: function () {
|
|
if (thisCallSeq === self._lastCallSeq) {
|
|
self._disableOkBtn(false);
|
|
self._indicateIsValidating(false);
|
|
self._updateError(_t('components.modals.add-basemap.xyz.couldnt-validate'));
|
|
}
|
|
}
|
|
});
|
|
} else if (url) {
|
|
this._indicateIsValidating(false);
|
|
this._updateError(urlErrorMsg);
|
|
} else {
|
|
this._indicateIsValidating(false);
|
|
this._updateError();
|
|
}
|
|
},
|
|
|
|
_changeTMS: function (e) {
|
|
this.model.set('tms', !this.model.get('tms'));
|
|
this._onKeydown(e);
|
|
},
|
|
|
|
_setTMSCheckbox: function (e) {
|
|
this.$('.js-tms .Checkbox-input').toggleClass('is-checked', this.model.get('tms'));
|
|
},
|
|
|
|
_byCustomURL: function (url, tms) {
|
|
// Minimal test for "valid URL" w/o having to complicate it with regex
|
|
if (url && url.indexOf('/') === -1) throw new TypeError('invalid URL');
|
|
|
|
// Only lowercase the placeholder variables, since the URL may contain case-sensitive data (e.g. API keys and such)
|
|
url = url.replace(/\{S\}/g, '{s}')
|
|
.replace(/\{X\}/g, '{x}')
|
|
.replace(/\{Y\}/g, '{y}')
|
|
.replace(/\{Z\}/g, '{z}');
|
|
|
|
var layer = new CustomBaselayerModel({
|
|
urlTemplate: url,
|
|
attribution: null,
|
|
maxZoom: 21,
|
|
minZoom: 0,
|
|
name: '',
|
|
tms: tms,
|
|
category: 'Custom',
|
|
type: 'Tiled'
|
|
});
|
|
layer.set('className', layer._generateClassName(url));
|
|
|
|
return layer;
|
|
},
|
|
|
|
_setTMS: function (ev) {
|
|
var $checkbox = $(ev.target).closest('.Checkbox');
|
|
$checkbox.find('.Checkbox-input').toggleClass('is-checked');
|
|
this._update(ev);
|
|
},
|
|
|
|
_updateOkBtn: function () {
|
|
this._submitButton.find('span').text(_t('components.modals.add-basemap.add-btn'));
|
|
},
|
|
|
|
_disableOkBtn: function (disable) {
|
|
this._submitButton.toggleClass('is-disabled', disable);
|
|
},
|
|
|
|
_updateError: function (msg) {
|
|
this.$('.js-error').text(msg)[ msg ? 'addClass' : 'removeClass' ]('is-visible');
|
|
},
|
|
|
|
_indicateIsValidating: function (indicate) {
|
|
this.$('.js-validating').toggle(!!indicate);
|
|
}
|
|
|
|
});
|