tangled
alpha
login
or
join now
margin.at
/
margin
87
fork
atom
Write on the margins of the internet. Powered by the AT Protocol.
margin.at
extension
web
atproto
comments
87
fork
atom
overview
issues
4
pulls
1
pipelines
remove text selection popup
scanash.com
1 month ago
50899d3a
33bf7042
+2
-124
1 changed file
expand all
collapse all
unified
split
extension
content
content.js
+2
-124
extension/content/content.js
···
2
2
let sidebarHost = null;
3
3
let sidebarShadow = null;
4
4
let popoverEl = null;
5
5
-
let selectionPopupEl = null;
5
5
+
6
6
7
7
let activeItems = [];
8
8
let currentSelection = null;
···
470
470
471
471
document.addEventListener("mousemove", handleMouseMove);
472
472
document.addEventListener("click", handleDocumentClick, true);
473
473
-
document.addEventListener("mouseup", handleTextSelection);
474
474
-
}
475
475
-
476
476
-
function handleTextSelection(e) {
477
477
-
if (e.target.closest && e.target.closest("#margin-overlay-host")) return;
478
478
-
479
479
-
const selection = window.getSelection();
480
480
-
const selectedText = selection?.toString().trim();
481
481
-
if (!selectedText || selectedText.length < 3) {
482
482
-
hideSelectionPopup();
483
483
-
return;
484
484
-
}
485
485
-
486
486
-
const anchorNode = selection.anchorNode;
487
487
-
if (anchorNode) {
488
488
-
const parent = anchorNode.parentElement;
489
489
-
if (
490
490
-
parent &&
491
491
-
(parent.tagName === "INPUT" ||
492
492
-
parent.tagName === "TEXTAREA" ||
493
493
-
parent.isContentEditable)
494
494
-
) {
495
495
-
return;
496
496
-
}
497
497
-
}
498
498
-
499
499
-
currentSelection = {
500
500
-
text: selectedText,
501
501
-
selector: { type: "TextQuoteSelector", exact: selectedText },
502
502
-
};
503
503
-
504
504
-
showSelectionPopup(e.clientX, e.clientY);
505
505
-
}
506
506
-
507
507
-
function showSelectionPopup(x, y) {
508
508
-
hideSelectionPopup();
509
509
-
if (!sidebarShadow) return;
510
510
-
511
511
-
const container = sidebarShadow.getElementById("margin-overlay-container");
512
512
-
if (!container) return;
513
513
-
514
514
-
selectionPopupEl = document.createElement("div");
515
515
-
selectionPopupEl.className = "margin-selection-popup";
516
516
-
517
517
-
const popupWidth = 180;
518
518
-
const viewportWidth = window.innerWidth;
519
519
-
let left = x + 5;
520
520
-
if (left + popupWidth > viewportWidth) {
521
521
-
left = viewportWidth - popupWidth - 10;
522
522
-
}
523
523
-
524
524
-
selectionPopupEl.style.left = `${left}px`;
525
525
-
selectionPopupEl.style.top = `${y + 10}px`;
526
526
-
527
527
-
selectionPopupEl.innerHTML = `
528
528
-
<button class="selection-btn btn-annotate">
529
529
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
530
530
-
<path d="M12 20h9M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
531
531
-
</svg>
532
532
-
Annotate
533
533
-
</button>
534
534
-
<button class="selection-btn btn-highlight">
535
535
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
536
536
-
<path d="M9 11l3 3L22 4"/>
537
537
-
<path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>
538
538
-
</svg>
539
539
-
Highlight
540
540
-
</button>
541
541
-
`;
542
542
-
543
543
-
selectionPopupEl
544
544
-
.querySelector(".btn-annotate")
545
545
-
.addEventListener("click", (e) => {
546
546
-
e.stopPropagation();
547
547
-
hideSelectionPopup();
548
548
-
showInlineComposeModal();
549
549
-
});
550
550
-
551
551
-
selectionPopupEl
552
552
-
.querySelector(".btn-highlight")
553
553
-
.addEventListener("click", async (e) => {
554
554
-
e.stopPropagation();
555
555
-
hideSelectionPopup();
556
556
-
557
557
-
chrome.runtime.sendMessage(
558
558
-
{
559
559
-
type: "CREATE_HIGHLIGHT",
560
560
-
data: {
561
561
-
url: window.location.href,
562
562
-
title: document.title,
563
563
-
selector: currentSelection.selector,
564
564
-
color: "#fcd34d",
565
565
-
},
566
566
-
},
567
567
-
(res) => {
568
568
-
if (res && res.success) {
569
569
-
fetchAnnotations();
570
570
-
}
571
571
-
},
572
572
-
);
573
573
-
});
574
574
-
575
575
-
container.appendChild(selectionPopupEl);
576
576
-
577
577
-
setTimeout(() => {
578
578
-
document.addEventListener("mousedown", closeSelectionPopupOutside, {
579
579
-
once: true,
580
580
-
});
581
581
-
}, 100);
582
582
-
}
583
583
-
584
584
-
function hideSelectionPopup() {
585
585
-
if (selectionPopupEl) {
586
586
-
selectionPopupEl.remove();
587
587
-
selectionPopupEl = null;
588
588
-
}
589
589
-
}
590
590
-
591
591
-
function closeSelectionPopupOutside(e) {
592
592
-
if (selectionPopupEl && !selectionPopupEl.contains(e.target)) {
593
593
-
hideSelectionPopup();
594
594
-
}
595
473
}
596
474
597
475
function showInlineComposeModal() {
···
762
640
const firstRect = firstRange.getClientRects()[0];
763
641
const totalWidth =
764
642
Math.min(uniqueAuthors.length, maxShow + (overflow > 0 ? 1 : 0)) *
765
765
-
18 +
643
643
+
18 +
766
644
8;
767
645
const leftPos = firstRect.left - totalWidth;
768
646
const topPos = firstRect.top + firstRect.height / 2 - 12;