Skip to content

Commit db4220d

Browse files
committed
fix #5: show duplicate mappings
1 parent 8f2de6d commit db4220d

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

code.js

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,7 @@
10541054
const lastRow = Math.max(0, Math.ceil((scrollY - textPaddingY + height) / rowHeight));
10551055

10561056
// Populate batches for the text
1057-
let hoverBox = null;
1057+
const hoverBoxes = [];
10581058
const hoveredMapping = hover && hover.mapping;
10591059
const mappingBatches = [];
10601060
const badMappingBatches = [];
@@ -1112,20 +1112,34 @@
11121112
if (range === null) continue;
11131113

11141114
// Check if this mapping is hovered
1115-
const isHovered = hoveredMapping && (sourceIndex === null
1116-
? mappings[map] === hoveredMapping.generatedLine &&
1117-
mappings[map + 1] === hoveredMapping.generatedColumn
1118-
: mappings[map + 2] === hoveredMapping.originalSource &&
1119-
mappings[map + 3] === hoveredMapping.originalLine &&
1120-
mappings[map + 4] === hoveredMapping.originalColumn
1121-
);
1115+
let isHovered = false;
1116+
if (hoveredMapping) {
1117+
const isGenerated = sourceIndex === null;
1118+
const hoverIsGenerated = hover.sourceIndex === null;
1119+
const matchesGenerated =
1120+
mappings[map] === hoveredMapping.generatedLine &&
1121+
mappings[map + 1] === hoveredMapping.generatedColumn;
1122+
const matchesOriginal =
1123+
mappings[map + 2] === hoveredMapping.originalSource &&
1124+
mappings[map + 3] === hoveredMapping.originalLine &&
1125+
mappings[map + 4] === hoveredMapping.originalColumn;
1126+
isHovered = hoveredMapping && (isGenerated !== hoverIsGenerated
1127+
// If this is on the opposite pane from the mouse, show all
1128+
// mappings that match the hovered mapping instead of showing
1129+
// an exact match.
1130+
? matchesGenerated || matchesOriginal
1131+
// If this is on the same pane as the mouse, only show the exact
1132+
// mapping instead of showing everything that matches the target
1133+
// so hovering isn't confusing.
1134+
: isGenerated ? matchesGenerated : matchesOriginal);
1135+
}
11221136

11231137
// Add a rectangle to that color's batch
11241138
const { startColumn, endColumn } = range;
11251139
const color = mappings[map + 3] % originalLineColors.length;
11261140
const [x1, y1, x2, y2] = boxForRange(x, y, row, columnWidth, range);
11271141
if (isHovered) {
1128-
hoverBox = { color, rect: [x1 - 2, y1 - 2, x2 - x1 + 4, y2 - y1 + 4] };
1142+
hoverBoxes.push({ color, rect: [x1 - 2, y1 - 2, x2 - x1 + 4, y2 - y1 + 4] });
11291143
} else if (row >= lines.length || startColumn > endOfLineColumn) {
11301144
badMappingBatches[color].push(x1, y1, x2 - x1, y2 - y1);
11311145
} else if (endColumn > endOfLineColumn) {
@@ -1164,17 +1178,31 @@
11641178
let status = '';
11651179

11661180
// Draw the hover box for all text areas
1167-
if (hoverBox) {
1168-
const [rx, ry, rw, rh] = hoverBox.rect;
1169-
c.shadowColor = originalLineColors[hoverBox.color].replace(' 0.3)', ' 1)');
1181+
if (hoverBoxes.length > 0) {
1182+
// Draw the glows
11701183
c.shadowBlur = 20;
11711184
c.fillStyle = 'black';
1172-
c.fillRect(rx - 1, ry - 1, rw + 2, rh + 2);
1185+
for (const { rect: [rx, ry, rw, rh], color } of hoverBoxes) {
1186+
c.shadowColor = originalLineColors[color].replace(' 0.3)', ' 1)');
1187+
c.fillRect(rx - 1, ry - 1, rw + 2, rh + 2);
1188+
}
11731189
c.shadowColor = 'transparent';
1174-
c.clearRect(rx, ry, rw, rh);
1190+
1191+
// Hollow out the boxes and draw a border around each one
1192+
for (const { rect: [rx, ry, rw, rh] } of hoverBoxes) {
1193+
c.clearRect(rx, ry, rw, rh);
1194+
}
11751195
c.strokeStyle = textColor;
11761196
c.lineWidth = 2;
1177-
c.strokeRect(rx, ry, rw, rh);
1197+
for (const { rect: [rx, ry, rw, rh] } of hoverBoxes) {
1198+
c.strokeRect(rx, ry, rw, rh);
1199+
}
1200+
1201+
// Hollow out the boxes again. This is necessary to remove overlapping
1202+
// borders from adjacent boxes due to duplicate mappings.
1203+
for (const { rect: [rx, ry, rw, rh] } of hoverBoxes) {
1204+
c.clearRect(rx + 2, ry + 1, rw - 4, rh - 2);
1205+
}
11781206
}
11791207

11801208
// Draw the hover caret, but only for this text area
@@ -1301,8 +1329,8 @@
13011329
const generatedArrowHead = hover.sourceIndex === originalTextArea.sourceIndex;
13021330
const [ox, oy, ow, oh] = originalHoverRect;
13031331
const [gx, gy, , gh] = generatedHoverRect;
1304-
const x1 = Math.min(ox + ow, originalBounds.x + originalBounds.width) + (originalArrowHead ? 10 : 0);
1305-
const x2 = Math.max(gx, generatedBounds.x + margin) - (generatedArrowHead ? 10 : 0);
1332+
const x1 = Math.min(ox + ow, originalBounds.x + originalBounds.width) + (originalArrowHead ? 10 : 2);
1333+
const x2 = Math.max(gx, generatedBounds.x + margin) - (generatedArrowHead ? 10 : 2);
13061334
const y1 = oy + oh / 2;
13071335
const y2 = gy + gh / 2;
13081336

0 commit comments

Comments
 (0)