Changeset View
Changeset View
Standalone View
Standalone View
webroot/rsrc/js/application/diff/DiffChangesetList.js
| Show First 20 Lines • Show All 433 Lines • ▼ Show 20 Lines | _onKeyCreate: function() { | ||||
| this._warnUser( | this._warnUser( | ||||
| pht( | pht( | ||||
| 'You must select source text to create a new inline comment.')); | 'You must select source text to create a new inline comment.')); | ||||
| return; | return; | ||||
| } | } | ||||
| this._setSourceSelection(null, null); | this._setSourceSelection(null, null); | ||||
| var config = { | |||||
| startOffset: start.offset, | |||||
| endOffset: end.offset | |||||
| }; | |||||
| var changeset = start.changeset; | var changeset = start.changeset; | ||||
| changeset.newInlineForRange(start.targetNode, end.targetNode); | changeset.newInlineForRange(start.targetNode, end.targetNode, config); | ||||
| }, | }, | ||||
| _onkeydone: function() { | _onkeydone: function() { | ||||
| var cursor = this._cursorItem; | var cursor = this._cursorItem; | ||||
| if (cursor) { | if (cursor) { | ||||
| if (cursor.type == 'comment') { | if (cursor.type == 'comment') { | ||||
| var inline = cursor.target; | var inline = cursor.target; | ||||
| ▲ Show 20 Lines • Show All 784 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)) { | |||||
| return; | |||||
| } | |||||
| this._hoverInline = inline; | 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') { | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
| resetHover: function() { | resetHover: function() { | ||||
| this._setHoverInline(null); | this._setHoverInline(null); | ||||
| this._hoverOrigin = null; | this._hoverOrigin = null; | ||||
| this._hoverTarget = null; | this._hoverTarget = null; | ||||
| }, | }, | ||||
| _redrawHover: function() { | _redrawHover: function() { | ||||
| var ii; | |||||
| var map = this._hoverMap; | |||||
| 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; | |||||
| } | |||||
| var reticle = this._getHoverNode(); | var reticle = this._getHoverNode(); | ||||
| if (!this._hoverOrigin || this.isAsleep()) { | |||||
| JX.DOM.remove(reticle); | JX.DOM.remove(reticle); | ||||
| if (!this._hoverOrigin || this.isAsleep()) { | |||||
| return; | return; | ||||
| } | } | ||||
| JX.DOM.getContentFrame().appendChild(reticle); | |||||
| 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) { | ||||
| var tmp = top; | var tmp = top; | ||||
| top = bot; | top = bot; | ||||
| bot = tmp; | bot = tmp; | ||||
| } | } | ||||
| // Find the leftmost cell that we're going to highlight. This is the | // Find the leftmost cell that we're going to highlight. This is the | ||||
| // next sibling with a "data-copy-mode" attribute, which is a marker | // next sibling with a "data-copy-mode" attribute, which is a marker | ||||
| // for the cell with actual content in it. | // for the cell with actual content in it. | ||||
| var content_cell = top; | var content_cell = top; | ||||
| while (content_cell && !content_cell.getAttribute('data-copy-mode')) { | while (content_cell && !this._isContentCell(content_cell)) { | ||||
| 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; | ||||
| } | } | ||||
| var inline = this._hoverInline; | |||||
| if (!inline) { | |||||
| var pos = JX.$V(content_cell) | var pos = JX.$V(content_cell) | ||||
| .add(JX.Vector.getAggregateScrollForNode(content_cell)); | .add(JX.Vector.getAggregateScrollForNode(content_cell)); | ||||
| var dim = JX.$V(content_cell) | var dim = JX.$V(content_cell) | ||||
| .add(JX.Vector.getAggregateScrollForNode(content_cell)) | .add(JX.Vector.getAggregateScrollForNode(content_cell)) | ||||
| .add(-pos.x, -pos.y) | .add(-pos.x, -pos.y) | ||||
| .add(JX.Vector.getDim(content_cell)); | .add(JX.Vector.getDim(content_cell)); | ||||
| var bpos = JX.$V(bot) | var bpos = JX.$V(bot) | ||||
| .add(JX.Vector.getAggregateScrollForNode(bot)); | .add(JX.Vector.getAggregateScrollForNode(bot)); | ||||
| dim.y = (bpos.y - pos.y) + JX.Vector.getDim(bot).y; | dim.y = (bpos.y - pos.y) + JX.Vector.getDim(bot).y; | ||||
| pos.setPos(reticle); | pos.setPos(reticle); | ||||
| dim.setDim(reticle); | dim.setDim(reticle); | ||||
| JX.DOM.getContentFrame().appendChild(reticle); | |||||
| JX.DOM.show(reticle); | JX.DOM.show(reticle); | ||||
| return; | |||||
| } | |||||
| if (!inline.hoverMap) { | |||||
| inline.hoverMap = this._newHoverMap(top, bot, content_cell, inline); | |||||
| } | |||||
| map = inline.hoverMap; | |||||
| for (ii = 0; ii < map.length; ii++) { | |||||
| JX.DOM.alterClass(map[ii].cellNode, 'inline-hover', true); | |||||
| if (map[ii].bright) { | |||||
| JX.DOM.alterClass(map[ii].cellNode, 'inline-hover-bright', true); | |||||
| } | |||||
| 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) { | |||||
| var start = inline.getStartOffset() || 0; | |||||
| var end = inline.getEndOffset() || 0; | |||||
| var head_row = JX.DOM.findAbove(top, 'tr'); | |||||
| var last_row = JX.DOM.findAbove(bot, 'tr'); | |||||
| var cursor = head_row; | |||||
| var rows = []; | |||||
| var idx = null; | |||||
| var ii; | |||||
| do { | |||||
| for (ii = 0; ii < cursor.childNodes.length; ii++) { | |||||
| var child = cursor.childNodes[ii]; | |||||
| if (!JX.DOM.isType(child, 'td')) { | |||||
| continue; | |||||
| } | |||||
| if (child === content_cell) { | |||||
| idx = ii; | |||||
| } | |||||
| if (ii === idx) { | |||||
| if (!this._isContentCell(child)) { | |||||
| break; | |||||
| } | |||||
| rows.push({ | |||||
| cellNode: child | |||||
| }); | |||||
| } | |||||
| } | |||||
| if (cursor === last_row) { | |||||
| break; | |||||
| } | |||||
| cursor = cursor.nextSibling; | |||||
| } while (cursor); | |||||
| var info; | |||||
| var content; | |||||
| for (ii = 0; ii < rows.length; ii++) { | |||||
| info = this._getSelectionOffset(rows[ii].cellNode, null); | |||||
| content = info.content; | |||||
| content = content.replace(/\n+$/, ''); | |||||
| rows[ii].content = content; | |||||
| } | |||||
| var attr_dull = { | |||||
| className: 'inline-hover-text' | |||||
| }; | |||||
| var attr_bright = { | |||||
| className: 'inline-hover-text inline-hover-text-bright' | |||||
| }; | |||||
| var attr_container = { | |||||
| className: 'inline-hover-container' | |||||
| }; | |||||
| var min = 0; | |||||
| var max = rows.length - 1; | |||||
| var offset_min; | |||||
| var offset_max; | |||||
| var len; | |||||
| var node; | |||||
| var text; | |||||
| var any_highlight = false; | |||||
| for (ii = 0; ii < rows.length; ii++) { | |||||
| content = rows[ii].content; | |||||
| len = content.length; | |||||
| if (ii === min) { | |||||
| offset_min = start; | |||||
| } else { | |||||
| offset_min = 0; | |||||
| } | |||||
| if (ii === max) { | |||||
| offset_max = Math.min(end, len); | |||||
| } else { | |||||
| offset_max = len; | |||||
| } | |||||
| var has_min = (offset_min > 0); | |||||
| var has_max = (offset_max < len); | |||||
| if (has_min || has_max) { | |||||
| any_highlight = true; | |||||
| } | |||||
| rows[ii].min = offset_min; | |||||
| rows[ii].max = offset_max; | |||||
| rows[ii].hasMin = has_min; | |||||
| rows[ii].hasMax = has_max; | |||||
| } | |||||
| for (ii = 0; ii < rows.length; ii++) { | |||||
| content = rows[ii].content; | |||||
| offset_min = rows[ii].min; | |||||
| offset_max = rows[ii].max; | |||||
| var has_highlight = (rows[ii].hasMin || rows[ii].hasMax); | |||||
| if (any_highlight) { | |||||
| var parts = []; | |||||
| if (offset_min > 0) { | |||||
| text = content.substring(0, offset_min); | |||||
| node = JX.$N('span', attr_dull, text); | |||||
| parts.push(node); | |||||
| } | |||||
| if (len) { | |||||
| text = content.substring(offset_min, offset_max); | |||||
| node = JX.$N('span', attr_bright, text); | |||||
| parts.push(node); | |||||
| } | |||||
| if (offset_max < len) { | |||||
| text = content.substring(offset_max, len); | |||||
| node = JX.$N('span', attr_dull, text); | |||||
| parts.push(node); | |||||
| } | |||||
| rows[ii].hoverNode = JX.$N('div', attr_container, parts); | |||||
| } else { | |||||
| rows[ii].hoverNode = null; | |||||
| } | |||||
| rows[ii].bright = (any_highlight && !has_highlight); | |||||
| } | |||||
| return rows; | |||||
| }, | }, | ||||
| _getHoverNode: function() { | _getHoverNode: function() { | ||||
| if (!this._hoverNode) { | if (!this._hoverNode) { | ||||
| var attributes = { | var attributes = { | ||||
| className: 'differential-reticle' | className: 'differential-reticle' | ||||
| }; | }; | ||||
| this._hoverNode = JX.$N('div', attributes); | this._hoverNode = JX.$N('div', attributes); | ||||
| ▲ Show 20 Lines • Show All 1,095 Lines • ▼ Show 20 Lines | _getFragmentLocation: function(fragment) { | ||||
| } else { | } else { | ||||
| column_count = 0; | column_count = 0; | ||||
| } | } | ||||
| } else { | } else { | ||||
| return null; | return null; | ||||
| } | } | ||||
| } | } | ||||
| var seen = 0; | var info = this._getSelectionOffset(td, fragment); | ||||
| for (var ii = 0; ii < td.childNodes.length; ii++) { | |||||
| var child = td.childNodes[ii]; | |||||
| if (child === fragment) { | |||||
| offset = seen; | |||||
| break; | |||||
| } | |||||
| seen += child.textContent.length; | |||||
| } | |||||
| if (offset === null) { | if (info.found) { | ||||
| offset = info.offset; | |||||
| } else { | |||||
| if (is_end) { | if (is_end) { | ||||
| offset = seen; | offset = info.offset; | ||||
| } else { | } else { | ||||
| offset = 0; | offset = 0; | ||||
| } | } | ||||
| } | } | ||||
| } catch (ex) { | } catch (ex) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| Show All 10 Lines | _getFragmentLocation: function(fragment) { | ||||
| changesetID: changeset_id, | changesetID: changeset_id, | ||||
| line: line, | line: line, | ||||
| displayColumn: column_count, | displayColumn: column_count, | ||||
| offset: offset, | offset: offset, | ||||
| targetNode: target_node | targetNode: target_node | ||||
| }; | }; | ||||
| }, | }, | ||||
| _getSelectionOffset: function(node, target) { | |||||
| if (!node.childNodes || !node.childNodes.length) { | |||||
| return { | |||||
| offset: node.textContent.length, | |||||
| content: node.textContent, | |||||
| found: false | |||||
| }; | |||||
| } | |||||
| var found = false; | |||||
| var offset = 0; | |||||
| var content = ''; | |||||
| for (var ii = 0; ii < node.childNodes.length; ii++) { | |||||
| var child = node.childNodes[ii]; | |||||
| if (child === target) { | |||||
| found = true; | |||||
| } | |||||
| var spec = this._getSelectionOffset(child, target); | |||||
| content += spec.content; | |||||
| if (!found) { | |||||
| offset += spec.offset; | |||||
| } | |||||
| found = found || spec.found; | |||||
| } | |||||
| return { | |||||
| offset: offset, | |||||
| content: content, | |||||
| found: found | |||||
| }; | |||||
| }, | |||||
| _getSelectedRanges: function() { | _getSelectedRanges: function() { | ||||
| var ranges = []; | var ranges = []; | ||||
| if (!window.getSelection) { | if (!window.getSelection) { | ||||
| return ranges; | return ranges; | ||||
| } | } | ||||
| var selection = window.getSelection(); | var selection = window.getSelection(); | ||||
| for (var ii = 0; ii < selection.rangeCount; ii++) { | for (var ii = 0; ii < selection.rangeCount; ii++) { | ||||
| var range = selection.getRangeAt(ii); | var range = selection.getRangeAt(ii); | ||||
| if (range.collapsed) { | if (range.collapsed) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ranges.push(range); | ranges.push(range); | ||||
| } | } | ||||
| return ranges; | return ranges; | ||||
| }, | |||||
| _isContentCell: function(node) { | |||||
| return !!node.getAttribute('data-copy-mode'); | |||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||