summaryrefslogtreecommitdiff
path: root/threads.js
diff options
context:
space:
mode:
Diffstat (limited to 'threads.js')
-rw-r--r--threads.js413
1 files changed, 411 insertions, 2 deletions
diff --git a/threads.js b/threads.js
index eda8fc7..8fbd587 100644
--- a/threads.js
+++ b/threads.js
@@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
-modules.threads = '2014-July-30';
+modules.threads = '2014-August-13';
var ThreadManager;
var Process;
@@ -774,7 +774,7 @@ Process.prototype.evaluate = function (
if (!context) {return null; }
if (context instanceof Function) {
return context.apply(
- this.homeContext.receiver,
+ this.blockReceiver(),
args.asArray().concat([this])
);
}
@@ -2189,6 +2189,20 @@ Process.prototype.reportTextSplit = function (string, delimiter) {
return new List(str.split(del));
};
+// Process notification operations
+
+Process.prototype.doNotify = function (title, content) {
+ // TODO webkitNotification
+ if (window.plugin) {
+ if (window.plugin.notification) {
+ window.plugin.notification.local.add({
+ message: content,
+ title: title
+ });
+ }
+ }
+};
+
// Process debugging
Process.prototype.alert = function (data) {
@@ -2601,6 +2615,78 @@ Process.prototype.reportTimer = function () {
return 0;
};
+Process.prototype.reportLanguage = function () {
+ var ide = this.homeContext.receiver.parentThatIsA(IDE_Morph);
+ if (ide) {
+ var lang = ide.userLanguage;
+ if (lang) {
+ return lang;
+ }
+ }
+ return 'en';
+};
+
+Process.prototype.reportLocation = function (name) {
+ var myself = this;
+
+ if (!myself.context.jsonpScript) {
+ if (!navigator.geolocation) {
+ myself.handleError({name: 'Location',
+ message: 'navigator.geolocation is not supported'});
+ }
+ window.OSM_JSONP_Callback = function (data) {
+ myself.context.json = data;
+ window.OSM_JSONP_Callback = undefined;
+ };
+ myself.context.jsonpScript = document.createElement('script');
+
+ navigator.geolocation.getCurrentPosition(
+ function (pos) {
+ var crd = pos.coords;
+
+ myself.context.jsonpScript.src =
+ 'https://nominatim.openstreetmap.org/reverse'
+ + '?format=json&json_callback=OSM_JSONP_Callback'
+ + '&zoom=18&addressdetails=1'
+ + '&lat='
+ + crd.latitude
+ + '&lon='
+ + crd.longitude;
+ document.getElementsByTagName('HEAD')[0]
+ .appendChild(myself.context.jsonpScript);
+ },
+ function (err) {
+ console.log(err);
+ myself.handleError({name: 'Location', message: err});
+ },
+ { enableHightAccuracy: true, timeout: 30000, maximumAge: 0}
+ );
+ } else {
+ if (myself.context.json) {
+ switch (myself.inputOption(name)) {
+ case 'all':
+ return myself.context.json.display_name;
+ case 'state district':
+ return myself.context.json.address.state_district;
+ case 'house number':
+ return myself.context.json.address.house_number;
+ case 'licence':
+ return myself.context.json.licence;
+ case 'country':
+ case 'state':
+ case 'suburb':
+ case 'city':
+ case 'road':
+ return myself.context.
+ json.address[myself.inputOption(name)];
+ }
+ }
+ }
+
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
// Process Dates and times in Snap
// Map block options to built-in functions
var dateMap = {
@@ -2630,6 +2716,329 @@ Process.prototype.reportDate = function (datefn) {
return result;
};
+// Process File access
+// http://www.html5rocks.com/en/tutorials/file/filesystem/
+Process.prototype.fileErrorHandler = function (e) {
+ var msg = '';
+
+ switch (e.code) {
+ case FileError.QUOTA_EXCEEDED_ERR:
+ msg = localize('no space left');
+ break;
+ case FileError.NOT_FOUND_ERR:
+ msg = localize('not found');
+ break;
+ case FileError.SECURITY_ERR:
+ msg = localize('access denied');
+ break;
+ case FileError.INVALID_MODIFICATION_ERR:
+ msg = 'INVALID_MODIFICATION_ERR';
+ break;
+ case FileError.INVALID_STATE_ERR:
+ msg = 'INVALID_STATE_ERR';
+ break;
+ default:
+ msg = localize('unknown error');
+ break;
+ }
+
+ this.handleError(msg);
+};
+
+Process.prototype.reportFileOrDirectoryContent = function (typeInput, filepath) {
+ var myself = this;
+ var type = myself.inputOption(typeInput);
+
+ if (myself.context.result === null) {
+ myself.context.result = false;
+
+ if (window.resolveLocalFileSystemURL) {
+ window.resolveLocalFileSystemURL(filepath,
+ function (entry) {
+ if (type === 'file') {
+ entry.file(
+ function (file) {
+ var reader = new FileReader();
+
+ reader.onloadend = function (e) {
+ myself.context.result = this.result;
+ };
+
+ reader.readAsText(file);
+ },
+ myself.fileErrorHandler
+ );
+ } else {
+ var dirReader = entry.createReader();
+ dirReader.readEntries(
+ function (results) {
+ var items = [];
+ results.forEach(
+ function (item) {
+ items.push(item.name);
+ }
+ );
+ myself.context.result = new List(items);
+ },
+ myself.fileErrorHandler
+ );
+ }
+ },
+ myself.fileErrorHandler
+ );
+ }
+ } else {
+ if (myself.context.result !== false) {
+ return myself.context.result;
+ }
+ }
+
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.doSetFileContent = function (content, filepath) {
+ var dirpath = filepath.substring(0,
+ filepath.lastIndexOf('/'));
+ var filename = filepath.substring(
+ filepath.lastIndexOf('/') + 1);
+
+ if (window.resolveLocalFileSystemURL) {
+ window.resolveLocalFileSystemURL(dirpath,
+ function (dirEntry) {
+ dirEntry.getFile(filename,
+ {create: true, exclusive: false},
+ function (fileEntry) {
+ fileEntry.createWriter(
+ function (fileWriter) {
+ var blob;
+
+ try {
+ blob = new Blob([content],
+ {type: 'text/plain'});
+ // No `new Blob` for Android
+ } catch (e) {
+ window.BlobBuilder =
+ window.BlobBuilder ||
+ window.WebKitBlobBuilder ||
+ window.MozBlobBuilder ||
+ window.MSBlobBuilder;
+
+ if (e.name == 'TypeError'
+ && window.BlobBuilder) {
+ var bb = new BlobBuilder();
+ bb.append(content);
+ blob = bb.getBlob('text/plain');
+ }
+ }
+
+ fileWriter.write(blob);
+ },
+ myself.fileErrorHandler
+ );
+ },
+ myself.fileErrorHandler
+ );
+ },
+ myself.fileErrorHandler
+ );
+ }
+};
+
+Process.prototype.createFileOrDirectory = function (typeInput, filepath) {
+ var myself = this;
+ var type = myself.inputOption(typeInput);
+
+ function createDir(rootDirEntry, folders) {
+ rootDirEntry.getDirectory(folders[0], {create: true},
+ function (dirEntry) {
+ if (folders.length === 1) {
+ if (type === 'file') {
+ dirEntry.getFile(folders.slice(1),
+ {create: true, exclusive: false},
+ function (fileEntry) {
+ return;
+ },
+ myself.fileErrorHandler
+ );
+
+ return;
+ }
+ }
+
+ if (folders.length) {
+ createDir(dirEntry, folders.slice(1));
+ }
+ },
+ myself.fileErrorHandler
+ );
+ }
+
+ window.requestFileSystem(window.PERSISTENT, 0,
+ function (fileSystem) {
+ createDir(fileSystem.root, path.split('/'));
+ },
+ myself.fileErrorHandler
+ );
+};
+
+Process.prototype.reportFileOrDirectoryExists = function (typeInput, filepath) {
+ var myself = this;
+ var type = myself.inputOption(typeInput);
+
+ if (myself.context.result === null) {
+ myself.context.result = 'wait';
+
+ if (window.resolveLocalFileSystemURL) {
+ window.resolveLocalFileSystemURL(filepath,
+ function (entry) {
+ if (type === 'file') {
+ myself.context.result = !entry.isDirectory;
+ } else {
+ myself.context.result = entry.isDirectory;
+ }
+ },
+ myself.fileErrorHandler
+ );
+ }
+ } else {
+ if (myself.context.result !== 'wait') {
+ return myself.context.result;
+ }
+ }
+
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.doDeleteFileOrDirectory = function (typeInput, filepath) {
+ if (window.resolveLocalFileSystemURL) {
+ window.resolveLocalFileSystemURL(filepath,
+ function (entry) {
+ entry.remove();
+ },
+ myself.fileErrorHandler
+ );
+ }
+};
+
+Process.prototype.reportHomeDirectory = function () {
+ if (cordova) {
+ if (cordova.file) {
+ return cordova.file.dataDirectory;
+ }
+ }
+ return '';
+};
+
+Process.prototype.getCompassHeading = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ stage.compassHeading = null;
+ if (navigator.compass) {
+ navigator.compass.getCurrentHeading(
+ function (result) {
+ stage.compassHeading = result;
+ },
+ function () {
+ stage.compassHeading =
+ {'magneticHeading': 0, 'trueHeading': 0,
+ 'headingAccuracy': 0, 'timestamp': 0};
+ }
+ );
+ } else {
+ stage.compassHeading =
+ {'magneticHeading': 0, 'trueHeading': 0,
+ 'headingAccuracy': 0, 'timestamp': 0};
+ }
+};
+
+Process.prototype.reportCompassHeading = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.compassHeading !== null) {
+ return stage.compassHeading.magneticHeading;
+ }
+ } else {
+ this.context.wait = true;
+ this.getCompassHeading();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.getAcceleration = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ stage.acceleration = null;
+ if (navigator.accelerometer) {
+ navigator.accelerometer.getCurrentAcceleration(
+ function (result) {
+ stage.acceleration = result;
+ },
+ function () {
+ stage.acceleration =
+ {'timestamp': 0, 'z': 0, 'y': 0, 'x': 0};
+ }
+ );
+ } else {
+ stage.acceleration =
+ {'timestamp': 0, 'z': 0, 'y': 0, 'x': 0};
+ }
+};
+
+Process.prototype.reportAccelerationX = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.acceleration !== null) {
+ return stage.acceleration.x;
+ }
+ } else {
+ this.context.wait = true;
+ this.getAcceleration();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.reportAccelerationY = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.acceleration !== null) {
+ return stage.acceleration.y;
+ }
+ } else {
+ this.context.wait = true;
+ this.getAcceleration();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.reportAccelerationZ = function () {
+ var stage = this.homeContext.receiver.parentThatIsA(StageMorph);
+
+ if (this.context.wait) {
+ if (stage.acceleration !== null) {
+ return stage.acceleration.z;
+ }
+ } else {
+ this.context.wait = true;
+ this.getAcceleration();
+ }
+ this.pushContext('doYield');
+ this.pushContext();
+};
+
+Process.prototype.doVibrate = function (seconds) {
+ if ("vibrate" in navigator) {
+ window.navigator.vibrate(seconds * 1000);
+ }
+};
+
// Process code mapping
/*