diff --git a/Antedit/README.md b/Antedit/README.md
index 3ca0522..7ad05c5 100644
--- a/Antedit/README.md
+++ b/Antedit/README.md
@@ -6,6 +6,7 @@ The editor functionality can be extended by its extension mechanism.
Extension can be developed/released/isntalled by the editor itself.
### Change logs
+- 0.2.2-b: Support horizotal scrolling on horizotal tabbars
- 0.2.1-b: Add open file to right, editor actions are only attached to code editor
- 0.2.0-b: Support diff mode in editor + fix new Monaco version compatible bug
- 0.1.17-b: Fix extension keybinding bug with the new monaco editor
diff --git a/Antedit/assets/scheme.html b/Antedit/assets/scheme.html
index e410cc4..2b12645 100644
--- a/Antedit/assets/scheme.html
+++ b/Antedit/assets/scheme.html
@@ -23,7 +23,7 @@
-
+
diff --git a/Antedit/build/debug/README.md b/Antedit/build/debug/README.md
deleted file mode 100644
index 3ca0522..0000000
--- a/Antedit/build/debug/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Antedit
-Simple yet powerful text/code editor based on the Monaco editor,
-the editor that powers VS Code.
-
-The editor functionality can be extended by its extension mechanism.
-Extension can be developed/released/isntalled by the editor itself.
-
-### Change logs
-- 0.2.1-b: Add open file to right, editor actions are only attached to code editor
-- 0.2.0-b: Support diff mode in editor + fix new Monaco version compatible bug
-- 0.1.17-b: Fix extension keybinding bug with the new monaco editor
-- 0.1.16-b: use the new version of monaco editor
-- 0.1.14-b: improve output log display
-- 0.1.13-b: Allow file upload in file view, add menu context in tabbar
-- 0.1.12-b: fix recent files not adding correctly
-- 0.1.11-b: fix file type parsing from path
-- 0.1.10-b: Antedit now has it own extension manager
-- 0.1.9-a: Allow output text selection
-- 0.1.8-a: Allow to change language mode
-- 0.1.7-a: Add keyboard shortcut support to extension actions
\ No newline at end of file
diff --git a/Antedit/build/debug/extensions/EditorExtensionMaker/main.tpl b/Antedit/build/debug/extensions/EditorExtensionMaker/main.tpl
deleted file mode 100644
index f5a4487..0000000
--- a/Antedit/build/debug/extensions/EditorExtensionMaker/main.tpl
+++ /dev/null
@@ -1,19 +0,0 @@
-(function() {
- // import the CodePad application module
- const App = this.OS.application.Antedit;
-
- // define the extension
- App.extensions.{0} = class {0} extends App.EditorBaseExtension {
- constructor(app) {
- super("{0}",app);
- }
-
- test() {
- return this.notify("Test action is invoked");
- }
-
- cleanup() {}
-
- };
-
-}).call(this);
\ No newline at end of file
diff --git a/Antedit/build/debug/extensions/EditorExtensionMaker/meta.tpl b/Antedit/build/debug/extensions/EditorExtensionMaker/meta.tpl
deleted file mode 100644
index d6b24d2..0000000
--- a/Antedit/build/debug/extensions/EditorExtensionMaker/meta.tpl
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "javascripts": ["{0}.js"],
- "copies": [],
- "meta": {
- "name": "{0}",
- "text": "{0}",
- "version": "0.0.1-a",
- "actions" : [
- {
- "text": "__(Example action)",
- "name": "test"
- }
- ]
- }
-}
\ No newline at end of file
diff --git a/Antedit/build/debug/extensions/extensions.json b/Antedit/build/debug/extensions/extensions.json
deleted file mode 100644
index ced33a1..0000000
--- a/Antedit/build/debug/extensions/extensions.json
+++ /dev/null
@@ -1,33 +0,0 @@
-[
- {
- "name": "EditorExtensionMaker",
- "text": "Antedit Extension",
- "version": "0.0.1-a",
- "actions" : [
- {
- "text": "__(New Extension)",
- "name": "create"
- },
- {
- "text": "__(Build)",
- "name": "build"
- },
- {
- "text": "__(Run)",
- "name": "run"
- },
- {
- "text": "__(Build release)",
- "name": "release"
- },
- {
- "text": "__(Install from file)",
- "name": "install"
- },
- {
- "text": "__(Install from URL)",
- "name": "installFromURL"
- }
- ]
- }
-]
diff --git a/Antedit/build/debug/main.css b/Antedit/build/debug/main.css
deleted file mode 100644
index 49448d0..0000000
--- a/Antedit/build/debug/main.css
+++ /dev/null
@@ -1,171 +0,0 @@
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container
-{
- /*border-top: 1px solid #272822;*/
- overflow: hidden;
- overflow-x: auto;
- font-size: 12px;
- scrollbar-width: none;
- /*scrollbar-color: #656565 transparent;*/
-}
-
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container::-webkit-scrollbar {
- height: 0;
-}
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container::-webkit-scrollbar-track {
- background: transparent;
-}
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container::-webkit-scrollbar-thumb {
- background-color: #656565;
- border: 0;
- }
-
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container > ul
-{
- width: intrinsic;
- width: -moz-max-content;
- width: -webkit-max-content;
- width: max-content;
-}
-
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view ul afx-list-item:nth-child(even) li.selected,
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container > ul > afx-list-item > li.selected{
- background-color:#272822;
- color:white;
- border: 0;
- border-radius: 0;
-}
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view afx-list-view i.closable:before {
- color:#afafaf;
-}
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view ul afx-list-item:nth-child(even) li,
-afx-app-window[data-id = "antedit"] afx-tab-bar> afx-list-view > div.list-container > ul li{
- background-color:#333333;
- color:#afafaf;
- border-radius: 0;
- border: 0;
- padding-top: 5px;
- padding-bottom: 5px;
- padding-right: 20px;
- border-right: 1px solid #272822;
-}
-
-afx-app-window[data-id = "antedit"] afx-tab-container[data-id="sidebar-tab-container"] afx-tab-bar> afx-list-view > div.list-container {
- background-color: #333333;
-}
-afx-app-window[data-id = "antedit"] afx-tab-container[data-id="sidebar-tab-container"] afx-tab-bar> afx-list-view > div.list-container > ul li{
- float: none;
- font-size: 20px;
-}
-
-afx-app-window[data-id = "antedit"] .afx-window-wrapper afx-vbox[data-id = "sidebar"]{
- background-color:#272822;
-}
-afx-app-window[data-id = "antedit"] div.afx-window-content {
- background-color:#333333;
-}
-afx-app-window[data-id = "antedit"] afx-resizer {
- background-color:#272822;
- border-right: 1px solid #656565;
- border-bottom: 1px solid #656565;
-}
-
-afx-app-window[data-id = "antedit"] .bottom-tab-content {
- background-color:#272822;
-}
-
-afx-app-window[data-id = "antedit"] .afx-window-wrapper afx-tree-view{
- color: white;
- padding: 0;
-}
-afx-app-window[data-id = "antedit"] .afx-window-wrapper afx-tree-view afx-tree-view-item ul li{
- padding-left: 10px;
-}
-afx-app-window[data-id = "antedit"] .afx-window-wrapper .afx_tree_item_selected ul{
- background-color: #116cd6;
-}
-
-afx-app-window[data-id = "antedit"] afx-file-view afx-tree-view .afx-tree-view-item:before{
- color: white;
-}
-
-afx-app-window[data-id = "antedit"] .afx-window-wrapper div[data-id="statctn"]{
- color: white;
- background-color: #007acc;
- padding-right: 10px;
- padding-top: 5px;
- font-size: 11px;
-}
-
-afx-app-window[data-id = "antedit"] .afx-window-wrapper div[data-id="statctn"] afx-label {
- padding-left: 10px;
-}
-
-afx-app-window[data-id = "antedit"] div[data-id="output-tab"] {
- overflow-y: auto;
- overflow-x: hidden;
- user-select: text;
-}
-
-afx-app-window[data-id = "antedit"] div[data-id="output-tab"] pre {
- margin: 3px;
- white-space: pre-wrap; /* css-3 */
- white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
- font-family: monospace;
-}
-
-afx-app-window[data-id = "antedit"] div[data-id="output-tab"] pre.code-pad-log-error {
- color: red;
-}
-
-afx-app-window[data-id = "antedit"] div[data-id="output-tab"] pre.code-pad-log-warn {
- color: orange;
-}
-
-afx-app-window[data-id = "antedit"] div[data-id="output-tab"] pre.code-pad-log-info {
- color: white;
-}
-
-afx-app-window[data-id = "antedit"] afx-button[ data-id="logger-clear" ] button{
- border: 0;
- background: transparent;
-}
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item {
- color: white !important;
-}
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item afx-label i.label-text{
- font-weight: bold !important;
-}
-
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item p {
- margin: 0;
- padding: 0;
- padding-left:15px;
- font-size: 11px;
-}
-
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item p[data-id="ext-list-item-b-p"] {
- text-align: right;
- font-size: 11px;
-}
-
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item > li {
- background-color: transparent !important;
- padding-right: 5px !important;
-}
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item > li.selected {
- background-color: #116cd6 !important;
-}
-afx-app-window[data-id = "antedit"] afx-antedit-ext-list-item button {
- height: 22px;
- width: 24px;
- padding: 0 !important;
-}
-afx-app-window[data-id = "antedit"] input[data-id="txt_ext_search"] {
- background-color: transparent;
- border-radius: 0;
- border-color: #333;
- color: white;
-}
\ No newline at end of file
diff --git a/Antedit/build/debug/main.js b/Antedit/build/debug/main.js
deleted file mode 100644
index 45d1e5d..0000000
--- a/Antedit/build/debug/main.js
+++ /dev/null
@@ -1 +0,0 @@
-var OS;!function(t){let e,i;!function(e){let i;!function(e){class i extends t.API.VFS.BaseFileHandle{constructor(t){super(""),this.path=`${t[0].path} -> ${t[1].path}`,this.cache=t,this.basename=`${t[0].basename} -> ${t[1].basename}`,this.info={type:"file",mime:void 0,size:0,name:this.basename,path:this.path},this.ready=!0}meta(){return new Promise(async(t,e)=>{try{await Promise.all([this.cache[0].meta(),this.cache[1].meta]),t({result:this.info,error:!1})}catch(t){e(t)}})}_rd(t){return new Promise(async(t,e)=>{try{this.cache[0].cache=await this.cache[0].read(),this.cache[1].cache=await this.cache[1].read(),t(this.cache)}catch(t){e(t)}})}_wr(t,e){return this.cache=e,new Promise((t,e)=>{t({result:!0,error:!1})})}setPath(t){}}e.DiffEditorFileHandle=i}(i=e.VFS||(e.VFS={}))}(e=t.API||(t.API={})),function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>{if(!this.currfile.dirty)return console.log("dirty",this.currfile.path),this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0)}),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let a=0;a(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(){this.currfile.cache=this.getValue(),this.currfile.write("text/plain").then(t=>{this.currfile.dirty=!1,this.currfile.text=this.currfile.basename,this.tabbar.update(void 0)}).catch(t=>this.app.error(__("Unable to save file: {0}",this.currfile.path),t))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write():this.saveAs()}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write()})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.openFile("Untitled".asFileHandle()),this.resetEditor()}isDirty(){return this.dirties().length>0}setTabbarCtxMenu(t,e){this.tabbar.contextmenuHandle=(i,a)=>(a.items=t,a.onmenuselect=t=>{if(e){const a=$(i.target).closest("afx-list-item");e(a[0],t.data.item.data)}},a.show(i))}}}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(e){class i extends t.application.BaseEditorModel{constructor(t,e,i){super(t,e,i)}resetEditor(){}getTexModel(){return{model:this.editor.getModel(),position:this.editor.getPosition()}}setTextModel(t){this.editor.setModel(t.model),t.position&&(this.editor.setPosition(t.position),this.editor.revealLineInCenter(t.position.lineNumber))}newTextModelFrom(t){if(Array.isArray(t.cache))return{model:{original:this.newTextModelFrom(t.cache[0]).model,modified:this.newTextModelFrom(t.cache[1]).model}};{if("Untitled"===t.path.toString())return{model:monaco.editor.createModel(t.cache,"textplain")};const e=monaco.Uri.parse(t.protocol+"://antedit/file/"+t.genealogy.join("/")),i=monaco.editor.getModel(e);return i?(i.setValue(t.cache),{model:i}):{model:monaco.editor.createModel(t.cache,void 0,e)}}}getModes(){return monaco.languages.getLanguages().map(t=>{const e=t;return t.aliases?e.text=t.aliases[0]:e.text=t.id,t})}setTheme(t){}setMode(t){if(this.editor==this._code_editor)monaco.editor.setModelLanguage(this.editor.getModel(),t.id);else for(const e of this.editor.getModel())monaco.editor.setModelLanguage(e,t.id);this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}get editor(){return Array.isArray(this.currfile.cache)?this._diff_editor:this._code_editor}editorSetup(t){this.code_container=$("").css("width","100%").css("height","100%"),this.diff_container=$("").css("width","100%").css("height","100%").css("display","none"),$(t).append(this.code_container),$(t).append(this.diff_container),this._code_editor=monaco.editor.create(this.code_container[0],{value:"",language:"textplain"}),this._diff_editor=monaco.editor.createDiffEditor(this.diff_container[0],{readOnly:!0}),i.modes||(i.modes={},monaco.languages.getLanguages().forEach(t=>{i.modes[t.id]=t}))}on(t,e){switch(t){case"input":this._code_editor.onDidChangeModelContent(e);break;case"focus":this._code_editor.onDidFocusEditorText(e),this._diff_editor.getOriginalEditor().onDidFocusEditorText(e),this._diff_editor.getModifiedEditor().onDidFocusEditorText(e);break;case"changeCursor":this._code_editor.onDidChangeCursorPosition(e),this._diff_editor.getOriginalEditor().onDidChangeCursorPosition(e),this._diff_editor.getModifiedEditor().onDidChangeCursorPosition(e)}}resize(){this.editor&&this.editor.layout()}focus(){Array.isArray(this.currfile.cache)?(this.code_container.hide(),this.diff_container.show()):(this.code_container.show(),this.diff_container.hide()),this.editor&&(this.editor.layout(),this.editor.focus())}getModeForPath(t){return{}}getEditorStatus(){let t=void 0;this.editor==this._code_editor?t=this.editor:(t=this.editor.getOriginalEditor(),this.editor.getModifiedEditor().hasTextFocus()&&(t=this.editor.getModifiedEditor()));const e=t.getPosition();let a=void 0;const s=t.getModel();return s&&(a=i.modes[s.getLanguageId()]),{row:e.lineNumber,column:e.column,line:s?s.getLineCount():0,langmode:{text:a?a.aliases[0]:"",mode:a},file:this.currfile.path}}getValue(){return this.editor==this._code_editor?this.editor.getValue():this.currfile.cache}setValue(t){this.editor==this._code_editor&&this.editor.setValue(t)}getEditor(){return this._code_editor}}e.MonacoEditorModel=i}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e,i;!function(t){let e;!function(t){class e extends t.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"afx-label",ref:"label"},{el:"p",ref:"desc",id:"ext-list-item-d-p"},{el:"p",id:"ext-list-item-b-p",children:[{el:"i",ref:"intall_status"},{el:"afx-button",ref:"btn_remove"},{el:"afx-button",ref:"btn_install"}]}]}}ondatachange(){const t=this.data;if(!t)return;const e=this.refs.label;e.iconclass="bi bi-puzzle",e.text=`${t.text} - v${t.version}`;const i=this.refs.desc;$(i).text(t.description);const a=this.refs.btn_install,s=this.refs.btn_remove;t.installed?($(s).show(),s.iconclass="bi bi-trash-fill",a.iconclass="bi bi-arrow-repeat",$(this.refs.intall_status).text(__("Installed: v{0} ",t.installed).__())):($(s).hide(),a.iconclass="fa bi-cloud-download-fill",$(this.refs.intall_status).text(" "))}init(){this.closable=!1,this.data={};const t=this.refs.btn_install,e=this.refs.btn_remove;t.onbtclick=t=>{this.data.download&&this.data.install_action&&this.data.install_action(this.data.download,t=>{this.data.installed=t,this.update(void 0)})},e.onbtclick=t=>{this.data.installed&&this.data.uninstall_action&&this.data.uninstall_action(this.data.name,()=>{delete this.data.installed,this.update(void 0)})}}reload(t){this.data=this.data}}t.define("afx-antedit-ext-list-item",e)}(e=t.tag||(t.tag={}))}(e=t.GUI||(t.GUI={})),function(e){class i extends e.BaseApplication{constructor(t){super("Antedit",t),this.currdir=void 0,this.diff_buffer=[void 0,void 0]}main(){this.extensions={},this.eum=new a,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.sidebar_container=this.find("sidebar-tab-container"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.extension_list_view=this.find("extension-list"),this.logger=new s(this.find("output-tab")),this.split_mode=!0,this.fileview.fetch=t=>new Promise((async function(e,i){let a;a="string"==typeof t?t.asFileHandle():t;try{const t=await a.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let e="Untitled".asFileHandle();this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(e=this.args[0].path.asFileHandle(),this.currdir=e.parent())),this.setting.recent||(this.setting.recent=[]),this.setting.extension_repos||(this.setting.extension_repos=["https://raw.githubusercontent.com/lxsang/antos-antedit-extensions/master/extensions.json"]);const i=this.find("wrapper");$(i).css("visibility","hidden"),monaco.editor.setTheme("vs-dark");const n=new t.application.MonacoEditorModel(this,this.find("left-tabbar"),this.find("left-editorarea")),o=new t.application.MonacoEditorModel(this,this.find("right-tabbar"),this.find("right-editorarea"));n.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,n)),o.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,o)),this.eum.add(n).add(o),this.eum.onstatuschange=t=>this.updateStatus(t),$(i).css("visibility","visible"),this.setup(),this.eum.active.openFile(e)}get tb_ctxmenu(){return[{text:"__(Close)",id:"close"},{text:"__(Close All)",id:"close-all"},{text:"__(Move to other side)",id:"mv-side"}]}tabbar_ctx_menu_handle(t,e,i){switch(e.id){case"close":if(!t)return;i.closeTab(t);break;case"close-all":i.closeAll();break;case"mv-side":if(!t)return;let e=this.eum.editors[0];i==e&&(e=this.eum.editors[1]),e.openFile(t.data),i.closeTab(t),0==this.split_mode&&this.toggleSplitMode()}}setup(){this.sidebar_container.selectedIndex=0,this.extension_list_view.itemtag="afx-antedit-ext-list-item",this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&(this.addRecent(t.data.path),"dir"!==t.data.type))return this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.fileview.contextmenuHandle=(t,e)=>{let i=this.fileview.selectedFile;const a=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"},{text:"__(Upload)",id:"upload"}];return i&&"file"===i.type&&(a.push({text:"__(Select for compare)",id:"diff-org"}),a.push({text:"__(Compare with selected)",id:"diff-mod"}),a.push({text:"__(Open to right)",id:"open-right"})),e.items=a,e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)},this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.fileview.ondragndrop=t=>{if(!t.data.from||!t.data.to)return;const e=t.data.from[0].data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(a){const s=i,n=e.parent().path;s.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1);const t={name:"Editor",text:__("Editor")},e={name:"langmode",text:__("Change language mode"),shortcut:"CTRL-K"};this.eum.addAction(t,e,async t=>{try{const t=await this.openDialog("SelectionDialog",{title:__("Select language"),data:this.eum.active.getModes()});this.eum.active.setMode(t)}catch(t){console.log(t)}}),$(this.find("txt_ext_search")).keyup(t=>this.extension_search(t)),this.loadExtensionMetaData(),this.toggleSideBar(),this.toggleSplitMode(),this.applyAllSetting()}extension_search(t){let e;const i=this.find("txt_ext_search");switch(t.which){case 37:return t.preventDefault();case 38:return this.extension_list_view.selectPrev(),t.preventDefault();case 39:return t.preventDefault();case 40:return this.extension_list_view.selectNext(),t.preventDefault();case 13:return t.preventDefault();default:var a=i.value,s=[];if(2===a.length)return void(this.extension_list_view.data=this.extension_meta_data);if(a.length<3)return;var n=new RegExp(a,"i");for(e in this.extension_meta_data)this.extension_meta_data[e].text.match(n)&&s.push(this.extension_meta_data[e]);this.extension_list_view.data=s}}refreshExtensionRepositories(){const t=[],e=this.meta().path+"/extensions/extensions.json";for(let i of[e].concat(this.setting.extension_repos))t.push(i.asFileHandle().read("json"));Promise.all(t).then(t=>{const e={};for(let i of t.shift())e[i.name]=i;this.extension_meta_data=[];for(let a of t)for(let t of a)e[t.name]&&(t.installed=e[t.name].version),t.install_action=(e,a)=>{new i.extensions.EditorExtensionMaker(this).installZip(e).then(()=>{this.loadExtensionMetaData(),a&&a(t.version),this.notify(__("Extension '{0}' installed",t.text))}).catch(e=>{this.error(__("Unable to install '{0}': {1}",t.text,e.toString()),e)})},t.uninstall_action=(t,e)=>{new i.extensions.EditorExtensionMaker(this).uninstall(t).then(()=>{this.loadExtensionMetaData(),e&&e(),this.notify(__("Extension '{0}' uninstalled",t))}).catch(e=>{this.error(__("Unable to uninstall '{0}': {1}",t,e.toString()),e)})},this.extension_meta_data.push(t);this.extension_list_view.data=this.extension_meta_data}).catch(t=>{this.error(__("Unable to read extension from repositories: {0}",t.toString()),t)})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row,t.column,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path,this.refreshExtensionRepositories()):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&this.showBottomBar(!0),this.bottombar.selectedIndex=0}openDiff(e){const i=new t.API.VFS.DiffEditorFileHandle(e);this.eum.active.openFile(i)}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){this.setting.showBottomBar=t,t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.showBottomBar(!this.setting.showBottomBar)}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let a=this.fileview.selectedFile,s=this.currdir;switch(a&&"dir"===a.type&&(s=a.path.asFileHandle()),a&&"file"===a.type&&(s=a.path.asFileHandle().parent()),i.id){case"new":if(!s)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${s.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),__e(t))}});break;case"newdir":if(!s)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await s.mk(t),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",s.path),__e(t))}});break;case"rename":if(!a)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:a.filename}).then(async t=>{if(t!==a.filename){a=a.path.asFileHandle(),s=a.parent();try{return await a.move(`${s.path}/${t}`),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to rename: {0}",a.path),__e(t))}}});break;case"delete":if(!a)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",a.filename)}).then(async t=>{if(t){a=a.path.asFileHandle(),s=a.parent();try{return await a.remove(),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to delete: {0}",a.path),__e(t))}}});break;case"upload":if(!s)return;s.upload().then(t=>(this.notify(__("File uploaded to: {0}",s.path)),this.fileview.update(s.path))).catch(t=>this.error(__("Unable to upload file: {e}",t.toString()),__e(t)));break;case"diff-org":if(!a)return;this.diff_buffer[0]=a.path.asFileHandle();break;case"diff-mod":if(!a)return;if(!this.diff_buffer[0])return;this.diff_buffer[1]=a.path.asFileHandle(),this.openDiff(this.diff_buffer);break;case"open-right":if(!a||"dir"===a.type)return;0==this.split_mode&&this.toggleSplitMode(),this.eum.editors[1].openFile(a.path.asFileHandle())}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.unshift(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t]&&this.extensions[t].cleanup&&this.extensions[t].cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}loadExtensionMetaData(){this.loadExtensionMetaFromFile(this.meta().path+"/extensions/extensions.json").catch(t=>this.error(__("Cannot load extension meta data"),t))}loadExtensionMetaFromFile(t){return new Promise((e,i)=>{t.asFileHandle().read("json").then(t=>{for(let e of t)for(let t of e.actions)this.eum.addAction(e,t,(t,i)=>{this.loadAndRunExtensionAction(t,i,e.root)});e()}).catch(t=>{i(__e(t))})})}loadAndRunExtensionAction(t,e,a){if(i.extensions[t])this.runExtensionAction(t,e);else{let i=`${this.meta().path}/extensions/${t}/main.js`;a&&(i=a+"/main.js"),this._api.requires(i,!0).then(()=>this.runExtensionAction(t,e)).catch(e=>this.error(__("unable to load extension: {0}",t),e))}}runExtensionAction(t,e){if(!this.extensions[t]){if(!i.extensions[t])return this.error(__("Unable to find extension: {0}",t));this.extensions[t]=new i.extensions[t](this)}if(!this.extensions[t][e])return this.error(__("Unable to find action: {0}",e));this.extensions[t].preload().then(()=>this.extensions[t][e]()).catch(t=>this.error(__("Unable to preload extension"),t))}}e.Antedit=i;class a{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}addAction(t,e,i){const a={id:`${t.name}:${e.name}`,label:`${t.text.__()}: ${e.text.__()}`,keybindings:[],precondition:null,keybindingContext:null,contextMenuGroupId:t.name,run:()=>i(t.name,e.name)};if(e.shortcut){const t=e.shortcut.split("-");let i=0;for(const e of t)switch(e){case"CTRL":i|=monaco.KeyMod.CtrlCmd;break;case"ALT":i|=monaco.KeyMod.Alt;break;case"SHIFT":i|=monaco.KeyMod.Shift;break;case"SUPPER":i|=monaco.KeyMod.WinCtrl;break;default:const t="Key"+e;monaco.KeyCode[t]?i|=monaco.KeyCode[t]:i=0}0!=i&&a.keybindings.push(i)}for(let t of this.models){const e=t.getEditor();e.getAction(a.id)||e.addAction(a)}}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class s{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let a=$("").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();a.text(`[${i}]: ${e.__()}`)}else a.text(e.__());$(this.target).append(a),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){t.match(/warn/i)?this.log("warn",t,!1):t.match(/error/i)?this.log("error",t,!1):this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=s,i.dependencies=["pkg://MonacoCore/path.js","pkg://MonacoCore/bundle/app.bundle.js"]}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){class e{constructor(t,e){this.app=e,this.name=t}preload(){return t.API.require(t.application.Antedit.extensions[this.name].dependencies)}basedir(){return`${this.app.meta().path}/extensions/${this.name}`}notify(t){return this.app.notify(t)}error(t,e){return this.app.error(t,e)}logger(){return this.app.setting.showBottomBar?this.app.showOutput(!1):this.app.showOutput(!0),this.app.logger}metadata(e){return new Promise((i,a)=>{if(!this.app.currdir)return a(t.API.throwe(__("Current folder is not found")));`${this.app.currdir.path}/${e}`.asFileHandle().read("json").then(t=>{!t.root&&this.app.currdir&&(t.root=this.app.currdir.path),i(t)}).catch(s=>{this.app.openDialog("FileDialog",{title:__("Select build directory"),root:this.app.currdir.path,mimes:["dir"]}).then(t=>{`${t.file.path}/${e}`.asFileHandle().read("json").then(e=>{e.root||(e.root=t.file.path),i(e)}).catch(t=>a(t))}).catch(e=>a(t.API.throwe(__("Unable to read meta-data"))))})})}}e.dependencies=[],t.application.Antedit.extensions={},t.application.Antedit.EditorBaseExtension=e,t.application.Antedit.extensions.EditorExtensionMaker=class extends e{constructor(t){super("EditorExtensionMaker",t)}create(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(New extension at)",file:{basename:__("ExtensionName")},mimes:["dir"]}).then(t=>this.mktpl(t.file.path,t.name))}build(e){this.logger().clear(),this.metadata("extension.json").then(async i=>{try{const a=await t.API.VFS.cat(i.javascripts.map(t=>`${i.root}/${t}`),"");await(i.root+"/build/debug/main.js").asFileHandle().setCache(a).write("text/plain"),await(i.root+"/build/debug/extension.json").asFileHandle().setCache(i.meta).write("object"),await t.API.VFS.copy(i.copies.map(t=>`${i.root}/${t}`),i.root+"/build/debug"),this.logger().info(__("Files generated in {0}",i.root+"/build/debug")),e&&e()}catch(t){return this.logger().error(__("Unable to build extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}run(){this.logger().clear(),this.metadata("extension.json").then(async e=>{if(!e||!e.meta||!e.meta.name)return this.logger().error(__("Invalid extension meta-data"));try{const i=e.root+"/build/debug/main.js";t.API.shared[i]&&delete t.API.shared[i],await t.API.requires(i),this.app.extensions[e.meta.name]&&this.app.extensions[e.meta.name].cleanup&&this.app.extensions[e.meta.name].cleanup(),this.app.extensions[e.meta.name]=new t.application.Antedit.extensions[e.meta.name](this.app);for(let t of e.meta.actions)this.app.eum.addAction(e.meta,t,(t,i)=>{this.app.loadAndRunExtensionAction(t,i,e.root+"/build")});this.app.eum.active.getEditor().trigger(e.meta.name,"editor.action.quickCommand")}catch(t){return this.logger().error(__("Unable to run extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}release(){this.logger().clear(),this.metadata("extension.json").then(async e=>{this.build(async()=>{try{await t.API.VFS.mkar(e.root+"/build/debug",`${e.root}/build/release/${e.meta.name}.zip`),this.logger().info(__("Archive created at {0}",`${e.root}/build/release/${e.meta.name}.zip`))}catch(t){return this.logger().error(__("Unable to create archive: {0}",t.stack))}})}).catch(t=>this.logger().error(__("Unable to read meta-data: {0}",t.stack)))}install(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(Select extension archive)",mimes:[".*/zip"]}).then(async t=>{try{return await this.installZip(t.file.path),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(t){return this.logger().error(__("Unable to install extension: {0}",t.stack))}})}installFromURL(){this.logger().clear(),this.app.openDialog("PromptDialog",{title:__("Enter URI"),label:__("Please enter extension URI:")}).then(async t=>{if(t)try{return await this.installZip(t),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(e){return this.app.error(__("Unable to install extension: {0}",t))}})}mktpl(e,i){const a=`${e}/${i}`,s=[a,a+"/build",a+"/build/release",a+"/build/debug"],n=[["main.tpl",`${a}/${i}.js`],["meta.tpl",a+"/extension.json"]];t.API.VFS.mkdirAll(s,!0).then(async()=>{try{return await t.API.VFS.mktpl(n,this.basedir(),t=>t.format(i,`${e}/${i}`)),this.app.currdir=a.asFileHandle(),this.app.toggleSideBar(),this.app.eum.active.openFile(`${a}/${i}.js`.asFileHandle())}catch(t){return this.logger().error(__("Unable to create extension template: {0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to create extension directories: {0}",t.stack)))}uninstall(t){return new Promise(async(e,i)=>{try{const i=this.app.meta().path+"/extensions",a=(i+"/extensions.json").asFileHandle(),s=await a.read("json");let n=void 0,o=void 0;for(let e in s)if(s[e].name===t){n=s[e],o=e;break}if(void 0===n)return e();await`${i}/${t}`.asFileHandle().remove(),s.splice(o,1),a.cache=s,await a.write("object"),e()}catch(t){i(t)}})}installZip(e){return new Promise(async(i,a)=>{try{await t.API.requires("os://scripts/jszip.min.js");const a=await e.asFileHandle().read("binary"),s=await JSZip.loadAsync(a),n=await s.file("extension.json").async("uint8array"),o=JSON.parse(new TextDecoder("utf-8").decode(n));await this.uninstall(o.name);const r=this.ext_dir(o.name),l=[r],h=[];for(let t in s.files)s.files[t].dir?l.push(r+"/"+t):"extension.json"!=t&&h.push(t);l.length>0?(await t.API.VFS.mkdirAll(l,!0),await this.installFiles(h,s,o)):await this.installFiles(h,s,o),i()}catch(t){a(__e(t))}})}ext_dir(t){return`${this.app.meta().path}/extensions/${t}`}installFiles(t,e,i){return 0===t.length?this.installMeta(i):new Promise(async(a,s)=>{try{const n=t.splice(0,1)[0],o=`${this.ext_dir(i.name)}/${n}`,r=await e.file(n).async("uint8array"),l=await o.asFileHandle().setCache(new Blob([r],{type:"octet/stream"})).write("text/plain");if(l.error)return s(l.error);await this.installFiles(t,e,i),a()}catch(t){s(__e(t))}})}installMeta(t){return new Promise(async(e,i)=>{const a=(this.ext_dir("")+"/extensions.json").asFileHandle();try{const s=await a.read("json"),n=[];for(let t of s)n.push(t.name);const o=n.indexOf(t.name);o>=0&&s.splice(o,1),s.push(t);try{return await a.setCache(s).write("object"),e()}catch(t){return i(__e(t))}}catch(s){try{return await a.setCache([t]).write("object"),e()}catch(t){return i(__e(t))}}})}}}(OS||(OS={}));
\ No newline at end of file
diff --git a/Antedit/build/debug/package.json b/Antedit/build/debug/package.json
deleted file mode 100644
index 2c22ce3..0000000
--- a/Antedit/build/debug/package.json
+++ /dev/null
@@ -1,89 +0,0 @@
-{
- "pkgname": "Antedit",
- "app": "Antedit",
- "name": "Antos Editor",
- "description": "Antos text/code editor",
- "info": {
- "author": "Xuan Sang LE",
- "email": "mrsang@iohub.dev"
- },
- "version": "0.2.1-b",
- "category": "Development",
- "iconclass": "bi bi-journal-code",
- "mimes": [
- "text/.*",
- "[^/]*/json.*",
- "[^/]*/.*ml",
- "[^/]*/javascript",
- "dir"
- ],
- "dependencies": [
- "MonacoCore@0.33.0-r"
- ],
- "locale": {
- "en_GB": {
- "Output": "Output",
- "Close tab": "Close tab",
- "Close without saving ?": "Close without saving ?",
- "Unable to open: {0}": "Unable to open: {0}",
- "Unable to save file: {0}": "Unable to save file: {0}",
- "Save as": "Save as",
- "New extension at": "New extension at",
- "Select extension archive": "Select extension archive",
- "Current folder is not found": "Current folder is not found",
- "Select build directory": "Select build directory",
- "Unable to read meta-data": "Unable to read meta-data",
- "ExtensionName": "ExtensionName",
- "Files generated in {0}": "Files generated in {0}",
- "Unable to build extension:{0}": "Unable to build extension:{0}",
- "Unable to read meta-data:{0}": "Unable to read meta-data:{0}",
- "Invalid extension meta-data": "Invalid extension meta-data",
- "Unable to run extension:{0}": "Unable to run extension:{0}",
- "Archive created at {0}": "Archive created at {0}",
- "Unable to read meta-data: {0}": "Unable to read meta-data: {0}",
- "Extension installed": "Extension installed",
- "Unable to install extension: {0}": "Unable to install extension: {0}",
- "Enter URI": "Enter URI",
- "Please enter extension URI:": "Please enter extension URI:",
- "Unable to create extension directories: {0}": "Unable to create extension directories: {0}",
- "New file": "New file",
- "New folder": "New folder",
- "Rename": "Rename",
- "Delete": "Delete",
- "File name": "File name",
- "Folder name": "Folder name",
- "Quit": "Quit",
- "View": "View",
- "Toggle bottom bar": "Toggle bottom bar",
- "Toggle split view": "Toggle split view",
- "Unable to move file/folder": "Unable to move file/folder",
- "Editor": "Editor",
- "Change language mode": "Change language mode",
- "Select language": "Select language",
- "Unable to disable split view: Please save changes of modified files on the right panel": "Unable to disable split view: Please save changes of modified files on the right panel",
- "File": "File",
- "New": "New",
- "Open Recent": "Open Recent",
- "Open": "Open",
- "Open Folder": "Open Folder",
- "Save": "Save",
- "Fail to create: {0}": "Fail to create: {0}",
- "Fail to rename: {0}": "Fail to rename: {0}",
- "Fail to delete: {0}": "Fail to delete: {0}",
- "Open file": "Open file",
- "Open folder": "Open folder",
- "Cannot load extension meta data": "Cannot load extension meta data",
- "unable to load extension: {0}": "unable to load extension: {0}",
- "Unable to find extension: {0}": "Unable to find extension: {0}",
- "Unable to find action: {0}": "Unable to find action: {0}",
- "Unable to preload extension": "Unable to preload extension",
- "Example action": "Example action",
- "New Extension": "New Extension",
- "Build": "Build",
- "Run": "Run",
- "Build release": "Build release",
- "Install extension from file": "Install extension from file",
- "Install extension from URL": "Install extension from URL"
- }
- }
-}
\ No newline at end of file
diff --git a/Antedit/build/debug/scheme.html b/Antedit/build/debug/scheme.html
deleted file mode 100644
index e410cc4..0000000
--- a/Antedit/build/debug/scheme.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Antedit/build/release/Antedit.zip b/Antedit/build/release/Antedit.zip
index a352cc9..f3bef56 100644
Binary files a/Antedit/build/release/Antedit.zip and b/Antedit/build/release/Antedit.zip differ
diff --git a/Antedit/package.json b/Antedit/package.json
index 2c22ce3..4f032b8 100644
--- a/Antedit/package.json
+++ b/Antedit/package.json
@@ -7,7 +7,7 @@
"author": "Xuan Sang LE",
"email": "mrsang@iohub.dev"
},
- "version": "0.2.1-b",
+ "version": "0.2.2-b",
"category": "Development",
"iconclass": "bi bi-journal-code",
"mimes": [
diff --git a/Antedit/ts/BaseEditorModel.ts b/Antedit/ts/BaseEditorModel.ts
index d5fdc10..6440a35 100644
--- a/Antedit/ts/BaseEditorModel.ts
+++ b/Antedit/ts/BaseEditorModel.ts
@@ -191,7 +191,6 @@ namespace OS {
return false;
}*/
if (!this.currfile.dirty) {
- console.log("dirty", this.currfile.path);
this.currfile.dirty = true;
this.currfile.text += "*";
return this.tabbar.update(undefined);
@@ -268,7 +267,8 @@ namespace OS {
this.currfile.selected = false;
file.selected = true;
//console.log cnt
- this.tabbar.push(file);
+ const el = this.tabbar.push(file);
+ this.app.trigger("tab-opened", el);
}
/**
diff --git a/Antedit/ts/main.ts b/Antedit/ts/main.ts
index 0f19539..b3b4ea2 100644
--- a/Antedit/ts/main.ts
+++ b/Antedit/ts/main.ts
@@ -471,7 +471,18 @@ namespace OS {
this.bindKey("ALT-F", () => this.menuAction("opendir"));
this.bindKey("CTRL-S", () => this.menuAction("save"));
this.bindKey("ALT-W", () => this.menuAction("saveas"));
-
+
+ const list_container = $(".list-container", this.find("editor-main-container"));
+ list_container.each((i,el) => {
+ $(el).on("wheel", (evt)=>{
+ el.scrollLeft += (evt.originalEvent as WheelEvent).deltaY;
+ });
+ });
+ this.on("tab-opened", (el) => {
+ const container = $(el).closest(".list-container");
+ if(container && container[0])
+ container[0].scrollLeft = container[0].scrollWidth;
+ });
this.fileview.ondragndrop = (e) => {
if(!e.data.from || !e.data.to)
{
diff --git a/GitGrapth/LibGitGraph.ts b/GitGraph/LibGitGraph.ts
similarity index 93%
rename from GitGrapth/LibGitGraph.ts
rename to GitGraph/LibGitGraph.ts
index 36b807b..4dd5dd3 100644
--- a/GitGrapth/LibGitGraph.ts
+++ b/GitGraph/LibGitGraph.ts
@@ -85,18 +85,29 @@ namespace OS {
{
this.options[k] = option[k];
}
- this.current_y_offset = this.options.y_offset;
- this.init_graph();
+ if(this.options.target)
+ {
+ $(this.options.target)
+ .addClass("git_grapth_container")
+ .css("overflow-y", "auto")
+ .css("overflow-x", "hidden")
+ .css("display", "block")
+ .css("position", "relative");
+ }
}
set base_dir(v: VFS.BaseFileHandle)
{
this._base_dir = v;
- this.render_next();
+ if(v)
+ {
+ this.init_graph();
+ this.render_next();
+ }
}
private gen_color(x:number): string
{
- let n = x + 11;
+ let n = x + 10;
const rgb = [0, 0, 0];
for (let i = 0; i < 24; i++) {
rgb[i%3] <<= 1;
@@ -154,11 +165,17 @@ namespace OS {
{
return this.error(API.throwe("Target element is undefined"));
}
- $(this.options.target)
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("display", "block")
- .css("position", "relative");
+ this.current_y_offset = this.options.y_offset;
+ this.lines_data = [];
+ this.commits = {};
+ this.oldest_commit_date = undefined;
+ this.svg_element = undefined;
+ this.commits_list_element = undefined;
+ this.load_more_el = undefined;
+ this.commit_detail_el = undefined;
+ this.current_head = undefined;
+
+ $(this.options.target).empty();
this.svg_element = this.make_svg_el("svg",{
width: this.options.x_offset,
height: this.options.y_offset
@@ -169,7 +186,6 @@ namespace OS {
.css("left", "0")
//s.css("z-index", 10)
.css("top", "0");
- $(this.options.target).empty();
this.options.target.appendChild(this.svg_element);
const div = $("")
.css("position", "absolute")
@@ -206,6 +222,10 @@ namespace OS {
}
private render_next()
{
+ if(this._base_dir == undefined)
+ {
+ return;
+ }
this.load(this.oldest_commit_date)
.then((data: CommitData[]) =>
{
@@ -429,14 +449,15 @@ namespace OS {
.on("click",e => {
if(this._on_open_diff)
{
+ const parent_comit = commit.hashes.parents.split(" ")[0];
Promise.all([
- this.get_file(arr[1], `${commit.hashes.commit}^`),
+ this.get_file(arr[1], `${parent_comit}`),
this.get_file(arr[1], commit.hashes.commit)
])
.then((values) => {
// create the file
const files = values.map((content, index) =>{
- const file = `mem://${commit.hashes.commit.slice(0,8)}${index==0?"^":""}/${arr[1]}`.asFileHandle();
+ const file = `mem://${(index == 0 ?parent_comit:commit.hashes.commit).slice(0,8)}/${arr[1]}`.asFileHandle();
file.cache = content;
file.info.mime = "text/plain";
return file;
diff --git a/GitGraph/README.md b/GitGraph/README.md
new file mode 100644
index 0000000..062a544
--- /dev/null
+++ b/GitGraph/README.md
@@ -0,0 +1,21 @@
+# LibGitGraph
+Git grapth visualization API for AntOS application.
+
+The visualization can be easily integrated to an AntOS application, example:
+
+```typescript
+const graph = new API.LibGitGraph({
+ target: this.find("git-graph");
+});
+graph.on_open_diff = (files) => {
+ console.log(files);
+}
+graph.base_dir = "home://workspace/repo-git".asFileHandle();
+```
+
+## Change logs:
+- v0.1.4-b: Fetch changes on a commit based on current commit and its left most parent commit
+- v0.1.3-b: Support open Git repo with open with dialog
+- v0.1.2-b: fix init bug
+- v0.1.1-b: add class to container element
+- v0.1.0-b: Initial version
\ No newline at end of file
diff --git a/GitGrapth/api/api.lua b/GitGraph/api/api.lua
similarity index 100%
rename from GitGrapth/api/api.lua
rename to GitGraph/api/api.lua
diff --git a/GitGrapth/build.json b/GitGraph/build.json
similarity index 98%
rename from GitGrapth/build.json
rename to GitGraph/build.json
index f45153b..e6c775b 100644
--- a/GitGrapth/build.json
+++ b/GitGraph/build.json
@@ -4,7 +4,7 @@
"clean": {
"jobs": [
{
- "name": "vfs-rm",
+ "name": "vfs-rm_no_error",
"data": ["build/debug","build/release"]
}
]
diff --git a/GitGraph/build/debug/README.md b/GitGraph/build/debug/README.md
new file mode 100644
index 0000000..062a544
--- /dev/null
+++ b/GitGraph/build/debug/README.md
@@ -0,0 +1,21 @@
+# LibGitGraph
+Git grapth visualization API for AntOS application.
+
+The visualization can be easily integrated to an AntOS application, example:
+
+```typescript
+const graph = new API.LibGitGraph({
+ target: this.find("git-graph");
+});
+graph.on_open_diff = (files) => {
+ console.log(files);
+}
+graph.base_dir = "home://workspace/repo-git".asFileHandle();
+```
+
+## Change logs:
+- v0.1.4-b: Fetch changes on a commit based on current commit and its left most parent commit
+- v0.1.3-b: Support open Git repo with open with dialog
+- v0.1.2-b: fix init bug
+- v0.1.1-b: add class to container element
+- v0.1.0-b: Initial version
\ No newline at end of file
diff --git a/GitGrapth/build/debug/api/api.lua b/GitGraph/build/debug/api/api.lua
similarity index 100%
rename from GitGrapth/build/debug/api/api.lua
rename to GitGraph/build/debug/api/api.lua
diff --git a/GitGraph/build/debug/libgitgraph.js b/GitGraph/build/debug/libgitgraph.js
new file mode 100644
index 0000000..9c6438e
--- /dev/null
+++ b/GitGraph/build/debug/libgitgraph.js
@@ -0,0 +1 @@
+var OS;!function(t){let s;!function(s){s.LibGitGraph=class{constructor(t){this._base_dir=void 0,this.lines_data=[],this.commits={},this.oldest_commit_date=void 0,this.svg_element=void 0,this.commits_list_element=void 0,this.load_more_el=void 0,this.commit_detail_el=void 0,this.current_head=void 0,this._on_open_diff=void 0,this.options={commits_per_page:100,x_offset:24,y_offset:24,target:void 0,popup_height:250};for(const s in t)this.options[s]=t[s];this.options.target&&$(this.options.target).addClass("git_grapth_container").css("overflow-y","auto").css("overflow-x","hidden").css("display","block").css("position","relative")}set base_dir(t){this._base_dir=t,t&&(this.init_graph(),this.render_next())}gen_color(t){let s=t+10;const e=[0,0,0];for(let t=0;t<24;t++)e[t%3]<<=1,e[t%3]|=1&s,s>>=1;return"#"+e.reduce((t,s)=>(s>15?s.toString(16):"0"+s.toString(16))+t,"")}meta(){return t.setting.system.packages.GitGraph}call(t){return new Promise(async(e,i)=>{t.args.base_dir=this._base_dir.path;let o={path:this.meta().path+"/api/api.lua",parameters:t},a=await s.apigateway(o,!1);a.error?i(s.throwe(__("LibGitGrapth server call error: {0}",a.error))):e(a.result)})}load(t){let s={action:"log",args:{n_commits:this.options.commits_per_page.toString(),before:t||null}};return this.call(s)}error(s){t.announcer.oserror(__("GitGraph error: {0}",s.toString()),s)}set on_open_diff(t){this._on_open_diff=t}init_graph(){if(!this.options.target)return this.error(s.throwe("Target element is undefined"));this.current_y_offset=this.options.y_offset,this.lines_data=[],this.commits={},this.oldest_commit_date=void 0,this.svg_element=void 0,this.commits_list_element=void 0,this.load_more_el=void 0,this.commit_detail_el=void 0,this.current_head=void 0,$(this.options.target).empty(),this.svg_element=this.make_svg_el("svg",{width:this.options.x_offset,height:this.options.y_offset}),$(this.svg_element).css("display","block").css("position","absolute").css("left","0").css("top","0"),this.options.target.appendChild(this.svg_element);const t=$("").css("position","absolute").css("left","0").css("top","0").css("width","100%").css("padding-top",this.options.y_offset/2+"px");this.commits_list_element=t[0],this.options.target.appendChild(this.commits_list_element);const e=$("").css("height",this.options.y_offset+"px").css("display","block").css("padding","0").css("margin","0").css("line-height",this.options.y_offset+"px").css("vertical-align","middle");e.addClass("git_grapth_load_more"),e.on("click",t=>this.render_next()),e.text(__("More").__()),this.load_more_el=e[0],this.commits_list_element.appendChild(this.load_more_el);const i=$("").css("position","absolute").css("top","0").css("height",this.options.popup_height+"px").css("display","none").css("user-select","text").addClass("git_grapth_commit_detail");this.commit_detail_el=i[0],this.options.target.appendChild(this.commit_detail_el)}render_next(){null!=this._base_dir&&this.load(this.oldest_commit_date).then(t=>{this.oldest_commit_date&&t.shift(),this.draw_graph(t)}).catch(t=>this.error(t))}make_svg_el(t,s){const e=document.createElementNS("http://www.w3.org/2000/svg",t);for(var i in s)e.setAttribute(i,s[i]);return e}max_line_off_x(){return 0==this.lines_data.length?0:Math.max.apply(Math,this.lines_data.map(t=>t.x_offset))}update_line_data(t,s){const e=t.hashes.parents.split(" "),i=this.lines_data.filter(s=>s.next_commit==t.hashes.commit);let o={src:[],dest:void 0};if(0===i.length){let i={next_commit:e[0],x_offset:this.max_line_off_x()+this.options.x_offset,current_commit:t.hashes.commit,beginning:!0,y_offset:s,color:this.gen_color(this.lines_data.length)};this.lines_data.push(i),o.dest=i}else{let a=Math.min.apply(Math,i.map(t=>t.x_offset)),_=void 0;for(let n of i)n.x_offset==a?(_=n,_.next_commit=e[0],_.current_commit=t.hashes.commit,_.y_offset=s):(this.lines_data.splice(this.lines_data.indexOf(n),1),o.src.push(n));o.dest=_}if(2===e.length){let i=void 0;i=this.lines_data.filter(t=>t.next_commit==e[1])[0],i?i.y_offset=s+this.options.y_offset:(i={next_commit:e[1],x_offset:this.max_line_off_x()+this.options.x_offset,current_commit:t.hashes.commit,beginning:!0,y_offset:s+this.options.y_offset,color:this.gen_color(this.lines_data.length)},this.lines_data.push(i)),o.src.push(i)}return o}draw_line(t,s,e,i,o,a){let _={stroke:o,fill:"none","stroke-width":1.5};if(a&&(_["stroke-width"]=a),t==e)_.d=`M ${t},${s} L ${e},${i}`;else{let o=t,a=s,n=e,h=i,l=(Math.abs(n-o),Math.abs(h-a));s").css("display","block");return e[0].innerHTML=`${t.__()}: ${s}`,e[0]}open_popup(s){const e=s.domel;if(!e)return;$(this.commit_detail_el).empty();const i=$(e).position(),o=this.svg_element.getBBox(),a=o.x+o.width+this.options.x_offset/2,_=this.make_svg_el("svg",{width:a-s.cx+5,height:this.options.y_offset});$(_).css("display","block").css("position","absolute").css("left","0").css("top","-2px"),_.appendChild(this.draw_line(0,this.options.y_offset/2,a-s.cx,this.options.y_offset/2,s.color)),$(this.commit_detail_el).css("border","2px solid "+s.color).css("color",s.color).append($("").css("position","absolute").css("height",this.options.y_offset).css("left",s.cx-a).css("padding-left",a-s.cx).append(_).append($("").text("[X]").css("cursor","pointer")).addClass("git_grapth_commit_detail_ctrl").on("click",t=>{$(this.commit_detail_el).css("display","none").empty()}));const n=$("").css("display","block").css("overflow-y","auto").css("overflow-x","hidden").css("flex","1").css("border-right","1px solid "+s.color).addClass("git_grapth_commit_detail_left"),h=$("").css("display","block").css("overflow-y","auto").css("overflow-x","hidden").css("flex","1").addClass("git_grapth_commit_detail_right");n.append(this.gen_commit_data_header(__("Commit"),s.hashes.commit)),n.append(this.gen_commit_data_header(__("Parents"),s.hashes.parents)),n.append(this.gen_commit_data_header(__("Author"),`${s.committer.name} <${s.committer.email}>`)),n.append(this.gen_commit_data_header(__("Date"),new Date(s.committer.date).toDateString())),n.append($("").css("white-space","pre-wrap").text(s.message)),this.commit_detail_el.appendChild(n[0]),this.commit_detail_el.appendChild(h[0]),this.list_file(s.hashes.commit).then(e=>{const i=$("");$.each(e,(e,o)=>{const a=o.split("\t"),_=$(""),n=$("").css("cursor","pointer").addClass("git_graph_file_"+a[0].toLowerCase()).on("click",e=>{if(this._on_open_diff){const e=s.hashes.parents.split(" ")[0];Promise.all([this.get_file(a[1],""+e),this.get_file(a[1],s.hashes.commit)]).then(t=>{const i=t.map((t,i)=>{const o=`mem://${(0==i?e:s.hashes.commit).slice(0,8)}/${a[1]}`.asFileHandle();return o.cache=t,o.info.mime="text/plain",o});this._on_open_diff(i)}).catch(e=>{t.announcer.oserror(__("Unable to fetch diff of {0}: {1}",s.hashes.commit,e.toString()),e)})}});n.text(a[1]),i.append(_.append(n))}),h.append(i)}).catch(s=>t.announcer.oserror(__("Unable to get commit changes: {0}",s.toString()),s)),$(this.commit_detail_el).css("top",i.top).css("left",a).css("display","flex").css("width",`calc(100% - ${a+this.options.x_offset}px)`).css("fflex-direction","row");const l=this.commit_detail_el.getBoundingClientRect().bottom-this.options.target.getBoundingClientRect().bottom;l>0&&(this.options.target.scrollTop+=l+10)}render_commit(t,s){let e=!1;const i=$("").css("padding","0").css("margin","0").css("display","block").css("height",this.options.y_offset+"px").css("line-height",this.options.y_offset+"px").css("color",s).css("vertical-align","middle").css("white-space","nowrap").css("overflow","hidden");i.addClass("git_graph_commit_message");let o=`${t.hashes.commit.slice(0,8)} `;t.branches=[];for(const s of t.extra.split(",").map(t=>t.trim()).filter(t=>""!=t)){let a=s.match(/HEAD -> (.*)/i);a&&2==a.length?(o+=`${a[1]} `,i.addClass("git_graph_commit_current_head"),e=!0,t.branches.push(a[1]),this.current_head=t):(a=s.match(/tag: (.*)/i))?o+=`${a[1]} `:(o+=`${s} `,t.branches.push(s))}return o+=`${t.message.split("\n")[0]} `,o+=`${t.committer.name} `,o+=`${new Date(t.committer.date).toDateString()}`,i[0].innerHTML=o,i.on("click",s=>{this.open_popup(t)}),this.commits_list_element.insertBefore(i[0],this.load_more_el),t.domel=i[0],e}draw_graph(t){for(const s of t){if(this.oldest_commit_date=s.committer.date,s.extra.includes("refs/stash"))continue;this.commits[s.hashes.commit]=s;let t=this.update_line_data(s,this.current_y_offset),e=t.src;for(const s of e.filter(s=>s.x_offset!=t.dest.x_offset))this.svg_element.appendChild(this.draw_line(t.dest.x_offset,t.dest.y_offset,s.x_offset,s.y_offset,s.color));this.lines_data.sort((t,s)=>t.x_offset-s.x_offset);let i=this.options.x_offset;for(const t of this.lines_data)t.beginning&&t.y_offset>this.current_y_offset||(t.y_offset=this.current_y_offset,t.beginning||(t.x_offset>i?(this.svg_element.appendChild(this.draw_line(t.x_offset,t.y_offset-this.options.y_offset,t.x_offset-this.options.x_offset,t.y_offset,t.color)),t.x_offset=i):this.svg_element.appendChild(this.draw_line(t.x_offset,t.y_offset-this.options.y_offset,t.x_offset,t.y_offset,t.color))),i+=this.options.x_offset,t.beginning=!1);let o={cx:t.dest.x_offset,cy:t.dest.y_offset,r:4,fill:t.dest.color,stroke:"black","stroke-width":0};this.render_commit(s,t.dest.color)&&(o.r=1.5*o.r),s.cx=o.cx,s.color=o.fill;const a=this.make_svg_el("circle",o);this.svg_element.appendChild(a),this.current_y_offset+=this.options.y_offset}const s=this.svg_element.getBBox();this.svg_element.setAttribute("width",(s.x+s.width).toString()),this.svg_element.setAttribute("height",(s.y+s.height+this.options.y_offset/2).toString()),$(".git_graph_commit_message",this.commits_list_element).css("padding-left",s.x+s.width+this.options.x_offset/2+"px")}list_file(t){let s={action:"list_file",args:{commit:t}};return this.call(s)}get_changes(t,s){let e={action:"get_changes",args:{commit:s,file:t}};return this.call(e)}get_file(t,s){let e={action:"get_file",args:{commit:s,file:t}};return this.call(e)}}}(s=t.API||(t.API={}))}(OS||(OS={}));
\ No newline at end of file
diff --git a/GitGrapth/main.css b/GitGraph/build/debug/main.css
similarity index 90%
rename from GitGrapth/main.css
rename to GitGraph/build/debug/main.css
index 268876d..c13b4b0 100644
--- a/GitGrapth/main.css
+++ b/GitGraph/build/debug/main.css
@@ -1,7 +1,14 @@
-afx-app-window[data-id="GitGraph"] div[data-id="git-graph"]
+div.git_grapth_container
{
overflow-y: auto;
- background-color: bisque;
+ background-color: #1e1e1e;
+}
+
+afx-app-window[data-id="GitGraph"] afx-label[data-id="txt-repo"] i.label-text
+{
+ display: block;
+ text-align: center;
+ font-weight: bold;
}
p.git_graph_commit_message:hover
@@ -65,7 +72,7 @@ p.git_graph_commit_message i.git_graph_commit_branch::before
div.git_grapth_commit_detail
{
border-radius: 5px;
- background-color: whitesmoke;
+ background-color: bisque;
box-shadow: 0px 3px 6px 0px rgb(0,0,0,0.5);
}
@@ -179,7 +186,7 @@ p.git_grapth_load_more
{
font-weight: normal ;
text-align: left;
- color:#131313;
+ color:bisque;
display: inline-block !important;
padding-left: 5px !important;
padding-right: 5px !important;
diff --git a/GitGraph/build/debug/main.js b/GitGraph/build/debug/main.js
new file mode 100644
index 0000000..d1f6d93
--- /dev/null
+++ b/GitGraph/build/debug/main.js
@@ -0,0 +1 @@
+var OS;!function(t){let i,e;i=t.API||(t.API={}),function(t){class e extends t.BaseApplication{constructor(t){super("GitGraph",t),t&&t[0]&&(this.curr_repo=t[0].path.asFileHandle(),"file"===t[0].type&&(this.curr_repo=this.curr_repo.parent()))}main(){this.graph=new i.LibGitGraph({target:this.find("git-graph")}),this.graph.on_open_diff=t=>{this._gui.launch("Antedit",[]).then(i=>{i.observable.one("launched",()=>i.openDiff(t))}).catch(t=>this.error(__("Unable to open diff with Antedit: {0}",t.toString()),t))},this.find("btn-open").onbtclick=t=>{this.openDialog("FileDialog",{title:__("Select a repository"),type:"dir"}).then(t=>{this.setRepo(t.file)})},this.setRepo(this.curr_repo)}setRepo(t){t&&(this.find("txt-repo").text=t.path,this.curr_repo=t,this.graph.base_dir=t)}}t.GitGraph=e,e.dependencies=["pkg://GitGraph/libgitgraph.js"]}(e=t.application||(t.application={}))}(OS||(OS={}));
\ No newline at end of file
diff --git a/GitGrapth/build/debug/package.json b/GitGraph/build/debug/package.json
similarity index 50%
rename from GitGrapth/build/debug/package.json
rename to GitGraph/build/debug/package.json
index 9be563a..423144b 100644
--- a/GitGrapth/build/debug/package.json
+++ b/GitGraph/build/debug/package.json
@@ -4,13 +4,13 @@
"name":"GIT Visualization",
"description":"Git Grapth",
"info":{
- "author": "",
- "email": ""
+ "author": "Dany LE",
+ "email": "contact@iohub.dev"
},
- "version":"0.0.1-a",
- "category":"Other",
- "iconclass":"fa fa-adn",
- "mimes":["none"],
+ "version":"0.1.4-b",
+ "category":"Development",
+ "iconclass":"bi bi-git",
+ "mimes":["dir"],
"dependencies":[],
"locale": {}
}
\ No newline at end of file
diff --git a/GitGraph/build/debug/scheme.html b/GitGraph/build/debug/scheme.html
new file mode 100644
index 0000000..a81aee3
--- /dev/null
+++ b/GitGraph/build/debug/scheme.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GitGraph/build/release/GitGraph.zip b/GitGraph/build/release/GitGraph.zip
new file mode 100644
index 0000000..ed3b7d0
Binary files /dev/null and b/GitGraph/build/release/GitGraph.zip differ
diff --git a/GitGrapth/build/debug/main.css b/GitGraph/main.css
similarity index 90%
rename from GitGrapth/build/debug/main.css
rename to GitGraph/main.css
index 268876d..c13b4b0 100644
--- a/GitGrapth/build/debug/main.css
+++ b/GitGraph/main.css
@@ -1,7 +1,14 @@
-afx-app-window[data-id="GitGraph"] div[data-id="git-graph"]
+div.git_grapth_container
{
overflow-y: auto;
- background-color: bisque;
+ background-color: #1e1e1e;
+}
+
+afx-app-window[data-id="GitGraph"] afx-label[data-id="txt-repo"] i.label-text
+{
+ display: block;
+ text-align: center;
+ font-weight: bold;
}
p.git_graph_commit_message:hover
@@ -65,7 +72,7 @@ p.git_graph_commit_message i.git_graph_commit_branch::before
div.git_grapth_commit_detail
{
border-radius: 5px;
- background-color: whitesmoke;
+ background-color: bisque;
box-shadow: 0px 3px 6px 0px rgb(0,0,0,0.5);
}
@@ -179,7 +186,7 @@ p.git_grapth_load_more
{
font-weight: normal ;
text-align: left;
- color:#131313;
+ color:bisque;
display: inline-block !important;
padding-left: 5px !important;
padding-right: 5px !important;
diff --git a/GitGraph/main.ts b/GitGraph/main.ts
new file mode 100644
index 0000000..3679ad0
--- /dev/null
+++ b/GitGraph/main.ts
@@ -0,0 +1,67 @@
+namespace OS {
+ export namespace API
+ {
+ export declare class LibGitGraph
+ {
+ constructor(options:GenericObject);
+ base_dir: VFS.BaseFileHandle;
+ on_open_diff: (file:VFS.BaseFileHandle[]) => void;
+ list_file: (commit: string) => Promise;
+ get_changes: (file:string, commit: string) => Promise;
+ get_file: (file:string, commit: string) => Promise
+ }
+ }
+ export namespace application {
+ /**
+ *
+ * @class GitGraph
+ * @extends {BaseApplication}
+ */
+ export class GitGraph extends BaseApplication {
+ private graph: API.LibGitGraph;
+ private curr_repo: API.VFS.BaseFileHandle;
+ constructor(args: AppArgumentsType[]) {
+ super("GitGraph", args);
+ if(args && args[0])
+ {
+ this.curr_repo = args[0].path.asFileHandle();
+ if(args[0].type === "file")
+ this.curr_repo = this.curr_repo.parent();
+ }
+ }
+ main(): void {
+ this.graph = new API.LibGitGraph({
+ target: this.find("git-graph")
+ });
+ this.graph.on_open_diff = (files) => {
+ this._gui.launch("Antedit", [])
+ .then((p) =>{
+ p.observable.one("launched",() =>(p as any).openDiff(files));
+ })
+ .catch(e => this.error(__("Unable to open diff with Antedit: {0}", e.toString()),e ));
+
+ }
+ (this.find("btn-open") as GUI.tag.ButtonTag).onbtclick = (e) => {
+ this.openDialog("FileDialog", {
+ title: __("Select a repository"),
+ type: "dir",
+
+ }).then((d) => {
+ this.setRepo(d.file);
+ });
+ };
+ this.setRepo(this.curr_repo);
+ }
+
+ private setRepo(d:API.VFS.BaseFileHandle): void
+ {
+ if(!d) return;
+ (this.find("txt-repo") as GUI.tag.LabelTag).text = d.path;
+ this.curr_repo = d;
+ this.graph.base_dir = d;
+ }
+ }
+
+ GitGraph.dependencies = ["pkg://GitGraph/libgitgraph.js"];
+ }
+}
\ No newline at end of file
diff --git a/GitGrapth/package.json b/GitGraph/package.json
similarity index 50%
rename from GitGrapth/package.json
rename to GitGraph/package.json
index 9be563a..423144b 100644
--- a/GitGrapth/package.json
+++ b/GitGraph/package.json
@@ -4,13 +4,13 @@
"name":"GIT Visualization",
"description":"Git Grapth",
"info":{
- "author": "",
- "email": ""
+ "author": "Dany LE",
+ "email": "contact@iohub.dev"
},
- "version":"0.0.1-a",
- "category":"Other",
- "iconclass":"fa fa-adn",
- "mimes":["none"],
+ "version":"0.1.4-b",
+ "category":"Development",
+ "iconclass":"bi bi-git",
+ "mimes":["dir"],
"dependencies":[],
"locale": {}
}
\ No newline at end of file
diff --git a/GitGraph/scheme.html b/GitGraph/scheme.html
new file mode 100644
index 0000000..a81aee3
--- /dev/null
+++ b/GitGraph/scheme.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GitGrapth/README.md b/GitGrapth/README.md
deleted file mode 100644
index c4f13ef..0000000
--- a/GitGrapth/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# LibGitGraph
-This is an example project, generated by AntOS Development Kit
-
-## Howto
-Use the Antedit command palette to access to the SDK functionalities:
-
-1. Create new project
-2. Init the project from the current folder located in side bar
-3. Build and run the project
-4. Release the project in zip package
-
-## Set up build target
-
-Open the `build.json` file from the current project tree and add/remove
-build target entries and jobs. Save the file
\ No newline at end of file
diff --git a/GitGrapth/build/debug/README.md b/GitGrapth/build/debug/README.md
deleted file mode 100644
index c4f13ef..0000000
--- a/GitGrapth/build/debug/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# LibGitGraph
-This is an example project, generated by AntOS Development Kit
-
-## Howto
-Use the Antedit command palette to access to the SDK functionalities:
-
-1. Create new project
-2. Init the project from the current folder located in side bar
-3. Build and run the project
-4. Release the project in zip package
-
-## Set up build target
-
-Open the `build.json` file from the current project tree and add/remove
-build target entries and jobs. Save the file
\ No newline at end of file
diff --git a/GitGrapth/build/debug/libgitgraph.js b/GitGrapth/build/debug/libgitgraph.js
deleted file mode 100644
index 8035d9f..0000000
--- a/GitGrapth/build/debug/libgitgraph.js
+++ /dev/null
@@ -1,498 +0,0 @@
-
-var OS;
-(function (OS) {
- let API;
- (function (API) {
- ;
- class LibGitGraph {
- constructor(option) {
- this._base_dir = undefined;
- this.lines_data = [];
- this.commits = {};
- this.oldest_commit_date = undefined;
- this.svg_element = undefined;
- this.commits_list_element = undefined;
- this.load_more_el = undefined;
- this.commit_detail_el = undefined;
- this.current_head = undefined;
- this._on_open_diff = undefined;
- this.options = {
- commits_per_page: 100,
- x_offset: 24,
- y_offset: 24,
- target: undefined,
- popup_height: 250
- };
- for (const k in option) {
- this.options[k] = option[k];
- }
- this.current_y_offset = this.options.y_offset;
- this.init_graph();
- }
- set base_dir(v) {
- this._base_dir = v;
- this.render_next();
- }
- gen_color(x) {
- let n = x + 11;
- const rgb = [0, 0, 0];
- for (let i = 0; i < 24; i++) {
- rgb[i % 3] <<= 1;
- rgb[i % 3] |= n & 0x01;
- n >>= 1;
- }
- return '#' + rgb.reduce((a, c) => (c > 0x0f ? c.toString(16) : '0' + c.toString(16)) + a, '');
- }
- meta() {
- return OS.setting.system.packages['GitGraph'];
- }
- call(request) {
- return new Promise(async (ok, reject) => {
- request.args.base_dir = this._base_dir.path;
- let cmd = {
- path: this.meta().path + "/api/api.lua",
- parameters: request
- };
- let data = await API.apigateway(cmd, false);
- if (!data.error) {
- ok(data.result);
- }
- else {
- reject(API.throwe(__("LibGitGrapth server call error: {0}", data.error)));
- }
- });
- }
- load(before) {
- let request = {
- action: 'log',
- args: {
- n_commits: this.options.commits_per_page.toString(),
- before: before ? before : null
- }
- };
- return this.call(request);
- }
- error(e) {
- OS.announcer.oserror(__("GitGraph error: {0}", e.toString()), e);
- }
- set on_open_diff(c) {
- this._on_open_diff = c;
- }
- init_graph() {
- if (!this.options.target) {
- return this.error(API.throwe("Target element is undefined"));
- }
- $(this.options.target)
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("display", "block")
- .css("position", "relative");
- this.svg_element = this.make_svg_el("svg", {
- width: this.options.x_offset,
- height: this.options.y_offset
- });
- $(this.svg_element)
- .css("display", "block")
- .css("position", "absolute")
- .css("left", "0")
- //s.css("z-index", 10)
- .css("top", "0");
- $(this.options.target).empty();
- this.options.target.appendChild(this.svg_element);
- const div = $("")
- .css("position", "absolute")
- .css("left", "0")
- .css("top", "0")
- .css("width", "100%")
- .css("padding-top", `${this.options.y_offset / 2}px`);
- this.commits_list_element = div[0];
- this.options.target.appendChild(this.commits_list_element);
- const p = $("")
- .css("height", `${this.options.y_offset}px`)
- .css("display", "block")
- .css("padding", "0")
- .css("margin", "0")
- .css("line-height", `${this.options.y_offset}px`)
- .css("vertical-align", "middle");
- p.addClass("git_grapth_load_more");
- p.on("click", (e) => this.render_next());
- p.text(__("More").__());
- this.load_more_el = p[0];
- this.commits_list_element.appendChild(this.load_more_el);
- const popup = $("")
- .css("position", "absolute")
- .css("top", "0")
- .css("height", this.options.popup_height + "px")
- .css("display", "none")
- .css("user-select", "text")
- .addClass("git_grapth_commit_detail");
- this.commit_detail_el = popup[0];
- this.options.target.appendChild(this.commit_detail_el);
- }
- render_next() {
- this.load(this.oldest_commit_date)
- .then((data) => {
- if (this.oldest_commit_date) {
- // remove the first commit as it is already in
- // the graph
- data.shift();
- }
- this.draw_graph(data);
- })
- .catch(e => this.error(e));
- }
- make_svg_el(tag, attrs) {
- const el = document.createElementNS('http://www.w3.org/2000/svg', tag);
- for (var k in attrs)
- el.setAttribute(k, attrs[k]);
- return el;
- }
- max_line_off_x() {
- if (this.lines_data.length == 0)
- return 0;
- return Math.max.apply(Math, this.lines_data.map((o) => o.x_offset));
- }
- update_line_data(commit, y_offset) {
- const parent_commits = commit.hashes.parents.split(" ");
- // get the list of child lines
- const children = this.lines_data.filter((line) => line.next_commit == commit.hashes.commit);
- let merge = {
- src: [],
- dest: undefined
- };
- if (children.length === 0) {
- // add new line
- let line = {
- next_commit: parent_commits[0],
- x_offset: this.max_line_off_x() + this.options.x_offset,
- current_commit: commit.hashes.commit,
- beginning: true,
- y_offset: y_offset,
- color: this.gen_color(this.lines_data.length),
- };
- this.lines_data.push(line);
- merge.dest = line;
- }
- else {
- let min_offset_x = Math.min.apply(Math, children.map((o) => o.x_offset));
- let line = undefined;
- for (let el of children) {
- if (el.x_offset == min_offset_x) {
- line = el;
- line.next_commit = parent_commits[0];
- line.current_commit = commit.hashes.commit;
- line.y_offset = y_offset;
- }
- else {
- this.lines_data.splice(this.lines_data.indexOf(el), 1);
- merge.src.push(el);
- }
- }
- merge.dest = line;
- }
- if (parent_commits.length === 2) {
- let line = undefined;
- line = this.lines_data.filter(l => l.next_commit == parent_commits[1])[0];
- if (!line) {
- // add new line
- line = {
- next_commit: parent_commits[1],
- x_offset: this.max_line_off_x() + this.options.x_offset,
- current_commit: commit.hashes.commit,
- beginning: true,
- y_offset: y_offset + this.options.y_offset,
- color: this.gen_color(this.lines_data.length),
- };
- this.lines_data.push(line);
- }
- else {
- line.y_offset = y_offset + this.options.y_offset;
- }
- merge.src.push(line);
- }
- return merge;
- }
- draw_line(_x1, _y1, _x2, _y2, color, stroke) {
- let line_opt = {
- stroke: color,
- fill: 'none',
- "stroke-width": 1.5
- };
- if (stroke) {
- line_opt['stroke-width'] = stroke;
- }
- if (_x1 == _x2) {
- line_opt.d = `M ${_x1},${_y1} L ${_x2},${_y2}`;
- }
- else {
- let x1 = _x1;
- let y1 = _y1;
- let x2 = _x2;
- let y2 = _y2;
- let dx = Math.abs(x2 - x1);
- let dy = Math.abs(y2 - y1);
- if (_y1 < _y2) {
- x1 = _x2;
- y1 = _y2;
- x2 = _x1;
- y2 = _y1;
- }
- line_opt.d = `M ${x1},${y1} C ${x1},${y1 - dy} ${x2},${y2 + dy} ${x2},${y2}`;
- }
- const line = this.make_svg_el("path", line_opt);
- return line;
- }
- gen_commit_data_header(name, value) {
- const p = $("")
- .css("display", "block");
- p[0].innerHTML = `${name.__()}: ${value}`;
- return p[0];
- }
- open_popup(commit) {
- const el = commit.domel;
- if (!el)
- return;
- $(this.commit_detail_el).empty();
- const position = $(el).position();
- const bbox = this.svg_element.getBBox();
- const off_left = bbox.x + bbox.width + this.options.x_offset / 2;
- const svg = this.make_svg_el("svg", {
- width: off_left - commit.cx + 5,
- height: this.options.y_offset
- });
- $(svg)
- .css("display", "block")
- .css("position", "absolute")
- .css("left", "0")
- .css("top", "-2px");
- svg.appendChild(this.draw_line(0, this.options.y_offset / 2, off_left - commit.cx, this.options.y_offset / 2, commit.color));
- /*
- svg.appendChild(
- this.make_svg_el("circle",{
- cx: off_left-commit.cx - 1,
- cy: this.options.y_offset/2,
- r:4,
- fill: commit.color,
- "stroke-width": 0.0
- })
- );*/
- $(this.commit_detail_el)
- .css("border", "2px solid " + commit.color)
- .css("color", commit.color)
- .append($("")
- .css("position", "absolute")
- .css("height", this.options.y_offset)
- .css("left", commit.cx - off_left)
- .css("padding-left", off_left - commit.cx)
- .append(svg)
- .append($("").text('[X]')
- .css("cursor", "pointer"))
- .addClass("git_grapth_commit_detail_ctrl")
- .on("click", (e) => {
- $(this.commit_detail_el)
- .css("display", "none")
- .empty();
- }));
- const left = $("")
- .css("display", "block")
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("flex", "1")
- .css("border-right", "1px solid " + commit.color)
- .addClass("git_grapth_commit_detail_left");
- const right = $("")
- .css("display", "block")
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("flex", "1")
- .addClass("git_grapth_commit_detail_right");
- // display
- left.append(this.gen_commit_data_header(__("Commit"), commit.hashes.commit));
- left.append(this.gen_commit_data_header(__("Parents"), commit.hashes.parents));
- left.append(this.gen_commit_data_header(__("Author"), `${commit.committer.name} <${commit.committer.email}>`));
- left.append(this.gen_commit_data_header(__("Date"), (new Date(commit.committer.date).toDateString())));
- left.append($("")
- .css("white-space", "pre-wrap")
- .text(commit.message));
- this.commit_detail_el.appendChild(left[0]);
- this.commit_detail_el.appendChild(right[0]);
- this.list_file(commit.hashes.commit)
- .then((files) => {
- const ul = $('');
- $.each(files, (index, value) => {
- const arr = value.split("\t");
- const li = $('');
- const a = $('')
- .css("cursor", "pointer")
- .addClass(`git_graph_file_${arr[0].toLowerCase()}`)
- .on("click", e => {
- if (this._on_open_diff) {
- Promise.all([
- this.get_file(arr[1], `${commit.hashes.commit}^`),
- this.get_file(arr[1], commit.hashes.commit)
- ])
- .then((values) => {
- // create the file
- const files = values.map((content, index) => {
- const file = `mem://${commit.hashes.commit.slice(0, 8)}${index == 0 ? "^" : ""}/${arr[1]}`.asFileHandle();
- file.cache = content;
- file.info.mime = "text/plain";
- return file;
- });
- this._on_open_diff(files);
- })
- .catch((e) => {
- OS.announcer.oserror(__("Unable to fetch diff of {0}: {1}", commit.hashes.commit, e.toString()), e);
- });
- }
- });
- a.text(arr[1]);
- ul.append(li.append(a));
- });
- right.append(ul);
- })
- .catch((e) => OS.announcer.oserror(__("Unable to get commit changes: {0}", e.toString()), e));
- // scroll down if necessary
- $(this.commit_detail_el)
- .css("top", position.top)
- .css("left", off_left)
- .css("display", "flex")
- .css("width", `calc(100% - ${off_left + this.options.x_offset}px)`)
- .css("fflex-direction", "row");
- const delta = this.commit_detail_el.getBoundingClientRect().bottom -
- this.options.target.getBoundingClientRect().bottom;
- if (delta > 0) {
- this.options.target.scrollTop += delta + 10;
- }
- }
- render_commit(commit, color) {
- let current = false;
- const p = $("")
- .css("padding", "0")
- .css("margin", "0")
- .css("display", "block")
- .css("height", `${this.options.y_offset}px`)
- .css("line-height", `${this.options.y_offset}px`)
- .css("color", color)
- .css("vertical-align", "middle")
- .css("white-space", "nowrap")
- .css("overflow", "hidden");
- p.addClass("git_graph_commit_message");
- let html = `${commit.hashes.commit.slice(0, 8)} `;
- commit.branches = [];
- for (const tag of commit.extra.split(",").map(e => e.trim()).filter(e => e != "")) {
- let found = tag.match(/HEAD -> (.*)/i);
- if (found && found.length == 2) {
- html += `${found[1]} `;
- p.addClass("git_graph_commit_current_head");
- current = true;
- commit.branches.push(found[1]);
- this.current_head = commit;
- }
- else if ((found = tag.match(/tag: (.*)/i))) {
- html += `${found[1]} `;
- }
- else {
- html += `${tag} `;
- commit.branches.push(tag);
- }
- }
- html += `${commit.message.split("\n")[0]} `;
- html += `${commit.committer.name} `;
- html += `${new Date(commit.committer.date).toDateString()}`;
- p[0].innerHTML = html;
- p.on("click", (e) => {
- this.open_popup(commit);
- });
- this.commits_list_element.insertBefore(p[0], this.load_more_el);
- commit.domel = p[0];
- return current;
- }
- draw_graph(data) {
- for (const commit of data) {
- this.oldest_commit_date = commit.committer.date;
- if (commit.extra.includes("refs/stash")) {
- continue;
- }
- this.commits[commit.hashes.commit] = commit;
- let merge = this.update_line_data(commit, this.current_y_offset);
- let lines = merge.src;
- // combine the lines
- for (const linedata of lines.filter(o => o.x_offset != merge.dest.x_offset)) {
- this.svg_element.appendChild(this.draw_line(merge.dest.x_offset, merge.dest.y_offset, linedata.x_offset, linedata.y_offset, linedata.color));
- }
- this.lines_data.sort((a, b) => a.x_offset - b.x_offset);
- let x_offset = this.options.x_offset;
- for (const linedata of this.lines_data) {
- if (linedata.beginning && linedata.y_offset > this.current_y_offset) {
- continue;
- }
- linedata.y_offset = this.current_y_offset;
- if (!linedata.beginning) {
- if (linedata.x_offset > x_offset) {
- this.svg_element.appendChild(this.draw_line(linedata.x_offset, linedata.y_offset - this.options.y_offset, linedata.x_offset - this.options.x_offset, linedata.y_offset, linedata.color));
- linedata.x_offset = x_offset;
- }
- else {
- this.svg_element.appendChild(this.draw_line(linedata.x_offset, linedata.y_offset - this.options.y_offset, linedata.x_offset, linedata.y_offset, linedata.color));
- }
- }
- x_offset += this.options.x_offset;
- linedata.beginning = false;
- }
- let options = {
- cx: merge.dest.x_offset,
- cy: merge.dest.y_offset,
- r: 4,
- fill: merge.dest.color,
- stroke: 'black',
- "stroke-width": 0.0
- };
- if (this.render_commit(commit, merge.dest.color)) {
- options.r = options.r * 1.5;
- }
- commit.cx = options.cx;
- commit.color = options.fill;
- const circle = this.make_svg_el("circle", options);
- this.svg_element.appendChild(circle);
- this.current_y_offset += this.options.y_offset;
- }
- const bbox = this.svg_element.getBBox();
- this.svg_element.setAttribute("width", (bbox.x + bbox.width).toString());
- this.svg_element.setAttribute("height", (bbox.y + bbox.height + this.options.y_offset / 2).toString());
- //$(this.commits_list_element).css("left", `-${bbox.x + bbox.width}px`);
- $(".git_graph_commit_message", this.commits_list_element).css("padding-left", `${bbox.x + bbox.width + this.options.x_offset / 2}px`);
- }
- list_file(hash) {
- let request = {
- action: 'list_file',
- args: {
- commit: hash
- }
- };
- return this.call(request);
- }
- get_changes(file, hash) {
- let request = {
- action: 'get_changes',
- args: {
- commit: hash,
- file: file
- }
- };
- return this.call(request);
- }
- get_file(file, hash) {
- let request = {
- action: 'get_file',
- args: {
- commit: hash,
- file: file
- }
- };
- return this.call(request);
- }
- }
- API.LibGitGraph = LibGitGraph;
- })(API = OS.API || (OS.API = {}));
-})(OS || (OS = {}));
diff --git a/GitGrapth/build/debug/main.js b/GitGrapth/build/debug/main.js
deleted file mode 100644
index 6040e7f..0000000
--- a/GitGrapth/build/debug/main.js
+++ /dev/null
@@ -1,536 +0,0 @@
-
-
-var OS;
-(function (OS) {
- let API;
- (function (API) {
- })(API = OS.API || (OS.API = {}));
- let application;
- (function (application) {
- /**
- *
- * @class GitGraph
- * @extends {BaseApplication}
- */
- class GitGraph extends application.BaseApplication {
- constructor(args) {
- super("GitGraph", args);
- }
- main() {
- let graph = new API.LibGitGraph({
- target: this.find("git-graph")
- });
- graph.on_open_diff = (files) => {
- console.log(files);
- //(OS.PM.processes.Antedit[0] as any).openDiff(files)
- this._gui.launch("Antedit", [])
- .then((p) => {
- p.observable.one("launched", () => p.openDiff(files));
- });
- };
- graph.base_dir = "home://workspace/antos/".asFileHandle();
- }
- }
- application.GitGraph = GitGraph;
- //GitGraph.dependencies = ["pkg://GitGraph/libgitgraph.js"];
- })(application = OS.application || (OS.application = {}));
-})(OS || (OS = {}));
-
-
-var OS;
-(function (OS) {
- let API;
- (function (API) {
- ;
- class LibGitGraph {
- constructor(option) {
- this._base_dir = undefined;
- this.lines_data = [];
- this.commits = {};
- this.oldest_commit_date = undefined;
- this.svg_element = undefined;
- this.commits_list_element = undefined;
- this.load_more_el = undefined;
- this.commit_detail_el = undefined;
- this.current_head = undefined;
- this._on_open_diff = undefined;
- this.options = {
- commits_per_page: 100,
- x_offset: 24,
- y_offset: 24,
- target: undefined,
- popup_height: 250
- };
- for (const k in option) {
- this.options[k] = option[k];
- }
- this.current_y_offset = this.options.y_offset;
- this.init_graph();
- }
- set base_dir(v) {
- this._base_dir = v;
- this.render_next();
- }
- gen_color(x) {
- let n = x + 11;
- const rgb = [0, 0, 0];
- for (let i = 0; i < 24; i++) {
- rgb[i % 3] <<= 1;
- rgb[i % 3] |= n & 0x01;
- n >>= 1;
- }
- return '#' + rgb.reduce((a, c) => (c > 0x0f ? c.toString(16) : '0' + c.toString(16)) + a, '');
- }
- meta() {
- return OS.setting.system.packages['GitGraph'];
- }
- call(request) {
- return new Promise(async (ok, reject) => {
- request.args.base_dir = this._base_dir.path;
- let cmd = {
- path: this.meta().path + "/api/api.lua",
- parameters: request
- };
- let data = await API.apigateway(cmd, false);
- if (!data.error) {
- ok(data.result);
- }
- else {
- reject(API.throwe(__("LibGitGrapth server call error: {0}", data.error)));
- }
- });
- }
- load(before) {
- let request = {
- action: 'log',
- args: {
- n_commits: this.options.commits_per_page.toString(),
- before: before ? before : null
- }
- };
- return this.call(request);
- }
- error(e) {
- OS.announcer.oserror(__("GitGraph error: {0}", e.toString()), e);
- }
- set on_open_diff(c) {
- this._on_open_diff = c;
- }
- init_graph() {
- if (!this.options.target) {
- return this.error(API.throwe("Target element is undefined"));
- }
- $(this.options.target)
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("display", "block")
- .css("position", "relative");
- this.svg_element = this.make_svg_el("svg", {
- width: this.options.x_offset,
- height: this.options.y_offset
- });
- $(this.svg_element)
- .css("display", "block")
- .css("position", "absolute")
- .css("left", "0")
- //s.css("z-index", 10)
- .css("top", "0");
- $(this.options.target).empty();
- this.options.target.appendChild(this.svg_element);
- const div = $("")
- .css("position", "absolute")
- .css("left", "0")
- .css("top", "0")
- .css("width", "100%")
- .css("padding-top", `${this.options.y_offset / 2}px`);
- this.commits_list_element = div[0];
- this.options.target.appendChild(this.commits_list_element);
- const p = $("")
- .css("height", `${this.options.y_offset}px`)
- .css("display", "block")
- .css("padding", "0")
- .css("margin", "0")
- .css("line-height", `${this.options.y_offset}px`)
- .css("vertical-align", "middle");
- p.addClass("git_grapth_load_more");
- p.on("click", (e) => this.render_next());
- p.text(__("More").__());
- this.load_more_el = p[0];
- this.commits_list_element.appendChild(this.load_more_el);
- const popup = $("")
- .css("position", "absolute")
- .css("top", "0")
- .css("height", this.options.popup_height + "px")
- .css("display", "none")
- .css("user-select", "text")
- .addClass("git_grapth_commit_detail");
- this.commit_detail_el = popup[0];
- this.options.target.appendChild(this.commit_detail_el);
- }
- render_next() {
- this.load(this.oldest_commit_date)
- .then((data) => {
- if (this.oldest_commit_date) {
- // remove the first commit as it is already in
- // the graph
- data.shift();
- }
- this.draw_graph(data);
- })
- .catch(e => this.error(e));
- }
- make_svg_el(tag, attrs) {
- const el = document.createElementNS('http://www.w3.org/2000/svg', tag);
- for (var k in attrs)
- el.setAttribute(k, attrs[k]);
- return el;
- }
- max_line_off_x() {
- if (this.lines_data.length == 0)
- return 0;
- return Math.max.apply(Math, this.lines_data.map((o) => o.x_offset));
- }
- update_line_data(commit, y_offset) {
- const parent_commits = commit.hashes.parents.split(" ");
- // get the list of child lines
- const children = this.lines_data.filter((line) => line.next_commit == commit.hashes.commit);
- let merge = {
- src: [],
- dest: undefined
- };
- if (children.length === 0) {
- // add new line
- let line = {
- next_commit: parent_commits[0],
- x_offset: this.max_line_off_x() + this.options.x_offset,
- current_commit: commit.hashes.commit,
- beginning: true,
- y_offset: y_offset,
- color: this.gen_color(this.lines_data.length),
- };
- this.lines_data.push(line);
- merge.dest = line;
- }
- else {
- let min_offset_x = Math.min.apply(Math, children.map((o) => o.x_offset));
- let line = undefined;
- for (let el of children) {
- if (el.x_offset == min_offset_x) {
- line = el;
- line.next_commit = parent_commits[0];
- line.current_commit = commit.hashes.commit;
- line.y_offset = y_offset;
- }
- else {
- this.lines_data.splice(this.lines_data.indexOf(el), 1);
- merge.src.push(el);
- }
- }
- merge.dest = line;
- }
- if (parent_commits.length === 2) {
- let line = undefined;
- line = this.lines_data.filter(l => l.next_commit == parent_commits[1])[0];
- if (!line) {
- // add new line
- line = {
- next_commit: parent_commits[1],
- x_offset: this.max_line_off_x() + this.options.x_offset,
- current_commit: commit.hashes.commit,
- beginning: true,
- y_offset: y_offset + this.options.y_offset,
- color: this.gen_color(this.lines_data.length),
- };
- this.lines_data.push(line);
- }
- else {
- line.y_offset = y_offset + this.options.y_offset;
- }
- merge.src.push(line);
- }
- return merge;
- }
- draw_line(_x1, _y1, _x2, _y2, color, stroke) {
- let line_opt = {
- stroke: color,
- fill: 'none',
- "stroke-width": 1.5
- };
- if (stroke) {
- line_opt['stroke-width'] = stroke;
- }
- if (_x1 == _x2) {
- line_opt.d = `M ${_x1},${_y1} L ${_x2},${_y2}`;
- }
- else {
- let x1 = _x1;
- let y1 = _y1;
- let x2 = _x2;
- let y2 = _y2;
- let dx = Math.abs(x2 - x1);
- let dy = Math.abs(y2 - y1);
- if (_y1 < _y2) {
- x1 = _x2;
- y1 = _y2;
- x2 = _x1;
- y2 = _y1;
- }
- line_opt.d = `M ${x1},${y1} C ${x1},${y1 - dy} ${x2},${y2 + dy} ${x2},${y2}`;
- }
- const line = this.make_svg_el("path", line_opt);
- return line;
- }
- gen_commit_data_header(name, value) {
- const p = $("")
- .css("display", "block");
- p[0].innerHTML = `${name.__()}: ${value}`;
- return p[0];
- }
- open_popup(commit) {
- const el = commit.domel;
- if (!el)
- return;
- $(this.commit_detail_el).empty();
- const position = $(el).position();
- const bbox = this.svg_element.getBBox();
- const off_left = bbox.x + bbox.width + this.options.x_offset / 2;
- const svg = this.make_svg_el("svg", {
- width: off_left - commit.cx + 5,
- height: this.options.y_offset
- });
- $(svg)
- .css("display", "block")
- .css("position", "absolute")
- .css("left", "0")
- .css("top", "-2px");
- svg.appendChild(this.draw_line(0, this.options.y_offset / 2, off_left - commit.cx, this.options.y_offset / 2, commit.color));
- /*
- svg.appendChild(
- this.make_svg_el("circle",{
- cx: off_left-commit.cx - 1,
- cy: this.options.y_offset/2,
- r:4,
- fill: commit.color,
- "stroke-width": 0.0
- })
- );*/
- $(this.commit_detail_el)
- .css("border", "2px solid " + commit.color)
- .css("color", commit.color)
- .append($("")
- .css("position", "absolute")
- .css("height", this.options.y_offset)
- .css("left", commit.cx - off_left)
- .css("padding-left", off_left - commit.cx)
- .append(svg)
- .append($("").text('[X]')
- .css("cursor", "pointer"))
- .addClass("git_grapth_commit_detail_ctrl")
- .on("click", (e) => {
- $(this.commit_detail_el)
- .css("display", "none")
- .empty();
- }));
- const left = $("")
- .css("display", "block")
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("flex", "1")
- .css("border-right", "1px solid " + commit.color)
- .addClass("git_grapth_commit_detail_left");
- const right = $("")
- .css("display", "block")
- .css("overflow-y", "auto")
- .css("overflow-x", "hidden")
- .css("flex", "1")
- .addClass("git_grapth_commit_detail_right");
- // display
- left.append(this.gen_commit_data_header(__("Commit"), commit.hashes.commit));
- left.append(this.gen_commit_data_header(__("Parents"), commit.hashes.parents));
- left.append(this.gen_commit_data_header(__("Author"), `${commit.committer.name} <${commit.committer.email}>`));
- left.append(this.gen_commit_data_header(__("Date"), (new Date(commit.committer.date).toDateString())));
- left.append($("")
- .css("white-space", "pre-wrap")
- .text(commit.message));
- this.commit_detail_el.appendChild(left[0]);
- this.commit_detail_el.appendChild(right[0]);
- this.list_file(commit.hashes.commit)
- .then((files) => {
- const ul = $('');
- $.each(files, (index, value) => {
- const arr = value.split("\t");
- const li = $('');
- const a = $('')
- .css("cursor", "pointer")
- .addClass(`git_graph_file_${arr[0].toLowerCase()}`)
- .on("click", e => {
- if (this._on_open_diff) {
- Promise.all([
- this.get_file(arr[1], `${commit.hashes.commit}^`),
- this.get_file(arr[1], commit.hashes.commit)
- ])
- .then((values) => {
- // create the file
- const files = values.map((content, index) => {
- const file = `mem://${commit.hashes.commit.slice(0, 8)}${index == 0 ? "^" : ""}/${arr[1]}`.asFileHandle();
- file.cache = content;
- file.info.mime = "text/plain";
- return file;
- });
- this._on_open_diff(files);
- })
- .catch((e) => {
- OS.announcer.oserror(__("Unable to fetch diff of {0}: {1}", commit.hashes.commit, e.toString()), e);
- });
- }
- });
- a.text(arr[1]);
- ul.append(li.append(a));
- });
- right.append(ul);
- })
- .catch((e) => OS.announcer.oserror(__("Unable to get commit changes: {0}", e.toString()), e));
- // scroll down if necessary
- $(this.commit_detail_el)
- .css("top", position.top)
- .css("left", off_left)
- .css("display", "flex")
- .css("width", `calc(100% - ${off_left + this.options.x_offset}px)`)
- .css("fflex-direction", "row");
- const delta = this.commit_detail_el.getBoundingClientRect().bottom -
- this.options.target.getBoundingClientRect().bottom;
- if (delta > 0) {
- this.options.target.scrollTop += delta + 10;
- }
- }
- render_commit(commit, color) {
- let current = false;
- const p = $("")
- .css("padding", "0")
- .css("margin", "0")
- .css("display", "block")
- .css("height", `${this.options.y_offset}px`)
- .css("line-height", `${this.options.y_offset}px`)
- .css("color", color)
- .css("vertical-align", "middle")
- .css("white-space", "nowrap")
- .css("overflow", "hidden");
- p.addClass("git_graph_commit_message");
- let html = `${commit.hashes.commit.slice(0, 8)} `;
- commit.branches = [];
- for (const tag of commit.extra.split(",").map(e => e.trim()).filter(e => e != "")) {
- let found = tag.match(/HEAD -> (.*)/i);
- if (found && found.length == 2) {
- html += `${found[1]} `;
- p.addClass("git_graph_commit_current_head");
- current = true;
- commit.branches.push(found[1]);
- this.current_head = commit;
- }
- else if ((found = tag.match(/tag: (.*)/i))) {
- html += `${found[1]} `;
- }
- else {
- html += `${tag} `;
- commit.branches.push(tag);
- }
- }
- html += `${commit.message.split("\n")[0]} `;
- html += `${commit.committer.name} `;
- html += `${new Date(commit.committer.date).toDateString()}`;
- p[0].innerHTML = html;
- p.on("click", (e) => {
- this.open_popup(commit);
- });
- this.commits_list_element.insertBefore(p[0], this.load_more_el);
- commit.domel = p[0];
- return current;
- }
- draw_graph(data) {
- for (const commit of data) {
- this.oldest_commit_date = commit.committer.date;
- if (commit.extra.includes("refs/stash")) {
- continue;
- }
- this.commits[commit.hashes.commit] = commit;
- let merge = this.update_line_data(commit, this.current_y_offset);
- let lines = merge.src;
- // combine the lines
- for (const linedata of lines.filter(o => o.x_offset != merge.dest.x_offset)) {
- this.svg_element.appendChild(this.draw_line(merge.dest.x_offset, merge.dest.y_offset, linedata.x_offset, linedata.y_offset, linedata.color));
- }
- this.lines_data.sort((a, b) => a.x_offset - b.x_offset);
- let x_offset = this.options.x_offset;
- for (const linedata of this.lines_data) {
- if (linedata.beginning && linedata.y_offset > this.current_y_offset) {
- continue;
- }
- linedata.y_offset = this.current_y_offset;
- if (!linedata.beginning) {
- if (linedata.x_offset > x_offset) {
- this.svg_element.appendChild(this.draw_line(linedata.x_offset, linedata.y_offset - this.options.y_offset, linedata.x_offset - this.options.x_offset, linedata.y_offset, linedata.color));
- linedata.x_offset = x_offset;
- }
- else {
- this.svg_element.appendChild(this.draw_line(linedata.x_offset, linedata.y_offset - this.options.y_offset, linedata.x_offset, linedata.y_offset, linedata.color));
- }
- }
- x_offset += this.options.x_offset;
- linedata.beginning = false;
- }
- let options = {
- cx: merge.dest.x_offset,
- cy: merge.dest.y_offset,
- r: 4,
- fill: merge.dest.color,
- stroke: 'black',
- "stroke-width": 0.0
- };
- if (this.render_commit(commit, merge.dest.color)) {
- options.r = options.r * 1.5;
- }
- commit.cx = options.cx;
- commit.color = options.fill;
- const circle = this.make_svg_el("circle", options);
- this.svg_element.appendChild(circle);
- this.current_y_offset += this.options.y_offset;
- }
- const bbox = this.svg_element.getBBox();
- this.svg_element.setAttribute("width", (bbox.x + bbox.width).toString());
- this.svg_element.setAttribute("height", (bbox.y + bbox.height + this.options.y_offset / 2).toString());
- //$(this.commits_list_element).css("left", `-${bbox.x + bbox.width}px`);
- $(".git_graph_commit_message", this.commits_list_element).css("padding-left", `${bbox.x + bbox.width + this.options.x_offset / 2}px`);
- }
- list_file(hash) {
- let request = {
- action: 'list_file',
- args: {
- commit: hash
- }
- };
- return this.call(request);
- }
- get_changes(file, hash) {
- let request = {
- action: 'get_changes',
- args: {
- commit: hash,
- file: file
- }
- };
- return this.call(request);
- }
- get_file(file, hash) {
- let request = {
- action: 'get_file',
- args: {
- commit: hash,
- file: file
- }
- };
- return this.call(request);
- }
- }
- API.LibGitGraph = LibGitGraph;
- })(API = OS.API || (OS.API = {}));
-})(OS || (OS = {}));
diff --git a/GitGrapth/build/debug/scheme.html b/GitGrapth/build/debug/scheme.html
deleted file mode 100644
index 441a698..0000000
--- a/GitGrapth/build/debug/scheme.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/GitGrapth/main.ts b/GitGrapth/main.ts
deleted file mode 100644
index 5a850b2..0000000
--- a/GitGrapth/main.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-namespace OS {
- export namespace API
- {
- export declare class LibGitGraph
- {
- constructor(options:GenericObject);
- base_dir: VFS.BaseFileHandle;
- on_open_diff: (file:VFS.BaseFileHandle[]) => void;
- list_file: (commit: string) => Promise;
- get_changes: (file:string, commit: string) => Promise;
- get_file: (file:string, commit: string) => Promise
- }
- }
- export namespace application {
- /**
- *
- * @class GitGraph
- * @extends {BaseApplication}
- */
- export class GitGraph extends BaseApplication {
- constructor(args: AppArgumentsType[]) {
- super("GitGraph", args);
- }
- main(): void {
- let graph = new API.LibGitGraph({
- target: this.find("git-graph")
- });
- graph.on_open_diff = (files) => {
- console.log(files);
- //(OS.PM.processes.Antedit[0] as any).openDiff(files)
-
- this._gui.launch("Antedit", [])
- .then((p) =>{
- p.observable.one("launched",() =>(p as any).openDiff(files));
- });
-
- }
- graph.base_dir = "home://workspace/antos/".asFileHandle();
- }
- }
-
- //GitGraph.dependencies = ["pkg://GitGraph/libgitgraph.js"];
- }
-}
\ No newline at end of file
diff --git a/GitGrapth/scheme.html b/GitGrapth/scheme.html
deleted file mode 100644
index 441a698..0000000
--- a/GitGrapth/scheme.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libantosdk/README.md b/libantosdk/README.md
index 04457c7..dacd21a 100644
--- a/libantosdk/README.md
+++ b/libantosdk/README.md
@@ -2,6 +2,7 @@
AntOSDK: development API for AntOS based applications/projects
## Change logs
+- 0.0.14: vfs-rm can be configured to be silent when the target does not exist
- 0.0.13: allow linux-job handle to set defaut pwd if it is not specified in job description
- 0.0.12: TS worker now allows user specific compile options (defined un build file)
- 0.0.11: Update AntOS API v1.2.1
diff --git a/libantosdk/build/debug/README.md b/libantosdk/build/debug/README.md
index 04457c7..dacd21a 100644
--- a/libantosdk/build/debug/README.md
+++ b/libantosdk/build/debug/README.md
@@ -2,6 +2,7 @@
AntOSDK: development API for AntOS based applications/projects
## Change logs
+- 0.0.14: vfs-rm can be configured to be silent when the target does not exist
- 0.0.13: allow linux-job handle to set defaut pwd if it is not specified in job description
- 0.0.12: TS worker now allows user specific compile options (defined un build file)
- 0.0.11: Update AntOS API v1.2.1
diff --git a/libantosdk/build/debug/core/worker.js b/libantosdk/build/debug/core/worker.js
index 6e61252..874caa3 100644
--- a/libantosdk/build/debug/core/worker.js
+++ b/libantosdk/build/debug/core/worker.js
@@ -446,7 +446,12 @@ class VFSJob extends AntOSDKBaseJob {
case 'rm':
this.delete(this.job.data)
.then(d => this.result(d))
- .catch(e => this.error(e));
+ .catch((e) =>this.error(e));
+ break;
+ case 'rm_no_error':
+ this.delete(this.job.data)
+ .then(d => this.result(d))
+ .catch((e) =>this.result(false));
break;
case 'mkdir':
this.mkdir(this.job.data)
@@ -473,6 +478,7 @@ API.jobhandle["sdk-import"] = LoadScritpJob;
API.jobhandle["sdk-setup"] = SDKSetup;
API.jobhandle["vfs-cat"] = VFSJob;
API.jobhandle["vfs-rm"] = VFSJob;
+API.jobhandle["vfs-rm_no_error"] = VFSJob;
API.jobhandle["vfs-mkdir"] = VFSJob;
API.jobhandle["vfs-cp"] = VFSJob;
diff --git a/libantosdk/build/debug/package.json b/libantosdk/build/debug/package.json
index 4453376..6d40a6f 100644
--- a/libantosdk/build/debug/package.json
+++ b/libantosdk/build/debug/package.json
@@ -7,7 +7,7 @@
"author": "Xuan Sang LE",
"email": "mrsang@iohub.dev"
},
- "version": "0.0.13-a",
+ "version": "0.0.14-a",
"category": "Development",
"iconclass": "fa fa-cog",
"mimes": [
diff --git a/libantosdk/core/worker.js b/libantosdk/core/worker.js
index 6e61252..874caa3 100644
--- a/libantosdk/core/worker.js
+++ b/libantosdk/core/worker.js
@@ -446,7 +446,12 @@ class VFSJob extends AntOSDKBaseJob {
case 'rm':
this.delete(this.job.data)
.then(d => this.result(d))
- .catch(e => this.error(e));
+ .catch((e) =>this.error(e));
+ break;
+ case 'rm_no_error':
+ this.delete(this.job.data)
+ .then(d => this.result(d))
+ .catch((e) =>this.result(false));
break;
case 'mkdir':
this.mkdir(this.job.data)
@@ -473,6 +478,7 @@ API.jobhandle["sdk-import"] = LoadScritpJob;
API.jobhandle["sdk-setup"] = SDKSetup;
API.jobhandle["vfs-cat"] = VFSJob;
API.jobhandle["vfs-rm"] = VFSJob;
+API.jobhandle["vfs-rm_no_error"] = VFSJob;
API.jobhandle["vfs-mkdir"] = VFSJob;
API.jobhandle["vfs-cp"] = VFSJob;
diff --git a/libantosdk/package.json b/libantosdk/package.json
index 4453376..6d40a6f 100644
--- a/libantosdk/package.json
+++ b/libantosdk/package.json
@@ -7,7 +7,7 @@
"author": "Xuan Sang LE",
"email": "mrsang@iohub.dev"
},
- "version": "0.0.13-a",
+ "version": "0.0.14-a",
"category": "Development",
"iconclass": "fa fa-cog",
"mimes": [
diff --git a/packages.json b/packages.json
index 198e0bc..3b33388 100644
--- a/packages.json
+++ b/packages.json
@@ -45,7 +45,7 @@
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Antedit/README.md",
"category": "Development",
"author": "Xuan Sang LE",
- "version": "0.2.1-b",
+ "version": "0.2.2-b",
"dependencies": ["MonacoCore@0.33.0-r"],
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Antedit/build/release/Antedit.zip"
},
@@ -69,16 +69,6 @@
"dependencies": ["Antunnel@0.2.0-b"],
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/AntunnelPlugins/build/release/AntunnelPlugins.zip"
},
- {
- "pkgname": "AntunnelTestClient",
- "name": "AntunnelTestClient",
- "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/AntunnelTestClient/README.md",
- "category": "Development",
- "author": "Dany LE",
- "version": "0.1.0-a",
- "dependencies": ["Antunnel@0.2.1-b"],
- "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/AntunnelTestClient/build/release/AntunnelTestClient.zip"
- },
{
"pkgname": "Archive",
"name": "Archive",
@@ -169,6 +159,16 @@
"dependencies": [],
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Dockman/build/release/Dockman.zip"
},
+ {
+ "pkgname": "GitGraph",
+ "name": "GIT Visualization",
+ "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/GitGraph/README.md",
+ "category": "Development",
+ "author": "Dany LE",
+ "version": "0.1.4-b",
+ "dependencies": [],
+ "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/GitGraph/build/release/GitGraph.zip"
+ },
{
"pkgname": "GPClient",
"name": "Generic Purpose client",
@@ -215,7 +215,7 @@
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libantosdk/README.md",
"category": "Development",
"author": "Xuan Sang LE",
- "version": "0.0.13-a",
+ "version": "0.0.14-a",
"dependencies": [],
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libantosdk/build/release/libantosdk.zip"
},