<commit_before>define( [
            'dojo/_base/declare',
            'dojo/_base/array',
            'dojo/aspect',
            'dojo/has',
            'dojo/window',
            'dojo/dom-construct',
            'JBrowse/Util',
            'dijit/form/Button',
            'dijit/form/RadioButton',
            'dijit/Dialog'
        ],
        function(
            declare,
            array,
            aspect,
            has,
            dojoWindow,
            dom,
            Util,
            dijitButton,
            dijitRadioButton,
            dijitDialog
        ) {
/**
 * Mixin for a track that can export its data.
 * @lends JBrowse.View.Track.ExportMixin
 */
return declare( null, {

    _canExport: function() {
        if( this.config.noExport )
            return false;

        var visibleRegion = this.browser.view.visibleRegion();
        var wholeRefSeqRegion = { ref: this.refSeq.name, start: this.refSeq.start, end: this.refSeq.end };
        var canExportVisibleRegion = this._canExportRegion( visibleRegion );
        var canExportWholeRef = this._canExportRegion( wholeRefSeqRegion );
        return canExportVisibleRegion || canExportWholeRef;
    },

    _possibleExportRegions: function() {
        return [
            // the visible region
            (function() {
                 var r = dojo.clone( this.browser.view.visibleRegion() );
                 r.description = 'Visible region';
                 r.name = 'visible';
                 return r;
             }.call(this)),
            // whole reference sequence
            { ref: this.refSeq.name, start: this.refSeq.start, end: this.refSeq.end, description: 'Whole reference sequence', name: 'wholeref' }
        ];
    },

    _exportDialogContent: function() {
        // note that the `this` for this content function is not the track, it's the menu-rendering context
        var possibleRegions = this.track._possibleExportRegions();

        // for each region, calculate its length and determine whether we can export it
        array.forEach( possibleRegions, function( region ) {
            region.length = Math.round( region.end - region.start + 1 );
            region.canExport = this._canExportRegion( region );
        },this.track);

        var form = dom.create('form', { onSubmit: function() { return false; } });
        form.innerHTML = ''
            + ' <fieldset class="region">'
            + '   <legend>Region to save</legend>'
            + function() {
                    var regions = '';
                    var checked = 0;
                    array.forEach( possibleRegions, function(r) {
                       var locstring = Util.assembleLocString(r);
                       regions += ' <input '+( r.canExport ? checked++ ? '' : ' checked="checked"' : ' disabled="disabled"' )
                               + '     type="radio" data-dojo-type="dijit.form.RadioButton" name="region" id="region_'+r.name+'"'
                               + '     value="'+locstring+'" />'
                               + '   '+r.description+' - '
                               +         locstring+' ('+Util.humanReadableNumber(r.length)+(r.canExport ? 'b' : 'b, too large')+')'
                               + '
';
                   });
                   return regions;

              }.call(this)
            + ' </fieldset>'
            + ' '
            + ' <fieldset class="format">'
            + '   <legend>Format</legend>'
            + function() {
                   var fmts = '';
                   var checked = 0;
                   array.forEach( this.track._exportFormats(), function(fmt) {
                       if( ! fmt.name ) {
                           fmt = { name: fmt, label: fmt };
                       }
                       fmts += ' <input type="radio" '+ (checked++?'':'checked="checked" ')
                               +'      data-dojo-type="dijit.form.RadioButton" name="format" id="format'+fmt.name+'" value="'+fmt.name+'" />'
                               + '   '+fmt.label+''
                               + '
';
                   },this);
                   return fmts;
              }.call(this)
            + ' </fieldset>';

        var actionBar = dom.create( 'div', {
            className: 'dijitDialogPaneActionBar'
        });

        // note that the `this` for this content function is not the track, it's the menu-rendering context
        var dialog = this.dialog;

        new dijitButton({ iconClass: 'dijitIconDelete', onClick: dojo.hitch(dialog,'hide'), label: 'Cancel' })
            .placeAt( actionBar );
        var viewButton = new dijitButton({ iconClass: 'dijitIconTask',
                          label: 'View',
                          disabled: ! array.some(possibleRegions,function(r) { return r.canExport; }),
                          onClick: dojo.hitch( this.track, function() {
                            var track = this;
                            viewButton.set('disabled',true);
                            viewButton.set('iconClass','jbrowseIconBusy');

                            var region = this._readRadio( form.elements.region );
                            var format = this._readRadio( form.elements.format );
                            this.exportRegion( region, format, function(output) {
                                dialog.hide();
                                var text = dom.create('textarea', {
                                                           rows: Math.round( dojoWindow.getBox().h / 12 * 0.5 ),
                                                           wrap: 'soft',
                                                           cols: 80,
                                                           readonly: true
                                                       });
                                text.value = output;
                                var actionBar = dom.create( 'div', {
                                    className: 'dijitDialogPaneActionBar'
                                });
                                var exportView = new dijitDialog({
                                    className: 'export-view-dialog',
                                    title: format + ' export - '+ region+' ('+Util.humanReadableNumber(output.length)+'b)',
                                    content: [ text, actionBar ]
                                });
                                new dijitButton({ iconClass: 'dijitIconDelete',
                                                  label: 'Close', onClick: dojo.hitch( exportView, 'hide' )
                                                })
                                     .placeAt(actionBar);

                                // data URL download doesn't work on IE < 10
                                if( ! (has('ie') < 10) ) {
                                    new dijitButton(
                                        {
                                            iconClass: 'dijitIconSave',
                                            label: 'Save',
                                            onClick: function() {
                                                exportView.hide();
                                                track._fileDownload({ format: format, data: output });
                                            }
                                        }).placeAt(actionBar);
                                }

                                aspect.after( exportView, 'hide', function() {
                                    // manually unhook and free the (possibly huge) text area
                                    text.parentNode.removeChild( text );
                                    text = null;
                                    setTimeout( function() {
                                        exportView.destroyRecursive();
                                    }, 500 );
                                });
                                exportView.show();
                            });
                          })})
            .placeAt( actionBar );

        // don't show a download button if the user is using IE older
        // than 10, cause it won't work.
        if( ! (has('ie') < 10) ) {
            var dlButton = new dijitButton({ iconClass: 'dijitIconSave',
                              label: 'Save',
                              disabled: ! array.some(possibleRegions,function(r) { return r.canExport; }),
                              onClick: dojo.hitch( this.track, function() {
                                var format = this._readRadio( form.elements.format );
                                var region = this._readRadio( form.elements.region );
                                dlButton.set('disabled',true);
                                dlButton.set('iconClass','jbrowseIconBusy');
                                this.exportRegion( region, format, dojo.hitch( this, function( output ) {
                                    dialog.hide();
                                    this._fileDownload({ format: format, data: output });
                                }));
                              })})
                .placeAt( actionBar );
        }

        return [ form, actionBar ];
    },

    _fileDownload: function( args ) {
        // do the file download by setting the src of a hidden iframe,
        // because missing with the href of the window messes up
        // WebApollo long polling
        var iframe = dom.create( 'iframe', {
            style: { display: 'none' }
        },this.div );
        iframe.src = "data:"+( args.format ? 'application/x-'+args.format.toLowerCase() : 'text/plain' )
            +","+escape( args.data || '' );
    },

    // cross-platform function for (portably) reading the value of a radio control. sigh. *rolls eyes*
    _readRadio: function( r ) {
        if( r.length ) {
            for( var i = 0; i<r.length; i++ ) {
                if( r[i].checked )
                    return r[i].value;
            }
        }
        return r.value;
    },

    exportRegion: function( region, format, callback ) {
        // parse the locstring if necessary
        if( typeof region == 'string' )
            region = Util.parseLocString( region );

        // we can only export from the currently-visible reference
        // sequence right now
        if( region.ref != this.refSeq.name ) {
            console.error("cannot export data for ref seq "+region.ref+", "
                          + "exporting is currently only supported for the "
                          + "currently-visible reference sequence" );
            return;
        }

        require( ['JBrowse/View/Export/'+format], dojo.hitch(this,function( exportDriver ) {
            new exportDriver({
                refSeq: this.refSeq,
                track: this,
                store: this.store
            }).exportRegion( region, callback );
        }));
    },

    _trackMenuOptions: function() {
        var opts = this.inherited(arguments);

        if( ! this.config.noExport )
            // add a "Save track data as" option to the track menu
            opts.push({ label: 'Save track data',
                        iconClass: 'dijitIconSave',
                        disabled: ! this._canExport(),
                        action: 'bareDialog',
                        content: this._exportDialogContent,
                        dialog: { id: 'exportDialog', className: 'export-dialog' }
                      });

        return opts;
    },

    _canExportRegion: function( l ) {
        //console.log('can generic export?');
        if( ! l ) return false;

        // if we have a maxExportSpan configured for this track, use it.
        if( typeof this.config.maxExportSpan == 'number' || typeof this.config.maxExportSpan == 'string' ) {
            return l.end - l.start + 1 <= this.config.maxExportSpan;
        }
        else {
            // if we know the store's feature density, then use that with
            // a limit of maxExportFeatures or 5,000 features
            var thisB = this;
            var storeStats = {};
            // will return immediately if the stats are available
            this.store.getGlobalStats( function( s ) {
                storeStats = s;
            });
            if( storeStats.featureDensity ) {
                return storeStats.featureDensity*(l.end - l.start) <= ( thisB.config.maxExportFeatures || 5000 );
            }
        }

        // otherwise, i guess we can export
        return true;
    }

});
});
<commit_msg>make the View function in track data export not wrap long lines<commit_after>define( [
            'dojo/_base/declare',
            'dojo/_base/array',
            'dojo/aspect',
            'dojo/has',
            'dojo/window',
            'dojo/dom-construct',
            'JBrowse/Util',
            'dijit/form/Button',
            'dijit/form/RadioButton',
            'dijit/Dialog'
        ],
        function(
            declare,
            array,
            aspect,
            has,
            dojoWindow,
            dom,
            Util,
            dijitButton,
            dijitRadioButton,
            dijitDialog
        ) {
/**
 * Mixin for a track that can export its data.
 * @lends JBrowse.View.Track.ExportMixin
 */
return declare( null, {

    _canExport: function() {
        if( this.config.noExport )
            return false;

        var visibleRegion = this.browser.view.visibleRegion();
        var wholeRefSeqRegion = { ref: this.refSeq.name, start: this.refSeq.start, end: this.refSeq.end };
        var canExportVisibleRegion = this._canExportRegion( visibleRegion );
        var canExportWholeRef = this._canExportRegion( wholeRefSeqRegion );
        return canExportVisibleRegion || canExportWholeRef;
    },

    _possibleExportRegions: function() {
        return [
            // the visible region
            (function() {
                 var r = dojo.clone( this.browser.view.visibleRegion() );
                 r.description = 'Visible region';
                 r.name = 'visible';
                 return r;
             }.call(this)),
            // whole reference sequence
            { ref: this.refSeq.name, start: this.refSeq.start, end: this.refSeq.end, description: 'Whole reference sequence', name: 'wholeref' }
        ];
    },

    _exportDialogContent: function() {
        // note that the `this` for this content function is not the track, it's the menu-rendering context
        var possibleRegions = this.track._possibleExportRegions();

        // for each region, calculate its length and determine whether we can export it
        array.forEach( possibleRegions, function( region ) {
            region.length = Math.round( region.end - region.start + 1 );
            region.canExport = this._canExportRegion( region );
        },this.track);

        var form = dom.create('form', { onSubmit: function() { return false; } });
        form.innerHTML = ''
            + ' <fieldset class="region">'
            + '   <legend>Region to save</legend>'
            + function() {
                    var regions = '';
                    var checked = 0;
                    array.forEach( possibleRegions, function(r) {
                       var locstring = Util.assembleLocString(r);
                       regions += ' <input '+( r.canExport ? checked++ ? '' : ' checked="checked"' : ' disabled="disabled"' )
                               + '     type="radio" data-dojo-type="dijit.form.RadioButton" name="region" id="region_'+r.name+'"'
                               + '     value="'+locstring+'" />'
                               + '   '+r.description+' - '
                               +         locstring+' ('+Util.humanReadableNumber(r.length)+(r.canExport ? 'b' : 'b, too large')+')'
                               + '
';
                   });
                   return regions;

              }.call(this)
            + ' </fieldset>'
            + ' '
            + ' <fieldset class="format">'
            + '   <legend>Format</legend>'
            + function() {
                   var fmts = '';
                   var checked = 0;
                   array.forEach( this.track._exportFormats(), function(fmt) {
                       if( ! fmt.name ) {
                           fmt = { name: fmt, label: fmt };
                       }
                       fmts += ' <input type="radio" '+ (checked++?'':'checked="checked" ')
                               +'      data-dojo-type="dijit.form.RadioButton" name="format" id="format'+fmt.name+'" value="'+fmt.name+'" />'
                               + '   '+fmt.label+''
                               + '
';
                   },this);
                   return fmts;
              }.call(this)
            + ' </fieldset>';

        var actionBar = dom.create( 'div', {
            className: 'dijitDialogPaneActionBar'
        });

        // note that the `this` for this content function is not the track, it's the menu-rendering context
        var dialog = this.dialog;

        new dijitButton({ iconClass: 'dijitIconDelete', onClick: dojo.hitch(dialog,'hide'), label: 'Cancel' })
            .placeAt( actionBar );
        var viewButton = new dijitButton({ iconClass: 'dijitIconTask',
                          label: 'View',
                          disabled: ! array.some(possibleRegions,function(r) { return r.canExport; }),
                          onClick: dojo.hitch( this.track, function() {
                            var track = this;
                            viewButton.set('disabled',true);
                            viewButton.set('iconClass','jbrowseIconBusy');

                            var region = this._readRadio( form.elements.region );
                            var format = this._readRadio( form.elements.format );
                            this.exportRegion( region, format, function(output) {
                                dialog.hide();
                                var text = dom.create('textarea', {
                                                           rows: Math.round( dojoWindow.getBox().h / 12 * 0.5 ),
                                                           wrap: 'off',
                                                           cols: 80,
                                                           style: "maxWidth: 90em; overflow: scroll; overflow-y: scroll; overflow-x: scroll; overflow:-moz-scrollbars-vertical;",
                                                           readonly: true
                                                       });
                                text.value = output;
                                var actionBar = dom.create( 'div', {
                                    className: 'dijitDialogPaneActionBar'
                                });
                                var exportView = new dijitDialog({
                                    className: 'export-view-dialog',
                                    title: format + ' export - '+ region+' ('+Util.humanReadableNumber(output.length)+'b)',
                                    content: [ text, actionBar ]
                                });
                                new dijitButton({ iconClass: 'dijitIconDelete',
                                                  label: 'Close', onClick: dojo.hitch( exportView, 'hide' )
                                                })
                                     .placeAt(actionBar);

                                // data URL download doesn't work on IE < 10
                                if( ! (has('ie') < 10) ) {
                                    new dijitButton(
                                        {
                                            iconClass: 'dijitIconSave',
                                            label: 'Save',
                                            onClick: function() {
                                                exportView.hide();
                                                track._fileDownload({ format: format, data: output });
                                            }
                                        }).placeAt(actionBar);
                                }

                                aspect.after( exportView, 'hide', function() {
                                    // manually unhook and free the (possibly huge) text area
                                    text.parentNode.removeChild( text );
                                    text = null;
                                    setTimeout( function() {
                                        exportView.destroyRecursive();
                                    }, 500 );
                                });
                                exportView.show();
                            });
                          })})
            .placeAt( actionBar );

        // don't show a download button if the user is using IE older
        // than 10, cause it won't work.
        if( ! (has('ie') < 10) ) {
            var dlButton = new dijitButton({ iconClass: 'dijitIconSave',
                              label: 'Save',
                              disabled: ! array.some(possibleRegions,function(r) { return r.canExport; }),
                              onClick: dojo.hitch( this.track, function() {
                                var format = this._readRadio( form.elements.format );
                                var region = this._readRadio( form.elements.region );
                                dlButton.set('disabled',true);
                                dlButton.set('iconClass','jbrowseIconBusy');
                                this.exportRegion( region, format, dojo.hitch( this, function( output ) {
                                    dialog.hide();
                                    this._fileDownload({ format: format, data: output });
                                }));
                              })})
                .placeAt( actionBar );
        }

        return [ form, actionBar ];
    },

    _fileDownload: function( args ) {
        // do the file download by setting the src of a hidden iframe,
        // because missing with the href of the window messes up
        // WebApollo long polling
        var iframe = dom.create( 'iframe', {
            style: { display: 'none' }
        },this.div );
        iframe.src = "data:"+( args.format ? 'application/x-'+args.format.toLowerCase() : 'text/plain' )
            +","+escape( args.data || '' );
    },

    // cross-platform function for (portably) reading the value of a radio control. sigh. *rolls eyes*
    _readRadio: function( r ) {
        if( r.length ) {
            for( var i = 0; i<r.length; i++ ) {
                if( r[i].checked )
                    return r[i].value;
            }
        }
        return r.value;
    },

    exportRegion: function( region, format, callback ) {
        // parse the locstring if necessary
        if( typeof region == 'string' )
            region = Util.parseLocString( region );

        // we can only export from the currently-visible reference
        // sequence right now
        if( region.ref != this.refSeq.name ) {
            console.error("cannot export data for ref seq "+region.ref+", "
                          + "exporting is currently only supported for the "
                          + "currently-visible reference sequence" );
            return;
        }

        require( ['JBrowse/View/Export/'+format], dojo.hitch(this,function( exportDriver ) {
            new exportDriver({
                refSeq: this.refSeq,
                track: this,
                store: this.store
            }).exportRegion( region, callback );
        }));
    },

    _trackMenuOptions: function() {
        var opts = this.inherited(arguments);

        if( ! this.config.noExport )
            // add a "Save track data as" option to the track menu
            opts.push({ label: 'Save track data',
                        iconClass: 'dijitIconSave',
                        disabled: ! this._canExport(),
                        action: 'bareDialog',
                        content: this._exportDialogContent,
                        dialog: { id: 'exportDialog', className: 'export-dialog' }
                      });

        return opts;
    },

    _canExportRegion: function( l ) {
        //console.log('can generic export?');
        if( ! l ) return false;

        // if we have a maxExportSpan configured for this track, use it.
        if( typeof this.config.maxExportSpan == 'number' || typeof this.config.maxExportSpan == 'string' ) {
            return l.end - l.start + 1 <= this.config.maxExportSpan;
        }
        else {
            // if we know the store's feature density, then use that with
            // a limit of maxExportFeatures or 5,000 features
            var thisB = this;
            var storeStats = {};
            // will return immediately if the stats are available
            this.store.getGlobalStats( function( s ) {
                storeStats = s;
            });
            if( storeStats.featureDensity ) {
                return storeStats.featureDensity*(l.end - l.start) <= ( thisB.config.maxExportFeatures || 5000 );
            }
        }

        // otherwise, i guess we can export
        return true;
    }

});
});
<|endoftext|>


<commit_before>/**
Original code at:
http://www.diveintojavascript.com/projects/sidjs-load-javascript-and-stylesheets-on-demand

SidJS - JavaScript And CSS Lazy Loader 0.1

Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of SidJS nor the names of its contributors may be
      used to endorse or promote products derived from this software without
      specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Sniffing by Boris Popoff <http://gueschla.com/> (see http://dean.edwards.name/weblog/2007/03/sniff/)

So why sniff? Well, the state of the browser is pretty fucked up:
Opera:
- script:
    - detects load
    - triggers load, readystatechange
- link:
    - detects load
    - triggers load
Safari, Chrome, Firefox:
- script:
    - detects load
    - triggers load
- link:
    - detects load (WebKit)
    - triggers NONE
IE8:
- script:
    - detects readystatechange
    - triggers readystatechange
- link:
    - detects load, readystatechange
    - triggers load, readystatechange
Assume all versions of IE support readystatechange
*/
(function() {
  var win = window,
    doc = document,
    proto = 'prototype',
    head = doc.getElementsByTagName('head')[0],
    body = doc.getElementsByTagName('body')[0],
    style = doc.getElementsByTagName('style')[0],
    sniff = /*@cc_on!@*/1 + /(?:Gecko|AppleWebKit)\/(\S*)/.test(navigator.userAgent); // 0 - IE, 1 - O, 2 - GK/WK

  var createNode = function(tag, attrs) {
    var attr, node = doc.createElement(tag);
    for (attr in attrs) {
      if (attrs.hasOwnProperty(attr)) {
        node.setAttribute(attr, attrs[attr]);
      }
    }
    return node;
  };

  var load = function(type, urls, callback, scope) {
    if (this == win) {
      return new load(type, urls, callback, scope);
    }

    urls = (typeof urls == 'string' ? [urls] : urls);
    if (scope && scope != 'afterfirststyle') {
      scope = (scope ? (scope == 'body' ? body : head) : (type == 'js' ? body : head));
    }

    this.callback = callback || function() {};
    this.queue = [];

    var node, i = len = 0, that = this;

    for (i = 0, len = urls.length; i < len; i++) {
      this.queue[i] = 1;
      if (type == 'css') {
        node = createNode('link', { type: 'text/css', rel: 'stylesheet', href: urls[i] });
      }
      else {
        node = createNode('script', { type: 'text/javascript', src: urls[i] });
      }
      if (style && scope == 'afterfirststyle') {
        if (style.nextSibling) {
          style.parentNode.insertBefore(node, style.nextSibling);
        }
      } else {
        scope.appendChild(node);
      }

      if (sniff) {
        if (type == 'css' && sniff == 2) {
          var intervalID = setInterval(function() {
            try {
              node.sheet.cssRules;
              clearInterval(intervalID);
              that.__callback();
            }
            catch (ex) {}
          }, 100);
        }
        else {
          node.onload = function() {
            that.__callback();
          }
        }
      }
      else {
        node.onreadystatechange = function() {
          if (/^loaded|complete$/.test(this.readyState)) {
            this.onreadystatechange = null;
            that.__callback();
          }
        };
      }
    }

    return this;
  };
  load[proto].__callback = function() {
    if (this.queue.pop() && (this.queue == 0)) { this.callback(); }
  };

  window.Sid = {
    css: function(urls, callback, scope) {
      return load('css', urls, callback, scope);
    },
    js: function(urls, callback, scope) {
      return load('js', urls, callback, scope);
    },
    load: function(type, urls, callback, scope) {
      return load(type, urls, callback, scope);
    }
  };
})();<commit_msg>Fix sidjs<commit_after>/**
Original code at:
http://www.diveintojavascript.com/projects/sidjs-load-javascript-and-stylesheets-on-demand

SidJS - JavaScript And CSS Lazy Loader 0.1

Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of SidJS nor the names of its contributors may be
      used to endorse or promote products derived from this software without
      specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Sniffing by Boris Popoff <http://gueschla.com/> (see http://dean.edwards.name/weblog/2007/03/sniff/)

So why sniff? Well, the state of the browser is pretty fucked up:
Opera:
- script:
    - detects load
    - triggers load, readystatechange
- link:
    - detects load
    - triggers load
Safari, Chrome, Firefox:
- script:
    - detects load
    - triggers load
- link:
    - detects load (WebKit)
    - triggers NONE
IE8:
- script:
    - detects readystatechange
    - triggers readystatechange
- link:
    - detects load, readystatechange
    - triggers load, readystatechange
Assume all versions of IE support readystatechange
*/
(function() {
  var win = window,
    doc = document,
    proto = 'prototype',
    head = doc.getElementsByTagName('head')[0],
    body = doc.getElementsByTagName('body')[0],
    style = doc.getElementsByTagName('style')[0],
    sniff = /*@cc_on!@*/1 + /(?:Gecko|AppleWebKit)\/(\S*)/.test(navigator.userAgent); // 0 - IE, 1 - O, 2 - GK/WK

  var createNode = function(tag, attrs) {
    var attr, node = doc.createElement(tag);
    for (attr in attrs) {
      if (attrs.hasOwnProperty(attr)) {
        node.setAttribute(attr, attrs[attr]);
      }
    }
    return node;
  };

  var load = function(type, urls, callback, scope) {
    if (this == win) {
      return new load(type, urls, callback, scope);
    }

    urls = (typeof urls == 'string' ? [urls] : urls);
    if (scope) {
      if (scope != 'afterfirststyle') {
        if (scope == 'body') {
          scope = body;
        } else {
          scope = head;
        }
      }
    } else {
      if (type == 'js') {
        scope = body;
      } else {
        scope = head;
      }
    }

    this.callback = callback || function() {};
    this.queue = [];

    var node, i = len = 0, that = this;

    for (i = 0, len = urls.length; i < len; i++) {
      this.queue[i] = 1;
      if (type == 'css') {
        node = createNode('link', { type: 'text/css', rel: 'stylesheet', href: urls[i] });
      }
      else {
        node = createNode('script', { type: 'text/javascript', src: urls[i] });
      }
      if (style && scope == 'afterfirststyle') {
        if (style.nextSibling) {
          style.parentNode.insertBefore(node, style.nextSibling);
        }
      } else {
        scope.appendChild(node);
      }

      if (sniff) {
        if (type == 'css' && sniff == 2) {
          var intervalID = setInterval(function() {
            try {
              node.sheet.cssRules;
              clearInterval(intervalID);
              that.__callback();
            }
            catch (ex) {}
          }, 100);
        }
        else {
          node.onload = function() {
            that.__callback();
          }
        }
      }
      else {
        node.onreadystatechange = function() {
          if (/^loaded|complete$/.test(this.readyState)) {
            this.onreadystatechange = null;
            that.__callback();
          }
        };
      }
    }

    return this;
  };
  load[proto].__callback = function() {
    if (this.queue.pop() && (this.queue == 0)) { this.callback(); }
  };

  window.Sid = {
    css: function(urls, callback, scope) {
      return load('css', urls, callback, scope);
    },
    js: function(urls, callback, scope) {
      return load('js', urls, callback, scope);
    },
    load: function(type, urls, callback, scope) {
      return load(type, urls, callback, scope);
    }
  };
})();<|endoftext|>


<commit_before>/**
 * Runtime.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/*global ActiveXObject:true */

/**
Defines constructor for Flash runtime.

@class moxie/runtime/flash/Runtime
@private
*/
define("moxie/runtime/flash/Runtime", [
	"moxie/core/utils/Basic",
	"moxie/core/utils/Env",
	"moxie/core/utils/Dom",
	"moxie/core/Exceptions",
	"moxie/runtime/Runtime"
], function(Basic, Env, Dom, x, Runtime) {

	var type = 'flash', extensions = {};

	/**
	Get the version of the Flash Player

	@method getShimVersion
	@private
	@return {Number} Flash Player version
	*/
	function getShimVersion() {
		var version;

		try {
			version = navigator.plugins['Shockwave Flash'];
			version = version.description;
		} catch (e1) {
			try {
				version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
			} catch (e2) {
				version = '0.0';
			}
		}
		version = version.match(/\d+/g);
		return parseFloat(version[0] + '.' + version[1]);
	}

	/**
	Constructor for the Flash Runtime

	@class FlashRuntime
	@extends Runtime
	*/
	function FlashRuntime(options) {
		var I = this, initTimer;

		options = Basic.extend({ swf_url: Env.swf_url }, options);

		Runtime.call(this, options, type, {
			access_binary: function(value) {
				return value && I.mode === 'browser';
			},
			access_image_binary: function(value) {
				return value && I.mode === 'browser';
			},
			display_media: Runtime.capTrue,
			do_cors: Runtime.capTrue,
			drag_and_drop: false,
			report_upload_progress: function() {
				return I.mode === 'client';
			},
			resize_image: Runtime.capTrue,
			return_response_headers: false,
			return_response_type: function(responseType) {
				return !Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) || I.mode === 'browser';
			},
			return_status_code: function(code) {
				return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]);
			},
			select_file: Runtime.capTrue,
			select_multiple: Runtime.capTrue,
			send_binary_string: function(value) {
				return value && I.mode === 'browser';
			},
			send_browser_cookies: function(value) {
				return value && I.mode === 'browser';
			},
			send_custom_headers: function(value) {
				return value && I.mode === 'browser';
			},
			send_multipart: Runtime.capTrue,
			slice_blob: Runtime.capTrue,
			stream_upload: function(value) {
				return value && I.mode === 'browser';
			},
			summon_file_dialog: false,
			upload_filesize: function(size) {
				return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client';
			},
			use_http_method: function(methods) {
				return !Basic.arrayDiff(methods, ['GET', 'POST']);
			}
		}, {
			// capabilities that require specific mode
			access_binary: function(value) {
				return value ? 'browser' : 'client';
			},
			access_image_binary: function(value) {
				return value ? 'browser' : 'client';
			},
			report_upload_progress: function(value) {
				return value ? 'browser' : 'client';
			},
			return_response_type: function(responseType) {
				return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser'];
			},
			return_status_code: function(code) {
				return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser'];
			},
			send_binary_string: function(value) {
				return value ? 'browser' : 'client';
			},
			send_browser_cookies: function(value) {
				return value ? 'browser' : 'client';
			},
			send_custom_headers: function(value) {
				return value ? 'browser' : 'client';
			},
			stream_upload: function(value) {
				return value ? 'client' : 'browser';
			},
			upload_filesize: function(size) {
				return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser';
			}
		}, 'client');

		// minimal requirement Flash Player 10
		if (getShimVersion() < 11.3) {
			this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before
		}

		Basic.extend(this, {

			getShim: function() {
				return Dom.get(this.uid);
			},

			shimExec: function(component, action) {
				var args = [].slice.call(arguments, 2);
				return I.getShim().exec(this.uid, component, action, args);
			},

			init: function() {
				var html, el, container;

				container = this.getShimContainer();

				// if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)
				Basic.extend(container.style, {
					position: 'absolute',
					top: '-8px',
					left: '-8px',
					width: '9px',
					height: '9px',
					overflow: 'hidden'
				});

				// insert flash object
				html = '<object id="' + this.uid + '" type="application/x-shockwave-flash" data="' +  options.swf_url + '" ';

				if (Env.browser === 'IE') {
					html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
				}

				html += 'width="100%" height="100%" style="outline:0">'  +
					'<param name="movie" value="' + options.swf_url + '" />' +
					'<param name="flashvars" value="uid=' + escape(this.uid) + '&target=' + Env.global_event_dispatcher + '" />' +
					'<param name="wmode" value="transparent" />' +
					'<param name="allowscriptaccess" value="always" />' +
				'</object>';

				if (Env.browser === 'IE') {
					el = document.createElement('div');
					container.appendChild(el);
					el.outerHTML = html;
					el = container = null; // just in case
				} else {
					container.innerHTML = html;
				}

				// Init is dispatched by the shim
				initTimer = setTimeout(function() {
					if (I && !I.initialized) { // runtime might be already destroyed by this moment
						I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR));
					}
				}, 5000);
			},

			destroy: (function(destroy) { // extend default destroy method
				return function() {
					destroy.call(I);
					clearTimeout(initTimer); // initialization check might be still onwait
					options = initTimer = destroy = I = null;
				};
			}(this.destroy))

		}, extensions);
	}

	Runtime.addConstructor(type, FlashRuntime);

	return extensions;
});
<commit_msg>Runtime, Flash: Fix comment.<commit_after>/**
 * Runtime.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/*global ActiveXObject:true */

/**
Defines constructor for Flash runtime.

@class moxie/runtime/flash/Runtime
@private
*/
define("moxie/runtime/flash/Runtime", [
	"moxie/core/utils/Basic",
	"moxie/core/utils/Env",
	"moxie/core/utils/Dom",
	"moxie/core/Exceptions",
	"moxie/runtime/Runtime"
], function(Basic, Env, Dom, x, Runtime) {

	var type = 'flash', extensions = {};

	/**
	Get the version of the Flash Player

	@method getShimVersion
	@private
	@return {Number} Flash Player version
	*/
	function getShimVersion() {
		var version;

		try {
			version = navigator.plugins['Shockwave Flash'];
			version = version.description;
		} catch (e1) {
			try {
				version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
			} catch (e2) {
				version = '0.0';
			}
		}
		version = version.match(/\d+/g);
		return parseFloat(version[0] + '.' + version[1]);
	}

	/**
	Constructor for the Flash Runtime

	@class FlashRuntime
	@extends Runtime
	*/
	function FlashRuntime(options) {
		var I = this, initTimer;

		options = Basic.extend({ swf_url: Env.swf_url }, options);

		Runtime.call(this, options, type, {
			access_binary: function(value) {
				return value && I.mode === 'browser';
			},
			access_image_binary: function(value) {
				return value && I.mode === 'browser';
			},
			display_media: Runtime.capTrue,
			do_cors: Runtime.capTrue,
			drag_and_drop: false,
			report_upload_progress: function() {
				return I.mode === 'client';
			},
			resize_image: Runtime.capTrue,
			return_response_headers: false,
			return_response_type: function(responseType) {
				return !Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) || I.mode === 'browser';
			},
			return_status_code: function(code) {
				return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]);
			},
			select_file: Runtime.capTrue,
			select_multiple: Runtime.capTrue,
			send_binary_string: function(value) {
				return value && I.mode === 'browser';
			},
			send_browser_cookies: function(value) {
				return value && I.mode === 'browser';
			},
			send_custom_headers: function(value) {
				return value && I.mode === 'browser';
			},
			send_multipart: Runtime.capTrue,
			slice_blob: Runtime.capTrue,
			stream_upload: function(value) {
				return value && I.mode === 'browser';
			},
			summon_file_dialog: false,
			upload_filesize: function(size) {
				return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client';
			},
			use_http_method: function(methods) {
				return !Basic.arrayDiff(methods, ['GET', 'POST']);
			}
		}, {
			// capabilities that require specific mode
			access_binary: function(value) {
				return value ? 'browser' : 'client';
			},
			access_image_binary: function(value) {
				return value ? 'browser' : 'client';
			},
			report_upload_progress: function(value) {
				return value ? 'browser' : 'client';
			},
			return_response_type: function(responseType) {
				return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser'];
			},
			return_status_code: function(code) {
				return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser'];
			},
			send_binary_string: function(value) {
				return value ? 'browser' : 'client';
			},
			send_browser_cookies: function(value) {
				return value ? 'browser' : 'client';
			},
			send_custom_headers: function(value) {
				return value ? 'browser' : 'client';
			},
			stream_upload: function(value) {
				return value ? 'client' : 'browser';
			},
			upload_filesize: function(size) {
				return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser';
			}
		}, 'client');

		// minimal requirement for Flash Player version
		if (getShimVersion() < 11.3) {
			this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before
		}

		Basic.extend(this, {

			getShim: function() {
				return Dom.get(this.uid);
			},

			shimExec: function(component, action) {
				var args = [].slice.call(arguments, 2);
				return I.getShim().exec(this.uid, component, action, args);
			},

			init: function() {
				var html, el, container;

				container = this.getShimContainer();

				// if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)
				Basic.extend(container.style, {
					position: 'absolute',
					top: '-8px',
					left: '-8px',
					width: '9px',
					height: '9px',
					overflow: 'hidden'
				});

				// insert flash object
				html = '<object id="' + this.uid + '" type="application/x-shockwave-flash" data="' +  options.swf_url + '" ';

				if (Env.browser === 'IE') {
					html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
				}

				html += 'width="100%" height="100%" style="outline:0">'  +
					'<param name="movie" value="' + options.swf_url + '" />' +
					'<param name="flashvars" value="uid=' + escape(this.uid) + '&target=' + Env.global_event_dispatcher + '" />' +
					'<param name="wmode" value="transparent" />' +
					'<param name="allowscriptaccess" value="always" />' +
				'</object>';

				if (Env.browser === 'IE') {
					el = document.createElement('div');
					container.appendChild(el);
					el.outerHTML = html;
					el = container = null; // just in case
				} else {
					container.innerHTML = html;
				}

				// Init is dispatched by the shim
				initTimer = setTimeout(function() {
					if (I && !I.initialized) { // runtime might be already destroyed by this moment
						I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR));
					}
				}, 5000);
			},

			destroy: (function(destroy) { // extend default destroy method
				return function() {
					destroy.call(I);
					clearTimeout(initTimer); // initialization check might be still onwait
					options = initTimer = destroy = I = null;
				};
			}(this.destroy))

		}, extensions);
	}

	Runtime.addConstructor(type, FlashRuntime);

	return extensions;
});
<|endoftext|>


<commit_before>import React from 'react';
import purebem from 'purebem';
import moment from 'moment';

import isNull from 'lodash.isnull';
import filter from 'lodash.filter';
import find from 'lodash.find';
import pick from 'lodash.pick';
import omit from 'lodash.omit';
import omitBy from 'lodash.omitby';

import firebaseRef from 'app/firebaseRef';

import ButtonSwitch from 'app/components/ButtonSwitch';
import ContentBox from 'app/components/ContentBox';
import InputField from 'app/components/InputField';
import ProjectMap from 'app/components/ProjectMap';

const ERROR_TITLE = 'Please fill in a title.';
const ERROR_DATE = 'Please fill in a valid date.';
const ERROR_END = 'A project must start before it can end.';

const initState = {
    end: '',
    error: {},
    isPublic: true,
    isSubmitting: false,
    sites: [],
    start: '',
    title: ''
};

const form = purebem.of('form');
const block = purebem.of('create-view');

const CreateView = React.createClass({

    getInitialState() {
        return {
            options: ['Public', 'Private']
        };
    },

    componentWillMount() {
        this.setState(initState);
    },

    isEmpty(string) {
        return !string || string.trim() === '';
    },

    isDate(string) {
        return !this.isEmpty(string) && moment(string, 'YYYYMMDD', true).isValid();
    },

    isValidDateOrder() {
        const { start, end } = this.state;
        return this.isDate(start) && this.isDate(end) && start < end;
    },

    getSites() {
        return this.state.sites.filter(site => site.name).map(site => pick(site, ['latlng', 'name']));
    },

    getErrors() {
        return Object.keys(this.state.error).length;
    },

    onInput(name) {
        return evt => {
            const { value } = evt.target;
            const { error } = this.state;

            switch (name) {
                case 'title':
                    error.title = this.isEmpty(value) ? ERROR_TITLE : undefined;
                    break;
                default:
                    error[name] = !this.isDate(value) ? ERROR_DATE : undefined;
                    error.order = !this.isValidDateOrder() ? ERROR_END : undefined;
            };

            this.setState({ error, [name]: value });
        };
    },

    onReset() {
        this.form.reset();
        this.onSitesClear();
        this.setState(initState);
    },

    onSubmit(evt) {
        evt.preventDefault();

        if (this.getErrors() > 0) {
            return;
        }

        console.log('submit…');

        // add project to projects
        // add projectId to user
        // ...
    },

    onSiteAdd(marker) {
        const sites = [ ...this.state.sites, marker ];
        this.setState({ sites });
    },

    onSiteInput(index) {
        return evt => {
            const { sites } = this.state;
            sites[index].name = evt.target.value;
            this.setState({ sites });
        }
    },

    onSiteRemove(index) {
        let { sites } = this.state;
        sites[index].setMap(null);
        sites = sites.filter((item, i) => index !== i);
        this.setState({ sites });
    },

    onSitesClear() {
        const sites = this.state.sites.filter(item => item.setMap(null));
        this.setState({ sites });
    },

    onSwitchClick() {
        this.setState({ isPublic: !this.state.isPublic });
    },

    renderPrivacyInfo() {
        const info = this.state.isPublic
            ? (
Public projects aim at collaboration. Users can find your project and may request to join.
)
            : (
Private projects aim at privacy. Other users cannot find nor participate in these projects.
);

        return (

{ info }

        );
    },

    renderSite(item, index) {
        return (

                Site name { index + 1 }
                <InputField
                    iconClass="icon-cross"
                    iconClick={ () => this.onSiteRemove(index) }
                    onInput={ this.onSiteInput(index) }
                    value={ item.name } />

        );
    },

    renderForm() {
        const buttonClass = purebem.many(block('button', ['submit']), 'button-primary');
        const { isSubmitting } = this.state;

        return (
            <form className={ block('form') } onSubmit={ this.onSubmit } ref={ (form) => this.form = form }>

                    Project title
                    <InputField
                        error={ this.state.error.title }
                        onInput={ this.onInput('title') }
                        name="title" />

                    Start date
                    <InputField
                        error={ this.state.error.start }
                        onInput={ this.onInput('start') }
                        placeholder="yyyymmdd"
                        name="start" />

                    End date
                    <InputField
                        error={ this.state.error.end || this.state.error.order }
                        onInput={ this.onInput('end') }
                        placeholder="yyyymmdd"
                        name="end" />

                {
                    [].map.call(this.state.sites, this.renderSite)
                }

Use the map to locate and mark your ringing sites. Their coordinates may be used to monitor migratory movements.

                <ButtonSwitch
                    className={ block('switch') }
                    isActive={ this.state.isPublic }
                    onClick={ this.onSwitchClick }
                    options={ this.state.options } />
                { this.renderPrivacyInfo() }

                    <button type="submit" className={ buttonClass } disabled={ isSubmitting }>Create</button>
                    <button type="button" className={ block('button', ['reset']) } onClick={ this.onReset }>Reset</button>

            </form>
        );
    },

    render() {
        return (

                    <ProjectMap
                        onClick={ this.onSiteAdd }
                        sites={ this.state.sites } />
                    <ContentBox background="white" shadow={ true }>
                        { this.renderForm() }
                    </ContentBox>

        );
    }

});

export default CreateView;
<commit_msg>form validation / error handling<commit_after>import React from 'react';
import purebem from 'purebem';
import moment from 'moment';

import isNull from 'lodash.isnull';
import filter from 'lodash.filter';
import find from 'lodash.find';
import pick from 'lodash.pick';
import omit from 'lodash.omit';
import omitBy from 'lodash.omitby';
import debounce from 'lodash.debounce';
import cloneDeep from 'lodash.clonedeep';
import assign from 'lodash.assign';

import firebaseRef from 'app/firebaseRef';

import ButtonSwitch from 'app/components/ButtonSwitch';
import ContentBox from 'app/components/ContentBox';
import InputField from 'app/components/InputField';
import ProjectMap from 'app/components/ProjectMap';

const ERROR_TITLE = 'Please fill in a title.';
const ERROR_DATE = 'Please fill in a valid date.';
const ERROR_END = 'A project must start before it can end.';

const defaultState = {
    end: {},
    errors: {},
    isPublic: true,
    isSubmitting: false,
    options: ['Public', 'Private'],
    sites: [],
    start: {},
    title: {}
};

const delayAction = debounce((action) => action(), 500);

const form = purebem.of('form');
const block = purebem.of('create-view');

const CreateView = React.createClass({

    componentWillMount() {
        this.setState(cloneDeep(defaultState));
    },

    isEmpty(str) {
        return !str || !str.trim().length;
    },

    isDate(str) {
        return moment(str, 'YYYYMMDD', true).isValid();
    },

    getSites() {
        return this.state.sites.filter(site => site.name).map(site => pick(site, ['latlng', 'name']));
    },

    hasErrors(errors) {
        return Object.keys(omitBy(errors, isNull)).length;
    },

    validateAll() {
        let errors = {};

        ['title', 'start', 'end'].map(name => {
            assign(errors, this.validateField(name, this.state[name].value));
        });

        return errors;
    },

    validateField(name, value) {
        const error = {};
        const { start, end } = this.state;

        switch (name) {
            case 'title':
                error[name] = this.isEmpty(value) ? ERROR_TITLE : null;
                break;
            default:
                error[name] = !this.isDate(value) ? ERROR_DATE : null;

                if (this.isDate(start.value) && this.isDate(end.value)) {
                    error.order = start.value >= end.value ? ERROR_END : null;
                }
        };

        return error;
    },

    handleChange(evt) {
        const { name, value } = evt.target;
        this.setState({ [name]: { value } });

        delayAction(() => {
            this.setState({ errors: this.validateField(name, value) });
        });
    },

    onReset() {
        this.form.reset();
        this.onSitesClear();
        this.setState(cloneDeep(defaultState));
    },

    onSubmit(evt) {
        evt.preventDefault();
        const errors = this.validateAll();

        if (this.hasErrors(errors)) {
            this.setState({ errors });
            return;
        }

        console.log('submit…');
    },

    onSiteAdd(marker) {
        const sites = [ ...this.state.sites, marker ];
        this.setState({ sites });
    },

    onSiteChange(index) {
        return evt => {
            const { sites } = this.state;
            sites[index].name = evt.target.value;
            this.setState({ sites });
        }
    },

    onSiteRemove(index) {
        let { sites } = this.state;
        sites[index].setMap(null);
        sites = sites.filter((item, i) => index !== i);
        this.setState({ sites });
    },

    onSitesClear() {
        const sites = this.state.sites.filter(item => item.setMap(null));
        this.setState({ sites });
    },

    onSwitchClick() {
        this.setState({ isPublic: !this.state.isPublic });
    },

    renderPrivacyInfo() {
        const info = this.state.isPublic
            ? (
Public projects aim at collaboration. Users can find your project and may request to join.
)
            : (
Private projects aim at privacy. Other users cannot find nor participate in these projects.
);

        return (

{ info }

        );
    },

    renderSite(item, index) {
        return (

                Site name { index + 1 }
                <InputField
                    iconClass="icon-cross"
                    iconClick={ () => this.onSiteRemove(index) }
                    onChange={ this.onSiteChange(index) }
                    value={ item.name } />

        );
    },

    renderForm() {
        const buttonClass = purebem.many(block('button', ['submit']), 'button-primary');
        const { title, start, end, errors, isSubmitting } = this.state;

        return (
            <form className={ block('form') } onSubmit={ this.onSubmit } ref={ (form) => this.form = form }>

                    Project title
                    <InputField
                        name="title"
                        error={ errors.title }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        value={ title.value } />

                    Start date
                    <InputField
                        name="start"
                        error={ errors.start }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        placeholder="yyyymmdd"
                        value={ start.value } />

                    End date
                    <InputField
                        name="end"
                        error={ errors.end || errors.order }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        placeholder="yyyymmdd"
                        value={ end.value } />

                {
                    [].map.call(this.state.sites, this.renderSite)
                }

Use the map to locate and mark your ringing sites. Their coordinates may be used to monitor migratory movements.

                <ButtonSwitch
                    className={ block('switch') }
                    isActive={ this.state.isPublic }
                    onClick={ this.onSwitchClick }
                    options={ this.state.options } />
                { this.renderPrivacyInfo() }

                    <button type="submit" className={ buttonClass } disabled={ isSubmitting }>Create</button>
                    <button type="button" className={ block('button', ['reset']) } onClick={ this.onReset }>Reset</button>

            </form>
        );
    },

    render() {
        return (

                    <ProjectMap
                        onClick={ this.onSiteAdd }
                        sites={ this.state.sites } />
                    <ContentBox background="white" shadow={ true }>
                        { this.renderForm() }
                    </ContentBox>

        );
    }

});

export default CreateView;
<|endoftext|>


<commit_before>function AnnotationsEventsController(annotations_controller) {

    this.DUMMY_TOOL = 'dummy_tool';
    this.IMAGE_MARKING_TOOL = 'image_marker';

    this.annotation_controller = annotations_controller;
    this.initialized_tools = {};

    this._bind_switch = function(switch_id, tool_label) {
        $("#" + switch_id).bind(
            'click',
            {'events_controller': this, 'tool_label': tool_label},
            function(event) {
                event.data.events_controller.activateTool(event.data.tool_label);
            }
        );
    };

    // Create a tool that simply ignores mouse events, this will be used, for example, to avoid
    // events propagation when capturing events on Shapes
    this.initializeDummyTool = function() {
        if (! (this.DUMMY_TOOL in this.initialized_tools)) {
            this.initialized_tools[this.DUMMY_TOOL] = new paper.Tool();
        }
    };

    this.initializeImageMarkingTool = function(marker_size, markers_limit, switch_id) {
        // by default, initialize dummy tool
        this.initializeDummyTool();

        if(! (this.IMAGE_MARKING_TOOL in this.initialized_tools)) {

            AnnotationsController.prototype.markers_counter = 0;

            if ((typeof markers_limit !== 'undefined') || (markers_limit > 0)) {
                AnnotationsController.prototype.max_markers_count = markers_limit;
            } else {
                AnnotationsController.prototype.max_markers_count = 0;
            }

            AnnotationsController.prototype._check_markers_limit = function() {
                if (this.max_markers_count > 0 && (this.markers_counter >= this.max_markers_count))
                    return false;
                return true;
            };

            AnnotationsController.prototype.removeMarker = function(marker_id) {
                var deleted = this.deleteShape(marker_id);
                if (deleted === true) {
                    this.markers_counter -= 1;
                }
            };

            AnnotationsController.prototype.addMarker = function(event) {
                var add_new_marker = this._check_markers_limit();
                if (add_new_marker === true) {
                    console.log('Adding marker');
                    var img_x = event.point.x + this.x_offset;
                    var img_y = event.point.y + this.y_offset;
                    var shape_id = this._getShapeId('marker');
                    this.drawCircle(shape_id, img_x, img_y, event.marker_radius, undefined, true);
                    this.markers_counter += 1;
                }
            };

            var marking_tool = new paper.Tool();

            marking_tool.annotations_controller = this.annotation_controller;
            marking_tool.marker_size = marker_size;

            marking_tool.onMouseDown = function(event) {
                event.marker_radius = this.marker_size / 2;
                this.annotations_controller.addMarker(event);
            };

            this.initialized_tools[this.IMAGE_MARKING_TOOL] = marking_tool;

            if (typeof switch_id !== 'undefined') {
                this._bind_switch(switch_id, this.IMAGE_MARKING_TOOL);
            }
        } else {
            console.warn('Tool "' + this.IMAGE_MARKING_TOOL + '" already initialized');
        }
    };

    this.activateTool = function(tool_label) {
        if (tool_label in this.initialized_tools) {
            var tool = this.initialized_tools[tool_label];
            tool.activate();
            this.annotation_controller.enableMouseEvents();
        } else {
            console.warn('Tool ' + tool_label + ' not initialized');
        }
    };
}
<commit_msg>automatically disable events on shapes when activating a tool<commit_after>function AnnotationsEventsController(annotations_controller) {

    this.DUMMY_TOOL = 'dummy_tool';
    this.IMAGE_MARKING_TOOL = 'image_marker';

    this.annotation_controller = annotations_controller;
    this.initialized_tools = {};

    this._bind_switch = function(switch_id, tool_label) {
        $("#" + switch_id).bind(
            'click',
            {'events_controller': this, 'tool_label': tool_label},
            function(event) {
                event.data.events_controller.activateTool(event.data.tool_label);
            }
        );
    };

    // Create a tool that simply ignores mouse events, this will be used, for example, to avoid
    // events propagation when capturing events on Shapes
    this.initializeDummyTool = function() {
        if (! (this.DUMMY_TOOL in this.initialized_tools)) {
            this.initialized_tools[this.DUMMY_TOOL] = new paper.Tool();
        }
    };

    this.initializeImageMarkingTool = function(marker_size, markers_limit, switch_id) {
        // by default, initialize dummy tool
        this.initializeDummyTool();

        if(! (this.IMAGE_MARKING_TOOL in this.initialized_tools)) {

            AnnotationsController.prototype.markers_counter = 0;

            if ((typeof markers_limit !== 'undefined') || (markers_limit > 0)) {
                AnnotationsController.prototype.max_markers_count = markers_limit;
            } else {
                AnnotationsController.prototype.max_markers_count = 0;
            }

            AnnotationsController.prototype._check_markers_limit = function() {
                if (this.max_markers_count > 0 && (this.markers_counter >= this.max_markers_count))
                    return false;
                return true;
            };

            AnnotationsController.prototype.removeMarker = function(marker_id) {
                var deleted = this.deleteShape(marker_id);
                if (deleted === true) {
                    this.markers_counter -= 1;
                }
            };

            AnnotationsController.prototype.addMarker = function(event) {
                var add_new_marker = this._check_markers_limit();
                if (add_new_marker === true) {
                    console.log('Adding marker');
                    var img_x = event.point.x + this.x_offset;
                    var img_y = event.point.y + this.y_offset;
                    var shape_id = this._getShapeId('marker');
                    this.drawCircle(shape_id, img_x, img_y, event.marker_radius, undefined, true);
                    this.markers_counter += 1;
                }
            };

            var marking_tool = new paper.Tool();

            marking_tool.annotations_controller = this.annotation_controller;
            marking_tool.marker_size = marker_size;

            marking_tool.onMouseDown = function(event) {
                event.marker_radius = this.marker_size / 2;
                this.annotations_controller.addMarker(event);
            };

            this.initialized_tools[this.IMAGE_MARKING_TOOL] = marking_tool;

            if (typeof switch_id !== 'undefined') {
                this._bind_switch(switch_id, this.IMAGE_MARKING_TOOL);
            }
        } else {
            console.warn('Tool "' + this.IMAGE_MARKING_TOOL + '" already initialized');
        }
    };

    this.activateTool = function(tool_label, disable_events_on_shapes) {
        if (tool_label in this.initialized_tools) {
            var sh_ev_off = (typeof disable_events_on_shapes === 'undefined') ? true : disable_events_on_shapes;
            if (sh_ev_off === true)
                this.annotation_controller.disableEventsOnShapes();
            var tool = this.initialized_tools[tool_label];
            tool.activate();
            this.annotation_controller.enableMouseEvents();
        } else {
            console.warn('Tool ' + tool_label + ' not initialized');
        }
    };
}
<|endoftext|>


<commit_before>app.service('DashboardService', function($q, $http){
  var mockData =
  [
      {
        "host":"elgervanboxtel.nl",
        "errordata": [
        {
          "errorComponent":"RegisterController.js",
          "line":23,
          "column":64,
          "ip":"206.45.67.30",
          "occurrences":1523
        },{
          "errorComponent":"RegisterController.js",
          "line":128,
          "column":99,
          "ip":"127.0.0.1",
          "occurrences":1478
        },{
          "errorComponent":"RegisterController.js",
          "line":542,
          "column":33,
          "ip":"172.56.52.13",
          "occurrences":892
        },{
          "errorComponent":"app.js",
          "line":150,
          "column":30,
          "ip":"127.0.0.1",
          "occurrences":253
        },{
          "errorComponent":"LoginController.js",
          "line":1501,
          "column":20,
          "ip":"82.26.64.3",
          "occurrences":240
        },{
          "errorComponent":"RegisterController.js",
          "line":88,
          "column":126,
          "ip":"72.62.84.2",
          "occurrences":55
        },{
          "errorComponent":"RegisterController.js",
          "line":23,
          "column":64,
          "ip":"98.26.35.2",
          "occurrences":12
        }]
      },
      {
        "host":"wouterroosendaal.nl",
        "errordata": [
        {
          "errorComponent":"TargetController.js",
          "line":16,
          "column":44,
          "ip":"206.45.67.30",
          "occurrences":1409
        },{
          "errorComponent":"TargetController.js",
          "line":222,
          "column":69,
          "ip":"127.0.0.1",
          "occurrences":1253
        },{
          "errorComponent":"TargetController.js",
          "line":857,
          "column":82,
          "ip":"172.56.52.13",
          "occurrences":398
        },{
          "errorComponent":"app.js",
          "line":150,
          "column":30,
          "ip":"127.0.0.1",
          "occurrences":309
        },{
          "errorComponent":"app.js",
          "line":1501,
          "column":20,
          "ip":"82.26.64.3",
          "occurrences":210
        },{
          "errorComponent":"MockService.js",
          "line":88,
          "column":126,
          "ip":"72.62.84.2",
          "occurrences":109
        },{
          "errorComponent":"MockService.js",
          "line":23,
          "column":64,
          "ip":"98.26.35.2",
          "occurrences":94
        }]
      },
      {
        "host":"tuvok.nl",
        "errordata": [
        {
          "errorComponent":"StarfleetController.js",
          "line":76,
          "column":12,
          "ip":"206.45.67.30",
          "occurrences":1809
        },{
          "errorComponent":"StarfleetController.js",
          "line":45,
          "column":21,
          "ip":"127.0.0.1",
          "occurrences":1478
        },{
          "errorComponent":"StarfleetController.js",
          "line":35,
          "column":12,
          "ip":"172.56.52.13",
          "occurrences":1209
        },{
          "errorComponent":"app.js",
          "line":76,
          "column":45,
          "ip":"127.0.0.1",
          "occurrences":987
        },{
          "errorComponent":"LoginController.js",
          "line":12,
          "column":33,
          "ip":"82.26.64.3",
          "occurrences":876
        },{
          "errorComponent":"StarfleetController.js",
          "line":66,
          "column":67,
          "ip":"72.62.84.2",
          "occurrences":654
        },{
          "errorComponent":"StarfleetController.js",
          "line":12,
          "column":123,
          "ip":"98.26.35.2",
          "occurrences":43
        }]
      }
  ],
  /**
   * Returns all domains which the current user is registered to
   */
  getMockHosts = function(){
    return $q(function(resolve, reject) {
      var mockHosts = [];
      for (var i = 0; i < mockData.length; i++) {
        mockHosts.push({"host": mockData[i].host});
      }
      // mock a return object as retrieved from api
      var returnobject = {};
      returnobject.data = {};
      returnobject.data.hosts = mockHosts;
      resolve(returnobject);
    });
  },
  getMockData = function(host) {
    return $q(function(resolve, reject) {
      for (var i = 0; i < mockData.length; i++) {
        if (mockData[i].host === host) {
          // mock a return object as retrieved from api
          var returnobject = {};
          returnobject.data = {};
          returnobject.data.errordata = mockData[i].errordata;
          resolve(returnobject);
        }
      }
    });
  },
  getHosts = function() {
    return $http.get('/api/host');
  },
  getData = function(host) {
    return $http.get('/api/data/forhost', {
      params: { name: host }
    });
  };
  return {
    getData:getData,
    getHosts:getHosts
  };

});<commit_msg>Remove mock data from Dashboardservice<commit_after>app.service('DashboardService', function($q, $http){
  var getHosts = function() {
    return $http.get('/api/host');
  },
  getData = function(host) {
    return $http.get('/api/data/forhost', {
      params: { name: host }
    });
  };
  return {
    getData:getData,
    getHosts:getHosts
  };

});<|endoftext|>


<commit_before>/*
 * Copyright 2015 brutusin.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author Ignacio del Valle Alles idelvall@brutusin.org
 */
if ("undefined" === typeof BrutusinForms) {
    throw new Error("brutusin-json-forms-bootstrap.js requires brutusin-json-forms.js");
}
if ("undefined" === typeof markdown && window.console) {
    console.warn("Include markdown.js (https://github.com/evilstreak/markdown-js) to add markdown support in property description popups");
}

if (("undefined" === typeof $ || "undefined" === typeof $.fn || "undefined" === typeof $.fn.selectpicker) && window.console) {
    console.warn("Include bootstrap-select.js (https://github.com/silviomoreto/bootstrap-select) to turn native selects into bootstrap components");
}

BrutusinForms.addDecorator(function (element, schema) {
    if (element.tagName) {
        var tagName = element.tagName.toLowerCase();
        if (tagName === "input" && element.type !== "checkbox" || tagName === "textarea") {
            element.className += " form-control";
        } else if (tagName === "select") {
            element.className += " chosen-select form-control";
        } else if (tagName === "button") {
            element.className += "btn btn-primary  btn-xs";
        } else if (tagName === "form") {
            element.className += " form-inline";
        }
        if (tagName === "label" || tagName === "button") {
            if (element.title) {
                var helpLink = document.createElement("a");
                helpLink.setAttribute("style", "outline: 0; text-decoration: none; margin-left: 2px;");
                helpLink.setAttribute("tabIndex", -1);
                helpLink.className = "glyphicon glyphicon-info-sign"
                helpLink.setAttribute("data-toggle", "popover");
                helpLink.setAttribute("data-trigger", "focus");
                if ("undefined" === typeof markdown) {
                    helpLink.setAttribute("data-content", element.title);
                } else {
                    helpLink.setAttribute("data-content", markdown.toHTML(element.title));
                }
                if (schema.title) {
                    helpLink.title = schema.title;
                } else {
                    helpLink.title = "Help";
                }
                $(helpLink).popover({
                    placement: 'top',
                    container: 'body',
                    html: !("undefined" === typeof markdown)
                });
                element.parentNode.appendChild(helpLink);
            }
        }
//        if (element.title && (tagName === "input" || tagName === "textarea" || tagName === "select")) {
//            element.setAttribute("data-toggle", "tooltip");
//            element.setAttribute("data-trigger", "focus");
//            if ("undefined" === typeof markdown) {
//                element.setAttribute("data-content", element.title);
//            } else {
//                element.setAttribute("data-content", markdown.toHTML(element.title));
//            }
//            if (schema.title) {
//                element.title = schema.title;
//            } else {
//                element.title = "Help";
//            }
//            $(element).popover({
//                placement: 'top',
//                container: 'body',
//                html: !("undefined" === typeof markdown)
//            });
//        }
        // https://github.com/silviomoreto/bootstrap-select
        if (!("undefined" === typeof $ || "undefined" === typeof $.fn || "undefined" === typeof $.fn.selectpicker) && tagName === "select") {
            element.title = "";
            element.className += " selectpicker";
            element.setAttribute("data-live-search", true);
            $(element).selectpicker();
        }
    }
});<commit_msg>add format helper<commit_after>/*
 * Copyright 2015 brutusin.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author Ignacio del Valle Alles idelvall@brutusin.org
 */
if ("undefined" === typeof BrutusinForms) {
    throw new Error("brutusin-json-forms-bootstrap.js requires brutusin-json-forms.js");
}
if ("undefined" === typeof markdown && window.console) {
    console.warn("Include markdown.js (https://github.com/evilstreak/markdown-js) to add markdown support in property description popups");
}

if (("undefined" === typeof $ || "undefined" === typeof $.fn || "undefined" === typeof $.fn.selectpicker) && window.console) {
    console.warn("Include bootstrap-select.js (https://github.com/silviomoreto/bootstrap-select) to turn native selects into bootstrap components");
}

// Basic bootstrap css
BrutusinForms.addDecorator(function (element, schema) {
    if (element.tagName) {
        var tagName = element.tagName.toLowerCase();
        if (tagName === "input" && element.type !== "checkbox" || tagName === "textarea") {
            element.className += " form-control";
        } else if (tagName === "select") {
            element.className += " chosen-select form-control";
        } else if (tagName === "button") {
            element.className += "btn btn-primary  btn-xs";
        } else if (tagName === "form") {
            element.className += " form-inline";
        }
    }
});

// Description help icon
BrutusinForms.addDecorator(function (element, schema) {
    if (element.tagName) {
        if (tagName === "label" || tagName === "button") {
            if (element.title) {
                var helpLink = document.createElement("a");
                helpLink.setAttribute("style", "outline: 0; text-decoration: none; margin-left: 2px;");
                helpLink.setAttribute("tabIndex", -1);
                helpLink.className = "glyphicon glyphicon-info-sign"
                helpLink.setAttribute("data-toggle", "popover");
                helpLink.setAttribute("data-trigger", "focus");
                if ("undefined" === typeof markdown) {
                    helpLink.setAttribute("data-content", element.title);
                } else {
                    helpLink.setAttribute("data-content", markdown.toHTML(element.title));
                }
                if (schema.title) {
                    helpLink.title = schema.title;
                } else {
                    helpLink.title = "Help";
                }
                $(helpLink).popover({
                    placement: 'top',
                    container: 'body',
                    html: !("undefined" === typeof markdown)
                });
                element.parentNode.appendChild(helpLink);
            }
        }
    }
});
// Popover over inputs
//BrutusinForms.addDecorator(function (element, schema) {
//if (element.tagName) {
//        if (element.title && (tagName === "input" || tagName === "textarea" || tagName === "select")) {
//            element.setAttribute("data-toggle", "tooltip");
//            element.setAttribute("data-trigger", "focus");
//            if ("undefined" === typeof markdown) {
//                element.setAttribute("data-content", element.title);
//            } else {
//                element.setAttribute("data-content", markdown.toHTML(element.title));
//            }
//            if (schema.title) {
//                element.title = schema.title;
//            } else {
//                element.title = "Help";
//            }
//            $(element).popover({
//                placement: 'top',
//                container: 'body',
//                html: !("undefined" === typeof markdown)
//            });
//        }
//    }
//});
// Bootstrap select
BrutusinForms.addDecorator(function (element, schema) {
    if (element.tagName) {
        // https://github.com/silviomoreto/bootstrap-select
        if (!("undefined" === typeof $ || "undefined" === typeof $.fn || "undefined" === typeof $.fn.selectpicker) && tagName === "select") {
            element.title = "";
            element.className += " selectpicker";
            element.setAttribute("data-live-search", true);
            $(element).selectpicker();
        }
    }
});
Brutusin.bootstrap = new Object();
// helper button for string (with format) fields
Brutusin.bootstrap.addFormatHelper = function (format, glyphicon, onclick) {
    BrutusinForms.addDecorator(function (element, schema) {
        if (element.tagName) {
            var tagName = element.tagName.toLowerCase();
            if (tagName === "input" && schema.type === "string" && schema.format === format) {
                var table = document.createElement("table");
                var tr = document.createElement("tr");
                var td1 = document.createElement("td");
                td1.setAttribute("style", "width:100%");
                var td2 = document.createElement("td");
                table.appendChild(tr);
                tr.appendChild(td1);
                tr.appendChild(td2);
                var searchButton = document.createElement("button");
                searchButton.className = "btn btn-default glyphicon " + glyphicon;
                searchButton.title = "Select file";
                searchButton.onclick = onclick;
                var parent = element.parentNode;
                parent.removeChild(element);
                td1.appendChild(element);
                td2.appendChild(searchButton);
                parent.appendChild(table);
            }
        }
    });
};

<|endoftext|>


<commit_before>const path = require('path');
const fs = require('fs');

const plugins = require('./plugins');
const paths = require('./paths');

const {
  ROOT,
  MODULES,
  FRONTEND,
  UI,
  STATIC
} = paths;

module.exports = {
  context: ROOT,
  entry: `./${path.relative(ROOT, path.join(FRONTEND, 'index.js'))}`,
  resolve: {
    modules: MODULES,
    alias: fs.readdirSync(FRONTEND)
      .map((name) => path.join(FRONTEND, name))
      .filter((fullpath) => fs.statSync(fullpath).isDirectory())
      .reduce((aliases, fullpath) => Object.assign(aliases, {
        [`@${path.basename(fullpath)}`]: fullpath
      }), {
        '@root': FRONTEND,
        '@ui': UI
      })
  },
  resolveLoader: {
    modules: MODULES
  },
  output: {
    pathinfo: true,
    path: STATIC,
    publicPath: '/static/',
    filename: '[name].js'
  },
  plugins: [
    plugins['no-errors'],
    plugins['define'],
    plugins['shell']
  ],
  module: {
    rules: [{
      test: /js?$/,
      enforce: 'pre',
      use: [{
        loader: 'eslint-loader',
        options: {
          presets: [
            'react-app'
          ]
        }
      }],
      include: [
        FRONTEND,
        UI
      ]
    }, {
      exclude: [
        /\.html$/,
        /\.(js|jsx)$/,
        /\.css$/,
        /\.json$/,
        /\.svg$/,
        /\.(eot|svg|ttf|woff|woff2)$/
      ],
      loader: 'url-loader',
      include: [
        FRONTEND,
        UI
      ],
      options: {
        limit: 10000
      }
    }, {
      test: /js?$/,
      exclude: /node_modules/,
      include: [
        FRONTEND,
        UI
      ],
      loaders: [
        'babel-loader'
      ]
    }, {
      test: /\.svg/,
      exclude: [
        /node_modules/,
        path.join(UI, 'shared', 'fonts'),
      ],
      include: [
        FRONTEND,
        UI
      ],
      loader: [
        'file-loader'
      ]
    }, {
      test: /\.(eot|svg|ttf|woff|woff2)$/,
      loader: 'file-loader',
      // XXX: By commenting this out, production "BUILD=production make compile"
      //      will break.
      //
      // exclude: /node_modules/,
      include: [
        path.join(UI, 'shared', 'fonts')
      ],
    }, {
      test: /\.css$/,
      loader: 'style-loader!css-loader'
      // XXX: Commenting out breaks node_modules that use css
      //        i.e react-select.

      // exclude: /node_modules/,
      // include: [
      //   FRONTEND,
      //   UI
      // ]
    }]
  }
};
<commit_msg>fix missing plugins instantiation<commit_after>const path = require('path');
const fs = require('fs');

const plugins = require('./plugins');
const paths = require('./paths');

const {
  ROOT,
  MODULES,
  FRONTEND,
  UI,
  STATIC
} = paths;

module.exports = {
  context: ROOT,
  entry: `./${path.relative(ROOT, path.join(FRONTEND, 'index.js'))}`,
  resolve: {
    modules: MODULES,
    alias: fs.readdirSync(FRONTEND)
      .map((name) => path.join(FRONTEND, name))
      .filter((fullpath) => fs.statSync(fullpath).isDirectory())
      .reduce((aliases, fullpath) => Object.assign(aliases, {
        [`@${path.basename(fullpath)}`]: fullpath
      }), {
        '@root': FRONTEND,
        '@ui': UI
      })
  },
  resolveLoader: {
    modules: MODULES
  },
  output: {
    pathinfo: true,
    path: STATIC,
    publicPath: '/static/',
    filename: '[name].js'
  },
  plugins: [
    plugins['no-errors'](),
    plugins['define'](),
    plugins['shell']()
  ],
  module: {
    rules: [{
      test: /js?$/,
      enforce: 'pre',
      use: [{
        loader: 'eslint-loader',
        options: {
          presets: [
            'react-app'
          ]
        }
      }],
      include: [
        FRONTEND,
        UI
      ]
    }, {
      exclude: [
        /\.html$/,
        /\.(js|jsx)$/,
        /\.css$/,
        /\.json$/,
        /\.svg$/,
        /\.(eot|svg|ttf|woff|woff2)$/
      ],
      loader: 'url-loader',
      include: [
        FRONTEND,
        UI
      ],
      options: {
        limit: 10000
      }
    }, {
      test: /js?$/,
      exclude: /node_modules/,
      include: [
        FRONTEND,
        UI
      ],
      loaders: [
        'babel-loader'
      ]
    }, {
      test: /\.svg/,
      exclude: [
        /node_modules/,
        path.join(UI, 'shared', 'fonts'),
      ],
      include: [
        FRONTEND,
        UI
      ],
      loader: [
        'file-loader'
      ]
    }, {
      test: /\.(eot|svg|ttf|woff|woff2)$/,
      loader: 'file-loader',
      // XXX: By commenting this out, production "BUILD=production make compile"
      //      will break.
      //
      // exclude: /node_modules/,
      include: [
        path.join(UI, 'shared', 'fonts')
      ],
    }, {
      test: /\.css$/,
      loader: 'style-loader!css-loader'
      // XXX: Commenting out breaks node_modules that use css
      //        i.e react-select.

      // exclude: /node_modules/,
      // include: [
      //   FRONTEND,
      //   UI
      // ]
    }]
  }
};
<|endoftext|>