Merge branch 'master' of github.com:TurboWarp/packager
This commit is contained in:
9 files changed
+47
-26
No files matched your search
Generated
+3
-3
@@ -10592,9 +10592,9 @@
|
||||
}
|
||||
},
|
||||
"svelte": {
|
||||
"version": "3.42.3",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.42.3.tgz",
|
||||
"integrity": "sha512-pbdtdNZEx2GBqSM6XEgPoHbwtvWBwFLt/1bRmzsyXZO+i424wFnPe7O5B3GOJDPFSxPRztumAW3mL5LPzecWUg=="
|
||||
"version": "3.42.4",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.42.4.tgz",
|
||||
"integrity": "sha512-DqC0AmDdBrrbIA+Kzl3yhBb6qCn4vZOAfxye2pTnIpinLegyagC5sLI8Pe9GPlXu9VpHBXIwpDDedpMfu++epA=="
|
||||
},
|
||||
"svelte-dev-helper": {
|
||||
"version": "1.1.9",
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
"scratch-svg-renderer": "git://github.com/TurboWarp/scratch-svg-renderer.git#develop",
|
||||
"scratch-vm": "git://github.com/TurboWarp/scratch-vm.git#develop",
|
||||
"sha.js": "^2.4.11",
|
||||
"svelte": "^3.42.3"
|
||||
"svelte": "^3.42.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.0",
|
||||
|
||||
@@ -134,9 +134,12 @@
|
||||
e.target.select();
|
||||
};
|
||||
const handleDrop = ({detail: dataTransfer}) => {
|
||||
$type = 'file';
|
||||
files = dataTransfer.files;
|
||||
fileInputElement.files = files;
|
||||
const name = dataTransfer.files[0].name;
|
||||
if (name.endsWith('.sb') || name.endsWith('.sb2') || name.endsWith('.sb3')) {
|
||||
$type = 'file';
|
||||
files = dataTransfer.files;
|
||||
fileInputElement.files = files;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -12,6 +12,16 @@ const identifyProjectType = (projectData) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const isScratch1Project = (uint8array) => {
|
||||
const MAGIC = 'ScratchV';
|
||||
for (let i = 0; i < MAGIC.length; i++) {
|
||||
if (uint8array[i] !== MAGIC.charCodeAt(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const unknownAnalysis = () => ({
|
||||
stageVariables: {},
|
||||
usesMusic: true
|
||||
@@ -270,15 +280,17 @@ const downloadProject = async (data, progressCallback) => {
|
||||
});
|
||||
analysis = downloaded.analysis;
|
||||
} else {
|
||||
// It's a binary blob
|
||||
blob = new Blob([data]);
|
||||
let zip;
|
||||
try {
|
||||
zip = await JSZip.loadAsync(data);
|
||||
} catch (e) {
|
||||
// It's a Scratch 1 project, probably
|
||||
}
|
||||
if (zip) {
|
||||
if (isScratch1Project(bufferView)) {
|
||||
analysis = unknownAnalysis();
|
||||
} else {
|
||||
let zip;
|
||||
try {
|
||||
zip = await JSZip.loadAsync(data);
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
throw new Error('Cannot parse project');
|
||||
}
|
||||
const projectDataFile = zip.file('project.json');
|
||||
const projectDataText = await projectDataFile.async('text');
|
||||
const projectData = JSON.parse(projectDataText);
|
||||
@@ -288,8 +300,6 @@ const downloadProject = async (data, progressCallback) => {
|
||||
} else {
|
||||
analysis = analyzeScratch2(projectData);
|
||||
}
|
||||
} else {
|
||||
analysis = unknownAnalysis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import styles from './style.css';
|
||||
import {readAsText} from '../common/readers';
|
||||
|
||||
class Dropper {
|
||||
class DropArea {
|
||||
constructor (el, callback) {
|
||||
this.el = el;
|
||||
this.callback = callback;
|
||||
@@ -32,4 +32,4 @@ class Dropper {
|
||||
}
|
||||
}
|
||||
|
||||
export default Dropper;
|
||||
export default DropArea;
|
||||
@@ -1,5 +1,5 @@
|
||||
import ContextMenu from './context-menu';
|
||||
import Dropper from './dropper';
|
||||
import DropArea from './drop-area';
|
||||
import styles from './style.css';
|
||||
import {readAsText} from '../common/readers';
|
||||
|
||||
@@ -269,7 +269,7 @@ class ListMonitor extends Monitor {
|
||||
this.root.appendChild(this.rowsOuter);
|
||||
this.root.appendChild(this.footer);
|
||||
|
||||
this.dropper = new Dropper(this.rowsOuter, this.dropperCallback.bind(this));
|
||||
this.dropper = new DropArea(this.rowsOuter, this.dropperCallback.bind(this));
|
||||
|
||||
this.handleImport = this.handleImport.bind(this);
|
||||
this.handleExport = this.handleExport.bind(this);
|
||||
@@ -315,9 +315,7 @@ class ListMonitor extends Monitor {
|
||||
const files = e.target.files;
|
||||
if (files.length === 0) return;
|
||||
const file = files[0];
|
||||
readAsText(file).then((text) => {
|
||||
this.import(reader.result);
|
||||
});
|
||||
readAsText(file).then((text) => this.import(text));
|
||||
});
|
||||
fileSelector.click();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Dropper from './dropper';
|
||||
import DropArea from './drop-area';
|
||||
import styles from './style.css';
|
||||
|
||||
class Question {
|
||||
@@ -25,7 +25,7 @@ class Question {
|
||||
this.input.className = styles.questionInput;
|
||||
this.input.addEventListener('keypress', this.onkeypress.bind(this));
|
||||
|
||||
this.dropper = new Dropper(this.input, this.dropperCallback.bind(this));
|
||||
this.dropper = new DropArea(this.input, this.dropperCallback.bind(this));
|
||||
|
||||
this.submitButton = document.createElement('button');
|
||||
this.submitButton.className = styles.questionSubmitButton;
|
||||
|
||||
@@ -60,3 +60,12 @@ test('sb', async () => {
|
||||
expect(project.blob.size).toBe(554);
|
||||
expect(project.type).toBe('blob');
|
||||
});
|
||||
|
||||
test('invalid project', async () => {
|
||||
try {
|
||||
await downloadProject(readTestProject('invalid.txt'), () => {});
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Expected error, got success');
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
I am not a valid project
|
||||
Reference in new issue
Block a user