summaryrefslogtreecommitdiffstats
path: root/public/js/vendor/easy-button.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/js/vendor/easy-button.js')
-rw-r--r--public/js/vendor/easy-button.js379
1 files changed, 379 insertions, 0 deletions
diff --git a/public/js/vendor/easy-button.js b/public/js/vendor/easy-button.js
new file mode 100644
index 0000000..f71e072
--- /dev/null
+++ b/public/js/vendor/easy-button.js
@@ -0,0 +1,379 @@
+(function(){
+
+// This is for grouping buttons into a bar
+// takes an array of `L.easyButton`s and
+// then the usual `.addTo(map)`
+L.Control.EasyBar = L.Control.extend({
+
+ options: {
+ position: 'topleft', // part of leaflet's defaults
+ id: null, // an id to tag the Bar with
+ leafletClasses: true // use leaflet classes?
+ },
+
+
+ initialize: function(buttons, options){
+
+ if(options){
+ L.Util.setOptions( this, options );
+ }
+
+ this._buildContainer();
+ this._buttons = [];
+
+ for(var i = 0; i < buttons.length; i++){
+ buttons[i]._bar = this;
+ buttons[i]._container = buttons[i].button;
+ this._buttons.push(buttons[i]);
+ this.container.appendChild(buttons[i].button);
+ }
+
+ },
+
+
+ _buildContainer: function(){
+ this._container = this.container = L.DomUtil.create('div', '');
+ this.options.leafletClasses && L.DomUtil.addClass(this.container, 'leaflet-bar easy-button-container leaflet-control');
+ this.options.id && (this.container.id = this.options.id);
+ },
+
+
+ enable: function(){
+ L.DomUtil.addClass(this.container, 'enabled');
+ L.DomUtil.removeClass(this.container, 'disabled');
+ this.container.setAttribute('aria-hidden', 'false');
+ return this;
+ },
+
+
+ disable: function(){
+ L.DomUtil.addClass(this.container, 'disabled');
+ L.DomUtil.removeClass(this.container, 'enabled');
+ this.container.setAttribute('aria-hidden', 'true');
+ return this;
+ },
+
+
+ onAdd: function () {
+ return this.container;
+ },
+
+ addTo: function (map) {
+ this._map = map;
+
+ for(var i = 0; i < this._buttons.length; i++){
+ this._buttons[i]._map = map;
+ }
+
+ var container = this._container = this.onAdd(map),
+ pos = this.getPosition(),
+ corner = map._controlCorners[pos];
+
+ L.DomUtil.addClass(container, 'leaflet-control');
+
+ if (pos.indexOf('bottom') !== -1) {
+ corner.insertBefore(container, corner.firstChild);
+ } else {
+ corner.appendChild(container);
+ }
+
+ return this;
+ }
+
+});
+
+L.easyBar = function(){
+ var args = [L.Control.EasyBar];
+ for(var i = 0; i < arguments.length; i++){
+ args.push( arguments[i] );
+ }
+ return new (Function.prototype.bind.apply(L.Control.EasyBar, args));
+};
+
+// L.EasyButton is the actual buttons
+// can be called without being grouped into a bar
+L.Control.EasyButton = L.Control.extend({
+
+ options: {
+ position: 'topleft', // part of leaflet's defaults
+
+ id: null, // an id to tag the button with
+
+ type: 'replace', // [(replace|animate)]
+ // replace swaps out elements
+ // animate changes classes with all elements inserted
+
+ states: [], // state names look like this
+ // {
+ // stateName: 'untracked',
+ // onClick: function(){ handle_nav_manually(); };
+ // title: 'click to make inactive',
+ // icon: 'fa-circle', // wrapped with <a>
+ // }
+
+ leafletClasses: true, // use leaflet styles for the button
+ tagName: 'button',
+ },
+
+
+
+ initialize: function(icon, onClick, title, id){
+
+ // clear the states manually
+ this.options.states = [];
+
+ // add id to options
+ if(id != null){
+ this.options.id = id;
+ }
+
+ // storage between state functions
+ this.storage = {};
+
+ // is the last item an object?
+ if( typeof arguments[arguments.length-1] === 'object' ){
+
+ // if so, it should be the options
+ L.Util.setOptions( this, arguments[arguments.length-1] );
+ }
+
+ // if there aren't any states in options
+ // use the early params
+ if( this.options.states.length === 0 &&
+ typeof icon === 'string' &&
+ typeof onClick === 'function'){
+
+ // turn the options object into a state
+ this.options.states.push({
+ icon: icon,
+ onClick: onClick,
+ title: typeof title === 'string' ? title : ''
+ });
+ }
+
+ // curate and move user's states into
+ // the _states for internal use
+ this._states = [];
+
+ for(var i = 0; i < this.options.states.length; i++){
+ this._states.push( new State(this.options.states[i], this) );
+ }
+
+ this._buildButton();
+
+ this._activateState(this._states[0]);
+
+ },
+
+ _buildButton: function(){
+
+ this.button = L.DomUtil.create(this.options.tagName, '');
+
+ // the next three if statements should be collapsed into the options
+ // when it's time for breaking changes.
+ if (this.tagName === 'button') {
+ this.button.type = 'button';
+ }
+
+ if (this.options.id ){
+ this.button.id = this.options.id;
+ }
+
+ if (this.options.leafletClasses){
+ L.DomUtil.addClass(this.button, 'easy-button-button leaflet-bar-part leaflet-interactive');
+ }
+
+ // don't let double clicks and mousedown get to the map
+ L.DomEvent.addListener(this.button, 'dblclick', L.DomEvent.stop);
+ L.DomEvent.addListener(this.button, 'mousedown', L.DomEvent.stop);
+
+ // take care of normal clicks
+ L.DomEvent.addListener(this.button,'click', function(e){
+ L.DomEvent.stop(e);
+ this._currentState.onClick(this, this._map ? this._map : null );
+ this._map.getContainer().focus();
+ }, this);
+
+ // prep the contents of the control
+ if(this.options.type == 'replace'){
+ this.button.appendChild(this._currentState.icon);
+ } else {
+ for(var i=0;i<this._states.length;i++){
+ this.button.appendChild(this._states[i].icon);
+ }
+ }
+ },
+
+
+ _currentState: {
+ // placeholder content
+ stateName: 'unnamed',
+ icon: (function(){ return document.createElement('span'); })()
+ },
+
+
+
+ _states: null, // populated on init
+
+
+
+ state: function(newState){
+
+ // activate by name
+ if(typeof newState == 'string'){
+
+ this._activateStateNamed(newState);
+
+ // activate by index
+ } else if (typeof newState == 'number'){
+
+ this._activateState(this._states[newState]);
+ }
+
+ return this;
+ },
+
+
+ _activateStateNamed: function(stateName){
+ for(var i = 0; i < this._states.length; i++){
+ if( this._states[i].stateName == stateName ){
+ this._activateState( this._states[i] );
+ }
+ }
+ },
+
+ _activateState: function(newState){
+
+ if( newState === this._currentState ){
+
+ // don't touch the dom if it'll just be the same after
+ return;
+
+ } else {
+
+ // swap out elements... if you're into that kind of thing
+ if( this.options.type == 'replace' ){
+ this.button.appendChild(newState.icon);
+ this.button.removeChild(this._currentState.icon);
+ }
+
+ if( newState.title ){
+ this.button.title = newState.title;
+ } else {
+ this.button.removeAttribute('title');
+ }
+
+ // update classes for animations
+ for(var i=0;i<this._states.length;i++){
+ L.DomUtil.removeClass(this._states[i].icon, this._currentState.stateName + '-active');
+ L.DomUtil.addClass(this._states[i].icon, newState.stateName + '-active');
+ }
+
+ // update classes for animations
+ L.DomUtil.removeClass(this.button, this._currentState.stateName + '-active');
+ L.DomUtil.addClass(this.button, newState.stateName + '-active');
+
+ // update the record
+ this._currentState = newState;
+
+ }
+ },
+
+
+
+ enable: function(){
+ L.DomUtil.addClass(this.button, 'enabled');
+ L.DomUtil.removeClass(this.button, 'disabled');
+ this.button.setAttribute('aria-hidden', 'false');
+ return this;
+ },
+
+
+
+ disable: function(){
+ L.DomUtil.addClass(this.button, 'disabled');
+ L.DomUtil.removeClass(this.button, 'enabled');
+ this.button.setAttribute('aria-hidden', 'true');
+ return this;
+ },
+
+
+ removeFrom: function (map) {
+
+ this._container.parentNode.removeChild(this._container);
+ this._map = null;
+
+ return this;
+ },
+
+ onAdd: function(){
+ var containerObj = L.easyBar([this], {
+ position: this.options.position,
+ leafletClasses: this.options.leafletClasses
+ });
+ this._container = containerObj.container;
+ return this._container;
+ }
+
+
+});
+
+L.easyButton = function(/* args will pass automatically */){
+ var args = Array.prototype.concat.apply([L.Control.EasyButton],arguments);
+ return new (Function.prototype.bind.apply(L.Control.EasyButton, args));
+};
+
+/*************************
+ *
+ * util functions
+ *
+ *************************/
+
+// constructor for states so only curated
+// states end up getting called
+function State(template, easyButton){
+
+ this.title = template.title;
+ this.stateName = template.stateName ? template.stateName : 'unnamed-state';
+
+ // build the wrapper
+ this.icon = L.DomUtil.create('span', '');
+
+ L.DomUtil.addClass(this.icon, 'button-state state-' + this.stateName.replace(/(^\s*|\s*$)/g,''));
+ this.icon.innerHTML = buildIcon(template.icon);
+ this.onClick = L.Util.bind(template.onClick?template.onClick:function(){}, easyButton);
+}
+
+function buildIcon(ambiguousIconString) {
+
+ var tmpIcon;
+
+ // does this look like html? (i.e. not a class)
+ if( ambiguousIconString.match(/[&;=<>"']/) ){
+
+ // if so, the user should have put in html
+ // so move forward as such
+ tmpIcon = ambiguousIconString;
+
+ // then it wasn't html, so
+ // it's a class list, figure out what kind
+ } else {
+ ambiguousIconString = ambiguousIconString.replace(/(^\s*|\s*$)/g,'');
+ tmpIcon = L.DomUtil.create('span', '');
+
+ if( ambiguousIconString.indexOf('fa-') === 0 ){
+ L.DomUtil.addClass(tmpIcon, 'fa ' + ambiguousIconString)
+ } else if ( ambiguousIconString.indexOf('glyphicon-') === 0 ) {
+ L.DomUtil.addClass(tmpIcon, 'glyphicon ' + ambiguousIconString)
+ } else {
+ L.DomUtil.addClass(tmpIcon, /*rollwithit*/ ambiguousIconString)
+ }
+
+ // make this a string so that it's easy to set innerHTML below
+ tmpIcon = tmpIcon.outerHTML;
+ }
+
+ return tmpIcon;
+}
+
+})();