-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
170 lines (158 loc) · 5.03 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
<!DOCTYPE html5>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Converts HTML exported from Pocket into an importable format</title>
<style>
form > div {
margin-bottom: 16px;
margin-top: 16px;
}
span.warn {
color: #d22;
}
</style>
</head>
<body>
<p>
Pocket
<a
href="https://help.getpocket.com/article/1015-exporting-your-pocket-list"
rel="noopener norefrer"
target="_blank"
>can export saves.</a
>
However, exported html
<a
href="https://getpocket.com/import/browser"
rel="noopener norefrer"
target="_blank"
>cannot be imported as-is.</a
>
</p>
<p>
Select the exported html file and click "Convert!" to convert it to an
importable format.
</p>
<form id="_form" onsubmit>
<div>
<label>
Exported file
<input accept="text/html" id="fileInput" type="file" />
</label>
</div>
<div>
<label>
Chunk size
<select id="chunkSizeInput">
<option value="100">100</option>
<option value="200">200</option>
<option selected value="400">400</option>
<option value="600">600</option>
<option value="800">800</option>
</select>
<br />
<span class="warn"
>If the chunk size is too large, 504 error will be returned upon import.</span
>
</label>
</div>
<div>
<button>Convert!</button>
</div>
</form>
<ul id="resultList"></ul>
<script>
const TEMPLATE = `<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'none'; img-src data: *; object-src 'none'"><\/meta>
<TITLE>Bookmarks<\/TITLE>
<H1>Bookmark Menu<i/H1>
<DL><p>
<HR>
<!-- placeholder -->
<\/DL>`;
document.addEventListener("DOMContentLoaded", (event) => {
const _form = document.getElementById("_form");
const fileInput = document.getElementById("fileInput");
const chunkSizeInput = document.getElementById("chunkSizeInput");
const resultList = document.getElementById("resultList");
_form.addEventListener("submit", (e) => {
e.preventDefault();
const files = fileInput.files;
if (files.length !== 1) {
return;
}
const exportedFile = files[0];
const chunkSize = parseInt(chunkSizeInput.value, 10);
(async () => {
const hrefAndTitles = await loadExportedHtml(exportedFile);
const reversed = hrefAndTitles.reverse();
resultList.innerHTML = "";
let i = 1;
for (const chunked of chunk(reversed, chunkSize)) {
const links = chunked
.map(
({ href, title }) =>
'<DT><A HREF="' +
encodeURI(href) +
'" ADD_DATE="0" LAST_MODIFIED="0">' +
title +
"<\/A>"
)
.join("\n");
const importableHtml = TEMPLATE.replace(
"<!-- placeholder -->",
links
);
const anchor = document.createElement("a");
anchor.download = `bookmarks${i}.html`;
anchor.href = await htmlToDataUri(importableHtml);
anchor.textContent = anchor.download;
const li = document.createElement("li");
li.appendChild(anchor);
resultList.appendChild(li);
i++;
}
})();
});
});
function loadExportedHtml(file) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.addEventListener("load", () => {
const parser = new DOMParser();
const dom = parser.parseFromString(reader.result, "text/html");
const anchors = Array.from(dom.getElementsByTagName("a"));
resolve(
anchors.map((anchor) => ({
href: anchor.href,
title: anchor.textContent,
}))
);
});
reader.readAsText(file);
});
}
function chunk(array, size) {
const result = [];
const last = Math.ceil(array.length / size);
for (let i = 0; i < last; i++) {
result.push(array.slice(i * size, (i + 1) * size));
}
return result;
}
function htmlToDataUri(str) {
return new Promise((resolve) => {
const fileReader = new FileReader();
fileReader.addEventListener("load", () => resolve(fileReader.result));
fileReader.readAsDataURL(new Blob([str], { type: "text/html" }));
});
}
</script>
</body>
</html>