Changeset View
Changeset View
Standalone View
Standalone View
webroot/rsrc/js/application/diff/DiffChangesetList.js
| Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | members: { | ||||
| _changesets: null, | _changesets: null, | ||||
| _cursorItem: null, | _cursorItem: null, | ||||
| _focusNode: null, | _focusNode: null, | ||||
| _focusStart: null, | _focusStart: null, | ||||
| _focusEnd: null, | _focusEnd: null, | ||||
| _hoverNode: null, | |||||
| _hoverInline: null, | _hoverInline: null, | ||||
| _hoverOrigin: null, | _hoverOrigin: null, | ||||
| _hoverTarget: null, | _hoverTarget: null, | ||||
| _rangeActive: false, | _rangeActive: false, | ||||
| _rangeOrigin: null, | _rangeOrigin: null, | ||||
| _rangeTarget: null, | _rangeTarget: null, | ||||
| ▲ Show 20 Lines • Show All 1,023 Lines • ▼ Show 20 Lines | _oncollapse: function(is_collapse, e) { | ||||
| var inline = this._getInlineForEvent(e); | var inline = this._getInlineForEvent(e); | ||||
| inline.setCollapsed(is_collapse); | inline.setCollapsed(is_collapse); | ||||
| }, | }, | ||||
| _onresize: function() { | _onresize: function() { | ||||
| this._redrawFocus(); | this._redrawFocus(); | ||||
| this._redrawSelection(); | this._redrawSelection(); | ||||
| this._redrawHover(); | |||||
| // Force a banner redraw after a resize event. Particularly, this makes | // Force a banner redraw after a resize event. Particularly, this makes | ||||
| // sure the inline state updates immediately after an inline edit | // sure the inline state updates immediately after an inline edit | ||||
| // operation, even if the changeset itself has not changed. | // operation, even if the changeset itself has not changed. | ||||
| this._bannerChangeset = null; | this._bannerChangeset = null; | ||||
| this._redrawBanner(); | this._redrawBanner(); | ||||
| ▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | _getFocusNode: function() { | ||||
| if (!this._focusNode) { | if (!this._focusNode) { | ||||
| var node = JX.$N('div', {className : 'keyboard-focus-focus-reticle'}); | var node = JX.$N('div', {className : 'keyboard-focus-focus-reticle'}); | ||||
| this._focusNode = node; | this._focusNode = node; | ||||
| } | } | ||||
| return this._focusNode; | return this._focusNode; | ||||
| }, | }, | ||||
| _setHoverInline: function(inline) { | _setHoverInline: function(inline) { | ||||
| if (inline && (this._hoverInline === inline)) { | var origin = null; | ||||
| return; | var target = null; | ||||
| } | |||||
| this._hoverInline = inline; | |||||
| if (inline) { | if (inline) { | ||||
| var changeset = inline.getChangeset(); | var changeset = inline.getChangeset(); | ||||
| var changeset_id; | var changeset_id; | ||||
| var side = inline.getDisplaySide(); | var side = inline.getDisplaySide(); | ||||
| if (side == 'right') { | if (side == 'right') { | ||||
| changeset_id = changeset.getRightChangesetID(); | changeset_id = changeset.getRightChangesetID(); | ||||
| Show All 9 Lines | _setHoverInline: function(inline) { | ||||
| } | } | ||||
| var prefix = 'C' + changeset_id + new_part + 'L'; | var prefix = 'C' + changeset_id + new_part + 'L'; | ||||
| var number = inline.getLineNumber(); | var number = inline.getLineNumber(); | ||||
| var length = inline.getLineLength(); | var length = inline.getLineLength(); | ||||
| try { | try { | ||||
| var origin = JX.$(prefix + number); | origin = JX.$(prefix + number); | ||||
| var target = JX.$(prefix + (number + length)); | target = JX.$(prefix + (number + length)); | ||||
| this._hoverOrigin = origin; | |||||
| this._hoverTarget = target; | |||||
| } catch (error) { | } catch (error) { | ||||
| // There may not be any nodes present in the document. A case where | // There may not be any nodes present in the document. A case where | ||||
| // this occurs is when you reply to a ghost inline which was made | // this occurs is when you reply to a ghost inline which was made | ||||
| // on lines near the bottom of "long.txt" in an earlier diff, and | // on lines near the bottom of "long.txt" in an earlier diff, and | ||||
| // the file was later shortened so those lines no longer exist. For | // the file was later shortened so those lines no longer exist. For | ||||
| // more details, see T11662. | // more details, see T11662. | ||||
| this._hoverOrigin = null; | origin = null; | ||||
| this._hoverTarget = null; | target = null; | ||||
| } | } | ||||
| } else { | |||||
| this._hoverOrigin = null; | |||||
| this._hoverTarget = null; | |||||
| } | } | ||||
| this._redrawHover(); | this._setHoverRange(origin, target, inline); | ||||
| }, | }, | ||||
| _setHoverRange: function(origin, target) { | _setHoverRange: function(origin, target, inline) { | ||||
| inline = inline || null; | |||||
| var origin_dirty = (origin !== this._hoverOrigin); | |||||
| var target_dirty = (target !== this._hoverTarget); | |||||
| var inline_dirty = (inline !== this._hoverInline); | |||||
| var any_dirty = (origin_dirty || target_dirty || inline_dirty); | |||||
| if (any_dirty) { | |||||
| this._hoverOrigin = origin; | this._hoverOrigin = origin; | ||||
| this._hoverTarget = target; | this._hoverTarget = target; | ||||
| this._hoverInline = inline; | |||||
| this._redrawHover(); | this._redrawHover(); | ||||
| } | |||||
| }, | }, | ||||
| resetHover: function() { | resetHover: function() { | ||||
| this._setHoverInline(null); | this._setHoverRange(null, null, null); | ||||
| this._hoverOrigin = null; | |||||
| this._hoverTarget = null; | |||||
| }, | }, | ||||
| _redrawHover: function() { | _redrawHover: function() { | ||||
| var ii; | |||||
| var map = this._hoverMap; | var map = this._hoverMap; | ||||
| if (map) { | if (map) { | ||||
| for (ii = 0; ii < map.length; ii++) { | |||||
| JX.DOM.alterClass(map[ii].cellNode, 'inline-hover', false); | |||||
| if (map[ii].bright) { | |||||
| JX.DOM.alterClass(map[ii].cellNode, 'inline-hover-bright', false); | |||||
| } | |||||
| if (map[ii].hoverNode) { | |||||
| JX.DOM.remove(map[ii].hoverNode); | |||||
| } | |||||
| } | |||||
| this._hoverMap = null; | this._hoverMap = null; | ||||
| this._applyHoverHighlight(map, false); | |||||
| } | } | ||||
| var reticle = this._getHoverNode(); | var rows = this._hoverRows; | ||||
| JX.DOM.remove(reticle); | if (rows) { | ||||
| this._hoverRows = null; | |||||
| this._applyHoverHighlight(rows, false); | |||||
| } | |||||
| if (!this._hoverOrigin || this.isAsleep()) { | if (!this._hoverOrigin || this.isAsleep()) { | ||||
| return; | return; | ||||
| } | } | ||||
| var top = this._hoverOrigin; | var top = this._hoverOrigin; | ||||
| var bot = this._hoverTarget; | var bot = this._hoverTarget; | ||||
| if (JX.$V(top).y > JX.$V(bot).y) { | if (JX.$V(top).y > JX.$V(bot).y) { | ||||
| Show All 10 Lines | _redrawHover: function() { | ||||
| content_cell = content_cell.nextSibling; | content_cell = content_cell.nextSibling; | ||||
| } | } | ||||
| // If we didn't find a cell to highlight, don't highlight anything. | // If we didn't find a cell to highlight, don't highlight anything. | ||||
| if (!content_cell) { | if (!content_cell) { | ||||
| return; | return; | ||||
| } | } | ||||
| rows = this._findContentCells(top, bot, content_cell); | |||||
| var inline = this._hoverInline; | var inline = this._hoverInline; | ||||
| if (!inline) { | if (!inline) { | ||||
| var pos = JX.$V(content_cell) | this._hoverRows = rows; | ||||
| .add(JX.Vector.getAggregateScrollForNode(content_cell)); | this._applyHoverHighlight(this._hoverRows, true); | ||||
| return; | |||||
| } | |||||
| var dim = JX.$V(content_cell) | if (!inline.hoverMap) { | ||||
| .add(JX.Vector.getAggregateScrollForNode(content_cell)) | inline.hoverMap = this._newHoverMap(rows, inline); | ||||
| .add(-pos.x, -pos.y) | } | ||||
| .add(JX.Vector.getDim(content_cell)); | |||||
| var bpos = JX.$V(bot) | |||||
| .add(JX.Vector.getAggregateScrollForNode(bot)); | |||||
| dim.y = (bpos.y - pos.y) + JX.Vector.getDim(bot).y; | |||||
| pos.setPos(reticle); | this._hoverMap = inline.hoverMap; | ||||
| dim.setDim(reticle); | this._applyHoverHighlight(this._hoverMap, true); | ||||
| }, | |||||
| JX.DOM.getContentFrame().appendChild(reticle); | _applyHoverHighlight: function(items, on) { | ||||
| JX.DOM.show(reticle); | for (var ii = 0; ii < items.length; ii++) { | ||||
| var item = items[ii]; | |||||
| return; | JX.DOM.alterClass(item.lineNode, 'inline-hover', on); | ||||
| } | JX.DOM.alterClass(item.cellNode, 'inline-hover', on); | ||||
| if (!inline.hoverMap) { | if (item.bright) { | ||||
| inline.hoverMap = this._newHoverMap(top, bot, content_cell, inline); | JX.DOM.alterClass(item.cellNode, 'inline-hover-bright', on); | ||||
| } | } | ||||
| map = inline.hoverMap; | if (item.hoverNode) { | ||||
| for (ii = 0; ii < map.length; ii++) { | if (on) { | ||||
| JX.DOM.alterClass(map[ii].cellNode, 'inline-hover', true); | item.cellNode.insertBefore( | ||||
| if (map[ii].bright) { | item.hoverNode, | ||||
| JX.DOM.alterClass(map[ii].cellNode, 'inline-hover-bright', true); | item.cellNode.firstChild); | ||||
| } else { | |||||
| JX.DOM.remove(item.hoverNode); | |||||
| } | } | ||||
| if (map[ii].hoverNode) { | |||||
| map[ii].cellNode.insertBefore( | |||||
| map[ii].hoverNode, | |||||
| map[ii].cellNode.firstChild); | |||||
| } | } | ||||
| } | } | ||||
| this._hoverMap = map; | |||||
| }, | }, | ||||
| _newHoverMap: function(top, bot, content_cell, inline) { | _findContentCells: function(top, bot, content_cell) { | ||||
| var start = inline.getStartOffset(); | |||||
| var end = inline.getEndOffset(); | |||||
| var head_row = JX.DOM.findAbove(top, 'tr'); | var head_row = JX.DOM.findAbove(top, 'tr'); | ||||
| var last_row = JX.DOM.findAbove(bot, 'tr'); | var last_row = JX.DOM.findAbove(bot, 'tr'); | ||||
| var cursor = head_row; | var cursor = head_row; | ||||
| var rows = []; | var rows = []; | ||||
| var idx = null; | var idx = null; | ||||
| var ii; | var ii; | ||||
| var line_cell = null; | |||||
| do { | do { | ||||
| line_cell = null; | |||||
| for (ii = 0; ii < cursor.childNodes.length; ii++) { | for (ii = 0; ii < cursor.childNodes.length; ii++) { | ||||
| var child = cursor.childNodes[ii]; | var child = cursor.childNodes[ii]; | ||||
| if (!JX.DOM.isType(child, 'td')) { | if (!JX.DOM.isType(child, 'td')) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (child.getAttribute('data-n')) { | |||||
| line_cell = child; | |||||
| } | |||||
| if (child === content_cell) { | if (child === content_cell) { | ||||
| idx = ii; | idx = ii; | ||||
| } | } | ||||
| if (ii === idx) { | if (ii !== idx) { | ||||
| if (!this._isContentCell(child)) { | continue; | ||||
| break; | |||||
| } | } | ||||
| if (this._isContentCell(child)) { | |||||
| rows.push({ | rows.push({ | ||||
| lineNode: line_cell, | |||||
| cellNode: child | cellNode: child | ||||
| }); | }); | ||||
| } | } | ||||
| break; | |||||
| } | } | ||||
| if (cursor === last_row) { | if (cursor === last_row) { | ||||
| break; | break; | ||||
| } | } | ||||
| cursor = cursor.nextSibling; | cursor = cursor.nextSibling; | ||||
| } while (cursor); | } while (cursor); | ||||
| return rows; | |||||
| }, | |||||
| _newHoverMap: function(rows, inline) { | |||||
| var start = inline.getStartOffset(); | |||||
| var end = inline.getEndOffset(); | |||||
| var info; | var info; | ||||
| var content; | var content; | ||||
| for (ii = 0; ii < rows.length; ii++) { | for (ii = 0; ii < rows.length; ii++) { | ||||
| info = this._getSelectionOffset(rows[ii].cellNode, null); | info = this._getSelectionOffset(rows[ii].cellNode, null); | ||||
| content = info.content; | content = info.content; | ||||
| content = content.replace(/\n+$/, ''); | content = content.replace(/\n+$/, ''); | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | _newHoverMap: function(rows, inline) { | ||||
| } | } | ||||
| rows[ii].bright = (any_highlight && !has_highlight); | rows[ii].bright = (any_highlight && !has_highlight); | ||||
| } | } | ||||
| return rows; | return rows; | ||||
| }, | }, | ||||
| _getHoverNode: function() { | |||||
| if (!this._hoverNode) { | |||||
| var attributes = { | |||||
| className: 'differential-reticle' | |||||
| }; | |||||
| this._hoverNode = JX.$N('div', attributes); | |||||
| } | |||||
| return this._hoverNode; | |||||
| }, | |||||
| _deleteInlineByID: function(id) { | _deleteInlineByID: function(id) { | ||||
| var uri = this.getInlineURI(); | var uri = this.getInlineURI(); | ||||
| var data = { | var data = { | ||||
| op: 'refdelete', | op: 'refdelete', | ||||
| id: id | id: id | ||||
| }; | }; | ||||
| var handler = JX.bind(this, this.redrawPreview); | var handler = JX.bind(this, this.redrawPreview); | ||||
| ▲ Show 20 Lines • Show All 1,206 Lines • Show Last 20 Lines | |||||