diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..f33004ee1 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +js/espruinotools.js diff --git a/js/.eslintignore b/js/.eslintignore deleted file mode 100644 index cd6466f7f..000000000 --- a/js/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -espruinotools.js diff --git a/js/.eslintrc.json b/js/.eslintrc.json index 92ffbaa09..cb816d7b5 100644 --- a/js/.eslintrc.json +++ b/js/.eslintrc.json @@ -10,10 +10,40 @@ { "SwitchCase": 1 } - ] + ], + "no-undef": "warn", + "no-redeclare": "warn", + "no-var": "warn", + "no-unused-vars":"off" // we define stuff to use in other scripts }, "env": { "browser": true, "node": true - } + }, + "extends": "eslint:recommended", + "globals": { + "btoa": "writable", + "Espruino": "writable", + + "htmlElement": "readonly", + "Puck": "readonly", + "escapeHtml": "readonly", + "htmlToArray": "readonly", + "heatshrink": "readonly", + "Puck": "readonly", + "Promise": "readonly", + "Comms": "readonly", + "Progress": "readonly", + "showToast": "readonly", + "showPrompt": "readonly", + "httpGet": "readonly", + "getVersionInfo": "readonly", + "AppInfo": "readonly", + "marked": "readonly", + "appSorter": "readonly", + "Uint8Array" : "readonly", + "SETTINGS" : "readonly", + "globToRegex" : "readonly", + "toJS" : "readonly" + } } diff --git a/js/appinfo.js b/js/appinfo.js index 6e65bda18..052597ca9 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -7,16 +7,16 @@ if (typeof btoa==="undefined") { // Converts a string into most efficient way to send to Espruino (either json, base64, or compressed base64) function toJS(txt) { - var json = JSON.stringify(txt); - var b64 = "atob("+JSON.stringify(btoa(json))+")"; - var js = b64.length < json.length ? b64 : json; + let json = JSON.stringify(txt); + let b64 = "atob("+JSON.stringify(btoa(json))+")"; + let js = b64.length < json.length ? b64 : json; if (typeof heatshrink !== "undefined") { - var ua = new Uint8Array(txt.length); - for (var i=0;i { return new Promise((resolve,reject) => { - var appJSONName = app.id+".info"; + let appJSONName = app.id+".info"; // Check we don't already have a JSON file! - var appJSONFile = fileContents.find(f=>f.name==appJSONName); + let appJSONFile = fileContents.find(f=>f.name==appJSONName); if (appJSONFile) reject("App JSON file explicitly specified!"); // Now actually create the app JSON - var json = { + let json = { id : app.id }; if (app.shortName) json.name = app.shortName; @@ -108,7 +108,7 @@ var AppInfo = { json.icon = app.id+".img"; if (app.sortorder) json.sortorder = app.sortorder; if (app.version) json.version = app.version; - var fileList = fileContents.map(storageFile=>storageFile.name); + let fileList = fileContents.map(storageFile=>storageFile.name); fileList.unshift(appJSONName); // do we want this? makes life easier! json.files = fileList.join(","); if ('data' in app) { diff --git a/js/comms.js b/js/comms.js index 4f8a64d62..602be8227 100644 --- a/js/comms.js +++ b/js/comms.js @@ -1,7 +1,7 @@ Puck.debug=3; // FIXME: use UART lib so that we handle errors properly -var Comms = { +let Comms = { reset : (opt) => new Promise((resolve,reject) => { Puck.write(`\x03\x10reset(${opt=="wipe"?"1":""});\n`, (result) => { if (result===null) return reject("Connection failed"); @@ -16,13 +16,13 @@ var Comms = { }).then(fileContents => { return new Promise((resolve,reject) => { console.log("uploadApp",fileContents.map(f=>f.name).join(", ")); - var maxBytes = fileContents.reduce((b,f)=>b+f.cmd.length, 0)||1; - var currentBytes = 0; + let maxBytes = fileContents.reduce((b,f)=>b+f.cmd.length, 0)||1; + let currentBytes = 0; - var appInfoFileName = app.id+".info"; - var appInfoFile = fileContents.find(f=>f.name==appInfoFileName); + let appInfoFileName = app.id+".info"; + let appInfoFile = fileContents.find(f=>f.name==appInfoFileName); if (!appInfoFile) reject(`${appInfoFileName} not found`); - var appInfo = JSON.parse(appInfoFile.content); + let appInfo = JSON.parse(appInfoFile.content); // Upload each file one at a time function doUploadFiles() { @@ -35,14 +35,14 @@ var Comms = { }); return; } - var f = fileContents.shift(); + let f = fileContents.shift(); console.log(`Upload ${f.name} => ${JSON.stringify(f.content)}`); // Chould check CRC here if needed instead of returning 'OK'... // E.CRC32(require("Storage").read(${JSON.stringify(app.name)})) - var cmds = f.cmd.split("\n"); + let cmds = f.cmd.split("\n"); function uploadCmd() { if (!cmds.length) return doUploadFiles(); - var cmd = cmds.shift(); + let cmd = cmds.shift(); Progress.show({ min:currentBytes / maxBytes, max:(currentBytes+cmd.length) / maxBytes}); @@ -84,7 +84,7 @@ var Comms = { Progress.hide({sticky:true}); return reject(""); } - Puck.write('\x10Bluetooth.print("[");require("Storage").list(/\.info$/).forEach(f=>{var j=require("Storage").readJSON(f,1)||{};j.id=f.slice(0,-5);Bluetooth.print(JSON.stringify(j)+",")});Bluetooth.println("0]")\n', (appList,err) => { + Puck.write('\x10Bluetooth.print("[");require("Storage").list(/\\.info$/).forEach(f=>{var j=require("Storage").readJSON(f,1)||{};j.id=f.slice(0,-5);Bluetooth.print(JSON.stringify(j)+",")});Bluetooth.println("0]")\n', (appList,err) => { Progress.hide({sticky:true}); try { appList = JSON.parse(appList); @@ -152,9 +152,9 @@ var Comms = { }, setTime : () => { return new Promise((resolve,reject) => { - var d = new Date(); - var tz = d.getTimezoneOffset()/-60 - var cmd = '\x03\x10setTime('+(d.getTime()/1000)+');'; + let d = new Date(); + let tz = d.getTimezoneOffset()/-60 + let cmd = '\x03\x10setTime('+(d.getTime()/1000)+');'; // in 1v93 we have timezones too cmd += 'E.setTimeZone('+tz+');'; cmd += "(s=>{s&&(s.timezone="+tz+")&&require('Storage').write('setting.json',s);})(require('Storage').readJSON('setting.json',1))\n"; @@ -165,17 +165,17 @@ var Comms = { }); }, disconnectDevice: () => { - var connection = Puck.getConnection(); + let connection = Puck.getConnection(); if (!connection) return; connection.close(); }, watchConnectionChange : cb => { - var connected = Puck.isConnected(); + let connected = Puck.isConnected(); //TODO Switch to an event listener when Puck will support it - var interval = setInterval(() => { + let interval = setInterval(() => { if (connected === Puck.isConnected()) return; connected = Puck.isConnected(); @@ -220,20 +220,20 @@ var Comms = { readStorageFile : (filename) => { // StorageFiles are different to normal storage entries return new Promise((resolve,reject) => { // Use "\xFF" to signal end of file (can't occur in files anyway) - var fileContent = ""; - var fileSize = undefined; - var connection = Puck.getConnection(); + let fileContent = ""; + let fileSize = undefined; + let connection = Puck.getConnection(); connection.received = ""; connection.cb = function(d) { - var finished = false; - var eofIndex = d.indexOf("\xFF"); + let finished = false; + let eofIndex = d.indexOf("\xFF"); if (eofIndex>=0) { finished = true; d = d.substr(0,eofIndex); } fileContent += d; if (fileSize === undefined) { - var newLineIdx = fileContent.indexOf("\n"); + let newLineIdx = fileContent.indexOf("\n"); if (newLineIdx>=0) { fileSize = parseInt(fileContent.substr(0,newLineIdx)); console.log("File size is "+fileSize); diff --git a/js/index.js b/js/index.js index fd06e7cd0..34975f3a1 100644 --- a/js/index.js +++ b/js/index.js @@ -1,12 +1,12 @@ -var appJSON = []; // List of apps and info from apps.json -var appsInstalled = []; // list of app JSON -var appSortInfo = {}; // list of data to sort by, from appdates.csv { created, modified } -var files = []; // list of files on Bangle -var DEFAULTSETTINGS = { +let appJSON = []; // List of apps and info from apps.json +let appsInstalled = []; // list of app JSON +let appSortInfo = {}; // list of data to sort by, from appdates.csv { created, modified } +let files = []; // list of files on Bangle +let DEFAULTSETTINGS = { pretokenise : true, favourites : ["boot","launch","setting"] }; -var SETTINGS = JSON.parse(JSON.stringify(DEFAULTSETTINGS)); // clone +let SETTINGS = JSON.parse(JSON.stringify(DEFAULTSETTINGS)); // clone httpGet("apps.json").then(apps=>{ try { @@ -23,7 +23,7 @@ httpGet("apps.json").then(apps=>{ httpGet("appdates.csv").then(csv=>{ document.querySelector(".sort-nav").classList.remove("hidden"); csv.split("\n").forEach(line=>{ - var l = line.split(","); + let l = line.split(","); appSortInfo[l[0]] = { created : Date.parse(l[1]), modified : Date.parse(l[2]) @@ -35,7 +35,7 @@ httpGet("appdates.csv").then(csv=>{ // =========================================== Top Navigation function showChangeLog(appid) { - var app = appNameToApp(appid); + let app = appNameToApp(appid); function show(contents) { showPrompt(app.name+" Change Log",contents,{ok:true}).catch(()=>{}); } @@ -43,9 +43,9 @@ function showChangeLog(appid) { then(show).catch(()=>show("No Change Log available")); } function showReadme(appid) { - var app = appNameToApp(appid); - var appPath = `apps/${appid}/`; - var markedOptions = { baseUrl : appPath }; + let app = appNameToApp(appid); + let appPath = `apps/${appid}/`; + let markedOptions = { baseUrl : appPath }; function show(contents) { if (!contents) return; showPrompt(app.name + " Documentation", marked(contents, markedOptions), {ok: true}, false).catch(() => {}); @@ -56,7 +56,7 @@ function handleCustomApp(appTemplate) { // Pops up an IFRAME that allows an app to be customised if (!appTemplate.custom) throw new Error("App doesn't have custom HTML"); return new Promise((resolve,reject) => { - var modal = htmlElement(`