<commit_before>
var search_list = [];

function updateData(frm){
  search_list.push(frm);
  d3.csv("http://singaporenews.github.io/transposed_terms.csv", function(error, data){
    if (search_list.length > 5){
      length = search_list.length;
      search_list = search_list.slice(-5);
    };

    line_color.domain(d3.keys(
      data[0]).filter(function(key){ return key !== 'headline_year'; }
      )
    );

    var headline_terms = line_color.domain().map(function(term){
      return {
        term: term,
        values: data.map(function(d){
          return {year: d.headline_year, count: +d[term]};
        })
      };
    });

    /*
    if (search_list.length > 5){
      length = search_list.length;
      search_list = search_list.slice(-5);
    };
    */
    used_data = $.map(headline_terms, function(element){
      return ($.inArray(element.term,search_list)>-1?element:null)
    });

    line_color.domain(search_list);

    //used_data = headline_terms.filter(function(d){ return d.term == frm; });

    var xAxis = d3.svg.axis()
      .scale(line_x)
      .orient("bottom")
      .ticks(used_data[0].values.map(function(d){ return d.year; }));

    var yAxis = d3.svg.axis()
      .scale(line_y)
      .orient('left');

    var minY = d3.min(used_data, function(c){ return d3.min(c.values, function(v){
                  return v.count; });
                });

    var maxY = d3.max(used_data, function(c){ return d3.max(c.values, function(v){
                  return v.count; });
                });

    line_x.domain(used_data[0].values.map(function(d){ return d.year; }));

    line_y.domain([minY, maxY]);

    var term_label = line_svg.selectAll('.term_label')
        .data(used_data);

    term_label
        .enter()
      .append('text')
        .attr('class', 'term_label');

        /*
        .transition()
        .duration(750)
        .attr('class', 'term_label')
        .attr("x", -60)
        .attr("y", function(d,i){ return i+"em"; })
        .style("text-anchor", "middle")
        .style("font-size", "16px")
        .transition()
        .duration(750)
        .style('fill', function(d){ return color(d.term); })
        .text(function(d){ return d.term; });
      */
    term_label
        .transition()
        .duration(750)
        .attr("x", -60)
        .attr("y", function(d,i){ return i+"em"; })
        .style("text-anchor", "middle")
        .style("font-size", "16px")
        .transition()
        .duration(750)
        .style('fill', function(d){ return line_color(d.term); })
        .text(function(d){ return d.term; });

    term_label.exit().transition().duration(750).remove();

    line_svg.selectAll('.line_y.axis')
      .transition()
      .duration(750)
      .call(yAxis);

    var terms = line_svg.selectAll('.terms');

    var termsLines = terms.selectAll('.line')
        .data(used_data);

    termsLines.enter().append('path')
        .transition()
        .duration(750)
        .attr('class', 'line')
        .attr('d', function(d){ return line(d.values); })
        .style('stroke', function(d){ return line_color(d.term); });

    termsLines.exit().transition().duration(750).remove();

    termsLines
      .transition()
      .duration(750)
      .attr('class', 'line')
      .attr('d', function(d){ return line(d.values); })
      .style('stroke', function(d){ return line_color(d.term); });

  });
};

function createChart(frm){
  search_list.push(frm);
  d3.csv("http://singaporenews.github.io/transposed_terms.csv", function(error, data){

    line_color.domain(d3.keys(
      data[0]).filter(function(key){ return key !== 'headline_year'; }
      )
    );

    var headline_terms = line_color.domain().map(function(term){
      return {
        term: term,
        values: data.map(function(d){
          return {year: d.headline_year, count: +d[term]};
        })
      };
    });

    used_data = headline_terms.filter(function(d){ return d.term == frm; });

    var xAxis = d3.svg.axis()
      .scale(line_x)
      .orient("bottom")
      .ticks(used_data[0].values.map(function(d){ return d.year; }));

    var yAxis = d3.svg.axis()
      .scale(line_y)
      .orient('left');

    var minY = d3.min(used_data, function(c){ return d3.min(c.values, function(v){
                  return v.count; });
                });

    var maxY = d3.max(used_data, function(c){ return d3.max(c.values, function(v){
                  return v.count; });
                });

    line_x.domain(used_data[0].values.map(function(d){ return d.year; }));

    line_y.domain([minY, maxY]);

    var term_label = line_svg.selectAll('term_label')
        .data(used_data)
        .enter()
      .append('text')
        .attr('class', 'term_label')
        .attr("x", -60)
        .attr("y", function(d,i){ return i+"em"; })
        .style("text-anchor", "middle")
        .style("font-size", "16px")
        .style("fill", "#53565A")
        .transition()
        .duration(750)
        .style('fill', function(d){ return line_color(d.term); })
        .text(function(d){ return d.term; });

    line_svg.append('g')
        .attr('class', 'line_x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis)
        .selectAll('text')
            .style('text-anchor', 'end')
            .attr('dx', '-.8em')
            .attr('dy', '.15em')
            .attr('transform', function(d){
              return 'rotate(-65)'
            });

    line_svg.append('g')
        .attr('class', 'line_y axis')
        .call(yAxis)
      .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '.71em')
        .style('text-anchor', 'end')
        .text('Count');

    var terms = line_svg.append('g')
              .attr('class', 'terms');

    var termsLines = terms.selectAll('.line')
        .data(used_data);

    termsLines.enter().append('path')
        .attr('class', 'line');

    termsLines.exit().remove();

    termsLines
      .attr('d', function(d){ return line(d.values); })
      .style('stroke', function(d){ return line_color(d.term); });

  });
}<commit_msg>update data<commit_after>
var search_list = [];

function updateData(frm){
  search_list.push(frm);
  d3.csv("http://singaporenews.github.io/transposed_terms.csv", function(error, data){
    if (search_list.length > 5){
      length = search_list.length;
      search_list = search_list.slice(-5);
    };

    line_color.domain(d3.keys(
      data[0]).filter(function(key){ return key !== 'headline_year'; }
      )
    );

    var headline_terms = line_color.domain().map(function(term){
      return {
        term: term,
        values: data.map(function(d){
          return {year: d.headline_year, count: +d[term]};
        })
      };
    });

    /*
    if (search_list.length > 5){
      length = search_list.length;
      search_list = search_list.slice(-5);
    };
    */
    used_data = $.map(headline_terms, function(element){
      return ($.inArray(element.term,search_list)>-1?element:null)
    });

    line_color.domain(search_list);

    //used_data = headline_terms.filter(function(d){ return d.term == frm; });

    var xAxis = d3.svg.axis()
      .scale(line_x)
      .orient("bottom")
      .ticks(used_data[0].values.map(function(d){ return d.year; }));

    var yAxis = d3.svg.axis()
      .scale(line_y)
      .orient('left');

    var minY = d3.min(used_data, function(c){ return d3.min(c.values, function(v){
                  return v.count; });
                });

    var maxY = d3.max(used_data, function(c){ return d3.max(c.values, function(v){
                  return v.count; });
                });

    line_x.domain(used_data[0].values.map(function(d){ return d.year; }));

    line_y.domain([minY, maxY]);

    var term_label = line_svg.selectAll('.term_label')
        .data(used_data);

    term_label
        .enter()
      .append('text')
        .attr('class', 'term_label');

        /*
        .transition()
        .duration(750)
        .attr('class', 'term_label')
        .attr("x", -60)
        .attr("y", function(d,i){ return i+"em"; })
        .style("text-anchor", "middle")
        .style("font-size", "16px")
        .transition()
        .duration(750)
        .style('fill', function(d){ return color(d.term); })
        .text(function(d){ return d.term; });
      */
    term_label
        .transition()
        .duration(750)
        .attr("x", -70)
        .attr("y", function(d,i){ return i+"em"; })
        .style("text-anchor", "middle")
        .style("font-size", "16px")
        .transition()
        .duration(750)
        .style('fill', function(d){ return line_color(d.term); })
        .text(function(d){ return d.term; });

    term_label.exit().transition().duration(750).remove();

    line_svg.selectAll('.line_y.axis')
      .transition()
      .duration(750)
      .call(yAxis);

    var terms = line_svg.selectAll('.terms');

    var termsLines = terms.selectAll('.line')
        .data(used_data);

    termsLines.enter().append('path')
        .transition()
        .duration(750)
        .attr('class', 'line')
        .attr('d', function(d){ return line(d.values); })
        .style('stroke', function(d){ return line_color(d.term); });

    termsLines.exit().transition().duration(750).remove();

    termsLines
      .transition()
      .duration(750)
      .attr('class', 'line')
      .attr('d', function(d){ return line(d.values); })
      .style('stroke', function(d){ return line_color(d.term); });

  });
};

function createChart(frm){
  search_list.push(frm);
  d3.csv("http://singaporenews.github.io/transposed_terms.csv", function(error, data){

    line_color.domain(d3.keys(
      data[0]).filter(function(key){ return key !== 'headline_year'; }
      )
    );

    var headline_terms = line_color.domain().map(function(term){
      return {
        term: term,
        values: data.map(function(d){
          return {year: d.headline_year, count: +d[term]};
        })
      };
    });

    used_data = headline_terms.filter(function(d){ return d.term == frm; });

    var xAxis = d3.svg.axis()
      .scale(line_x)
      .orient("bottom")
      .ticks(used_data[0].values.map(function(d){ return d.year; }));

    var yAxis = d3.svg.axis()
      .scale(line_y)
      .orient('left');

    var minY = d3.min(used_data, function(c){ return d3.min(c.values, function(v){
                  return v.count; });
                });

    var maxY = d3.max(used_data, function(c){ return d3.max(c.values, function(v){
                  return v.count; });
                });

    line_x.domain(used_data[0].values.map(function(d){ return d.year; }));

    line_y.domain([minY, maxY]);

    var term_label = line_svg.selectAll('term_label')
        .data(used_data)
        .enter()
      .append('text')
        .attr('class', 'term_label')
        .attr("x", -70)
        .attr("y", function(d,i){ return i+"em"; })
        .style("text-anchor", "middle")
        .style("font-size", "16px")
        .style("fill", "#53565A")
        .transition()
        .duration(750)
        .style('fill', function(d){ return line_color(d.term); })
        .text(function(d){ return d.term; });

    line_svg.append('g')
        .attr('class', 'line_x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis)
        .selectAll('text')
            .style('text-anchor', 'end')
            .attr('dx', '-.8em')
            .attr('dy', '.15em')
            .attr('transform', function(d){
              return 'rotate(-65)'
            });

    line_svg.append('g')
        .attr('class', 'line_y axis')
        .call(yAxis)
      .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '.71em')
        .style('text-anchor', 'end')
        .text('Count');

    var terms = line_svg.append('g')
              .attr('class', 'terms');

    var termsLines = terms.selectAll('.line')
        .data(used_data);

    termsLines.enter().append('path')
        .attr('class', 'line');

    termsLines.exit().remove();

    termsLines
      .attr('d', function(d){ return line(d.values); })
      .style('stroke', function(d){ return line_color(d.term); });

  });
}<|endoftext|>


<commit_before>var BUDGET = 'budget-';
var LS_KEY_PRODUCT_LIST = 'products';

// setup
function setupStorage(){
    // localStorage.clear();

    // init products
    if(localStorage.getItem(LS_KEY_PRODUCT_LIST)){
        console.log('existing setup');
    }
    else{
        console.log('setting up products...');

        var arrProducts = new Array(1);
        var index = -1;

        index++;
        var objProduct = new Object();
        objProduct.id = index;
        objProduct.name = 'Haha';
        objProduct.price = 10;
        objProduct.remarks = 'test product ' + index;
        arrProducts[index] = objProduct;

        index++;
        objProduct = new Object();
        objProduct.id = index;
        objProduct.name = 'Haha';
        objProduct.price = 10;
        objProduct.remarks = 'test product ' + index;
        arrProducts[index] = objProduct;

        console.log('clearing localstorage...');
        localStorage.clear();

        console.log('loading data into localstorage...');
        console.log('storing: ' + JSON.stringify(arrProducts));
        localStorage.setItem(LS_KEY_PRODUCT_LIST, JSON.stringify(arrProducts));
    }
}

function storage_getProducts(){
    return JSON.parse(localStorage.getItem(LS_KEY_PRODUCT_LIST));
}

function storage_addProduct(sName, sPrice, sRemarks){
    var objProduct = new Object();
    var nPrice = parseFloat(sPrice);

    // generate index (length + 1)
    var arrProducts = storage_getProducts();
    objProduct.id = arrProducts.length;
    objProduct.name = sName;
    objProduct.price = nPrice;
    objProduct.remarks = sRemarks;

    arrProducts[objProduct.id] = objProduct;
    localStorage.setItem(LS_KEY_PRODUCT_LIST, JSON.stringify(arrProducts));
}

function storage_removeAllProducts(){
    var arrProducts = storage_getProducts();
    arrProducts.splice(0, arrProducts.length);

    console.log('after cleaing... ' + JSON.stringify(arrProducts));
    localStorage.setItem(LS_KEY_PRODUCT_LIST, JSON.stringify(arrProducts));
}

function storage_RefreshList_UL(element_id){
    console.log('element_id: ' + element_id);
    $('#' + element_id).empty();

    var arrProducts = storage_getProducts();
    console.log('storage_RefreshList_UL() ' + arrProducts.length);
    if(arrProducts.length > 0){
        var sItemList = "
";
        for(var i = 0; i < arrProducts.length; i++){
            sItemList = sItemList + '
' + arrProducts[i].name + '
';
        }
        sItemList = sItemList + '
';
        console.log('sItemList: ' + sItemList);

        console.log('div-html-before: ' + $('#' + element_id).html());
        // $('#' + element_id).html(sItemList);
        // $('#' + element_id).page();
        $('#' + element_id).append(sItemList);
        $('#' + element_id + ' > ul').listview('refresh');

        console.log('div-html-after: ' + $('#' + element_id).html());
    }
    else{
        $('#' + element_id).html('
(no item)
');
    }
}

// Budget
function storage_budget_saveBudget(sYYYYMM, sAmount){
    var boolStatus = false;
    try{
        var nAmount = parseFloat(sAmount);
        localStorage.setItem(BUDGET + sYYYYMM, nAmount);
        boolStatus = true;
    }
    catch(err){
        console.error('storage_budget_saveBudget() - ' + err.description);
        e_alert('Error: ' + err.description);
    }

    return boolStatus;
}

function storage_budget_retrieveBudget(sYYYYMM){
    return parseFloat(localStorage.getItem(BUDGET + sYYYYMM));
}

<commit_msg>Update storage.api.js<commit_after>var BUDGET = 'budget-';
var LS_KEY_PRODUCT_LIST = 'products';

// setup
function setupStorage(){
    // localStorage.clear();

    // init products
    if(localStorage.getItem(LS_KEY_PRODUCT_LIST)){
        console.log('existing setup');
    }
    else{
        console.log('setting up products...');

        var arrProducts = new Array(1);
        var index = -1;

        index++;
        var objProduct = new Object();
        objProduct.id = index;
        objProduct.name = 'Haha';
        objProduct.price = 10;
        objProduct.remarks = 'test product ' + index;
        arrProducts[index] = objProduct;

        index++;
        objProduct = new Object();
        objProduct.id = index;
        objProduct.name = 'Haha';
        objProduct.price = 10;
        objProduct.remarks = 'test product ' + index;
        arrProducts[index] = objProduct;

        console.log('clearing localstorage...');
        localStorage.clear();

        console.log('loading data into localstorage...');
        console.log('storing: ' + JSON.stringify(arrProducts));
        localStorage.setItem(LS_KEY_PRODUCT_LIST, JSON.stringify(arrProducts));
    }
}

function storage_getProducts(){
    return JSON.parse(localStorage.getItem(LS_KEY_PRODUCT_LIST));
}

function storage_addProduct(sName, sPrice, sRemarks){
    var objProduct = new Object();
    var nPrice = parseFloat(sPrice);

    // generate index (length + 1)
    var arrProducts = storage_getProducts();
    objProduct.id = arrProducts.length;
    objProduct.name = sName;
    objProduct.price = nPrice;
    objProduct.remarks = sRemarks;

    arrProducts[objProduct.id] = objProduct;
    localStorage.setItem(LS_KEY_PRODUCT_LIST, JSON.stringify(arrProducts));
}

function storage_removeAllProducts(){
    var arrProducts = storage_getProducts();
    arrProducts.splice(0, arrProducts.length);

    console.log('after cleaing... ' + JSON.stringify(arrProducts));
    localStorage.setItem(LS_KEY_PRODUCT_LIST, JSON.stringify(arrProducts));
}

function storage_RefreshList_UL(element_id){
    console.log('element_id: ' + element_id);
    $('#' + element_id).empty();

    Try{

    var arrProducts = storage_getProducts();
    console.log('storage_RefreshList_UL() ' + arrProducts.length);
    if(arrProducts.length > 0){
        var sItemList = "
";
        for(var i = 0; i < arrProducts.length; i++){
            sItemList = sItemList + '
' + arrProducts[i].name + '
';
        }
        sItemList = sItemList + '
';
        console.log('sItemList: ' + sItemList);

        console.log('div-html-before: ' + $('#' + element_id).html());
        // $('#' + element_id).html(sItemList);
        // $('#' + element_id).page();
        $('#' + element_id).append(sItemList);
        $('#' + element_id + ' > ul').listview('refresh');

        console.log('div-html-after: ' + $('#' + element_id).html());
    }
    else{
        $('#' + element_id).html('
(no item)
');
    }

    }catch(err){
         Alert('error: ' + err.description);
    }
}

// Budget
function storage_budget_saveBudget(sYYYYMM, sAmount){
    var boolStatus = false;
    try{
        var nAmount = parseFloat(sAmount);
        localStorage.setItem(BUDGET + sYYYYMM, nAmount);
        boolStatus = true;
    }
    catch(err){
        console.error('storage_budget_saveBudget() - ' + err.description);
        e_alert('Error: ' + err.description);
    }

    return boolStatus;
}

function storage_budget_retrieveBudget(sYYYYMM){
    return parseFloat(localStorage.getItem(BUDGET + sYYYYMM));
}

<|endoftext|>


<commit_before>
var margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = 860 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.linear()
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);

var color = d3.scale.category20();

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var stack = d3.layout.stack()
  .offset('zero')
  .values(function(d){ return d.values; })
  .x(function(d){ return d.yearCol; })
  .y(function(d){ return d.countCol; });

var area = d3.svg.area()
    .interpolate('cardinal')
    .x(function(d) { return x(d.yearCol); })
    .y0(function(d) { return y(d.y0); })
    .y1(function(d) { return y(d.y0 + d.y); });

var svg = d3.select("div#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv('Words_allyears_26oct.csv', function(error, data){

  var list = ['war', 'bomb', 'blast'];
  color.domain(list);

  var data = $.map(data, function(element){
    return ($.inArray(element.wordCol,list)>-1?element:null)
  });

  data.forEach(function(d){
    d.countCol = +d.countCol;
    d.yearCol = d.yearCol;
  });

  function complete(x, key){
    for (i=0; i<key.length; i++){
      tempdata = x.filter(function(d){ return d.wordCol == key[i]; });
      yearsPresent = []
      years = [];

      for (year=1955; year<2010; year++){
        years.push(year)
        for (row=0; row<tempdata.length; row++){
          if (tempdata[row].yearCol === year){
            yearsPresent.push(year);
          }
        }
      }

      for (year=0; year<years.length; year++){
        if (yearsPresent.indexOf(years[year]) < 0){
          dict = {}
          dict['countCol'] = 0;
          dict['wordCol'] = tempdata[0].wordCol;
          dict['yearCol'] = years[year];
          data.push(dict);
        }
      }
    }

  };
  complete(data, list);

  var nest = d3.nest()
    .key(function(d){ return d.wordCol; })
    .sortValues(function(a,b){ return parseFloat(a.yearCol) - parseFloat(b.yearCol); })
    .entries(data);

  console.log(nest);

  var layers = stack(nest);

  x.domain(d3.extent(data, function(d){ return d.yearCol; }));
  y.domain([0, d3.max(data, function(d){ return d.y0 + d.y; })]);

  svg.selectAll(".layer")
      .data(layers)
    .enter().append("path")
      .attr("class", "layer")
      .attr("d", function(d) { return area(d.values); })
      .style("fill", function(d, i) { return color(i); });

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

});

  <commit_msg>update data<commit_after>
var margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = 860 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.linear()
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);

var color = d3.scale.category20();

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var stack = d3.layout.stack()
  .offset('zero')
  .values(function(d){ return d.values; })
  .x(function(d){ return d.yearCol; })
  .y(function(d){ return d.countCol; });

var area = d3.svg.area()
    .interpolate('cardinal')
    .x(function(d) { return x(d.yearCol); })
    .y0(function(d) { return y(d.y0); })
    .y1(function(d) { return y(d.y0 + d.y); });

var svg = d3.select("div#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv('Words_allyears_26oct.csv', function(error, data){

  var list = ['war', 'bomb', 'blast'];

  var data = $.map(data, function(element){
    return ($.inArray(element.wordCol,list)>-1?element:null)
  });

  data.forEach(function(d){
    d.countCol = +d.countCol;
  });

  function complete(x, key){
    for (i=0; i<key.length; i++){
      tempdata = x.filter(function(d){ return d.wordCol == key[i]; });
      yearsPresent = []
      years = [];

      for (year=1955; year<2010; year++){
        years.push(year)
        for (row=0; row<tempdata.length; row++){
          if (tempdata[row].yearCol === year){
            yearsPresent.push(year);
          }
        }
      }

      for (year=0; year<years.length; year++){
        if (yearsPresent.indexOf(years[year]) < 0){
          dict = {}
          dict['countCol'] = 0;
          dict['wordCol'] = tempdata[0].wordCol;
          dict['yearCol'] = years[year];
          data.push(dict);
        }
      }
    }

  };
  complete(data, list);

  var nest = d3.nest()
    .key(function(d){ return d.wordCol; })
    .sortValues(function(a,b){ return parseFloat(a.yearCol) - parseFloat(b.yearCol); })
    .entries(data);

  console.log(nest);

  var layers = stack(nest);

  x.domain(d3.extent(data, function(d){ return d.yearCol; }));
  y.domain([0, d3.max(data, function(d){ return d.y0 + d.y; })]);

  svg.selectAll(".layer")
      .data(layers)
    .enter().append("path")
      .attr("class", "layer")
      .attr("d", function(d) { return area(d.values); })
      .style("fill", function(d, i) { return color(i); });

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

});

  <|endoftext|>


<commit_before>function HumanActor(faction, room, legName, torsoName, weaponName, headName, initialX, initialY, initialFacingDirection) {
    var actor = this
    actor.faction = faction
    actor.faction.actors.push(actor)
    actor.room = room
    actor.legName = legName
    actor.torsoName = torsoName
    actor.weaponName = weaponName
    actor.headName = headName
    actor.layers = []
    actor.destination = room
    actor.facing = initialFacingDirection
    actor.health = actor.healthLimit = 6
    actor.initialX = initialX
    actor.initialY = initialY

    faction.orderGiven.listen(function() {
        actor.think()
    })
}

HumanActor.prototype.setup = function() {
    var actor = this

    actor.room.game.contentLoaded.listen(function() {
        actor.group = new SprigganGroup(actor.room.game.actorsGroup, function() {
            actor.room.game.mode.clicked(actor)
        })

        var healthSpriteSpacing = 2

        actor.healthSprites = []
        while (actor.healthSprites.length < actor.healthLimit) {
            var healthSprite = new SprigganSprite(actor.group, BattleContent, "battle/markers")
            healthSprite.hide()
            healthSprite.loop("healthGood")
            healthSprite.move(healthSpriteSpacing * (actor.healthSprites.length + 0.5 - actor.healthLimit / 2), 0)
            actor.healthSprites.push(healthSprite)
        }

        actor.legSpriteGroup = new SpriteGroup(actor.group, BattleContent, "character", [actor.legName])
        actor.legSpriteGroup.loop("idleDown")
        actor.torsoSpriteGroup = new SpriteGroup(actor.group, BattleContent, "character", [actor.torsoName, actor.weaponName, actor.headName])
        actor.torsoSpriteGroup.loop("idleDown")

        actor.group.move(actor.initialX, actor.initialY)

        actor.room.game.actors.push(actor)
        actor.room.actors.push(actor)

        actor.room.addIdleActor(actor, "up")

        actor.room.arrived.raise(actor)
    })
}

HumanActor.prototype.hurt = function(damage) {
    if (!this.health) return

    var newHealth = Math.max(0, this.health - damage)

    if (this.health == this.healthLimit)
        for (var i = 0; i < this.healthLimit; i++) this.healthSprites[i].show()

    for (var i = newHealth; i < this.health; i++)
        this.healthSprites[i].loop("healthBad")

    this.health = newHealth
    this.think()
    if (!this.health) {
        for (var i = 0; i < this.healthLimit; i++) this.healthSprites[i].dispose()
        this.legSpriteGroup.play("death")
        this.torsoSpriteGroup.play("death")
    }
}

HumanActor.prototype.setDestination = function(room) {
    var actor = this
    actor.destination = room
    actor.think()
}

HumanActor.prototype.think = function() {
    var actor = this

    if (!actor.health) return

    if (!actor.moving) {
        var newDirection = actor.controller.getDirectionToMove()

        if (!newDirection) {
            actor.destination = actor.room
            actor.moving = false
        } else {
            actor.room.removeIdleActor(actor)
            actor.facing = newDirection
            var link = actor.room.links[newDirection]
            var next = link.roomOpposite(actor.room)
            actor.moving = true

            if (!actor.walking) {
                actor.walking = true
                var foot = "left"

                function TakeStep() {
                    foot = foot == "left" ? "right" : "left"
                    BattleContent.sounds.footstep.play()
                    actor.legSpriteGroup.play("walk" + (foot == "left" ? "A" : "B") + Capitalize(actor.facing), TakeStep)
                }

                TakeStep()
            }

            // Walking over a link is a four step process:
            // - Walk 20 pixels in front of the boundary our side.
            // - Walk to the boundary.  The room swap happens here.
            // - Walk 20 pixels in front of the boundary on the new side.
            // - Recurse to .think()

            var xDiff = 0, yDiff = 0

            switch (actor.facing) {
                case "up":
                    yDiff = -actor.room.game.tileset.linkLength
                    break
                case "down":
                    yDiff = actor.room.game.tileset.linkLength
                    break
                case "left":
                    xDiff = -actor.room.game.tileset.linkLength
                    break
                case "right":
                    xDiff = actor.room.game.tileset.linkLength
                    break
            }

            var x = (next.x + actor.room.x) * actor.room.game.tileset.gridSpacing / 2
            var y = (next.y + actor.room.y) * actor.room.game.tileset.gridSpacing / 2

            actor.group.moveAtPixelsPerSecond(x - xDiff, y - yDiff, 100, function() {
                link.enteredBy(actor)
                actor.group.moveAtPixelsPerSecond(x, y , 100, function() {
                    actor.room = next
                    actor.room.arrived.raise(actor)
                    actor.group.moveAtPixelsPerSecond(x + xDiff, y + yDiff, 100, function() {
                        link.leftBy(actor)
                        actor.moving = false
                        actor.room.addIdleActor(actor, newDirection)
                    })
                })
            })
        }
    }

    if (!actor.moving) {
        actor.walking = false

        var x = actor.room.x * actor.room.game.tileset.gridSpacing
        var y = actor.room.y * actor.room.game.tileset.gridSpacing
        if (actor.room.idleActors.length > 1) {
            var angle = actor.room.idleActors.indexOf(actor) * 2 * Math.PI / actor.room.idleActors.length
            x += Math.sin(angle) * 8
            y += Math.cos(angle) * 8
        }
        actor.group.moveAtPixelsPerSecond(x, y, 100)
        actor.legSpriteGroup.loop("idle" + Capitalize(actor.facing))
    }

    if (!actor.acting) {
        for (var i = 0; i < actor.faction.orders.length; i++) {
            if (actor.faction.orders[i].tryExecute(actor, function() {
                actor.acting = false
                actor.think()
            })) {
                actor.acting = true
                break
            }
        }
    }

    Items[actor.weaponName].weapon.handle(actor)

    if (!actor.acting) {
        if (actor.moving)
            actor.torsoSpriteGroup.loop("walk" + Capitalize(actor.facing))
        else
            actor.torsoSpriteGroup.loop("idle" + Capitalize(actor.facing))
    }
}

HumanActor.prototype.say = function(text, horizontalAlignment, verticalAlignment) {
    this.stopSaying()
    this.speechGroup = SprigganWrite(this.group, sharedContent, "fontBig", fontBig, text, "center", "bottom")
    this.speechGroup.moveAtPixelsPerSecond(0, -12, 64)
}

HumanActor.prototype.stopSaying = function() {
    if (this.speechGroup) {
        this.speechGroup.dispose()
        this.speechGroup = null
    }
}

HumanActor.prototype.hearSound = function(room) {
    this.controller.hearSound(room)
}<commit_msg>Fixed actors not being moved between rooms when using links.  This caused AI to not be able to see people they have line of sight with.<commit_after>function HumanActor(faction, room, legName, torsoName, weaponName, headName, initialX, initialY, initialFacingDirection) {
    var actor = this
    actor.faction = faction
    actor.faction.actors.push(actor)
    actor.room = room
    actor.legName = legName
    actor.torsoName = torsoName
    actor.weaponName = weaponName
    actor.headName = headName
    actor.layers = []
    actor.destination = room
    actor.facing = initialFacingDirection
    actor.health = actor.healthLimit = 6
    actor.initialX = initialX
    actor.initialY = initialY

    faction.orderGiven.listen(function() {
        actor.think()
    })
}

HumanActor.prototype.setup = function() {
    var actor = this

    actor.room.game.contentLoaded.listen(function() {
        actor.group = new SprigganGroup(actor.room.game.actorsGroup, function() {
            actor.room.game.mode.clicked(actor)
        })

        var healthSpriteSpacing = 2

        actor.healthSprites = []
        while (actor.healthSprites.length < actor.healthLimit) {
            var healthSprite = new SprigganSprite(actor.group, BattleContent, "battle/markers")
            healthSprite.hide()
            healthSprite.loop("healthGood")
            healthSprite.move(healthSpriteSpacing * (actor.healthSprites.length + 0.5 - actor.healthLimit / 2), 0)
            actor.healthSprites.push(healthSprite)
        }

        actor.legSpriteGroup = new SpriteGroup(actor.group, BattleContent, "character", [actor.legName])
        actor.legSpriteGroup.loop("idleDown")
        actor.torsoSpriteGroup = new SpriteGroup(actor.group, BattleContent, "character", [actor.torsoName, actor.weaponName, actor.headName])
        actor.torsoSpriteGroup.loop("idleDown")

        actor.group.move(actor.initialX, actor.initialY)

        actor.room.game.actors.push(actor)
        actor.room.actors.push(actor)

        actor.room.addIdleActor(actor, "up")

        actor.room.arrived.raise(actor)
    })
}

HumanActor.prototype.hurt = function(damage) {
    if (!this.health) return

    var newHealth = Math.max(0, this.health - damage)

    if (this.health == this.healthLimit)
        for (var i = 0; i < this.healthLimit; i++) this.healthSprites[i].show()

    for (var i = newHealth; i < this.health; i++)
        this.healthSprites[i].loop("healthBad")

    this.health = newHealth
    this.think()
    if (!this.health) {
        for (var i = 0; i < this.healthLimit; i++) this.healthSprites[i].dispose()
        this.legSpriteGroup.play("death")
        this.torsoSpriteGroup.play("death")
    }
}

HumanActor.prototype.setDestination = function(room) {
    var actor = this
    actor.destination = room
    actor.think()
}

HumanActor.prototype.think = function() {
    var actor = this

    if (!actor.health) return

    if (!actor.moving) {
        var newDirection = actor.controller.getDirectionToMove()

        if (!newDirection) {
            actor.destination = actor.room
            actor.moving = false
        } else {
            actor.room.removeIdleActor(actor)
            actor.facing = newDirection
            var link = actor.room.links[newDirection]
            var next = link.roomOpposite(actor.room)
            actor.moving = true

            if (!actor.walking) {
                actor.walking = true
                var foot = "left"

                function TakeStep() {
                    foot = foot == "left" ? "right" : "left"
                    BattleContent.sounds.footstep.play()
                    actor.legSpriteGroup.play("walk" + (foot == "left" ? "A" : "B") + Capitalize(actor.facing), TakeStep)
                }

                TakeStep()
            }

            // Walking over a link is a four step process:
            // - Walk 20 pixels in front of the boundary our side.
            // - Walk to the boundary.  The room swap happens here.
            // - Walk 20 pixels in front of the boundary on the new side.
            // - Recurse to .think()

            var xDiff = 0, yDiff = 0

            switch (actor.facing) {
                case "up":
                    yDiff = -actor.room.game.tileset.linkLength
                    break
                case "down":
                    yDiff = actor.room.game.tileset.linkLength
                    break
                case "left":
                    xDiff = -actor.room.game.tileset.linkLength
                    break
                case "right":
                    xDiff = actor.room.game.tileset.linkLength
                    break
            }

            var x = (next.x + actor.room.x) * actor.room.game.tileset.gridSpacing / 2
            var y = (next.y + actor.room.y) * actor.room.game.tileset.gridSpacing / 2

            actor.group.moveAtPixelsPerSecond(x - xDiff, y - yDiff, 100, function() {
                link.enteredBy(actor)
                actor.group.moveAtPixelsPerSecond(x, y , 100, function() {
                    SprigganRemoveByValue(actor.room.actors, actor)
                    next.actors.push(actor)
                    actor.room = next
                    actor.room.arrived.raise(actor)
                    actor.group.moveAtPixelsPerSecond(x + xDiff, y + yDiff, 100, function() {
                        link.leftBy(actor)
                        actor.moving = false
                        actor.room.addIdleActor(actor, newDirection)
                    })
                })
            })
        }
    }

    if (!actor.moving) {
        actor.walking = false

        var x = actor.room.x * actor.room.game.tileset.gridSpacing
        var y = actor.room.y * actor.room.game.tileset.gridSpacing
        if (actor.room.idleActors.length > 1) {
            var angle = actor.room.idleActors.indexOf(actor) * 2 * Math.PI / actor.room.idleActors.length
            x += Math.sin(angle) * 8
            y += Math.cos(angle) * 8
        }
        actor.group.moveAtPixelsPerSecond(x, y, 100)
        actor.legSpriteGroup.loop("idle" + Capitalize(actor.facing))
    }

    if (!actor.acting) {
        for (var i = 0; i < actor.faction.orders.length; i++) {
            if (actor.faction.orders[i].tryExecute(actor, function() {
                actor.acting = false
                actor.think()
            })) {
                actor.acting = true
                break
            }
        }
    }

    Items[actor.weaponName].weapon.handle(actor)

    if (!actor.acting) {
        if (actor.moving)
            actor.torsoSpriteGroup.loop("walk" + Capitalize(actor.facing))
        else
            actor.torsoSpriteGroup.loop("idle" + Capitalize(actor.facing))
    }
}

HumanActor.prototype.say = function(text, horizontalAlignment, verticalAlignment) {
    this.stopSaying()
    this.speechGroup = SprigganWrite(this.group, sharedContent, "fontBig", fontBig, text, "center", "bottom")
    this.speechGroup.moveAtPixelsPerSecond(0, -12, 64)
}

HumanActor.prototype.stopSaying = function() {
    if (this.speechGroup) {
        this.speechGroup.dispose()
        this.speechGroup = null
    }
}

HumanActor.prototype.hearSound = function(room) {
    this.controller.hearSound(room)
}<|endoftext|>


<commit_before>/* jshint browser: true */

(function (window, $) {
    "use strict";

    /*
     *  Represenets an editor
     *  @constructor
     *  @param {DOMNode} element - The TEXTAREA element to add the Wysiwyg to.
     *  @param {object} userOptions - The default options selected by the user.
     */
    function Wysiwyg(element, userOptions) {

        // This calls the $ function, with the element as a parameter and
        // returns the jQuery object wrapper for element. It also assigns the
        // jQuery object wrapper to the property $editor on `this`.
        this.selectedRange = null;
        this.editor = $(element);
        var editor = $(element);
        var defaults = {
            hotKeys: {
                "Ctrl+b meta+b": "bold",
                "Ctrl+i meta+i": "italic",
                "Ctrl+u meta+u": "underline",
                "Ctrl+z": "undo",
                "Ctrl+y meta+y meta+shift+z": "redo",
                "Ctrl+l meta+l": "justifyleft",
                "Ctrl+r meta+r": "justifyright",
                "Ctrl+e meta+e": "justifycenter",
                "Ctrl+j meta+j": "justifyfull",
                "Shift+tab": "outdent",
                "tab": "indent"
            },
            toolbarSelector: "[data-role=editor-toolbar]",
            commandRole: "edit",
            activeToolbarClass: "btn-info",
            selectionMarker: "edit-focus-marker",
            selectionColor: "red",
            dragAndDropImages: true,
            keypressTimeout: 200,
            fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
        };

        var options = $.extend(true, {}, defaults, userOptions);
        var toolbarBtnSelector = "a[data-" + options.commandRole + "],button[data-" + options.commandRole + "],input[type=button][data-" + options.commandRole + "]";
        this.bindHotkeys(editor, options, toolbarBtnSelector);

        if (options.dragAndDropImages) {
            this.initFileDrops(editor, options, toolbarBtnSelector);
        }

        this.bindToolbar(editor, $(options.toolbarSelector), options, toolbarBtnSelector);

        editor.attr("contenteditable", true)
            .on("mouseup keyup mouseout", function () {
                this.saveSelection();
                this.updateToolbar(editor, toolbarBtnSelector, options);
            }.bind(this));

        $(window).bind("touchend", function (e) {
            var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
                currentRange = this.getCurrentRange(),
                clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);

            if (!clear || isInside) {
                this.saveSelection();
                this.updateToolbar(editor, toolbarBtnSelector, options);
            }
        });
    }

    Wysiwyg.prototype.readFileIntoDataUrl = function (fileInfo) {
        var loader = $.Deferred(),
            fReader = new FileReader();

        fReader.onload = function (e) {
            loader.resolve(e.target.result);
        };

        fReader.onerror = loader.reject;
        fReader.onprogress = loader.notify;
        fReader.readAsDataURL(fileInfo);
        return loader.promise();
    };

    Wysiwyg.prototype.cleanHtml = function (o) {
        var self = this;
        if ($(self).data("wysiwyg-html-mode") === true) {
            $(self).html($(self).text());
            $(self).attr("contenteditable", true);
            $(self).data("wysiwyg-html-mode", false);
        }

        // Strip the images with src="data:image/.." out;
        if (o === true && $(self).parent().is("form")) {
            var gGal = $(self).html;
            if ($(gGal).has("img").length) {
                var gImages = $("img", $(gGal));
                var gResults = [];
                var gEditor = $(self).parent();
                $.each(gImages, function (i, v) {
                    if ($(v).attr("src").match(/^data:image\/.*$/)) {
                        gResults.push(gImages[i]);
                        $(gEditor).prepend("<input value='" + $(v).attr("src") + "' type='hidden' name='postedimage/" + i + "' />");
                        $(v).attr("src", "postedimage/" + i);
                    }
                });
            }
        }

        var html = $(self).html();
        return html && html.replace(/(
|\s|

<\/div>| )*$/, "");
    };

    Wysiwyg.prototype.updateToolbar = function (editor, toolbarBtnSelector, options) {
        if (options.activeToolbarClass) {
            $(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
                var self = $(this);
                var commandArr = self.data(options.commandRole).split(" ");
                var command = commandArr[0];

                // If the command has an argument and its value matches this button. == used for string/number comparison
                if (commandArr.length > 1 && document.queryCommandEnabled(command) && document.queryCommandValue(command) === commandArr[1]) {
                    self.addClass(options.activeToolbarClass);
                }

                // Else if the command has no arguments and it is active
                else if (commandArr.length === 1 && document.queryCommandEnabled(command) && document.queryCommandState(command)) {
                    self.addClass(options.activeToolbarClass);
                }

                // Else the command is not active
                else {
                    self.removeClass(options.activeToolbarClass);
                }
            });
        }
    };

    Wysiwyg.prototype.execCommand = function (commandWithArgs, valueArg, editor, options, toolbarBtnSelector) {
        var commandArr = commandWithArgs.split(" "),
            command = commandArr.shift(),
            args = commandArr.join(" ") + (valueArg || "");

        var parts = commandWithArgs.split("-");

        if (parts.length === 1) {
            document.execCommand(command, false, args);
        } else if (parts[0] === "format" && parts.length === 2) {
            document.execCommand("formatBlock", false, parts[1]);
        }

        (editor).trigger("change");
        this.updateToolbar(editor, toolbarBtnSelector, options);
    };

    Wysiwyg.prototype.bindHotkeys = function (editor, options, toolbarBtnSelector) {
        var self = this;
        $.each(options.hotKeys, function (hotkey, command) {
            if (!command) return;

            $(editor).keydown(hotkey, function (e) {
                if (editor.attr("contenteditable") && $(editor).is(":visible")) {
                    e.preventDefault();
                    e.stopPropagation();
                    self.execCommand(command, null, editor, options, toolbarBtnSelector);
                }
            }).keyup(hotkey, function (e) {
                if (editor.attr("contenteditable") && $(editor).is(":visible")) {
                    e.preventDefault();
                    e.stopPropagation();
                }
            });
        });

        editor.keyup(function () { editor.trigger("change"); });
    };

    Wysiwyg.prototype.getCurrentRange = function () {
        var sel, range;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
            }
        } else if (document.selection) {
            range = document.selection.createRange();
        }

        return range;
    };

    Wysiwyg.prototype.saveSelection = function () {
        this.selectedRange = this.getCurrentRange();
    };

    Wysiwyg.prototype.restoreSelection = function () {
        var selection;
        if (window.getSelection || document.createRange) {
            selection = window.getSelection();
            if (this.selectedRange) {
                try {
                    selection.removeAllRanges();
                }
                catch (ex) {
                    document.body.createTextRange().select();
                    document.selection.empty();
                }
                selection.addRange(this.selectedRange);
            }
        } else if (document.selection && this.selectedRange) {
            this.selectedRange.select();
        }
    };

    Wysiwyg.prototype.restoreSelection2 = function (inputSel) {
        var selection;
        if (window.getSelection || document.createRange) {
            selection = window.getSelection();
            if (this.selectedRange) {
                try {
                    selection.removeAllRanges();
                }
                catch (ex) {
                    //try adding value here for edge when there is no selection
                    document.body.createTextRange().select();
                    document.selection.empty();
                }
                selection.addRange(inputSel);
            }
        } else if (document.selection && inputSel) {
            inputSel.select();
        }
    };

    // Adding Toggle HTML based on the work by @jd0000, but cleaned up a little to work in this context.
    Wysiwyg.prototype.toggleHtmlEdit = function (editor) {
        if (editor.data("wysiwyg-html-mode") !== true) {
            var oContent = editor.html();
            var editorPre = $("
");
            $(editorPre).append(document.createTextNode(oContent));
            $(editorPre).attr("contenteditable", true);
            $(editor).html(" ");
            $(editor).append($(editorPre));
            $(editor).attr("contenteditable", false);
            $(editor).data("wysiwyg-html-mode", true);
            $(editorPre).focus();
        } else {
            $(editor).html($(editor).text());
            $(editor).attr("contenteditable", true);
            $(editor).data("wysiwyg-html-mode", false);
            $(editor).focus();
        }
    };

    Wysiwyg.prototype.insertFiles = function (files, options, editor, toolbarBtnSelector) {
        var self = this;
        editor.focus();
        $.each(files, function (idx, fileInfo) {
            if (/^image\//.test(fileInfo.type)) {
                $.when(self.readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
                    self.execCommand("insertimage", dataUrl, editor, options, toolbarBtnSelector);
                    editor.trigger("image-inserted");
                }).fail(function (e) {
                    options.fileUploadError("file-reader", e);
                });
            } else {
                options.fileUploadError("unsupported-file-type", fileInfo.type);
            }
        });
    };

    Wysiwyg.prototype.markSelection = function (input, color, options) {
        this.restoreSelection();
        if (document.queryCommandSupported("hiliteColor")) {
            document.execCommand("hiliteColor", false, color || "transparent");
        }
        this.saveSelection();
        //input.data(options.selectionMarker, color);
    };

    Wysiwyg.prototype.bindToolbar = function (editor, toolbar, options, toolbarBtnSelector) {
        var self = this;
        toolbar.find(toolbarBtnSelector).click(function () {
            self.restoreSelection();
            editor.focus();

            if (editor.data(options.commandRole) === "html") {
                self.toggleHtmlEdit(editor);
            } else {
                self.execCommand($(this).data(options.commandRole), null, editor, options, toolbarBtnSelector);
            }

            self.saveSelection();
        });

        toolbar.find("[data-toggle=dropdown]").on('click', (function () {
            self.restoreSelection();
            self.markSelection(null, options.selectionColor, options);
        }));

        $(".dropdown").on("hide.bs.dropdown", function () {
            self.markSelection(null, false, options);
        });

        toolbar.find("input[type=text][data-" + options.commandRole + "]").on("webkitspeechchange change", function () {
            var newValue = this.value;  // Ugly but prevents fake double-calls due to selection restoration
            this.value = "";
            self.restoreSelection();
            if (newValue) {
                editor.focus();
                self.execCommand($(this).data(options.commandRole), newValue, editor, options, toolbarBtnSelector);
            }
            self.saveSelection();
        }).on("focus", function () {
            console.log('focus');
            var input = $(this);
            // if (!input.data(options.selectionMarker)) {
            //     self.markSelection(input, options.selectionColor, options);
            // }
        }).on("blur", function () {
            console.log('blur');
            var input = $(this);
            self.markSelection(input, false, options);
        });
        toolbar.find("input[type=file][data-" + options.commandRole + "]").change(function () {
            self.restoreSelection();
            if (this.type === "file" && this.files && this.files.length > 0) {
                self.insertFiles(this.files, options, editor, toolbarBtnSelector);
            }
            self.saveSelection();
            this.value = "";
        });
    };

    Wysiwyg.prototype.initFileDrops = function (editor, options, toolbarBtnSelector) {
        var self = this;
        editor.on("dragenter dragover", false).on("drop", function (e) {
            var dataTransfer = e.originalEvent.dataTransfer;
            e.stopPropagation();
            e.preventDefault();
            if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
                self.insertFiles(dataTransfer.files, options, editor, toolbarBtnSelector);
            }
        });
    };

    /*
     *  Represenets an editor
     *  @constructor
     *  @param {object} userOptions - The default options selected by the user.
     */

    $.fn.wysiwyg = function (userOptions) {
        var wysiwyg = new Wysiwyg(this, userOptions);
    };

})(window, window.jQuery);
<commit_msg>remove unneccessary code<commit_after>/* jshint browser: true */

(function (window, $) {
    "use strict";

    /*
     *  Represenets an editor
     *  @constructor
     *  @param {DOMNode} element - The TEXTAREA element to add the Wysiwyg to.
     *  @param {object} userOptions - The default options selected by the user.
     */
    function Wysiwyg(element, userOptions) {

        // This calls the $ function, with the element as a parameter and
        // returns the jQuery object wrapper for element. It also assigns the
        // jQuery object wrapper to the property $editor on `this`.
        this.selectedRange = null;
        this.editor = $(element);
        var editor = $(element);
        var defaults = {
            hotKeys: {
                "Ctrl+b meta+b": "bold",
                "Ctrl+i meta+i": "italic",
                "Ctrl+u meta+u": "underline",
                "Ctrl+z": "undo",
                "Ctrl+y meta+y meta+shift+z": "redo",
                "Ctrl+l meta+l": "justifyleft",
                "Ctrl+r meta+r": "justifyright",
                "Ctrl+e meta+e": "justifycenter",
                "Ctrl+j meta+j": "justifyfull",
                "Shift+tab": "outdent",
                "tab": "indent"
            },
            toolbarSelector: "[data-role=editor-toolbar]",
            commandRole: "edit",
            activeToolbarClass: "btn-info",
            selectionMarker: "edit-focus-marker",
            selectionColor: "darkgrey",
            dragAndDropImages: true,
            keypressTimeout: 200,
            fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
        };

        var options = $.extend(true, {}, defaults, userOptions);
        var toolbarBtnSelector = "a[data-" + options.commandRole + "],button[data-" + options.commandRole + "],input[type=button][data-" + options.commandRole + "]";
        this.bindHotkeys(editor, options, toolbarBtnSelector);

        if (options.dragAndDropImages) {
            this.initFileDrops(editor, options, toolbarBtnSelector);
        }

        this.bindToolbar(editor, $(options.toolbarSelector), options, toolbarBtnSelector);

        editor.attr("contenteditable", true)
            .on("mouseup keyup mouseout", function () {
                this.saveSelection();
                this.updateToolbar(editor, toolbarBtnSelector, options);
            }.bind(this));

        $(window).bind("touchend", function (e) {
            var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
                currentRange = this.getCurrentRange(),
                clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);

            if (!clear || isInside) {
                this.saveSelection();
                this.updateToolbar(editor, toolbarBtnSelector, options);
            }
        });
    }

    Wysiwyg.prototype.readFileIntoDataUrl = function (fileInfo) {
        var loader = $.Deferred(),
            fReader = new FileReader();

        fReader.onload = function (e) {
            loader.resolve(e.target.result);
        };

        fReader.onerror = loader.reject;
        fReader.onprogress = loader.notify;
        fReader.readAsDataURL(fileInfo);
        return loader.promise();
    };

    Wysiwyg.prototype.cleanHtml = function (o) {
        var self = this;
        if ($(self).data("wysiwyg-html-mode") === true) {
            $(self).html($(self).text());
            $(self).attr("contenteditable", true);
            $(self).data("wysiwyg-html-mode", false);
        }

        // Strip the images with src="data:image/.." out;
        if (o === true && $(self).parent().is("form")) {
            var gGal = $(self).html;
            if ($(gGal).has("img").length) {
                var gImages = $("img", $(gGal));
                var gResults = [];
                var gEditor = $(self).parent();
                $.each(gImages, function (i, v) {
                    if ($(v).attr("src").match(/^data:image\/.*$/)) {
                        gResults.push(gImages[i]);
                        $(gEditor).prepend("<input value='" + $(v).attr("src") + "' type='hidden' name='postedimage/" + i + "' />");
                        $(v).attr("src", "postedimage/" + i);
                    }
                });
            }
        }

        var html = $(self).html();
        return html && html.replace(/(
|\s|

<\/div>| )*$/, "");
    };

    Wysiwyg.prototype.updateToolbar = function (editor, toolbarBtnSelector, options) {
        if (options.activeToolbarClass) {
            $(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
                var self = $(this);
                var commandArr = self.data(options.commandRole).split(" ");
                var command = commandArr[0];

                // If the command has an argument and its value matches this button. == used for string/number comparison
                if (commandArr.length > 1 && document.queryCommandEnabled(command) && document.queryCommandValue(command) === commandArr[1]) {
                    self.addClass(options.activeToolbarClass);
                }

                // Else if the command has no arguments and it is active
                else if (commandArr.length === 1 && document.queryCommandEnabled(command) && document.queryCommandState(command)) {
                    self.addClass(options.activeToolbarClass);
                }

                // Else the command is not active
                else {
                    self.removeClass(options.activeToolbarClass);
                }
            });
        }
    };

    Wysiwyg.prototype.execCommand = function (commandWithArgs, valueArg, editor, options, toolbarBtnSelector) {
        var commandArr = commandWithArgs.split(" "),
            command = commandArr.shift(),
            args = commandArr.join(" ") + (valueArg || "");

        var parts = commandWithArgs.split("-");

        if (parts.length === 1) {
            document.execCommand(command, false, args);
        } else if (parts[0] === "format" && parts.length === 2) {
            document.execCommand("formatBlock", false, parts[1]);
        }

        (editor).trigger("change");
        this.updateToolbar(editor, toolbarBtnSelector, options);
    };

    Wysiwyg.prototype.bindHotkeys = function (editor, options, toolbarBtnSelector) {
        var self = this;
        $.each(options.hotKeys, function (hotkey, command) {
            if (!command) return;

            $(editor).keydown(hotkey, function (e) {
                if (editor.attr("contenteditable") && $(editor).is(":visible")) {
                    e.preventDefault();
                    e.stopPropagation();
                    self.execCommand(command, null, editor, options, toolbarBtnSelector);
                }
            }).keyup(hotkey, function (e) {
                if (editor.attr("contenteditable") && $(editor).is(":visible")) {
                    e.preventDefault();
                    e.stopPropagation();
                }
            });
        });

        editor.keyup(function () { editor.trigger("change"); });
    };

    Wysiwyg.prototype.getCurrentRange = function () {
        var sel, range;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
            }
        } else if (document.selection) {
            range = document.selection.createRange();
        }

        return range;
    };

    Wysiwyg.prototype.saveSelection = function () {
        this.selectedRange = this.getCurrentRange();
    };

    Wysiwyg.prototype.restoreSelection = function () {
        var selection;
        if (window.getSelection || document.createRange) {
            selection = window.getSelection();
            if (this.selectedRange) {
                try {
                    selection.removeAllRanges();
                }
                catch (ex) {
                    document.body.createTextRange().select();
                    document.selection.empty();
                }
                selection.addRange(this.selectedRange);
            }
        } else if (document.selection && this.selectedRange) {
            this.selectedRange.select();
        }
    };

    // Adding Toggle HTML based on the work by @jd0000, but cleaned up a little to work in this context.
    Wysiwyg.prototype.toggleHtmlEdit = function (editor) {
        if (editor.data("wysiwyg-html-mode") !== true) {
            var oContent = editor.html();
            var editorPre = $("
");
            $(editorPre).append(document.createTextNode(oContent));
            $(editorPre).attr("contenteditable", true);
            $(editor).html(" ");
            $(editor).append($(editorPre));
            $(editor).attr("contenteditable", false);
            $(editor).data("wysiwyg-html-mode", true);
            $(editorPre).focus();
        } else {
            $(editor).html($(editor).text());
            $(editor).attr("contenteditable", true);
            $(editor).data("wysiwyg-html-mode", false);
            $(editor).focus();
        }
    };

    Wysiwyg.prototype.insertFiles = function (files, options, editor, toolbarBtnSelector) {
        var self = this;
        editor.focus();
        $.each(files, function (idx, fileInfo) {
            if (/^image\//.test(fileInfo.type)) {
                $.when(self.readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
                    self.execCommand("insertimage", dataUrl, editor, options, toolbarBtnSelector);
                    editor.trigger("image-inserted");
                }).fail(function (e) {
                    options.fileUploadError("file-reader", e);
                });
            } else {
                options.fileUploadError("unsupported-file-type", fileInfo.type);
            }
        });
    };

    Wysiwyg.prototype.markSelection = function (input, color, options) {
        this.restoreSelection();
        if (document.queryCommandSupported("hiliteColor")) {
            document.execCommand("hiliteColor", false, color || "transparent");
        }
        this.saveSelection();
        //input.data(options.selectionMarker, color);
    };

    Wysiwyg.prototype.bindToolbar = function (editor, toolbar, options, toolbarBtnSelector) {
        var self = this;
        toolbar.find(toolbarBtnSelector).click(function () {
            self.restoreSelection();
            editor.focus();

            if (editor.data(options.commandRole) === "html") {
                self.toggleHtmlEdit(editor);
            } else {
                self.execCommand($(this).data(options.commandRole), null, editor, options, toolbarBtnSelector);
            }

            self.saveSelection();
        });

        toolbar.find("[data-toggle=dropdown]").on('click', (function () {
            self.restoreSelection();
            self.markSelection(null, options.selectionColor, options);
        }));

        toolbar.on("hide.bs.dropdown", function () {
            self.markSelection(null, false, options);
        });

        toolbar.find("input[type=text][data-" + options.commandRole + "]").on("webkitspeechchange change", function () {
            var newValue = this.value;  // Ugly but prevents fake double-calls due to selection restoration
            this.value = "";
            self.restoreSelection();
            if (newValue) {
                editor.focus();
                self.execCommand($(this).data(options.commandRole), newValue, editor, options, toolbarBtnSelector);
            }
            self.saveSelection();
        }).on("focus", function () {
            console.log('focus');
            var input = $(this);
            // if (!input.data(options.selectionMarker)) {
            //     self.markSelection(input, options.selectionColor, options);
            // }
        }).on("blur", function () {
            console.log('blur');
            var input = $(this);
            self.markSelection(input, false, options);
        });
        toolbar.find("input[type=file][data-" + options.commandRole + "]").change(function () {
            self.restoreSelection();
            if (this.type === "file" && this.files && this.files.length > 0) {
                self.insertFiles(this.files, options, editor, toolbarBtnSelector);
            }
            self.saveSelection();
            this.value = "";
        });
    };

    Wysiwyg.prototype.initFileDrops = function (editor, options, toolbarBtnSelector) {
        var self = this;
        editor.on("dragenter dragover", false).on("drop", function (e) {
            var dataTransfer = e.originalEvent.dataTransfer;
            e.stopPropagation();
            e.preventDefault();
            if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
                self.insertFiles(dataTransfer.files, options, editor, toolbarBtnSelector);
            }
        });
    };

    /*
     *  Represenets an editor
     *  @constructor
     *  @param {object} userOptions - The default options selected by the user.
     */

    $.fn.wysiwyg = function (userOptions) {
        var wysiwyg = new Wysiwyg(this, userOptions);
    };

})(window, window.jQuery);
<|endoftext|>


<commit_before>/* ==========================================================
 * Tooltip.js v0.0.1
 * ==========================================================
 * Copyright 2012 xsokev
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

define([
    "bootstrap/Support",
    "dojo/_base/declare",
    "dojo/query",
    "dojo/_base/lang",
    'dojo/_base/window',
    'dojo/on',
    'dojo/mouse',
    'dojo/dom-class',
    "dojo/dom-attr",
    'dojo/dom-style',
    'dojo/dom-geometry',
    'dojo/dom-construct',
    'dojo/html',
    "dojo/NodeList-dom",
    'dojo/NodeList-manipulate',
    'dojo/NodeList-traverse',
    "dojo/domReady!"
], function (support, declare, query, lang, win, on, mouse, domClass, domAttr, domStyle, domGeom, domConstruct, html) {
    "use strict";

    var toggleSelector = '[data-toggle="tooltip"]';
    var Tooltip = declare("Tooltip", null, {
        defaultOptions:{
            animation:true,
            placement:'top',
            selector:false,
            template:'

',
            trigger:'hover',
            title:'',
            delay:0,
            html: true
        },
        constructor:function (element, options) {
            this.init('tooltip', element, options);
        },
        init:function (type, element, options) {
            this.domNode = element;

            var eventIn, eventOut;
            this.type = type;
            this.options = this.getOptions(options);
            this.enabled = true;

            if (this.options.trigger === 'click') {
                if (this.options.selector) {
                    this.eventActivate = on(this.domNode, on.selector(this.options.selector, 'click'), lang.hitch(this, 'toggle'));
                } else {
                    this.eventActivate = on(this.domNode, 'click', lang.hitch(this, 'toggle'));
                }
            } else if (this.options.trigger !== 'manual') {
                eventIn = this.options.trigger === 'hover' ? mouse.enter : 'focusin';
                eventOut = this.options.trigger === 'hover' ? mouse.leave : 'focusout';
                if (this.options.selector) {
                    eventIn = on.selector(this.options.selector, eventIn);
                    eventOut = on.selector(this.options.selector, eventOut);
                }
                this.eventActivate = on(this.domNode, eventIn, lang.hitch(this, 'enter'));
                this.eventDeactivate = on(this.domNode, eventOut, lang.hitch(this, 'leave'));
            }

            if (this.options.selector) {
                (this._options = lang.mixin({}, lang.mixin(lang.clone(this.options), { trigger:'manual', selector:'' })));
            } else {
                this.fixTitle();
            }
        },
        getOptions:function (options) {
            options = lang.mixin({},
                lang.mixin(lang.clone(this.defaultOptions),
                    lang.mixin(options, support.getData(this.domNode))));
            if (options.delay && typeof options.delay === 'number') {
                options.delay = {
                    show:options.delay,
                    hide:options.delay
                };
            }
            return options;
        },
        enter:function (e) {
            var self = support.getData(e.target, this.type);
            if (!self) {
                query(e.target)[this.type](this._options);
                self = support.getData(e.target, this.type);
            }
            if (this.timeout) {
                clearTimeout(this.timeout);
            }
            if (self) {
                if (!self.options.delay || !self.options.delay.show) {
                    return self.show();
                }
                self.hoverState = 'in';
                this.timeout = setTimeout(function () {
                    if (self.hoverState === 'in') {
                        self.show();
                    }
                }, self.options.delay.show);
            }
            return this;
        },
        leave:function (e) {
            var self = support.getData(e.target, this.type);
            if (!self) {
                query(e.target)[this.type](this._options);
                self = support.getData(e.target, this.type);
            }
            if (this.timeout) {
                clearTimeout(this.timeout);
            }
            if (self) {
                if (!self.options.delay || !self.options.delay.hide) {
                    return self.hide();
                }
                self.hoverState = 'out';
                this.timeout = setTimeout(function () {
                    if (self.hoverState === 'out') {
                        self.hide();
                    }
                }, self.options.delay.hide);
            }
            return this;
        },
        show:function () {
            var tip, inside, pos, actualWidth, actualHeight, placement, tp;
            if (this.hasContent() && this.enabled) {
                tip = this.tip();
                this.setContent();
                //fix: passing data-animation as boolean false should work the same as passing a string ('false')
                if (this.options.animation && (this.options.animation !== 'false' && this.options.animation !== false)) {
                    domClass.add(tip, 'fade');
                }
                placement = typeof this.options.placement === 'function' ?
                    this.options.placement.call(this, tip, this.domNode) :
                    this.options.placement;

                inside = /in/.test(placement);

                domConstruct.place(tip, (inside ? this.domNode : win.body()), 'last');
                domStyle.set(tip, {top:0, left:0, display:'block'});

                pos = this.getPosition(inside);
                var tipPos = domGeom.position(tip);
                actualWidth = tipPos.w;
                actualHeight = tipPos.h;

                switch (inside ? placement.split(' ')[1] : placement) {
                    case 'bottom':
                        tp = {top:(pos.top + pos.height) + "px", left:(pos.left + pos.width / 2 - actualWidth / 2) + "px"};
                        break;
                    case 'top':
                        tp = {top:(pos.top - actualHeight) + "px", left:(pos.left + pos.width / 2 - actualWidth / 2) + "px"};
                        break;
                    case 'left':
                        tp = {top:(pos.top + pos.height / 2 - actualHeight / 2) + "px", left:(pos.left - actualWidth) + "px"};
                        break;
                    case 'right':
                        tp = {top:(pos.top + pos.height / 2 - actualHeight / 2) + "px", left:(pos.left + pos.width) + "px"};
                        break;
                }
                domStyle.set(tip, tp);
                domClass.add(tip, (new Array(placement, 'in')).join(" "));
            }
        },
        hide:function () {
            var _this = this;
            var tip = this.tip();
            domClass.remove(tip, 'in');
            function _removeWithAnimation() {
                var timeout = setTimeout(function () {
                    _this.hideEvent.remove();
                }, 500);

                _this.hideEvent = on.once(tip, support.trans.end, function () {
                    clearTimeout(timeout);
                    _destroyTip();
                });
            }
            function _destroyTip() {
                domConstruct.destroy(tip);
                _this.tipNode = null;
            }

            if (support.trans && domClass.contains(tip, 'fade')) {
                _removeWithAnimation();
            } else {
                _destroyTip();
            }
            return this;
        },
        setContent:function () {
            var tip = this.tip();
            var title = this.getTitle();
            query('.tooltip-inner', tip)[this.options.html ? 'html' : 'text'](title);
            domClass.remove(tip, 'fade in top bottom left right');
        },
        hasContent:function () {
            return this.getTitle();
        },
        fixTitle:function () {
            if (domAttr.get(this.domNode, 'title') || typeof(domAttr.get(this.domNode, 'data-original-title')) !== 'string') {
                domAttr.set(this.domNode, 'data-original-title', domAttr.get(this.domNode, 'title') || '');
                domAttr.remove(this.domNode, 'title');
            }
        },
        getTitle:function () {
            return domAttr.get(this.domNode, 'data-original-title') || (typeof this.options.title === 'function' ? this.options.title.call(this.domNode) : this.options.title);
        },
        getPosition:function (inside) {
            var pos = domGeom.position(this.domNode, true);
            return lang.mixin({},
                lang.mixin(inside ? {top:0, left:0} : {top:pos.y, left:pos.x}, {
                    width:pos.w, height:pos.h }));
        },
        tip:function () {
            return this.tipNode = (this.tipNode) ? this.tipNode : domConstruct.toDom(this.options.template);
        },
        validate:function () {
            if (!this.domNode.parentNode) {
                domStyle.set(this.domNode, "display", "none");
                this.domNode = null;
                this.options = null;
            }
        },
        enable:function () {
            this.enabled = true;
        },
        disable:function () {
            this.enabled = false;
        },
        toggleEnabled:function () {
            this.enabled = !this.enabled;
        },
        toggle:function () {
            this[domClass.contains(this.tip(), 'in') ? 'hide' : 'show']();
        },
        destroy: function() {
            this.hide();
            if (this.eventActivate) { this.eventActivate.remove(); }
            if (this.eventDeactivate) { this.eventDeactivate.remove(); }
            support.removeData(this.domNode, 'tooltip');
        }
    });

    lang.extend(query.NodeList, {
        tooltip:function (option) {
            var options = (lang.isObject(option)) ? option : {};
            return this.forEach(function (node) {
                var data = support.getData(node, 'tooltip');
                if (!data) {
                    support.setData(node, 'tooltip', (data = new Tooltip(node, options)));
                }
                if (lang.isString(option)) {
                    data[option].call(data);
                }
            });
        }
    });

    query(toggleSelector).tooltip();

    return Tooltip;
});<commit_msg>Fixes issue #9 - Popover opened inside Modal remains visible when Modal is close.<commit_after>/* ==========================================================
 * Tooltip.js v0.0.1
 * ==========================================================
 * Copyright 2012 xsokev
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

define([
    "bootstrap/Support",
    "dojo/_base/declare",
    "dojo/query",
    "dojo/_base/lang",
    'dojo/_base/window',
    'dojo/on',
    'dojo/mouse',
    'dojo/dom-class',
    "dojo/dom-attr",
    'dojo/dom-style',
    'dojo/dom-geometry',
    'dojo/dom-construct',
    'dojo/html',
    "dojo/NodeList-dom",
    'dojo/NodeList-manipulate',
    'dojo/NodeList-traverse',
    "dojo/domReady!"
], function (support, declare, query, lang, win, on, mouse, domClass, domAttr, domStyle, domGeom, domConstruct, html) {
    "use strict";

    var toggleSelector = '[data-toggle=tooltip]';
    var Tooltip = declare("Tooltip", null, {
        defaultOptions:{
            animation:true,
            placement:'top',
            selector:false,
            template:'

',
            trigger:'hover',
            title:'',
            delay:0,
            html: true
        },
        constructor:function (element, options) {
            this.init('tooltip', element, options);
        },
        init:function (type, element, options) {
            var _this = this;
            this.domNode = element;

            var eventIn, eventOut;
            this.type = type;
            this.options = this.getOptions(options);
            this.enabled = true;

            if (this.options.trigger === 'click') {
                query(this.domNode).parents('.modal').on('hidden', function(){
                    _this.hide();
                });
                if (this.options.selector) {
                    this.eventActivate = on(this.domNode, on.selector(this.options.selector, 'click'), lang.hitch(this, 'toggle'));
                } else {
                    this.eventActivate = on(this.domNode, 'click', lang.hitch(this, 'toggle'));
                }
            } else if (this.options.trigger !== 'manual') {
                eventIn = this.options.trigger === 'hover' ? mouse.enter : 'focusin';
                eventOut = this.options.trigger === 'hover' ? mouse.leave : 'focusout';
                if (this.options.selector) {
                    eventIn = on.selector(this.options.selector, eventIn);
                    eventOut = on.selector(this.options.selector, eventOut);
                }
                this.eventActivate = on(this.domNode, eventIn, lang.hitch(this, 'enter'));
                this.eventDeactivate = on(this.domNode, eventOut, lang.hitch(this, 'leave'));
            }

            if (this.options.selector) {
                (this._options = lang.mixin({}, lang.mixin(lang.clone(this.options), { trigger:'manual', selector:'' })));
            } else {
                this.fixTitle();
            }
        },
        getOptions:function (options) {
            options = lang.mixin({},
                lang.mixin(lang.clone(this.defaultOptions),
                    lang.mixin(options, support.getData(this.domNode))));
            if (options.delay && typeof options.delay === 'number') {
                options.delay = {
                    show:options.delay,
                    hide:options.delay
                };
            }
            return options;
        },
        enter:function (e) {
            var self = support.getData(e.target, this.type);
            if (!self) {
                query(e.target)[this.type](this._options);
                self = support.getData(e.target, this.type);
            }
            if (this.timeout) {
                clearTimeout(this.timeout);
            }
            if (self) {
                if (!self.options.delay || !self.options.delay.show) {
                    return self.show();
                }
                self.hoverState = 'in';
                this.timeout = setTimeout(function () {
                    if (self.hoverState === 'in') {
                        self.show();
                    }
                }, self.options.delay.show);
            }
            return this;
        },
        leave:function (e) {
            var self = support.getData(e.target, this.type);
            if (!self) {
                query(e.target)[this.type](this._options);
                self = support.getData(e.target, this.type);
            }
            if (this.timeout) {
                clearTimeout(this.timeout);
            }
            if (self) {
                if (!self.options.delay || !self.options.delay.hide) {
                    return self.hide();
                }
                self.hoverState = 'out';
                this.timeout = setTimeout(function () {
                    if (self.hoverState === 'out') {
                        self.hide();
                    }
                }, self.options.delay.hide);
            }
            return this;
        },
        show:function () {
            var tip, inside, pos, actualWidth, actualHeight, placement, tp;
            if (this.hasContent() && this.enabled) {
                tip = this.tip();
                this.setContent();
                //fix: passing data-animation as boolean false should work the same as passing a string ('false')
                if (this.options.animation && (this.options.animation !== 'false' && this.options.animation !== false)) {
                    domClass.add(tip, 'fade');
                }
                placement = typeof this.options.placement === 'function' ?
                    this.options.placement.call(this, tip, this.domNode) :
                    this.options.placement;

                inside = /in/.test(placement);

                domConstruct.place(tip, (inside ? this.domNode : win.body()), 'last');
                domStyle.set(tip, {top:0, left:0, display:'block'});

                pos = this.getPosition(inside);
                var tipPos = domGeom.position(tip);
                actualWidth = tipPos.w;
                actualHeight = tipPos.h;

                switch (inside ? placement.split(' ')[1] : placement) {
                    case 'bottom':
                        tp = {top:(pos.top + pos.height) + "px", left:(pos.left + pos.width / 2 - actualWidth / 2) + "px"};
                        break;
                    case 'top':
                        tp = {top:(pos.top - actualHeight) + "px", left:(pos.left + pos.width / 2 - actualWidth / 2) + "px"};
                        break;
                    case 'left':
                        tp = {top:(pos.top + pos.height / 2 - actualHeight / 2) + "px", left:(pos.left - actualWidth) + "px"};
                        break;
                    case 'right':
                        tp = {top:(pos.top + pos.height / 2 - actualHeight / 2) + "px", left:(pos.left + pos.width) + "px"};
                        break;
                }
                domStyle.set(tip, tp);
                domClass.add(tip, (new Array(placement, 'in')).join(" "));
            }
        },
        hide:function () {
            var _this = this;
            var tip = this.tip();
            domClass.remove(tip, 'in');
            function _removeWithAnimation() {
                var timeout = setTimeout(function () {
                    _this.hideEvent.remove();
                }, 500);

                _this.hideEvent = on.once(tip, support.trans.end, function () {
                    clearTimeout(timeout);
                    _destroyTip();
                });
            }
            function _destroyTip() {
                domConstruct.destroy(tip);
                _this.tipNode = null;
            }

            if (support.trans && domClass.contains(tip, 'fade')) {
                _removeWithAnimation();
            } else {
                _destroyTip();
            }
            return this;
        },
        setContent:function () {
            var tip = this.tip();
            var title = this.getTitle();
            query('.tooltip-inner', tip)[this.options.html ? 'html' : 'text'](title);
            domClass.remove(tip, 'fade in top bottom left right');
        },
        hasContent:function () {
            return this.getTitle();
        },
        fixTitle:function () {
            if (domAttr.get(this.domNode, 'title') || typeof(domAttr.get(this.domNode, 'data-original-title')) !== 'string') {
                domAttr.set(this.domNode, 'data-original-title', domAttr.get(this.domNode, 'title') || '');
                domAttr.remove(this.domNode, 'title');
            }
        },
        getTitle:function () {
            return domAttr.get(this.domNode, 'data-original-title') || (typeof this.options.title === 'function' ? this.options.title.call(this.domNode) : this.options.title);
        },
        getPosition:function (inside) {
            var pos = domGeom.position(this.domNode, true);
            return lang.mixin({},
                lang.mixin(inside ? {top:0, left:0} : {top:pos.y, left:pos.x}, {
                    width:pos.w, height:pos.h }));
        },
        tip:function () {
            return this.tipNode = (this.tipNode) ? this.tipNode : domConstruct.toDom(this.options.template);
        },
        validate:function () {
            if (!this.domNode.parentNode) {
                domStyle.set(this.domNode, "display", "none");
                this.domNode = null;
                this.options = null;
            }
        },
        enable:function () {
            this.enabled = true;
        },
        disable:function () {
            this.enabled = false;
        },
        toggleEnabled:function () {
            this.enabled = !this.enabled;
        },
        toggle:function () {
            this[domClass.contains(this.tip(), 'in') ? 'hide' : 'show']();
        },
        destroy: function() {
            this.hide();
            if (this.eventActivate) { this.eventActivate.remove(); }
            if (this.eventDeactivate) { this.eventDeactivate.remove(); }
            support.removeData(this.domNode, 'tooltip');
        }
    });

    lang.extend(query.NodeList, {
        tooltip:function (option) {
            var options = (lang.isObject(option)) ? option : {};
            return this.forEach(function (node) {
                var data = support.getData(node, 'tooltip');
                if (!data) {
                    support.setData(node, 'tooltip', (data = new Tooltip(node, options)));
                }
                if (lang.isString(option)) {
                    data[option].call(data);
                }
            });
        }
    });

    query(toggleSelector).tooltip();

    return Tooltip;
});<|endoftext|>


<commit_before>define(['jquery', 'common/util', 'app-config', 'broken/builds', 'broken/updater', 'broken/renderer'],
  function ($, util, config, data, updater, renderer) {
    var my = {},
      throttler = util.newThrottler(updater.addForUrl, config.bulkUpdateSize, config.updateInterval);

    var initFormSubmit = function () {
      var selectedTestCases = function () {
        var selected = $('input.testCaseSelect:checked');
        var ids = $.makeArray(selected.map(function () {
          return $(this).data('testcaseid');
        }));
        return ids.map(function (id) {
          return data.testCaseForId(id);
        });
      };

      var selectedBuilds = function () {
        var selected = $('input.buildSelect:checked');
        var ids = $.makeArray(selected.map(function () {
          return $(this).data('buildid');
        }));
        return ids.map(function (id) {
          return data.buildForId(id);
        });
      };

      $('#claimForm').submit(function (event) {
        try {
          var testCases = selectedTestCases();
          var builds = selectedBuilds();
          var claim = {};
          $(this).serializeArray().forEach(function (field) {
            claim[field.name] = field.value;
          });
          util.sequentially(testCases.concat(builds), function (testCase) {
            return updater.claim(testCase, claim);
          });
        } catch (err) {
          console.log(err);
        }
        event.preventDefault();
      });

      $('#dropClaimsForm').submit(function (event) {
        try {
          var testCases = selectedTestCases();
          var builds = selectedBuilds();
          testCases.concat(builds).forEach(updater.unclaim);
        } catch (err) {
          console.log(err);
        }
        event.preventDefault();
      });
    };

    my.init = function (urlsDef) {
      initFormSubmit();
      updater.views().then(renderer.addViews);
      renderer.renderLoop();
      urlsDef.then(
        throttler.scheduleUpdates,
        function (error, statusCode, statusText) {
          var loading = $('#projects').find('.loading')[0];
          loading.innerHTML = '
Loading Failed: ' + statusText + '
';
        }
      )
        .then(function (urls) {
          if (!urls) {
            $(data).trigger(data.event);
          }
        });
    };

    return my;
  });<commit_msg>Make sure the drawing event is fired only if there are no urls to draw.<commit_after>define(['jquery', 'common/util', 'app-config', 'broken/builds', 'broken/updater', 'broken/renderer'],
  function ($, util, config, data, updater, renderer) {
    var my = {},
      throttler = util.newThrottler(updater.addForUrl, config.bulkUpdateSize, config.updateInterval);

    var initFormSubmit = function () {
      var selectedTestCases = function () {
        var selected = $('input.testCaseSelect:checked');
        var ids = $.makeArray(selected.map(function () {
          return $(this).data('testcaseid');
        }));
        return ids.map(function (id) {
          return data.testCaseForId(id);
        });
      };

      var selectedBuilds = function () {
        var selected = $('input.buildSelect:checked');
        var ids = $.makeArray(selected.map(function () {
          return $(this).data('buildid');
        }));
        return ids.map(function (id) {
          return data.buildForId(id);
        });
      };

      $('#claimForm').submit(function (event) {
        try {
          var testCases = selectedTestCases();
          var builds = selectedBuilds();
          var claim = {};
          $(this).serializeArray().forEach(function (field) {
            claim[field.name] = field.value;
          });
          util.sequentially(testCases.concat(builds), function (testCase) {
            return updater.claim(testCase, claim);
          });
        } catch (err) {
          console.log(err);
        }
        event.preventDefault();
      });

      $('#dropClaimsForm').submit(function (event) {
        try {
          var testCases = selectedTestCases();
          var builds = selectedBuilds();
          testCases.concat(builds).forEach(updater.unclaim);
        } catch (err) {
          console.log(err);
        }
        event.preventDefault();
      });
    };

    my.init = function (urlsDef) {
      initFormSubmit();
      updater.views().then(renderer.addViews);
      renderer.renderLoop();
      urlsDef.then(
        throttler.scheduleUpdates,
        function (error, statusCode, statusText) {
          var loading = $('#projects').find('.loading')[0];
          loading.innerHTML = '
Loading Failed: ' + statusText + '
';
        }
      );

      urlsDef.then(function (urls) {
        if (!urls) {
          $(data).trigger(data.event);
        }
      });
    };

    return my;
  });<|endoftext|>