Skip to content

Commit e522bad

Browse files
committed
close #17: add loading from clipboard on paste
1 parent 9578420 commit e522bad

File tree

1 file changed

+44
-33
lines changed

1 file changed

+44
-33
lines changed

code.js

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -85,48 +85,53 @@
8585
}
8686

8787
function showLoadingError(text) {
88-
promptText.style.display = 'block';
89-
toolbar.style.display = 'none';
90-
statusBar.style.display = 'none';
91-
canvas.style.display = 'none';
88+
resetLoadingState();
9289
errorText.style.display = 'block';
9390
errorText.textContent = text;
94-
}
9591

96-
async function startLoading(files) {
97-
if (files.length === 1) {
98-
const file0 = files[0];
99-
const code = await loadFile(file0);
100-
101-
// Check for both "//" and "/*" comments
102-
let match = /\/\/#\s*sourceMappingURL=data:([^,]+),([^ ]+)/.exec(code);
103-
if (!match) match = /\/\*#\s*sourceMappingURL=data:((?:[^,*]|\*[^/])+),((?:[^ *]|\*[^/])+)(?:[^*]|\*[^/])*\*\//.exec(code);
104-
105-
// Check for a non-empty data URL payload
106-
if (match && match[2]) {
107-
const parts = match[1].split(';');
108-
const map = parts.indexOf('base64') >= 0 ? utf8ToUTF16(atob(match[2])) : decodeURIComponent(match[2]);
109-
finishLoading(code, map);
92+
// Push an empty hash since the state has been cleared
93+
if (location.hash !== '') {
94+
try {
95+
history.pushState({}, '', location.pathname);
96+
} catch (e) {
11097
}
98+
}
99+
}
111100

112-
else if (match = /\/([/*])#\s*sourceMappingURL=data:/.exec(code)) {
113-
showLoadingError(`Could not find any base64 data in the embedded "/${match[1]}# sourceMappingURL=" comment.`);
101+
async function finishLoadingCodeWithEmbeddedSourceMap(code, file) {
102+
// Check for both "//" and "/*" comments
103+
let match = /\/(\/)[#@] *sourceMappingURL=([^\s]+)/.exec(code);
104+
if (!match) match = /\/(\*)[#@] *sourceMappingURL=((?:[^\s*]|\*[^/])+)(?:[^*]|\*[^/])*\*\//.exec(code);
105+
106+
// Check for a non-empty data URL payload
107+
if (match && match[2]) {
108+
let map;
109+
try {
110+
// Use "new URL" to ensure that the URL has a protocol (e.g. "data:" or "https:")
111+
map = await fetch(new URL(match[2])).then(r => r.text());
112+
} catch (e) {
113+
showLoadingError(`Failed to parse the URL in the "/${match[1]}# sourceMappingURL=" comment: ${e && e.message || e}`);
114+
return;
114115
}
116+
finishLoading(code, map);
117+
}
115118

116-
else if (match = /\/([/*])#\s*sourceMappingURL=/.exec(code)) {
117-
showLoadingError(`The embedded "/${match[1]}# sourceMappingURL=" comment does not contain an inline source map. ` +
118-
`You must import both the JavaScript file and the source map file that goes with it.`);
119-
}
119+
else if (file && isProbablySourceMap(file)) {
120+
// Allow loading a source map without a generated file because why not
121+
finishLoading('', code);
122+
}
120123

121-
else if (isProbablySourceMap(file0)) {
122-
// Allow loading a source map without a generated file because why not
123-
finishLoading('', code);
124-
}
124+
else {
125+
const c = file && file.name.endsWith('ss') ? '*' : '/';
126+
showLoadingError(`Failed to find an embedded "/${c}# sourceMappingURL=" comment in the ${file ? 'imported file' : 'pasted text'}.`);
127+
}
128+
}
125129

126-
else {
127-
const c = file0.name.endsWith('ss') ? '*' : '/';
128-
showLoadingError(`Failed to find an embedded "/${c}# sourceMappingURL=" comment in the imported file.`);
129-
}
130+
async function startLoading(files) {
131+
if (files.length === 1) {
132+
const file0 = files[0];
133+
const code = await loadFile(file0);
134+
finishLoadingCodeWithEmbeddedSourceMap(code, file0);
130135
}
131136

132137
else if (files.length === 2) {
@@ -159,6 +164,12 @@
159164
}
160165
}
161166

167+
document.body.addEventListener('paste', e => {
168+
e.preventDefault();
169+
const code = e.clipboardData.getData('text/plain');
170+
finishLoadingCodeWithEmbeddedSourceMap(code, null);
171+
});
172+
162173
// Accelerate VLQ decoding with a lookup table
163174
const vlqTable = new Uint8Array(128);
164175
const vlqChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

0 commit comments

Comments
 (0)