Summary: Ref T12733. Completely removes the objectives UI. Test Plan: - Grepped for `objective`, etc. - Browsed revisions, no JS errors / broken stuff. - (If I missed anything, it's likely to turn up in followup changes.) Reviewers: chad Reviewed By: chad Maniphest Tasks: T12733 Differential Revision: https://secure.phabricator.com/D18043
		
			
				
	
	
		
			706 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			706 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * @provides phabricator-diff-inline
 | 
						|
 * @requires javelin-dom
 | 
						|
 * @javelin
 | 
						|
 */
 | 
						|
 | 
						|
JX.install('DiffInline', {
 | 
						|
 | 
						|
  construct : function() {
 | 
						|
  },
 | 
						|
 | 
						|
  members: {
 | 
						|
    _id: null,
 | 
						|
    _phid: null,
 | 
						|
    _changesetID: null,
 | 
						|
    _row: null,
 | 
						|
    _hidden: false,
 | 
						|
    _number: null,
 | 
						|
    _length: null,
 | 
						|
    _displaySide: null,
 | 
						|
    _isNewFile: null,
 | 
						|
    _undoRow: null,
 | 
						|
    _replyToCommentPHID: null,
 | 
						|
    _originalText: null,
 | 
						|
    _snippet: null,
 | 
						|
 | 
						|
    _isDeleted: false,
 | 
						|
    _isInvisible: false,
 | 
						|
    _isLoading: false,
 | 
						|
 | 
						|
    _changeset: null,
 | 
						|
 | 
						|
    _isDraft: null,
 | 
						|
    _isFixed: null,
 | 
						|
    _isEditing: false,
 | 
						|
    _isNew: false,
 | 
						|
 | 
						|
    bindToRow: function(row) {
 | 
						|
      this._row = row;
 | 
						|
 | 
						|
      var row_data = JX.Stratcom.getData(row);
 | 
						|
      row_data.inline = this;
 | 
						|
      this._hidden = row_data.hidden || false;
 | 
						|
 | 
						|
      // TODO: Get smarter about this once we do more editing, this is pretty
 | 
						|
      // hacky.
 | 
						|
      var comment = JX.DOM.find(row, 'div', 'differential-inline-comment');
 | 
						|
      var data = JX.Stratcom.getData(comment);
 | 
						|
 | 
						|
      this._id = data.id;
 | 
						|
      this._phid = data.phid;
 | 
						|
 | 
						|
      // TODO: This is very, very, very, very, very, very, very hacky.
 | 
						|
      var td = comment.parentNode;
 | 
						|
      var th = td.previousSibling;
 | 
						|
      if (th.parentNode.firstChild != th) {
 | 
						|
        this._displaySide = 'right';
 | 
						|
      } else {
 | 
						|
        this._displaySide = 'left';
 | 
						|
      }
 | 
						|
 | 
						|
      this._number = parseInt(data.number, 10);
 | 
						|
      this._length = parseInt(data.length, 10);
 | 
						|
      this._originalText = data.original;
 | 
						|
      this._isNewFile =
 | 
						|
        (this.getDisplaySide() == 'right') ||
 | 
						|
        (data.left != data.right);
 | 
						|
 | 
						|
      this._replyToCommentPHID = data.replyToCommentPHID;
 | 
						|
 | 
						|
      this._isDraft = data.isDraft;
 | 
						|
      this._isFixed = data.isFixed;
 | 
						|
      this._isGhost = data.isGhost;
 | 
						|
 | 
						|
      this._changesetID = data.changesetID;
 | 
						|
      this._isNew = false;
 | 
						|
      this._snippet = data.snippet;
 | 
						|
 | 
						|
      this.setInvisible(false);
 | 
						|
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    bindToRange: function(data) {
 | 
						|
      this._displaySide = data.displaySide;
 | 
						|
      this._number = parseInt(data.number, 10);
 | 
						|
      this._length = parseInt(data.length, 10);
 | 
						|
      this._isNewFile = data.isNewFile;
 | 
						|
      this._changesetID = data.changesetID;
 | 
						|
      this._isNew = true;
 | 
						|
 | 
						|
      // Insert the comment after any other comments which already appear on
 | 
						|
      // the same row.
 | 
						|
      var parent_row = JX.DOM.findAbove(data.target, 'tr');
 | 
						|
      var target_row = parent_row.nextSibling;
 | 
						|
      while (target_row && JX.Stratcom.hasSigil(target_row, 'inline-row')) {
 | 
						|
        target_row = target_row.nextSibling;
 | 
						|
      }
 | 
						|
 | 
						|
      var row = this._newRow();
 | 
						|
      parent_row.parentNode.insertBefore(row, target_row);
 | 
						|
 | 
						|
      this.setInvisible(true);
 | 
						|
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    bindToReply: function(inline) {
 | 
						|
      this._displaySide = inline._displaySide;
 | 
						|
      this._number = inline._number;
 | 
						|
      this._length = inline._length;
 | 
						|
      this._isNewFile = inline._isNewFile;
 | 
						|
      this._changesetID = inline._changesetID;
 | 
						|
      this._isNew = true;
 | 
						|
 | 
						|
      this._replyToCommentPHID = inline._phid;
 | 
						|
 | 
						|
      var changeset = this.getChangeset();
 | 
						|
 | 
						|
      // We're going to figure out where in the document to position the new
 | 
						|
      // inline. Normally, it goes after any existing inline rows (so if
 | 
						|
      // several inlines reply to the same line, they appear in chronological
 | 
						|
      // order).
 | 
						|
 | 
						|
      // However: if inlines are threaded, we want to put the new inline in
 | 
						|
      // the right place in the thread. This might be somewhere in the middle,
 | 
						|
      // so we need to do a bit more work to figure it out.
 | 
						|
 | 
						|
      // To find the right place in the thread, we're going to look for any
 | 
						|
      // inline which is at or above the level of the comment we're replying
 | 
						|
      // to. This means we've reached a new fork of the thread, and should
 | 
						|
      // put our new inline before the comment we found.
 | 
						|
      var ancestor_map = {};
 | 
						|
      var ancestor = inline;
 | 
						|
      var reply_phid;
 | 
						|
      while (ancestor) {
 | 
						|
        reply_phid = ancestor.getReplyToCommentPHID();
 | 
						|
        if (!reply_phid) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        ancestor_map[reply_phid] = true;
 | 
						|
        ancestor = changeset.getInlineByPHID(reply_phid);
 | 
						|
      }
 | 
						|
 | 
						|
      var parent_row = inline._row;
 | 
						|
      var target_row = parent_row.nextSibling;
 | 
						|
      while (target_row && JX.Stratcom.hasSigil(target_row, 'inline-row')) {
 | 
						|
        var target = changeset.getInlineForRow(target_row);
 | 
						|
        reply_phid = target.getReplyToCommentPHID();
 | 
						|
 | 
						|
        // If we found an inline which is replying directly to some ancestor
 | 
						|
        // of this new comment, this is where the new rows go.
 | 
						|
        if (ancestor_map.hasOwnProperty(reply_phid)) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        target_row = target_row.nextSibling;
 | 
						|
      }
 | 
						|
 | 
						|
      var row = this._newRow();
 | 
						|
      parent_row.parentNode.insertBefore(row, target_row);
 | 
						|
 | 
						|
      this.setInvisible(true);
 | 
						|
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    setChangeset: function(changeset) {
 | 
						|
      this._changeset = changeset;
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    getChangeset: function() {
 | 
						|
      return this._changeset;
 | 
						|
    },
 | 
						|
 | 
						|
    setEditing: function(editing) {
 | 
						|
      this._isEditing = editing;
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    canReply: function() {
 | 
						|
      if (!this._hasAction('reply')) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
 | 
						|
      return true;
 | 
						|
    },
 | 
						|
 | 
						|
    canEdit: function() {
 | 
						|
      if (!this._hasAction('edit')) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
 | 
						|
      return true;
 | 
						|
    },
 | 
						|
 | 
						|
    canDone: function() {
 | 
						|
      if (!JX.DOM.scry(this._row, 'input', 'differential-inline-done').length) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
 | 
						|
      return true;
 | 
						|
    },
 | 
						|
 | 
						|
    canHide: function() {
 | 
						|
      if (!JX.DOM.scry(this._row, 'a', 'hide-inline').length) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
 | 
						|
      return true;
 | 
						|
    },
 | 
						|
 | 
						|
    getRawText: function() {
 | 
						|
      return this._originalText;
 | 
						|
    },
 | 
						|
 | 
						|
    _hasAction: function(action) {
 | 
						|
      var nodes = JX.DOM.scry(this._row, 'a', 'differential-inline-' + action);
 | 
						|
      return (nodes.length > 0);
 | 
						|
    },
 | 
						|
 | 
						|
    _newRow: function() {
 | 
						|
      var attributes = {
 | 
						|
        sigil: 'inline-row'
 | 
						|
      };
 | 
						|
 | 
						|
      var row = JX.$N('tr', attributes);
 | 
						|
 | 
						|
      JX.Stratcom.getData(row).inline = this;
 | 
						|
      this._row = row;
 | 
						|
 | 
						|
      this._id = null;
 | 
						|
      this._phid = null;
 | 
						|
      this._hidden = false;
 | 
						|
 | 
						|
      this._originalText = null;
 | 
						|
 | 
						|
      return row;
 | 
						|
    },
 | 
						|
 | 
						|
    setHidden: function(hidden) {
 | 
						|
      this._hidden = hidden;
 | 
						|
 | 
						|
      JX.DOM.alterClass(this._row, 'inline-hidden', this._hidden);
 | 
						|
 | 
						|
      var op;
 | 
						|
      if (hidden) {
 | 
						|
        op = 'hide';
 | 
						|
      } else {
 | 
						|
        op = 'show';
 | 
						|
      }
 | 
						|
 | 
						|
      var inline_uri = this._getInlineURI();
 | 
						|
      var comment_id = this._id;
 | 
						|
 | 
						|
      new JX.Workflow(inline_uri, {op: op, ids: comment_id})
 | 
						|
        .setHandler(JX.bag)
 | 
						|
        .start();
 | 
						|
 | 
						|
      this._didUpdate(true);
 | 
						|
    },
 | 
						|
 | 
						|
    isHidden: function() {
 | 
						|
      return this._hidden;
 | 
						|
    },
 | 
						|
 | 
						|
    toggleDone: function() {
 | 
						|
      var uri = this._getInlineURI();
 | 
						|
      var data = {
 | 
						|
        op: 'done',
 | 
						|
        id: this._id
 | 
						|
      };
 | 
						|
 | 
						|
      var ondone = JX.bind(this, this._ondone);
 | 
						|
 | 
						|
      new JX.Workflow(uri, data)
 | 
						|
        .setHandler(ondone)
 | 
						|
        .start();
 | 
						|
    },
 | 
						|
 | 
						|
    _ondone: function(response) {
 | 
						|
      var checkbox = JX.DOM.find(
 | 
						|
        this._row,
 | 
						|
        'input',
 | 
						|
        'differential-inline-done');
 | 
						|
 | 
						|
      checkbox.checked = (response.isChecked ? 'checked' : null);
 | 
						|
 | 
						|
      var comment = JX.DOM.findAbove(
 | 
						|
        checkbox,
 | 
						|
        'div',
 | 
						|
        'differential-inline-comment');
 | 
						|
 | 
						|
      JX.DOM.alterClass(comment, 'inline-is-done', response.isChecked);
 | 
						|
 | 
						|
      // NOTE: This is marking the inline as having an unsubmitted checkmark,
 | 
						|
      // as opposed to a submitted checkmark. This is different from the
 | 
						|
      // top-level "draft" state of unsubmitted comments.
 | 
						|
      JX.DOM.alterClass(comment, 'inline-state-is-draft', response.draftState);
 | 
						|
 | 
						|
      this._isFixed = response.isChecked;
 | 
						|
 | 
						|
      this._didUpdate();
 | 
						|
    },
 | 
						|
 | 
						|
    create: function(text) {
 | 
						|
      var uri = this._getInlineURI();
 | 
						|
      var handler = JX.bind(this, this._oncreateresponse);
 | 
						|
      var data = this._newRequestData('new', text);
 | 
						|
 | 
						|
      this.setLoading(true);
 | 
						|
 | 
						|
      new JX.Request(uri, handler)
 | 
						|
        .setData(data)
 | 
						|
        .send();
 | 
						|
    },
 | 
						|
 | 
						|
    reply: function(text) {
 | 
						|
      var changeset = this.getChangeset();
 | 
						|
      return changeset.newInlineReply(this, text);
 | 
						|
    },
 | 
						|
 | 
						|
    edit: function(text) {
 | 
						|
      var uri = this._getInlineURI();
 | 
						|
      var handler = JX.bind(this, this._oneditresponse);
 | 
						|
      var data = this._newRequestData('edit', text || null);
 | 
						|
 | 
						|
      this.setLoading(true);
 | 
						|
 | 
						|
      new JX.Request(uri, handler)
 | 
						|
        .setData(data)
 | 
						|
        .send();
 | 
						|
    },
 | 
						|
 | 
						|
    delete: function(is_ref) {
 | 
						|
      var uri = this._getInlineURI();
 | 
						|
      var handler = JX.bind(this, this._ondeleteresponse);
 | 
						|
 | 
						|
      // NOTE: This may be a direct delete (the user clicked on the inline
 | 
						|
      // itself) or a "refdelete" (the user clicked somewhere else, like the
 | 
						|
      // preview, but the inline is present on the page).
 | 
						|
 | 
						|
      // For a "refdelete", we prompt the user to confirm that they want to
 | 
						|
      // delete the comment, because they can not undo deletions from the
 | 
						|
      // preview. We could jump the user to the inline instead, but this would
 | 
						|
      // be somewhat disruptive and make deleting several comments more
 | 
						|
      // difficult.
 | 
						|
 | 
						|
      var op;
 | 
						|
      if (is_ref) {
 | 
						|
        op = 'refdelete';
 | 
						|
      } else {
 | 
						|
        op = 'delete';
 | 
						|
      }
 | 
						|
 | 
						|
      var data = this._newRequestData(op);
 | 
						|
 | 
						|
      this.setLoading(true);
 | 
						|
 | 
						|
      new JX.Workflow(uri, data)
 | 
						|
        .setHandler(handler)
 | 
						|
        .start();
 | 
						|
    },
 | 
						|
 | 
						|
    getDisplaySide: function() {
 | 
						|
      return this._displaySide;
 | 
						|
    },
 | 
						|
 | 
						|
    getLineNumber: function() {
 | 
						|
      return this._number;
 | 
						|
    },
 | 
						|
 | 
						|
    getLineLength: function() {
 | 
						|
      return this._length;
 | 
						|
    },
 | 
						|
 | 
						|
    isNewFile: function() {
 | 
						|
      return this._isNewFile;
 | 
						|
    },
 | 
						|
 | 
						|
    getID: function() {
 | 
						|
      return this._id;
 | 
						|
    },
 | 
						|
 | 
						|
    getPHID: function() {
 | 
						|
      return this._phid;
 | 
						|
    },
 | 
						|
 | 
						|
    getChangesetID: function() {
 | 
						|
      return this._changesetID;
 | 
						|
    },
 | 
						|
 | 
						|
    getReplyToCommentPHID: function() {
 | 
						|
      return this._replyToCommentPHID;
 | 
						|
    },
 | 
						|
 | 
						|
    setDeleted: function(deleted) {
 | 
						|
      this._isDeleted = deleted;
 | 
						|
      this._redraw();
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    setInvisible: function(invisible) {
 | 
						|
      this._isInvisible = invisible;
 | 
						|
      this._redraw();
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    setLoading: function(loading) {
 | 
						|
      this._isLoading = loading;
 | 
						|
      this._redraw();
 | 
						|
      return this;
 | 
						|
    },
 | 
						|
 | 
						|
    _newRequestData: function(operation, text) {
 | 
						|
      return {
 | 
						|
        op: operation,
 | 
						|
        id: this._id,
 | 
						|
        on_right: ((this.getDisplaySide() == 'right') ? 1 : 0),
 | 
						|
        renderer: this.getChangeset().getRenderer(),
 | 
						|
        number: this.getLineNumber(),
 | 
						|
        length: this.getLineLength(),
 | 
						|
        is_new: this.isNewFile(),
 | 
						|
        changesetID: this.getChangesetID(),
 | 
						|
        replyToCommentPHID: this.getReplyToCommentPHID() || '',
 | 
						|
        text: text || ''
 | 
						|
      };
 | 
						|
    },
 | 
						|
 | 
						|
    _oneditresponse: function(response) {
 | 
						|
      var rows = JX.$H(response).getNode();
 | 
						|
 | 
						|
      this._drawEditRows(rows);
 | 
						|
 | 
						|
      this.setLoading(false);
 | 
						|
      this.setInvisible(true);
 | 
						|
    },
 | 
						|
 | 
						|
    _oncreateresponse: function(response) {
 | 
						|
      var rows = JX.$H(response).getNode();
 | 
						|
 | 
						|
      this._drawEditRows(rows);
 | 
						|
    },
 | 
						|
 | 
						|
    _ondeleteresponse: function() {
 | 
						|
      this._drawUndeleteRows();
 | 
						|
 | 
						|
      this.setLoading(false);
 | 
						|
      this.setDeleted(true);
 | 
						|
 | 
						|
      this._didUpdate();
 | 
						|
    },
 | 
						|
 | 
						|
    _drawUndeleteRows: function() {
 | 
						|
      return this._drawUndoRows('undelete', this._row);
 | 
						|
    },
 | 
						|
 | 
						|
    _drawUneditRows: function(text) {
 | 
						|
      return this._drawUndoRows('unedit', null, text);
 | 
						|
    },
 | 
						|
 | 
						|
    _drawUndoRows: function(mode, cursor, text) {
 | 
						|
      var templates = this.getChangeset().getUndoTemplates();
 | 
						|
 | 
						|
      var template;
 | 
						|
      if (this.getDisplaySide() == 'right') {
 | 
						|
        template = templates.r;
 | 
						|
      } else {
 | 
						|
        template = templates.l;
 | 
						|
      }
 | 
						|
      template = JX.$H(template).getNode();
 | 
						|
 | 
						|
      this._undoRow = this._drawRows(template, cursor, mode, text);
 | 
						|
    },
 | 
						|
 | 
						|
    _drawContentRows: function(rows) {
 | 
						|
      return this._drawRows(rows, null, 'content');
 | 
						|
    },
 | 
						|
 | 
						|
    _drawEditRows: function(rows) {
 | 
						|
      this.setEditing(true);
 | 
						|
      return this._drawRows(rows, null, 'edit');
 | 
						|
    },
 | 
						|
 | 
						|
    _drawRows: function(rows, cursor, type, text) {
 | 
						|
      var first_row = JX.DOM.scry(rows, 'tr')[0];
 | 
						|
      var first_meta;
 | 
						|
      var row = first_row;
 | 
						|
      var anchor = cursor || this._row;
 | 
						|
      cursor = cursor || this._row.nextSibling;
 | 
						|
 | 
						|
      var next_row;
 | 
						|
      while (row) {
 | 
						|
        // Grab this first, since it's going to change once we insert the row
 | 
						|
        // into the document.
 | 
						|
        next_row = row.nextSibling;
 | 
						|
 | 
						|
        // Bind edit and undo rows to this DiffInline object so that
 | 
						|
        // interactions like hovering work properly.
 | 
						|
        JX.Stratcom.getData(row).inline = this;
 | 
						|
 | 
						|
        anchor.parentNode.insertBefore(row, cursor);
 | 
						|
        cursor = row;
 | 
						|
 | 
						|
        var row_meta = {
 | 
						|
          node: row,
 | 
						|
          type: type,
 | 
						|
          text: text || null,
 | 
						|
          listeners: []
 | 
						|
        };
 | 
						|
 | 
						|
        if (!first_meta) {
 | 
						|
          first_meta = row_meta;
 | 
						|
        }
 | 
						|
 | 
						|
        if (type == 'edit') {
 | 
						|
          row_meta.listeners.push(
 | 
						|
            JX.DOM.listen(
 | 
						|
              row,
 | 
						|
              ['submit', 'didSyntheticSubmit'],
 | 
						|
              'inline-edit-form',
 | 
						|
              JX.bind(this, this._onsubmit, row_meta)));
 | 
						|
 | 
						|
          row_meta.listeners.push(
 | 
						|
            JX.DOM.listen(
 | 
						|
              row,
 | 
						|
              'click',
 | 
						|
              'inline-edit-cancel',
 | 
						|
              JX.bind(this, this._oncancel, row_meta)));
 | 
						|
        } else if (type == 'content') {
 | 
						|
          // No special listeners for these rows.
 | 
						|
        } else {
 | 
						|
          row_meta.listeners.push(
 | 
						|
            JX.DOM.listen(
 | 
						|
              row,
 | 
						|
              'click',
 | 
						|
              'differential-inline-comment-undo',
 | 
						|
              JX.bind(this, this._onundo, row_meta)));
 | 
						|
        }
 | 
						|
 | 
						|
        // If the row has a textarea, focus it. This allows the user to start
 | 
						|
        // typing a comment immediately after a "new", "edit", or "reply"
 | 
						|
        // action.
 | 
						|
        var textareas = JX.DOM.scry(
 | 
						|
          row,
 | 
						|
          'textarea',
 | 
						|
          'differential-inline-comment-edit-textarea');
 | 
						|
        if (textareas.length) {
 | 
						|
          var area = textareas[0];
 | 
						|
          area.focus();
 | 
						|
 | 
						|
          var length = area.value.length;
 | 
						|
          JX.TextAreaUtils.setSelectionRange(area, length, length);
 | 
						|
        }
 | 
						|
 | 
						|
        row = next_row;
 | 
						|
      }
 | 
						|
 | 
						|
      JX.Stratcom.invoke('resize');
 | 
						|
 | 
						|
      return first_meta;
 | 
						|
    },
 | 
						|
 | 
						|
    _onsubmit: function(row, e) {
 | 
						|
      e.kill();
 | 
						|
 | 
						|
      var handler = JX.bind(this, this._onsubmitresponse, row);
 | 
						|
 | 
						|
      this.setLoading(true);
 | 
						|
 | 
						|
      JX.Workflow.newFromForm(e.getTarget())
 | 
						|
        .setHandler(handler)
 | 
						|
        .start();
 | 
						|
    },
 | 
						|
 | 
						|
    _onundo: function(row, e) {
 | 
						|
      e.kill();
 | 
						|
 | 
						|
      this._removeRow(row);
 | 
						|
 | 
						|
      if (row.type == 'undelete') {
 | 
						|
        var uri = this._getInlineURI();
 | 
						|
        var data = this._newRequestData('undelete');
 | 
						|
        var handler = JX.bind(this, this._onundelete);
 | 
						|
 | 
						|
        this.setDeleted(false);
 | 
						|
        this.setLoading(true);
 | 
						|
 | 
						|
        new JX.Request(uri, handler)
 | 
						|
          .setData(data)
 | 
						|
          .send();
 | 
						|
      }
 | 
						|
 | 
						|
      if (row.type == 'unedit') {
 | 
						|
        if (this.getID()) {
 | 
						|
          this.edit(row.text);
 | 
						|
        } else {
 | 
						|
          this.create(row.text);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    _onundelete: function() {
 | 
						|
      this.setLoading(false);
 | 
						|
      this._didUpdate();
 | 
						|
    },
 | 
						|
 | 
						|
    _oncancel: function(row, e) {
 | 
						|
      e.kill();
 | 
						|
 | 
						|
      var text = this._readText(row.node);
 | 
						|
      if (text && text.length && (text != this._originalText)) {
 | 
						|
        this._drawUneditRows(text);
 | 
						|
      }
 | 
						|
 | 
						|
      this._removeRow(row);
 | 
						|
      this.setEditing(false);
 | 
						|
 | 
						|
      this.setInvisible(false);
 | 
						|
 | 
						|
      this._didUpdate(true);
 | 
						|
    },
 | 
						|
 | 
						|
    _readText: function(row) {
 | 
						|
      var textarea;
 | 
						|
      try {
 | 
						|
        textarea = JX.DOM.find(
 | 
						|
          row,
 | 
						|
          'textarea',
 | 
						|
          'differential-inline-comment-edit-textarea');
 | 
						|
      } catch (ex) {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
 | 
						|
      return textarea.value;
 | 
						|
    },
 | 
						|
 | 
						|
    _onsubmitresponse: function(row, response) {
 | 
						|
      this._removeRow(row);
 | 
						|
 | 
						|
      this.setLoading(false);
 | 
						|
      this.setInvisible(false);
 | 
						|
      this.setEditing(false);
 | 
						|
 | 
						|
      this._onupdate(response);
 | 
						|
    },
 | 
						|
 | 
						|
    _onupdate: function(response) {
 | 
						|
      var new_row;
 | 
						|
      if (response.markup) {
 | 
						|
        new_row = this._drawContentRows(JX.$H(response.markup).getNode()).node;
 | 
						|
      }
 | 
						|
 | 
						|
      // TODO: Save the old row so the action it's undo-able if it was a
 | 
						|
      // delete.
 | 
						|
      var remove_old = true;
 | 
						|
      if (remove_old) {
 | 
						|
        JX.DOM.remove(this._row);
 | 
						|
      }
 | 
						|
 | 
						|
      this.bindToRow(new_row);
 | 
						|
 | 
						|
      this._didUpdate();
 | 
						|
    },
 | 
						|
 | 
						|
    _didUpdate: function(local_only) {
 | 
						|
      // After making changes to inline comments, refresh the transaction
 | 
						|
      // preview at the bottom of the page.
 | 
						|
      if (!local_only) {
 | 
						|
        this.getChangeset().getChangesetList().redrawPreview();
 | 
						|
      }
 | 
						|
 | 
						|
      this.getChangeset().getChangesetList().redrawCursor();
 | 
						|
      this.getChangeset().getChangesetList().resetHover();
 | 
						|
 | 
						|
      // Emit a resize event so that UI elements like the keyboard focus
 | 
						|
      // reticle can redraw properly.
 | 
						|
      JX.Stratcom.invoke('resize');
 | 
						|
    },
 | 
						|
 | 
						|
    _redraw: function() {
 | 
						|
      var is_invisible = (this._isInvisible || this._isDeleted);
 | 
						|
      var is_loading = (this._isLoading);
 | 
						|
 | 
						|
      var row = this._row;
 | 
						|
      JX.DOM.alterClass(row, 'differential-inline-hidden', is_invisible);
 | 
						|
      JX.DOM.alterClass(row, 'differential-inline-loading', is_loading);
 | 
						|
    },
 | 
						|
 | 
						|
    _removeRow: function(row) {
 | 
						|
      JX.DOM.remove(row.node);
 | 
						|
      for (var ii = 0; ii < row.listeners.length; ii++) {
 | 
						|
        row.listeners[ii].remove();
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    _getInlineURI: function() {
 | 
						|
      var changeset = this.getChangeset();
 | 
						|
      var list = changeset.getChangesetList();
 | 
						|
      return list.getInlineURI();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
});
 |