kopia lustrzana https://github.com/backface/turtlestitch
commit
643cf9072f
|
@ -1,2 +1,2 @@
|
|||
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
||||
var saveAs=saveAs||function(e){"use strict";if(typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),i="download"in r,o=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),f=e.webkitRequestFileSystem,u=e.requestFileSystem||f||e.mozRequestFileSystem,s=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},c="application/octet-stream",d=0,l=500,w=function(t){var r=function(){if(typeof t==="string"){n().revokeObjectURL(t)}else{t.remove()}};if(e.chrome){r()}else{setTimeout(r,l)}},p=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var i=e["on"+t[r]];if(typeof i==="function"){try{i.call(e,n||e)}catch(o){s(o)}}}},v=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob(["\ufeff",e],{type:e.type})}return e},y=function(t,s,l){if(!l){t=v(t)}var y=this,m=t.type,S=false,h,R,O=function(){p(y,"writestart progress write writeend".split(" "))},g=function(){if(R&&a&&typeof FileReader!=="undefined"){var r=new FileReader;r.onloadend=function(){var e=r.result;R.location.href="data:attachment/file"+e.slice(e.search(/[,;]/));y.readyState=y.DONE;O()};r.readAsDataURL(t);y.readyState=y.INIT;return}if(S||!h){h=n().createObjectURL(t)}if(R){R.location.href=h}else{var i=e.open(h,"_blank");if(i==undefined&&a){e.location.href=h}}y.readyState=y.DONE;O();w(h)},b=function(e){return function(){if(y.readyState!==y.DONE){return e.apply(this,arguments)}}},E={create:true,exclusive:false},N;y.readyState=y.INIT;if(!s){s="download"}if(i){h=n().createObjectURL(t);r.href=h;r.download=s;setTimeout(function(){o(r);O();w(h);y.readyState=y.DONE});return}if(e.chrome&&m&&m!==c){N=t.slice||t.webkitSlice;t=N.call(t,0,t.size,c);S=true}if(f&&s!=="download"){s+=".download"}if(m===c||f){R=e}if(!u){g();return}d+=t.size;u(e.TEMPORARY,d,b(function(e){e.root.getDirectory("saved",E,b(function(e){var n=function(){e.getFile(s,E,b(function(e){e.createWriter(b(function(n){n.onwriteend=function(t){R.location.href=e.toURL();y.readyState=y.DONE;p(y,"writeend",t);w(e)};n.onerror=function(){var e=n.error;if(e.code!==e.ABORT_ERR){g()}};"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=y["on"+e]});n.write(t);y.abort=function(){n.abort();y.readyState=y.DONE};y.readyState=y.WRITING}),g)}),g)};e.getFile(s,{create:false},b(function(e){e.remove();n()}),b(function(e){if(e.code===e.NOT_FOUND_ERR){n()}else{g()}}))}),g)}),g)},m=y.prototype,S=function(e,t,n){return new y(e,t,n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){if(!n){e=v(e)}return navigator.msSaveOrOpenBlob(e,t||"download")}}m.abort=function(){var e=this;e.readyState=e.DONE;p(e,"abort")};m.readyState=m.INIT=0;m.WRITING=1;m.DONE=2;m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null;return S}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!=null){define([],function(){return saveAs})}
|
||||
var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})}
|
||||
|
|
17
blocks.js
17
blocks.js
|
@ -1982,7 +1982,7 @@ SyntaxElementMorph.prototype.exportPictureWithResult = function (aBubble) {
|
|||
// request to open pic in new window.
|
||||
ide.saveCanvasAs(
|
||||
pic,
|
||||
(ide.projetName || localize('untitled')) + ' ' + localize('script pic')
|
||||
(ide.projectName || localize('untitled')) + ' ' + localize('script pic')
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -2583,9 +2583,8 @@ BlockMorph.prototype.userMenu = function () {
|
|||
);
|
||||
ide.saveCanvasAs(
|
||||
myself.topBlock().scriptPic(),
|
||||
(ide.projetName || localize('untitled')) + ' ' +
|
||||
localize('script pic'),
|
||||
false // request new window
|
||||
(ide.projectName || localize('untitled')) + ' ' +
|
||||
localize('script pic')
|
||||
);
|
||||
},
|
||||
'open a new window\nwith a picture of this script'
|
||||
|
@ -6382,9 +6381,8 @@ ScriptsMorph.prototype.exportScriptsPicture = function () {
|
|||
if (pic) {
|
||||
ide.saveCanvasAs(
|
||||
pic,
|
||||
(ide.projetName || localize('untitled')) + ' ' +
|
||||
localize('script pic'),
|
||||
false // request new window
|
||||
(ide.projectName || localize('untitled')) + ' ' +
|
||||
localize('script pic')
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -11734,9 +11732,8 @@ CommentMorph.prototype.userMenu = function () {
|
|||
var ide = myself.parentThatIsA(IDE_Morph);
|
||||
ide.saveCanvasAs(
|
||||
myself.fullImageClassic(),
|
||||
(ide.projetName || localize('untitled')) + ' ' +
|
||||
localize('comment pic'),
|
||||
false // request new window
|
||||
(ide.projectName || localize('untitled')) + ' ' +
|
||||
localize('comment pic')
|
||||
);
|
||||
},
|
||||
'open a new window\nwith a picture of this comment'
|
||||
|
|
3
byob.js
3
byob.js
|
@ -941,8 +941,7 @@ CustomCommandBlockMorph.prototype.userMenu = function () {
|
|||
ide.saveCanvasAs(
|
||||
this.topBlock().scriptPic(),
|
||||
(ide.projectName || localize('untitled')) + ' ' +
|
||||
localize('script pic'),
|
||||
false // request opening a new window
|
||||
localize('script pic')
|
||||
);
|
||||
},
|
||||
'open a new window\nwith a picture of this script'
|
||||
|
|
86
gui.js
86
gui.js
|
@ -889,7 +889,7 @@ IDE_Morph.prototype.createControlBar = function () {
|
|||
}
|
||||
this.refreshResumeSymbol();
|
||||
};
|
||||
|
||||
|
||||
this.controlBar.refreshResumeSymbol = function () {
|
||||
var pauseSymbols;
|
||||
if (Process.prototype.enableSingleStepping &&
|
||||
|
@ -2945,8 +2945,7 @@ IDE_Morph.prototype.projectMenu = function () {
|
|||
} else {
|
||||
myself.prompt('Export Project As...', function (name) {
|
||||
// false - override the shiftClick setting to use XML
|
||||
// true - open XML in a new tab
|
||||
myself.exportProject(name, false, true);
|
||||
myself.exportProject(name, false);
|
||||
}, null, 'exportProject');
|
||||
}
|
||||
},
|
||||
|
@ -3584,7 +3583,7 @@ IDE_Morph.prototype.rawSaveProject = function (name) {
|
|||
};
|
||||
|
||||
|
||||
IDE_Morph.prototype.exportProject = function (name, plain, newWindow) {
|
||||
IDE_Morph.prototype.exportProject = function (name, plain) {
|
||||
// Export project XML, saving a file to disk
|
||||
// newWindow requests displaying the project in a new tab.
|
||||
var menu, str, dataPrefix;
|
||||
|
@ -3596,7 +3595,7 @@ IDE_Morph.prototype.exportProject = function (name, plain, newWindow) {
|
|||
menu = this.showMessage('Exporting');
|
||||
str = this.serializer.serialize(this.stage);
|
||||
this.setURL('#open:' + dataPrefix + encodeURIComponent(str));
|
||||
this.saveXMLAs(str, name, newWindow);
|
||||
this.saveXMLAs(str, name);
|
||||
menu.destroy();
|
||||
this.showMessage('Exported!', 1);
|
||||
} catch (err) {
|
||||
|
@ -3720,7 +3719,7 @@ IDE_Morph.prototype.exportScriptsPicture = function () {
|
|||
y += padding;
|
||||
y += each.height;
|
||||
});
|
||||
this.saveCanvasAs(pic, this.projectName || localize('untitled'), true);
|
||||
this.saveCanvasAs(pic, this.projectName || localize('Untitled'));
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.exportProjectSummary = function (useDropShadows) {
|
||||
|
@ -4000,8 +3999,7 @@ IDE_Morph.prototype.exportProjectSummary = function (useDropShadows) {
|
|||
this.saveFileAs(
|
||||
'<!DOCTYPE html>' + html.toString(),
|
||||
'text/html;charset=utf-8',
|
||||
pname,
|
||||
false // request opening a new window.
|
||||
pname
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -4215,15 +4213,11 @@ IDE_Morph.prototype.setURL = function (str) {
|
|||
IDE_Morph.prototype.saveFileAs = function (
|
||||
contents,
|
||||
fileType,
|
||||
fileName,
|
||||
newWindow // (optional) defaults to false.
|
||||
fileName
|
||||
) {
|
||||
/** Allow for downloading a file to a disk or open in a new tab.
|
||||
/** Allow for downloading a file to a disk.
|
||||
This relies the FileSaver.js library which exports saveAs()
|
||||
Two utility methods saveImageAs and saveXMLAs should be used first.
|
||||
1. Opening a new window uses standard URI encoding.
|
||||
2. downloading a file uses Blobs.
|
||||
- every other combo is unsupposed.
|
||||
*/
|
||||
var blobIsSupported = false,
|
||||
world = this.world(),
|
||||
|
@ -4235,13 +4229,6 @@ IDE_Morph.prototype.saveFileAs = function (
|
|||
// handle text/plain as a .txt file
|
||||
fileExt = '.' + (fileExt === 'plain' ? 'txt' : fileExt);
|
||||
|
||||
// This is a workaround for a known Chrome crash with large URLs
|
||||
function exhibitsChomeBug(contents) {
|
||||
var MAX_LENGTH = 2e6,
|
||||
isChrome = navigator.userAgent.indexOf('Chrome') !== -1;
|
||||
return isChrome && contents.length > MAX_LENGTH;
|
||||
}
|
||||
|
||||
function dataURItoBlob(text, mimeType) {
|
||||
var i,
|
||||
data = text,
|
||||
|
@ -4259,37 +4246,11 @@ IDE_Morph.prototype.saveFileAs = function (
|
|||
return new Blob([data], {type: mimeType });
|
||||
}
|
||||
|
||||
function dataURLFormat(text) {
|
||||
var hasTypeStr = text.indexOf('data:') === 0;
|
||||
if (hasTypeStr) {return text; }
|
||||
return 'data:' + fileType + ',' + encodeURIComponent(text);
|
||||
}
|
||||
|
||||
try {
|
||||
blobIsSupported = !!new Blob();
|
||||
} catch (e) {}
|
||||
|
||||
if (newWindow) {
|
||||
// Blob URIs need a custom URL to be displayed in a new window
|
||||
if (contents instanceof Blob) {
|
||||
dataURI = URL.createObjectURL(contents);
|
||||
} else {
|
||||
dataURI = dataURLFormat(contents);
|
||||
}
|
||||
|
||||
// Detect crashing errors - fallback to downloading if necessary
|
||||
if (!exhibitsChomeBug(dataURI)) {
|
||||
window.open(dataURI, fileName);
|
||||
// Blob URIs should be "cleaned up" to reduce memory.
|
||||
if (contents instanceof Blob) {
|
||||
URL.revokeObjectURL(dataURI);
|
||||
}
|
||||
} else {
|
||||
// (recursively) call this defauling newWindow to false
|
||||
this.showMessage('download to disk text');
|
||||
this.saveFileAs(contents, fileType, fileName);
|
||||
}
|
||||
} else if (blobIsSupported) {
|
||||
if (blobIsSupported) {
|
||||
if (!(contents instanceof Blob)) {
|
||||
contents = dataURItoBlob(contents, fileType);
|
||||
}
|
||||
|
@ -4308,26 +4269,26 @@ IDE_Morph.prototype.saveFileAs = function (
|
|||
}
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.saveCanvasAs = function (canvas, fileName, newWindow) {
|
||||
IDE_Morph.prototype.saveCanvasAs = function (canvas, fileName) {
|
||||
// Export a Canvas object as a PNG image
|
||||
// Note: This commented out due to poor browser support.
|
||||
// cavas.toBlob() is currently supported in Firefox, IE, Chrome but
|
||||
// cavas.toBlob() is currently supported in Firefox, IE, Chrome but
|
||||
// browsers prevent easily saving the generated files.
|
||||
// Do not re-enable without revisiting issue #1191
|
||||
// if (canvas.toBlob) {
|
||||
// var myself = this;
|
||||
// canvas.toBlob(function (blob) {
|
||||
// myself.saveFileAs(blob, 'image/png', fileName, newWindow);
|
||||
// myself.saveFileAs(blob, 'image/png', fileName);
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
this.saveFileAs(canvas.toDataURL(), 'image/png', fileName, newWindow);
|
||||
|
||||
this.saveFileAs(canvas.toDataURL(), 'image/png', fileName);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.saveXMLAs = function(xml, fileName, newWindow) {
|
||||
IDE_Morph.prototype.saveXMLAs = function(xml, fileName) {
|
||||
// wrapper to saving XML files with a proper type tag.
|
||||
this.saveFileAs(xml, 'text/xml;chartset=utf-8', fileName, newWindow);
|
||||
this.saveFileAs(xml, 'text/xml;chartset=utf-8', fileName);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.switchToUserMode = function () {
|
||||
|
@ -5728,7 +5689,7 @@ ProjectDialogMorph.prototype.buildFilterField = function () {
|
|||
this.filterField.reactToKeystroke = function (evt) {
|
||||
var text = this.getValue();
|
||||
|
||||
myself.listField.elements =
|
||||
myself.listField.elements =
|
||||
myself.projectList.filter(function (aProject) {
|
||||
var name,
|
||||
notes;
|
||||
|
@ -6356,7 +6317,7 @@ ProjectDialogMorph.prototype.fixLayout = function () {
|
|||
|
||||
// LibraryImportDialogMorph ///////////////////////////////////////////
|
||||
// I am preview dialog shown before importing a library.
|
||||
// I inherit from a DialogMorph but look similar to
|
||||
// I inherit from a DialogMorph but look similar to
|
||||
// ProjectDialogMorph, and BlockImportDialogMorph
|
||||
|
||||
LibraryImportDialogMorph.prototype = new DialogBoxMorph();
|
||||
|
@ -6591,7 +6552,7 @@ LibraryImportDialogMorph.prototype.fixLayout = function () {
|
|||
Morph.prototype.trackChanges = oldFlag;
|
||||
this.changed();
|
||||
};
|
||||
|
||||
|
||||
// Library Cache Utilities.
|
||||
LibraryImportDialogMorph.prototype.hasCached = function (key) {
|
||||
return this.libraryCache.hasOwnProperty(key);
|
||||
|
@ -6918,8 +6879,7 @@ SpriteIconMorph.prototype.userMenu = function () {
|
|||
var ide = myself.parentThatIsA(IDE_Morph);
|
||||
ide.saveCanvasAs(
|
||||
myself.object.fullImageClassic(),
|
||||
this.object.name,
|
||||
true
|
||||
this.object.name
|
||||
);
|
||||
},
|
||||
'open a new window\nwith a picture of the stage'
|
||||
|
@ -7322,7 +7282,7 @@ CostumeIconMorph.prototype.exportCostume = function () {
|
|||
// don't show SVG costumes in a new tab (shows text)
|
||||
ide.saveFileAs(this.object.contents.src, 'text/svg', this.object.name);
|
||||
} else { // rasterized Costume
|
||||
ide.saveCanvasAs(this.object.contents, this.object.name, false);
|
||||
ide.saveCanvasAs(this.object.contents, this.object.name);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8347,7 +8307,7 @@ PaletteHandleMorph.prototype.mouseEnter
|
|||
|
||||
PaletteHandleMorph.prototype.mouseLeave
|
||||
= StageHandleMorph.prototype.mouseLeave;
|
||||
|
||||
|
||||
PaletteHandleMorph.prototype.mouseDoubleClick = function () {
|
||||
this.target.parentThatIsA(IDE_Morph).setPaletteWidth(200);
|
||||
};
|
||||
|
@ -8447,7 +8407,7 @@ CamSnapshotDialogMorph.prototype.buildContents = function () {
|
|||
|
||||
this.addButton('ok', 'Save');
|
||||
this.addButton('cancel', 'Cancel');
|
||||
|
||||
|
||||
this.fixLayout();
|
||||
this.drawNew();
|
||||
};
|
||||
|
|
|
@ -7248,8 +7248,7 @@ StageMorph.prototype.userMenu = function () {
|
|||
function () {
|
||||
ide.saveCanvasAs(
|
||||
myself.fullImageClassic(),
|
||||
myself.name,
|
||||
true // open as new window
|
||||
myself.name
|
||||
);
|
||||
},
|
||||
'open a new window\nwith a picture of the stage'
|
||||
|
@ -9335,8 +9334,7 @@ WatcherMorph.prototype.userMenu = function () {
|
|||
inp.click();
|
||||
}
|
||||
);
|
||||
if (this.currentValue &&
|
||||
(isString(this.currentValue) || !isNaN(+this.currentValue))) {
|
||||
if (isString(this.currentValue) || !isNaN(+this.currentValue)) {
|
||||
menu.addItem(
|
||||
'export...',
|
||||
function () {
|
||||
|
@ -9344,8 +9342,7 @@ WatcherMorph.prototype.userMenu = function () {
|
|||
ide.saveFileAs(
|
||||
myself.currentValue.toString(),
|
||||
'text/plain;charset=utf-8',
|
||||
myself.getter, // variable name
|
||||
false
|
||||
myself.getter // variable name
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue