mirror of
https://github.com/lxsang/antos-frontend.git
synced 2024-12-27 17:58:22 +01:00
add extension maker
This commit is contained in:
parent
a29a449eaf
commit
c94cb0963d
@ -12,10 +12,16 @@ class TreeViewItemPrototype extends Ant.OS.GUI.BaseTag
|
|||||||
@setopt "selected", false
|
@setopt "selected", false
|
||||||
@setopt "treepath", @aid()
|
@setopt "treepath", @aid()
|
||||||
|
|
||||||
|
update: (p) ->
|
||||||
|
return unless p
|
||||||
|
return unless p is @get("treepath")
|
||||||
|
@set "open", true
|
||||||
|
|
||||||
__data__: (v) ->
|
__data__: (v) ->
|
||||||
return unless v
|
return unless v
|
||||||
@set "nodes", v.nodes if v.nodes
|
@set "nodes", v.nodes if v.nodes
|
||||||
@set "open", v.open
|
@set "open", v.open
|
||||||
|
@set "treepath", v.path if v.path
|
||||||
|
|
||||||
__selected__: (v) ->
|
__selected__: (v) ->
|
||||||
$(@refs.wrapper).removeClass()
|
$(@refs.wrapper).removeClass()
|
||||||
@ -176,6 +182,7 @@ class TreeViewTag extends Ant.OS.GUI.BaseTag
|
|||||||
__data__: (v) ->
|
__data__: (v) ->
|
||||||
return unless v
|
return unless v
|
||||||
$(@root).empty()
|
$(@root).empty()
|
||||||
|
@set "treepath", v.path if v.path
|
||||||
el = $("<#{@get "itemtag"}>").appendTo @root
|
el = $("<#{@get "itemtag"}>").appendTo @root
|
||||||
el[0].uify undefined
|
el[0].uify undefined
|
||||||
el[0].set "treeroot", if @is_root() then @ else @get "treeroot"
|
el[0].set "treeroot", if @is_root() then @ else @get "treeroot"
|
||||||
|
@ -10,7 +10,7 @@ class Ant.OS.GUI.BaseTag
|
|||||||
@root.get = (k) => @get k
|
@root.get = (k) => @get k
|
||||||
@root.aid = () => @aid()
|
@root.aid = () => @aid()
|
||||||
@root.calibrate = () => @calibrate()
|
@root.calibrate = () => @calibrate()
|
||||||
@root.sync = () => @sync()
|
@root.sync = (d) => @sync(d)
|
||||||
@mounted = false
|
@mounted = false
|
||||||
@root.setup = () => @setup()
|
@root.setup = () => @setup()
|
||||||
@refs = {}
|
@refs = {}
|
||||||
@ -67,9 +67,9 @@ class Ant.OS.GUI.BaseTag
|
|||||||
return @opts if opt is "*"
|
return @opts if opt is "*"
|
||||||
@opts[opt]
|
@opts[opt]
|
||||||
|
|
||||||
sync: () ->
|
sync: (d) ->
|
||||||
@update()
|
@update(d)
|
||||||
$(@root).children().each () -> @update()
|
$(@root).children().each () -> @update(d)
|
||||||
@root
|
@root
|
||||||
|
|
||||||
setup: () ->
|
setup: () ->
|
||||||
@ -116,9 +116,9 @@ Element.prototype.mount = () ->
|
|||||||
$(@).children().each () -> @mount()
|
$(@).children().each () -> @mount()
|
||||||
@
|
@
|
||||||
|
|
||||||
Element.prototype.update = () ->
|
Element.prototype.update = (d) ->
|
||||||
return @sync() if @sync
|
return @sync(d) if @sync
|
||||||
$(@).children().each () -> @update()
|
$(@).children().each () -> @update(d)
|
||||||
@
|
@
|
||||||
|
|
||||||
Element.prototype.uify = (observable) ->
|
Element.prototype.uify = (observable) ->
|
||||||
|
@ -255,7 +255,8 @@ class RemoteFileHandle extends Ant.OS.API.VFS.BaseFileHandle
|
|||||||
@b64(t)
|
@b64(t)
|
||||||
.then (r) =>
|
.then (r) =>
|
||||||
Ant.OS.API.handle.write @path, r
|
Ant.OS.API.handle.write @path, r
|
||||||
.then (result) -> resolve result
|
.then (result) ->
|
||||||
|
resolve result
|
||||||
.catch (e) -> reject e
|
.catch (e) -> reject e
|
||||||
.catch (e) -> reject e
|
.catch (e) -> reject e
|
||||||
|
|
||||||
|
@ -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 = extensions
|
||||||
module_dir_src = coffees/extensions
|
module_dir_src = coffees/extensions
|
||||||
|
125
src/packages/CodePad/coffees/BaseExtension.coffee
Normal file
125
src/packages/CodePad/coffees/BaseExtension.coffee
Normal file
@ -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 = {}
|
@ -25,7 +25,7 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
@mktpl dir.parent().path, dir.basename
|
@mktpl dir.parent().path, dir.basename
|
||||||
|
|
||||||
buildnrun: () ->
|
buildnrun: () ->
|
||||||
@metadata().then (meta) =>
|
@metadata("project.json").then (meta) =>
|
||||||
@build(meta).then () =>
|
@build(meta).then () =>
|
||||||
@run(meta).catch (e) => @error.toString()
|
@run(meta).catch (e) => @error.toString()
|
||||||
.catch (e) =>
|
.catch (e) =>
|
||||||
@ -33,9 +33,9 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
.catch (e) => @error e.toString()
|
.catch (e) => @error e.toString()
|
||||||
|
|
||||||
release: () ->
|
release: () ->
|
||||||
@metadata().then (meta) =>
|
@metadata("project.json").then (meta) =>
|
||||||
@build(meta).then () =>
|
@build(meta).then () =>
|
||||||
@mkar(meta)
|
@mkar("#{meta.root}/build/debug", "#{meta.root}/build/release/#{meta.name}.zip")
|
||||||
.then () ->
|
.then () ->
|
||||||
.catch (e) => @error.toString()
|
.catch (e) => @error.toString()
|
||||||
.catch (e) =>
|
.catch (e) =>
|
||||||
@ -46,7 +46,6 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
# private functions
|
# private functions
|
||||||
mktpl: (path, name, flag) ->
|
mktpl: (path, name, flag) ->
|
||||||
rpath = "#{path}/#{name}"
|
rpath = "#{path}/#{name}"
|
||||||
console.log rpath
|
|
||||||
dirs = [
|
dirs = [
|
||||||
"#{rpath}/build",
|
"#{rpath}/build",
|
||||||
"#{rpath}/build/release",
|
"#{rpath}/build/release",
|
||||||
@ -58,11 +57,11 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
]
|
]
|
||||||
dirs.unshift rpath if flag
|
dirs.unshift rpath if flag
|
||||||
files = [
|
files = [
|
||||||
["main.tpl", "#{rpath}/coffees/main.coffee"],
|
["templates/sdk-main.tpl", "#{rpath}/coffees/main.coffee"],
|
||||||
["package.tpl", "#{rpath}/package.json"],
|
["templates/sdk-package.tpl", "#{rpath}/package.json"],
|
||||||
["project.tpl", "#{rpath}/project.json"],
|
["templates/sdk-project.tpl", "#{rpath}/project.json"],
|
||||||
["README.tpl", "#{rpath}/README.md"],
|
["templates/sdk-README.tpl", "#{rpath}/README.md"],
|
||||||
["scheme.tpl", "#{rpath}/assets/scheme.html"]
|
["templates/sdk-scheme.tpl", "#{rpath}/assets/scheme.html"]
|
||||||
]
|
]
|
||||||
@mkdirAll dirs
|
@mkdirAll dirs
|
||||||
.then () =>
|
.then () =>
|
||||||
@ -74,48 +73,6 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
.catch (e) => @error e.stack
|
.catch (e) => @error e.stack
|
||||||
.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) ->
|
verify: (list) ->
|
||||||
new Promise (resolve, reject) =>
|
new Promise (resolve, reject) =>
|
||||||
return resolve() if list.length is 0
|
return resolve() if list.length is 0
|
||||||
@ -133,7 +90,7 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
|
|
||||||
compile: (meta) ->
|
compile: (meta) ->
|
||||||
new Promise (resolve, reject) =>
|
new Promise (resolve, reject) =>
|
||||||
@import("#{@basedir()}/AntOSDK/coffeescript.js").then () =>
|
@import("#{@basedir()}/coffeescript.js").then () =>
|
||||||
list = ("#{meta.root}/#{v}" for v in meta.coffees)
|
list = ("#{meta.root}/#{v}" for v in meta.coffees)
|
||||||
@verify((f for f in list)).then () =>
|
@verify((f for f in list)).then () =>
|
||||||
@cat(list).then (code) =>
|
@cat(list).then (code) =>
|
||||||
@ -193,65 +150,3 @@ class App.extensions.AntOSDK extends App.BaseExtension
|
|||||||
@app.systemsetting.system.packages[meta.name] = v
|
@app.systemsetting.system.packages[meta.name] = v
|
||||||
@notify __("Running {0}...", meta.name)
|
@notify __("Running {0}...", meta.name)
|
||||||
@app._gui.forceLaunch 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()
|
|
217
src/packages/CodePad/coffees/extensions/ExtensionMaker.coffee
Normal file
217
src/packages/CodePad/coffees/extensions/ExtensionMaker.coffee
Normal file
@ -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
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -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"
|
@ -92,6 +92,17 @@ class CodePad extends this.OS.GUI.BaseApplication
|
|||||||
}]
|
}]
|
||||||
m.show e
|
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-N", () => @menuAction "new"
|
||||||
@bindKey "ALT-O", () => @menuAction "open"
|
@bindKey "ALT-O", () => @menuAction "open"
|
||||||
@bindKey "ALT-F", () => @menuAction "opendir"
|
@bindKey "ALT-F", () => @menuAction "opendir"
|
||||||
@ -221,7 +232,7 @@ class CodePad extends this.OS.GUI.BaseApplication
|
|||||||
.then (d) =>
|
.then (d) =>
|
||||||
for ext in d
|
for ext in d
|
||||||
if @extensions[ext.name]
|
if @extensions[ext.name]
|
||||||
@extensions[ext.name].child = {}
|
@extensions[ext.name].child = []
|
||||||
@extensions[ext.name].addAction v for v in ext.actions
|
@extensions[ext.name].addAction v for v in ext.actions
|
||||||
else
|
else
|
||||||
@extensions[ext.name] = new CMDMenu ext.text
|
@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
|
@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) ->
|
save: (file) ->
|
||||||
file.write("text/plain")
|
file.write("text/plain")
|
||||||
.then (d) =>
|
.then (d) =>
|
||||||
@ -352,28 +443,6 @@ class CodePad extends this.OS.GUI.BaseApplication
|
|||||||
]
|
]
|
||||||
menu
|
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
|
class CMDMenu
|
||||||
constructor: (@text, @shortcut) ->
|
constructor: (@text, @shortcut) ->
|
||||||
@child = []
|
@child = []
|
||||||
@ -411,8 +480,6 @@ CMDMenu.fromMenu = (mn) ->
|
|||||||
|
|
||||||
CodePad.CMDMenu = CMDMenu
|
CodePad.CMDMenu = CMDMenu
|
||||||
|
|
||||||
CodePad.extensions = {}
|
|
||||||
|
|
||||||
CodePad.dependencies = [
|
CodePad.dependencies = [
|
||||||
"os://scripts/ace/ace.js",
|
"os://scripts/ace/ace.js",
|
||||||
"os://scripts/ace/ext-language_tools.js",
|
"os://scripts/ace/ext-language_tools.js",
|
||||||
|
@ -21,5 +21,28 @@
|
|||||||
"name": "release"
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user