amWiki/lib/autoNavigation.js

213 lines
8.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 工作端 - Atom - 自动化模块
* @author Tevin
*/
const {CompositeDisposable} = require('atom');
const fs = require('fs');
const crypto = require('crypto');
const makeNav = require('../build/makeNavigation');
const mngFolder = require('../build/manageFolder');
const mngWiki = require('../build/manageWiki');
const autoNavigation = (function () {
return {
/**
* 订阅
* @private
*/
_subscriptions: null,
/**
* atom 树形导航模块的引用
* @private
*/
_treeViewPkgMain: null,
/**
* wiki 列表记录
* @private
*/
_wikis: null,
/**
* 用户相关监听
* @private
*/
_listenUser: function () {
//监听用户普通操作
this._subscriptions = new CompositeDisposable();
this._subscriptions.add(atom.commands.onDidDispatch((e) => {
//重命名、新增文件夹或文件、创建副本等事件
if (/core\:confirm/.test(e.type)) {
this._getCurLib((wId) => {
this._checkLibChange(wId);
});
}
//删除、剪切、粘帖文件事件
else if (/tree-view\:(remove|cut|paste)/.test(e.type)) {
this._getCurLib((wId) => {
this._checkLibChange(wId);
});
}
//删除项目文件夹事件
//else if (e.type === 'tree-view:remove-project-folder') {}
}));
//从atom目录树监听用户拖拽操作
atom.packages.activatePackage('tree-view').then((pkg) => {
this._treeViewPkgMain = pkg.mainModule;
const elm = pkg.mainModule.treeView[0] || pkg.mainModule.treeView.element;
elm.addEventListener('drop', (e) => {
let path, wId;
for (let item of e.path) {
if (item.className.indexOf('project-root') >= 0) {
path = item.querySelector('.header > span').getAttribute('data-path');
wId = mngWiki.createWikiId(path);
if (typeof this._wikis[wId] !== 'undefined') {
this._checkLibChange(wId);
} else {
path = path.replace(/\\/g, '/');
mngWiki.addWiki(path, wId);
this._checkLibChange(wId);
}
break;
}
}
}, false);
});
//当编辑器打开一个文件时的回调
//this._subscriptions.add(atom.workspace.onDidOpen(function () {}));
},
/**
* 变化相关监听
* @private
*/
_listenChange: function () {
//当项目数量变化时的回调(即添加或删除项目)
this._subscriptions.add(atom.project.onDidChangePaths((list) => {
//文库列表比对,添加新增
for (let [i, item] of list) {
item = item.replace(/\\/g, '/') + '/library/';
for (let wId in this._wikis) {
if (this._wikis.hasOwnProperty(wId) && item === this._wikis[wId].path) {
list[i] = null;
}
}
}
for (let item of list) {
if (item && mngFolder.isAmWiki(item)) {
mngWiki.addWiki(item.replace(/\\/g, '/') + '/');
}
}
}));
},
/**
* 时间相关监听
* @private
*/
_listenTime: function () {
//切换窗口出去超过30秒回来时检查目录
let lastTimestamp;
window.addEventListener('blur', () => {
lastTimestamp = Date.now();
});
window.addEventListener('focus', () => {
//如果atom插件设置“得到焦点时检查库变化”项处于开启状态检查当前文库
if (atom.config.get('amWiki.checkLibraryOnWindowFocus')) {
if (Date.now() - lastTimestamp > 30000) {
this._getCurLib((wId) => {
this._checkLibChange(wId);
});
}
}
});
//当atom启动时如果插件设置“启动时全量检查文库变化”项处于开启状态全量检查文库直接检查不判断当前库
if (atom.config.get('amWiki.checkAllLibraryOnAtomStart')) {
for (let wId in this._wikis) {
if (this._wikis.hasOwnProperty(wId)) {
setTimeout(() => {
mngWiki.checkWikiValid(wId);
this._checkLibChange(wId);
}, 100);
}
}
}
},
/**
* 推测当前文库是哪一个
* @param {Function} callback
* @param {Number} recursive - 递归次数标记
* @private
*/
_getCurLib: function (callback, recursive = 1) {
const treeView = this._treeViewPkgMain.treeView, //目录树主对象
treeState = this._treeViewPkgMain.state; //目录树全局状态
let wId = '';
//如果 treeView 已经准备完毕,获取路径
if (treeView && treeView.selectedPath) {
//如果 treeView 当前路径是已经存在的 wiki
wId = mngWiki.createWikiId(treeView.selectedPath.replace(/\\/g, '/').split('library')[0]);
if (typeof this._wikis[wId] !== 'undefined') {
callback(wId);
}
//否则从 treeState 获取路径
else if (treeState && treeState.selectedPath) {
//如果 treeState 当前路径补是已存在的wiki
wId = mngWiki.createWikiId(treeState.selectedPath.replace(/\\/g, '/').split('library')[0]);
if (typeof this._wikis[wId] !== 'undefined') {
callback(wId);
}
//如果 treeState 当前路径也不匹配,不再检查
}
}
//如果_treeView未准备完毕0.2秒后重新检查且最多只递归3次超过后不再检查
else {
setTimeout(() => {
recursive++;
if (recursive <= 3) {
this._getCurLib(callback, recursive);
}
}, 200);
}
},
/**
* 检查文库变化
* @param {String} wId
* @private
*/
_checkLibChange: function (wId) {
//利用延迟跳出执行列队,等待系统文件操作完毕再读取
setTimeout(() => {
if (this._wikis[wId].deprecated) {
return;
}
const [tree, list, files] = mngFolder.readLibraryTree(this._wikis[wId].path);
if (!tree) {
return
}
const libMd5 = crypto.createHash('md5').update(files.join('&')).digest('base64');
if (this._wikis[wId].treeMD5 !== libMd5) {
this._wikis[wId].treeMD5 = libMd5;
//更新导航文件
makeNav.make(this._wikis[wId].path, tree, list);
}
}, 100);
},
/**
* 监听发起
* @param {[Object]} wikis - 文库记录列表的引用
* @public
*/
start: function (wikis) {
this._wikis = wikis;
this._listenUser();
this._listenChange();
this._listenTime();
},
/**
* 监听释放
* @public
*/
destroy: function () {
this._subscriptions && this._subscriptions.dispose();
}
};
})();
module.exports = autoNavigation;