-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
182 lines (162 loc) · 9.04 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content="This bookmarklet allows you to easily link to (almost) any text on (almost) any webpage." />
<meta name="author" content="https://www.curiositry.com">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="MobileOptimized" content="320">
<meta name="HandheldFriendly" content="True">
<title>🔗 Link to selected text bookmarklet: create scroll-to-text fragment links in Firefox in 1 click</title>
<link rel="stylesheet" href="css/tufte.min.css" media="screen" />
<!-- <link rel="shortcut icon" href="favicon.png" /> -->
<!-- <link rel="apple-touch-icon" href="apple-touch-icon.png" /> -->
</head>
<body>
<h1>Bookmarklet: Create Link to Selected Text Fragment</h1>
<h2>Deeplink to any text on the web</h2>
<br>
<p>This bookmarklet allows you to easily link to (almost) any text on (almost) any webpage.</p>
<p>
<ol>
<li><strong>Select some words.</strong></li>
<li><strong>Click the bookmarklet</strong> to generate a link <em>to that text</em> deep down in the middle of an article.</li>
<li>If you forgot to select text before clicking the bookmarklet, you can select it now.</li>
</ol>
</p>
<p>
<em>Boom!</em> The page will reload so you can preview the URL and make sure it worked correctly. If possible, the bookmarklet will also put the URL that links directly to the selected text on your clipboard. </p>
<p>Drag the bookmarklet to your browser’s bookmarks bar:</p>
<p>
<a id="bookmarklet" href="javascript:void%20function(){javascript:(function(){function%20a(){var%20a;if(window.getSelection%26%26(a=window.getSelection()).modify){if(a=window.getSelection(),!a.isCollapsed){var%20b=document.createRange();b.setStart(a.anchorNode,a.anchorOffset),b.setEnd(a.focusNode,a.focusOffset);var%20c=b.collapsed;b.detach();var%20d=a.focusNode,e=a.focusOffset;a.collapse(a.anchorNode,a.anchorOffset);var%20f=[];f=c%3F[%22backward%22,%22forward%22]:[%22forward%22,%22backward%22],a.modify(%22move%22,f[0],%22character%22),a.modify(%22move%22,f[1],%22word%22),a.extend(d,e);let%20g=a.toString();a.modify(%22extend%22,f[1],%22character%22);!0==/\p{P}|\s/gu.test(g.slice(g.length-1,g.length))%26%26(a.modify(%22extend%22,f[1],%22character%22),a.modify(%22extend%22,f[1],%22character%22),console.log(%22reversing%20again%22)),a.modify(%22extend%22,f[0],%22word%22)}}else%20if((a=document.selection)%26%26%22Control%22!=a.type){var%20g=a.createRange();if(g.text){for(g.expand(%22word%22);/\s$/.test(g.text);)g.moveEnd(%22character%22,-1);g.select()}}}function%20b(){let%20b=%22%22;const%20c=document.activeElement,d=c%3Fc.tagName.toLowerCase():null;return%22textarea%22==d||%22input%22==d%26%26/^(%3F:text|search|password|tel|url)$/i.test(c.type)%26%26%22number%22==typeof%20c.selectionStart%3F(a(),b=c.value.slice(c.selectionStart,c.selectionEnd)):window.getSelection%26%26(a(),b=window.getSelection().toString()),b}function%20c(){let%20a=encodeURIComponent(b());if(0%3Ca.length){if(0%3C(a.match(/%250A/g)||[]).length){let%20b=a.split(%22%250A%22);a=b[0]+%22,%22+b[b.length-1]}let%20b=d+%22%23:~:text=%22+a;navigator.clipboard.writeText(b).then(()=%3E{console.log(%22URL%20copied%20to%20clipboard:%22,b)}),window.location=b}else%20console.log(%22Selection%20was%20blank,%20please%20select%20some%20text.%22)}let%20d=window.location,e=encodeURIComponent(b());1%3Ee.length%3Fdocument.onmouseup=document.onkeyup=function(){c()}:c()})()}();">
Link to Selected Text
</a>
</p>
<p>(^^^ Or click it to try it on this page!)</p>
<p> Inspired by <a href="https://calebhearth.com/text-fragments?ref=https://www.curiositry.com/text-fragment-linker/">this article</a>.
</p><p>
⇒ If none of this makes sense, read <a href="https://autodidacts.io/scroll-to-text-fragment-bookmarklet/">the announcement post</a> for more confusion.</p>
<h2>Go advanced!</h2>
<p>For more advanced text-linking, use the widget below:</p>
<p><em>Example: to highlight half of a word, you can put “high” in the prefix field and “light” in the text field.</em></p>
<label for="urlInput">URL</label>
<input id="urlInput" title="URL" value="https://www.curiositry.com/text-fragment-linker/">
<br>
<label for="prefixInput">Prefix (optional)</label>
<input id="prefixInput" title="Prefix" value="more">
<label for="startInput">Start</label>
<input id="startInput" title="Start" >
<label for="textInput">Text (if start and end are used this is ignored)</label>
<input id="textInput" title="Text" value="advanced">
<label for="endInput">End</label>
<input id="endInput" title="End" >
<label for="suffixInput">Suffix (optional)</label>
<input id="suffixInput" title="Suffix" >
<p>Your link!</p>
<p>
<a href="https://www.curiositry.com/text-fragment-linker/#:~:text=more-,advanced,-text" id="output" class="output">https://www.curiositry.com/text-fragment-linker/#:~:text=more-,advanced,-text</a>
</p>
<label for="additionalTextInput">Additional text fragment(s) (optional)</label>
<input id="additionalTextInput" title="Additional text fragments" value="widget">
<p>Preview (may not work for all sites)</p>
<iframe src="https://www.curiositry.com/text-fragment-linker/#:~:text=more-,advanced,-text" id="preview"></iframe>
<br><hr>
<footer>
<p>
Open-source on <a href="https://github.com/curiositry/text-fragment-linker/">GitHub</a> (MIT Licence)
• built with <a href="https://edwardtufte.github.io/tufte-css/">tufte.css</a> & <a href="https://github.com/chriszarate/bookmarkleter">bookmarkleter</a>
<p>If you like it, please tell your friends and post it to Reddit and stuff.</p>
</p>
</footer>
<script>
let url = window.location;
function update() {
console.log("Update function run")
let oldurl = document.getElementById("preview").src;
let url = document.getElementById("urlInput").value;
let prefix = encodeURIComponent(document.getElementById("prefixInput").value);
let start = encodeURIComponent(document.getElementById("startInput").value);
let text = encodeURIComponent(document.getElementById("textInput").value);
let end = encodeURIComponent(document.getElementById("endInput").value);
let suffix = encodeURIComponent(document.getElementById("suffixInput").value);
let additionalText = document.getElementById("additionalTextInput").value;
// Clear example selectors if URL isn't to this page, and they haven't been changed
// This is because it's easy to miss that those fields are pre-filled, and breaking what
// the user entered in a different field
if (url != oldurl) {
if (text == "advanced" || prefix == "more") {
if (oldurl.includes("curiositry.com") && !url.includes("curiositry.com")) {
document.getElementById("textInput").value = "";
document.getElementById("prefixInput").value = "";
document.getElementById("additionalTextInput").value = "";
}
}
}
if (prefix.length > 0) {
prefix = prefix+"-,"
}
if (suffix.length > 0) {
suffix = ",-"+suffix
}
if (start.length > 0) {
if (end.length > 0) {
text = start + "," + end
}
}
if (additionalText.length > 0) {
additionalText = "&text="+additionalText;
} else {
additionalText = "";
}
let output = url + "#:~:text=" + prefix + text + suffix + additionalText;
// clear previous highlights by fully reloading the iframe
document.getElementById("preview").src = '';
// set the iframe to the new url (or the same url, but with new text fragments to highlight)
document.getElementById("preview").src = output;
// for very large documents (ie ebooks), it doesn't scroll to text because the text hasn't loaded
// so we re-source the iframe once it has loaded in
document.getElementById("preview").onload = function() {
document.getElementById("preview").src = document.getElementById("preview").src;
}
document.getElementById("output").innerHTML = output;
document.getElementById("output").href = output;
}
const inputFields = document.querySelectorAll('input');
inputFields.forEach(function (field) {
field.addEventListener('input', function (event) {
console.log(`Input event triggered in ${field.name}`);
update();
});
});
</script>
<style>
iframe,
input {
box-sizing: border-box;
width: calc(100% - 2em);
max-width: 100%;
display: block;
margin: 1rem 0;
}
input {
padding: 0.5rem;
}
iframe {
height: 100vh;
}
#output {
font-size: larger;
font-weight: 700;
}
#bookmarklet {
font-size: larger;
padding: 0.75em 1em 0.5em 1em;
margin: 0.5em 0;
display: inline-block;
background: beige;
border: 1px solid grey;
border-radius: 0.15rem;
}
</style>
</body>
</html>