<commit_before>/**
 * TODO: ECMAScript 5 has String.trim, change $.trim to it when browsers support
 * it.
 */

// Create a new namespace.
function WikipediaLib(
  episodes_article,
  season_keyword,
  episodes_keyword,
  progress_error
) {
  season_keyword = season_keyword.toLowerCase();
  episodes_keyword = episodes_keyword.toLowerCase();

  /**
   * Removes HTML comments from text.
   */
  function removeComments(text) {
    return text.replace(/<!--[\s\S]*?-->/gm, "");
  }

  /**
   * Removes some of MediaWiki markup - italic text, bold text, bold and italic
   * text, links, references, nowrap template.
   *
   * http://www.mediawiki.org/wiki/Help:Formatting
   * http://en.wikipedia.org/wiki/Template:Nowrap
   */
  function removeMarkup(text) {
    return text.replace(/'''''([\s\S]*?)'''''/g, "$1")
      .replace(/'''([\s\S]*?)'''/g, "$1")
      .replace(/''([\s\S]*?)''/g, "$1")
      .replace(/\[\[([^\|]*?)\]\]/g, "$1")
      .replace(/\[\[[\s\S]*?\|([\s\S]*?)\]\]/g, "$1")
      .replace(/<\s*ref[\s\S]*?\/>/gm, "")
      .replace(/<\s*ref[\s\S]*?[^\/]>[\s\S]*?<\s*\/\s*ref\s*>/gm, "")
      .replace(/<\s*ref\s*>[\s\S]*?<\s*\/\s*ref\s*>/gm, "")
      .replace(/\{\{\s*nowrap\s*\|([\s\S]*?)\}\}/, "$1");
  }

  /**
   * Finds all top-level templates matching given template constructor.
   */
  function findTemplates(constructor, content) {
    var last = null, depth = 0, lastChar = " ", templates = [];
    for (var i = 0; i < content.length; ++i) {
      var c = content[i];
      var d = depth;
      if ((lastChar ==  "{") && (c == "{"))
        if (++depth == 1) last = i - 1;
      if ((lastChar == "}") && (c == "}")) --depth;
      if ((depth == 0) && (last != null)) {
        try {
          var t = new constructor(content.substring(last, i + 1));
          templates.push(t);
        } catch (e) {
        }
        last = null;
      }
      if (d != depth) lastChar = " ";
      else lastChar = c;
    }
    return templates;
  }

  /**
   * MediaWiki template.  Object provides several variables:
   *
   * - templateName - name of the template
   *
   * - unnamedParams - list of unnamed parameters
   *
   * - namedParams - dictionary of named parameters
   *
   * http://en.wikipedia.org/wiki/Help:Template
   */
  function Template(content) {
    function splitParams(text) {
      var params = [], last = 0, depth = 0, lastChar = " ";
      for (var i = 0; i < text.length; ++i) {
        var c = text[i];
        var d = depth;
        if ((lastChar ==  "{") && (c == "{")) ++depth;
        if ((lastChar ==  "[") && (c == "[")) ++depth;
        if ((lastChar == "}") && (c == "}")) --depth;
        if ((lastChar == "]") && (c == "]")) --depth;
        if ((depth == 0) && (c == "|")) {
          params.push(text.substring(last, i));
          last = i + 1;
        }
        if (d != depth) lastChar = " ";
        else lastChar = c;
      }
      if (last != text.length) params.push(text.substring(last, text.length));
      if (depth != 0) throw "Unexpected end of template";
      return params;
    }

    var a = content.match(/^{{([\s\S]*)}}$/);
    if (!a) throw "Template syntax error";
    content = $.map(splitParams(a[1]), function(e, i) {
      return $.trim(e);
    });
    if (content.length < 1) throw "Template syntax error";
    this.templateName = content[0].toLowerCase();
    content = content.splice(1);

    this.unnamedParams = $.grep(content, function(e, i) {
      return !e.match("=");
    });

    var named = $.grep(content, function(e, i) {
      return e.match("=");
    });
    var namedParams = {}
    $.each(named, function(i, e) {
      var a = e.indexOf("=");
      var name = $.trim(e.substr(0, a));
      var value = $.trim(e.substr(a + 1));
      namedParams[name] = value;
    });
    this.namedParams = namedParams;
  }

  /**
   * Sub-class of Template.  Additional methods: getTitle, getNumber,
   * getAirDate, getSummary.  They will return null if requested information is
   * unavailable.
   *
   * http://en.wikipedia.org/wiki/Template:Episode_list
   */
  function EpisodeList(content) {
    Template.call(this, content);
    if (!this.templateName.match(/^episode list/))
      throw "This is not an episode list template";

    var params = this.namedParams;

    this.getTitle = function() {
      if (params["Title"]) return removeMarkup(params["Title"]);
      if (params["RTitle"]) return removeMarkup(params["RTitle"]);
      return null;
    }

    this.getNumber = function() {
      if (params["EpisodeNumber2"])
        return removeMarkup(params["EpisodeNumber2"]);
      if (params["EpisodeNumber"])
        return removeMarkup(params["EpisodeNumber"]);
      return null;
    }

    this.getAirDate = function() {
      if (!params["OriginalAirDate"]) return null;
      try {
        var text = removeMarkup(params["OriginalAirDate"]);

        // Ignore extra shit people tend to place here
        var start = null, end, depth = 0, lastChar = " ";
        for (var i = 0; i < text.length; ++i) {
          var c = text[i];
          var d = depth;
          if ((lastChar ==  "{") && (c == "{"))
            if (++depth == 1) start = i - 1;
          if ((lastChar == "}") && (c == "}")) --depth;
          if ((depth == 0) && (start != null)) {
            end = i + 1;
            break;
          }
          if (d != depth) lastChar = " ";
          else lastChar = c;
        }

        return new StartDate(text.substring(start, end));
      } catch (e) {
        return null;
      }
    }

    this.getSummary = function() {
      if (!params["ShortSummary"]) return null;
      return removeMarkup(params["ShortSummary"]);
    }
  }

  /**
   * Sub-class of Template.  Provides year, month, day variables and toString
   * method.
   *
   * http://en.wikipedia.org/wiki/Template:Start_date
   */
  function StartDate(content) {
    Template.call(this, content);
    if ((!this.templateName.match(/^start date$/)) &&
        (!this.templateName.match(/^dts$/)))
      throw "This is not a start date template";

    var params = this.unnamedParams, year, month = null, day = null;
    if (params.length < 1)
      throw "Not enough parameters";
    year = params[0];
    if (params.length >= 2) month = params[1];
    if (params.length >= 3) day = params[2];

    this.year = year;
    this.month = month;
    this.day = day;
    this.toString = function() {
      if (day !== null) {
        return year + "." + month + "." + day;
      }
      if (month !== null) {
        return year + "." + month;
      }
      return year;
    }
  }

  /**
   * Breaks down a MediaWiki article revision into sections.  Provides sections
   * variable.
   */
  function Article(content) {
    content = removeComments(content);
    var title =  "", step = true, sections = {};
    $.each(content.split(/==+([\s\S]+?)==+/), function(i, e) {
      if (step) sections[title] = e;
      else title = $.trim(e.toLowerCase());
      step = !step;
    });
    var names = content.match(/==+[\s\S]+?==+/g);
    if (names) {
      function sectionDepth(name) {
        return name.split("=").length - 1;
      }
      trimNames = $.map(names, function(e, i) {
        return $.trim(e.replace(/==+([\s\S]+?)==+/, "$1").toLowerCase());
      });
      // Adds sub-section contents to master sections.  O(n^2), could be O(n)
      for (var i = 0; i < names.length; ++i) {
        var depth = sectionDepth(names[i]);
        var j = i + 1;
        while ((j < names.length) && (sectionDepth(names[j]) > depth))
          sections[trimNames[i]] += sections[trimNames[j++]];
      }
    }
    this.sections = sections;
  }

  /**
   * Requests given article title from Wikipedia.  If request is successful it
   * runs given callback on the fetched article.
   */
  function getArticle(title, callback) {
    var url = "https://en.wikipedia.org/w/api.php?" +
      "format=json&callback=?&" +
      "action=query&prop=revisions&rvprop=content&redirects&titles=";
    $.ajax({
      dataType: "jsonp",
      url: url + title,
      success: function(data) {
        if (data.query.pages["-1"]) {
          progress_error();
        } else {
          var n;
          for (n in data.query.pages);
          callback(new Article(data.query.pages[n].revisions[0]["*"]));
        }
      },
      error: progress_error
    });
  }

  /**
   * All information about one TV series.  Provides seasons variables and toJSON
   * method.
   */
  function TVSeries(seasons) {
    this.seasons = seasons;
    this.toJSON = function() {
      function serialize(season) {
        return $.map(season, function(episode) {
          var airDate = episode.getAirDate();
          if (airDate != null) airDate = airDate.toString();
          return { number: episode.getNumber(),
                   title: episode.getTitle(),
                   air_date: airDate,
                   summary: episode.getSummary() };
        });
      }

      var data = {};
      for (season in seasons) {
        data[season] = serialize(seasons[season]);
      }
      return data;
    }
  }

  function getTVSeries(callback) {
    var seasonData = {};

    function finalize() {
      if (isSeasonDataEmpty()) {
        progress_error();
      } else {
        callback(new TVSeries(seasonData));
      }
    }

    function updateSeasonData(number, episodes) {
      // If there already is a season with this number then somebody is trying
      // to fuck us up.
      if ((episodes.length) && (seasonData[number] == null))
        seasonData[number] = episodes;
    }

    function isSeasonDataEmpty() {
      var empty = true;
      for (a in seasonData) empty = false;
      return empty;
    }

    function episodeSection(section) {
      return (section == "episodes") ||
        (section == "list of episodes") ||
        (section == "episode list") ||
        (episodes_keyword && section == episodes_keyword);
    }

    function seasonSection(section) {
      var m;
      if (season_keyword) {
        regex = new RegExp('^' + season_keyword + '\s*(\d+)[\s\S]*$');
        m = section.match(regex);
        if (m != null) return m[1];
      }
      m = section.match(/^season\s*(\d+)[\s\S]*$/);
      if (m != null) return m[1];
      m = section.match(/^series\s*(\d+)[\s\S]*$/);
      if (m != null) return m[1];
      return null;
    }

    // Episodes data without a season section
    function findOneSeason(article) {
      var success = false;
      for (section in article.sections) {
        if (episodeSection(section)) {
          var episodes = findTemplates(EpisodeList, article.sections[section]);
          updateSeasonData(1, episodes);
          success = true;
        }
      }
      if (!success) {
        progress_error();
      } else {
        finalize();
      }
    }

    function findBySeasons(article) {
      var sections = [];

      function processSections() {
        if (sections.length) {
          var section = sections.pop();
          var number = section[0];
          var section = section[1];
          var template = section.match(/$[\s\S]*?{{:([\s\S]*?)}}[\s\S]*/m);
          if (template != null) {
            // Episode list in a separate article
            template = $.trim(template[1]);
            getArticle(template, function(a) {
              for (section in a.sections) {
                if (episodeSection(section)) {
                  var episodes = findTemplates(EpisodeList, a.sections[section]);
                  updateSeasonData(number, episodes);
                }
              }
              processSections();
            });
          } else {
            var episodes = findTemplates(EpisodeList, section);
            updateSeasonData(number, episodes);
            processSections();
          }
        } else {
          if (isSeasonDataEmpty()) {
            findOneSeason(article);
          } else {
            finalize();
          }
        }
      }

      for (section in article.sections) {
        var number = seasonSection(section);
        if (number != null) {
          sections.push([number, article.sections[section]]);
        }
      }
      processSections();
    }

    getArticle(episodes_article, function(article) {
      findBySeasons(article);
    });
  }

  // Public methods.
  return { getTVSeries: getTVSeries };
}
<commit_msg>Style changes<commit_after>/**
 * TODO: ECMAScript 5 has String.trim, change $.trim to it when browsers support
 * it.
 */

// Create a new namespace.
function WikipediaLib(
  episodes_article,
  season_keyword,
  episodes_keyword,
  progress_error
) {
  season_keyword = season_keyword.toLowerCase();
  episodes_keyword = episodes_keyword.toLowerCase();

  /**
   * Removes HTML comments from text.
   */
  function removeComments(text) {
    return text.replace(/<!--[\s\S]*?-->/gm, "");
  }

  /**
   * Removes some of MediaWiki markup - italic text, bold text, bold and italic
   * text, links, references, nowrap template.
   *
   * http://www.mediawiki.org/wiki/Help:Formatting
   * http://en.wikipedia.org/wiki/Template:Nowrap
   */
  function removeMarkup(text) {
    return text.replace(/'''''([\s\S]*?)'''''/g, "$1")
      .replace(/'''([\s\S]*?)'''/g, "$1")
      .replace(/''([\s\S]*?)''/g, "$1")
      .replace(/\[\[([^\|]*?)\]\]/g, "$1")
      .replace(/\[\[[\s\S]*?\|([\s\S]*?)\]\]/g, "$1")
      .replace(/<\s*ref[\s\S]*?\/>/gm, "")
      .replace(/<\s*ref[\s\S]*?[^\/]>[\s\S]*?<\s*\/\s*ref\s*>/gm, "")
      .replace(/<\s*ref\s*>[\s\S]*?<\s*\/\s*ref\s*>/gm, "")
      .replace(/\{\{\s*nowrap\s*\|([\s\S]*?)\}\}/, "$1");
  }

  /**
   * Finds all top-level templates matching given template constructor.
   */
  function findTemplates(constructor, content) {
    var last = null;
    var depth = 0;
    var lastChar = " ";
    var templates = [];
    for (var i = 0; i < content.length; ++i) {
      var c = content[i];
      var d = depth;
      if ((lastChar ==  "{") && (c == "{")) {
        if (++depth == 1) {
          last = i - 1;
        }
      }
      if ((lastChar == "}") && (c == "}")) {
        --depth;
      }
      if ((depth == 0) && (last != null)) {
        try {
          var t = new constructor(content.substring(last, i + 1));
          templates.push(t);
        } catch (e) {
        }
        last = null;
      }
      if (d != depth) {
        lastChar = " ";
      } else {
        lastChar = c;
      }
    }
    return templates;
  }

  /**
   * MediaWiki template.  Object provides several variables:
   *
   * - templateName - name of the template
   *
   * - unnamedParams - list of unnamed parameters
   *
   * - namedParams - dictionary of named parameters
   *
   * http://en.wikipedia.org/wiki/Help:Template
   */
  function Template(content) {
    function splitParams(text) {
      var params = [], last = 0, depth = 0, lastChar = " ";
      for (var i = 0; i < text.length; ++i) {
        var c = text[i];
        var d = depth;
        if ((lastChar ==  "{") && (c == "{")) ++depth;
        if ((lastChar ==  "[") && (c == "[")) ++depth;
        if ((lastChar == "}") && (c == "}")) --depth;
        if ((lastChar == "]") && (c == "]")) --depth;
        if ((depth == 0) && (c == "|")) {
          params.push(text.substring(last, i));
          last = i + 1;
        }
        if (d != depth) lastChar = " ";
        else lastChar = c;
      }
      if (last != text.length) params.push(text.substring(last, text.length));
      if (depth != 0) throw "Unexpected end of template";
      return params;
    }

    var a = content.match(/^{{([\s\S]*)}}$/);
    if (!a) throw "Template syntax error";
    content = $.map(splitParams(a[1]), function(e, i) {
      return $.trim(e);
    });
    if (content.length < 1) throw "Template syntax error";
    this.templateName = content[0].toLowerCase();
    content = content.splice(1);

    this.unnamedParams = $.grep(content, function(e, i) {
      return !e.match("=");
    });

    var named = $.grep(content, function(e, i) {
      return e.match("=");
    });
    var namedParams = {}
    $.each(named, function(i, e) {
      var a = e.indexOf("=");
      var name = $.trim(e.substr(0, a));
      var value = $.trim(e.substr(a + 1));
      namedParams[name] = value;
    });
    this.namedParams = namedParams;
  }

  /**
   * Sub-class of Template.  Additional methods: getTitle, getNumber,
   * getAirDate, getSummary.  They will return null if requested information is
   * unavailable.
   *
   * http://en.wikipedia.org/wiki/Template:Episode_list
   */
  function EpisodeList(content) {
    Template.call(this, content);
    if (!this.templateName.match(/^episode list/))
      throw "This is not an episode list template";

    var params = this.namedParams;

    this.getTitle = function() {
      if (params["Title"]) return removeMarkup(params["Title"]);
      if (params["RTitle"]) return removeMarkup(params["RTitle"]);
      return null;
    }

    this.getNumber = function() {
      if (params["EpisodeNumber2"])
        return removeMarkup(params["EpisodeNumber2"]);
      if (params["EpisodeNumber"])
        return removeMarkup(params["EpisodeNumber"]);
      return null;
    }

    this.getAirDate = function() {
      if (!params["OriginalAirDate"]) return null;
      try {
        var text = removeMarkup(params["OriginalAirDate"]);

        // Ignore extra shit people tend to place here
        var start = null, end, depth = 0, lastChar = " ";
        for (var i = 0; i < text.length; ++i) {
          var c = text[i];
          var d = depth;
          if ((lastChar ==  "{") && (c == "{"))
            if (++depth == 1) start = i - 1;
          if ((lastChar == "}") && (c == "}")) --depth;
          if ((depth == 0) && (start != null)) {
            end = i + 1;
            break;
          }
          if (d != depth) {
            lastChar = " ";
          } else {
            lastChar = c;
          }
        }

        return new StartDate(text.substring(start, end));
      } catch (e) {
        return null;
      }
    }

    this.getSummary = function() {
      if (!params["ShortSummary"]) {
        return null;
      }
      return removeMarkup(params["ShortSummary"]);
    }
  }

  /**
   * Sub-class of Template.  Provides year, month, day variables and toString
   * method.
   *
   * http://en.wikipedia.org/wiki/Template:Start_date
   */
  function StartDate(content) {
    Template.call(this, content);
    if (
      (!this.templateName.match(/^start date$/)) &&
      (!this.templateName.match(/^dts$/))
    ) {
      throw "This is not a start date template";
    }

    var params = this.unnamedParams, year, month = null, day = null;
    if (params.length < 1) {
      throw "Not enough parameters";
    }
    year = params[0];
    if (params.length >= 2) month = params[1];
    if (params.length >= 3) day = params[2];

    this.year = year;
    this.month = month;
    this.day = day;
    this.toString = function() {
      if (day !== null) {
        return year + "." + month + "." + day;
      }
      if (month !== null) {
        return year + "." + month;
      }
      return year;
    }
  }

  /**
   * Breaks down a MediaWiki article revision into sections.  Provides sections
   * variable.
   */
  function Article(content) {
    content = removeComments(content);
    var title =  "", step = true, sections = {};
    $.each(content.split(/==+([\s\S]+?)==+/), function(i, e) {
      if (step) sections[title] = e;
      else title = $.trim(e.toLowerCase());
      step = !step;
    });
    var names = content.match(/==+[\s\S]+?==+/g);
    if (names) {
      function sectionDepth(name) {
        return name.split("=").length - 1;
      }
      trimNames = $.map(names, function(e, i) {
        return $.trim(e.replace(/==+([\s\S]+?)==+/, "$1").toLowerCase());
      });
      // Adds sub-section contents to master sections.  O(n^2), could be O(n)
      for (var i = 0; i < names.length; ++i) {
        var depth = sectionDepth(names[i]);
        var j = i + 1;
        while ((j < names.length) && (sectionDepth(names[j]) > depth))
          sections[trimNames[i]] += sections[trimNames[j++]];
      }
    }
    this.sections = sections;
  }

  /**
   * Requests given article title from Wikipedia.  If request is successful it
   * runs given callback on the fetched article.
   */
  function getArticle(title, callback) {
    var url = "https://en.wikipedia.org/w/api.php?" +
      "format=json&callback=?&" +
      "action=query&prop=revisions&rvprop=content&redirects&titles=";
    $.ajax({
      dataType: "jsonp",
      url: url + title,
      success: function(data) {
        if (data.query.pages["-1"]) {
          progress_error();
        } else {
          var n;
          for (n in data.query.pages);
          callback(new Article(data.query.pages[n].revisions[0]["*"]));
        }
      },
      error: progress_error
    });
  }

  /**
   * All information about one TV series.  Provides seasons variables and toJSON
   * method.
   */
  function TVSeries(seasons) {
    this.seasons = seasons;
    this.toJSON = function() {
      function serialize(season) {
        return $.map(season, function(episode) {
          var airDate = episode.getAirDate();
          if (airDate != null) airDate = airDate.toString();
          return { number: episode.getNumber(),
                   title: episode.getTitle(),
                   air_date: airDate,
                   summary: episode.getSummary() };
        });
      }

      var data = {};
      for (season in seasons) {
        data[season] = serialize(seasons[season]);
      }
      return data;
    }
  }

  function getTVSeries(callback) {
    var seasonData = {};

    function finalize() {
      if (isSeasonDataEmpty()) {
        progress_error();
      } else {
        callback(new TVSeries(seasonData));
      }
    }

    function updateSeasonData(number, episodes) {
      // If there already is a season with this number then somebody is trying
      // to fuck us up.
      if ((episodes.length) && (seasonData[number] == null))
        seasonData[number] = episodes;
    }

    function isSeasonDataEmpty() {
      var empty = true;
      for (a in seasonData) empty = false;
      return empty;
    }

    function episodeSection(section) {
      return (section == "episodes") ||
        (section == "list of episodes") ||
        (section == "episode list") ||
        (episodes_keyword && section == episodes_keyword);
    }

    function seasonSection(section) {
      var m;
      if (season_keyword) {
        regex = new RegExp('^' + season_keyword + '\s*(\d+)[\s\S]*$');
        m = section.match(regex);
        if (m != null) return m[1];
      }
      m = section.match(/^season\s*(\d+)[\s\S]*$/);
      if (m != null) return m[1];
      m = section.match(/^series\s*(\d+)[\s\S]*$/);
      if (m != null) return m[1];
      return null;
    }

    // Episodes data without a season section
    function findOneSeason(article) {
      var success = false;
      for (section in article.sections) {
        if (episodeSection(section)) {
          var episodes = findTemplates(EpisodeList, article.sections[section]);
          updateSeasonData(1, episodes);
          success = true;
        }
      }
      if (!success) {
        progress_error();
      } else {
        finalize();
      }
    }

    function findBySeasons(article) {
      var sections = [];

      function processSections() {
        if (sections.length) {
          var section = sections.pop();
          var number = section[0];
          var section = section[1];
          var template = section.match(/$[\s\S]*?{{:([\s\S]*?)}}[\s\S]*/m);
          if (template != null) {
            // Episode list in a separate article
            template = $.trim(template[1]);
            getArticle(template, function(a) {
              for (section in a.sections) {
                if (episodeSection(section)) {
                  var episodes = findTemplates(EpisodeList, a.sections[section]);
                  updateSeasonData(number, episodes);
                }
              }
              processSections();
            });
          } else {
            var episodes = findTemplates(EpisodeList, section);
            updateSeasonData(number, episodes);
            processSections();
          }
        } else {
          if (isSeasonDataEmpty()) {
            findOneSeason(article);
          } else {
            finalize();
          }
        }
      }

      for (section in article.sections) {
        var number = seasonSection(section);
        if (number != null) {
          sections.push([number, article.sections[section]]);
        }
      }
      processSections();
    }

    getArticle(episodes_article, function(article) {
      findBySeasons(article);
    });
  }

  // Public methods.
  return { getTVSeries: getTVSeries };
}
<|endoftext|>


<commit_before>/* global $:false */
/* global document:false */
/* global alert:false */

$(document).ready(function(event) {
  $.ajax("http://ccmtdev08.canyonco.org/Election/ElectionResultDetails", {
    success: function(data) {
      if (!data.Error) {
        //alert(data.Results.PartyName.length);
        drawResults(data);

        $(".tabs .tab-links a").on("click",function(e){
          var t=$(this).attr("href");
          $(t).fadeIn(400).siblings().hide();
          $(this).parent("li").addClass("active").siblings().removeClass("active");
          e.preventDefault();
        });

      } else {
        alert("Result Details Error: " + data.Error);
        $(".electionContainer").hide();
      }
    },
    error: function(err) {
      alert("Error: " + err.status + " " + err.statusText + " " + err.responseText);
      $(".electionContainer").hide();
    }
  });

});

var drawResults = function(data) {
  $.each(data.Results, function(index, row) {
    //$('<input/>', {'value':JSON.stringify(row), attr:{size: "775"}}).appendTo("#electionDetails");
    drawParty(row, index);
    drawContests(row);
  });
};

var drawParty = function(data, index) {
  if (data) {
    var cls="";
    if (index === 0) cls = "active";

    // tabs
    var link = $("", {'href':"#" + partyLinkName(data.PartyName), 'text':partyTabName(data.PartyName)});
    $("
", {'html':link}).addClass(cls).appendTo("#party-tabs");

    // content...
    $("
").attr('id',partyLinkName(data.PartyName)).addClass("tab " + cls).appendTo("#party-content");
  }
};

var drawContests = function(data) {
  var partyTab = "#" + partyLinkName(data.PartyName);
  $.each(data.Contests, function(index, row) {
    //alert(JSON.stringify(row));
    //$('<input/>', {'value':row.Name, attr:{size: "75"}}).appendTo("#electionDetails");
    $('
').appendTo(partyTab);
    $('<input/>', {'value':row.Name, attr:{size: "75"}}).appendTo(partyTab);
    $('
').appendTo(partyTab);
    drawChoices(row, partyTab);
  });
  $('
').appendTo(partyTab);
};

var drawChoices = function(data, tab) {
  $.each(data.Choices, function(index, row) {
    $('<input/>', {'value':row.Name, attr:{size: "30"}}).appendTo(tab);
    $('<input/>', {'value':row.VoteCount, attr:{size: "30"}}).appendTo(tab);
    $('<input/>', {'value':row.Percentage, attr:{size: "30"}}).appendTo(tab);
    $('
').appendTo(tab);
  });
};

var capitalizeFirstLetter = function(word) {
  var first = word[0] || "";
  var rest = word.substring(1);

  return first.toUpperCase() + rest;
};

var partyTabName = function(word) {
  word = word.toLowerCase() || "results";
  return capitalizeFirstLetter(word.split(' ')[0]);
};

var partyLinkName = function(word) {
  word = word.toLowerCase() || "results";
  return word.substring(0,3);
};<commit_msg>wrong server<commit_after>/* global $:false */
/* global document:false */
/* global alert:false */

$(document).ready(function(event) {
  $.ajax("http://ccmtprod08.canyonco.org/Election/ElectionResultDetails", {
    success: function(data) {
      if (!data.Error) {
        //alert(data.Results.PartyName.length);
        drawResults(data);

        $(".tabs .tab-links a").on("click",function(e){
          var t=$(this).attr("href");
          $(t).fadeIn(400).siblings().hide();
          $(this).parent("li").addClass("active").siblings().removeClass("active");
          e.preventDefault();
        });

      } else {
        alert("Result Details Error: " + data.Error);
        $(".electionContainer").hide();
      }
    },
    error: function(err) {
      alert("Error: " + err.status + " " + err.statusText + " " + err.responseText);
      $(".electionContainer").hide();
    }
  });

});

var drawResults = function(data) {
  $.each(data.Results, function(index, row) {
    //$('<input/>', {'value':JSON.stringify(row), attr:{size: "775"}}).appendTo("#electionDetails");
    drawParty(row, index);
    drawContests(row);
  });
};

var drawParty = function(data, index) {
  if (data) {
    var cls="";
    if (index === 0) cls = "active";

    // tabs
    var link = $("", {'href':"#" + partyLinkName(data.PartyName), 'text':partyTabName(data.PartyName)});
    $("
", {'html':link}).addClass(cls).appendTo("#party-tabs");

    // content...
    $("
").attr('id',partyLinkName(data.PartyName)).addClass("tab " + cls).appendTo("#party-content");
  }
};

var drawContests = function(data) {
  var partyTab = "#" + partyLinkName(data.PartyName);
  $.each(data.Contests, function(index, row) {
    //alert(JSON.stringify(row));
    //$('<input/>', {'value':row.Name, attr:{size: "75"}}).appendTo("#electionDetails");
    $('
').appendTo(partyTab);
    $('<input/>', {'value':row.Name, attr:{size: "75"}}).appendTo(partyTab);
    $('
').appendTo(partyTab);
    drawChoices(row, partyTab);
  });
  $('
').appendTo(partyTab);
};

var drawChoices = function(data, tab) {
  $.each(data.Choices, function(index, row) {
    $('<input/>', {'value':row.Name, attr:{size: "30"}}).appendTo(tab);
    $('<input/>', {'value':row.VoteCount, attr:{size: "30"}}).appendTo(tab);
    $('<input/>', {'value':row.Percentage, attr:{size: "30"}}).appendTo(tab);
    $('
').appendTo(tab);
  });
};

var capitalizeFirstLetter = function(word) {
  var first = word[0] || "";
  var rest = word.substring(1);

  return first.toUpperCase() + rest;
};

var partyTabName = function(word) {
  word = word.toLowerCase() || "results";
  return capitalizeFirstLetter(word.split(' ')[0]);
};

var partyLinkName = function(word) {
  word = word.toLowerCase() || "results";
  return word.substring(0,3);
};<|endoftext|>


<commit_before>/**
 * Provides a base class for anything wrapping a text input.
 */
wesabe.$class('wesabe.views.widgets.BaseField', wesabe.views.widgets.BaseWidget, function($class, $super, $package) {
  // import jQuery as $
  var $ = jQuery;

  $class.DOM_EVENT_MAP = {
    keydown: 'onKeyDown', keypress: 'onKeyPress', keyup: 'onKeyUp',
    blur: 'onBlur', focus: 'onFocus',
    change: 'onChange', pollingchange: 'onPollingChange'};

  $.extend($class.prototype, {
    _value: null,
    _changeWatcher: null,

    init: function(element, delegate) {
      var me = this;

      $super.init.call(me, element);

      // bind the events that subclasses or delegates declare themselves interested in
      var delegates = [me];
      if (delegate) delegates.push(delegate);

      var domBindings = {};

      $.each($class.DOM_EVENT_MAP, function(key, method) {
        domBindings[method] = 0;
        $.each(delegates, function(i, d) {
          if (d[method]) {
            element.bind(key, function(event){ d[method].call(d, event, me) });
            domBindings[method]++;
          }
        });
      });

      if (domBindings.onPollingChange > 0)
        this._startWatchingForChanges();

      element.attr('autocomplete', 'off');
    },

    getValue: function() {
      return this.getElement().val();
    },

    setValue: function(value) {
      this.getElement().val(value);
    },

    getName: function() {
      return this.getElement().attr('name');
    },

    setName: function(name) {
      this.getElement().attr('name', name);
    },

    isEnabled: function() {
      return !this.getElement().attr('disabled');
    },

    setEnabled: function(enabled) {
      this.getElement().attr('disabled', !enabled);
      if (!enabled)
        this.blur();
    },

    clear: function() {
      this.getElement().val('');
    },

    focus: function() {
      var element = this.getElement();
      if (element.length) element[0].focus();
    },

    blur: function() {
      this.getElement().blur();
    },

    clearAndBlur: function() {
      this.clear();
      this.blur();
    },

    isEmpty: function() {
      return !this.getElement().val();
    },

    selectAllAndFocus: function() {
      var element = this.getElement();
      element.caret(0, element.val().length);
      this.focus();
    },

    _startWatchingForChanges: function(msToWait) {
      var me = this;
      me._value = me.getValue();
      (function() {
        if (me._value !== me.getValue()) {
          me._value = me.getValue();
          me.getElement().trigger('pollingchange');
        }
        me._changeWatcher = setTimeout(arguments.callee, msToWait || 50);
      })();
    },

    _stopWatchingForChanges: function() {
      clearTimeout(this._changeWatcher);
    },

    destroy: function() {
      this._stopWatchingForChanges();
      $super.destroy.apply(this, arguments);
    }
  });
});
<commit_msg>Allow BaseFields to create their own elements.<commit_after>/**
 * Provides a base class for anything wrapping a text input.
 */
wesabe.$class('wesabe.views.widgets.BaseField', wesabe.views.widgets.BaseWidget, function($class, $super, $package) {
  // import jQuery as $
  var $ = jQuery;

  $class.DOM_EVENT_MAP = {
    keydown: 'onKeyDown', keypress: 'onKeyPress', keyup: 'onKeyUp',
    blur: 'onBlur', focus: 'onFocus',
    change: 'onChange', pollingchange: 'onPollingChange'};

  $.extend($class.prototype, {
    _value: null,
    _changeWatcher: null,

    init: function(element, delegate) {
      var me = this;

      if (!element)
        element = $('<input type="text">');

      $super.init.call(me, element);

      // bind the events that subclasses or delegates declare themselves interested in
      var delegates = [me];
      if (delegate) delegates.push(delegate);

      var domBindings = {};

      $.each($class.DOM_EVENT_MAP, function(key, method) {
        domBindings[method] = 0;
        $.each(delegates, function(i, d) {
          if (d[method]) {
            element.bind(key, function(event){ d[method].call(d, event, me) });
            domBindings[method]++;
          }
        });
      });

      if (domBindings.onPollingChange > 0)
        this._startWatchingForChanges();

      element.attr('autocomplete', 'off');
    },

    getValue: function() {
      return this.getElement().val();
    },

    setValue: function(value) {
      this.getElement().val(value);
    },

    getName: function() {
      return this.getElement().attr('name');
    },

    setName: function(name) {
      this.getElement().attr('name', name);
    },

    isEnabled: function() {
      return !this.getElement().attr('disabled');
    },

    setEnabled: function(enabled) {
      this.getElement().attr('disabled', !enabled);
      if (!enabled)
        this.blur();
    },

    clear: function() {
      this.getElement().val('');
    },

    focus: function() {
      var element = this.getElement();
      if (element.length) element[0].focus();
    },

    blur: function() {
      this.getElement().blur();
    },

    clearAndBlur: function() {
      this.clear();
      this.blur();
    },

    isEmpty: function() {
      return !this.getElement().val();
    },

    selectAllAndFocus: function() {
      var element = this.getElement();
      element.caret(0, element.val().length);
      this.focus();
    },

    _startWatchingForChanges: function(msToWait) {
      var me = this;
      me._value = me.getValue();
      (function() {
        if (me._value !== me.getValue()) {
          me._value = me.getValue();
          me.getElement().trigger('pollingchange');
        }
        me._changeWatcher = setTimeout(arguments.callee, msToWait || 50);
      })();
    },

    _stopWatchingForChanges: function() {
      clearTimeout(this._changeWatcher);
    },

    destroy: function() {
      this._stopWatchingForChanges();
      $super.destroy.apply(this, arguments);
    }
  });
});
<|endoftext|>


<commit_before>define([
    'jquery',
    'fancytree',
    'uicontextmenu',
    'underscore',
    'backbone',
    'app',
    'views/navigationtree/NavigationTreeView'
], function($, fancytree, uicontextmenu, _, Backbone, app, NavigationTreeView) {

    var NavigationTreeView = Backbone.View.extend({

        initialize: function(options) {
            _.bindAll(this, 'render', 'convertToTree', 'sortCmp', 'getNodeHref', 'getNodeIcon');

            this.projectId = 0;

            if (typeof options !== typeof undefined && typeof options.draggable !== typeof undefined) {
                this.draggable = options.draggable;
            } else {
                this.draggable = false;
            }

            if (typeof options !== typeof undefined && typeof options.checkboxes !== typeof undefined) {
                this.checkboxes = options.checkboxes;
            } else {
                this.checkboxes = false;
            }

            this.rootNodeUrl = options.rootNodeUrl;
            this.nodeUrlPrefix = options.nodeUrlPrefix;

            this.nodeUrlSuffix = '/view';
            if (typeof options !== typeof undefined && typeof options.nodeUrlSuffix !== typeof undefined) {
                this.nodeUrlSuffix = options.nodeUrlSuffix;
            }

            this.collection = options.collection;
        },

        events: {

        },

        getNodeHref: function(node, parent, nodeUrlPrefix) {
            var url = nodeUrlPrefix + '/testsuites/';
            if (parseInt(node.node_type_id) === 2) {
                url += node.node_id + this.nodeUrlSuffix;
            } else {
                url += parent.node_id + '/testcases/' + node.node_id + this.nodeUrlSuffix;
            }
            return url;
        },

        getNodeIcon: function(node) {
            if (node != null) {
                if (typeof node.attributes !== typeof undefined && node.attributes !== null) {
                    var attributes = JSON.parse(node.attributes);
                    if (typeof attributes.execution_type_id !== typeof undefined) {
                        if (parseInt(attributes.execution_type_id) === 2) {
                            return '/icons/robot-icon.png';
                        }
                    }
                }
            }
            return true;
        },

        convertToTree: function(parent, children, nodeUrlPrefix, selected) {
            for (idx in children) {
                var child = children[idx];
                var folder = parseInt(child.node_type_id) === 3 ? false : true;
                var node = {
                    title: child.display_name,
                    key: child.descendant,
                    folder: folder,
                    expanded: true,
                    children: [],
                    node_id: child.node_id,
                    node_type_id: child.node_type_id,
                    href: this.getNodeHref(child, parent, nodeUrlPrefix),
                    icon: this.getNodeIcon(child)
                };
                parent.children.push(node);
                this.convertToTree(node, child.children, nodeUrlPrefix,selected);
            }

            // Only test cases can be selected... in the database at least.
            if (parent.node_type_id == 3) {
                for (entry in selected) {
                    if (selected[entry]['test_cases_id'] == parent.node_id) {
                        parent.selected = true;
                        parent.preselected = true;
                    }
                }
            }
        },

        /**
         * Used by FancyTree, after a node is moved. This is the sort comparator to organise
         * the nodes within the tree.
         */
        sortCmp: function(a, b) {
            var x = a.data.node_type_id + a.title.toLowerCase(),
                y = b.data.node_type_id + b.title.toLowerCase();
            return x === y ? 0 : x > y ? 1 : -1;
        },

        render: function(options) {
            console.log('Rendering navigation tree for project ID [' + this.projectId + ']');
            var el = options.el;
            var selected = [];
            if (typeof options.selected !== typeof undefined) {
                selected = options.selected;
            }
            var self = this;
            var nodeObject = this.collection.get(this.projectId);
            var model = nodeObject.toJSON();

            tree = [];
            var node = {
                title: model.display_name,
                key: model.descendant,
                folder: true,
                expanded: true,
                children: [],
                node_id: model.node_id,
                node_type_id: model.node_type_id,
                href: self.rootNodeUrl,
                icon: true,
                selected: false,
                preselected: false
            };
            self.convertToTree(node, model.children, self.nodeUrlPrefix, selected);
            tree.push(node);

            // --- check boxes
            var checkbox = self.checkboxes;
            var selectMode = 1;
            if (checkbox) {
                selectMode = 3;
            }
            // --- end check boxes

            // --- drag and drop
            var extensions = [];
            var dnd = {};
            // enable drag and drop
            if (self.draggable) {
                extensions.push('dnd');
                dnd = {
                    preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
                    preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
                    autoExpandMS: 400,
                    dragStart: function(node, data) {
                        // Defines whether this node is draggable or not
                        // The top level project should have dnd disabled
                        if (node.data.node_type_id == 1) {
                            return false;
                        }
                        return true;
                    },
                    dragStop: function(node, data) {

                    },
                    dragOver: function(node, data) {
                    },
                    dragEnter: function(node, data) {
                        // Defines whether another node can be dragged on this node
                        // Return ['before', 'after'] to restrict available hitModes.
                        // Any other return value will calc the hitMode from the cursor position.
                        // Prevent dropping a parent below another parent (only sort
                        // nodes under the same parent)
                        // if(node.parent !== data.otherNode.parent){
                        //   return false;
                        // }
                        // Don't allow dropping *over* a node (would create a child)
                        // return ["before", "after"];

                        var selectedNode = data.otherNode; // the selected node
                        if (selectedNode.data.node_type_id == 3) {
                            // Test cases should not be dnd onto projects or test cases, only test suites
                            if (node.data.node_type_id != 2) {
                                return false;
                            }
                            // Test cases should not be dnd onto its own parent
                            if (node == selectedNode.parent) {
                                return false;
                            }
                        }
                        if (selectedNode.data.node_type_id == 2) {
                            // Test suites should not be dnd onto test cases
                            if (node.data.node_type_id == 3) {
                                return false;
                            }
                            // Test suites should not be dnd onto its own parent
                            if (node == selectedNode.parent) {
                                return false;
                            }
                        }
                        return "over";
                    },
                    dragDrop: function(node, data) {
                        var selectedNode = data.otherNode; // the selected node
                        var descendant = '' + selectedNode.data.node_type_id + '-' + selectedNode.data.node_id;
                        var ancestor = '' + node.data.node_type_id + '-' + node.data.node_id;
                        var url = "/api/navigationtree/move";
                        $.ajax({
                          type: "POST",
                          url: url,
                          data: {descendant: descendant, ancestor: ancestor},
                          success: function(jqXHR, textStatus, data) {
                            selectedNode.moveTo(node, jqXHR.hitMode);
                            var rootNode = node.tree.rootNode;
                            rootNode.sortChildren(self.sortCmp, true);
                            app.showAlert('Success!', 'Moved successfully!', 'success');
                          },
                          error: function(jqXHR, textStatus, data) {
                            var responseText = jQuery.parseJSON(jqXHR.responseText);
                            var message = responseText.error.message;
                            app.showAlert('Error moving!', message, 'error');
                          }
                        });
                    },
                    dragLeave: function(node, data) {
                    }
                }
            };
            // --- end of drag and drop

            el.fancytree('destroy');
            el.fancytree({
                source: tree,
                extensions: extensions,
                activeVisible: true, // Make sure, active nodes are visible (expanded).
                aria: false, // Enable WAI-ARIA support.
                autoActivate: true, // Automatically activate a node when it is focused (using keys).
                autoCollapse: false, // Automatically collapse all siblings, when a node is expanded.
                autoScroll: false, // Automatically scroll nodes into visible area.
                clickFolderMode: 1, // 1:activate, 2:expand, 3:activate and expand, 4:activate (dblclick expands)
                checkbox: checkbox, // Show checkboxes.
                debugLevel: 1, // 0:quiet, 1:normal, 2:debug
                disabled: false, // Disable control
                generateIds: true, // Generate id attributes like
                idPrefix: "ft_", // Used to generate node id´s like <span id='fancytree-id-<key>'>.
                icon: true, // Display node icons.
                keyboard: true, // Support keyboard navigation.
                keyPathSeparator: "/", // Used by node.getKeyPath() and tree.loadKeyPath().
                minExpandLevel: 2, // 1: root node is not collapsible
                selectMode: selectMode, // 1:single, 2:multi, 3:multi-hier
                tabindex: 0, // Whole tree behaves as one single control
                childcounter: {
                    deep: true,
                    hideZeros: true,
                    hideExpanded: true
                },
                focus: function(e, data) {
                    var node = data.node;
                    // Auto-activate focused node after 1 second
                    if(node.data.href){
                        node.scheduleAction("activate", 100000);
                    }
                },
                blur: function(e, data) {
                    data.node.scheduleAction("cancel");
                },
                activate: function(e, data) {
                    if (data.draggable)
                        return; // prevent false hits
                    var node = data.node;
                    if(node.data.href){
                        Backbone.history.navigate(node.data.href, { trigger: false });
                    }
                },
                click: function(e, data) { // allow re-loads
                    var node = data.node;
                    if(node.isActive() && node.data.href){
                        // TODO: data.tree.reactivate();
                    }
                },
                // https://github.com/mar10/fancytree/issues/581
                init: function (e, data) {
                    data.tree.getRootNode().visit(function (node) {
                        if (node.data.preselected) node.setSelected(true);
                    });
                },
                dnd: dnd
            });
            // end
            var rootNode = el.fancytree('getRootNode');
            if (typeof rootNode.sortChildren !== typeof undefined) {
                rootNode.sortChildren(self.sortCmp, true);
            }

            // context menu
            el.contextmenu({
                delegate: ".fancytree-node",
                menu: [
                    {
                        title: "Edit",
                        cmd: "edit",
                        uiIcon: "ui-icon-pencil"
                    },
                    {
                        title: "Delete",
                        cmd: "delete",
                        uiIcon: "ui-icon-trash"
                    }
                ],
                select: function(event, ui) {
                    var nodeId = ui.target[0].parentNode.parentNode.id;
                    var underscoreIndex = nodeId.indexOf('_');
                    if (underscoreIndex > 0) {
                        var length = nodeId.length;
                        var key = nodeId.substring(underscoreIndex+1, length);
                        var node = el.fancytree('getNodeByKey', key);
                        var href = node.data.href;
                        if (ui.cmd == 'edit') {
                            var editHref = href.substring(0, href.length - 5);
                            Backbone.history.navigate(editHref, {
                                trigger: false
                            });
                        } else if (ui.cmd == 'delete') {
                            var editHref = href.substring(0, href.length - 5);
                            var deleteHref = editHref + '/confirmDelete';
                            Backbone.history.navigate(deleteHref, {
                                trigger: false
                            });
                        } else {
                            console.log('Command ' + ui.cmd + ' not recognized!');
                        }
                    }
                }
            });

            this.delegateEvents();
        }

    });

    return NavigationTreeView;

});<commit_msg>Commenting code is good<commit_after>define([
    'jquery',
    'fancytree',
    'uicontextmenu',
    'underscore',
    'backbone',
    'app',
    'views/navigationtree/NavigationTreeView'
], function($, fancytree, uicontextmenu, _, Backbone, app, NavigationTreeView) {

    var NavigationTreeView = Backbone.View.extend({

        initialize: function(options) {
            _.bindAll(this, 'render', 'convertToTree', 'sortCmp', 'getNodeHref', 'getNodeIcon');

            this.projectId = 0;

            if (typeof options !== typeof undefined && typeof options.draggable !== typeof undefined) {
                this.draggable = options.draggable;
            } else {
                this.draggable = false;
            }

            if (typeof options !== typeof undefined && typeof options.checkboxes !== typeof undefined) {
                this.checkboxes = options.checkboxes;
            } else {
                this.checkboxes = false;
            }

            this.rootNodeUrl = options.rootNodeUrl;
            this.nodeUrlPrefix = options.nodeUrlPrefix;

            this.nodeUrlSuffix = '/view';
            if (typeof options !== typeof undefined && typeof options.nodeUrlSuffix !== typeof undefined) {
                this.nodeUrlSuffix = options.nodeUrlSuffix;
            }

            this.collection = options.collection;
        },

        events: {

        },

        getNodeHref: function(node, parent, nodeUrlPrefix) {
            var url = nodeUrlPrefix + '/testsuites/';
            if (parseInt(node.node_type_id) === 2) {
                url += node.node_id + this.nodeUrlSuffix;
            } else {
                url += parent.node_id + '/testcases/' + node.node_id + this.nodeUrlSuffix;
            }
            return url;
        },

        getNodeIcon: function(node) {
            if (node != null) {
                if (typeof node.attributes !== typeof undefined && node.attributes !== null) {
                    var attributes = JSON.parse(node.attributes);
                    if (typeof attributes.execution_type_id !== typeof undefined) {
                        if (parseInt(attributes.execution_type_id) === 2) {
                            return '/icons/robot-icon.png';
                        }
                    }
                }
            }
            return true;
        },

        convertToTree: function(parent, children, nodeUrlPrefix, selected) {
            for (idx in children) {
                var child = children[idx];
                var folder = parseInt(child.node_type_id) === 3 ? false : true;
                var node = {
                    title: child.display_name,
                    key: child.descendant,
                    folder: folder,
                    expanded: true,
                    children: [],
                    node_id: child.node_id,
                    node_type_id: child.node_type_id,
                    href: this.getNodeHref(child, parent, nodeUrlPrefix),
                    icon: this.getNodeIcon(child)
                };
                parent.children.push(node);
                this.convertToTree(node, child.children, nodeUrlPrefix,selected);
            }

            // Only test cases can be selected... in the database at least.
            if (parent.node_type_id == 3) {
                for (entry in selected) {
                    if (selected[entry]['test_cases_id'] == parent.node_id) {
                        parent.selected = true;
                        parent.preselected = true;
                    }
                }
            }
        },

        /**
         * Used by FancyTree, after a node is moved. This is the sort comparator to organise
         * the nodes within the tree.
         */
        sortCmp: function(a, b) {
            var x = a.data.node_type_id + a.title.toLowerCase(),
                y = b.data.node_type_id + b.title.toLowerCase();
            return x === y ? 0 : x > y ? 1 : -1;
        },

        render: function(options) {
            console.log('Rendering navigation tree for project ID [' + this.projectId + ']');
            var el = options.el;
            var selected = [];
            if (typeof options.selected !== typeof undefined) {
                selected = options.selected;
            }
            var self = this;
            var nodeObject = this.collection.get(this.projectId);
            var model = nodeObject.toJSON();

            tree = [];
            var node = {
                title: model.display_name,
                key: model.descendant,
                folder: true,
                expanded: true,
                children: [],
                node_id: model.node_id,
                node_type_id: model.node_type_id,
                href: self.rootNodeUrl,
                icon: true,
                selected: false,
                preselected: false
            };
            self.convertToTree(node, model.children, self.nodeUrlPrefix, selected);
            tree.push(node);

            // --- check boxes
            var checkbox = self.checkboxes;
            var selectMode = 1;
            if (checkbox) {
                selectMode = 3;
            }
            // --- end check boxes

            // --- drag and drop
            var extensions = [];
            var dnd = {};
            // enable drag and drop
            if (self.draggable) {
                extensions.push('dnd');
                dnd = {
                    preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
                    preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
                    autoExpandMS: 400,
                    dragStart: function(node, data) {
                        // Defines whether this node is draggable or not
                        // The top level project should have dnd disabled
                        if (node.data.node_type_id == 1) {
                            return false;
                        }
                        return true;
                    },
                    dragStop: function(node, data) {

                    },
                    dragOver: function(node, data) {
                    },
                    dragEnter: function(node, data) {
                        // Defines whether another node can be dragged on this node
                        // Return ['before', 'after'] to restrict available hitModes.
                        // Any other return value will calc the hitMode from the cursor position.
                        // Prevent dropping a parent below another parent (only sort
                        // nodes under the same parent)
                        // if(node.parent !== data.otherNode.parent){
                        //   return false;
                        // }
                        // Don't allow dropping *over* a node (would create a child)
                        // return ["before", "after"];

                        var selectedNode = data.otherNode; // the selected node
                        if (selectedNode.data.node_type_id == 3) {
                            // Test cases should not be dnd onto projects or test cases, only test suites
                            if (node.data.node_type_id != 2) {
                                return false;
                            }
                            // Test cases should not be dnd onto its own parent
                            if (node == selectedNode.parent) {
                                return false;
                            }
                        }
                        if (selectedNode.data.node_type_id == 2) {
                            // Test suites should not be dnd onto test cases
                            if (node.data.node_type_id == 3) {
                                return false;
                            }
                            // Test suites should not be dnd onto its own parent
                            if (node == selectedNode.parent) {
                                return false;
                            }
                        }
                        return "over";
                    },
                    dragDrop: function(node, data) {
                        var selectedNode = data.otherNode; // the selected node
                        var descendant = '' + selectedNode.data.node_type_id + '-' + selectedNode.data.node_id;
                        var ancestor = '' + node.data.node_type_id + '-' + node.data.node_id;
                        var url = "/api/navigationtree/move";
                        $.ajax({
                          type: "POST",
                          url: url,
                          data: {descendant: descendant, ancestor: ancestor},
                          success: function(jqXHR, textStatus, data) {
                            selectedNode.moveTo(node, jqXHR.hitMode);
                            var rootNode = node.tree.rootNode;
                            rootNode.sortChildren(self.sortCmp, true);
                            app.showAlert('Success!', 'Moved successfully!', 'success');
                          },
                          error: function(jqXHR, textStatus, data) {
                            var responseText = jQuery.parseJSON(jqXHR.responseText);
                            var message = responseText.error.message;
                            app.showAlert('Error moving!', message, 'error');
                          }
                        });
                    },
                    dragLeave: function(node, data) {
                    }
                }
            };
            // --- end of drag and drop

            el.fancytree('destroy');
            el.fancytree({
                source: tree,
                extensions: extensions,
                activeVisible: true, // Make sure, active nodes are visible (expanded).
                aria: false, // Enable WAI-ARIA support.
                autoActivate: true, // Automatically activate a node when it is focused (using keys).
                autoCollapse: false, // Automatically collapse all siblings, when a node is expanded.
                autoScroll: false, // Automatically scroll nodes into visible area.
                clickFolderMode: 1, // 1:activate, 2:expand, 3:activate and expand, 4:activate (dblclick expands)
                checkbox: checkbox, // Show checkboxes.
                debugLevel: 1, // 0:quiet, 1:normal, 2:debug
                disabled: false, // Disable control
                generateIds: true, // Generate id attributes like
                idPrefix: "ft_", // Used to generate node id´s like <span id='fancytree-id-<key>'>.
                icon: true, // Display node icons.
                keyboard: true, // Support keyboard navigation.
                keyPathSeparator: "/", // Used by node.getKeyPath() and tree.loadKeyPath().
                minExpandLevel: 2, // 1: root node is not collapsible
                selectMode: selectMode, // 1:single, 2:multi, 3:multi-hier
                tabindex: 0, // Whole tree behaves as one single control
                childcounter: {
                    deep: true,
                    hideZeros: true,
                    hideExpanded: true
                },
                focus: function(e, data) {
                    var node = data.node;
                    // Auto-activate focused node after 1 second
                    if(node.data.href){
                        node.scheduleAction("activate", 100000);
                    }
                },
                blur: function(e, data) {
                    data.node.scheduleAction("cancel");
                },
                activate: function(e, data) {
                    if (data.draggable)
                        return; // prevent false hits
                    var node = data.node;
                    if(node.data.href){
                        Backbone.history.navigate(node.data.href, { trigger: false });
                    }
                },
                click: function(e, data) { // allow re-loads
                    var node = data.node;
                    if(node.isActive() && node.data.href){
                        // TODO: data.tree.reactivate();
                    }
                },
                // https://github.com/mar10/fancytree/issues/581
                init: function (e, data) {
                    data.tree.getRootNode().visit(function (node) {
                        if (node.data.preselected) node.setSelected(true);
                    });
                },
                dnd: dnd
            });
            // end
            var rootNode = el.fancytree('getRootNode');
            if (typeof rootNode.sortChildren !== typeof undefined) {
                rootNode.sortChildren(self.sortCmp, true);
            }

            // context menu
            el.contextmenu({
                delegate: ".fancytree-node",
                menu: [
                    {
                        title: "Edit",
                        cmd: "edit",
                        uiIcon: "ui-icon-pencil"
                    },
                    {
                        title: "Delete",
                        cmd: "delete",
                        uiIcon: "ui-icon-trash"
                    }
                ],
                select: function(event, ui) {
                    var nodeId = ui.target[0].parentNode.parentNode.id;
                    // fancy tree HTML elements have the key as ft_$KEY
                    var underscoreIndex = nodeId.indexOf('_');
                    if (underscoreIndex > 0) {
                        var length = nodeId.length;
                        var key = nodeId.substring(underscoreIndex+1, length);
                        var node = el.fancytree('getNodeByKey', key);
                        var href = node.data.href;
                        if (ui.cmd == 'edit') {
                            var editHref = href.substring(0, href.length - 5);
                            Backbone.history.navigate(editHref, {
                                trigger: false
                            });
                        } else if (ui.cmd == 'delete') {
                            var editHref = href.substring(0, href.length - 5);
                            var deleteHref = editHref + '/confirmDelete';
                            Backbone.history.navigate(deleteHref, {
                                trigger: false
                            });
                        } else {
                            console.log('Command ' + ui.cmd + ' not recognized!');
                        }
                    }
                }
            });

            this.delegateEvents();
        }

    });

    return NavigationTreeView;

});<|endoftext|>


<commit_before>import debounce from 'lodash.debounce'
import { createAction } from 'redux-actions'

import { planTrip } from './api'
import { queryIsValid } from '../util/state'

export const settingMode = createAction('SET_MODE')
export const settingDepart = createAction('SET_DEPART')
export const settingDate = createAction('SET_DATE')
export const settingTime = createAction('SET_TIME')
export const changingForm = createAction('FORM_CHANGED')

export function setMode (payload) {
  return function (dispatch, getState) {
    dispatch(settingMode(payload))
    dispatch(formChanged())
  }
}

export function setDepart (payload) {
  return function (dispatch, getState) {
    dispatch(settingDepart(payload))
    dispatch(formChanged())
  }
}

export function setDate (payload) {
  return function (dispatch, getState) {
    dispatch(settingDate(payload))
    dispatch(formChanged())
  }
}

export function setTime (payload) {
  return function (dispatch, getState) {
    dispatch(settingTime(payload))
    dispatch(formChanged())
  }
}

let debouncedPlanTrip  // store as global, so it can be reused.  Maybe there's a better way?

export function formChanged () {
  return function (dispatch, getState) {
    dispatch(changingForm())
    const otpState = getState().otp
    const {autoPlan, debouncePlanTimeMs} = otpState.config
    if (autoPlan && queryIsValid(otpState)) {
      if (!debouncedPlanTrip) {
        debouncedPlanTrip = debounce(() => dispatch(planTrip()), debouncePlanTimeMs)
      }
      debouncedPlanTrip()
    }
  }
}
<commit_msg>refactor(form): update debounce upon state change<commit_after>import debounce from 'lodash.debounce'
import { createAction } from 'redux-actions'

import { planTrip } from './api'
import { queryIsValid } from '../util/state'

export const settingMode = createAction('SET_MODE')
export const settingDepart = createAction('SET_DEPART')
export const settingDate = createAction('SET_DATE')
export const settingTime = createAction('SET_TIME')
export const changingForm = createAction('FORM_CHANGED')

export function setMode (payload) {
  return function (dispatch, getState) {
    dispatch(settingMode(payload))
    dispatch(formChanged())
  }
}

export function setDepart (payload) {
  return function (dispatch, getState) {
    dispatch(settingDepart(payload))
    dispatch(formChanged())
  }
}

export function setDate (payload) {
  return function (dispatch, getState) {
    dispatch(settingDate(payload))
    dispatch(formChanged())
  }
}

export function setTime (payload) {
  return function (dispatch, getState) {
    dispatch(settingTime(payload))
    dispatch(formChanged())
  }
}

let debouncedPlanTrip  // store as variable here, so it can be reused.
let lastDebouncePlanTimeMs

export function formChanged () {
  return function (dispatch, getState) {
    dispatch(changingForm())
    const otpState = getState().otp
    const {autoPlan, debouncePlanTimeMs} = otpState.config
    if (autoPlan && queryIsValid(otpState)) {
      if (!debouncedPlanTrip || lastDebouncePlanTimeMs !== debouncePlanTimeMs) {
        debouncedPlanTrip = debounce(() => dispatch(planTrip()), debouncePlanTimeMs)
        lastDebouncePlanTimeMs = debouncePlanTimeMs
      }
      debouncedPlanTrip()
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

// Setting up route
angular.module('articles').config(['$stateProvider',
	function($stateProvider) {
		// Articles state routing
		$stateProvider.
		state('listEvents', {
			url: '/events',
			templateUrl: 'modules/events/views/list-events.client.view.html'
		}).
		state('createEvent', {
			url: '/events/create',
			templateUrl: 'modules/events/views/create-event.client.view.html'
		}).
		state('viewEvent', {
			url: '/events/:eventId',
			templateUrl: 'modules/events/views/view-event.client.view.html'
		}).
		state('editEvent', {
			url: '/events/:eventId/edit',
			templateUrl: 'modules/events/views/edit-event.client.view.html'
		});
	}
]);<commit_msg>some remanants of articles<commit_after>'use strict';

// Setting up route
angular.module('events').config(['$stateProvider',
	function($stateProvider) {
		// Events state routing
		$stateProvider.
		state('listEvents', {
			url: '/events',
			templateUrl: 'modules/events/views/list-events.client.view.html'
		}).
		state('createEvent', {
			url: '/events/create',
			templateUrl: 'modules/events/views/create-event.client.view.html'
		}).
		state('viewEvent', {
			url: '/events/:eventId',
			templateUrl: 'modules/events/views/view-event.client.view.html'
		}).
		state('editEvent', {
			url: '/events/:eventId/edit',
			templateUrl: 'modules/events/views/edit-event.client.view.html'
		});
	}
]);
<|endoftext|>