kopia lustrzana https://github.com/backface/turtlestitch
363 wiersze
12 KiB
JavaScript
363 wiersze
12 KiB
JavaScript
IDE_Morph.prototype.openIn = function (world) {
|
|
var hash, usr, myself = this, urlLanguage = null;
|
|
|
|
// get persistent user data, if any
|
|
if (localStorage) {
|
|
usr = localStorage['-snap-user'];
|
|
if (usr) {
|
|
usr = SnapCloud.parseResponse(usr)[0];
|
|
if (usr) {
|
|
SnapCloud.username = usr.username || null;
|
|
SnapCloud.password = usr.password || null;
|
|
if (SnapCloud.username) {
|
|
this.source = 'cloud';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SnapCloud.isloggedin(function ()
|
|
{
|
|
str = SnapCloud.encodeDict(
|
|
{
|
|
username: SnapCloud.username
|
|
}
|
|
);
|
|
localStorage['-snap-user'] = str;
|
|
myself.source = 'cloud';
|
|
myself.showMessage('now connected.', 2);
|
|
}, myself.cloudError()
|
|
);
|
|
|
|
this.buildPanes();
|
|
world.add(this);
|
|
world.userMenu = this.userMenu;
|
|
|
|
// override SnapCloud's user message with Morphic
|
|
SnapCloud.message = function (string) {
|
|
var m = new MenuMorph(null, string),
|
|
intervalHandle;
|
|
m.popUpCenteredInWorld(world);
|
|
intervalHandle = setInterval(function () {
|
|
m.destroy();
|
|
clearInterval(intervalHandle);
|
|
}, 2000);
|
|
};
|
|
|
|
// prevent non-DialogBoxMorphs from being dropped
|
|
// onto the World in user-mode
|
|
world.reactToDropOf = function (morph) {
|
|
if (!(morph instanceof DialogBoxMorph)) {
|
|
if (world.hand.grabOrigin) {
|
|
morph.slideBackTo(world.hand.grabOrigin);
|
|
} else {
|
|
world.hand.grab(morph);
|
|
}
|
|
}
|
|
};
|
|
|
|
this.reactToWorldResize(world.bounds);
|
|
|
|
function getURL(url) {
|
|
try {
|
|
var request = new XMLHttpRequest();
|
|
request.open('GET', url, false);
|
|
request.send();
|
|
if (request.status === 200) {
|
|
return request.responseText;
|
|
}
|
|
throw new Error('unable to retrieve ' + url);
|
|
} catch (err) {
|
|
myself.showMessage('unable to retrieve project');
|
|
return '';
|
|
}
|
|
}
|
|
|
|
// dynamic notifications from non-source text files
|
|
// has some issues, commented out for now
|
|
/*
|
|
this.cloudMsg = getURL('http://snap.berkeley.edu/cloudmsg.txt');
|
|
motd = getURL('http://snap.berkeley.edu/motd.txt');
|
|
if (motd) {
|
|
this.inform('Snap!', motd);
|
|
}
|
|
*/
|
|
function interpretUrlAnchors() {
|
|
var dict;
|
|
if (location.hash.substr(0, 6) === '#open:') {
|
|
hash = location.hash.substr(6);
|
|
if (hash.charAt(0) === '%'
|
|
|| hash.search(/\%(?:[0-9a-f]{2})/i) > -1) {
|
|
hash = decodeURIComponent(hash);
|
|
}
|
|
if (contains(
|
|
['project', 'blocks', 'sprites', 'snapdata'].map(
|
|
function (each) {
|
|
return hash.substr(0, 8).indexOf(each);
|
|
}
|
|
),
|
|
1
|
|
)) {
|
|
this.droppedText(hash);
|
|
} else {
|
|
this.droppedText(getURL(hash));
|
|
}
|
|
} else if (location.hash.substr(0, 5) === '#run:') {
|
|
hash = location.hash.substr(5);
|
|
if (hash.charAt(0) === '%'
|
|
|| hash.search(/\%(?:[0-9a-f]{2})/i) > -1) {
|
|
hash = decodeURIComponent(hash);
|
|
}
|
|
if (hash.substr(0, 8) === '<project>') {
|
|
this.rawOpenProjectString(hash);
|
|
} else {
|
|
this.rawOpenProjectString(getURL(hash));
|
|
}
|
|
this.toggleAppMode(true);
|
|
this.runScripts();
|
|
} else if (location.hash.substr(0, 9) === '#present:') {
|
|
this.shield = new Morph();
|
|
this.shield.color = this.color;
|
|
this.shield.setExtent(this.parent.extent());
|
|
this.parent.add(this.shield);
|
|
myself.showMessage('Fetching project\nfrom the cloud...');
|
|
|
|
// make sure to lowercase the username
|
|
dict = SnapCloud.parseDict(location.hash.substr(9));
|
|
dict.Username = dict.Username.toLowerCase();
|
|
|
|
SnapCloud.getPublicProject(
|
|
SnapCloud.encodeDict(dict),
|
|
function (projectData) {
|
|
var msg;
|
|
myself.nextSteps([
|
|
function () {
|
|
msg = myself.showMessage('Opening project...');
|
|
},
|
|
function () {nop(); }, // yield (bug in Chrome)
|
|
function () {
|
|
if (projectData.indexOf('<snapdata') === 0) {
|
|
myself.rawOpenCloudDataString(projectData);
|
|
} else if (
|
|
projectData.indexOf('<project') === 0
|
|
) {
|
|
myself.rawOpenProjectString(projectData);
|
|
}
|
|
myself.hasChangedMedia = true;
|
|
},
|
|
function () {
|
|
myself.shield.destroy();
|
|
myself.shield = null;
|
|
msg.destroy();
|
|
|
|
if (dict.editMode) {
|
|
myself.toggleAppMode(false);
|
|
} else {
|
|
myself.toggleAppMode(true);
|
|
}
|
|
|
|
if (!dict.noRun) {
|
|
myself.runScripts();
|
|
}
|
|
|
|
if (dict.hideControls) {
|
|
myself.controlBar.hide();
|
|
window.onbeforeunload = function () {nop(); };
|
|
}
|
|
}
|
|
]);
|
|
},
|
|
this.cloudError()
|
|
);
|
|
} else if (location.hash.substr(0, 7) === '#cloud:') {
|
|
this.shield = new Morph();
|
|
this.shield.alpha = 0;
|
|
this.shield.setExtent(this.parent.extent());
|
|
this.parent.add(this.shield);
|
|
myself.showMessage('Fetching project\nfrom the cloud...');
|
|
|
|
// make sure to lowercase the username
|
|
dict = SnapCloud.parseDict(location.hash.substr(7));
|
|
dict.Username = dict.Username.toLowerCase();
|
|
|
|
SnapCloud.getPublicProject(
|
|
SnapCloud.encodeDict(dict),
|
|
function (projectData) {
|
|
var msg;
|
|
myself.nextSteps([
|
|
function () {
|
|
msg = myself.showMessage('Opening project...');
|
|
},
|
|
function () {nop(); }, // yield (bug in Chrome)
|
|
function () {
|
|
if (projectData.indexOf('<snapdata') === 0) {
|
|
myself.rawOpenCloudDataString(projectData);
|
|
} else if (
|
|
projectData.indexOf('<project') === 0
|
|
) {
|
|
myself.rawOpenProjectString(projectData);
|
|
}
|
|
myself.hasChangedMedia = true;
|
|
},
|
|
function () {
|
|
myself.shield.destroy();
|
|
myself.shield = null;
|
|
msg.destroy();
|
|
myself.toggleAppMode(false);
|
|
}
|
|
]);
|
|
},
|
|
this.cloudError()
|
|
);
|
|
} else if (location.hash.substr(0, 6) === '#lang:') {
|
|
urlLanguage = location.hash.substr(6);
|
|
this.setLanguage(urlLanguage);
|
|
this.loadNewProject = true;
|
|
} else if (location.hash.substr(0, 7) === '#signup') {
|
|
this.createCloudAccount();
|
|
}
|
|
}
|
|
|
|
if (this.userLanguage) {
|
|
this.loadNewProject = true;
|
|
this.setLanguage(this.userLanguage, interpretUrlAnchors);
|
|
} else {
|
|
interpretUrlAnchors.call(this);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
// IDE_Morph cloud interface
|
|
|
|
IDE_Morph.prototype.initializeCloud = function () {
|
|
//SnapCloud.reconnect();
|
|
console.log("init cloud");
|
|
var myself = this,
|
|
world = this.world();
|
|
new DialogBoxMorph(
|
|
null,
|
|
function (user) {
|
|
var pwh = hex_sha512(user.password),
|
|
str;
|
|
SnapCloud.login(
|
|
user.username,
|
|
user.password, //pwh,
|
|
function () {
|
|
str = SnapCloud.encodeDict(
|
|
{
|
|
username: user.username,
|
|
}
|
|
);
|
|
localStorage['-snap-user'] = str;
|
|
console.log(user.username)
|
|
SnapCloud.username = user.username;
|
|
myself.source = 'cloud';
|
|
myself.showMessage('now connected.', 2);
|
|
},
|
|
myself.cloudError()
|
|
);
|
|
}
|
|
).withKey('cloudlogin').promptCredentials(
|
|
'Sign in',
|
|
'login',
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null, //'stay signed in on this computer\nuntil logging out',
|
|
world,
|
|
myself.cloudIcon(),
|
|
myself.cloudMsg
|
|
);
|
|
};
|
|
|
|
IDE_Morph.prototype.createCloudAccount = function () {
|
|
window.open('http://' + window.location.hostname + '/signup');
|
|
};
|
|
|
|
IDE_Morph.prototype.resetCloudPassword = function () {
|
|
var myself = this,
|
|
world = this.world();
|
|
/*
|
|
// force-logout, commented out for now:
|
|
delete localStorage['-snap-user'];
|
|
SnapCloud.clear();
|
|
*/
|
|
new DialogBoxMorph(
|
|
null,
|
|
function (user) {
|
|
SnapCloud.resetPassword(
|
|
user.username,
|
|
function (txt, title) {
|
|
new DialogBoxMorph().inform(
|
|
title,
|
|
txt +
|
|
'.\n\nAn e-mail with a link to\n' +
|
|
'reset your password\n' +
|
|
'has been sent to the address provided',
|
|
world,
|
|
myself.cloudIcon(null, new Color(0, 180, 0))
|
|
);
|
|
},
|
|
myself.cloudError()
|
|
);
|
|
}
|
|
).withKey('cloudresetpassword').promptCredentials(
|
|
'Reset password',
|
|
'resetPassword',
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
world,
|
|
myself.cloudIcon(),
|
|
myself.cloudMsg
|
|
);
|
|
};
|
|
|
|
IDE_Morph.prototype.changeCloudPassword = function () {
|
|
window.open('http://' + window.location.hostname + '/change_password');
|
|
};
|
|
|
|
ProjectDialogMorph.prototype.init = function (ide, task) {
|
|
var myself = this;
|
|
|
|
// additional properties:
|
|
this.ide = ide;
|
|
this.task = task || 'open'; // String describing what do do (open, save)
|
|
this.source = 'local'; // ide.source || 'local'; // or 'cloud' or 'examples'
|
|
this.projectList = []; // [{name: , thumb: , notes:}]
|
|
|
|
this.handle = null;
|
|
this.srcBar = null;
|
|
this.nameField = null;
|
|
this.listField = null;
|
|
this.preview = null;
|
|
this.notesText = null;
|
|
this.notesField = null;
|
|
this.deleteButton = null;
|
|
this.shareButton = null;
|
|
this.unshareButton = null;
|
|
|
|
// initialize inherited properties:
|
|
ProjectDialogMorph.uber.init.call(
|
|
this,
|
|
this, // target
|
|
null, // function
|
|
null // environment
|
|
);
|
|
|
|
// override inherited properites:
|
|
this.labelString = this.task === 'save' ? 'Save Project' : 'Open Project';
|
|
this.createLabel();
|
|
this.key = 'project' + task;
|
|
|
|
// build contents
|
|
this.buildContents();
|
|
this.onNextStep = function () { // yield to show "updating" message
|
|
myself.setSource(myself.source);
|
|
};
|
|
};
|