From c94cb0963da062864e9c8e46f7e41d05c8013091 Mon Sep 17 00:00:00 2001 From: Xuan Sang LE Date: Sun, 17 May 2020 23:58:21 +0200 Subject: [PATCH] add extension maker --- src/core/tags/TreeViewTag.coffee | 9 +- src/core/tags/tag.coffee | 14 +- src/core/vfs.coffee | 3 +- src/packages/CodePad/Makefile | 2 +- .../CodePad/coffees/BaseExtension.coffee | 125 ++++++++++ .../CodePad/coffees/extensions/AntOSDK.coffee | 125 +--------- .../coffees/extensions/ExtensionMaker.coffee | 217 ++++++++++++++++++ .../extensions/{AntOSDK => }/coffeescript.js | 0 .../extensions/templates/ext-extension.tpl | 17 ++ .../coffees/extensions/templates/ext-main.tpl | 10 + .../README.tpl => templates/sdk-README.tpl} | 0 .../main.tpl => templates/sdk-main.tpl} | 0 .../package.tpl => templates/sdk-package.tpl} | 0 .../project.tpl => templates/sdk-project.tpl} | 0 .../scheme.tpl => templates/sdk-scheme.tpl} | 0 src/packages/CodePad/coffees/main.coffee | 117 ++++++++-- src/packages/CodePad/extensions.json | 23 ++ 17 files changed, 512 insertions(+), 150 deletions(-) create mode 100644 src/packages/CodePad/coffees/BaseExtension.coffee create mode 100644 src/packages/CodePad/coffees/extensions/ExtensionMaker.coffee rename src/packages/CodePad/coffees/extensions/{AntOSDK => }/coffeescript.js (100%) create mode 100644 src/packages/CodePad/coffees/extensions/templates/ext-extension.tpl create mode 100644 src/packages/CodePad/coffees/extensions/templates/ext-main.tpl rename src/packages/CodePad/coffees/extensions/{AntOSDK/templates/README.tpl => templates/sdk-README.tpl} (100%) rename src/packages/CodePad/coffees/extensions/{AntOSDK/templates/main.tpl => templates/sdk-main.tpl} (100%) rename src/packages/CodePad/coffees/extensions/{AntOSDK/templates/package.tpl => templates/sdk-package.tpl} (100%) rename src/packages/CodePad/coffees/extensions/{AntOSDK/templates/project.tpl => templates/sdk-project.tpl} (100%) rename src/packages/CodePad/coffees/extensions/{AntOSDK/templates/scheme.tpl => templates/sdk-scheme.tpl} (100%) diff --git a/src/core/tags/TreeViewTag.coffee b/src/core/tags/TreeViewTag.coffee index b868cb8..30a6e36 100644 --- a/src/core/tags/TreeViewTag.coffee +++ b/src/core/tags/TreeViewTag.coffee @@ -12,10 +12,16 @@ class TreeViewItemPrototype extends Ant.OS.GUI.BaseTag @setopt "selected", false @setopt "treepath", @aid() + update: (p) -> + return unless p + return unless p is @get("treepath") + @set "open", true + __data__: (v) -> return unless v @set "nodes", v.nodes if v.nodes @set "open", v.open + @set "treepath", v.path if v.path __selected__: (v) -> $(@refs.wrapper).removeClass() @@ -152,7 +158,7 @@ class TreeViewTag extends Ant.OS.GUI.BaseTag @setopt "fetch", undefined @setopt "treepath", @aid() @indexcounter = 0 - + __selectedItem: (v) -> return unless v @get("selectedItem").set "selected", false if @get("selectedItem") @@ -176,6 +182,7 @@ class TreeViewTag extends Ant.OS.GUI.BaseTag __data__: (v) -> return unless v $(@root).empty() + @set "treepath", v.path if v.path el = $("<#{@get "itemtag"}>").appendTo @root el[0].uify undefined el[0].set "treeroot", if @is_root() then @ else @get "treeroot" diff --git a/src/core/tags/tag.coffee b/src/core/tags/tag.coffee index c95b151..c4d4548 100644 --- a/src/core/tags/tag.coffee +++ b/src/core/tags/tag.coffee @@ -10,7 +10,7 @@ class Ant.OS.GUI.BaseTag @root.get = (k) => @get k @root.aid = () => @aid() @root.calibrate = () => @calibrate() - @root.sync = () => @sync() + @root.sync = (d) => @sync(d) @mounted = false @root.setup = () => @setup() @refs = {} @@ -67,9 +67,9 @@ class Ant.OS.GUI.BaseTag return @opts if opt is "*" @opts[opt] - sync: () -> - @update() - $(@root).children().each () -> @update() + sync: (d) -> + @update(d) + $(@root).children().each () -> @update(d) @root setup: () -> @@ -116,9 +116,9 @@ Element.prototype.mount = () -> $(@).children().each () -> @mount() @ -Element.prototype.update = () -> - return @sync() if @sync - $(@).children().each () -> @update() +Element.prototype.update = (d) -> + return @sync(d) if @sync + $(@).children().each () -> @update(d) @ Element.prototype.uify = (observable) -> diff --git a/src/core/vfs.coffee b/src/core/vfs.coffee index 4cbbeb2..7febc14 100644 --- a/src/core/vfs.coffee +++ b/src/core/vfs.coffee @@ -255,7 +255,8 @@ class RemoteFileHandle extends Ant.OS.API.VFS.BaseFileHandle @b64(t) .then (r) => Ant.OS.API.handle.write @path, r - .then (result) -> resolve result + .then (result) -> + resolve result .catch (e) -> reject e .catch (e) -> reject e diff --git a/src/packages/CodePad/Makefile b/src/packages/CodePad/Makefile index 6c643ef..4c8eb79 100644 --- a/src/packages/CodePad/Makefile +++ b/src/packages/CodePad/Makefile @@ -1,4 +1,4 @@ -coffee_files = coffees/CommandPalette.coffee coffees/main.coffee +coffee_files = coffees/CommandPalette.coffee coffees/main.coffee coffees/BaseExtension.coffee module_dir = extensions module_dir_src = coffees/extensions diff --git a/src/packages/CodePad/coffees/BaseExtension.coffee b/src/packages/CodePad/coffees/BaseExtension.coffee new file mode 100644 index 0000000..8d312ee --- /dev/null +++ b/src/packages/CodePad/coffees/BaseExtension.coffee @@ -0,0 +1,125 @@ +class CodePad.BaseExtension + + constructor: (@app) -> + + preload: () -> + Ant.OS.API.require @dependencies() + + import: (lib) -> + Ant.OS.API.requires lib + + basedir: () -> + "#{@app.meta().path}/extensions" + + notify: (m) -> + @app.notify m + + error: (m) -> + @app.error m + + dependencies: () -> + [] + + cat: (list, data) -> + new Promise (resolve, reject) => + return resolve data if list.length is 0 + file = (list.splice 0, 1)[0].asFileHandle() + file + .read() + .then (text) => + data = data + "\n" + text + @cat list, data + .then (d) -> resolve d + .catch (e) -> reject e + .catch (e) -> reject e + + copy: (files, to) -> + new Promise (resolve, reject) => + return resolve() if files.length is 0 + file = (files.splice 0, 1)[0].asFileHandle() + tof = "#{to}/#{file.basename}".asFileHandle() + file.read("binary") + .then (data) => + tof.setCache(new Blob [data], { type: file.info.mime }) + .write(file.info.mime) + .then (d) => + @copy files, to + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + + mkar: (src, dest) -> + @notify __("Preparing for release") + new Promise (r, e) => + @import("os://scripts/jszip.min.js").then () -> + src.asFileHandle() + .read().then (d) -> + return e d.error if d.error + r d.result + .catch (ex) -> e ex + .catch (ex) -> e ex + .then (files) => + new Promise (r, e) => + zip = new JSZip() + fn = (list) => + return r zip if list.length is 0 + f = (list.splice 0, 1)[0].path.asFileHandle() + return fn list if f.type is "dir" + f.read("binary").then (d) => + zip.file f.basename, d, { binary: true } + @notify __("add {0} to zip", f.basename) + fn list + .catch (ex) -> e ex + fn files + .then (zip) => + zip.generateAsync({ type: "base64" }).then (data) => + dest.asFileHandle() + .setCache('data:application/zip;base64,' + data) + .write("base64").then (r) => + return @error __("Cannot save the zip file: {0}", r.error) if r.error + @notify __("Package is generated in release folder") + .catch (e) => @error e.toString() + .catch (e) => @error e.toString() + + mkdirAll: (list) -> + new Promise (resolve, reject) => + return resolve() if list.length is 0 + path = (list.splice 0, 1)[0].asFileHandle() + path.parent().mk path.basename + .then (d) => + @mkdirAll list + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + + mkfileAll: (list, path, name) -> + new Promise (resolve, reject) => + return resolve() if list.length is 0 + item = (list.splice 0, 1)[0] + "#{@basedir()}/#{item[0]}" + .asFileHandle() + .read() + .then (data) => + file = item[1].asFileHandle() + .setCache(data.format name, "#{path}/#{name}") + .write "text/plain" + .then () => + @mkfileAll list, path, name + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + .catch (e) -> reject e + + metadata: (file) -> + new Promise (resolve, reject) => + if not @app.currdir + return reject @app._api.throwe __("Current folder is not found") + "#{@app.currdir.path}/#{file}" + .asFileHandle() + .read("json") + .then (data) -> + resolve data + .catch (e) => + reject @app._api.throwe __("Unable to read meta-data") + +CodePad.extensions = {} \ No newline at end of file diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK.coffee b/src/packages/CodePad/coffees/extensions/AntOSDK.coffee index 2e435db..fff2e84 100644 --- a/src/packages/CodePad/coffees/extensions/AntOSDK.coffee +++ b/src/packages/CodePad/coffees/extensions/AntOSDK.coffee @@ -25,7 +25,7 @@ class App.extensions.AntOSDK extends App.BaseExtension @mktpl dir.parent().path, dir.basename buildnrun: () -> - @metadata().then (meta) => + @metadata("project.json").then (meta) => @build(meta).then () => @run(meta).catch (e) => @error.toString() .catch (e) => @@ -33,9 +33,9 @@ class App.extensions.AntOSDK extends App.BaseExtension .catch (e) => @error e.toString() release: () -> - @metadata().then (meta) => + @metadata("project.json").then (meta) => @build(meta).then () => - @mkar(meta) + @mkar("#{meta.root}/build/debug", "#{meta.root}/build/release/#{meta.name}.zip") .then () -> .catch (e) => @error.toString() .catch (e) => @@ -46,7 +46,6 @@ class App.extensions.AntOSDK extends App.BaseExtension # private functions mktpl: (path, name, flag) -> rpath = "#{path}/#{name}" - console.log rpath dirs = [ "#{rpath}/build", "#{rpath}/build/release", @@ -58,11 +57,11 @@ class App.extensions.AntOSDK extends App.BaseExtension ] dirs.unshift rpath if flag files = [ - ["main.tpl", "#{rpath}/coffees/main.coffee"], - ["package.tpl", "#{rpath}/package.json"], - ["project.tpl", "#{rpath}/project.json"], - ["README.tpl", "#{rpath}/README.md"], - ["scheme.tpl", "#{rpath}/assets/scheme.html"] + ["templates/sdk-main.tpl", "#{rpath}/coffees/main.coffee"], + ["templates/sdk-package.tpl", "#{rpath}/package.json"], + ["templates/sdk-project.tpl", "#{rpath}/project.json"], + ["templates/sdk-README.tpl", "#{rpath}/README.md"], + ["templates/sdk-scheme.tpl", "#{rpath}/assets/scheme.html"] ] @mkdirAll dirs .then () => @@ -73,48 +72,6 @@ class App.extensions.AntOSDK extends App.BaseExtension @app.openFile "#{rpath}/README.md".asFileHandle() .catch (e) => @error e.stack .catch (e) => @error e.stack - - mkdirAll: (list) -> - new Promise (resolve, reject) => - return resolve() if list.length is 0 - path = (list.splice 0, 1)[0].asFileHandle() - console.log path.parent().path, path.basename - path.parent().mk path.basename - .then (d) => - @mkdirAll list - .then () -> resolve() - .catch (e) -> reject e - .catch (e) -> reject e - - mkfileAll: (list, path, name) -> - new Promise (resolve, reject) => - return resolve() if list.length is 0 - item = (list.splice 0, 1)[0] - "#{@basedir()}/AntOSDK/templates/#{item[0]}" - .asFileHandle() - .read() - .then (data) => - file = item[1].asFileHandle() - .setCache(data.format name, "#{path}/#{name}") - .write "text/plain" - .then () => - @mkfileAll list, path, name - .then () -> resolve() - .catch (e) -> reject e - .catch (e) -> reject e - .catch (e) -> reject e - - metadata: () -> - new Promise (resolve, reject) => - if not @app.currdir - return reject @app._api.throwe __("Project folder is not found") - "#{@app.currdir.path}/project.json" - .asFileHandle() - .read("json") - .then (data) -> - resolve data - .catch (e) => - reject @app._api.throwe __("Unable to read project meta-data") verify: (list) -> new Promise (resolve, reject) => @@ -133,7 +90,7 @@ class App.extensions.AntOSDK extends App.BaseExtension compile: (meta) -> new Promise (resolve, reject) => - @import("#{@basedir()}/AntOSDK/coffeescript.js").then () => + @import("#{@basedir()}/coffeescript.js").then () => list = ("#{meta.root}/#{v}" for v in meta.coffees) @verify((f for f in list)).then () => @cat(list).then (code) => @@ -192,66 +149,4 @@ class App.extensions.AntOSDK extends App.BaseExtension @notify __("Installing...") @app.systemsetting.system.packages[meta.name] = v @notify __("Running {0}...", meta.name) - @app._gui.forceLaunch meta.name - - cat: (list, data) -> - new Promise (resolve, reject) => - return resolve data if list.length is 0 - file = (list.splice 0, 1)[0].asFileHandle() - file - .read() - .then (text) => - data = data + "\n" + text - @cat list, data - .then (d) -> resolve d - .catch (e) -> reject e - .catch (e) -> reject e - - copy: (files, to) -> - new Promise (resolve, reject) => - return resolve() if files.length is 0 - file = (files.splice 0, 1)[0].asFileHandle() - tof = "#{to}/#{file.basename}".asFileHandle() - file.read("binary") - .then (data) => - tof.setCache(new Blob [data], { type: file.info.mime }) - .write(file.info.mime) - .then (d) => - @copy files, to - .then () -> resolve() - .catch (e) -> reject e - .catch (e) -> reject e - - mkar: (meta) -> - @notify __("Preparing for release") - new Promise (r, e) => - @import("os://scripts/jszip.min.js").then () -> - "#{meta.root}/build/debug".asFileHandle() - .read().then (d) -> - return e d.error if d.error - r d.result - .catch (ex) -> e ex - .catch (ex) -> e ex - .then (files) => - new Promise (r, e) => - zip = new JSZip() - fn = (list) => - return r zip if list.length is 0 - f = (list.splice 0, 1)[0].path.asFileHandle() - return fn list if f.type is "dir" - f.read("binary").then (d) => - zip.file f.basename, d, { binary: true } - @notify __("add {0} to zip", f.basename) - fn list - .catch (ex) -> e ex - fn files - .then (zip) => - zip.generateAsync({ type: "base64" }).then (data) => - "#{meta.root}/build/release/#{meta.name}.zip" - .asFileHandle() - .setCache('data:application/zip;base64,' + data) - .write("base64").then (r) => - return @error __("Cannot save the zip file: {0}", r.error) if r.error - @notify __("Package is generated in release folder") - .catch (e) => @error e.toString() - .catch (e) => @error e.toString() \ No newline at end of file + @app._gui.forceLaunch meta.name \ No newline at end of file diff --git a/src/packages/CodePad/coffees/extensions/ExtensionMaker.coffee b/src/packages/CodePad/coffees/extensions/ExtensionMaker.coffee new file mode 100644 index 0000000..9b52986 --- /dev/null +++ b/src/packages/CodePad/coffees/extensions/ExtensionMaker.coffee @@ -0,0 +1,217 @@ +# import the CodePad application module +App = this.OS.APP.CodePad + +# define the extension +class App.extensions.ExtensionMaker extends App.BaseExtension + constructor: (app) -> + super app + + # public functions + create: () -> + @app.openDialog("FileDialog", { + title: "__(New CodePad extension at)", + file: { basename: __("ExtensionName") }, + mimes: ["dir"] + }).then (d) => + @mktpl d.file.path, d.name + + buildnrun: () -> + @metadata("extension.json").then (meta) => + @build(meta).then () => + @run(meta).catch (e) => @error.toString() + .catch (e) => + @error e.toString() + .catch (e) => @error e.toString() + + release: () -> + @metadata("extension.json").then (meta) => + @build(meta).then () => + @mkar("#{meta.root}/build/debug", + "#{meta.root}/build/release/#{meta.meta.name}.zip") + .then () -> + .catch (e) => @error.toString() + .catch (e) => + @error e.toString() + .catch (e) => @error e.toString() + + install: () -> + @app.openDialog("FileDialog", { + title: "__(Select extension archive)", + mimes: [".*/zip"] + }).then (d) => + @installZip d.file.path + .then () => + @notify __("Extension installed") + @app.loadExtensionMetaData() + .catch (e) => @error e.stack + # private functions + mktpl: (path, name) -> + rpath = "#{path}/#{name}" + dirs = [ + rpath, + "#{rpath}/build", + "#{rpath}/build/release", + "#{rpath}/build/debug" + ] + files = [ + ["templates/ext-main.tpl", "#{rpath}/#{name}.coffee"], + ["templates/ext-extension.tpl", "#{rpath}/extension.json"], + ] + @mkdirAll dirs + .then () => + @mkfileAll(files, path, name) + .then () => + @app.currdir = rpath.asFileHandle() + @app.initSideBar() + @app.openFile "#{rpath}/#{name}.coffee".asFileHandle() + .catch (e) => @error e.stack + .catch (e) => @error e.stack + + + verify: (list) -> + new Promise (resolve, reject) => + return resolve() if list.length is 0 + file = (list.splice 0, 1)[0].asFileHandle() + @notify __("Verifying: {0}", file.path) + file.read().then (data) => + try + CoffeeScript.nodes data + @verify list + .then () -> resolve() + .catch (e) -> reject e + catch ex + reject ex + .catch (e) -> reject e + + compile: (meta) -> + new Promise (resolve, reject) => + @import("#{@basedir()}/coffeescript.js").then () => + list = ("#{meta.root}/#{v}" for v in meta.coffees) + @verify((f for f in list)).then () => + @cat(list).then (code) => + jsrc = CoffeeScript.compile code + @notify __("Compiled successful") + resolve jsrc + .catch (e) -> reject e + .catch (e) -> reject e + .catch (e) -> reject e + + build: (meta) -> + new Promise (resolve, reject) => + @compile(meta).then (src) => + @cat ("#{meta.root}/#{v}" for v in meta.javascripts), src + .then (jsrc) -> + new Promise (r, e) -> + "#{meta.root}/build/debug/#{meta.meta.name}.js" + .asFileHandle() + .setCache jsrc + .write("text/plain") + .then (d) -> + return e d if d.error + r() + .catch (ex) -> e ex + .then () -> + new Promise (r, e) -> + "#{meta.root}/build/debug/extension.json" + .asFileHandle() + .setCache meta.meta + .write("object") + .then (data) -> + return e data.error if data.error + r data + .catch (ex) -> e ex + .then () => + @copy ("#{meta.root}/#{v}" for v in meta.copies), "#{meta.root}/build/debug" + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + + run: (meta) -> + path = "#{meta.root}/build/debug/#{meta.meta.name}.js" + delete @app._api.shared[path] if @app._api.shared[path] + @app._api.requires path + .then () => + if @app.extensions[meta.meta.name] + @app.extensions[meta.meta.name].child = [] + @app.extensions[meta.meta.name].addAction v for v in meta.meta.actions + else + @app.extensions[meta.meta.name] = new App.CMDMenu meta.meta.text + @app.extensions[meta.meta.name].name = meta.meta.name + @app.extensions[meta.meta.name].addAction v for v in meta.meta.actions + @app.spotlight.addAction @app.extensions[meta.meta.name] + @app.extensions[meta.meta.name].onchildselect (e) => + @app.loadAndRunExtensionAction e.data.item.get "data" + @app.spotlight.run @app + .catch (e) => @error e.toString() + + + installExtension: (files, zip) -> + new Promise (resolve, reject) => + idx = files.indexOf "extension.json" + reject(@app._api.throwe __("No meta-data found")) if idx < 0 + metafile = (files.splice idx, 1)[0] + # read the meta file + zip.file(metafile).async("uint8array").then (d) => + meta = JSON.parse(new TextDecoder("utf-8").decode(d)) + @installFiles files, zip, meta + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + + installFiles: (files, zip, meta) -> + return @installMeta(meta) if files.length is 0 + new Promise (resolve, reject) => + file = (files.splice 0, 1)[0] + path = "#{@basedir()}/#{file}" + zip.file(file).async("uint8array").then (d) => + path.asFileHandle() + .setCache(new Blob [d], { type: "octet/stream" }) + .write("text/plain").then (r) => + return reject r.error if r.error + @installFiles files, zip, meta + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + .catch (e) -> reject e + + installMeta: (meta) -> + new Promise (resolve, reject) => + file = "#{@app.meta().path}/extensions.json".asFileHandle() + file.read("json").then (data) -> + names = (v.name) for v in data + idx = name.indexOf meta.name + data.splice idx, 1 if idx >= 0 + data.push meta + file.setCache data + .write("object") + .then () -> resolve() + .catch (e) -> reject e + .catch (e) -> reject e + + installZip: (path) -> + new Promise (resolve, reject) => + @import("os://scripts/jszip.min.js").then () => + path.asFileHandle().read("binary").then (data) => + JSZip.loadAsync(data).then (zip) => + pth = @basedir() + dir = [] + files = [] + for name, file of zip.files + if file.dir + dir.push(pth + "/" + name) + else + files.push name + if dir.length > 0 + @mkdirAll dir + .then () => + @installExtension files, zip + .then () -> resolve() + .catch(e) -> reject(e) + .catch (e) -> reject e + else + @installExtension files, zip + .then () -> resolve() + .catch (e) -> reject(e) + .catch (e) -> reject e + .catch (e) -> reject e + .catch (e) -> reject e \ No newline at end of file diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK/coffeescript.js b/src/packages/CodePad/coffees/extensions/coffeescript.js similarity index 100% rename from src/packages/CodePad/coffees/extensions/AntOSDK/coffeescript.js rename to src/packages/CodePad/coffees/extensions/coffeescript.js diff --git a/src/packages/CodePad/coffees/extensions/templates/ext-extension.tpl b/src/packages/CodePad/coffees/extensions/templates/ext-extension.tpl new file mode 100644 index 0000000..352b742 --- /dev/null +++ b/src/packages/CodePad/coffees/extensions/templates/ext-extension.tpl @@ -0,0 +1,17 @@ +{ + "root": "{1}", + "javascripts": [], + "coffees": ["{0}.coffee"], + "copies": [], + "meta": { + "name": "{0}", + "text": "{0}", + "version": "0.0.1-a", + "actions" : [ + { + "text": "__(Example action)", + "name": "test" + } + ] + } +} diff --git a/src/packages/CodePad/coffees/extensions/templates/ext-main.tpl b/src/packages/CodePad/coffees/extensions/templates/ext-main.tpl new file mode 100644 index 0000000..5728ffb --- /dev/null +++ b/src/packages/CodePad/coffees/extensions/templates/ext-main.tpl @@ -0,0 +1,10 @@ +# import the CodePad application module +App = this.OS.APP.CodePad + +# define the extension +class App.extensions.{0} extends App.BaseExtension + constructor: (app) -> + super app + + test: () -> + @notify "Test action is invoked" \ No newline at end of file diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK/templates/README.tpl b/src/packages/CodePad/coffees/extensions/templates/sdk-README.tpl similarity index 100% rename from src/packages/CodePad/coffees/extensions/AntOSDK/templates/README.tpl rename to src/packages/CodePad/coffees/extensions/templates/sdk-README.tpl diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK/templates/main.tpl b/src/packages/CodePad/coffees/extensions/templates/sdk-main.tpl similarity index 100% rename from src/packages/CodePad/coffees/extensions/AntOSDK/templates/main.tpl rename to src/packages/CodePad/coffees/extensions/templates/sdk-main.tpl diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK/templates/package.tpl b/src/packages/CodePad/coffees/extensions/templates/sdk-package.tpl similarity index 100% rename from src/packages/CodePad/coffees/extensions/AntOSDK/templates/package.tpl rename to src/packages/CodePad/coffees/extensions/templates/sdk-package.tpl diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK/templates/project.tpl b/src/packages/CodePad/coffees/extensions/templates/sdk-project.tpl similarity index 100% rename from src/packages/CodePad/coffees/extensions/AntOSDK/templates/project.tpl rename to src/packages/CodePad/coffees/extensions/templates/sdk-project.tpl diff --git a/src/packages/CodePad/coffees/extensions/AntOSDK/templates/scheme.tpl b/src/packages/CodePad/coffees/extensions/templates/sdk-scheme.tpl similarity index 100% rename from src/packages/CodePad/coffees/extensions/AntOSDK/templates/scheme.tpl rename to src/packages/CodePad/coffees/extensions/templates/sdk-scheme.tpl diff --git a/src/packages/CodePad/coffees/main.coffee b/src/packages/CodePad/coffees/main.coffee index 40a3bf1..8ea2559 100644 --- a/src/packages/CodePad/coffees/main.coffee +++ b/src/packages/CodePad/coffees/main.coffee @@ -92,6 +92,17 @@ class CodePad extends this.OS.GUI.BaseApplication }] m.show e + @fileview.contextmenuHandle = (e, m) => + m.set "items", [ + { text: "__(New file)", id: "new" }, + { text: "__(New folder)", id: "newdir" }, + { text: "__(Rename)", id: "rename" }, + { text: "__(Delete)", id: "delete" } + ] + m.set "onmenuselect", (e) => + @ctxFileMenuHandle e + m.show e + @bindKey "ALT-N", () => @menuAction "new" @bindKey "ALT-O", () => @menuAction "open" @bindKey "ALT-F", () => @menuAction "opendir" @@ -221,7 +232,7 @@ class CodePad extends this.OS.GUI.BaseApplication .then (d) => for ext in d if @extensions[ext.name] - @extensions[ext.name].child = {} + @extensions[ext.name].child = [] @extensions[ext.name].addAction v for v in ext.actions else @extensions[ext.name] = new CMDMenu ext.text @@ -271,6 +282,86 @@ class CodePad extends this.OS.GUI.BaseApplication @menuAction e.data.item.get("data").dataid, r } + ctxFileMenuHandle: (e) -> + el = e.data.item + return unless el + data = el.get("data") + return unless data + file = @fileview.get "selectedFile" + dir = @currdir + dir = file.path.asFileHandle() if file and file.type is "dir" + dir = file.path.asFileHandle().parent() if file and file.type is "file" + + switch data.id + when "new" + return unless dir + @openDialog("PromptDialog", { + title: "__(New file)", + label: "__(File name)" + }) + .then (d) => + fp = "#{dir.path}/#{d}".asFileHandle() + fp.write("text/plain") + .then (r) => + return @error __("Fail to create {0}: {1}", d, r.error) if r.error + @fileview.update dir.path + .catch (e) => + @error __("Fail to create: {0}", e.stack) + + when "newdir" + return unless dir + @openDialog("PromptDialog", { + title: "__(New folder)", + label: "__(Folder name)" + }) + .then (d) => + dir.mk(d) + .then (r) => + return @error __("Fail to create {0}: {1}", d, r.error) if r.error + @fileview.update dir.path + .catch (e) => + @error __("Fail to create: {0}", e.stack) + + when "rename" + return unless file + @openDialog("PromptDialog", { + title: "__(Rename)", + label: "__(File name)", + value: file.filename + }) + .then (d) => + return if d is file.filename + file = file.path.asFileHandle() + dir = file.parent() + file.move "#{dir.path}/#{d}" + .then (r) => + return @error __("Fail to rename to {0}: {1}", d, r.error) if r.error + @fileview.update dir.path + .catch (e) => + console.log e + @error __("Fail to rename: {0}", e.stack) + + when "delete" + return unless file + @openDialog("YesNoDialog", { + title: "__(Delete)", + iconclass: "fa fa-question-circle", + text: __("Do you really want to delete: {0}?", file.filename) + }) + .then (d) => + return unless d + file = file.path.asFileHandle() + dir = file.parent() + file.remove() + .then (r) => + return @error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error + @fileview.update dir.path + .catch (e) => + @error __("Fail to delete: {0}", e.stack) + + else + + save: (file) -> file.write("text/plain") .then (d) => @@ -352,28 +443,6 @@ class CodePad extends this.OS.GUI.BaseApplication ] menu -class CodePad.BaseExtension - - constructor: (@app) -> - - preload: () -> - Ant.OS.API.require @dependencies() - - import: (lib) -> - Ant.OS.API.requires lib - - basedir: () -> - "#{@app.meta().path}/extensions" - - notify: (m) -> - @app.notify m - - error: (m) -> - @app.error m - - dependencies: () -> - [] - class CMDMenu constructor: (@text, @shortcut) -> @child = [] @@ -411,8 +480,6 @@ CMDMenu.fromMenu = (mn) -> CodePad.CMDMenu = CMDMenu -CodePad.extensions = {} - CodePad.dependencies = [ "os://scripts/ace/ace.js", "os://scripts/ace/ext-language_tools.js", diff --git a/src/packages/CodePad/extensions.json b/src/packages/CodePad/extensions.json index 27c44a2..8cb06f2 100644 --- a/src/packages/CodePad/extensions.json +++ b/src/packages/CodePad/extensions.json @@ -21,5 +21,28 @@ "name": "release" } ] + }, + { + "name": "ExtensionMaker", + "text": "CodePad Extension", + "version": "0.0.1-a", + "actions" : [ + { + "text": "__(New Extension)", + "name": "create" + }, + { + "text": "__(Build and Run)", + "name": "buildnrun" + }, + { + "text": "__(Build release)", + "name": "release" + }, + { + "text": "__(Install extension)", + "name": "install" + } + ] } ]