Skip to content

Commit d536ba6

Browse files
committed
rewrite pod2html js without jquery
1 parent cd18f25 commit d536ba6

File tree

2 files changed

+126
-103
lines changed

2 files changed

+126
-103
lines changed

root/pod2html/pod2html.tx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
%% }
44
%% override content -> {
55
<div class="metacpan-pod-renderer">
6+
<template id="metacpan-pod-renderer-content">
7+
<nav class="toc">
8+
<div class="toc-header"><strong>Contents</strong></div>
9+
<div class="toc-body"></div>
10+
</nav>
11+
<div class="pod-body"></div>
12+
</template>
613
<div class="panel panel-default">
714
<div class="panel-heading" role="tab">
815
<h3 class="panel-title">Pod Renderer</h3>

root/static/js/pod2html.mjs

Lines changed: 119 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,132 @@
1-
import jQuery from 'jquery';
21
import {
32
formatTOC,
43
createAnchors
54
}
65
from './document-ui.mjs';
76

8-
const pod2html_form = jQuery('#metacpan-pod-renderer-form');
9-
const pod2html_text = jQuery('[name="pod"]', pod2html_form);
10-
const pod2html_update = function(pod) {
11-
if (!pod) {
12-
pod = pod2html_text.get(0).value;
13-
}
14-
const submit = pod2html_form.find('input[type="submit"]');
15-
submit.attr("disabled", "disabled");
16-
const rendered = jQuery('#metacpan-pod-renderer-output');
17-
const loading = jQuery('#metacpan-pod-renderer-loading');
18-
const error = jQuery('#metacpan-pod-renderer-error');
19-
rendered.hide();
20-
rendered.html('');
21-
loading.show();
22-
error.hide();
23-
document.title = "Pod Renderer - metacpan.org";
24-
jQuery.ajax({
25-
url: '/pod2html',
26-
method: 'POST',
27-
data: {
28-
pod: pod
29-
},
30-
headers: {
31-
Accept: "application/json"
32-
},
33-
success: function(data) {
34-
const title = data.pod_title;
35-
document.title = "Pod Renderer - " + title + " - metacpan.org";
36-
rendered.html(
37-
'<nav class="toc"><div class="toc-header"><strong>Contents</strong></div>' +
38-
data.pod_index +
39-
'</nav>' +
40-
data.pod_html
41-
);
42-
var toc = jQuery("nav", rendered);
43-
if (toc.length) {
44-
formatTOC(toc[0]);
7+
const pod2htmlForm = document.querySelector('#metacpan-pod-renderer-form');
8+
if (pod2htmlForm) {
9+
const textInput = pod2htmlForm.querySelector('[name="pod"]');
10+
const submit = pod2htmlForm.querySelector('input[type="submit"]');
11+
const renderer = document.querySelector('.metacpan-pod-renderer');
12+
const rendered = document.querySelector('#metacpan-pod-renderer-output');
13+
const loading = document.querySelector('#metacpan-pod-renderer-loading');
14+
const error = document.querySelector('#metacpan-pod-renderer-error');
15+
const template = document.querySelector('#metacpan-pod-renderer-content');
16+
17+
const updateHTML = async (pod) => {
18+
if (!pod) {
19+
pod = textInput.value;
20+
}
21+
submit.disabled = true;
22+
document.title = "Pod Renderer - metacpan.org";
23+
24+
rendered.style.display = 'none';
25+
rendered.replaceChildren();
26+
loading.style.display = 'block';
27+
error.style.display = 'none';
28+
29+
try {
30+
const form = new FormData();
31+
form.set('pod', pod);
32+
33+
const response = await fetch('/pod2html', {
34+
method: 'POST',
35+
headers: {
36+
"Accept": "application/json",
37+
},
38+
body: form,
39+
});
40+
41+
if (!response.ok) {
42+
throw new Error(await response.text());
4543
}
44+
45+
const data = await response.json();
46+
47+
document.title = "Pod Renderer - " + data.pod_title + " - metacpan.org";
48+
49+
const body = template.content.cloneNode(true);
50+
body.querySelector('.toc-body').outerHTML = data.pod_index;
51+
body.querySelector('.pod-body').outerHTML = data.pod_html;
52+
rendered.replaceChildren(body);
53+
54+
formatTOC(rendered.querySelector('nav'));
4655
createAnchors(rendered);
47-
loading.hide();
48-
error.hide();
49-
rendered.show();
50-
submit.removeAttr("disabled");
51-
},
52-
error: function(data) {
53-
rendered.hide();
54-
loading.hide();
55-
error.html('Error rendering POD' +
56-
(data && data.length ? ' - ' + data : ''));
57-
error.show();
58-
submit.removeAttr("disabled");
56+
57+
loading.style.display = 'none';
58+
error.style.display = 'none';
59+
rendered.style.display = 'block';
60+
61+
submit.disabled = false;
5962
}
63+
catch (err) {
64+
rendered.style.display = 'none';
65+
loading.style.display = 'none';
66+
67+
error.replaceChildren();
68+
error.append('Error rendering POD - ' + err.message);
69+
error.style.display = 'block';
70+
submit.disabled = false;
71+
}
72+
};
73+
74+
pod2htmlForm.addEventListener('submit', (ev) => {
75+
ev.preventDefault();
76+
ev.stopPropagation();
77+
updateHTML();
6078
});
61-
};
62-
if (window.FileReader) {
63-
jQuery('input[type="file"]', pod2html_form).on('change', function() {
64-
const files = this.files;
65-
for (var i = 0; i < files.length; i++) {
66-
const file = files[i];
67-
const reader = new FileReader();
68-
reader.onload = function(e) {
69-
pod2html_text.get(0).value = e.target.result;
70-
pod2html_update(e.target.result);
71-
};
72-
reader.readAsText(file);
79+
80+
const readFile = (file) => {
81+
const reader = new FileReader();
82+
reader.addEventListener('load', () => {
83+
textInput.value = reader.result;
84+
updateHTML(reader.result);
85+
});
86+
reader.readAsText(file);
87+
};
88+
89+
const fileInput = pod2htmlForm.querySelector('input[type="file"]');
90+
fileInput.addEventListener('change', () => {
91+
const file = fileInput.files[0];
92+
if (!file) {
93+
return;
94+
}
95+
readFile(file);
96+
fileInput.value = null;
97+
});
98+
99+
let dragTimer;
100+
renderer.addEventListener("dragover", (ev) => {
101+
ev.preventDefault();
102+
if (dragTimer) {
103+
window.clearTimeout(dragTimer);
104+
}
105+
dragTimer = window.setTimeout(() => {
106+
renderer.classList.remove("dragging");
107+
window.clearTimeout(dragTimer);
108+
dragTimer = null;
109+
}, 500);
110+
});
111+
112+
document.addEventListener("dragenter", function() {
113+
renderer.classList.add("dragging");
114+
});
115+
116+
renderer.addEventListener("drop", (ev) => {
117+
const data = ev.dataTransfer;
118+
if (data && data.files && data.files.length) {
119+
const file = data.files[0];
120+
121+
ev.preventDefault();
122+
ev.stopPropagation();
123+
renderer.classList.remove("dragging");
124+
if (dragTimer) {
125+
window.clearTimeout(dragTimer);
126+
dragTimer = null;
127+
}
128+
129+
readFile(file);
73130
}
74-
this.value = null;
75131
});
76132
}
77-
pod2html_form.on('submit', function(e) {
78-
e.preventDefault();
79-
e.stopPropagation();
80-
pod2html_update();
81-
});
82-
83-
const renderer = jQuery(".metacpan-pod-renderer")
84-
85-
let dragTimer;
86-
renderer.on("dragover", function(event) {
87-
event.preventDefault();
88-
if (dragTimer) {
89-
window.clearTimeout(dragTimer);
90-
}
91-
dragTimer = window.setTimeout(function() {
92-
renderer.removeClass("dragging");
93-
window.clearTimeout(dragTimer);
94-
dragTimer = null;
95-
}, 500);
96-
});
97-
98-
jQuery(document).on("dragenter", function() {
99-
renderer.addClass("dragging");
100-
});
101-
102-
renderer.on("drop", function(event) {
103-
event.preventDefault();
104-
event.stopPropagation();
105-
renderer.removeClass("dragging");
106-
if (dragTimer) {
107-
window.clearTimeout(dragTimer);
108-
dragTimer = null;
109-
}
110-
const reader = new FileReader();
111-
reader.onload = function(e) {
112-
pod2html_text.get(0).value = e.target.result;
113-
pod2html_update(e.target.result);
114-
};
115-
reader.readAsText(event.originalEvent.dataTransfer.files[0]);
116-
});

0 commit comments

Comments
 (0)