<commit_before>(function (app) {

    /**
     * @name $assert
     *
     * @param {angular.IInjectorService} $injector
     *
     * @property {function} isTrue
     * @property {function} isFalse
     * @property {function} isTruthy
     * @property {function} isFalsy
     * @property {function} isArray
     * @property {function} isBlankObject
     * @property {function} isBlob
     * @property {function} isBoolean
     * @property {function} isDate
     * @property {function} isElement
     * @property {function} isFile
     * @property {function} isFunction
     * @property {function} isFormData
     * @property {function} isNumber
     * @property {function} isString
     * @property {function} isStringNotEmpty
     * @property {function} isScope
     * @property {function} isWindow
     * @property {function} isUndefined
     * @property {function} isObject
     * @property {function} isRegExp
     * @property {function} isPromiseLike
     * @property {function} isTypedArray
     *
     * @property {function} isTrueOrUndefined
     * @property {function} isFalseOrUndefined
     * @property {function} isArrayOrUndefined
     * @property {function} isBlankObjectOrUndefined
     * @property {function} isBlobOrUndefined
     * @property {function} isBooleanOrUndefined
     * @property {function} isDateOrUndefined
     * @property {function} isElementOrUndefined
     * @property {function} isFileOrUndefined
     * @property {function} isFunctionOrUndefined
     * @property {function} isFormDataOrUndefined
     * @property {function} isNumberOrUndefined
     * @property {function} isStringOrUndefined
     * @property {function} isStringNotEmptyOrUndefined
     * @property {function} isScopeOrUndefined
     * @property {function} isWindowOrUndefined
     * @property {function} isUndefinedOrUndefined
     * @property {function} isObjectOrUndefined
     * @property {function} isRegExpOrUndefined
     * @property {function} isPromiseLikeOrUndefined
     * @property {function} isTypedArrayOrUndefined
     *
     * @property {function} isTrueOrNull
     * @property {function} isFalseOrNull
     * @property {function} isArrayOrNull
     * @property {function} isBlankObjectOrNull
     * @property {function} isBlobOrNull
     * @property {function} isBooleanOrNull
     * @property {function} isDateOrNull
     * @property {function} isElementOrNull
     * @property {function} isFileOrNull
     * @property {function} isFunctionOrNull
     * @property {function} isFormDataOrNull
     * @property {function} isNumberOrNull
     * @property {function} isStringOrNull
     * @property {function} isStringNotEmptyOrNull
     * @property {function} isScopeOrNull
     * @property {function} isWindowOrNull
     * @property {function} isUndefinedOrNull
     * @property {function} isObjectOrNull
     * @property {function} isRegExpOrNull
     * @property {function} isPromiseLikeOrNull
     * @property {function} isTypedArrayOrNull
     *
     * @constructor
     */
    function Assert($injector) {

        var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/;

        var assertMethods = {

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isTrue: function(value) {
                return typeof value === 'boolean' && value === true;
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isFalse: function(value) {
                return typeof value === 'boolean' && value === false;
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isTruthy: function(value) {
                return !!value;
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isFalsy: function(value) {
                return !value;
            },

            /**
             * @param {Array} value
             * @returns {boolean}
             */
            isTypedArray: function (value) {
                return TYPED_ARRAY_REGEXP.test(toString.call(value));
            },

            /**
             * @param {angular.IScope} obj
             * @returns {boolean}
             */
            isScope: function (obj) {
                return angular.isObject(obj) && !!obj.$evalAsync && !!obj.$watch;
            },

            /**
             * @param {Window} obj
             * @returns {boolean}
             */
            isWindow: function (obj) {
                return angular.isObject(obj) && obj.window === obj;
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isFile: function (obj) {
                return angular.isObject(obj) && toString.call(obj) === '[object File]';
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isFormData: function (obj) {
                return angular.isObject(obj) && toString.call(obj) === '[object FormData]';
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isBlob: function (obj) {
                return angular.isObject(obj) && toString.call(obj) === '[object Blob]';
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isBoolean: function (value) {
                return typeof value === 'boolean';
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isPromiseLike: function (obj) {
                return angular.isObject(obj) && angular.isFunction(obj.then);
            },

            /**
             * @param {RegExp} value
             * @returns {boolean}
             */
            isRegExp: function (value) {
                return angular.isObject(value) && toString.call(value) === '[object RegExp]';
            },

            /***
             * @param {string} value
             * @returns {boolean}
             */
            isStringNotEmpty: function (value) {
                return typeof value === 'string' && value !== '';
            }
        };

        // some automatic assert types.
        var types = [
            ['Array', angular],
            ['BlankObject', angular],
            ['Boolean', assertMethods],
            ['Date', angular],
            ['Element', angular],
            ['Function', angular],
            ['Number', angular],
            ['String', angular],
            ['Undefined', angular],
            ['Object', angular],
            ['StringNotEmpty', assertMethods],
            ['Blob', assertMethods],
            ['File', assertMethods],
            ['FormData', assertMethods],
            ['Scope', assertMethods],
            ['Window', assertMethods],
            ['RegExp', assertMethods],
            ['PromiseLike', assertMethods],
            ['TypedArray', assertMethods]
        ];

        _.each(types, function (type) {
            var self = this;
            var angularName = 'is' + type[0];
            var name;
            self[angularName] = function (value) {
                if (!type[1][angularName](value)) {
                    var caller = (self[angularName].caller && self[angularName].caller.name) || '??';
                    throw new Error(caller + ' -> Parameter is not a ' + type[0].toLowerCase() + '.');
                }
                return self;
            };
            if (type[0] !== 'Undefined') {
                name = 'is' + type[0] + 'OrUndefined';
                self[name] = function (value) {
                    if (!type[1][angularName](value) && !angular.isUndefined(value)) {
                        var caller = (self[name].caller && self[name].caller.name) || '??';
                        throw new Error(caller + ' -> Parameter is not a ' + type[0].toLowerCase() + ' or undefined.');
                    }
                    return self;
                };
            }
            name = 'is' + type[0] + 'OrNull';
            self[name] = function (value) {
                if (!type[1][angularName](value) && value !== null) {
                    var caller = (self[name].caller && self[name].caller.name) || '??';
                    throw new Error(caller + ' -> Parameter is not a ' + type[0].toLowerCase() + ' or null.');
                }
                return self;
            };
        }.bind(this));

        /**
         * @param {*} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isInstanceOf = function (value, type) {
            var inst = $injector.get(type);
            if (!inst) {
                throw new Error('invalid type for isInstanceOf: ' + type);
            }
            var caller = (this.isInstanceOf.caller && this.isInstanceOf.caller.name) || '??';
            if (angular.isUndefined(value)) {
                throw new Error(caller + ' -> Parameter is undefined but should be an instance of ' + type);
            }
            if (value.constructor !== inst) {
                throw new Error(caller + ' -> Parameter is not an instance of ' + type);
            }
            return this;
        };

        /**
         * @param {*} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isInstanceOfOrUndefined = function (value, type) {
            var inst = $injector.get(type);
            if (!inst) {
                throw new Error('invalid type for isInstanceOf: ' + type);
            }
            if (!angular.isUndefined(value) && value.constructor !== inst) {
                var caller = (this.isInstanceOfOrUndefined.caller && this.isInstanceOfOrUndefined.caller.name) || '??';
                throw new Error(caller + ' -> Parameter is not an instance of ' + type + ' and is not undefined.');
            }
            return this;
        };

        /**
         * @param {*} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isInstanceOfOrNull = function (value, type) {
            var inst = $injector.get(type);
            if (!inst) {
                throw new Error('invalid type for isInstanceOf: ' + type);
            }
            if (value !== null && value.constructor !== inst) {
                var caller = (this.isInstanceOf.caller && this.isInstanceOf.caller.name) || '??';
                throw new Error(caller + ' -> Parameter is not an instance of ' + type + ' and is not null.');
            }
            return this;
        };

        /**
         * @param {number} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isEnum = function (value, type) {
            this.isNumber(value);
            var inst = $injector.get(type);
            if (_.indexOf(_.values(inst), value) === -1) {
                var caller = (this.isEnum.caller && this.isEnum.caller.name) || '??';
                throw new Error(caller + ' -> ENUM of type ' + type + ' does not contain ' + value);
            }
            return this;
        };
    }

    app.service('$assert', [
        '$log',
        '$injector',
        Assert
    ]);

})(angular.module('ngAssert',[]));<commit_msg>changed module name.<commit_after>(function (app) {

    /**
     * @name $assert
     *
     * @param {angular.IInjectorService} $injector
     *
     * @property {function} isTrue
     * @property {function} isFalse
     * @property {function} isTruthy
     * @property {function} isFalsy
     * @property {function} isArray
     * @property {function} isBlankObject
     * @property {function} isBlob
     * @property {function} isBoolean
     * @property {function} isDate
     * @property {function} isElement
     * @property {function} isFile
     * @property {function} isFunction
     * @property {function} isFormData
     * @property {function} isNumber
     * @property {function} isString
     * @property {function} isStringNotEmpty
     * @property {function} isScope
     * @property {function} isWindow
     * @property {function} isUndefined
     * @property {function} isObject
     * @property {function} isRegExp
     * @property {function} isPromiseLike
     * @property {function} isTypedArray
     *
     * @property {function} isTrueOrUndefined
     * @property {function} isFalseOrUndefined
     * @property {function} isArrayOrUndefined
     * @property {function} isBlankObjectOrUndefined
     * @property {function} isBlobOrUndefined
     * @property {function} isBooleanOrUndefined
     * @property {function} isDateOrUndefined
     * @property {function} isElementOrUndefined
     * @property {function} isFileOrUndefined
     * @property {function} isFunctionOrUndefined
     * @property {function} isFormDataOrUndefined
     * @property {function} isNumberOrUndefined
     * @property {function} isStringOrUndefined
     * @property {function} isStringNotEmptyOrUndefined
     * @property {function} isScopeOrUndefined
     * @property {function} isWindowOrUndefined
     * @property {function} isUndefinedOrUndefined
     * @property {function} isObjectOrUndefined
     * @property {function} isRegExpOrUndefined
     * @property {function} isPromiseLikeOrUndefined
     * @property {function} isTypedArrayOrUndefined
     *
     * @property {function} isTrueOrNull
     * @property {function} isFalseOrNull
     * @property {function} isArrayOrNull
     * @property {function} isBlankObjectOrNull
     * @property {function} isBlobOrNull
     * @property {function} isBooleanOrNull
     * @property {function} isDateOrNull
     * @property {function} isElementOrNull
     * @property {function} isFileOrNull
     * @property {function} isFunctionOrNull
     * @property {function} isFormDataOrNull
     * @property {function} isNumberOrNull
     * @property {function} isStringOrNull
     * @property {function} isStringNotEmptyOrNull
     * @property {function} isScopeOrNull
     * @property {function} isWindowOrNull
     * @property {function} isUndefinedOrNull
     * @property {function} isObjectOrNull
     * @property {function} isRegExpOrNull
     * @property {function} isPromiseLikeOrNull
     * @property {function} isTypedArrayOrNull
     *
     * @constructor
     */
    function Assert($injector) {

        var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/;

        var assertMethods = {

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isTrue: function(value) {
                return typeof value === 'boolean' && value === true;
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isFalse: function(value) {
                return typeof value === 'boolean' && value === false;
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isTruthy: function(value) {
                return !!value;
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isFalsy: function(value) {
                return !value;
            },

            /**
             * @param {Array} value
             * @returns {boolean}
             */
            isTypedArray: function (value) {
                return TYPED_ARRAY_REGEXP.test(toString.call(value));
            },

            /**
             * @param {angular.IScope} obj
             * @returns {boolean}
             */
            isScope: function (obj) {
                return angular.isObject(obj) && !!obj.$evalAsync && !!obj.$watch;
            },

            /**
             * @param {Window} obj
             * @returns {boolean}
             */
            isWindow: function (obj) {
                return angular.isObject(obj) && obj.window === obj;
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isFile: function (obj) {
                return angular.isObject(obj) && toString.call(obj) === '[object File]';
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isFormData: function (obj) {
                return angular.isObject(obj) && toString.call(obj) === '[object FormData]';
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isBlob: function (obj) {
                return angular.isObject(obj) && toString.call(obj) === '[object Blob]';
            },

            /**
             * @param {boolean} value
             * @returns {boolean}
             */
            isBoolean: function (value) {
                return typeof value === 'boolean';
            },

            /**
             * @param {Object} obj
             * @returns {boolean}
             */
            isPromiseLike: function (obj) {
                return angular.isObject(obj) && angular.isFunction(obj.then);
            },

            /**
             * @param {RegExp} value
             * @returns {boolean}
             */
            isRegExp: function (value) {
                return angular.isObject(value) && toString.call(value) === '[object RegExp]';
            },

            /***
             * @param {string} value
             * @returns {boolean}
             */
            isStringNotEmpty: function (value) {
                return typeof value === 'string' && value !== '';
            }
        };

        // some automatic assert types.
        var types = [
            ['Array', angular],
            ['BlankObject', angular],
            ['Boolean', assertMethods],
            ['Date', angular],
            ['Element', angular],
            ['Function', angular],
            ['Number', angular],
            ['String', angular],
            ['Undefined', angular],
            ['Object', angular],
            ['StringNotEmpty', assertMethods],
            ['Blob', assertMethods],
            ['File', assertMethods],
            ['FormData', assertMethods],
            ['Scope', assertMethods],
            ['Window', assertMethods],
            ['RegExp', assertMethods],
            ['PromiseLike', assertMethods],
            ['TypedArray', assertMethods]
        ];

        _.each(types, function (type) {
            var self = this;
            var angularName = 'is' + type[0];
            var name;
            self[angularName] = function (value) {
                if (!type[1][angularName](value)) {
                    var caller = (self[angularName].caller && self[angularName].caller.name) || '??';
                    throw new Error(caller + ' -> Parameter is not a ' + type[0].toLowerCase() + '.');
                }
                return self;
            };
            if (type[0] !== 'Undefined') {
                name = 'is' + type[0] + 'OrUndefined';
                self[name] = function (value) {
                    if (!type[1][angularName](value) && !angular.isUndefined(value)) {
                        var caller = (self[name].caller && self[name].caller.name) || '??';
                        throw new Error(caller + ' -> Parameter is not a ' + type[0].toLowerCase() + ' or undefined.');
                    }
                    return self;
                };
            }
            name = 'is' + type[0] + 'OrNull';
            self[name] = function (value) {
                if (!type[1][angularName](value) && value !== null) {
                    var caller = (self[name].caller && self[name].caller.name) || '??';
                    throw new Error(caller + ' -> Parameter is not a ' + type[0].toLowerCase() + ' or null.');
                }
                return self;
            };
        }.bind(this));

        /**
         * @param {*} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isInstanceOf = function (value, type) {
            var inst = $injector.get(type);
            if (!inst) {
                throw new Error('invalid type for isInstanceOf: ' + type);
            }
            var caller = (this.isInstanceOf.caller && this.isInstanceOf.caller.name) || '??';
            if (angular.isUndefined(value)) {
                throw new Error(caller + ' -> Parameter is undefined but should be an instance of ' + type);
            }
            if (value.constructor !== inst) {
                throw new Error(caller + ' -> Parameter is not an instance of ' + type);
            }
            return this;
        };

        /**
         * @param {*} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isInstanceOfOrUndefined = function (value, type) {
            var inst = $injector.get(type);
            if (!inst) {
                throw new Error('invalid type for isInstanceOf: ' + type);
            }
            if (!angular.isUndefined(value) && value.constructor !== inst) {
                var caller = (this.isInstanceOfOrUndefined.caller && this.isInstanceOfOrUndefined.caller.name) || '??';
                throw new Error(caller + ' -> Parameter is not an instance of ' + type + ' and is not undefined.');
            }
            return this;
        };

        /**
         * @param {*} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isInstanceOfOrNull = function (value, type) {
            var inst = $injector.get(type);
            if (!inst) {
                throw new Error('invalid type for isInstanceOf: ' + type);
            }
            if (value !== null && value.constructor !== inst) {
                var caller = (this.isInstanceOf.caller && this.isInstanceOf.caller.name) || '??';
                throw new Error(caller + ' -> Parameter is not an instance of ' + type + ' and is not null.');
            }
            return this;
        };

        /**
         * @param {number} value
         * @param {string} type
         *
         * @returns {$assert}
         */
        this.isEnum = function (value, type) {
            this.isNumber(value);
            var inst = $injector.get(type);
            if (_.indexOf(_.values(inst), value) === -1) {
                var caller = (this.isEnum.caller && this.isEnum.caller.name) || '??';
                throw new Error(caller + ' -> ENUM of type ' + type + ' does not contain ' + value);
            }
            return this;
        };
    }

    app.service('$assert', [
        '$injector',
        Assert
    ]);

})(angular.module('ngAssert',[]));<|endoftext|>


<commit_before>var getValue = function(record, key) {

};

var setValue = function(record, key, value) {

};

var hasMany = function(type, options) {
  options = options || {};

  options.hasOne = true;

  var meta = {
    type: type,
    options: options,
    isLink: true
  };

  return Ember.computed(function(key, value) {
    if (arguments.length > 1) {
      var oldValue = getValue(this, key);

      if (value !== oldValue) {
        setValue(this, key, value);
      }

      return value;

    } else {
      return getValue(this, key);
    }
  }).meta(meta);
};

export default hasMany;
<commit_msg>`options.hasOne = false;` for `hasMany`<commit_after>var getValue = function(record, key) {

};

var setValue = function(record, key, value) {

};

var hasMany = function(type, options) {
  options = options || {};

  options.hasOne = false;

  var meta = {
    type: type,
    options: options,
    isLink: true
  };

  return Ember.computed(function(key, value) {
    if (arguments.length > 1) {
      var oldValue = getValue(this, key);

      if (value !== oldValue) {
        setValue(this, key, value);
      }

      return value;

    } else {
      return getValue(this, key);
    }
  }).meta(meta);
};

export default hasMany;
<|endoftext|>


<commit_before>$(document).ready(function(){
    $(".button-collapse").sideNav({
        menuWidth: 300
    });
    var austat = new Austat();

});
function Austat(){
    this.map = null;
    this.layer = null;
    this.makeTopics();
    this.makeQuestion();
}
Austat.prototype.get_map = function(){
    if( !this.map ){
        this.map = new L.Map('map');

        // create the tile layer with correct attribution
        var osmUrll = 'http://otile2.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png'

        //var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
        var osmAttrib='Map data © OpenStreetMap contributors';
        var osm = new L.TileLayer(osmUrll, {minZoom: 0, maxZoom: 12, attribution: osmAttrib});

        // start the map in Central Australia
        this.map.setView(new L.LatLng(-24.967335, 134.625094),4);
        this.map.addLayer(osm);
    }
    return this.map;
}

Austat.prototype.checkboxQuestion = function(question){
    var tmpl = $('#checkbox-template').html();
    var html = Mustache.render(tmpl, question);
    $('#question').html(html);

    $('#question input[type=radio]').click(function(){
        var selected = $(this).attr('id');
        results(selected);
        return false;
    });
    $('#question').closest('.card').slideDown();
}
Austat.prototype.mapSetup = function(question){
    $('#map').closest('.card').slideDown();
    this.addPlacemarks(question);
}
Austat.prototype.makeQuestion = function(){
    var austat = this;
    var topic = this.getRandomTopic();
    $.ajax({
        url: '/query/' + topic,
        success: function(q){
            console.log(!q['value'])
                var l = austat.getRandomItem(q.locations);
                q.question = Mustache.render(q.question, l)
                if(l.geometry){
                    austat.addPlacemarks(q)
                }else{
                    austat.checkboxQuestion(q);
                }
        }
    });
}

Austat.prototype.getRandomItem = function(list){
    return list[Math.floor(Math.random()*list.length)];
}

Austat.prototype.getRandomTopic = function(){
    // Get a random topic.
    topics = this.getAllTopics();
    return this.getRandomItem(topics);
}

Austat.prototype.getAllTopics = function(){
    // Get a list of ids for selected topics.
    var topics = [];
    $('input[name=topic]').each(function(i, topic){
        if($(this).is(':checked')){
            topics.push($(this).attr('topic'));
        }
    });
    return topics;
}
Austat.prototype.makeTopics = function(){
    // Get topics from api and create controls.
    $.ajax({
        async: false,
        url: '/topics',
        success: function(topics){
            var template = $('#topics-template').html();
            var html = Mustache.render(template, topics);
            $('#topics').html(html)
        }
    });
}

Austat.prototype.results = function(selected){
    $('#question').closest('.card').slideUp(function(){
        $('#answer').closest('.card').slideDown();
    });
    //answer.answer.correct = false;
    //if ('answer_' + answer.answer.id === selected){
    //    answer.answer.correct = true;
    //}
    var tmpl = $('#answer-template').html();
    var html = Mustache.render(tmpl, answer);
    $('#answer').html(html);
    $('#answer #next').click(function(){
        this.makeQuestion()
        $(this).closest('.card').slideUp(function(){
            $('#question').closest('.card').slideDown();
        });
    });
}

Austat.prototype.addPlacemarks = function(question){
    map = this.get_map();
    var tmpl = $('#question-template').html();
    var html = Mustache.render(tmpl, question);
    $('#mapQuestion').html(html);
    $('#question').closest('.card').prev().slideDown();
    if (this.layer){
        this.map.removeLayer(this.layer);
    }
    question.locations.forEach(function(elem){

        var geom = L.geoJson(elem.geometry);
        geom.on('click',function(evt){
            //TODO call result on geom val
        })
         // TODO on hover display labels
        geom.bindPopup(elem.value);
        geom.on('mouseover', function(e) {
            e.layer.openPopup();
        });
        geom.on('mouseout', function(e) {
            e.layer.closePopup();
        });
        geom.openPopup();
        geom.addTo(map);
        this.layer = geom;
        map.invalidateSize()
    });
}
<commit_msg>Remove layers from map<commit_after>$(document).ready(function(){
    $(".button-collapse").sideNav({
        menuWidth: 300
    });
    var austat = new Austat();

});
function Austat(){
    this.map = null;
    this.layer = null;
    this.makeTopics();
    this.makeQuestion();
}
Austat.prototype.get_map = function(){
    if( !this.map ){
        this.map = new L.Map('map');

        // create the tile layer with correct attribution
        var osmUrll = 'http://otile2.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png'

        //var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
        var osmAttrib='Map data © OpenStreetMap contributors';
        var osm = new L.TileLayer(osmUrll, {minZoom: 0, maxZoom: 12, attribution: osmAttrib});

        // start the map in Central Australia
        this.map.setView(new L.LatLng(-24.967335, 134.625094),4);
        this.map.addLayer(osm);
    }
    return this.map;
}

Austat.prototype.checkboxQuestion = function(question){
    var tmpl = $('#checkbox-template').html();
    var html = Mustache.render(tmpl, question);
    $('#question').html(html);
    var mapObj = this
    $('#question input[type=radio]').click(function(){
        var selected = $(this).attr('id');
        mapObj.results(selected);
        return false;
    });
    $('#question').closest('.card').slideDown();
}
Austat.prototype.mapSetup = function(question){
    $('#map').closest('.card').slideDown();
    this.addPlacemarks(question);
}
Austat.prototype.makeQuestion = function(){
    var austat = this;
    var topic = this.getRandomTopic();
    $.ajax({
        url: '/query/' + topic,
        success: function(q){
            console.log(!q['value'])
                var l = austat.getRandomItem(q.locations);
                q.question = Mustache.render(q.question, l)
                if(l.geometry){
                    austat.addPlacemarks(q)
                }else{
                    austat.checkboxQuestion(q);
                }
        }
    });
}

Austat.prototype.getRandomItem = function(list){
    return list[Math.floor(Math.random()*list.length)];
}

Austat.prototype.getRandomTopic = function(){
    // Get a random topic.
    topics = this.getAllTopics();
    return this.getRandomItem(topics);
}

Austat.prototype.getAllTopics = function(){
    // Get a list of ids for selected topics.
    var topics = [];
    $('input[name=topic]').each(function(i, topic){
        if($(this).is(':checked')){
            topics.push($(this).attr('topic'));
        }
    });
    return topics;
}
Austat.prototype.makeTopics = function(){
    // Get topics from api and create controls.
    $.ajax({
        async: false,
        url: '/topics',
        success: function(topics){
            var template = $('#topics-template').html();
            var html = Mustache.render(template, topics);
            $('#topics').html(html)
        }
    });
}

Austat.prototype.results = function(selected){
    $('#question').closest('.card').slideUp(function(){
        $('#answer').closest('.card').slideDown();
    });
    var mapObj = this;
    //answer.answer.correct = false;
    //if ('answer_' + answer.answer.id === selected){
    //    answer.answer.correct = true;
    //}
    var tmpl = $('#answer-template').html();
    var html = Mustache.render(tmpl, answer);
    $('#answer').html(html);
    $('#answer #next').click(function(){
        mapObj.makeQuestion()
        $(this).closest('.card').slideUp(function(){
            $('#question').closest('.card').slideDown();
        });
    });
}

Austat.prototype.addPlacemarks = function(question){
    map = this.get_map();
    var tmpl = $('#question-template').html();
    var html = Mustache.render(tmpl, question);
    $('#mapQuestion').html(html);
    $('#question').closest('.card').prev().slideDown();
    if (this.layer){
        this.map.removeLayer(this.layer);
    }
    var mapObj = this
    question.locations.forEach(function(elem){
        geom = L.geoJson(elem.geometry);
        geom.bindPopup(elem.name);
        geom.on('mouseover', function(e) {
            e.layer.openPopup();
        });
        geom.on('mouseout', function(e) {
            e.layer.closePopup();
        });
        geom.on('click', function(e) {
            mapObj.results(geom.value)
            $('#map').closest('.card').slideUp();
        });
        geom.openPopup();
        geom.addTo(map);
        this.layer = geom;
        map.invalidateSize()
    });
}
<|endoftext|>


<commit_before>describe("select formatting buttons when selection has style applied", function(){
  var STYLES = ['italic', 'bold', 'underline', 'strikethrough'];
  var SHORTCUT_KEYS = ['I', 'B', 'U', '5']; // italic, bold, underline, strikethrough
  var FIRST_LINE = 0;

  before(function(cb){
    helper.newPad(cb);
    this.timeout(60000);
  });

  var applyStyleOnLine = function(style, line) {
    var chrome$ = helper.padChrome$;
    selectLine(line);
    var $formattingButton = chrome$('.buttonicon-' + style);
    $formattingButton.click();
  }

  var isButtonSelected = function(style) {
    var chrome$ = helper.padChrome$;
    var $formattingButton = chrome$('.buttonicon-' + style);
   return $formattingButton.parent().hasClass('selected');
  }

  var selectLine = function(lineNumber, offsetStart, offsetEnd) {
    var inner$ = helper.padInner$;
    var $line = inner$("div").eq(lineNumber);
    helper.selectLines($line, $line, offsetStart, offsetEnd);
  }

  var placeCaretOnLine = function(lineNumber) {
    var inner$ = helper.padInner$;
    var $line = inner$("div").eq(lineNumber);
    $line.sendkeys('{leftarrow}');
  }

  var undo = function() {
    var $undoButton = helper.padChrome$(".buttonicon-undo");
    $undoButton.click();
  }

  var testIfFormattingButtonIsDeselected = function(style) {
    it('deselects the ' + style + ' button', function(done) {
      helper.waitFor(function(){
        return isButtonSelected(style) === false;
      }).done(done)
    });
  }

  var testIfFormattingButtonIsSelected = function(style) {
    it('selects the ' + style + ' button', function(done) {
      helper.waitFor(function(){
        return isButtonSelected(style);
      }).done(done)
    });
  }

  var applyStyleOnLineAndSelectIt = function(line, style, cb) {
    applyStyleOnLineOnFullLineAndRemoveSelection(line, style, selectLine, cb);
  }

  var applyStyleOnLineAndPlaceCaretOnit = function(line, style, cb) {
    applyStyleOnLineOnFullLineAndRemoveSelection(line, style, placeCaretOnLine, cb);
  }

  var applyStyleOnLineOnFullLineAndRemoveSelection = function(line, style, selectTarget, cb) {
    applyStyleOnLine(style, line);

    // we have to give some time to Etherpad detects the selection changed
    setTimeout(function() {
      // remove selection from previous line
      selectLine(line + 1);
      setTimeout(function() {
        // select the text or place the caret on a position that
        // has the formatting text applied previously
        selectTarget(line);
        cb();
      }, 1000);
    }, 1000);
  }

  var pressFormattingShortcutOnSelection = function(key) {
    var inner$ = helper.padInner$;
    var chrome$ = helper.padChrome$;

    //get the first text element out of the inner iframe
    var $firstTextElement = inner$("div").first();

    //select this text element
    $firstTextElement.sendkeys('{selectall}');

    var e = inner$.Event(helper.evtType);
    e.ctrlKey = true; // Control key
    e.which = key.charCodeAt(0); // I, U, B, 5
    inner$("#innerdocbody").trigger(e);
  }

  STYLES.forEach(function(style){
    context('when selection is in a text with ' + style + ' applied', function(){
      before(function (done) {
        this.timeout(4000);
        applyStyleOnLineAndSelectIt(FIRST_LINE, style, done);
      });

      after(function () {
        undo();
      });

      testIfFormattingButtonIsSelected(style);
    });

    context('when caret is in a position with ' + style + ' applied', function(){
      before(function (done) {
        this.timeout(4000);
        applyStyleOnLineAndPlaceCaretOnit(FIRST_LINE, style, done);
      });

      after(function () {
        undo();
      });

      testIfFormattingButtonIsSelected(style)
    });
  });

  context('when user applies a style and the selection does not change', function() {
    var style = STYLES[0]; // italic
    before(function () {
      applyStyleOnLine(style, FIRST_LINE);
    });

    // clean the style applied
    after(function () {
      applyStyleOnLine(style, FIRST_LINE);
    });

    it('selects the style button', function (done) {
      expect(isButtonSelected(style)).to.be(true);
      done();
    });
  });

  SHORTCUT_KEYS.forEach(function(key, index){
    var styleOfTheShortcut = STYLES[index]; // italic, bold, ...
    context('when user presses CMD + ' + key, function() {
      before(function () {
        pressFormattingShortcutOnSelection(key);
      });

      testIfFormattingButtonIsSelected(styleOfTheShortcut);

      context('and user presses CMD + ' + key + ' again', function() {
        before(function () {
          pressFormattingShortcutOnSelection(key);
        });

        testIfFormattingButtonIsDeselected(styleOfTheShortcut);
      });
    });
  });
});
<commit_msg>tests: remove more edge settimeout issues (#4060)<commit_after>describe("select formatting buttons when selection has style applied", function(){
  var STYLES = ['italic', 'bold', 'underline', 'strikethrough'];
  var SHORTCUT_KEYS = ['I', 'B', 'U', '5']; // italic, bold, underline, strikethrough
  var FIRST_LINE = 0;

  before(function(cb){
    helper.newPad(cb);
    this.timeout(60000);
  });

  var applyStyleOnLine = function(style, line) {
    var chrome$ = helper.padChrome$;
    selectLine(line);
    var $formattingButton = chrome$('.buttonicon-' + style);
    $formattingButton.click();
  }

  var isButtonSelected = function(style) {
    var chrome$ = helper.padChrome$;
    var $formattingButton = chrome$('.buttonicon-' + style);
   return $formattingButton.parent().hasClass('selected');
  }

  var selectLine = function(lineNumber, offsetStart, offsetEnd) {
    var inner$ = helper.padInner$;
    var $line = inner$("div").eq(lineNumber);
    helper.selectLines($line, $line, offsetStart, offsetEnd);
  }

  var placeCaretOnLine = function(lineNumber) {
    var inner$ = helper.padInner$;
    var $line = inner$("div").eq(lineNumber);
    $line.sendkeys('{leftarrow}');
  }

  var undo = function() {
    var $undoButton = helper.padChrome$(".buttonicon-undo");
    $undoButton.click();
  }

  var testIfFormattingButtonIsDeselected = function(style) {
    it('deselects the ' + style + ' button', function(done) {
      helper.waitFor(function(){
        return isButtonSelected(style) === false;
      }).done(done)
    });
  }

  var testIfFormattingButtonIsSelected = function(style) {
    it('selects the ' + style + ' button', function(done) {
      helper.waitFor(function(){
        return isButtonSelected(style);
      }).done(done)
    });
  }

  var applyStyleOnLineAndSelectIt = function(line, style, cb) {
    applyStyleOnLineOnFullLineAndRemoveSelection(line, style, selectLine, cb);
  }

  var applyStyleOnLineAndPlaceCaretOnit = function(line, style, cb) {
    applyStyleOnLineOnFullLineAndRemoveSelection(line, style, placeCaretOnLine, cb);
  }

  var applyStyleOnLineOnFullLineAndRemoveSelection = function(line, style, selectTarget, cb) {
    // see if line html has changed
    var inner$ = helper.padInner$;
    var oldLineHTML = inner$.find("div")[line];
    applyStyleOnLine(style, line);

    helper.waitFor(function(){
      var lineHTML = inner$.find("div")[line];
      return lineHTML !== oldLineHTML;
    });
      // remove selection from previous line
    selectLine(line + 1);
    setTimeout(function() {
      // select the text or place the caret on a position that
      // has the formatting text applied previously
      selectTarget(line);
      cb();
    }, 1000);
  }

  var pressFormattingShortcutOnSelection = function(key) {
    var inner$ = helper.padInner$;
    var chrome$ = helper.padChrome$;

    //get the first text element out of the inner iframe
    var $firstTextElement = inner$("div").first();

    //select this text element
    $firstTextElement.sendkeys('{selectall}');

    var e = inner$.Event(helper.evtType);
    e.ctrlKey = true; // Control key
    e.which = key.charCodeAt(0); // I, U, B, 5
    inner$("#innerdocbody").trigger(e);
  }

  STYLES.forEach(function(style){
    context('when selection is in a text with ' + style + ' applied', function(){
      before(function (done) {
        this.timeout(4000);
        applyStyleOnLineAndSelectIt(FIRST_LINE, style, done);
      });

      after(function () {
        undo();
      });

      testIfFormattingButtonIsSelected(style);
    });

    context('when caret is in a position with ' + style + ' applied', function(){
      before(function (done) {
        this.timeout(4000);
        applyStyleOnLineAndPlaceCaretOnit(FIRST_LINE, style, done);
      });

      after(function () {
        undo();
      });

      testIfFormattingButtonIsSelected(style)
    });
  });

  context('when user applies a style and the selection does not change', function() {
    var style = STYLES[0]; // italic
    before(function () {
      applyStyleOnLine(style, FIRST_LINE);
    });

    // clean the style applied
    after(function () {
      applyStyleOnLine(style, FIRST_LINE);
    });

    it('selects the style button', function (done) {
      expect(isButtonSelected(style)).to.be(true);
      done();
    });
  });

  SHORTCUT_KEYS.forEach(function(key, index){
    var styleOfTheShortcut = STYLES[index]; // italic, bold, ...
    context('when user presses CMD + ' + key, function() {
      before(function () {
        pressFormattingShortcutOnSelection(key);
      });

      testIfFormattingButtonIsSelected(styleOfTheShortcut);

      context('and user presses CMD + ' + key + ' again', function() {
        before(function () {
          pressFormattingShortcutOnSelection(key);
        });

        testIfFormattingButtonIsDeselected(styleOfTheShortcut);
      });
    });
  });
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import initializer from "ilios/instance-initializers/load-common-translations";

const { getOwner, Object:EmberObject } = Ember;

moduleForComponent('my-materials', 'Integration | Component | my materials', {
  integration: true,
  setup(){
    initializer.initialize(getOwner(this));
  },
});

let createMaterials = function(){
  let lm1 = EmberObject.create({
    title: 'title1',
    absoluteFileUri: 'http://myhost.com/url1',
    sessionTitle: 'session1title',
    course: '1',
    courseTitle: 'course1title',
    instructors: ['Instructor1name', 'Instructor2name'],
    firstOfferingDate: new Date(2003, 1, 2, 12),
    type: 'file',
    mimetype: 'pdf'
  });
  let lm2 = EmberObject.create({
    title: 'title2',
    link: 'http://myhost.com/url2',
    sessionTitle: 'session2title',
    course: '2',
    courseTitle: 'course2title',
    instructors: ['Instructor1name', 'Instructor2name'],
    firstOfferingDate: new Date(2016, 1, 2, 12),
    type: 'link',
  });
  let lm3 = EmberObject.create({
    title: 'title3',
    citation: 'citationtext',
    sessionTitle: 'session3title',
    course: '3',
    courseTitle: 'course3title',
    firstOfferingDate: new Date(2020, 1, 2, 12),
    type: 'citation'
  });

  return [lm1, lm2, lm3];
};

test('it renders empty', function(assert) {
  this.set('materials', []);
  this.set('nothing', parseInt);
  this.render(hbs`{{my-materials
    materials=materials
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
  }}`);

  assert.equal(this.$().text().trim(), 'None');
});

test('it renders with materials', function(assert) {
  assert.expect(26);
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;
  const firstLmLink = `${firstLmTitle} a`;
  const firstLmTypeIcon = `${firstLmTitle} i.fa-file-pdf-o`;
  const firstLmCourseTitle = `${materials}:eq(0) td:eq(1)`;
  const firstLmSessionTitle = `${materials}:eq(0) td:eq(0)`;
  const firstLmInstructor = `${materials}:eq(0) td:eq(3)`;
  const firstLmFirstOffering = `${materials}:eq(0) td:eq(4)`;

  const secondLmTitle = `${materials}:eq(1) td:eq(2)`;
  const secondLmLink = `${secondLmTitle} a`;
  const secondLmTypeIcon = `${secondLmTitle} i.fa-link`;

  const secondLmCourseTitle = `${materials}:eq(1) td:eq(1)`;
  const secondLmSessionTitle = `${materials}:eq(1) td:eq(0)`;
  const secondLmInstructor = `${materials}:eq(1) td:eq(3)`;
  const secondLmFirstOffering = `${materials}:eq(1) td:eq(4)`;

  const thirdLmTitle = `${materials}:eq(2) td:eq(2)`;
  const thirdLmLink = `${thirdLmTitle} a`;
  const thirdLmTypeIcon = `${thirdLmTitle} i.fa-paragraph`;
  const thirdLmCourseTitle = `${materials}:eq(2) td:eq(1)`;
  const thirdLmSessionTitle = `${materials}:eq(2) td:eq(0)`;
  const thirdLmInstructor = `${materials}:eq(2) td:eq(3)`;
  const thirdLmFirstOffering = `${materials}:eq(2) td:eq(4)`;

  const courseListOptions = '.course-filter option';
  const allCourses = `${courseListOptions}:eq(0)`;
  const firstCourse = `${courseListOptions}:eq(1)`;
  const secondCourse = `${courseListOptions}:eq(2)`;
  const thirdCourse = `${courseListOptions}:eq(3)`;

  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');
  assert.equal(this.$(firstLmLink).prop('href').trim(), 'http://myhost.com/url1');
  assert.equal(this.$(firstLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(firstLmSessionTitle).text().trim(), 'session1title');
  assert.equal(this.$(firstLmCourseTitle).text().trim(), 'course1title');
  assert.equal(this.$(firstLmInstructor).text().trim(), 'Instructor1name, Instructor2name');
  assert.equal(this.$(firstLmFirstOffering).text().trim(), '02/02/2003');

  assert.equal(this.$(secondLmTitle).text().trim(), 'title2');
  assert.equal(this.$(secondLmLink).prop('href').trim(), 'http://myhost.com/url2');
  assert.equal(this.$(secondLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(secondLmSessionTitle).text().trim(), 'session2title');
  assert.equal(this.$(secondLmCourseTitle).text().trim(), 'course2title');
  assert.equal(this.$(secondLmInstructor).text().trim(), 'Instructor1name, Instructor2name');
  assert.equal(this.$(secondLmFirstOffering).text().trim(), '02/02/2016');

  assert.equal(this.$(thirdLmTitle).text().replace(/[\t\n\s]+/g, ""), 'title3citationtext');
  assert.equal(this.$(thirdLmLink).length, 0);
  assert.equal(this.$(thirdLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(thirdLmSessionTitle).text().trim(), 'session3title');
  assert.equal(this.$(thirdLmCourseTitle).text().trim(), 'course3title');
  assert.equal(this.$(thirdLmInstructor).text().trim(), '');
  assert.equal(this.$(thirdLmFirstOffering).text().trim(), '02/02/2020');

  assert.equal(this.$(courseListOptions).length, 4);
  assert.equal(this.$(allCourses).text().trim(), 'All Courses');
  assert.equal(this.$(firstCourse).text().trim(), 'course1title');
  assert.equal(this.$(secondCourse).text().trim(), 'course2title');
  assert.equal(this.$(thirdCourse).text().trim(), 'course3title');
});

test('filter by title', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 3);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'title2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('filter by instructor', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;
  const secondLmTitle = `${materials}:eq(1) td:eq(2)`;

  assert.equal(this.$(materials).length, 3);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'instructor1name');

  assert.equal(this.$(materials).length, 2);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');
  assert.equal(this.$(secondLmTitle).text().trim(), 'title2');
});

test('filter by session title', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 3);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'session2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('filter by course title', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 3);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'course2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('filter by course', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('courseIdFilter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    courseIdFilter=courseIdFilter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 3);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('courseIdFilter', '2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('clicking sort fires action', function(assert) {
  assert.expect(8);

  this.set('materials', createMaterials());
  this.set('nothing', parseInt);

  let count = 0;
  let sortBys = ['title', 'title:desc', 'courseTitle', 'courseTitle:desc', 'sessionTitle', 'sessionTitle:desc', 'firstOfferingDate', 'firstOfferingDate:desc'];
  this.set('setSortBy', (what) => {
    assert.equal(what, sortBys[count]);
    this.set('sortBy', what);

    count++;
  });

  this.set('sortBy', 'firstOfferingDate');

  this.render(hbs`{{my-materials
    materials=materials
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    setSortBy=(action setSortBy)
    sortBy=sortBy
  }}`);

  const table = 'table:eq(0)';
  const headers = `${table} thead th`;
  const title = `${headers}:eq(2)`;
  const courseTitle = `${headers}:eq(1)`;
  const sessionTitle = `${headers}:eq(0)`;
  const firstOffering = `${headers}:eq(4)`;

  this.$(title).click();
  this.$(title).click();
  this.$(courseTitle).click();
  this.$(courseTitle).click();
  this.$(sessionTitle).click();
  this.$(sessionTitle).click();
  this.$(firstOffering).click();
  this.$(firstOffering).click();

});

test('choosing course fires action', function(assert) {
  assert.expect(3);

  this.set('materials', createMaterials());
  this.set('nothing', parseInt);

  let count = 0;
  let courses = ['1', '3', 'null'];
  this.set('setCourseIdFilter', (what) => {
    assert.equal(what, courses[count]);
    this.set('courseIdFilter', what);

    count++;
  });

  this.set('courseIdFilter', null);

  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    setCourseIdFilter=(action setCourseIdFilter)
    courseIdFilter=courseIdFilter
  }}`);

  const select = '.course-filter select';
  const options = `${select} option`;
  const allCourses = `${options}:eq(0)`;
  const firstCourse = `${options}:eq(1)`;
  const thirdCourse = `${options}:eq(3)`;

  this.$(firstCourse).prop('selected', true).change();
  this.$(thirdCourse).prop('selected', true).change();
  this.$(allCourses).prop('selected', true).change();

});

test('find with slash does not blow up on regex error', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 3);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', "course2\\");

  assert.equal(this.$(materials).length, 0);
});
<commit_msg>test for pdf d/l link in my-materials.<commit_after>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import initializer from "ilios/instance-initializers/load-common-translations";

const { getOwner, Object:EmberObject } = Ember;

moduleForComponent('my-materials', 'Integration | Component | my materials', {
  integration: true,
  setup(){
    initializer.initialize(getOwner(this));
  },
});

let createMaterials = function(){
  let lm1 = EmberObject.create({
    title: 'title1',
    absoluteFileUri: 'http://myhost.com/url1',
    sessionTitle: 'session1title',
    course: '1',
    courseTitle: 'course1title',
    instructors: ['Instructor1name', 'Instructor2name'],
    firstOfferingDate: new Date(2003, 1, 2, 12),
    type: 'file',
    mimetype: 'application/pdf'
  });
  let lm2 = EmberObject.create({
    title: 'title2',
    link: 'http://myhost.com/url2',
    sessionTitle: 'session2title',
    course: '2',
    courseTitle: 'course2title',
    instructors: ['Instructor1name', 'Instructor2name'],
    firstOfferingDate: new Date(2016, 1, 2, 12),
    type: 'link',
  });
  let lm3 = EmberObject.create({
    title: 'title3',
    citation: 'citationtext',
    sessionTitle: 'session3title',
    course: '3',
    courseTitle: 'course3title',
    firstOfferingDate: new Date(2020, 1, 2, 12),
    type: 'citation'
  });
  let lm4 = EmberObject.create({
    title: 'title4',
    absoluteFileUri: 'http://myhost.com/document.txt',
    sessionTitle: 'session4title',
    course: '4',
    courseTitle: 'course4title',
    instructors: ['Instructor3name', 'Instructor4name'],
    firstOfferingDate: new Date(2030, 1, 2, 12),
    type: 'file',
    mimetype: 'plain/text'
  });

  return [lm1, lm2, lm3, lm4];
};

test('it renders empty', function(assert) {
  this.set('materials', []);
  this.set('nothing', parseInt);
  this.render(hbs`{{my-materials
    materials=materials
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
  }}`);

  assert.equal(this.$().text().trim(), 'None');
});

test('it renders with materials', function(assert) {
  assert.expect(35);
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;

  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;
  const firstLmLink = `${firstLmTitle} a:eq(0)`;
  const firstLmTypeIcon = `${firstLmTitle} i.fa-file-pdf-o`;
  const firstLmCourseTitle = `${materials}:eq(0) td:eq(1)`;
  const firstLmSessionTitle = `${materials}:eq(0) td:eq(0)`;
  const firstLmInstructor = `${materials}:eq(0) td:eq(3)`;
  const firstLmFirstOffering = `${materials}:eq(0) td:eq(4)`;
  const firstLmDownloadLink = `${firstLmTitle} a:eq(1)`;

  const secondLmTitle = `${materials}:eq(1) td:eq(2)`;
  const secondLmLink = `${secondLmTitle} a`;
  const secondLmTypeIcon = `${secondLmTitle} i.fa-link`;

  const secondLmCourseTitle = `${materials}:eq(1) td:eq(1)`;
  const secondLmSessionTitle = `${materials}:eq(1) td:eq(0)`;
  const secondLmInstructor = `${materials}:eq(1) td:eq(3)`;
  const secondLmFirstOffering = `${materials}:eq(1) td:eq(4)`;

  const thirdLmTitle = `${materials}:eq(2) td:eq(2)`;
  const thirdLmLink = `${thirdLmTitle} a`;
  const thirdLmTypeIcon = `${thirdLmTitle} i.fa-paragraph`;
  const thirdLmCourseTitle = `${materials}:eq(2) td:eq(1)`;
  const thirdLmSessionTitle = `${materials}:eq(2) td:eq(0)`;
  const thirdLmInstructor = `${materials}:eq(2) td:eq(3)`;
  const thirdLmFirstOffering = `${materials}:eq(2) td:eq(4)`;

  const fourthLmTitle = `${materials}:eq(3) td:eq(2)`;
  const fourthLmLink = `${fourthLmTitle} a`;
  const fourthLmTypeIcon = `${fourthLmTitle} i.fa-file`;
  const fourthLmCourseTitle = `${materials}:eq(3) td:eq(1)`;
  const fourthLmSessionTitle = `${materials}:eq(3) td:eq(0)`;
  const fourthLmInstructor = `${materials}:eq(3) td:eq(3)`;
  const fourthLmFirstOffering = `${materials}:eq(3) td:eq(4)`;

  const courseListOptions = '.course-filter option';
  const allCourses = `${courseListOptions}:eq(0)`;
  const firstCourse = `${courseListOptions}:eq(1)`;
  const secondCourse = `${courseListOptions}:eq(2)`;
  const thirdCourse = `${courseListOptions}:eq(3)`;
  const fourthCourse = `${courseListOptions}:eq(4)`;

  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');
  assert.equal(this.$(firstLmLink).prop('href').trim(), 'http://myhost.com/url1?inline');
  assert.equal(this.$(firstLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(firstLmSessionTitle).text().trim(), 'session1title');
  assert.equal(this.$(firstLmCourseTitle).text().trim(), 'course1title');
  assert.equal(this.$(firstLmInstructor).text().trim(), 'Instructor1name, Instructor2name');
  assert.equal(this.$(firstLmFirstOffering).text().trim(), '02/02/2003');
  assert.equal(this.$(firstLmDownloadLink).prop('href').trim(), 'http://myhost.com/url1');

  assert.equal(this.$(secondLmTitle).text().trim(), 'title2');
  assert.equal(this.$(secondLmLink).prop('href').trim(), 'http://myhost.com/url2');
  assert.equal(this.$(secondLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(secondLmSessionTitle).text().trim(), 'session2title');
  assert.equal(this.$(secondLmCourseTitle).text().trim(), 'course2title');
  assert.equal(this.$(secondLmInstructor).text().trim(), 'Instructor1name, Instructor2name');
  assert.equal(this.$(secondLmFirstOffering).text().trim(), '02/02/2016');

  assert.equal(this.$(thirdLmTitle).text().replace(/[\t\n\s]+/g, ""), 'title3citationtext');
  assert.equal(this.$(thirdLmLink).length, 0);
  assert.equal(this.$(thirdLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(thirdLmSessionTitle).text().trim(), 'session3title');
  assert.equal(this.$(thirdLmCourseTitle).text().trim(), 'course3title');
  assert.equal(this.$(thirdLmInstructor).text().trim(), '');
  assert.equal(this.$(thirdLmFirstOffering).text().trim(), '02/02/2020');

  assert.equal(this.$(fourthLmTitle).text().trim(), 'title4');
  assert.equal(this.$(fourthLmLink).prop('href').trim(), 'http://myhost.com/document.txt');
  assert.equal(this.$(fourthLmTypeIcon).length, 1, 'LM type icon is present.');
  assert.equal(this.$(fourthLmSessionTitle).text().trim(), 'session4title');
  assert.equal(this.$(fourthLmCourseTitle).text().trim(), 'course4title');
  assert.equal(this.$(fourthLmInstructor).text().trim(), 'Instructor3name, Instructor4name');
  assert.equal(this.$(fourthLmFirstOffering).text().trim(), '02/02/2030');

  assert.equal(this.$(courseListOptions).length, 5);
  assert.equal(this.$(allCourses).text().trim(), 'All Courses');
  assert.equal(this.$(firstCourse).text().trim(), 'course1title');
  assert.equal(this.$(secondCourse).text().trim(), 'course2title');
  assert.equal(this.$(thirdCourse).text().trim(), 'course3title');
  assert.equal(this.$(fourthCourse).text().trim(), 'course4title');
});

test('filter by title', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 4);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'title2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('filter by instructor', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;
  const secondLmTitle = `${materials}:eq(1) td:eq(2)`;

  assert.equal(this.$(materials).length, 4);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'instructor1name');

  assert.equal(this.$(materials).length, 2);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');
  assert.equal(this.$(secondLmTitle).text().trim(), 'title2');
});

test('filter by session title', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 4);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'session2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('filter by course title', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 4);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', 'course2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('filter by course', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('courseIdFilter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    courseIdFilter=courseIdFilter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 4);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('courseIdFilter', '2');

  assert.equal(this.$(materials).length, 1);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title2');
});

test('clicking sort fires action', function(assert) {
  assert.expect(8);

  this.set('materials', createMaterials());
  this.set('nothing', parseInt);

  let count = 0;
  let sortBys = ['title', 'title:desc', 'courseTitle', 'courseTitle:desc', 'sessionTitle', 'sessionTitle:desc', 'firstOfferingDate', 'firstOfferingDate:desc'];
  this.set('setSortBy', (what) => {
    assert.equal(what, sortBys[count]);
    this.set('sortBy', what);

    count++;
  });

  this.set('sortBy', 'firstOfferingDate');

  this.render(hbs`{{my-materials
    materials=materials
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    setSortBy=(action setSortBy)
    sortBy=sortBy
  }}`);

  const table = 'table:eq(0)';
  const headers = `${table} thead th`;
  const title = `${headers}:eq(2)`;
  const courseTitle = `${headers}:eq(1)`;
  const sessionTitle = `${headers}:eq(0)`;
  const firstOffering = `${headers}:eq(4)`;

  this.$(title).click();
  this.$(title).click();
  this.$(courseTitle).click();
  this.$(courseTitle).click();
  this.$(sessionTitle).click();
  this.$(sessionTitle).click();
  this.$(firstOffering).click();
  this.$(firstOffering).click();

});

test('choosing course fires action', function(assert) {
  assert.expect(3);

  this.set('materials', createMaterials());
  this.set('nothing', parseInt);

  let count = 0;
  let courses = ['1', '3', 'null'];
  this.set('setCourseIdFilter', (what) => {
    assert.equal(what, courses[count]);
    this.set('courseIdFilter', what);

    count++;
  });

  this.set('courseIdFilter', null);

  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    setCourseIdFilter=(action setCourseIdFilter)
    courseIdFilter=courseIdFilter
  }}`);

  const select = '.course-filter select';
  const options = `${select} option`;
  const allCourses = `${options}:eq(0)`;
  const firstCourse = `${options}:eq(1)`;
  const thirdCourse = `${options}:eq(3)`;

  this.$(firstCourse).prop('selected', true).change();
  this.$(thirdCourse).prop('selected', true).change();
  this.$(allCourses).prop('selected', true).change();

});

test('find with slash does not blow up on regex error', function(assert) {
  this.set('materials', createMaterials());
  this.set('nothing', parseInt);
  this.set('filter', null);
  this.render(hbs`{{my-materials
    materials=materials
    sortBy='firstOfferingDate'
    setCourseIdFilter=(action nothing)
    setFilter=(action nothing)
    filter=filter
  }}`);

  const table = 'table:eq(0)';
  const materials = `${table} tbody tr`;
  const firstLmTitle = `${materials}:eq(0) td:eq(2)`;

  assert.equal(this.$(materials).length, 4);
  assert.equal(this.$(firstLmTitle).text().trim(), 'title1');

  this.set('filter', "course2\\");

  assert.equal(this.$(materials).length, 0);
});
<|endoftext|>


<commit_before>module.exports = function(grunt) {
    return {
        files: ["src/**/*"],
        tasks: ['build-dist']
    };
};<commit_msg>Updating build task name.<commit_after>module.exports = function(grunt) {
    return {
        files: ["src/**/*"],
        tasks: ['build']
    };
};
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * 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 Ajax.org B.V. 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 AJAX.ORG B.V. 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.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var dom = require("../lib/dom");
var lang = require("../lib/lang");
var event = require("../lib/event");
var searchboxCss = require("../requirejs/text!./searchbox.css");
var HashHandler = require("../keyboard/hash_handler").HashHandler;
var keyUtil = require("../lib/keys");

var MAX_COUNT = 999;

dom.importCssString(searchboxCss, "ace_searchbox");

var html = '
\
    \

\
        <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>\
        \
        \
        All\

\

\
        <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>\
        Replace\
        All\

\

\
        +\
        \
        .*\
        Aa\
        \\b\

\

'.replace(/> +/g, ">");

var SearchBox = function(editor, range, showReplaceForm) {
    var div = dom.createElement("div");
    div.innerHTML = html;
    this.element = div.firstChild;

    this.$init();
    this.setEditor(editor);
};

(function() {
    this.setEditor = function(editor) {
        editor.searchBox = this;
        editor.renderer.scroller.appendChild(this.element);
        this.editor = editor;
    };

    this.$initElements = function(sb) {
        this.searchBox = sb.querySelector(".ace_search_form");
        this.replaceBox = sb.querySelector(".ace_replace_form");
        this.searchOptions = sb.querySelector(".ace_search_options");
        this.replaceOption = sb.querySelector("[action=toggleReplace]");
        this.regExpOption = sb.querySelector("[action=toggleRegexpMode]");
        this.caseSensitiveOption = sb.querySelector("[action=toggleCaseSensitive]");
        this.wholeWordOption = sb.querySelector("[action=toggleWholeWords]");
        this.searchInput = this.searchBox.querySelector(".ace_search_field");
        this.replaceInput = this.replaceBox.querySelector(".ace_search_field");
        this.searchCounter = sb.querySelector(".ace_search_counter");
    };

    this.$init = function() {
        var sb = this.element;

        this.$initElements(sb);

        var _this = this;
        event.addListener(sb, "mousedown", function(e) {
            setTimeout(function(){
                _this.activeInput.focus();
            }, 0);
            event.stopPropagation(e);
        });
        event.addListener(sb, "click", function(e) {
            var t = e.target || e.srcElement;
            var action = t.getAttribute("action");
            if (action && _this[action])
                _this[action]();
            else if (_this.$searchBarKb.commands[action])
                _this.$searchBarKb.commands[action].exec(_this);
            event.stopPropagation(e);
        });

        event.addCommandKeyListener(sb, function(e, hashId, keyCode) {
            var keyString = keyUtil.keyCodeToString(keyCode);
            var command = _this.$searchBarKb.findKeyCommand(hashId, keyString);
            if (command && command.exec) {
                command.exec(_this);
                event.stopEvent(e);
            }
        });

        this.$onChange = lang.delayedCall(function() {
            _this.find(false, false);
        });

        event.addListener(this.searchInput, "input", function() {
            _this.$onChange.schedule(20);
        });
        event.addListener(this.searchInput, "focus", function() {
            _this.activeInput = _this.searchInput;
            _this.searchInput.value && _this.highlight();
        });
        event.addListener(this.replaceInput, "focus", function() {
            _this.activeInput = _this.replaceInput;
            _this.searchInput.value && _this.highlight();
        });
    };

    //keybinging outsite of the searchbox
    this.$closeSearchBarKb = new HashHandler([{
        bindKey: "Esc",
        name: "closeSearchBar",
        exec: function(editor) {
            editor.searchBox.hide();
        }
    }]);

    //keybinging outsite of the searchbox
    this.$searchBarKb = new HashHandler();
    this.$searchBarKb.bindKeys({
        "Ctrl-f|Command-f": function(sb) {
            var isReplace = sb.isReplace = !sb.isReplace;
            sb.replaceBox.style.display = isReplace ? "" : "none";
            sb.replaceOption.checked = false;
            sb.$syncOptions();
            sb.searchInput.focus();
        },
        "Ctrl-H|Command-Option-F": function(sb) {
            sb.replaceOption.checked = true;
            sb.$syncOptions();
            sb.replaceInput.focus();
        },
        "Ctrl-G|Command-G": function(sb) {
            sb.findNext();
        },
        "Ctrl-Shift-G|Command-Shift-G": function(sb) {
            sb.findPrev();
        },
        "esc": function(sb) {
            setTimeout(function() { sb.hide();});
        },
        "Return": function(sb) {
            if (sb.activeInput == sb.replaceInput)
                sb.replace();
            sb.findNext();
        },
        "Shift-Return": function(sb) {
            if (sb.activeInput == sb.replaceInput)
                sb.replace();
            sb.findPrev();
        },
        "Alt-Return": function(sb) {
            if (sb.activeInput == sb.replaceInput)
                sb.replaceAll();
            sb.findAll();
        },
        "Tab": function(sb) {
            (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();
        }
    });

    this.$searchBarKb.addCommands([{
        name: "toggleRegexpMode",
        bindKey: {win: "Alt-R|Alt-/", mac: "Ctrl-Alt-R|Ctrl-Alt-/"},
        exec: function(sb) {
            sb.regExpOption.checked = !sb.regExpOption.checked;
            sb.$syncOptions();
        }
    }, {
        name: "toggleCaseSensitive",
        bindKey: {win: "Alt-C|Alt-I", mac: "Ctrl-Alt-R|Ctrl-Alt-I"},
        exec: function(sb) {
            sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked;
            sb.$syncOptions();
        }
    }, {
        name: "toggleWholeWords",
        bindKey: {win: "Alt-B|Alt-W", mac: "Ctrl-Alt-B|Ctrl-Alt-W"},
        exec: function(sb) {
            sb.wholeWordOption.checked = !sb.wholeWordOption.checked;
            sb.$syncOptions();
        }
    }, {
        name: "toggleReplace",
        exec: function(sb) {
            sb.replaceOption.checked = !sb.replaceOption.checked;
            sb.$syncOptions();
        }
    }]);

    this.$syncOptions = function(preventScroll) {
        dom.setCssClass(this.replaceOption, "checked", this.replaceOption.checked);
        this.replaceOption.textContent = this.replaceOption.checked ? "-" : "+"
        dom.setCssClass(this.regExpOption, "checked", this.regExpOption.checked);
        dom.setCssClass(this.wholeWordOption, "checked", this.wholeWordOption.checked);
        dom.setCssClass(this.caseSensitiveOption, "checked", this.caseSensitiveOption.checked);
        this.replaceBox.style.display = this.replaceOption.checked ? "" : "none";
        this.find(false, false, preventScroll);
    };

    this.highlight = function(re) {
        this.editor.session.highlight(re || this.editor.$search.$options.re);
        this.editor.renderer.updateBackMarkers()
    };
    this.find = function(skipCurrent, backwards, preventScroll) {
        var range = this.editor.find(this.searchInput.value, {
            skipCurrent: skipCurrent,
            backwards: backwards,
            wrap: true,
            regExp: this.regExpOption.checked,
            caseSensitive: this.caseSensitiveOption.checked,
            wholeWord: this.wholeWordOption.checked,
            preventScroll: preventScroll
        });
        var noMatch = !range && this.searchInput.value;
        dom.setCssClass(this.searchBox, "ace_nomatch", noMatch);
        this.editor._emit("findSearchBox", { match: !noMatch });
        this.highlight();
        this.updateCounter();
    };
    this.updateCounter = function() {
        var editor = this.editor;
        var offset = editor.session.doc.positionToIndex(editor.selection.anchor);
        var regex = editor.$search.$options.re;
        var all = 0;
        var before = 0
        if (regex) {
            var value = editor.getValue();
            var last = regex.lastIndex = 0;
            var m;
            while ((m = regex.exec(value))) {
                all++;
                last = m.index;
                if (last <= offset)
                    before++;
                if (all > MAX_COUNT)
                    break
                if (!m[0]) {
                    regex.lastIndex = last += 1;
                    if (last >= value.length)
                        break;
                }
            }
        }
        this.searchCounter.textContent = before + " of " + (all > MAX_COUNT ? MAX_COUNT + "+" : all);
    };
    this.findNext = function() {
        this.find(true, false);
    };
    this.findPrev = function() {
        this.find(true, true);
    };
    this.findAll = function(){
        var range = this.editor.findAll(this.searchInput.value, {
            regExp: this.regExpOption.checked,
            caseSensitive: this.caseSensitiveOption.checked,
            wholeWord: this.wholeWordOption.checked
        });
        var noMatch = !range && this.searchInput.value;
        dom.setCssClass(this.searchBox, "ace_nomatch", noMatch);
        this.editor._emit("findSearchBox", { match: !noMatch });
        this.highlight();
        this.hide();
    };
    this.replace = function() {
        if (!this.editor.getReadOnly())
            this.editor.replace(this.replaceInput.value);
    };
    this.replaceAndFindNext = function() {
        if (!this.editor.getReadOnly()) {
            this.editor.replace(this.replaceInput.value);
            this.findNext()
        }
    };
    this.replaceAll = function() {
        if (!this.editor.getReadOnly())
            this.editor.replaceAll(this.replaceInput.value);
    };

    this.hide = function() {
        this.element.style.display = "none";
        this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb);
        this.editor.focus();
    };
    this.show = function(value, isReplace) {
        this.element.style.display = "";
        this.replaceOption.checked = isReplace;

        if (value)
            this.searchInput.value = value;

        this.searchInput.focus();
        this.searchInput.select();

        this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);

        this.$syncOptions(true);
    };

    this.isFocused = function() {
        var el = document.activeElement;
        return el == this.searchInput || el == this.replaceInput;
    }
}).call(SearchBox.prototype);

exports.SearchBox = SearchBox;

exports.Search = function(editor, isReplace) {
    var sb = editor.searchBox || new SearchBox(editor);
    sb.show(editor.session.getTextRange(), isReplace);
};

});

/* ------------------------------------------------------------------------------------------
 * TODO
 * --------------------------------------------------------------------------------------- */
/*
- move search form to the left if it masks current word
- includ all options that search has. ex: regex
- searchbox.searchbox is not that pretty. we should have just searchbox
- disable prev button if it makes sence
*/
<commit_msg>add search in range option<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * 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 Ajax.org B.V. 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 AJAX.ORG B.V. 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.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var dom = require("../lib/dom");
var lang = require("../lib/lang");
var event = require("../lib/event");
var searchboxCss = require("../requirejs/text!./searchbox.css");
var HashHandler = require("../keyboard/hash_handler").HashHandler;
var keyUtil = require("../lib/keys");

var MAX_COUNT = 999;

dom.importCssString(searchboxCss, "ace_searchbox");

var html = '
\
    \

\
        <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>\
        \
        \
        All\

\

\
        <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>\
        Replace\
        All\

\

\
        +\
        \
        .*\
        Aa\
        \\b\
        S\

\

'.replace(/> +/g, ">");

var SearchBox = function(editor, range, showReplaceForm) {
    var div = dom.createElement("div");
    div.innerHTML = html;
    this.element = div.firstChild;

    this.setSession = this.setSession.bind(this);

    this.$init();
    this.setEditor(editor);
};

(function() {
    this.setEditor = function(editor) {
        editor.searchBox = this;
        editor.renderer.scroller.appendChild(this.element);
        this.editor = editor;
    };

    this.setSession = function(e) {
        debugger
        this.searchRange = null;
        this.$syncOptions(true);
    }

    this.$initElements = function(sb) {
        this.searchBox = sb.querySelector(".ace_search_form");
        this.replaceBox = sb.querySelector(".ace_replace_form");
        this.searchOption = sb.querySelector("[action=searchInSelection]");
        this.replaceOption = sb.querySelector("[action=toggleReplace]");
        this.regExpOption = sb.querySelector("[action=toggleRegexpMode]");
        this.caseSensitiveOption = sb.querySelector("[action=toggleCaseSensitive]");
        this.wholeWordOption = sb.querySelector("[action=toggleWholeWords]");
        this.searchInput = this.searchBox.querySelector(".ace_search_field");
        this.replaceInput = this.replaceBox.querySelector(".ace_search_field");
        this.searchCounter = sb.querySelector(".ace_search_counter");
    };

    this.$init = function() {
        var sb = this.element;

        this.$initElements(sb);

        var _this = this;
        event.addListener(sb, "mousedown", function(e) {
            setTimeout(function(){
                _this.activeInput.focus();
            }, 0);
            event.stopPropagation(e);
        });
        event.addListener(sb, "click", function(e) {
            var t = e.target || e.srcElement;
            var action = t.getAttribute("action");
            if (action && _this[action])
                _this[action]();
            else if (_this.$searchBarKb.commands[action])
                _this.$searchBarKb.commands[action].exec(_this);
            event.stopPropagation(e);
        });

        event.addCommandKeyListener(sb, function(e, hashId, keyCode) {
            var keyString = keyUtil.keyCodeToString(keyCode);
            var command = _this.$searchBarKb.findKeyCommand(hashId, keyString);
            if (command && command.exec) {
                command.exec(_this);
                event.stopEvent(e);
            }
        });

        this.$onChange = lang.delayedCall(function() {
            _this.find(false, false);
        });

        event.addListener(this.searchInput, "input", function() {
            _this.$onChange.schedule(20);
        });
        event.addListener(this.searchInput, "focus", function() {
            _this.activeInput = _this.searchInput;
            _this.searchInput.value && _this.highlight();
        });
        event.addListener(this.replaceInput, "focus", function() {
            _this.activeInput = _this.replaceInput;
            _this.searchInput.value && _this.highlight();
        });
    };

    //keybinging outsite of the searchbox
    this.$closeSearchBarKb = new HashHandler([{
        bindKey: "Esc",
        name: "closeSearchBar",
        exec: function(editor) {
            editor.searchBox.hide();
        }
    }]);

    //keybinging outsite of the searchbox
    this.$searchBarKb = new HashHandler();
    this.$searchBarKb.bindKeys({
        "Ctrl-f|Command-f": function(sb) {
            var isReplace = sb.isReplace = !sb.isReplace;
            sb.replaceBox.style.display = isReplace ? "" : "none";
            sb.replaceOption.checked = false;
            sb.$syncOptions();
            sb.searchInput.focus();
        },
        "Ctrl-H|Command-Option-F": function(sb) {
            sb.replaceOption.checked = true;
            sb.$syncOptions();
            sb.replaceInput.focus();
        },
        "Ctrl-G|Command-G": function(sb) {
            sb.findNext();
        },
        "Ctrl-Shift-G|Command-Shift-G": function(sb) {
            sb.findPrev();
        },
        "esc": function(sb) {
            setTimeout(function() { sb.hide();});
        },
        "Return": function(sb) {
            if (sb.activeInput == sb.replaceInput)
                sb.replace();
            sb.findNext();
        },
        "Shift-Return": function(sb) {
            if (sb.activeInput == sb.replaceInput)
                sb.replace();
            sb.findPrev();
        },
        "Alt-Return": function(sb) {
            if (sb.activeInput == sb.replaceInput)
                sb.replaceAll();
            sb.findAll();
        },
        "Tab": function(sb) {
            (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();
        }
    });

    this.$searchBarKb.addCommands([{
        name: "toggleRegexpMode",
        bindKey: {win: "Alt-R|Alt-/", mac: "Ctrl-Alt-R|Ctrl-Alt-/"},
        exec: function(sb) {
            sb.regExpOption.checked = !sb.regExpOption.checked;
            sb.$syncOptions();
        }
    }, {
        name: "toggleCaseSensitive",
        bindKey: {win: "Alt-C|Alt-I", mac: "Ctrl-Alt-R|Ctrl-Alt-I"},
        exec: function(sb) {
            sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked;
            sb.$syncOptions();
        }
    }, {
        name: "toggleWholeWords",
        bindKey: {win: "Alt-B|Alt-W", mac: "Ctrl-Alt-B|Ctrl-Alt-W"},
        exec: function(sb) {
            sb.wholeWordOption.checked = !sb.wholeWordOption.checked;
            sb.$syncOptions();
        }
    }, {
        name: "searchInSelection",
        exec: function(sb) {
            sb.searchOption.checked = !sb.searchRange;
            sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange());
            sb.$syncOptions();
        }
    }]);

    this.setSearchRange = function(range) {
        this.searchRange = range;
        if (range) {
            this.searchRangeMarker = this.editor.session.addMarker(range, "ace_active-line");
        } else if (this.searchRangeMarker) {
            this.editor.session.removeMarker(this.searchRangeMarker);
            this.searchRangeMarker = null;
        }
    }

    this.$syncOptions = function(preventScroll) {
        dom.setCssClass(this.replaceOption, "checked", this.searchRange);
        dom.setCssClass(this.searchOption, "checked", this.searchOption.checked);
        this.replaceOption.textContent = this.replaceOption.checked ? "-" : "+";
        dom.setCssClass(this.regExpOption, "checked", this.regExpOption.checked);
        dom.setCssClass(this.wholeWordOption, "checked", this.wholeWordOption.checked);
        dom.setCssClass(this.caseSensitiveOption, "checked", this.caseSensitiveOption.checked);
        this.replaceBox.style.display = this.replaceOption.checked ? "" : "none";
        this.find(false, false, preventScroll);
    };

    this.highlight = function(re) {
        this.editor.session.highlight(re || this.editor.$search.$options.re);
        this.editor.renderer.updateBackMarkers()
    };
    this.find = function(skipCurrent, backwards, preventScroll) {
        var range = this.editor.find(this.searchInput.value, {
            skipCurrent: skipCurrent,
            backwards: backwards,
            wrap: true,
            regExp: this.regExpOption.checked,
            caseSensitive: this.caseSensitiveOption.checked,
            wholeWord: this.wholeWordOption.checked,
            preventScroll: preventScroll,
            range: this.searchRange
        });
        var noMatch = !range && this.searchInput.value;
        dom.setCssClass(this.searchBox, "ace_nomatch", noMatch);
        this.editor._emit("findSearchBox", { match: !noMatch });
        this.highlight();
        this.updateCounter();
    };
    this.updateCounter = function() {
        var editor = this.editor;
        var regex = editor.$search.$options.re;
        var all = 0;
        var before = 0
        if (regex) {
            var value = this.searchRange
                ? editor.session.getTextRange(this.searchRange)
                : editor.getValue();

            var offset = editor.session.doc.positionToIndex(editor.selection.anchor);
            if (this.searchRange)
                offset -= editor.session.doc.positionToIndex(this.searchRange.start);

            var last = regex.lastIndex = 0;
            var m;
            while ((m = regex.exec(value))) {
                all++;
                last = m.index;
                if (last <= offset)
                    before++;
                if (all > MAX_COUNT)
                    break
                if (!m[0]) {
                    regex.lastIndex = last += 1;
                    if (last >= value.length)
                        break;
                }
            }
        }
        this.searchCounter.textContent = before + " of " + (all > MAX_COUNT ? MAX_COUNT + "+" : all);
    };
    this.findNext = function() {
        this.find(true, false);
    };
    this.findPrev = function() {
        this.find(true, true);
    };
    this.findAll = function(){
        var range = this.editor.findAll(this.searchInput.value, {
            regExp: this.regExpOption.checked,
            caseSensitive: this.caseSensitiveOption.checked,
            wholeWord: this.wholeWordOption.checked
        });
        var noMatch = !range && this.searchInput.value;
        dom.setCssClass(this.searchBox, "ace_nomatch", noMatch);
        this.editor._emit("findSearchBox", { match: !noMatch });
        this.highlight();
        this.hide();
    };
    this.replace = function() {
        if (!this.editor.getReadOnly())
            this.editor.replace(this.replaceInput.value);
    };
    this.replaceAndFindNext = function() {
        if (!this.editor.getReadOnly()) {
            this.editor.replace(this.replaceInput.value);
            this.findNext()
        }
    };
    this.replaceAll = function() {
        if (!this.editor.getReadOnly())
            this.editor.replaceAll(this.replaceInput.value);
    };

    this.hide = function() {
        this.active = false;
        this.setSearchRange(null)
        this.editor.off("changeSession", this.setSession);

        this.element.style.display = "none";
        this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb);
        this.editor.focus();
    };
    this.show = function(value, isReplace) {
        this.active = true;
        this.editor.on("changeSession", this.setSession);
        this.element.style.display = "";
        this.replaceOption.checked = isReplace;

        if (value)
            this.searchInput.value = value;

        this.searchInput.focus();
        this.searchInput.select();

        this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);

        this.$syncOptions(true);
    };

    this.isFocused = function() {
        var el = document.activeElement;
        return el == this.searchInput || el == this.replaceInput;
    }
}).call(SearchBox.prototype);

exports.SearchBox = SearchBox;

exports.Search = function(editor, isReplace) {
    var sb = editor.searchBox || new SearchBox(editor);
    sb.show(editor.session.getTextRange(), isReplace);
};

});

/* ------------------------------------------------------------------------------------------
 * TODO
 * --------------------------------------------------------------------------------------- */
/*
- move search form to the left if it masks current word
- includ all options that search has. ex: regex
- searchbox.searchbox is not that pretty. we should have just searchbox
- disable prev button if it makes sence
*/
<|endoftext|>


<commit_before>var marked = require("marked")
var renderer = new marked.Renderer()
var accents = {
  "à" : "a",
  "á" : "a",
  "â" : "a",
  "ã" : "a",
  "ä" : "a",
  "å" : "a",
  "æ" : "ae",
  "ç" : "c",
  "è" : "e",
  "é" : "e",
  "ê" : "e",
  "ë" : "e",
  "ì" : "i",
  "í" : "i",
  "î" : "i",
  "ï" : "i",
  "ñ" : "n",
  "ò" : "o",
  "ó" : "o",
  "ô" : "o",
  "õ" : "o",
  "ö" : "o",
  "ø" : "o",
  "ù" : "u",
  "ú" : "u",
  "û" : "u",
  "ü" : "u",
  "ý" : "y"
}
var accentsRE = RegExp("(" + Object.keys(accents).join("|") + ")", "g")

marked.setOptions({
  highlight : function(code){
    return require("highlight.js").highlightAuto(code).value;
  },
  renderer : renderer,
  smartypants : true
})

renderer.heading = function(text, level){
  var escaped = text.toLowerCase()
    .replace(accentsRE, function(i){
      return accents[i]
    })
    .replace(/\W+/g, "-")

  return "<h" + level + " id=\"" + escaped + "\">" +
    "#" +
    text + "</h" + level + ">"
}

module.exports = marked
<commit_msg>Removing html links in anchors generation<commit_after>var marked = require("marked")
var renderer = new marked.Renderer()
var accents = {
  "à" : "a",
  "á" : "a",
  "â" : "a",
  "ã" : "a",
  "ä" : "a",
  "å" : "a",
  "æ" : "ae",
  "ç" : "c",
  "è" : "e",
  "é" : "e",
  "ê" : "e",
  "ë" : "e",
  "ì" : "i",
  "í" : "i",
  "î" : "i",
  "ï" : "i",
  "ñ" : "n",
  "ò" : "o",
  "ó" : "o",
  "ô" : "o",
  "õ" : "o",
  "ö" : "o",
  "ø" : "o",
  "ù" : "u",
  "ú" : "u",
  "û" : "u",
  "ü" : "u",
  "ý" : "y"
}
var accentsRE = RegExp("(" + Object.keys(accents).join("|") + ")", "g")

marked.setOptions({
  highlight : function(code){
    return require("highlight.js").highlightAuto(code).value;
  },
  renderer : renderer,
  smartypants : true
})

renderer.heading = function(text, level){
  var escaped = text.toLowerCase()
    .replace(accentsRE, function(i){
      return accents[i]
    })
    .replace(/(<\/?a[^>]*>)/ig, "") // strip html links in anchors
    .replace(/\W+/g, "-")

  return "<h" + level + " id=\"" + escaped + "\">" +
    "#" +
    text + "</h" + level + ">"
}

module.exports = marked
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('report-abuse', 'Integration | Component | report abuse', {
  integration: true
});

test('it renders', function(assert) {
  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });

  this.render(hbs`{{report-abuse}}`);

  assert.equal(this.$().text().trim(), '');

  // Template block usage:
  this.render(hbs`
    {{#report-abuse}}
      template block text
    {{/report-abuse}}
  `);

  assert.equal(this.$().text().trim(), 'template block text');
});
<commit_msg>fix test to say the thing<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('report-abuse', 'Integration | Component | report abuse', {
  integration: true
});

test('it renders', function(assert) {
  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });

  this.render(hbs`{{report-abuse}}`);

  assert.equal(this.$().text().trim(), 'report abuse');
});
<|endoftext|>