<commit_before>/*

Example usage:

$('.scrollwrap').scrollbalance({
    childSelector: '.mycolumn'
});

*/
(function($) {

    $.fn.scrollbalance = (function(options){
        var settings = $.extend({
            childSelector: '.scrollbox',
            topBuffer: 0
        }, options);

        this.each(function() {
            var container = $(this),
                top = container.offset().top;

            // make sure container has height
            container.find(settings.childSelector).each(function() {
                if (container.height() < $(this).outerHeight(true)) {
                    container.css('height', $(this).outerHeight(true) + 'px');
                }
            });

            container.find(settings.childSelector).each(function() {
                var col = $(this),
                    colHeight = col.outerHeight(true),
                    colWidth = col.width(),
                    maxScroll = container.height() - colHeight;

                function pinTop() {
                    return (colHeight < $(window).height());
                };

                if (maxScroll > 100) {
                    var innerHeight = col.height(),
                        inner = $('<div>').append(col.children());

                    col.html('').append(inner).css({
                        height: innerHeight + 'px',
                        position: 'relative'
                    });

                    inner.css({
                        width: colWidth + 'px',
                        position: 'absolute',
                        top: 0,
                        left: 0
                    });

                    var fixTop, fixLeft;
                    function balance_init() {
                        if (pinTop()) {
                            fixTop = settings.topBuffer;
                        }
                        else {
                            fixTop = $(window).height() - colHeight;
                        }
                        fixLeft = col.offset().left;
                    };

                    function balance() {
                        if (pinTop()) {
                            var raw_scroll = $(window).scrollTop() - top + settings.topBuffer;
                        }
                        else {
                            var raw_scroll = ($(window).height() + $(window).scrollTop()) - (top + colHeight);
                        }
                        var scroll = Math.max(
                            0,
                            Math.min(
                                maxScroll,
                                raw_scroll
                            )
                        );

                        if (scroll && scroll < maxScroll) {
                            inner.css({
                                position: 'fixed',
                                top: fixTop + 'px',
                                left: fixLeft - $(window).scrollLeft() + 'px'
                            });
                        }
                        else if (scroll) {
                            inner.css({
                                position: 'absolute',
                                top: maxScroll + 'px',
                                left: 0
                            });
                        }
                        else {
                            inner.css({
                                position: 'absolute',
                                top: 0,
                                left: 0
                            });

                        }
                    };

                    balance_init();
                    balance();
                    $(window).scroll(balance);
                    $(window).resize(function() {
                        balance_init();
                        balance();
                    });
                }
            });

        });
    });

})(jQuery);<commit_msg>Fix for columns with left border or padding<commit_after>/*

Example usage:

$('.scrollwrap').scrollbalance({
    childSelector: '.mycolumn'
});

*/
(function($) {

    $.fn.scrollbalance = (function(options){
        var settings = $.extend({
            childSelector: '.scrollbox',
            topBuffer: 0
        }, options);

        this.each(function() {
            var container = $(this),
                top = container.offset().top;

            // make sure container has height
            container.find(settings.childSelector).each(function() {
                if (container.height() < $(this).outerHeight(true)) {
                    container.css('height', $(this).outerHeight(true) + 'px');
                }
            });

            container.find(settings.childSelector).each(function() {
                var col = $(this),
                    colHeight = col.outerHeight(true),
                    colWidth = col.width(),
                    maxScroll = container.height() - colHeight;

                function pinTop() {
                    return (colHeight < $(window).height());
                };

                if (maxScroll > 100) {
                    var innerHeight = col.height(),
                        inner = $('<div>').append(col.children());

                    col.html('').append(inner).css({
                        height: innerHeight + 'px',
                        position: 'relative'
                    });

                    inner.css({
                        width: colWidth + 'px',
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        paddingLeft: col.css('paddingLeft')
                    });

                    var fixTop, fixLeft;
                    function balance_init() {
                        if (pinTop()) {
                            fixTop = settings.topBuffer;
                        }
                        else {
                            fixTop = $(window).height() - colHeight;
                        }
                        fixLeft = col.offset().left + parseInt(col.css('borderLeftWidth'));
                    };

                    function balance() {
                        if (pinTop()) {
                            var raw_scroll = $(window).scrollTop() - top + settings.topBuffer;
                        }
                        else {
                            var raw_scroll = ($(window).height() + $(window).scrollTop()) - (top + colHeight);
                        }
                        var scroll = Math.max(
                            0,
                            Math.min(
                                maxScroll,
                                raw_scroll
                            )
                        );

                        if (scroll && scroll < maxScroll) {
                            inner.css({
                                position: 'fixed',
                                top: fixTop + 'px',
                                left: fixLeft - $(window).scrollLeft() + 'px'
                            });
                        }
                        else if (scroll) {
                            inner.css({
                                position: 'absolute',
                                top: maxScroll + 'px',
                                left: 0
                            });
                        }
                        else {
                            inner.css({
                                position: 'absolute',
                                top: 0,
                                left: 0
                            });

                        }
                    };

                    balance_init();
                    balance();
                    $(window).scroll(balance);
                    $(window).resize(function() {
                        balance_init();
                        balance();
                    });
                }
            });

        });
    });

})(jQuery);<|endoftext|>


<commit_before>describe('Showdown', function () {
  var expect = window.expect,
    showdownProvider,
    markdown = '# Title',
    parsedHtml = '
Title
';

  beforeEach(function () {

    module('ng-showdown', function ($showdownProvider) {
      showdownProvider = $showdownProvider;
    });

  });

  describe('markdownToHtml directive', function () {
    var scope,
      compile,
      element,
      validTemplate = '

';

    beforeEach(function () {
      // Inject in angular constructs otherwise,
      //  you would need to inject these into each test
      inject(function ($rootScope, $compile) {
        scope = $rootScope.$new();
        compile = $compile;
      });
    });

    // JavaScript
    it('should have expected isolated scope', function () {
      element = createDirective(markdown);
      var isolated = element.isolateScope();
      expect(isolated.model).to.be.equal(markdown);
    });

    it('should parse markdown', function () {
      element = createDirective(markdown);
      expect(element.html()).to.be.equal(parsedHtml);
    });

    function createDirective(data, template) {
      var elm;

      // Setup scope state
      scope.someData = data;

      // Create directive
      elm = compile(template || validTemplate)(scope);

      // Trigger watchers
      scope.$apply();

      // Return
      return elm;
    }
  });

  describe('Showdown Provider', function () {

    it('should set showdown config variables', function () {
      showdownProvider.setOption('foo', 'bar');
      expect(showdownProvider.getOption('foo')).to.be.equal('bar');
    });

    it('should strip html', function () {
      expect(showdownProvider.$get().stripHtml('
Foo bar
')).to.be.equal('Foo bar');
    });

    it('should parse markdown', function () {
      expect(showdownProvider.$get().makeHtml(markdown)).to.be.equal(parsedHtml);
    });

  });

  describe('strip filter', function () {
    var stripHtmlFilter;

    beforeEach(function () {
      inject(function ($filter) {
        stripHtmlFilter = $filter('stripHtml');
      });
    });

    it('should exist', function () {
      expect(!!stripHtmlFilter).to.be.equal(true);
    });

    //Not testing full functionality here, the showdown provider gets those tests
    it('should strip html', function () {
      expect(stripHtmlFilter('
Foo bar
')).to.be.equal('Foo bar');
    });

  });

});
<commit_msg>test(directive): update test to work for directive change<commit_after>describe('Showdown', function () {
  var expect = window.expect,
    showdownProvider,
    markdown = '# Title',
    parsedHtml = '
Title
';

  beforeEach(function () {

    module('ng-showdown', function ($showdownProvider) {
      showdownProvider = $showdownProvider;
    });

  });

  describe('markdownToHtml directive', function () {
    var scope,
      compile,
      element,
      validTemplate = '

';

    beforeEach(function () {
      // Inject in angular constructs otherwise,
      //  you would need to inject these into each test
      inject(function ($rootScope, $compile) {
        scope = $rootScope.$new();
        compile = $compile;
      });
    });

    // JavaScript
    it('should have expected isolated scope', function () {
      element = createDirective(markdown);
      var isolated = element.isolateScope();
      expect(isolated.model).to.be.equal(markdown);
    });

    it('should parse markdown', function () {
      element = createDirective(markdown);
      expect(element.html()).to.be.equal('
' + parsedHtml + '
');
    });

    function createDirective(data, template) {
      var elm;

      // Setup scope state
      scope.someData = data;

      // Create directive
      elm = compile(template || validTemplate)(scope);

      // Trigger watchers
      scope.$apply();

      // Return
      return elm;
    }
  });

  describe('Showdown Provider', function () {

    it('should set showdown config variables', function () {
      showdownProvider.setOption('foo', 'bar');
      expect(showdownProvider.getOption('foo')).to.be.equal('bar');
    });

    it('should strip html', function () {
      expect(showdownProvider.$get().stripHtml('
Foo bar
')).to.be.equal('Foo bar');
    });

    it('should parse markdown', function () {
      expect(showdownProvider.$get().makeHtml(markdown)).to.be.equal(parsedHtml);
    });

  });

  describe('strip filter', function () {
    var stripHtmlFilter;

    beforeEach(function () {
      inject(function ($filter) {
        stripHtmlFilter = $filter('stripHtml');
      });
    });

    it('should exist', function () {
      expect(!!stripHtmlFilter).to.be.equal(true);
    });

    //Not testing full functionality here, the showdown provider gets those tests
    it('should strip html', function () {
      expect(stripHtmlFilter('
Foo bar
')).to.be.equal('Foo bar');
    });

  });

});
<|endoftext|>


<commit_before>// Reducers.

// Rolls a dataset by word, returning
// { word: String, count: Integer }
// as a map. This is used in conjunction with wordCounts.
function countByWord(a, x) {

    if(x.word in a) {
        a[x.word] += x.count;
    } else {
        a[x.word] = x.count;
    }

    return a;
}// Close countByWord.

// Rolls up the dataset by time, returning
// [ { time: Date object, count: Integer, ... } ]
//
// It also converts the date strings (ISO) into Date objects.
function countByTime(a, x) {

    if(a[a.length-1].time.getTime() === x.time.getTime()) {
        a[a.length-1].count += x.count;
    } else {
        a.push({count: x.count, time: x.time});
    }

    return a;
}// Close countByTime

//Counts words, returning as an array of objects.
// Takes a dataset [ { word: String, count: Integer, ...} ]
// and rolls into
// [ { word: String, count: Integer } ], marginalizing other dimensions.
function wordCounts(d) {

    var c = [];
    var countDict = d.reduce(countByWord, {});

    for(var w in countDict) {
        c.push({'word': w, 'count': countDict[w]});
    }

    return c;
}// Close wordCounts.

// Filters all entries matching a specific subject.
// data looks like [ { subject: String , .... } ]
function filterSubject(c, d) {

    return d.filter(function(x) { return x.subject === c; });
}

// Filters all entries matching a specific word.
// data looks like [ { word: String, ... } ]
function filterWord(w, d) {

    return d.filter(function(x) { return x.word === w; });
}

// Returns the width of the specified div.
function elementWidth(divId) {
    return parseInt(window.getComputedStyle(document.getElementById(divId))
                          .width) - 5;
}// Close elementHeight.

// D3 functions.
// data: [{'subject'   : subject,
//         'word'      : word,
//         'time'      : time,
//         'count'     : count }]

// TODO: Fill the actual debate times on the sparklines?
function sparkline(d3, id, data, start, stop, width, height, gradient) {

    var dataByTime = data.slice(1).reduce(countByTime,
        [
            {
                time: data[0].time,
                count: data[0].count
            }]);

    var dataInDebate = dataByTime.filter(
        function(x) { return (x.time >= start && x.time <= stop); });

    // Offsets for endpoints.
    var widthOffset = 20;
    var heightOffset = 16;

    // Perform the initial selection.
    var svg = d3.select("#"+id).append("svg")
                           .attr("id", id + "-svg")
                           .attr("height", height)
                           .attr("width", width);

    // Create the scales.
    var xScale = d3.time.scale()
                        .range([widthOffset, width - widthOffset])
                        .domain(d3.extent(dataByTime,
                                          function(d) { return d.time; }));

    var yScale = d3.scale.linear()
                          .range([height - heightOffset, heightOffset])
                          .domain(d3.extent(dataByTime,
                                            function(d) { return d.count; }));

    // Create the line function.
    var line = d3.svg.line()
                     .x(function(d) { return xScale(d.time); })
                     .y(function(d) { return yScale(d.count); })
                     .interpolate("linear");

    // Create the time axis.
    var xAxis = d3.svg.axis()
                .scale(xScale)
                .orient('bottom')
                .ticks(d3.time.hour)
                .tickFormat(d3.time.format("%_I %p"))
                .tickSize(0);

    // Grab the max counts.
    var maxCount = d3.max(dataByTime, function(d) { return d.count; });

    // Create the color gradient.
    svg.append("linearGradient")
       .attr("id", id + "-svg-count-gradient")
       .attr("gradientUnits", "userSpaceOnUse")
       .attr("x1", xScale(0)).attr("y1", yScale(0.10*maxCount))
       .attr("x2", xScale(0)).attr("y2", yScale(0.90*maxCount))
       .selectAll("stop")
       .data(gradient)
       .enter()
       .append('stop')
       .attr("offset", function(d) { return d.offset; })
       .attr("stop-color", function(d) { return d.color; });

    // Add the line to the svg.
    svg.append("path")
       .data([dataByTime])
       .attr("id", id + "-line")
       .attr("class", "line")
       .attr("d", line)
       .attr("stroke-width", 2.5)
       .attr("fill", "none")
       .attr("stroke", "url(#"+id+"-svg-count-gradient)");

    // Add the end points to the svg.
    svg.selectAll("circle")
       .attr("class", "end-points")
       .data([dataByTime[0], dataByTime[dataByTime.length-1]])
       .enter()
       .append("circle")
       .attr("r", 5)
       .attr("cx", function(d) { return xScale(d.time); })
       .attr("cy", function(d) { return yScale(d.count); })
       .attr("fill", "url(#"+id+"-svg-count-gradient)");

    // Highlight the actual debate time.
    svg.append("line")
       .attr("x1", xScale(start))
       .attr("y1", height - heightOffset)
       .attr("x2", xScale(stop))
       .attr("y2", height - heightOffset)
       .attr("stroke", "silver")
       .attr("stroke-width", "2px");

    var area = d3.svg.area()
      .x(function(d) { return xScale(d.time); })
      .y0(height - heightOffset)
      .y1(function(d) { return yScale(d.count); });

    svg.append("path")
       .datum(dataInDebate)
       .attr("class", "area")
       .attr("d", area)
       .attr("fill", "silver")
       .attr("fill-opacity", "0.2");

    // Draw the time axis.
    svg.append("g")
       .attr("class", "time-axis")
       .attr("transform", "translate(0," + (height - heightOffset) + ")")
       .attr("font-weight", "bold")
       .call(xAxis);
} // Close sparkline.

function updateSparkline(d3, id, data, start, stop, width, height) {

    // Slice out the data by time.
    var dataByTime = data.slice(1).reduce(countByTime,
        [
            {
                time: data[0].time,
                count: data[0].count
            }]);

    var dataInDebate = dataByTime.filter(
        function(x) { return (x.time >= start && x.time <= stop); });

    // Offsets for endpoints.
    var widthOffset = 20;
    var heightOffset = 16;

    // Redraw the y-scale.
    var yScale = d3.scale.linear()
                          .range([height - heightOffset, heightOffset])
                          .domain(d3.extent(dataByTime,
                                            function(d) { return d.count; }));
    var xScale = d3.time.scale()
                        .range([widthOffset, width - widthOffset])
                        .domain(d3.extent(dataByTime,
                                          function(d) { return d.time; }));
    // Create the line new line function.
    var line = d3.svg.line()
                     .x(function(d) { return xScale(d.time); })
                     .y(function(d) { return yScale(d.count); })
                     .interpolate("linear");

    var svg = d3.select("#"+id+"-svg");
    var transitionTime = 500;

    // Update the line for the svg.
    svg.selectAll("path")
      .data([dataByTime])
      .transition()
      .duration(transitionTime)
      .attr("d", line);

    // Update the end points to the svg.
    svg.selectAll("circle")
      .data([dataByTime[0], dataByTime[dataByTime.length-1]])
      .transition()
      .duration(transitionTime)
      .attr("cy", function(d) {return yScale(d.count);})
      .attr("fill", "url(#"+id+"-svg-count-gradient)");

    // Update the area.
    var area = d3.svg.area()
      .x(function(d) { return xScale(d.time); })
      .y0(height - heightOffset)
      .y1(function(d) { return yScale(d.count); });

    svg.select(".area")
      .datum(dataInDebate)
      .transition()
      .duration(transitionTime)
      .attr("d", area);
} // Close updateSparkline.

function hbar(d3, id, data, start, stop, width, height, maxVal, color) {

    var countData = wordCounts(data);

    // Create the svg group.
    var svg = d3.select("#"+id)
                .append("svg")
                .attr("id", id + "-svg")
                .attr("width", width)
                .attr("height", height)
                .append("g")
                .attr("transform", "translate(" + -60 + ",0)")
                .attr("font-weight", "bold");

    // Create the x and y scales.

    // We need to anchor left, so the highest values need to
    // map to the smallest width so when we subtract the scale
    // value we get the remaining space to draw.
    // This is because SVG rect's draw from the top left.
    var xScale = d3.scale.linear()
                         .range([width, 60 + 5])
                         .domain([0, maxVal]);

    var yScale = d3.scale.ordinal()
                         .rangeRoundBands([0, height], 0.35)
                         .domain(data.map( function(d) { return d.word; }));

    // Draw the axis.
    var yAxis = d3.svg.axis().scale(yScale).orient("right");

    // Draw the bars.
    var bars = svg.selectAll(".bar")
       .data(countData)
       .enter()

    // Define some parameters before building out.
    var transitionTime = 500; // Transition duration.
    // Define a threshold for which we put the count *outside* the bar.
    var lowerWidthThreshold = 0.25;
    bars.append("rect")
       .attr("class","bar")
       .attr("x", function(d) { return xScale(d.count); })
       .attr("width", function(d) { return width - xScale(d.count); })
       .attr("y", function(d) { return yScale(d.word); })
       .attr("height", function(d) { return yScale.rangeBand(); })
       .attr("stroke", "black")
       .attr("stroke-width", "1.0px")
       .attr("fill", color.base)
       .on("mouseover", function(d) {
            updateSparkline(d3, id.replace("barchart", "sparkline"),
                filterWord(d.word, data), start, stop, width, height);
            updateBarChart(d3.select(this), color.hover);
            d3.selectAll("."+id+"-svg-text")
              .transition()
              .duration(transitionTime)
              .attr("fill-opacity","1")
              .attr("stroke-opacity","1");
            })
       .on("mouseout", function(d) {
            updateSparkline(d3, id.replace("barchart", "sparkline"), data,
                start, stop, width, height);
            updateBarChart(d3.select(this), color.base);
            d3.selectAll("."+id+"-svg-text")
              .transition()
              .duration(transitionTime)
              .attr("fill-opacity", "0")
              .attr("stroke-opacity", "0");
            });

    bars.append("text")
        .attr("class",id + "-svg-text noselect")
        .attr("x",
            function(d) { return ((d.count/maxVal) >= lowerWidthThreshold) ?
                                 xScale(d.count) + 5 : xScale(d.count) - 5; })
        .attr("y",
            function(d) { return yScale(d.word) + yScale.rangeBand()/1.35; })
        .text(function(d) { return d.count.toLocaleString(); })
        .attr("letter-spacing", "1")
        .attr("fill",
            function(d) {
                return ((d.count/maxVal) >= lowerWidthThreshold) ?
                        "white": "black";})
        .attr("stroke","black")
        .attr("stroke-width", "0.5")
        .attr("text-anchor",
            function(d) {
                return ((d.count/maxVal) >= lowerWidthThreshold) ?
                        "start": "end"; })
        .attr("fill-opacity","0")
        .attr("stroke-opacity", "0");

    // Draw the axis.
    svg.append("g")
       .attr("class", "y-axis")
       .attr("transform","translate(" + (width-5) + ",0)")
       .call(yAxis)
       .select("path")
       .attr('fill','none')
       .attr('stroke', 'none');
}// Close hbar.

function updateBarChart(selection, color, count) {
    selection
      .transition()
      .duration(500)
      .attr("fill", color);

}// Close updateBarChart.

// Constants.

// Height of the plots.
var plotHeight = 229;

function getMaxValue(data) {
    // All counts per subject, word.
    var allCounts = data.reduce(function(a, x) {
        if(x.subject in a) {
            if(x.word in a[x.subject]) {
                a[x.subject][x.word] += x.count;
            } else {
                a[x.subject][x.word] = x.count;
            }
        } else {
            a[x.subject] = {};
            a[x.subject][x.word] = x.count;
        }
        return a;
    }, {});

    // Maximum word, subject combination.
    var maxValue =
        Object.keys(allCounts)
              .reduce(function(a, x) {
                  return Math.max(a, Object.keys(allCounts[x]).reduce(
                      function(a2, x2) {
                        return Math.max(a2, allCounts[x][x2]); }, 0))}, 0);

    return maxValue;
}// Close getMaxValue.

// Generates the callback for the d3.tsv function based on the contents of
// subjects.
function tsvCallback(subjects, start, stop) {

    var cb = function(data) {

        var cleanedData = data.map(function(x) {
            // Convert date type and truncate to minute.
            var newTime = new Date(x.time);
            newTime.setSeconds(0);
            newTime.setMilliseconds(0);

            // Convert count to integer.
            return {
                subject: x.subject,
                word: x.word,
                time: newTime,
                count: parseInt(x.count)
            };
        });

        var maxValue = getMaxValue(cleanedData);
        var startTime = new Date(start);
        var stopTime = new Date(stop);

        // For each subject, draw the sparkline and barchart.
        subjects.forEach(
            function(x) {
                sparkline(d3,
                          x.id + "-sparkline",
                          filterSubject(x.name, cleanedData),
                          startTime.getTime(), stopTime.getTime(),
                          elementWidth(x.id + "-sparkline"),
                          plotHeight,
                          x.colors.sparkline);
                hbar(d3,
                     x.id + "-barchart",
                     filterSubject(x.name, cleanedData),
                     startTime.getTime(), stopTime.getTime(),
                     elementWidth(x.id + "-barchart"),
                     plotHeight,
                     maxValue,
                     x.colors.barchart);
            });
    };

    return cb;
} // Close tsvCallback.
<commit_msg>Fixed overlap issue stemming from the length of the word 'douche'.<commit_after>// Reducers.

// Rolls a dataset by word, returning
// { word: String, count: Integer }
// as a map. This is used in conjunction with wordCounts.
function countByWord(a, x) {

    if(x.word in a) {
        a[x.word] += x.count;
    } else {
        a[x.word] = x.count;
    }

    return a;
}// Close countByWord.

// Rolls up the dataset by time, returning
// [ { time: Date object, count: Integer, ... } ]
//
// It also converts the date strings (ISO) into Date objects.
function countByTime(a, x) {

    if(a[a.length-1].time.getTime() === x.time.getTime()) {
        a[a.length-1].count += x.count;
    } else {
        a.push({count: x.count, time: x.time});
    }

    return a;
}// Close countByTime

//Counts words, returning as an array of objects.
// Takes a dataset [ { word: String, count: Integer, ...} ]
// and rolls into
// [ { word: String, count: Integer } ], marginalizing other dimensions.
function wordCounts(d) {

    var c = [];
    var countDict = d.reduce(countByWord, {});

    for(var w in countDict) {
        c.push({'word': w, 'count': countDict[w]});
    }

    return c;
}// Close wordCounts.

// Filters all entries matching a specific subject.
// data looks like [ { subject: String , .... } ]
function filterSubject(c, d) {

    return d.filter(function(x) { return x.subject === c; });
}

// Filters all entries matching a specific word.
// data looks like [ { word: String, ... } ]
function filterWord(w, d) {

    return d.filter(function(x) { return x.word === w; });
}

// Returns the width of the specified div.
function elementWidth(divId) {
    return parseInt(window.getComputedStyle(document.getElementById(divId))
                          .width) - 5;
}// Close elementHeight.

// D3 functions.
// data: [{'subject'   : subject,
//         'word'      : word,
//         'time'      : time,
//         'count'     : count }]

function sparkline(d3, id, data, start, stop, width, height, gradient) {

    var dataByTime = data.slice(1).reduce(countByTime,
        [
            {
                time: data[0].time,
                count: data[0].count
            }]);

    var dataInDebate = dataByTime.filter(
        function(x) { return (x.time >= start && x.time <= stop); });

    // Offsets for endpoints.
    var widthOffset = 20;
    var heightOffset = 16;

    // Perform the initial selection.
    var svg = d3.select("#"+id).append("svg")
                           .attr("id", id + "-svg")
                           .attr("height", height)
                           .attr("width", width);

    // Create the scales.
    var xScale = d3.time.scale()
                        .range([widthOffset, width - widthOffset])
                        .domain(d3.extent(dataByTime,
                                          function(d) { return d.time; }));

    var yScale = d3.scale.linear()
                          .range([height - heightOffset, heightOffset])
                          .domain(d3.extent(dataByTime,
                                            function(d) { return d.count; }));

    // Create the line function.
    var line = d3.svg.line()
                     .x(function(d) { return xScale(d.time); })
                     .y(function(d) { return yScale(d.count); })
                     .interpolate("linear");

    // Create the time axis.
    var xAxis = d3.svg.axis()
                .scale(xScale)
                .orient('bottom')
                .ticks(d3.time.hour)
                .tickFormat(d3.time.format("%_I %p"))
                .tickSize(0);

    // Grab the max counts.
    var maxCount = d3.max(dataByTime, function(d) { return d.count; });

    // Create the color gradient.
    svg.append("linearGradient")
       .attr("id", id + "-svg-count-gradient")
       .attr("gradientUnits", "userSpaceOnUse")
       .attr("x1", xScale(0)).attr("y1", yScale(0.10*maxCount))
       .attr("x2", xScale(0)).attr("y2", yScale(0.90*maxCount))
       .selectAll("stop")
       .data(gradient)
       .enter()
       .append('stop')
       .attr("offset", function(d) { return d.offset; })
       .attr("stop-color", function(d) { return d.color; });

    // Add the line to the svg.
    svg.append("path")
       .data([dataByTime])
       .attr("id", id + "-line")
       .attr("class", "line")
       .attr("d", line)
       .attr("stroke-width", 2.5)
       .attr("fill", "none")
       .attr("stroke", "url(#"+id+"-svg-count-gradient)");

    // Add the end points to the svg.
    svg.selectAll("circle")
       .attr("class", "end-points")
       .data([dataByTime[0], dataByTime[dataByTime.length-1]])
       .enter()
       .append("circle")
       .attr("r", 5)
       .attr("cx", function(d) { return xScale(d.time); })
       .attr("cy", function(d) { return yScale(d.count); })
       .attr("fill", "url(#"+id+"-svg-count-gradient)");

    // Highlight the actual debate time.
    svg.append("line")
       .attr("x1", xScale(start))
       .attr("y1", height - heightOffset)
       .attr("x2", xScale(stop))
       .attr("y2", height - heightOffset)
       .attr("stroke", "silver")
       .attr("stroke-width", "2px");

    var area = d3.svg.area()
      .x(function(d) { return xScale(d.time); })
      .y0(height - heightOffset)
      .y1(function(d) { return yScale(d.count); });

    svg.append("path")
       .datum(dataInDebate)
       .attr("class", "area")
       .attr("d", area)
       .attr("fill", "silver")
       .attr("fill-opacity", "0.2");

    // Draw the time axis.
    svg.append("g")
       .attr("class", "time-axis")
       .attr("transform", "translate(0," + (height - heightOffset) + ")")
       .attr("font-weight", "bold")
       .call(xAxis);
} // Close sparkline.

function updateSparkline(d3, id, data, start, stop, width, height) {

    // Slice out the data by time.
    var dataByTime = data.slice(1).reduce(countByTime,
        [
            {
                time: data[0].time,
                count: data[0].count
            }]);

    var dataInDebate = dataByTime.filter(
        function(x) { return (x.time >= start && x.time <= stop); });

    // Offsets for endpoints.
    var widthOffset = 20;
    var heightOffset = 16;

    // Redraw the y-scale.
    var yScale = d3.scale.linear()
                          .range([height - heightOffset, heightOffset])
                          .domain(d3.extent(dataByTime,
                                            function(d) { return d.count; }));
    var xScale = d3.time.scale()
                        .range([widthOffset, width - widthOffset])
                        .domain(d3.extent(dataByTime,
                                          function(d) { return d.time; }));
    // Create the line new line function.
    var line = d3.svg.line()
                     .x(function(d) { return xScale(d.time); })
                     .y(function(d) { return yScale(d.count); })
                     .interpolate("linear");

    var svg = d3.select("#"+id+"-svg");
    var transitionTime = 500;

    // Update the line for the svg.
    svg.selectAll("path")
      .data([dataByTime])
      .transition()
      .duration(transitionTime)
      .attr("d", line);

    // Update the end points to the svg.
    svg.selectAll("circle")
      .data([dataByTime[0], dataByTime[dataByTime.length-1]])
      .transition()
      .duration(transitionTime)
      .attr("cy", function(d) {return yScale(d.count);})
      .attr("fill", "url(#"+id+"-svg-count-gradient)");

    // Update the area.
    var area = d3.svg.area()
      .x(function(d) { return xScale(d.time); })
      .y0(height - heightOffset)
      .y1(function(d) { return yScale(d.count); });

    svg.select(".area")
      .datum(dataInDebate)
      .transition()
      .duration(transitionTime)
      .attr("d", area);
} // Close updateSparkline.

function hbar(d3, id, data, start, stop, width, height, maxVal, color) {

    var countData = wordCounts(data);

    // Create the svg group.
    var svg = d3.select("#"+id)
                .append("svg")
                .attr("id", id + "-svg")
                .attr("width", width)
                .attr("height", height)
                .append("g")
                .attr("transform", "translate(" + -60 + ",0)")
                .attr("font-weight", "bold");

    // Create the x and y scales.

    // We need to anchor left, so the highest values need to
    // map to the smallest width so when we subtract the scale
    // value we get the remaining space to draw.
    // This is because SVG rect's draw from the top left.
    var xScale = d3.scale.linear()
                         .range([width, 60 + 5])
                         .domain([0, maxVal]);

    var yScale = d3.scale.ordinal()
                         .rangeRoundBands([0, height], 0.35)
                         .domain(data.map( function(d) { return d.word; }));

    // Draw the axis.
    var yAxis = d3.svg.axis().scale(yScale).orient("right");

    // Draw the bars.
    var bars = svg.selectAll(".bar")
       .data(countData)
       .enter()

    // Define some parameters before building out.
    var transitionTime = 500; // Transition duration.
    // Define a threshold for which we put the count *outside* the bar.
    var lowerWidthThreshold = 0.25;
    bars.append("rect")
       .attr("class","bar")
       .attr("x", function(d) { return xScale(d.count) - 5; }) // -5 for douche.
       .attr("width", function(d) { return width - xScale(d.count); })
       .attr("y", function(d) { return yScale(d.word); })
       .attr("height", function(d) { return yScale.rangeBand(); })
       .attr("stroke", "black")
       .attr("stroke-width", "1.0px")
       .attr("fill", color.base)
       .on("mouseover", function(d) {
            updateSparkline(d3, id.replace("barchart", "sparkline"),
                filterWord(d.word, data), start, stop, width, height);
            updateBarChart(d3.select(this), color.hover);
            d3.selectAll("."+id+"-svg-text")
              .transition()
              .duration(transitionTime)
              .attr("fill-opacity","1")
              .attr("stroke-opacity","1");
            })
       .on("mouseout", function(d) {
            updateSparkline(d3, id.replace("barchart", "sparkline"), data,
                start, stop, width, height);
            updateBarChart(d3.select(this), color.base);
            d3.selectAll("."+id+"-svg-text")
              .transition()
              .duration(transitionTime)
              .attr("fill-opacity", "0")
              .attr("stroke-opacity", "0");
            });

    bars.append("text")
        .attr("class",id + "-svg-text noselect")
        .attr("x",
            function(d) { return ((d.count/maxVal) >= lowerWidthThreshold) ?
                                 xScale(d.count) + 5 : xScale(d.count) - 10; })
        .attr("y",
            function(d) { return yScale(d.word) + yScale.rangeBand()/1.35; })
        .text(function(d) { return d.count.toLocaleString(); })
        .attr("letter-spacing", "1")
        .attr("fill",
            function(d) {
                return ((d.count/maxVal) >= lowerWidthThreshold) ?
                        "white": "black";})
        .attr("stroke","black")
        .attr("stroke-width", "0.5")
        .attr("text-anchor",
            function(d) {
                return ((d.count/maxVal) >= lowerWidthThreshold) ?
                        "start": "end"; })
        .attr("fill-opacity","0")
        .attr("stroke-opacity", "0");

    // Draw the axis.
    svg.append("g")
       .attr("class", "y-axis")
       .attr("transform","translate(" + (width-10) + ",0)")
       .call(yAxis)
       .select("path")
       .attr('fill','none')
       .attr('stroke', 'none');
}// Close hbar.

function updateBarChart(selection, color, count) {
    selection
      .transition()
      .duration(500)
      .attr("fill", color);

}// Close updateBarChart.

// Constants.

// Height of the plots.
var plotHeight = 229;

function getMaxValue(data) {
    // All counts per subject, word.
    var allCounts = data.reduce(function(a, x) {
        if(x.subject in a) {
            if(x.word in a[x.subject]) {
                a[x.subject][x.word] += x.count;
            } else {
                a[x.subject][x.word] = x.count;
            }
        } else {
            a[x.subject] = {};
            a[x.subject][x.word] = x.count;
        }
        return a;
    }, {});

    // Maximum word, subject combination.
    var maxValue =
        Object.keys(allCounts)
              .reduce(function(a, x) {
                  return Math.max(a, Object.keys(allCounts[x]).reduce(
                      function(a2, x2) {
                        return Math.max(a2, allCounts[x][x2]); }, 0))}, 0);

    return maxValue;
}// Close getMaxValue.

// Generates the callback for the d3.tsv function based on the contents of
// subjects.
function tsvCallback(subjects, start, stop) {

    var cb = function(data) {

        var cleanedData = data.map(function(x) {
            // Convert date type and truncate to minute.
            var newTime = new Date(x.time);
            newTime.setSeconds(0);
            newTime.setMilliseconds(0);

            // Convert count to integer.
            return {
                subject: x.subject,
                word: x.word,
                time: newTime,
                count: parseInt(x.count)
            };
        });

        var maxValue = getMaxValue(cleanedData);
        var startTime = new Date(start);
        var stopTime = new Date(stop);

        // For each subject, draw the sparkline and barchart.
        subjects.forEach(
            function(x) {
                sparkline(d3,
                          x.id + "-sparkline",
                          filterSubject(x.name, cleanedData),
                          startTime.getTime(), stopTime.getTime(),
                          elementWidth(x.id + "-sparkline"),
                          plotHeight,
                          x.colors.sparkline);
                hbar(d3,
                     x.id + "-barchart",
                     filterSubject(x.name, cleanedData),
                     startTime.getTime(), stopTime.getTime(),
                     elementWidth(x.id + "-barchart"),
                     plotHeight,
                     maxValue,
                     x.colors.barchart);
            });
    };

    return cb;
} // Close tsvCallback.
<|endoftext|>


<commit_before>/*
 * jquery.submitOnEnter v1.0.1
 *
 * Copyright (c) 2012 Thibaut Courouble
 * http://thibaut.me
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 */

(function($) {
  'use strict';

  function submitOnEnter(event) {
    if (event.which === 13 && !event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
      event.preventDefault();
      event.stopPropagation();

      (event.delegateTarget.nodeName === 'FORM' ?
        $(event.delegateTarget) :
        (event.currentTarget.nodeName === 'FORM') ?
          $(event.currentTarget) :
          $(event.currentTarget).closest('form')
      ).not(':has(input[type=submit]:disabled)')
       .not(':has(button[type=submit]:disabled)')
       .submit();
    }
  }

  $.fn.submitOnEnter = function(selector) {
    return this.off('.submitOnEnter').on('keydown.submitOnEnter', selector, submitOnEnter);
  };
})(jQuery);
<commit_msg>Use keypress instead of keydown<commit_after>/*
 * jquery.submitOnEnter v1.0.1
 *
 * Copyright (c) 2012 Thibaut Courouble
 * http://thibaut.me
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 */

(function($) {
  'use strict';

  function submitOnEnter(event) {
    if (event.which === 13 && !event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
      event.preventDefault();
      event.stopPropagation();

      (event.delegateTarget.nodeName === 'FORM' ?
        $(event.delegateTarget) :
        (event.currentTarget.nodeName === 'FORM') ?
          $(event.currentTarget) :
          $(event.currentTarget).closest('form')
      ).not(':has(input[type=submit]:disabled)')
       .not(':has(button[type=submit]:disabled)')
       .submit();
    }
  }

  $.fn.submitOnEnter = function(selector) {
    return this.off('.submitOnEnter').on('keypress.submitOnEnter', selector, submitOnEnter);
  };
})(jQuery);
<|endoftext|>


<commit_before>/* global define, require, console, document: false */
'use strict';

define('snap-win', ['snap-svg'], function(snap) {
  window.Snap = snap;
});

define('camunda-tasklist-ui', [
  'camunda-tasklist-ui/require-conf',
  'snap-win'
], function(
  rjsConf
) {
  /**
   * @namespace cam
   */

  /**
   * @module cam.tasklist
   */

  var tasklistApp;

  var appModules = rjsConf.shim['camunda-tasklist-ui'];

  var deps = [
    'angular',
    'text!camunda-tasklist-ui/index.html'
  ].concat(appModules);

  // converts AMD paths to angular module names
  // "camunda-tasklist-ui/filter" will be "cam.tasklist.filter"
  function rj2ngNames(names) {
    var name, translated = [];
    for (var n = 0; n < names.length; n++) {
      if(names[n].indexOf("!") !== -1) continue;
      name = (require(names[n]) || {}).name;
      if (name) translated.push(name);
    }
    return translated;
  }

  function loaded() {
    var angular = require('angular');
    var $ = angular.element;

    function parseUriConfig() {
      var $baseTag = angular.element('base');
      var config = {};
      var names = ['href', 'app-root', 'admin-api', 'engine-api'];
      for(var i = 0; i < names.length; i++) {
        config[names[i]] = $baseTag.attr(names[i]);
      }
      return config;
    }

    var ngDeps = rj2ngNames(appModules).concat([
      'pascalprecht.translate',
      'ngRoute',
      'dataDepend'
    ]);

    var uriConfig = parseUriConfig();

    tasklistApp = angular.module('cam.tasklist', ngDeps);

    var notificationsPanel = require('camunda-commons-ui/directives/notificationsPanel');
    tasklistApp.directive('notificationsPanel', notificationsPanel);

    var engineSelect = require('camunda-commons-ui/directives/engineSelect');
    tasklistApp.directive('engineSelect', engineSelect);

    var autoFill = require('camunda-commons-ui/directives/autoFill');
    tasklistApp.directive('autoFill', autoFill);

    var nl2br = require('camunda-commons-ui/directives/nl2br');
    tasklistApp.directive('nl2br', nl2br);

    var compileTemplate = require('camunda-commons-ui/directives/compileTemplate');
    tasklistApp.directive('compileTemplate', compileTemplate);

    tasklistApp.factory('assignNotification', require('camunda-tasklist-ui/services/cam-tasklist-assign-notification'));
    tasklistApp.provider('configuration', require('camunda-tasklist-ui/services/cam-tasklist-configuration'));

    require('camunda-tasklist-ui/config/locales')(tasklistApp, uriConfig['app-root']);
    require('camunda-tasklist-ui/config/uris')(tasklistApp, uriConfig);

    //tasklistApp.config(require('camunda-tasklist-ui/config/uris'));
    tasklistApp.config(require('camunda-tasklist-ui/config/routes'));
    tasklistApp.config(require('camunda-tasklist-ui/config/date'));
    tasklistApp.config(require('camunda-tasklist-ui/config/tooltip'));

    tasklistApp.controller('camTasklistAppCtrl', require('camunda-tasklist-ui/controller/cam-tasklist-app-ctrl'));
    tasklistApp.controller('camTasklistViewCtrl', require('camunda-tasklist-ui/controller/cam-tasklist-view-ctrl'));

    $(document).ready(function() {
      angular.bootstrap(document, ['cam.tasklist', 'cam.embedded.forms']);

      setTimeout(function() {
        var $aufocused = $('[autofocus]');
        if ($aufocused.length) {
          $aufocused[0].focus();
        }
      }, 300);
    });
  }

  // configure require.js
  require.config(rjsConf);

  // and load the dependencies
  require(deps, loaded);
});
<commit_msg>feat(IE version): add a mechanism to detect IE version<commit_after>/* global define, require, console, document: false */
'use strict';

define('snap-win', ['snap-svg'], function(snap) {
  window.Snap = snap;
});

define('camunda-tasklist-ui', [
  'camunda-tasklist-ui/require-conf',
  'snap-win'
], function(
  rjsConf
) {
  /**
   * @namespace cam
   */

  /**
   * @module cam.tasklist
   */

  var tasklistApp;

  var appModules = rjsConf.shim['camunda-tasklist-ui'];

  var deps = [
    'angular',
    'text!camunda-tasklist-ui/index.html'
  ].concat(appModules);

  // converts AMD paths to angular module names
  // "camunda-tasklist-ui/filter" will be "cam.tasklist.filter"
  function rj2ngNames(names) {
    var name, translated = [];
    for (var n = 0; n < names.length; n++) {
      if(names[n].indexOf("!") !== -1) continue;
      name = (require(names[n]) || {}).name;
      if (name) translated.push(name);
    }
    return translated;
  }

  function loaded() {
    var angular = require('angular');
    var $ = angular.element;

    // Inspired by http://jsfiddle.net/evildonald/jLuF5/
    function detectIE() {
      var s = document.body.style;
      var version;

      if (s.msTextCombineHorizontal !== undefined) {
        version = 11;
      }
      else if (s.msFlexOrder !== undefined) {
        version = 10;
      }
      else if (s.msTransform !== undefined) {
        version = 9;
      }

      if (version) {
        $('html').addClass('ie ie'+version);
      }
    }

    function parseUriConfig() {
      var $baseTag = angular.element('base');
      var config = {};
      var names = ['href', 'app-root', 'admin-api', 'engine-api'];
      for(var i = 0; i < names.length; i++) {
        config[names[i]] = $baseTag.attr(names[i]);
      }
      return config;
    }

    var ngDeps = rj2ngNames(appModules).concat([
      'pascalprecht.translate',
      'ngRoute',
      'dataDepend'
    ]);

    var uriConfig = parseUriConfig();

    tasklistApp = angular.module('cam.tasklist', ngDeps);

    var notificationsPanel = require('camunda-commons-ui/directives/notificationsPanel');
    tasklistApp.directive('notificationsPanel', notificationsPanel);

    var engineSelect = require('camunda-commons-ui/directives/engineSelect');
    tasklistApp.directive('engineSelect', engineSelect);

    var autoFill = require('camunda-commons-ui/directives/autoFill');
    tasklistApp.directive('autoFill', autoFill);

    var nl2br = require('camunda-commons-ui/directives/nl2br');
    tasklistApp.directive('nl2br', nl2br);

    var compileTemplate = require('camunda-commons-ui/directives/compileTemplate');
    tasklistApp.directive('compileTemplate', compileTemplate);

    tasklistApp.factory('assignNotification', require('camunda-tasklist-ui/services/cam-tasklist-assign-notification'));
    tasklistApp.provider('configuration', require('camunda-tasklist-ui/services/cam-tasklist-configuration'));

    require('camunda-tasklist-ui/config/locales')(tasklistApp, uriConfig['app-root']);
    require('camunda-tasklist-ui/config/uris')(tasklistApp, uriConfig);

    //tasklistApp.config(require('camunda-tasklist-ui/config/uris'));
    tasklistApp.config(require('camunda-tasklist-ui/config/routes'));
    tasklistApp.config(require('camunda-tasklist-ui/config/date'));
    tasklistApp.config(require('camunda-tasklist-ui/config/tooltip'));

    tasklistApp.controller('camTasklistAppCtrl', require('camunda-tasklist-ui/controller/cam-tasklist-app-ctrl'));
    tasklistApp.controller('camTasklistViewCtrl', require('camunda-tasklist-ui/controller/cam-tasklist-view-ctrl'));

    $(document).ready(function() {
      detectIE();
      angular.bootstrap(document, ['cam.tasklist', 'cam.embedded.forms']);

      setTimeout(function() {
        var $aufocused = $('[autofocus]');
        if ($aufocused.length) {
          $aufocused[0].focus();
        }
      }, 300);
    });
  }

  // configure require.js
  require.config(rjsConf);

  // and load the dependencies
  require(deps, loaded);
});
<|endoftext|>


<commit_before>var typeOf = function(obj) {
  return typeof obj
}

var isType = function(obj, type) {
  return typeOf(obj) == type;
}

/**
 * inspectValue({a: 2, b: 3, c: 4})  //=>
 *   {type:'object', inspect:"{a: 2, b: 3, ... }"}
 *
 */

this.inspectValue = function(value) {
  var string;
  if (this.isKnownType(value)) {
    var type = this.knownType(value);
    return {
      type: "type-"+type.name,
      inspect: type.toString()
    };
  } else {
    return {
      type: "type-" + typeOf(value),
      inspect: this.inspect(value)
    };
  }
}

this.inspect = function(value) {
  var type = typeOf(value) ;
  if (this.isKnownType(value)) {
    return this.knownTypeString(value);
  } else if (type === 'undefined') {
    return "undefined";
  } else if (type === 'function') {
    return "function() { ... }";
  } else if (type === 'array') {
    if (value.length === 0) { return '[]'; }
    else if (value.length === 1) { return '[ ' + this.inspect(value[0]) + ' ]'; }
    else { return '[ ' + this.inspect(value[0]) + ', ... ]'; }
  } else if (value instanceof Error) {
    return 'Error: ' + value.message;
  } else if (value === null) {
    return 'null';
  } else if(typeOf(value) === 'date') {
    return value.toString();
  } else if(isType(value, 'string') || isType(value, 'number') || isType(value, 'boolean')) {
    return value;
  } else if (typeof value === 'object') {
    // `Ember.inspect` is able to handle this use case,
    // but it is very slow as it loops over all props,
    // so summarize to just first 2 props
    var ret = [], v, count = 0, broken = false;
    for (var key in value) {
      if (value.hasOwnProperty(key)) {
        if (count++ > 1) {
          broken = true;
          break;
        }
        v = value[key];
        if (this.isKnownType(v)) {v = this.knownTypeString(v); }
        else if (v === 'toString') { continue; } // ignore useless items
        else if (typeOf(v) === 'function') { v = "function() { ... }"; }
        else if (typeOf(v) === 'array') { v = '[Array : ' + v.length + ']'; }
        else if (typeOf(v) === 'object') { v = '[Object]'; }
        ret.push(key + ": " + v);
      }
    }
    var suffix = ' }';
    if (broken) {
      suffix = ' ...}';
    }
    return '{ ' + ret.join(', ') + suffix;
  } else {

    debug.log("serialize: couldn't find the type for ", value);
    return ''
  }
}

/*
 * serializeObject({a: 2, b:3}) // =>
 *  {
 *    a: {type: 'int', value: 2, name: 'a'},
 *    b: {type: int, value: 3, name: 'b'},
 *  }
 */

this.serializeObject = function(obj) {
  var data = {};

  _.each(obj || {}, function(value, name) {
    var inspectedObject = this.inspectValue(value);

     data[name] = {
      name: name,
      type: inspectedObject.type,
      value: inspectedObject.inspect.toString()
    }
  }, this);

  // debug.log('serialize: object ' + so);
  return data;
};

/*
 * picks out the properties that are unique to the object
 * and then calls serializeObject on them.
 *
 */

this.serializeObjectProperties = function(obj) {
  return this.serializeObject(
    _.pick(obj,
      _.difference(
        _.keys(obj),
        _.keys(obj.constructor.prototype)
      )
    )
  );
};
<commit_msg>[agent] update inspect to handle array types<commit_after>var typeOf = function(obj) {
  if (obj instanceof Array) {
    return 'array'
  }

  return typeof obj
}

var instanceOf = function(obj, Type) {
  return obj instanceof Type
}
var isType = function(obj, type) {
  return typeOf(obj) == type;
}

/**
 * inspectValue({a: 2, b: 3, c: 4})  //=>
 *   {type:'object', inspect:"{a: 2, b: 3, ... }"}
 *
 */

this.inspectValue = function(value) {
  var string;
  if (this.isKnownType(value)) {
    var type = this.knownType(value);
    return {
      type: "type-"+type.name,
      inspect: type.toString()
    };
  } else {
    return {
      type: "type-" + typeOf(value),
      inspect: this.inspect(value)
    };
  }
}

this.inspect = function(value) {
  var type = typeOf(value) ;
  if (this.isKnownType(value)) {
    return this.knownTypeString(value);
  } else if (type === 'undefined') {
    return "undefined";
  } else if (type === 'function') {
    return "function() { ... }";
  } else if (type === 'array') {
    if (value.length === 0) { return '[]'; }
    else if (value.length === 1) { return '[ ' + this.inspect(value[0]) + ' ]'; }
    else { return '[ ' + this.inspect(value[0]) + ', ... ]'; }
  } else if (value instanceof Error) {
    return 'Error: ' + value.message;
  } else if (value === null) {
    return 'null';
  } else if(typeOf(value) === 'date') {
    return value.toString();
  } else if(isType(value, 'string') || isType(value, 'number') || isType(value, 'boolean')) {
    return value;
  } else if (typeof value === 'object') {
    // `Ember.inspect` is able to handle this use case,
    // but it is very slow as it loops over all props,
    // so summarize to just first 2 props
    var ret = [], v, count = 0, broken = false;
    for (var key in value) {
      if (value.hasOwnProperty(key)) {
        if (count++ > 1) {
          broken = true;
          break;
        }
        v = value[key];
        if (this.isKnownType(v)) {v = this.knownTypeString(v); }
        else if (v === 'toString') { continue; } // ignore useless items
        else if (typeOf(v) === 'function') { v = "function() { ... }"; }
        else if (typeOf(v) === 'array') { v = '[Array : ' + v.length + ']'; }
        else if (typeOf(v) === 'object') { v = '[Object]'; }
        ret.push(key + ": " + v);
      }
    }
    var suffix = ' }';
    if (broken) {
      suffix = ' ...}';
    }
    return '{ ' + ret.join(', ') + suffix;
  } else {

    debug.log("serialize: couldn't find the type for ", value);
    return ''
  }
}

/*
 * serializeObject({a: 2, b:3}) // =>
 *  {
 *    a: {type: 'int', value: 2, name: 'a'},
 *    b: {type: int, value: 3, name: 'b'},
 *  }
 */

this.serializeObject = function(obj) {
  var data = {};

  _.each(obj || {}, function(value, name) {
    var inspectedObject = this.inspectValue(value);

     data[name] = {
      name: name,
      type: inspectedObject.type,
      value: inspectedObject.inspect.toString()
    }
  }, this);

  // debug.log('serialize: object ' + so);
  return data;
};

/*
 * picks out the properties that are unique to the object
 * and then calls serializeObject on them.
 *
 */

this.serializeObjectProperties = function(obj) {
  return this.serializeObject(
    _.pick(obj,
      _.difference(
        _.keys(obj),
        _.keys(obj.constructor.prototype)
      )
    )
  );
};
<|endoftext|>


<commit_before>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import {test} from 'tape';
import React from 'react';
import TestUtils from 'react-addons-test-utils';

import Markdown from '../../src/js/components/Markdown';
import Paragraph from '../../src/js/components/Paragraph';

test('loads a paragraph Markdown', (t) => {
  t.plan(3);
  const shallowRenderer = TestUtils.createRenderer();
  shallowRenderer.render(React.createElement(Markdown, {
    content: 'test',
    components: {
      p: {
        props: {
          className: 'testing',
          size: 'large'
        }
      }
    }
  }));
  const markdownElement = shallowRenderer.getRenderOutput();

  t.equal(markdownElement.type, Paragraph, 'Markdown uses Paragraph');
  if (markdownElement.props.className.indexOf('testing') > -1) {
    t.pass('Markdown paragraph has custom class');
  } else {
    t.fail('Markdown paragraph does not have custom class');
  }
  t.equal(markdownElement.props.size, 'large', 'Markdown paragraph is large');
});
<commit_msg>Convert Markdown-test to use enzyme.<commit_after>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import {test} from 'tape';
import React from 'react';
import { shallow } from 'enzyme';

import Markdown from '../../src/js/components/Markdown';
import Paragraph from '../../src/js/components/Paragraph';

test('loads a paragraph Markdown', (t) => {
  t.plan(3);

  const markdownElement = shallow(
    <Markdown content='test'
      components={{ p: { props: { className: 'testing', size: 'large' } } }} />
  );

  t.equal(markdownElement.find(Paragraph).length, 1);
  const props = markdownElement.find(Paragraph).props();
  if (props.className.indexOf('testing') > -1) {
    t.pass('Markdown paragraph has custom class');
  } else {
    t.fail('Markdown paragraph does not have custom class');
  }
  t.equal(props.size, 'large', 'Markdown paragraph is large');
});
<|endoftext|>


<commit_before>/*
 * waitForImages 1.1
 * -----------------
 * Provides a callback when all images have loaded in your given selector.
 * http://www.alexanderdickson.com/
 *
 *
 * Copyright (c) 2011 Alex Dickson
 * Licensed under the MIT licenses.
 * See website for more info.
 *
 */

;(function($) {
    $.fn.waitForImages = function(finishedCallback, eachCallback) {

        eachCallback = eachCallback || function() {};

        if ( ! $.isFunction(finishedCallback) ||  ! $.isFunction(eachCallback)) {
            throw {
                name: 'invalid_callback',
                message: 'A non valid callback was supplied.'
            };
        };

        var objs = $(this),
            allImgs = objs.find('img'),
            allImgsLength = allImgs.length,
            allImgsLoaded = 0;

        if (allImgsLength == 0) {
            finishedCallback.call();
        };

        return objs.each(function() {
            var obj = $(this),
                imgs = obj.find('img');

            if (imgs.length == 0) {
                return true;
            };

            imgs.each(function() {
                var image = $(this)[0];
                image.onload = function() {
                    allImgsLoaded++;
                    eachCallback.call(image, allImgsLoaded, allImgsLength);
                    if (allImgsLoaded == allImgsLength) {
                        finishedCallback.call();
                        return false;
                    };
                };
            });
        });
    };
})(jQuery);<commit_msg>Fixed stupid code :)<commit_after>/*
 * waitForImages 1.1
 * -----------------
 * Provides a callback when all images have loaded in your given selector.
 * http://www.alexanderdickson.com/
 *
 *
 * Copyright (c) 2011 Alex Dickson
 * Licensed under the MIT licenses.
 * See website for more info.
 *
 */

;(function($) {
    $.fn.waitForImages = function(finishedCallback, eachCallback) {

        eachCallback = eachCallback || function() {};

        if ( ! $.isFunction(finishedCallback) ||  ! $.isFunction(eachCallback)) {
            throw {
                name: 'invalid_callback',
                message: 'An invalid callback was supplied.'
            };
        };

        var objs = $(this),
            allImgs = objs.find('img'),
            allImgsLength = allImgs.length,
            allImgsLoaded = 0;

        if (allImgsLength == 0) {
            finishedCallback.call();
        };

        return objs.each(function() {
            var obj = $(this),
                imgs = obj.find('img');

            if (imgs.length == 0) {
                return true;
            };

            imgs.each(function() {
                var image = this;
                image.onload = function() {
                    allImgsLoaded++;
                    eachCallback.call(image, allImgsLoaded, allImgsLength);
                    if (allImgsLoaded == allImgsLength) {
                        finishedCallback.call();
                        return false;
                    };
                };
            });
        });
    };
})(jQuery);<|endoftext|>


<commit_before>import Vue from 'vue'
import Paginate from 'src/components/Paginate.vue'

describe('Paginate', () => {
  const Component = Vue.extend(Paginate)
  function initComponent() {
    return new Component({
      propsData: {
        pageCount: 10
      }
    }).$mount()
  }

  describe('Simple Cases', () => {
    it('success', () => {
      const vm = initComponent()
      expect(vm.$el.querySelector("li:first-child a").textContent).to.equal("Prev")
      expect(vm.$el.querySelector("li:last-child a").textContent).to.equal("Next")
      expect(vm.$el.querySelector(".active a").textContent).to.equal("1")
    })

    it('next and prev button event right', () => {
      const vm = initComponent()
      const nextButton = vm.$el.querySelector("li:last-child a")
      nextButton.click()

      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("2")

        const prevButton = vm.$el.querySelector("li:first-child a")
        prevButton.click()

        Vue.nextTick(() => {
          expect(vm.$el.querySelector(".active a").textContent).to.equal("1")
        })
      })
    })

    it('prev button when first page', () => {
      const vm = initComponent()
      const prevButton = vm.$el.querySelector("li:first-child a")
      prevButton.click()

      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("1")
      })
    })

    it('click page element', () => {
      const vm = initComponent()
      const pageItem = vm.$el.querySelector('li:nth-child(3) a')
      pageItem.click()
      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("2")
      })
    })

    it('set initial page success', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 1
        }
      }).$mount()
      expect(vm.$el.querySelector(".active a").textContent).to.equal("2")
    })

    it('set forcePage success', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 0,
          forcePage: 5
        }
      }).$mount()

      const nextButton = vm.$el.querySelector("li:last-child a")
      nextButton.click()
      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("6")

        const prevButton = vm.$el.querySelector("li:first-child a")
        prevButton.click()

        Vue.nextTick(() => {
          expect(vm.$el.querySelector(".active a").textContent).to.equal("6")
        })
      })
    })

    it('set forcePage in initialPage', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 5,
          forcePage: 5
        }
      }).$mount()

      expect(vm.$el.querySelector(".active a").textContent).to.equal("6")
      const nextButton = vm.$el.querySelector("li:last-child a")
      nextButton.click()
      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("6")
      })
    })
  })

  describe('page range tests', () => {
    it('page count not more than range', () => {
      const vm = new Component({
        propsData: {
          pageCount: 5,
          pageRange: 5
        }
      }).$mount()
      expect(vm.$el.querySelectorAll("li a").length).to.equal(7)
    })

    it('only has breakView in left', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 9
        }
      }).$mount()
      expect(vm.$el.querySelector(`li:nth-child(3) a`).textContent).to.equal('...')
      expect(vm.$el.querySelector(`li:nth-child(4) a`).textContent).to.equal('7')
    })
  })

  describe('enable first and last button', () => {
    it('Show fist and last button', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 1,
          firstLastButton: true
        }
      }).$mount()
      const firstButton = vm.$el.querySelector("li:first-child a")
      const lastButton = vm.$el.querySelector("li:last-child a")
      const activeItem = vm.$el.querySelector(".active a")
      expect(firstButton.textContent).to.equal("First")
      expect(lastButton.textContent).to.equal("Last")
      expect(activeItem.textContent).to.equal("2")

      firstButton.click()
      Vue.nextTick(() => {
        expect(activeItem.textContent).to.equal("1")

        lastButton.click()
        Vue.nextTick(() => {
          expect(activeItem.textContent).to.equal("10")
        })
      })
    })

    it('Show fist and last button when no li surround', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 1,
          noLiSurround: true,
          firstLastButton: true
        }
      }).$mount()
      const firstButton = vm.$el.querySelector("a:first-child")
      const lastButton = vm.$el.querySelector("a:last-child")
      const activeItem = vm.$el.querySelector("a.active")
      expect(firstButton.textContent).to.equal("First")
      expect(lastButton.textContent).to.equal("Last")
      expect(activeItem.textContent).to.equal("2")

      // firstButton.click()
      // Vue.nextTick(() => {
      //   expect(activeItem.textContent).to.equal("1")
      //
      //   lastButton.click()
      //   Vue.nextTick(() => {
      //     expect(activeItem.textContent).to.equal("10")
      //   })
      // })
    })
  })
})
<commit_msg>test: add test cases for hide prev and next button<commit_after>import Vue from 'vue'
import Paginate from 'src/components/Paginate.vue'

describe('Paginate', () => {
  const Component = Vue.extend(Paginate)
  function initComponent() {
    return new Component({
      propsData: {
        pageCount: 10
      }
    }).$mount()
  }

  describe('Simple Cases', () => {
    it('success', () => {
      const vm = initComponent()
      expect(vm.$el.querySelector("li:first-child a").textContent).to.equal("Prev")
      expect(vm.$el.querySelector("li:last-child a").textContent).to.equal("Next")
      expect(vm.$el.querySelector(".active a").textContent).to.equal("1")
    })

    it('next and prev button event right', () => {
      const vm = initComponent()
      const nextButton = vm.$el.querySelector("li:last-child a")
      nextButton.click()

      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("2")

        const prevButton = vm.$el.querySelector("li:first-child a")
        prevButton.click()

        Vue.nextTick(() => {
          expect(vm.$el.querySelector(".active a").textContent).to.equal("1")
        })
      })
    })

    it('prev button when first page', () => {
      const vm = initComponent()
      const prevButton = vm.$el.querySelector("li:first-child a")
      prevButton.click()

      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("1")
      })
    })

    it('click page element', () => {
      const vm = initComponent()
      const pageItem = vm.$el.querySelector('li:nth-child(3) a')
      pageItem.click()
      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("2")
      })
    })

    it('set initial page success', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 1
        }
      }).$mount()
      expect(vm.$el.querySelector(".active a").textContent).to.equal("2")
    })

    it('set forcePage success', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 0,
          forcePage: 5
        }
      }).$mount()

      const nextButton = vm.$el.querySelector("li:last-child a")
      nextButton.click()
      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("6")

        const prevButton = vm.$el.querySelector("li:first-child a")
        prevButton.click()

        Vue.nextTick(() => {
          expect(vm.$el.querySelector(".active a").textContent).to.equal("6")
        })
      })
    })

    it('set forcePage in initialPage', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 5,
          forcePage: 5
        }
      }).$mount()

      expect(vm.$el.querySelector(".active a").textContent).to.equal("6")
      const nextButton = vm.$el.querySelector("li:last-child a")
      nextButton.click()
      Vue.nextTick(() => {
        expect(vm.$el.querySelector(".active a").textContent).to.equal("6")
      })
    })
  })

  describe('page range tests', () => {
    it('page count not more than range', () => {
      const vm = new Component({
        propsData: {
          pageCount: 5,
          pageRange: 5
        }
      }).$mount()
      expect(vm.$el.querySelectorAll("li a").length).to.equal(7)
    })

    it('only has breakView in left', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 9
        }
      }).$mount()
      expect(vm.$el.querySelector(`li:nth-child(3) a`).textContent).to.equal('...')
      expect(vm.$el.querySelector(`li:nth-child(4) a`).textContent).to.equal('7')
    })
  })

  describe('enable first and last button', () => {
    it('Show fist and last button', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 1,
          firstLastButton: true
        }
      }).$mount()
      const firstButton = vm.$el.querySelector("li:first-child a")
      const lastButton = vm.$el.querySelector("li:last-child a")
      const activeItem = vm.$el.querySelector(".active a")
      expect(firstButton.textContent).to.equal("First")
      expect(lastButton.textContent).to.equal("Last")
      expect(activeItem.textContent).to.equal("2")

      firstButton.click()
      Vue.nextTick(() => {
        expect(activeItem.textContent).to.equal("1")

        lastButton.click()
        Vue.nextTick(() => {
          expect(activeItem.textContent).to.equal("10")
        })
      })
    })

    it('Show fist and last button when no li surround', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 1,
          noLiSurround: true,
          firstLastButton: true
        }
      }).$mount()
      const firstButton = vm.$el.querySelector("a:first-child")
      const lastButton = vm.$el.querySelector("a:last-child")
      const activeItem = vm.$el.querySelector("a.active")
      expect(firstButton.textContent).to.equal("First")
      expect(lastButton.textContent).to.equal("Last")
      expect(activeItem.textContent).to.equal("2")

      // firstButton.click()
      // Vue.nextTick(() => {
      //   expect(activeItem.textContent).to.equal("1")
      //
      //   lastButton.click()
      //   Vue.nextTick(() => {
      //     expect(activeItem.textContent).to.equal("10")
      //   })
      // })
    })
  })

  describe('prev and next button hide', () => {
    it('hide prev button when there is no previous page', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 0,
          hidePrevNext: true
        }
      }).$mount()

      const firstButton = vm.$el.querySelector("li:first-child a")
      expect(firstButton.textContent).to.equal("1")
    })

    it('hide next button when there is no next page', () => {
      const vm = new Component({
        propsData: {
          pageCount: 10,
          initialPage: 9,
          hidePrevNext: true
        }
      }).$mount()

      const lastButton = vm.$el.querySelector("li:last-child a")
      expect(lastButton.textContent).to.equal("10")
    })

    it('hide next and prev button when only one page', () => {
      const vm = new Component({
        propsData: {
          pageCount: 1,
          hidePrevNext: true
        }
      }).$mount()

      const firstButton = vm.$el.querySelector("li:first-child a")
      const lastButton = vm.$el.querySelector("li:last-child a")
      expect(firstButton.textContent).to.equal("1")
      expect(lastButton.textContent).to.equal("1")
    })
  })
})
<|endoftext|>


<commit_before>'use strict'

var convertReleaseNotes = require('../src/util/convertReleaseNotes.js');

describe('Test release notes converter', function(){
    it('multi release notes', function(){
        var notes = convertReleaseNotes([
            {
                title: 'title1',
            summary: 'Jira Summary1'
            },
            {
                title: 'title2',
                summary: 'Jira Summary2'
            },
        ]);
        console.log(notes);
    });

    it('single release notes', function(){
        var notes = convertReleaseNotes(
            {
                title: 'title1',
                summary: 'Jira Summary1'
            });
        console.log(notes);
    });
})
<commit_msg>add a converter to convert release notes<commit_after>'use strict'

var convertReleaseNotes = require('../src/util/convertReleaseNotes.js');

describe('Test release notes converter', function(){

    it('multi release notes', function(){
        var notes = convertReleaseNotes([
            {
                title: 'title1',
            summary: 'Jira Summary1'
            },
            {
                title: 'title2',
                summary: 'Jira Summary2'
            },
        ]);
        console.log(notes);
    });

    it('single release notes', function(){
        var notes = convertReleaseNotes(
            {
                title: 'title1',
                summary: 'Jira Summary1'
            });
        console.log(notes);
    });
})
<|endoftext|>


<commit_before>angular.module('calculatorApp', [])
    // Set the back-end common URL
    .value('URLBase', 'https://danielmunnoz.com/cenfotec/calculator/controller.php')
    /**
     * Define the service which will be provided by the Back-end
     */
    .service('CalculatorService', ['$http', 'URLBase',
        function($http, URLBase) {
            /**
             * Builds the URL to call the method of the Calculator
             *
             * @returns {*} - The result of the operation
             */
            var perform = function (operator, firstDigit, secondDigit) {
                var url = URLBase + '?operation=' + operator + '&firstDigit=' + firstDigit + '&secondDigit=' + secondDigit;

                return $http({
                    method: "GET",
                    url: url
                });
            };

            return {
                perform: perform
            }
        }])
;<commit_msg>localhost guideline<commit_after>angular.module('calculatorApp', [])
    // Set the back-end common URL
    .value('BaseURL', 'https://danielmunnoz.com/cenfotec/calculator/controller.php') // Set this to "/controller.php" when using localhost
    /**
     * Define the service which will be provided by the Back-end
     */
    .service('CalculatorService', ['$http', 'BaseURL',
        function($http, BaseURL) {
            /**
             * Builds the URL to call the method of the Calculator
             *
             * @returns {*} - The result of the operation
             */
            var perform = function (operator, firstDigit, secondDigit) {
                var url = BaseURL + '?operation=' + operator + '&firstDigit=' + firstDigit + '&secondDigit=' + secondDigit;

                return $http({
                    method: "GET",
                    url: url
                });
            };

            return {
                perform: perform
            }
        }])
;<|endoftext|>