@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Store inline comment offset information and show it when highlighting comments

Summary:
Ref T13513. When a user selects a text range and uses "New Inline Comment" to create a comment directly from a range, store the offset information alongside the comment.

When hovering the comment, highlight the original range.

Test Plan: {F7480926, size=full}

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21250

+377 -73
+34 -34
resources/celerity/map.php
··· 12 12 'core.pkg.css' => 'a560707d', 13 13 'core.pkg.js' => '0efaf0ac', 14 14 'dark-console.pkg.js' => '187792c2', 15 - 'differential.pkg.css' => 'd71d4531', 16 - 'differential.pkg.js' => 'ac6914bb', 15 + 'differential.pkg.css' => 'b042ee8b', 16 + 'differential.pkg.js' => '4b2b5659', 17 17 'diffusion.pkg.css' => '42c75c37', 18 18 'diffusion.pkg.js' => 'a98c0bf7', 19 19 'maniphest.pkg.css' => '35995d6d', ··· 63 63 'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222', 64 64 'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d', 65 65 'rsrc/css/application/differential/add-comment.css' => '7e5900d9', 66 - 'rsrc/css/application/differential/changeset-view.css' => 'a5cc67cf', 66 + 'rsrc/css/application/differential/changeset-view.css' => 'df3afa61', 67 67 'rsrc/css/application/differential/core.css' => '7300a73e', 68 68 'rsrc/css/application/differential/phui-inline-comment.css' => '48acce5b', 69 69 'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d', ··· 379 379 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be', 380 380 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9', 381 381 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', 382 - 'rsrc/js/application/diff/DiffChangeset.js' => '20715b98', 383 - 'rsrc/js/application/diff/DiffChangesetList.js' => '9d5b137e', 384 - 'rsrc/js/application/diff/DiffInline.js' => '6227a0e3', 382 + 'rsrc/js/application/diff/DiffChangeset.js' => 'b6bb0240', 383 + 'rsrc/js/application/diff/DiffChangesetList.js' => '2347e0a6', 384 + 'rsrc/js/application/diff/DiffInline.js' => '417b3cdb', 385 385 'rsrc/js/application/diff/DiffPathView.js' => '8207abf9', 386 386 'rsrc/js/application/diff/DiffTreeView.js' => '5d83623b', 387 387 'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd', ··· 559 559 'conpherence-transaction-css' => '3a3f5e7e', 560 560 'd3' => '9d068042', 561 561 'diff-tree-view-css' => 'e2d3e222', 562 - 'differential-changeset-view-css' => 'a5cc67cf', 562 + 'differential-changeset-view-css' => 'df3afa61', 563 563 'differential-core-view-css' => '7300a73e', 564 564 'differential-revision-add-comment-css' => '7e5900d9', 565 565 'differential-revision-comment-css' => '7dbc8d1d', ··· 774 774 'phabricator-darklog' => '3b869402', 775 775 'phabricator-darkmessage' => '26cd4b73', 776 776 'phabricator-dashboard-css' => '5a205b9d', 777 - 'phabricator-diff-changeset' => '20715b98', 778 - 'phabricator-diff-changeset-list' => '9d5b137e', 779 - 'phabricator-diff-inline' => '6227a0e3', 777 + 'phabricator-diff-changeset' => 'b6bb0240', 778 + 'phabricator-diff-changeset-list' => '2347e0a6', 779 + 'phabricator-diff-inline' => '417b3cdb', 780 780 'phabricator-diff-path-view' => '8207abf9', 781 781 'phabricator-diff-tree-view' => '5d83623b', 782 782 'phabricator-drag-and-drop-file-upload' => '4370900d', ··· 1082 1082 'javelin-behavior', 1083 1083 'javelin-request', 1084 1084 ), 1085 - '20715b98' => array( 1086 - 'javelin-dom', 1087 - 'javelin-util', 1088 - 'javelin-stratcom', 1089 - 'javelin-install', 1090 - 'javelin-workflow', 1091 - 'javelin-router', 1092 - 'javelin-behavior-device', 1093 - 'javelin-vector', 1094 - 'phabricator-diff-inline', 1095 - 'phabricator-diff-path-view', 1096 - 'phuix-button-view', 1097 - ), 1098 1085 '225bbb98' => array( 1099 1086 'javelin-install', 1100 1087 'javelin-reactor', ··· 1111 1098 'javelin-request', 1112 1099 'javelin-typeahead-source', 1113 1100 ), 1101 + '2347e0a6' => array( 1102 + 'javelin-install', 1103 + 'phuix-button-view', 1104 + 'phabricator-diff-tree-view', 1105 + ), 1114 1106 23631304 => array( 1115 1107 'phui-fontkit-css', 1116 1108 ), ··· 1258 1250 '407ee861' => array( 1259 1251 'javelin-behavior', 1260 1252 'javelin-uri', 1253 + ), 1254 + '417b3cdb' => array( 1255 + 'javelin-dom', 1261 1256 ), 1262 1257 '42c44e8b' => array( 1263 1258 'javelin-behavior', ··· 1503 1498 '60cd9241' => array( 1504 1499 'javelin-behavior', 1505 1500 ), 1506 - '6227a0e3' => array( 1507 - 'javelin-dom', 1508 - ), 1509 1501 '6337cf26' => array( 1510 1502 'javelin-behavior', 1511 1503 'javelin-dom', ··· 1816 1808 'javelin-uri', 1817 1809 'phabricator-textareautils', 1818 1810 ), 1819 - '9d5b137e' => array( 1820 - 'javelin-install', 1821 - 'phuix-button-view', 1822 - 'phabricator-diff-tree-view', 1823 - ), 1824 1811 '9f081f05' => array( 1825 1812 'javelin-behavior', 1826 1813 'javelin-dom', ··· 1865 1852 'javelin-install', 1866 1853 'javelin-dom', 1867 1854 ), 1868 - 'a5cc67cf' => array( 1869 - 'phui-inline-comment-view-css', 1870 - ), 1871 1855 'a77e2cbd' => array( 1872 1856 'javelin-behavior', 1873 1857 'javelin-stratcom', ··· 1999 1983 'javelin-stratcom', 2000 1984 'javelin-dom', 2001 1985 ), 1986 + 'b6bb0240' => array( 1987 + 'javelin-dom', 1988 + 'javelin-util', 1989 + 'javelin-stratcom', 1990 + 'javelin-install', 1991 + 'javelin-workflow', 1992 + 'javelin-router', 1993 + 'javelin-behavior-device', 1994 + 'javelin-vector', 1995 + 'phabricator-diff-inline', 1996 + 'phabricator-diff-path-view', 1997 + 'phuix-button-view', 1998 + ), 2002 1999 'b7b73831' => array( 2003 2000 'javelin-behavior', 2004 2001 'javelin-dom', ··· 2123 2120 'javelin-behavior', 2124 2121 'javelin-uri', 2125 2122 'phabricator-notification', 2123 + ), 2124 + 'df3afa61' => array( 2125 + 'phui-inline-comment-view-css', 2126 2126 ), 2127 2127 'e150bd50' => array( 2128 2128 'javelin-behavior',
+2
src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php
··· 208 208 'gentle.highlight' => '#fdf3da', 209 209 'gentle.highlight.border' => '#c9b8a8', 210 210 211 + 'highlight.bright' => '#fdf320', 212 + 211 213 'paste.content' => '#fffef5', 212 214 'paste.border' => '#e9dbcd', 213 215 'paste.highlight' => '#fdf3da',
+3 -1
src/infrastructure/diff/PhabricatorInlineCommentController.php
··· 320 320 ->setLineLength($length) 321 321 ->setContent((string)$this->getCommentText()) 322 322 ->setReplyToCommentPHID($this->getReplyToCommentPHID()) 323 - ->setIsEditing(true); 323 + ->setIsEditing(true) 324 + ->setStartOffset($request->getInt('startOffset')) 325 + ->setEndOffset($request->getInt('endOffset')); 324 326 325 327 $document_engine_key = $request->getStr('documentEngineKey'); 326 328 if ($document_engine_key !== null) {
+18
src/infrastructure/diff/interface/PhabricatorInlineComment.php
··· 222 222 return $this->getStorageObject()->getAttribute('documentEngineKey'); 223 223 } 224 224 225 + public function setStartOffset($offset) { 226 + $this->getStorageObject()->setAttribute('startOffset', $offset); 227 + return $this; 228 + } 229 + 230 + public function getStartOffset() { 231 + return $this->getStorageObject()->getAttribute('startOffset'); 232 + } 233 + 234 + public function setEndOffset($offset) { 235 + $this->getStorageObject()->setAttribute('endOffset', $offset); 236 + return $this; 237 + } 238 + 239 + public function getEndOffset() { 240 + return $this->getStorageObject()->getAttribute('endOffset'); 241 + } 242 + 225 243 public function getDateModified() { 226 244 return $this->getStorageObject()->getDateModified(); 227 245 }
+2
src/infrastructure/diff/view/PHUIDiffInlineCommentView.php
··· 91 91 'isDraftDone' => $is_draft_done, 92 92 'isEditing' => $inline->getIsEditing(), 93 93 'documentEngineKey' => $inline->getDocumentEngineKey(), 94 + 'startOffset' => $inline->getStartOffset(), 95 + 'endOffset' => $inline->getEndOffset(), 94 96 95 97 'on_right' => $this->getIsOnRight(), 96 98 );
+24
webroot/rsrc/css/application/differential/changeset-view.css
··· 487 487 background: {$lightyellow}; 488 488 color: {$blacktext}; 489 489 } 490 + 491 + .differential-diff tr td.inline-hover { 492 + background: {$gentle.highlight}; 493 + } 494 + 495 + .differential-diff tr td.inline-hover-bright { 496 + background: {$highlight.bright}; 497 + } 498 + 499 + .inline-hover-container { 500 + position: absolute; 501 + color: {$lightgreytext}; 502 + background: {$lightyellow}; 503 + } 504 + 505 + .inline-hover-text { 506 + padding-top: 2px; 507 + padding-bottom: 2px; 508 + } 509 + 510 + .inline-hover-text-bright { 511 + color: {$blacktext}; 512 + background: {$highlight.bright}; 513 + }
+3 -1
webroot/rsrc/js/application/diff/DiffChangeset.js
··· 711 711 return data.inline; 712 712 }, 713 713 714 - newInlineForRange: function(origin, target) { 714 + newInlineForRange: function(origin, target, options) { 715 715 var list = this.getChangesetList(); 716 716 717 717 var src = list.getLineNumberFromHeader(origin); ··· 741 741 displaySide: side, 742 742 isNewFile: is_new 743 743 }; 744 + 745 + JX.copy(data, options || {}); 744 746 745 747 var inline = new JX.DiffInline() 746 748 .setChangeset(this)
+251 -28
webroot/rsrc/js/application/diff/DiffChangesetList.js
··· 439 439 440 440 this._setSourceSelection(null, null); 441 441 442 + var config = { 443 + startOffset: start.offset, 444 + endOffset: end.offset 445 + }; 446 + 442 447 var changeset = start.changeset; 443 - changeset.newInlineForRange(start.targetNode, end.targetNode); 448 + changeset.newInlineForRange(start.targetNode, end.targetNode, config); 444 449 }, 445 450 446 451 _onkeydone: function() { ··· 1241 1246 }, 1242 1247 1243 1248 _setHoverInline: function(inline) { 1249 + if (inline && (this._hoverInline === inline)) { 1250 + return; 1251 + } 1252 + 1244 1253 this._hoverInline = inline; 1245 1254 1246 1255 if (inline) { ··· 1305 1314 }, 1306 1315 1307 1316 _redrawHover: function() { 1317 + var ii; 1318 + 1319 + var map = this._hoverMap; 1320 + if (map) { 1321 + for (ii = 0; ii < map.length; ii++) { 1322 + JX.DOM.alterClass(map[ii].cellNode, 'inline-hover', false); 1323 + 1324 + if (map[ii].bright) { 1325 + JX.DOM.alterClass(map[ii].cellNode, 'inline-hover-bright', false); 1326 + } 1327 + 1328 + if (map[ii].hoverNode) { 1329 + JX.DOM.remove(map[ii].hoverNode); 1330 + } 1331 + } 1332 + this._hoverMap = null; 1333 + } 1334 + 1308 1335 var reticle = this._getHoverNode(); 1336 + JX.DOM.remove(reticle); 1337 + 1309 1338 if (!this._hoverOrigin || this.isAsleep()) { 1310 - JX.DOM.remove(reticle); 1311 1339 return; 1312 1340 } 1313 - 1314 - JX.DOM.getContentFrame().appendChild(reticle); 1315 1341 1316 1342 var top = this._hoverOrigin; 1317 1343 var bot = this._hoverTarget; ··· 1325 1351 // next sibling with a "data-copy-mode" attribute, which is a marker 1326 1352 // for the cell with actual content in it. 1327 1353 var content_cell = top; 1328 - while (content_cell && !content_cell.getAttribute('data-copy-mode')) { 1354 + while (content_cell && !this._isContentCell(content_cell)) { 1329 1355 content_cell = content_cell.nextSibling; 1330 1356 } 1331 1357 ··· 1334 1360 return; 1335 1361 } 1336 1362 1337 - var pos = JX.$V(content_cell) 1338 - .add(JX.Vector.getAggregateScrollForNode(content_cell)); 1363 + var inline = this._hoverInline; 1364 + if (!inline) { 1365 + var pos = JX.$V(content_cell) 1366 + .add(JX.Vector.getAggregateScrollForNode(content_cell)); 1367 + 1368 + var dim = JX.$V(content_cell) 1369 + .add(JX.Vector.getAggregateScrollForNode(content_cell)) 1370 + .add(-pos.x, -pos.y) 1371 + .add(JX.Vector.getDim(content_cell)); 1372 + 1373 + var bpos = JX.$V(bot) 1374 + .add(JX.Vector.getAggregateScrollForNode(bot)); 1375 + dim.y = (bpos.y - pos.y) + JX.Vector.getDim(bot).y; 1376 + 1377 + pos.setPos(reticle); 1378 + dim.setDim(reticle); 1379 + 1380 + JX.DOM.getContentFrame().appendChild(reticle); 1381 + JX.DOM.show(reticle); 1382 + 1383 + return; 1384 + } 1385 + 1386 + if (!inline.hoverMap) { 1387 + inline.hoverMap = this._newHoverMap(top, bot, content_cell, inline); 1388 + } 1389 + 1390 + map = inline.hoverMap; 1391 + for (ii = 0; ii < map.length; ii++) { 1392 + JX.DOM.alterClass(map[ii].cellNode, 'inline-hover', true); 1393 + if (map[ii].bright) { 1394 + JX.DOM.alterClass(map[ii].cellNode, 'inline-hover-bright', true); 1395 + } 1396 + if (map[ii].hoverNode) { 1397 + map[ii].cellNode.insertBefore( 1398 + map[ii].hoverNode, 1399 + map[ii].cellNode.firstChild); 1400 + } 1401 + } 1402 + this._hoverMap = map; 1403 + }, 1404 + 1405 + _newHoverMap: function(top, bot, content_cell, inline) { 1406 + var start = inline.getStartOffset() || 0; 1407 + var end = inline.getEndOffset() || 0; 1408 + 1409 + var head_row = JX.DOM.findAbove(top, 'tr'); 1410 + var last_row = JX.DOM.findAbove(bot, 'tr'); 1411 + 1412 + var cursor = head_row; 1413 + var rows = []; 1414 + var idx = null; 1415 + var ii; 1416 + do { 1417 + for (ii = 0; ii < cursor.childNodes.length; ii++) { 1418 + var child = cursor.childNodes[ii]; 1419 + if (!JX.DOM.isType(child, 'td')) { 1420 + continue; 1421 + } 1422 + 1423 + if (child === content_cell) { 1424 + idx = ii; 1425 + } 1426 + 1427 + if (ii === idx) { 1428 + if (!this._isContentCell(child)) { 1429 + break; 1430 + } 1431 + rows.push({ 1432 + cellNode: child 1433 + }); 1434 + } 1435 + } 1436 + 1437 + if (cursor === last_row) { 1438 + break; 1439 + } 1440 + 1441 + cursor = cursor.nextSibling; 1442 + } while (cursor); 1443 + 1444 + var info; 1445 + var content; 1446 + for (ii = 0; ii < rows.length; ii++) { 1447 + info = this._getSelectionOffset(rows[ii].cellNode, null); 1448 + 1449 + content = info.content; 1450 + content = content.replace(/\n+$/, ''); 1451 + 1452 + rows[ii].content = content; 1453 + } 1454 + 1455 + var attr_dull = { 1456 + className: 'inline-hover-text' 1457 + }; 1458 + 1459 + var attr_bright = { 1460 + className: 'inline-hover-text inline-hover-text-bright' 1461 + }; 1462 + 1463 + var attr_container = { 1464 + className: 'inline-hover-container' 1465 + }; 1466 + 1467 + var min = 0; 1468 + var max = rows.length - 1; 1469 + var offset_min; 1470 + var offset_max; 1471 + var len; 1472 + var node; 1473 + var text; 1474 + var any_highlight = false; 1475 + for (ii = 0; ii < rows.length; ii++) { 1476 + content = rows[ii].content; 1477 + len = content.length; 1339 1478 1340 - var dim = JX.$V(content_cell) 1341 - .add(JX.Vector.getAggregateScrollForNode(content_cell)) 1342 - .add(-pos.x, -pos.y) 1343 - .add(JX.Vector.getDim(content_cell)); 1479 + if (ii === min) { 1480 + offset_min = start; 1481 + } else { 1482 + offset_min = 0; 1483 + } 1484 + 1485 + if (ii === max) { 1486 + offset_max = Math.min(end, len); 1487 + } else { 1488 + offset_max = len; 1489 + } 1344 1490 1345 - var bpos = JX.$V(bot) 1346 - .add(JX.Vector.getAggregateScrollForNode(bot)); 1347 - dim.y = (bpos.y - pos.y) + JX.Vector.getDim(bot).y; 1491 + var has_min = (offset_min > 0); 1492 + var has_max = (offset_max < len); 1348 1493 1349 - pos.setPos(reticle); 1350 - dim.setDim(reticle); 1494 + if (has_min || has_max) { 1495 + any_highlight = true; 1496 + } 1351 1497 1352 - JX.DOM.show(reticle); 1498 + rows[ii].min = offset_min; 1499 + rows[ii].max = offset_max; 1500 + rows[ii].hasMin = has_min; 1501 + rows[ii].hasMax = has_max; 1502 + } 1503 + 1504 + for (ii = 0; ii < rows.length; ii++) { 1505 + content = rows[ii].content; 1506 + offset_min = rows[ii].min; 1507 + offset_max = rows[ii].max; 1508 + 1509 + var has_highlight = (rows[ii].hasMin || rows[ii].hasMax); 1510 + 1511 + if (any_highlight) { 1512 + var parts = []; 1513 + 1514 + if (offset_min > 0) { 1515 + text = content.substring(0, offset_min); 1516 + node = JX.$N('span', attr_dull, text); 1517 + parts.push(node); 1518 + } 1519 + 1520 + if (len) { 1521 + text = content.substring(offset_min, offset_max); 1522 + node = JX.$N('span', attr_bright, text); 1523 + parts.push(node); 1524 + } 1525 + 1526 + if (offset_max < len) { 1527 + text = content.substring(offset_max, len); 1528 + node = JX.$N('span', attr_dull, text); 1529 + parts.push(node); 1530 + } 1531 + 1532 + rows[ii].hoverNode = JX.$N('div', attr_container, parts); 1533 + } else { 1534 + rows[ii].hoverNode = null; 1535 + } 1536 + 1537 + rows[ii].bright = (any_highlight && !has_highlight); 1538 + } 1539 + 1540 + return rows; 1353 1541 }, 1354 1542 1355 1543 _getHoverNode: function() { ··· 2461 2649 } 2462 2650 } 2463 2651 2464 - var seen = 0; 2465 - for (var ii = 0; ii < td.childNodes.length; ii++) { 2466 - var child = td.childNodes[ii]; 2467 - if (child === fragment) { 2468 - offset = seen; 2469 - break; 2470 - } 2471 - seen += child.textContent.length; 2472 - } 2652 + var info = this._getSelectionOffset(td, fragment); 2473 2653 2474 - if (offset === null) { 2654 + if (info.found) { 2655 + offset = info.offset; 2656 + } else { 2475 2657 if (is_end) { 2476 - offset = seen; 2658 + offset = info.offset; 2477 2659 } else { 2478 2660 offset = 0; 2479 2661 } ··· 2500 2682 }; 2501 2683 }, 2502 2684 2685 + _getSelectionOffset: function(node, target) { 2686 + if (!node.childNodes || !node.childNodes.length) { 2687 + return { 2688 + offset: node.textContent.length, 2689 + content: node.textContent, 2690 + found: false 2691 + }; 2692 + } 2693 + 2694 + var found = false; 2695 + var offset = 0; 2696 + var content = ''; 2697 + for (var ii = 0; ii < node.childNodes.length; ii++) { 2698 + var child = node.childNodes[ii]; 2699 + 2700 + if (child === target) { 2701 + found = true; 2702 + } 2703 + 2704 + var spec = this._getSelectionOffset(child, target); 2705 + 2706 + content += spec.content; 2707 + if (!found) { 2708 + offset += spec.offset; 2709 + } 2710 + 2711 + found = found || spec.found; 2712 + } 2713 + 2714 + return { 2715 + offset: offset, 2716 + content: content, 2717 + found: found 2718 + }; 2719 + }, 2720 + 2503 2721 _getSelectedRanges: function() { 2504 2722 var ranges = []; 2505 2723 ··· 2518 2736 } 2519 2737 2520 2738 return ranges; 2739 + }, 2740 + 2741 + _isContentCell: function(node) { 2742 + return !!node.getAttribute('data-copy-mode'); 2521 2743 } 2744 + 2522 2745 } 2523 2746 2524 2747 });
+40 -9
webroot/rsrc/js/application/diff/DiffInline.js
··· 48 48 _skipFocus: false, 49 49 _menu: null, 50 50 51 + _startOffset: null, 52 + _endOffset: null, 53 + 51 54 bindToRow: function(row) { 52 55 this._row = row; 53 56 ··· 93 96 this._snippet = data.snippet; 94 97 this._menuItems = data.menuItems; 95 98 this._documentEngineKey = data.documentEngineKey; 99 + this._startOffset = data.startOffset; 100 + this._endOffset = data.endOffset; 96 101 97 102 this._isEditing = data.isEditing; 98 103 ··· 147 152 return this._isGhost; 148 153 }, 149 154 155 + getStartOffset: function() { 156 + return this._startOffset; 157 + }, 158 + 159 + getEndOffset: function() { 160 + return this._endOffset; 161 + }, 162 + 150 163 bindToRange: function(data) { 151 164 this._displaySide = data.displaySide; 152 165 this._number = parseInt(data.number, 10); ··· 154 167 this._isNewFile = data.isNewFile; 155 168 this._changesetID = data.changesetID; 156 169 this._isNew = true; 170 + this._startOffset = data.startOffset; 171 + this._endOffset = data.endOffset; 157 172 158 173 // Insert the comment after any other comments which already appear on 159 174 // the same row. ··· 506 521 }, 507 522 508 523 _newRequestData: function(operation, text) { 509 - return { 524 + var data = { 510 525 op: operation, 511 - id: this._id, 526 + is_new: this.isNewFile(), 512 527 on_right: ((this.getDisplaySide() == 'right') ? 1 : 0), 513 528 renderer: this.getChangeset().getRendererKey(), 514 - number: this.getLineNumber(), 515 - length: this.getLineLength(), 516 - is_new: this.isNewFile(), 517 - changesetID: this.getChangesetID(), 518 - replyToCommentPHID: this.getReplyToCommentPHID(), 519 - text: text || null, 520 - documentEngineKey: this._documentEngineKey, 529 + text: text || null 521 530 }; 531 + 532 + if (operation === 'new') { 533 + var create_data = { 534 + changesetID: this.getChangesetID(), 535 + documentEngineKey: this._documentEngineKey, 536 + replyToCommentPHID: this.getReplyToCommentPHID(), 537 + startOffset: this._startOffset, 538 + endOffset: this._endOffset, 539 + number: this.getLineNumber(), 540 + length: this.getLineLength() 541 + }; 542 + 543 + JX.copy(data, create_data); 544 + } else { 545 + var edit_data = { 546 + id: this._id 547 + }; 548 + 549 + JX.copy(data, edit_data); 550 + } 551 + 552 + return data; 522 553 }, 523 554 524 555 _oneditresponse: function(response) {