// Copyright (C) 2010 Adam Barth. All rights reserved.
// Copyright (C) 2019 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
var CODE_REVIEW_UNITTEST;

(function() {
  /**
   * Create a new function with some of its arguements
   * pre-filled.
   * Taken from goog.partial in the Closure library.
   * @param {Function} fn A function to partially apply.
   * @param {...*} var_args Additional arguments that are partially
   *     applied to fn.
   * @return {!Function} A partially-applied form of the function.
   */
  function partial(fn, var_args) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function() {
      // Prepend the bound arguments to the current arguments.
      var newArgs = Array.prototype.slice.call(arguments);
      newArgs.unshift.apply(newArgs, args);
      return fn.apply(this, newArgs);
    };
  };

  function determineAttachmentID() {
    try {
      return /id=(\d+)/.exec(window.location.search)[1]
    } catch (ex) {
      return;
    }
  }

  // Attempt to activate only in the "Review Patch" context.
  if (window.top != window)
    return;

  if (!CODE_REVIEW_UNITTEST && !window.location.search.match(/action=review/)
      && !window.location.toString().match(/bugs\.webkit\.org\/PrettyPatch/))
    return;

  var attachment_id = determineAttachmentID();
  if (!attachment_id)
    console.log('No attachment ID');

  var minLeftSideRatio = 10;
  var maxLeftSideRatio = 90;
  var file_diff_being_resized = null;
  var files = {};
  var original_file_contents = {};
  var patched_file_contents = {};
  var WEBKIT_BASE_DIR = "//svn.webkit.org/repository/webkit/trunk/";
  var SIDE_BY_SIDE_DIFFS_KEY = 'sidebysidediffs';
  var g_displayed_draft_comments = false;
  var g_next_line_id = 0;
  var KEY_CODE = {
    down: 40,
    enter: 13,
    escape: 27,
    j: 74,
    k: 75,
    n: 78,
    p: 80,
    r: 82,
    up: 38
  }

  function idForLine(number) {
    return 'line' + number;
  }

  function forEachLine(callback) {
    var i = 0;
    for (var i = 0; i < g_next_line_id; i++) {
      var line = $('#' + idForLine(i));
      if (line[0])
        callback(line);
    }
  }

  function hoverify() {
    $(this).hover(function() {
      $(this).addClass('hot');
    },
    function () {
      $(this).removeClass('hot');
    });
  }

  function fileDiffFor(line) {
    return $(line).parents('.FileDiff');
  }

  function diffSectionFor(line) {
    return $(line).parents('.DiffSection');
  }

  function activeCommentFor(line) {
    // Scope to the diffSection as a performance improvement.
    return $('textarea[data-comment-for~="' + line[0].id + '"]', fileDiffFor(line));
  }

  function previousCommentsFor(line) {
    // Scope to the diffSection as a performance improvement.
    return $('div[data-comment-for~="' + line[0].id + '"].previousComment', fileDiffFor(line));
  }

  function findCommentPositionFor(line) {
    var previous_comments = previousCommentsFor(line);
    var num_previous_comments = previous_comments.size();
    if (num_previous_comments)
      return $(previous_comments[num_previous_comments - 1])
    return line;
  }

  function findCommentBlockFor(line) {
    var comment_block = findCommentPositionFor(line).next();
    if (!comment_block.hasClass('comment'))
      return;
    return comment_block;
  }

  function insertCommentFor(line, block) {
    findCommentPositionFor(line).after(block);
  }

  function addDraftComment(start_line_id, end_line_id, contents) {
    var line = $('#' + end_line_id);
    var start = numberFrom(start_line_id);
    var end = numberFrom(end_line_id);
    for (var i = start; i <= end; i++) {
      addDataCommentBaseLine($('#line' + i), end_line_id);
    }

    var comment_block = createCommentFor(line);
    $(comment_block).children('textarea').val(contents);
    freezeComment(comment_block);
  }

  function ensureDraftCommentsDisplayed() {
    if (g_displayed_draft_comments)
      return;
    g_displayed_draft_comments = true;

    var comments = g_draftCommentSaver.saved_comments();
    var errors = [];
    $(comments.comments).each(function() {
      try {
        addDraftComment(this.start_line_id, this.end_line_id, this.contents);
      } catch (e) {
        errors.push({'start': this.start_line_id, 'end': this.end_line_id, 'contents': this.contents});
      }
    });
    
    if (errors.length) {
      console.log('DRAFT COMMENTS WITH ERRORS:', JSON.stringify(errors));
      alert('Some draft comments failed to be added. See the console to manually resolve.');
    }
    
    var overall_comments = comments['overall-comments'];
    if (overall_comments) {
      openOverallComments();
      $('.overallComments textarea').val(overall_comments);
    }
  }

  function DraftCommentSaver(opt_attachment_id, opt_localStorage) {
    this._attachment_id = opt_attachment_id || attachment_id;
    this._localStorage = opt_localStorage || localStorage;
    this._save_comments = true;
  }

  DraftCommentSaver.prototype._json = function() {
    var comments = $('.comment');
    var comment_store = [];
    comments.each(function () {
      var file_diff = fileDiffFor(this);
      var textarea = $('textarea', this);

      var contents = textarea.val().trim();
      if (!contents)
        return;

      var comment_base_line = textarea.attr('data-comment-for');
      var lines = contextLinesFor(comment_base_line, file_diff);

      comment_store.push({
        start_line_id: lines.first().attr('id'),
        end_line_id: comment_base_line,
        contents: contents
      });
    });

    var overall_comments = $('.overallComments textarea').val().trim();
    return JSON.stringify({'born-on': Date.now(), 'comments': comment_store, 'overall-comments': overall_comments});
  }
  
  DraftCommentSaver.prototype.localStorageKey = function() {
    return DraftCommentSaver._keyPrefix + this._attachment_id;
  }
  
  DraftCommentSaver.prototype.saved_comments = function() {
    var serialized_comments = this._localStorage.getItem(this.localStorageKey());
    if (!serialized_comments)
      return [];

    var comments = {};
    try {
      comments = JSON.parse(serialized_comments);
    } catch (e) {
      this._erase_corrupt_comments();
      return {};
    }

    var individual_comments = comments.comments;
    if (!comments || !comments['born-on'] || !individual_comments || (individual_comments.length && !individual_comments[0].contents)) {
      this._erase_corrupt_comments();
      return {};
    }    
    return comments;
  }
  
  DraftCommentSaver.prototype._erase_corrupt_comments = function() {
    // FIXME: Show an error to the user instead of logging.
    console.log('Draft comments were corrupted. Erasing comments.');
    this.erase();
  }
  
  DraftCommentSaver.prototype.save = function() {
    if (!this._save_comments)
      return;

    var key = this.localStorageKey();
    var value = this._json();

    if (this._attemptToWrite(key, value))
      return;

    this._eraseOldCommentsForAllReviews();
    if (this._attemptToWrite(key, value))
      return;

    var remove_comments = this._should_remove_comments();
    if (!remove_comments) {
      this._save_comments = false;
      return;
    }

    this._eraseCommentsForAllReviews();
    if (this._attemptToWrite(key, value))
      return;

    this._save_comments = false;
    // FIXME: Show an error to the user.
  }

  DraftCommentSaver.prototype._should_remove_comments = function(message) {
    return prompt('Local storage quota is full. Remove draft comments from all previous reviews to make room?');
  }

  DraftCommentSaver.prototype._attemptToWrite = function(key, value) {
    try {
      this._localStorage.setItem(key, value);
      return true;
    } catch (e) {
      return false;
    }
  }

  DraftCommentSaver._keyPrefix = 'draft-comments-for-attachment-';

  DraftCommentSaver.prototype.erase = function() {
    this._localStorage.removeItem(this.localStorageKey());
  }

  DraftCommentSaver.prototype._eraseOldCommentsForAllReviews = function() {
    this._eraseComments(true);
  }
  DraftCommentSaver.prototype._eraseCommentsForAllReviews = function() {
    this._eraseComments(false);
  }

  var MONTH_IN_MS = 1000 * 60 * 60 * 24 * 30;

  DraftCommentSaver.prototype._eraseComments = function(only_old_reviews) {
    var length = this._localStorage.length;
    var keys_to_delete = [];
    for (var i = 0; i < length; i++) {
      var key = this._localStorage.key(i);
      if (key.indexOf(DraftCommentSaver._keyPrefix) != 0)
        continue;
        
      if (only_old_reviews) {
        try {
          var born_on = JSON.parse(this._localStorage.getItem(key))['born-on'];
          if (Date.now() - born_on < MONTH_IN_MS)
            continue;
        } catch (e) {
          console.log('Deleting JSON. JSON for code review is corrupt: ' + key);
        }        
      }
      keys_to_delete.push(key);
    }

    for (var i = 0; i < keys_to_delete.length; i++) {
      this._localStorage.removeItem(keys_to_delete[i]);
    }
  }
  
  var g_draftCommentSaver = new DraftCommentSaver();

  function saveDraftComments() {
    ensureDraftCommentsDisplayed();
    g_draftCommentSaver.save();
    setAutoSaveStateIndicator('saved');
  }

  function setAutoSaveStateIndicator(state) {
    var container = $('.autosave-state');
    container.text(state);
    
    if (state == 'saving')
      container.addClass(state);
    else
      container.removeClass('saving');
  }
  
  function unfreezeCommentFor(line) {
    // FIXME: This query is overly complex because we place comment blocks
    // after Lines.  Instead, comment blocks should be children of Lines.
    findCommentPositionFor(line).next().next().filter('.frozenComment').each(handleUnfreezeComment);
  }

  function createCommentFor(line) {
    if (line.attr('data-has-comment')) {
      unfreezeCommentFor(line);
      return;
    }
    line.attr('data-has-comment', 'true');
    line.addClass('commentContext');

    var comment_block = $('<div class="comment"><textarea data-comment-for="' + line.attr('id') + '"></textarea><div class="actions"><button class="ok">OK</button><button class="discard">Discard</button></div></div>');
    $('textarea', comment_block).bind('input', handleOverallCommentsInput);
    insertCommentFor(line, comment_block);
    return comment_block;
  }

  function addCommentFor(line) {
    var comment_block = createCommentFor(line);
    if (!comment_block)
      return;

    comment_block.hide().slideDown('fast', function() {
      $(this).children('textarea').focus();
    });
    return comment_block;
  }

  function addCommentField(comment_block) {
    var id = $(comment_block).attr('data-comment-for');
    if (!id)
      id = comment_block.id;
    return addCommentFor($('#' + id));
  }
  
  function handleAddCommentField() {
    addCommentField(this);
  }

  function addPreviousComment(line, author, comment_text) {
    var line_id = $(line).attr('id');
    var comment_block = $('<div data-comment-for="' + line_id + '" class="previousComment"></div>');
    var author_block = $('<div class="author"></div>').text(author + ':');
    var text_block = $('<div class="content"></div>').text(comment_text);
    comment_block.append(author_block).append(text_block).each(hoverify).click(handleAddCommentField);
    addDataCommentBaseLine($(line), line_id);
    insertCommentFor($(line), comment_block);
  }

  function displayPreviousComments(comments) {
    for (var i = 0; i < comments.length; ++i) {
      var author = comments[i].author;
      var file_name = comments[i].file_name;
      var line_number = comments[i].line_number;
      var comment_text = comments[i].comment_text;

      var file = files[file_name];

      var query = '.Line .to';
      if (line_number[0] == '-') {
        // The line_number represent a removal.  We need to adjust the query to
        // look at the "from" lines.
        query = '.Line .from';
        // Trim off the '-' control character.
        line_number = line_number.substr(1);
      }

      $(file).find(query).each(function() {
        if ($(this).text() != line_number)
          return;
        var line = lineContainerFromDescendant($(this));
        addPreviousComment(line, author, comment_text);
      });
    }

    if (comments.length == 0) {
      return;
    }

    descriptor = comments.length + ' comment';
    if (comments.length > 1)
      descriptor += 's';
    $('.help .more').before(' This patch has ' + descriptor + '.  Scroll through them with the "n" and "p" keys. ');
  }
  
  function showMoreHelp() {
    $('.more-help').removeClass('inactive');
  }
  
  function hideMoreHelp() {
    $('.more-help').addClass('inactive');
  }

  function scanForStyleQueueComments(text) {
    var comments = []
    var lines = text.split('\n');
    for (var i = 0; i < lines.length; ++i) {
      var parts = lines[i].match(/^([^:]+):(-?\d+):(.*)$/);
      if (!parts)
        continue;

      var file_name = parts[1];
      var line_number = parts[2];
      var comment_text = parts[3].trim();

      if (!file_name in files) {
        console.log('Filename in style queue output is not in the patch: ' + file_name);
        continue;
      }

      comments.push({
        'author': 'StyleQueue',
        'file_name': file_name,
        'line_number': line_number,
        'comment_text': comment_text
      });
    }
    return comments;
  }

  function scanForComments(author, text) {
    var comments = []
    var lines = text.split('\n');
    for (var i = 0; i < lines.length; ++i) {
      var parts = lines[i].match(/^([> ]+)([^:]+):(-?\d+)$/);
      if (!parts)
        continue;
      var quote_markers = parts[1];
      var file_name = parts[2];
      // FIXME: Store multiple lines for multiline comments and correctly import them here.
      var line_number = parts[3];
      if (!file_name in files)
        continue;
      while (i < lines.length && lines[i].length > 0 && lines[i][0] == '>')
        ++i;
      var comment_lines = [];
      while (i < lines.length && (lines[i].length == 0 || lines[i][0] != '>')) {
        comment_lines.push(lines[i]);
        ++i;
      }
      --i; // Decrement i because the for loop will increment it again in a second.
      var comment_text = comment_lines.join('\n').trim();
      comments.push({
        'author': author,
        'file_name': file_name,
        'line_number': line_number,
        'comment_text': comment_text
      });
    }
    return comments;
  }

  function isReviewFlag(select) {
    return $(select).attr('title') == 'Request for patch review.';
  }

  function isCommitQueueFlag(select) {
    return $(select).attr('title').match(/commit-queue/);
  }

  function findControlForFlag(select) {
    if (isReviewFlag(select))
      return $('#toolbar .review select');
    else if (isCommitQueueFlag(select))
      return $('#toolbar .commitQueue select');
    return $();
  }

  function addFlagsForAttachment(details) {
    var flag_control = "<select><option></option><option>?</option><option>+</option><option>-</option></select>";
    $('#flagContainer').append(
      $('<span class="review"> r: ' + flag_control + '</span>')).append(
      $('<span class="commitQueue"> cq: ' + flag_control + '</span>'));

    details.find('#flags select').each(function() {
      var requestee = $(this).parent().siblings('td:first-child').text().trim();
      if (requestee.length) {
        // Remove trailing ':'.
        requestee = requestee.substr(0, requestee.length - 1);
        requestee = ' (' + requestee + ')';
      }
      var control = findControlForFlag(this)
      control.attr('selectedIndex', $(this).attr('selectedIndex'));
      control.parent().prepend(requestee);
    });
  }

  window.addEventListener('message', handleStatusBubbleMessage, false);

  function fetchHistory() {
    $.get('attachment.cgi?id=' + attachment_id + '&action=edit', function(data) {
      var bug_id = /Attachment \d+ Details for Bug (\d+)/.exec(data)[1];
      $.get('show_bug.cgi?id=' + bug_id, function(data) {
        var comments = [];
        $(data).find('.bz_comment').each(function() {
          var author = $(this).find('.email').text().trim();
          var text = $(this).find('.bz_comment_text').text();

          var comment_marker = 'Comment on attachment ' + attachment_id + ' .details.';
          if (text.match(comment_marker)) {
            $.merge(comments, scanForComments(author, text));
          } else {
              comment_marker = '(From update of attachment ' + attachment_id + ' .details.)';
              if (text.match(comment_marker))
                $.merge(comments, scanForComments(author, text));
          }

          var style_queue_comment_marker = 'Attachment ' + attachment_id + ' .details. did not pass style-queue.'
          if (text.match(style_queue_comment_marker))
            $.merge(comments, scanForStyleQueueComments(text));
        });
        displayPreviousComments(comments);
        ensureDraftCommentsDisplayed();
      });

      var details = $(data);
      addFlagsForAttachment(details);

      var statusBubble = document.createElement('iframe');
      statusBubble.src  = 'https://webkit-queues.webkit.org/status-bubble/' + attachment_id;
      statusBubble.scrolling = 'no';
      // Can't append the HTML because we need to set the onload handler before appending the iframe to the DOM.
      statusBubble.onload = function () { handleStatusBubbleLoad(this); };
      $('.statusBubble').append(statusBubble);

      var statusBubbleNewEWS = document.createElement('iframe');
      statusBubbleNewEWS.src  = 'https://ews.webkit.org/status-bubble/' + attachment_id + '?hide_icons=True';
      // Can't append the HTML because we need to set the onload handler before appending the iframe to the DOM.
      statusBubbleNewEWS.scrolling = "no";
      statusBubbleNewEWS.onload = function () { handleStatusBubbleLoadNewEWS(this); };
      $('.statusBubble').append(statusBubbleNewEWS);

      $('#toolbar .bugLink').html('<a href="/show_bug.cgi?id=' + bug_id + '" target="_blank">Bug ' + bug_id + '</a>');
    });
  }

  function firstLine(file_diff) {
    var container = $('.LineContainer:not(.context)', file_diff)[0];
    if (!container)
      return 0;

    var from = fromLineNumber(container);
    var to = toLineNumber(container);
    return from || to;
  }

  function crawlDiff() {
    g_next_line_id = 0;
    var idify = function() {
      this.id = idForLine(g_next_line_id++);
    }

    $('.Line').each(idify).each(hoverify);
    $('.FileDiff').each(function() {
      var header = $(this).children('h1');
      var url_hash = '#L' + firstLine(this);

      var file_name = header.text();
      files[file_name] = this;

      addExpandLinks(file_name);

      var diff_links = $('<div class="FileDiffLinkContainer LinkContainer">' +
          diffLinksHtml() +
          '</div>');

      var file_link = $('a', header)[0];
      // If the base directory in the file path does not match a WebKit top level directory,
      // then PrettyPatch.rb doesn't linkify the header.
      if (file_link) {
        file_link.target = "_blank";
        file_link.href += url_hash;
        diff_links.append(tracLinks(file_name, url_hash));
      }

      $('h1', this).after(diff_links);
      updateDiffLinkVisibility(this);
    });
  }

  function tracLinks(file_name, url_hash) {
    var trac_links = $('<a target="_blank">annotate</a><a target="_blank">revision log</a>');
    trac_links[0].href = 'http://trac.webkit.org/browser/trunk/' + file_name + '?annotate=blame' + url_hash;
    trac_links[1].href = 'http://trac.webkit.org/log/trunk/' + file_name;
    var implementation_suffix_list = ['.cpp', '.mm'];
    for (var i = 0; i < implementation_suffix_list.length; ++i) {
      var suffix = implementation_suffix_list[i];
      if (file_name.lastIndexOf(suffix) == file_name.length - suffix.length) {
        var new_link = $('<a target="_blank">header</a>');
        var stem = file_name.substr(0, file_name.length - suffix.length);
        new_link[0].href= 'http://trac.webkit.org/log/trunk/' + stem + '.h';
        trac_links = $.merge(new_link, trac_links);
      }
    }
    return trac_links;
  }

  function isChangeLog(file_name) {
    return file_name.match(/\/ChangeLog$/) || file_name == 'ChangeLog';
  }

  function addExpandLinks(file_name) {
    if (isChangeLog(file_name))
      return;

    var file_diff = files[file_name];

    // Don't show the links to expand upwards/downwards if the patch starts/ends without context
    // lines, i.e. starts/ends with add/remove lines.
    var first_line = file_diff.querySelector('.LineContainer:not(.context)');

    // If there is no element with a "Line" class, then this is an image diff.
    if (!first_line)
      return;

    var expand_bar_index = 0;
    if (!$(first_line).hasClass('add') && !$(first_line).hasClass('remove'))
      $('h1', file_diff).after(expandBarHtml(BELOW))

    $('br', file_diff).replaceWith(expandBarHtml());

    // jquery doesn't support :last-of-type, so use querySelector instead.
    var last_line = file_diff.querySelector('.LineContainer:last-of-type');
    // Some patches for new files somehow end up with an empty context line at the end
    // with a from line number of 0. Don't show expand links in that case either.
    if (!$(last_line).hasClass('add') && !$(last_line).hasClass('remove') && fromLineNumber(last_line) != 0)
      $(file_diff.querySelector('.DiffSection:last-of-type')).after(expandBarHtml(ABOVE));
  }

  function expandBarHtml(opt_direction) {
    var html = '<div class="ExpandBar">' +
        '<div class="ExpandArea Expand' + ABOVE + '"></div>' +
        '<div class="ExpandLinkContainer LinkContainer"><span class="ExpandText">expand: </span>';

    // FIXME: If there are <100 line to expand, don't show the expand-100 link.
    // If there are <20 lines to expand, don't show the expand-20 link.
    if (!opt_direction || opt_direction == ABOVE) {
      html += expandLinkHtml(ABOVE, 100) +
          expandLinkHtml(ABOVE, 20);
    }

    html += expandLinkHtml(ALL);

    if (!opt_direction || opt_direction == BELOW) {
      html += expandLinkHtml(BELOW, 20) +
        expandLinkHtml(BELOW, 100);
    }

    html += '</div><div class="ExpandArea Expand' + BELOW + '"></div></div>';
    return html;
  }

  function expandLinkHtml(direction, amount) {
    return "<a class='ExpandLink' href='javascript:' data-direction='" + direction + "' data-amount='" + amount + "'>" +
        (amount ? amount + " " : "") + direction + "</a>";
  }

  function handleExpandLinkClick() {
    var expand_bar = $(this).parents('.ExpandBar');
    var file_name = expand_bar.parents('.FileDiff').children('h1')[0].textContent;
    var expand_function = partial(expand, expand_bar[0], file_name, this.getAttribute('data-direction'), Number(this.getAttribute('data-amount')));
    if (file_name in original_file_contents)
      expand_function();
    else
      getWebKitSourceFile(file_name, expand_function, expand_bar);
  }

  function handleSideBySideLinkClick() {
    convertDiff('sidebyside', this);
  }

  function handleUnifyLinkClick() {
    convertDiff('unified', this);
  }

  function convertDiff(difftype, convert_link) {
    var file_diffs = $(convert_link).parents('.FileDiff');
    if (!file_diffs.size()) {
      localStorage.setItem('code-review-diffstate', difftype);
      file_diffs = $('.FileDiff');
    }

    convertAllFileDiffs(difftype, file_diffs);
  }

  function patchRevision() {
    var revision = $('.revision');
    return revision[0] ? revision.first().text() : null;
  }

  function setFileContents(file_name, original_contents, patched_contents) {
    original_file_contents[file_name] = original_contents;
    patched_file_contents[file_name] = patched_contents;
  }

  function getWebKitSourceFile(file_name, onLoad, expand_bar) {
    function handleLoad(contents) {
      var split_contents = contents.split('\n');
      setFileContents(file_name, split_contents, applyDiff(split_contents, file_name));
      onLoad();
    };

    var revision = patchRevision();
    var queryParameters = revision ? '?p=' + revision : '';

    $.ajax({
      url: WEBKIT_BASE_DIR + file_name + queryParameters,
      context: document.body,
      complete: function(xhr, data) {
              if (xhr.status == 0)
                  handleLoadError(expand_bar);
              else
                  handleLoad(xhr.responseText);
      }
    });
  }

  function replaceExpandLinkContainers(expand_bar, text) {
    $('.ExpandLinkContainer', $(expand_bar).parents('.FileDiff')).replaceWith('<span class="ExpandText">' + text + '</span>');
  }

  function handleLoadError(expand_bar) {
    replaceExpandLinkContainers(expand_bar, "Can't expand. Is this a new or deleted file?");
  }

  var ABOVE = 'above';
  var BELOW = 'below';
  var ALL = 'all';

  function lineNumbersFromSet(set, is_last) {
    var to = -1;
    var from = -1;

    var size = set.size();
    var start = is_last ? (size - 1) : 0;
    var end = is_last ? -1 : size;
    var offset = is_last ? -1 : 1;

    for (var i = start; i != end; i += offset) {
      if (to != -1 && from != -1)
        return {to: to, from: from};

      var line_number = set[i];
      if ($(line_number).hasClass('to')) {
        if (to == -1)
          to = Number(line_number.textContent);
      } else {
        if (from == -1)
          from = Number(line_number.textContent);
      }
    }
  }

  function removeContextBarBelow(expand_bar) {
    $('.context', expand_bar.nextElementSibling).detach();
  }

  function expand(expand_bar, file_name, direction, amount) {
    if (file_name in original_file_contents && !patched_file_contents[file_name]) {
      // FIXME: In this case, try fetching the source file at the revision the patch was created at.
      // Might need to modify webkit-patch to include that data in the diff.
      replaceExpandLinkContainers(expand_bar, "Can't expand. Unable to apply patch to tip of tree.");
      return;
    }

    var above_expansion = expand_bar.querySelector('.Expand' + ABOVE)
    var below_expansion = expand_bar.querySelector('.Expand' + BELOW)

    var above_line_numbers = $('.expansionLineNumber', above_expansion);
    if (!above_line_numbers[0]) {
      var diff_section = expand_bar.previousElementSibling;
      above_line_numbers = $('.Line:not(.context) .lineNumber', diff_section);
    }

    var above_last_line_num, above_last_from_line_num;
    if (above_line_numbers[0]) {
      var above_numbers = lineNumbersFromSet(above_line_numbers, true);
      above_last_line_num = above_numbers.to;
      above_last_from_line_num = above_numbers.from;
    } else
      above_last_from_line_num = above_last_line_num = 0;

    var below_line_numbers = $('.expansionLineNumber', below_expansion);
    if (!below_line_numbers[0]) {
      var diff_section = expand_bar.nextElementSibling;
      if (diff_section)
        below_line_numbers = $('.Line:not(.context) .lineNumber', diff_section);
    }

    var below_first_line_num, below_first_from_line_num;
    if (below_line_numbers[0]) {
      var below_numbers = lineNumbersFromSet(below_line_numbers, false);
      below_first_line_num = below_numbers.to - 1;
      below_first_from_line_num = below_numbers.from - 1;
    } else
      below_first_from_line_num = below_first_line_num = patched_file_contents[file_name].length - 1;

    var start_line_num, start_from_line_num;
    var end_line_num;

    if (direction == ABOVE) {
      start_from_line_num = above_last_from_line_num;
      start_line_num = above_last_line_num;
      end_line_num = Math.min(start_line_num + amount, below_first_line_num);
    } else if (direction == BELOW) {
      end_line_num = below_first_line_num;
      start_line_num = Math.max(end_line_num - amount, above_last_line_num)
      start_from_line_num = Math.max(below_first_from_line_num - amount, above_last_from_line_num)
    } else { // direction == ALL
      start_line_num = above_last_line_num;
      start_from_line_num = above_last_from_line_num;
      end_line_num = below_first_line_num;
    }

    var lines = expansionLines(file_name, expansion_area, direction, start_line_num, end_line_num, start_from_line_num);

    var expansion_area;
    // Filling in all the remaining lines. Overwrite the expand links.
    if (start_line_num == above_last_line_num && end_line_num == below_first_line_num) {
      $('.ExpandLinkContainer', expand_bar).detach();
      below_expansion.insertBefore(lines, below_expansion.firstChild);
      removeContextBarBelow(expand_bar);
    } else if (direction == ABOVE) {
      above_expansion.appendChild(lines);
    } else {
      below_expansion.insertBefore(lines, below_expansion.firstChild);
      removeContextBarBelow(expand_bar);
    }
  }

  function unifiedLine(from, to, contents, is_expansion_line, opt_className, opt_attributes) {
    var className = is_expansion_line ? 'ExpansionLine' : 'LineContainer Line';
    if (opt_className)
      className += ' ' + opt_className;

    var lineNumberClassName = is_expansion_line ? 'expansionLineNumber' : 'lineNumber';

    var line = $('<div class="' + className + '" ' + (opt_attributes || '') + '>' +
        '<span class="from ' + lineNumberClassName + '">' + (from || '&nbsp;') +
        '</span><span class="to ' + lineNumberClassName + '">' + (to || '&nbsp;') +
        '</span><span class="text"></span>' +
        '</div>');

    $('.text', line).replaceWith(contents);
    return line;
  }

  function unifiedExpansionLine(from, to, contents) {
    return unifiedLine(from, to, contents, true);
  }

  function sideBySideExpansionLine(from, to, contents) {
    var line = $('<div class="ExpansionLine"></div>');
    // Clone the contents so we have two copies we can put back in the DOM.
    line.append(lineSide('from', contents.clone(true), true, from));
    line.append(lineSide('to', contents, true, to));
    return line;
  }

  function lineSide(side, contents, is_expansion_line, opt_line_number, opt_attributes, opt_class) {
    var class_name = '';
    if (opt_attributes || opt_class) {
      class_name = 'class="';
      if (opt_attributes)
        class_name += is_expansion_line ? 'ExpansionLine' : 'Line';
      class_name += ' ' + (opt_class || '') + '"';
    }

    var attributes = opt_attributes || '';

    var line_side = $('<div class="LineSide">' +
        '<div ' + attributes + ' ' + class_name + '>' +
          '<span class="' + side + ' ' + (is_expansion_line ? 'expansionLineNumber' : 'lineNumber') + '">' +
              (opt_line_number || '&nbsp;') +
          '</span>' +
          '<span class="text"></span>' +
        '</div>' +
        '</div>');

    $('.text', line_side).replaceWith(contents);
    return line_side;
  }

  function expansionLines(file_name, expansion_area, direction, start_line_num, end_line_num, start_from_line_num) {
    var fragment = document.createDocumentFragment();
    var is_side_by_side = isDiffSideBySide(files[file_name]);

    for (var i = 0; i < end_line_num - start_line_num; i++) {
      var from = start_from_line_num + i + 1;
      var to = start_line_num + i + 1;
      var contents = $('<span class="text"></span>');
      contents.text(patched_file_contents[file_name][start_line_num + i]);
      var line = is_side_by_side ? sideBySideExpansionLine(from, to, contents) : unifiedExpansionLine(from, to, contents);
      fragment.appendChild(line[0]);
    }

    return fragment;
  }

  function hunkStartingLine(patched_file, context, prev_line, hunk_num) {
    var current_line = -1;
    var last_context_line = context[context.length - 1];
    if (patched_file[prev_line] == last_context_line)
      current_line = prev_line + 1;
    else {
      console.log('Hunk #' + hunk_num + ' FAILED.');
      return -1;
    }

    // For paranoia sake, confirm the rest of the context matches;
    for (var i = 0; i < context.length - 1; i++) {
      if (patched_file[current_line - context.length + i] != context[i]) {
        console.log('Hunk #' + hunk_num + ' FAILED. Did not match preceding context.');
        return -1;
      }
    }

    return current_line;
  }

  function fromLineNumber(line) {
    var node = line.querySelector('.from');
    return node ? Number(node.textContent) : 0;
  }

  function toLineNumber(line) {
    var node = line.querySelector('.to');
    return node ? Number(node.textContent) : 0;
  }

  function textContentsFor(line) {
    // Just get the first match since a side-by-side diff has two lines with text inside them for
    // unmodified lines in the diff.
    return $('.text', line).first().text();
  }

  function lineNumberForFirstNonContextLine(patched_file, line, prev_line, context, hunk_num) {
    if (context.length) {
      var prev_line_num = fromLineNumber(prev_line) - 1;
      return hunkStartingLine(patched_file, context, prev_line_num, hunk_num);
    }

    if (toLineNumber(line) == 1 || fromLineNumber(line) == 1)
      return 0;

    console.log('Failed to apply patch. Adds or removes lines before any context lines.');
    return -1;
  }

  function applyDiff(original_file, file_name) {
    var diff_sections = files[file_name].getElementsByClassName('DiffSection');
    var patched_file = original_file.concat([]);

    // Apply diffs in reverse order to avoid needing to keep track of changing line numbers.
    for (var i = diff_sections.length - 1; i >= 0; i--) {
      var section = diff_sections[i];
      var lines = $('.Line:not(.context)', section);
      var current_line = -1;
      var context = [];
      var hunk_num = i + 1;

      for (var j = 0, lines_len = lines.length; j < lines_len; j++) {
        var line = lines[j];
        var line_contents = textContentsFor(line);
        if ($(line).hasClass('add')) {
          if (current_line == -1) {
            current_line = lineNumberForFirstNonContextLine(patched_file, line, lines[j-1], context, hunk_num);
            if (current_line == -1)
              return null;
          }

          patched_file.splice(current_line, 0, line_contents);
          current_line++;
        } else if ($(line).hasClass('remove')) {
          if (current_line == -1) {
            current_line = lineNumberForFirstNonContextLine(patched_file, line, lines[j-1], context, hunk_num);
            if (current_line == -1)
              return null;
          }

          if (patched_file[current_line] != line_contents) {
            console.log('Hunk #' + hunk_num + ' FAILED.');
            return null;
          }

          patched_file.splice(current_line, 1);
        } else if (current_line == -1) {
          context.push(line_contents);
        } else if (line_contents != patched_file[current_line]) {
          console.log('Hunk #' + hunk_num + ' FAILED. Context at end did not match');
          return null;
        } else {
          current_line++;
        }
      }
    }

    return patched_file;
  }

  function openOverallComments(e) {
    $('.overallComments textarea').addClass('open');
    $('.statusBubble').addClass('wrap');
  }

  var g_overallCommentsInputTimer;

  function handleOverallCommentsInput() {
    setAutoSaveStateIndicator('saving');
    // Save draft comments after we haven't received an input event in 1 second.
    if (g_overallCommentsInputTimer)
      clearTimeout(g_overallCommentsInputTimer);
    g_overallCommentsInputTimer = setTimeout(saveDraftComments, 1000);
  }

  function diffLinksHtml() {
    return '<a href="javascript:" class="unify-link">unified</a>' +
      '<a href="javascript:" class="side-by-side-link">side-by-side</a>';
  }

  function appendToolbar() {
    $(document.body).append('<div id="toolbar">' +
        '<div class="overallComments">' +
          '<textarea placeholder="Overall comments"></textarea>' +
        '</div>' +
        '<div>' +
          '<span class="statusBubble"></span>' +
          '<span class="actions">' +
            '<span class="links"><span class="bugLink"></span></span>' +
            '<span id="flagContainer"></span>' +
            '<button id="preview_comments">Preview</button>' +
            '<button id="post_comments">Publish</button> ' +
          '</span>' +
          '<div class="clear_float"></div>' +
        '</div>' +
        '<div class="autosave-state"></div>' +
        '</div>');

    $('.overallComments textarea').bind('click', openOverallComments);
    $('.overallComments textarea').bind('input', handleOverallCommentsInput);

    var toolbar = $('#toolbar');
    toolbar.css('position', '-webkit-sticky');
    var supportsSticky = toolbar.css('position') == '-webkit-sticky';
    document.body.style.marginBottom = supportsSticky ? 0 : '40px';
  }

  function handleDocumentReady() {
    crawlDiff();
    fetchHistory();

    $(document.body).prepend('<div id="message">' +
        '<div class="help">Select line numbers to add a comment. Scroll though diffs with the "j" and "k" keys.' +
          '<div class="DiffLinks LinkContainer">' +
            '<input type="checkbox" id="line-number-on-copy"><label for="line-number-on-copy">Skip line numbers on copy</label>' +
            diffLinksHtml() +
          '</div>' +
          '<a href="javascript:" class="more">[more]</a>' +
          '<div class="more-help inactive">' +
            '<div class="winter"></div>' +
            '<div class="lightbox"><table>' +
              '<tr><td>enter</td><td>add/edit comment for focused item</td></tr>' +
              '<tr><td>escape</td><td>accept current comment / close preview and help popups</td></tr>' +
              '<tr><td>j</td><td>focus next diff</td></tr>' +
              '<tr><td>k</td><td>focus previous diff</td></tr>' +
              '<tr><td>shift + j</td><td>focus next line</td></tr>' +
              '<tr><td>shift + k</td><td>focus previous line</td></tr>' +
              '<tr><td>n</td><td>focus next comment</td></tr>' +
              '<tr><td>p</td><td>focus previous comment</td></tr>' +
              '<tr><td>r</td><td>focus review select element</td></tr>' +
              '<tr><td>ctrl + shift + up</td><td>extend context of the focused comment</td></tr>' +
              '<tr><td>ctrl + shift + down</td><td>shrink context of the focused comment</td></tr>' +
            '</table></div>' +
          '</div>' +
        '</div>' +
        '</div>');

    appendToolbar();

    $(document.body).prepend('<div id="comment_form" class="inactive"><div class="winter"></div><div class="lightbox"><iframe id="reviewform" src="attachment.cgi?id=' + attachment_id + '&action=reviewform"></iframe></div></div>');
    $('#reviewform').bind('load', handleReviewFormLoad);

    loadDiffState();
    generateFileDiffResizeStyleElement();
    updateLineNumberOnCopyLinkContents();

    document.body.addEventListener('copy', handleCopy);
  };

  function forEachNode(nodeList, callback) {
    Array.prototype.forEach.call(nodeList, callback);
  }

  $('#line-number-on-copy').live('click', toggleShouldStripLineNumbersOnCopy);

  function updateLineNumberOnCopyLinkContents() {
    document.getElementById('line-number-on-copy').checked = shouldStripLineNumbersOnCopy();
  }

  function shouldStripLineNumbersOnCopy() {
    return localStorage.getItem('code-review-line-numbers-on-copy') == 'true';
  }

  function toggleShouldStripLineNumbersOnCopy() {
    localStorage.setItem('code-review-line-numbers-on-copy', !shouldStripLineNumbersOnCopy());
    updateLineNumberOnCopyLinkContents();
  }

  function sanitizeFragmentForCopy(fragment, shouldStripLineNumbers) {
    var classesToRemove = ['LinkContainer'];
    if (shouldStripLineNumbers)
      classesToRemove.push('lineNumber');

    classesToRemove.forEach(function(className) {
      forEachNode(fragment.querySelectorAll('.' + className), function(node) {
        $(node).remove();
      });
    });

    // Ensure that empty newlines show up in the copy now that
    // the line might collapse since the line number doesn't take up space.
    forEachNode(fragment.querySelectorAll('.text'), function(node) {
      if (node.textContent.match(/^\s*$/))
        node.innerHTML = '<br>';
    });
  }

  function handleCopy(event) {
    if (event.target.tagName == 'TEXTAREA')
      return;
    var selection = window.getSelection();
    var range = selection.getRangeAt(0);
    var selectionFragment = range.cloneContents();
    sanitizeFragmentForCopy(selectionFragment, shouldStripLineNumbersOnCopy())

    // FIXME: When event.clipboardData.setData supports text/html, remove all the code below.
    // https://bugs.webkit.org/show_bug.cgi?id=104179
    var container = document.createElement('div');
    container.appendChild(selectionFragment);
    document.body.appendChild(container);
    selection.selectAllChildren(container);

    setTimeout(function() {
      $(container).remove();
      selection.removeAllRanges();
      selection.addRange(range);
    });
  }

  function handleReviewFormLoad() {
    var review_form_contents = $('#reviewform').contents();
    if (review_form_contents[0].querySelector('#form-controls #flags')) {
      review_form_contents.bind('keydown', function(e) {
        if (e.keyCode == KEY_CODE.escape)
          hideCommentForm();
      });

      // This is the intial load of the review form iframe.
      var form = review_form_contents.find('form')[0];
      form.addEventListener('submit', eraseDraftComments);
      form.target = '';
      return;
    }

    // Review form iframe have the publish button has been pressed.
    var email_sent_to = review_form_contents[0].querySelector('#bugzilla-body dl');
    // If the email_send_to DL is not in the tree that means the publish failed for some reason,
    // e.g., you're not logged in. Show the comment form to allow you to login.
    if (!email_sent_to) {
      showCommentForm();
      return;
    }

    eraseDraftComments();
    // FIXME: Once WebKit supports seamless iframes, we can just make the review-form
    // iframe fill the page instead of redirecting back to the bug.
    window.location.replace($('#toolbar .bugLink a').attr('href'));
  }
  
  function eraseDraftComments() {
    g_draftCommentSaver.erase();
  }

  function loadDiffState() {
    var diffstate = localStorage.getItem('code-review-diffstate');
    if (diffstate != 'sidebyside' && diffstate != 'unified')
      return;

    convertAllFileDiffs(diffstate, $('.FileDiff'));
  }

  function isDiffSideBySide(file_diff) {
    return diffState(file_diff) == 'sidebyside';
  }

  function diffState(file_diff) {
    var diff_state = $(file_diff).attr('data-diffstate');
    return diff_state || 'unified';
  }

  function unifyLine(line, from, to, contents, classNames, attributes, id) {
    var new_line = unifiedLine(from, to, contents, false, classNames, attributes);
    var old_line = $(line);
    if (!old_line.hasClass('LineContainer'))
      old_line = old_line.parents('.LineContainer');

    var comments = commentsToTransferFor($(document.getElementById(id)));
    old_line.after(comments);
    old_line.replaceWith(new_line);
  }

  function updateDiffLinkVisibility(file_diff) {
    if (diffState(file_diff) == 'unified') {
      $('.side-by-side-link', file_diff).show();
      $('.unify-link', file_diff).hide();
    } else {
      $('.side-by-side-link', file_diff).hide();
      $('.unify-link', file_diff).show();
    }
  }

  function convertAllFileDiffs(diff_type, file_diffs) {
    file_diffs.each(function() {
      convertFileDiff(diff_type, this);
    });
  }

  function convertFileDiff(diff_type, file_diff) {
    if (diffState(file_diff) == diff_type)
      return;

    if (!$('.resizeHandle', file_diff).length)
      $(file_diff).append('<div class="resizeHandle"></div>');

    $(file_diff).removeClass('sidebyside unified');
    $(file_diff).addClass(diff_type);

    $(file_diff).attr('data-diffstate', diff_type);
    updateDiffLinkVisibility(file_diff);

    $('.context', file_diff).each(function() {
      convertLine(diff_type, this);
    });

    $('.shared .Line', file_diff).each(function() {
      convertLine(diff_type, this);
    });

    $('.ExpansionLine', file_diff).each(function() {
      convertExpansionLine(diff_type, this);
    });
  }

  function convertLine(diff_type, line) {
    var convert_function = diff_type == 'sidebyside' ? sideBySideifyLine : unifyLine;
    var from = fromLineNumber(line);
    var to = toLineNumber(line);
    var contents = $('.text', line).first();
    var classNames = classNamesForMovingLine(line);
    var attributes = attributesForMovingLine(line);
    var id = line.id;
    convert_function(line, from, to, contents, classNames, attributes, id)
  }

  function classNamesForMovingLine(line) {
    var classParts = line.className.split(' ');
    var classBuffer = [];
    for (var i = 0; i < classParts.length; i++) {
      var part = classParts[i];
      if (part != 'LineContainer' && part != 'Line')
        classBuffer.push(part);
    }
    return classBuffer.join(' ');
  }

  function attributesForMovingLine(line) {
    var attributesBuffer = ['id=' + line.id];
    // Make sure to keep all data- attributes.
    $(line.attributes).each(function() {
      if (this.name.indexOf('data-') == 0)
        attributesBuffer.push(this.name + '=' + this.value);
    });
    return attributesBuffer.join(' ');
  }

  function sideBySideifyLine(line, from, to, contents, classNames, attributes, id) {
    var from_class = '';
    var to_class = '';
    var from_attributes = '';
    var to_attributes = '';
    // Clone the contents so we have two copies we can put back in the DOM.
    var from_contents = contents.clone(true);
    var to_contents = contents;

    var container_class = 'LineContainer';
    var container_attributes = '';

    if (from && !to) { // This is a remove line.
      from_class = classNames;
      from_attributes = attributes;
      to_contents = '';
    } else if (to && !from) { // This is an add line.
      to_class = classNames;
      to_attributes = attributes;
      from_contents = '';
    } else {
      container_attributes = attributes;
      container_class += ' Line ' + classNames;
    }

    var new_line = $('<div ' + container_attributes + ' class="' + container_class + '"></div>');
    new_line.append(lineSide('from', from_contents, false, from, from_attributes, from_class));
    new_line.append(lineSide('to', to_contents, false, to, to_attributes, to_class));

    $(line).replaceWith(new_line);

    if (!line.classList.contains('context')) {
      var line = $(document.getElementById(id));
      line.after(commentsToTransferFor(line));
    }
  }

  function convertExpansionLine(diff_type, line) {
    var convert_function = diff_type == 'sidebyside' ? sideBySideExpansionLine : unifiedExpansionLine;
    var contents = $('.text', line).first();
    var from = fromLineNumber(line);
    var to = toLineNumber(line);
    var new_line = convert_function(from, to, contents);
    $(line).replaceWith(new_line);
  }

  function commentsToTransferFor(line) {
    var fragment = document.createDocumentFragment();

    previousCommentsFor(line).each(function() {
      fragment.appendChild(this);
    });

    var active_comments = activeCommentFor(line);
    var num_active_comments = active_comments.size();
    if (num_active_comments > 0) {
      if (num_active_comments > 1)
        console.log('ERROR: There is more than one active comment for ' + line.attr('id') + '.');

      var parent = active_comments[0].parentNode;
      var frozenComment = parent.nextSibling;
      fragment.appendChild(parent);
      fragment.appendChild(frozenComment);
    }

    return fragment;
  }

  function discardComment(comment_block) {
    var line_id = $(comment_block).find('textarea').attr('data-comment-for');
    var line = $('#' + line_id)
    $(comment_block).slideUp('fast', function() {
      $(this).remove();
      line.removeAttr('data-has-comment');
      trimCommentContextToBefore(line, line_id);
      saveDraftComments();
    });
  }

  function handleUnfreezeComment() {
    unfreezeComment(this);
  }

  function unfreezeComment(comment) {
    var unfrozen_comment = $(comment).prev();
    unfrozen_comment.show();
    $(comment).remove();
    unfrozen_comment.find('textarea')[0].focus();
  }

  function showFileDiffLinks() {
    $('.LinkContainer', this).each(function() { this.style.opacity = 1; });
  }

  function hideFileDiffLinks() {
    $('.LinkContainer', this).each(function() { this.style.opacity = 0; });
  }

  function handleDiscardComment() {
    discardComment($(this).parents('.comment'));
  }
  
  function handleAcceptComment() {
    acceptComment($(this).parents('.comment'));
  }
  
  function acceptComment(comment) {
    var frozen_comment = freezeComment($(comment));
    focusOn(frozen_comment);
    saveDraftComments();
    return frozen_comment;
  }

  $('.FileDiff').live('mouseenter', showFileDiffLinks);
  $('.FileDiff').live('mouseleave', hideFileDiffLinks);
  $('.side-by-side-link').live('click', handleSideBySideLinkClick);
  $('.unify-link').live('click', handleUnifyLinkClick);
  $('.ExpandLink').live('click', handleExpandLinkClick);
  $('.frozenComment').live('click', handleUnfreezeComment);
  $('.comment .discard').live('click', handleDiscardComment);
  $('.comment .ok').live('click', handleAcceptComment);
  $('.more').live('click', showMoreHelp);
  $('.more-help .winter').live('click', hideMoreHelp);

  function freezeComment(comment_block) {
    var comment_textarea = comment_block.find('textarea');
    if (comment_textarea.val().trim() == '') {
      discardComment(comment_block);
      return;
    }
    var line_id = comment_textarea.attr('data-comment-for');
    var line = $('#' + line_id)
    var frozen_comment = $('<div class="frozenComment"></div>').text(comment_textarea.val());
    findCommentBlockFor(line).hide().after(frozen_comment);
    return frozen_comment;
  }

  function focusOn(node, opt_is_backward) {
    if (node.length == 0)
      return;

    // Give a tabindex so the element can receive actual browser focus.
    // -1 makes the element focusable without actually putting in in the tab order.
    node.attr('tabindex', -1);
    node.focus();
    // Remove the tabindex on blur to avoid having the node be mouse-focusable.
    node.bind('blur', function() { node.removeAttr('tabindex'); });
    
    var node_top = node.offset().top;
    var is_top_offscreen = node_top <= $(document).scrollTop();
    
    var half_way_point = $(document).scrollTop() + window.innerHeight / 2;
    var is_top_past_halfway = opt_is_backward ? node_top < half_way_point : node_top > half_way_point;

    if (is_top_offscreen || is_top_past_halfway)
      $(document).scrollTop(node_top - window.innerHeight / 2);
  }

  function visibleNodeFilterFunction(is_backward) {
    var y = is_backward ? $('#toolbar')[0].offsetTop - 1 : 0;
    var x = window.innerWidth / 2;
    var reference_element = document.elementFromPoint(x, y);

    if (reference_element.nodeName == 'HTML' || reference_element.nodeName == 'BODY') {
      // In case we hit test a margin between file diffs, shift a fudge factor and try again.
      // FIXME: Is there a better way to do this?
      var file_diffs = $('.FileDiff');
      var first_diff = file_diffs.first();
      var second_diff = $(file_diffs[1]);
      var distance_between_file_diffs = second_diff.position().top - first_diff.position().top - first_diff.height();

      if (is_backward)
        y -= distance_between_file_diffs;
      else
        y += distance_between_file_diffs;

      reference_element = document.elementFromPoint(x, y);
    }

    if (reference_element.nodeName == 'HTML' || reference_element.nodeName == 'BODY')
      return null;
    
    return function(node) {
      var compare = reference_element.compareDocumentPosition(node[0]);
      if (is_backward)
        return compare & Node.DOCUMENT_POSITION_PRECEDING;
      return compare & Node.DOCUMENT_POSITION_FOLLOWING;
    }
  }

  function focusNext(filter, direction) {
    var focusable_nodes = $('a,.Line,.frozenComment,.previousComment,.DiffBlock,.overallComments').filter(function() {
      return !$(this).hasClass('DiffBlock') || $('.add,.remove', this).size();
    });

    var is_backward = direction == DIRECTION.BACKWARD;
    var index = focusable_nodes.index($(document.activeElement));
    
    var extra_filter = null;

    if (index == -1) {
      if (is_backward)
        index = focusable_nodes.length;
      extra_filter = visibleNodeFilterFunction(is_backward);
    }

    var offset = is_backward ? -1 : 1;
    var end = is_backward ? -1 : focusable_nodes.size();
    for (var i = index + offset; i != end; i = i + offset) {
      var node = $(focusable_nodes[i]);
      if (filter(node) && (!extra_filter || extra_filter(node))) {
        focusOn(node, is_backward);
        return true;
      }
    }
    return false;
  }

  var DIRECTION = {FORWARD: 1, BACKWARD: 2};

  function isComment(node) {
    return node.hasClass('frozenComment') || node.hasClass('previousComment') || node.hasClass('overallComments');
  }
  
  function isDiffBlock(node) {
    return node.hasClass('DiffBlock');
  }
  
  function isLine(node) {
    return node.hasClass('Line');
  }

  function commentTextareaForKeyTarget(key_target) {
    if (key_target.nodeName == 'TEXTAREA')
      return $(key_target);

    var comment_textarea = $(document.activeElement).prev().find('textarea');
    if (!comment_textarea.size())
      return null;
    return comment_textarea;
  }

  function extendCommentContextUp(key_target) {
    var comment_textarea = commentTextareaForKeyTarget(key_target);
    if (!comment_textarea)
      return;

    var comment_base_line = comment_textarea.attr('data-comment-for');
    var diff_section = diffSectionFor(comment_textarea);
    var lines = $('.Line', diff_section);
    for (var i = 0; i < lines.length - 1; i++) {
      if (hasDataCommentBaseLine(lines[i + 1], comment_base_line)) {
        addDataCommentBaseLine(lines[i], comment_base_line);
        break;
      }
    }
  }

  function shrinkCommentContextDown(key_target) {
    var comment_textarea = commentTextareaForKeyTarget(key_target);
    if (!comment_textarea)
      return;

    var comment_base_line = comment_textarea.attr('data-comment-for');
    var diff_section = diffSectionFor(comment_textarea);
    var lines = contextLinesFor(comment_base_line, diff_section);
    if (lines.size() > 1)
      removeDataCommentBaseLine(lines[0], comment_base_line);
  }

  function handleModifyContextKey(e) {
    var handled = false;

    if (e.shiftKey && e.ctrlKey) {
      switch (e.keyCode) {
      case KEY_CODE.up:
        extendCommentContextUp(e.target);
        handled = true;
        break;

      case KEY_CODE.down:
        shrinkCommentContextDown(e.target);
        handled = true;
        break;
      }
    }

    if (handled)
      e.preventDefault();

    return handled;
  }

  $('textarea').live('keydown', function(e) {
    if (handleModifyContextKey(e))
      return;

    if (e.keyCode == KEY_CODE.escape)
      handleEscapeKeyInTextarea(this);
  });

  $('body').live('keydown', function(e) {
    // FIXME: There's got to be a better way to avoid seeing these keypress
    // events.
    if (e.target.nodeName == 'TEXTAREA')
      return;

    // Don't want to override browser shortcuts like ctrl+r.
    if (e.metaKey || e.ctrlKey)
      return;

    if (handleModifyContextKey(e))
      return;

    var handled = false;
    switch (e.keyCode) {
    case KEY_CODE.r:
      $('.review select').focus();
      handled = true;
      break;

    case KEY_CODE.n:
      handled = focusNext(isComment, DIRECTION.FORWARD);
      break;

    case KEY_CODE.p:
      handled = focusNext(isComment, DIRECTION.BACKWARD);
      break;

    case KEY_CODE.j:
      if (e.shiftKey)
        handled = focusNext(isLine, DIRECTION.FORWARD);
      else
        handled = focusNext(isDiffBlock, DIRECTION.FORWARD);
      break;

    case KEY_CODE.k:
      if (e.shiftKey)
        handled = focusNext(isLine, DIRECTION.BACKWARD);
      else
        handled = focusNext(isDiffBlock, DIRECTION.BACKWARD);
      break;
      
    case KEY_CODE.enter:
      handled = handleEnterKey();
      break;
      
    case KEY_CODE.escape:
      hideMoreHelp();
      handled = true;
      break;
    }
    
    if (handled)
      e.preventDefault();
  });
  
  function handleEscapeKeyInTextarea(textarea) {
    var comment = $(textarea).parents('.comment');
    if (comment.size())
      acceptComment(comment);

    textarea.blur();
    document.body.focus();
  }
  
  function handleEnterKey() {
    if (document.activeElement.nodeName == 'BODY')
      return;

    var focused = $(document.activeElement);

    if (focused.hasClass('frozenComment')) {
      unfreezeComment(focused);
      return true;
    }
    
    if (focused.hasClass('overallComments')) {
      openOverallComments();
      focused.find('textarea')[0].focus();
      return true;
    }
    
    if (focused.hasClass('previousComment')) {
      addCommentField(focused);
      return true;
    }

    var lines = focused.hasClass('Line') ? focused : $('.Line', focused);
    var last = lines.last();
    if (last.attr('data-has-comment')) {
      unfreezeCommentFor(last);
      return true;
    }

    addCommentForLines(lines);
    return true;
  }

  function contextLinesFor(comment_base_lines, file_diff) {
    var base_lines = comment_base_lines.split(' ');
    return $('div[data-comment-base-line]', file_diff).filter(function() {
      return $(this).attr('data-comment-base-line').split(' ').some(function(item) {
        return base_lines.indexOf(item) != -1;
      });
    });
  }

  function numberFrom(line_id) {
    return Number(line_id.replace('line', ''));
  }

  function trimCommentContextToBefore(line, comment_base_line) {
    var line_to_trim_to = numberFrom(line.attr('id'));
    contextLinesFor(comment_base_line, fileDiffFor(line)).each(function() {
      var id = $(this).attr('id');
      if (numberFrom(id) > line_to_trim_to)
        return;

      if (!$('[data-comment-for=' + comment_base_line + ']').length)
        removeDataCommentBaseLine(this, comment_base_line);
    });
  }

  var drag_select_start_index = -1;

  function lineOffsetFrom(line, offset) {
    var file_diff = line.parents('.FileDiff');
    var all_lines = $('.Line', file_diff);
    var index = all_lines.index(line);
    return $(all_lines[index + offset]);
  }

  function previousLineFor(line) {
    return lineOffsetFrom(line, -1);
  }

  function nextLineFor(line) {
    return lineOffsetFrom(line, 1);
  }

  $('.resizeHandle').live('mousedown', function(event) {
    file_diff_being_resized = $(this).parent('.FileDiff');
  });

  function generateFileDiffResizeStyleElement() {
    // FIXME: Once we support calc, we can replace this with something that uses the attribute value.
    var styleText = '';
    for (var i = minLeftSideRatio; i <= maxLeftSideRatio; i++) {
      // FIXME: Once we support calc, put the resize handle at calc(i% - 5) so it doesn't cover up
      // the right-side line numbers.
      styleText += '.FileDiff[leftsidewidth="' + i + '"] .resizeHandle {' +
        'left: ' + i + '%' +
      '}' +
      '.FileDiff[leftsidewidth="' + i + '"] .LineSide:first-child,' +
      '.FileDiff[leftsidewidth="' + i + '"].sidebyside .DiffBlockPart.remove {' +
        'width:' + i + '%;' +
      '}' +
      '.FileDiff[leftsidewidth="' + i + '"] .LineSide:last-child,' +
      '.FileDiff[leftsidewidth="' + i + '"].sidebyside .DiffBlockPart.add {' +
        'width:' + (100 - i) + '%;' +
      '}';
    }
    var styleElement = document.createElement('style');
    styleElement.innerText = styleText;
    document.head.appendChild(styleElement);
  }

  $(document).bind('mousemove', function(event) {
    if (!file_diff_being_resized)
      return;

    var ratio = event.pageX / window.innerWidth;
    var percentage = Math.floor(ratio * 100);
    if (percentage < minLeftSideRatio)
      percentage = minLeftSideRatio;
    if (percentage > maxLeftSideRatio)
      percentage = maxLeftSideRatio;
    file_diff_being_resized.attr('leftsidewidth', percentage);
    event.preventDefault();
  });

  $(document).bind('mouseup', function(event) {
    file_diff_being_resized = null;
    processSelectedLines();
  });

  $('.lineNumber').live('click', function(e) {
    var line = lineFromLineDescendant($(this));
    if (line.hasClass('commentContext')) {
      var previous_line = previousLineFor(line);
      if (previous_line[0])
        trimCommentContextToBefore(previous_line, line.attr('data-comment-base-line'));
    } else if (e.shiftKey)
      extendCommentContextTo(line);
  }).live('mousedown', function(e) {
    // preventDefault to avoid selecting text when dragging to select comment context lines.
    // FIXME: should we use user-modify CSS instead?
    e.preventDefault();
    if (e.shiftKey)
      return;

    var line = lineFromLineDescendant($(this));
    if (line.hasClass('context'))
      return;

    drag_select_start_index = numberFrom(line.attr('id'));
    line.addClass('selected');
  });

  $('.LineContainer:not(.context)').live('mouseenter', function(e) {
    if (drag_select_start_index == -1 || e.shiftKey)
      return;
    selectToLineContainer(this);
  }).live('mouseup', function(e) {
    if (drag_select_start_index == -1 || e.shiftKey)
      return;

    selectToLineContainer(this);
    processSelectedLines();
  });

  function extendCommentContextTo(line) {
    var diff_section = diffSectionFor(line);
    var lines = $('.Line', diff_section);
    var lines_to_modify = [];
    var have_seen_start_line = false;
    var data_comment_base_line = null;
    lines.each(function() {
      if (data_comment_base_line)
        return;

      have_seen_start_line = have_seen_start_line || this == line[0];
      
      if (have_seen_start_line) {
        if ($(this).hasClass('commentContext'))
          data_comment_base_line = $(this).attr('data-comment-base-line');
        else
          lines_to_modify.push(this);
      }
    });
    
    // There is no comment context to extend.
    if (!data_comment_base_line)
      return;
    
    $(lines_to_modify).each(function() {
      $(this).addClass('commentContext');
      $(this).attr('data-comment-base-line', data_comment_base_line);
    });
  }

  function selectTo(focus_index) {
    var selected = $('.selected').removeClass('selected');
    var is_backward = drag_select_start_index > focus_index;
    var current_index = is_backward ? focus_index : drag_select_start_index;
    var last_index = is_backward ? drag_select_start_index : focus_index;
    while (current_index <= last_index) {
      $('#line' + current_index).addClass('selected')
      current_index++;
    }
  }

  function selectToLineContainer(line_container) {
    var line = lineFromLineContainer(line_container);

    // Ensure that the selected lines are all contained in the same DiffSection.
    var selected_lines = $('.selected');
    var selected_diff_section = diffSectionFor(selected_lines.first());
    var new_diff_section = diffSectionFor(line);
    if (new_diff_section[0] != selected_diff_section[0]) {
      var lines = $('.Line', selected_diff_section);
      if (numberFrom(selected_lines.first().attr('id')) == drag_select_start_index)
        line = lines.last();
      else
        line = lines.first();
    }
    
    selectTo(numberFrom(line.attr('id')));
  }

  function processSelectedLines() {
    drag_select_start_index = -1;
    addCommentForLines($('.selected'));
  }
  
  function addCommentForLines(lines) {    
    if (!lines.size())
      return;

    var already_has_comment = lines.last().hasClass('commentContext');

    var comment_base_line;
    if (already_has_comment)
      comment_base_line = lines.last().attr('data-comment-base-line');
    else {
      var last = lineFromLineDescendant(lines.last());
      addCommentFor($(last));
      comment_base_line = last.attr('id');
    }

    lines.each(function() {
      addDataCommentBaseLine(this, comment_base_line);
      $(this).removeClass('selected');
    });

    saveDraftComments();
  }

  function hasDataCommentBaseLine(line, id) {
    var val = $(line).attr('data-comment-base-line');
    if (!val)
      return false;

    var parts = val.split(' ');
    for (var i = 0; i < parts.length; i++) {
      if (parts[i] == id)
        return true;
    }
    return false;
  }

  function addDataCommentBaseLine(line, id) {
    $(line).addClass('commentContext');
    if (hasDataCommentBaseLine(line, id))
      return;

    var val = $(line).attr('data-comment-base-line');
    var parts = val ? val.split(' ') : [];
    parts.push(id);
    $(line).attr('data-comment-base-line', parts.join(' '));
  }

  function removeDataCommentBaseLine(line, comment_base_lines) {
    var val = $(line).attr('data-comment-base-line');
    if (!val)
      return;

    var base_lines = comment_base_lines.split(' ');
    var parts = val.split(' ');
    var new_parts = [];
    for (var i = 0; i < parts.length; i++) {
      if (base_lines.indexOf(parts[i]) == -1)
        new_parts.push(parts[i]);
    }

    var new_comment_base_line = new_parts.join(' ');
    if (new_comment_base_line)
      $(line).attr('data-comment-base-line', new_comment_base_line);
    else {
      $(line).removeAttr('data-comment-base-line');
      $(line).removeClass('commentContext');
    }
  }

  function lineFromLineDescendant(descendant) {
    return descendant.hasClass('Line') ? descendant : descendant.parents('.Line');
  }

  function lineContainerFromDescendant(descendant) {
    return descendant.hasClass('LineContainer') ? descendant : descendant.parents('.LineContainer');
  }

  function lineFromLineContainer(lineContainer) {
    var line = $(lineContainer);
    if (!line.hasClass('Line'))
      line = $('.Line', line);
    return line;
  }

  function contextSnippetFor(line, indent) {
    var snippets = []
    contextLinesFor(line.attr('id'), fileDiffFor(line)).each(function() {
      var action = ' ';
      if ($(this).hasClass('add'))
        action = '+';
      else if ($(this).hasClass('remove'))
        action = '-';
      snippets.push(indent + action + textContentsFor(this));
    });
    return snippets.join('\n');
  }

  function fileNameFor(line) {
    return fileDiffFor(line).find('h1').text();
  }

  function indentFor(depth) {
    return (new Array(depth + 1)).join('>') + ' ';
  }

  function snippetFor(line, indent) {
    var file_name = fileNameFor(line);
    var line_number = line.hasClass('remove') ? '-' + fromLineNumber(line[0]) : toLineNumber(line[0]);
    return indent + file_name + ':' + line_number + '\n' + contextSnippetFor(line, indent);
  }

  function quotePreviousComments(comments) {
    var quoted_comments = [];
    var depth = comments.size();
    comments.each(function() {
      var indent = indentFor(depth--);
      var text = $(this).children('.content').text();
      quoted_comments.push(indent + '\n' + indent + text.split('\n').join('\n' + indent));
    });
    return quoted_comments.join('\n');
  }

  $('#comment_form .winter').live('click', hideCommentForm);

  function serializedComments() {
    var comments_in_context = []
    forEachLine(function(line) {
      if (line.attr('data-has-comment') != 'true')
        return;
      var comment = findCommentBlockFor(line).children('textarea').val().trim();
      if (comment == '')
        return;
      var previous_comments = previousCommentsFor(line);
      var snippet = snippetFor(line, indentFor(previous_comments.size() + 1));
      var quoted_comments = quotePreviousComments(previous_comments);
      var comment_with_context = [];
      comment_with_context.push(snippet);
      if (quoted_comments != '')
        comment_with_context.push(quoted_comments);
      comment_with_context.push('\n' + comment);
      comments_in_context.push(comment_with_context.join('\n'));
    });
    var comment = $('.overallComments textarea').val().trim();
    if (comment != '')
      comment += '\n\n';
    comment += comments_in_context.join('\n\n');
    if (comments_in_context.length > 0)
      comment = 'View in context: ' + window.location + '\n\n' + comment;
    return comment;
  }

  function fillInReviewForm() {
    var review_form = $('#reviewform').contents();
    review_form.find('#comment').val(serializedComments());
    review_form.find('#flags select').each(function() {
      var control = findControlForFlag(this);
      if (!control.size())
        return;
      $(this).attr('selectedIndex', control.attr('selectedIndex'));
    });
  }

  function showCommentForm() {
    $('#comment_form').removeClass('inactive');
    $('#reviewform').contents().find('#submitBtn').focus();
  }
  
  function hideCommentForm() {
    $('#comment_form').addClass('inactive');
    
    // Make sure the top document has focus so key events don't keep going to the review form.
    document.body.tabIndex = -1;
    document.body.focus();
  }

  $('#preview_comments').live('click', function() {
    fillInReviewForm();
    showCommentForm();
  });

  $('#post_comments').live('click', function() {
    fillInReviewForm();
    $('#reviewform').contents().find('form').submit();
  });
  
  if (CODE_REVIEW_UNITTEST) {
    window.DraftCommentSaver = DraftCommentSaver;
    window.addCommentFor = addCommentFor;
    window.addPreviousComment = addPreviousComment;
    window.tracLinks = tracLinks;
    window.crawlDiff = crawlDiff;
    window.convertAllFileDiffs = convertAllFileDiffs;
    window.sanitizeFragmentForCopy = sanitizeFragmentForCopy;
    window.displayPreviousComments = displayPreviousComments;
    window.discardComment = discardComment;
    window.addCommentField = addCommentField;
    window.acceptComment = acceptComment;
    window.appendToolbar = appendToolbar;
    window.eraseDraftComments = eraseDraftComments;
    window.serializedComments = serializedComments;
    window.setFileContents = setFileContents;
    window.unfreezeComment = unfreezeComment;
    window.g_draftCommentSaver = g_draftCommentSaver;
    window.isChangeLog = isChangeLog;
  } else {
    $(document).ready(handleDocumentReady)
  }
})();
