mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 18:55:26 +00:00
314 lines
7.2 KiB
JavaScript
314 lines
7.2 KiB
JavaScript
'use strict';
|
|
|
|
/* global DOM */
|
|
/* global CloudCmd */
|
|
const {atob, btoa} = require('../../common/base64');
|
|
const createElement = require('@cloudcmd/create-element');
|
|
|
|
const {encode, decode} = require('../../common/entity');
|
|
|
|
const {getTitle, FS} = require('../../common/cloudfunc');
|
|
|
|
let Title;
|
|
|
|
const CURRENT_FILE = 'current-file';
|
|
const encodeNBSP = (a) => a?.replace('\xa0', ' ');
|
|
const decodeNBSP = (a) => a?.replace(' ', '\xa0');
|
|
|
|
module.exports._CURRENT_FILE = CURRENT_FILE;
|
|
/**
|
|
* set name from current (or param) file
|
|
*
|
|
* @param name
|
|
* @param current
|
|
*/
|
|
module.exports.setCurrentName = (name, current) => {
|
|
const Info = DOM.CurrentInfo;
|
|
const {link} = Info;
|
|
const {prefix} = CloudCmd;
|
|
const dir = prefix + FS + Info.dirPath;
|
|
const encoded = encode(name);
|
|
|
|
link.title = encoded;
|
|
link.href = dir + encoded;
|
|
link.innerHTML = encoded;
|
|
|
|
current.setAttribute('data-name', createNameAttribute(name));
|
|
CloudCmd.emit('current-file', current);
|
|
|
|
return link;
|
|
};
|
|
|
|
/**
|
|
* get name from current (or param) file
|
|
*
|
|
* @param currentFile
|
|
*/
|
|
module.exports.getCurrentName = (currentFile) => {
|
|
const current = currentFile || DOM.getCurrentFile();
|
|
|
|
if (!current)
|
|
return '';
|
|
|
|
return parseNameAttribute(current.getAttribute('data-name'));
|
|
};
|
|
|
|
/**
|
|
* Generate a `data-name` attribute for the given filename
|
|
* @param name The string name to encode
|
|
*/
|
|
const createNameAttribute = (name) => {
|
|
const encoded = btoa(encodeURI(name));
|
|
return `js-file-${encoded}`;
|
|
};
|
|
|
|
/**
|
|
* Parse a `data-name` attribute string back into the original filename
|
|
* @param attribute The string we wish to decode
|
|
*/
|
|
const parseNameAttribute = (attribute) => {
|
|
attribute = attribute.replace('js-file-', '');
|
|
return decodeNBSP(decodeURI(atob(attribute)));
|
|
};
|
|
|
|
module.exports._parseNameAttribute = parseNameAttribute;
|
|
|
|
const parseHrefAttribute = (prefix, attribute) => {
|
|
attribute = attribute.replace(RegExp('^' + prefix + FS), '');
|
|
return decode(decodeNBSP(attribute));
|
|
};
|
|
|
|
module.exports._parseHrefAttribute = parseHrefAttribute;
|
|
/**
|
|
* get current direcotory path
|
|
*/
|
|
module.exports.getCurrentDirPath = (panel = DOM.getPanel()) => {
|
|
const path = DOM.getByDataName('js-path', panel);
|
|
return path.textContent;
|
|
};
|
|
|
|
/**
|
|
* get link from current (or param) file
|
|
*
|
|
* @param currentFile - current file by default
|
|
*/
|
|
module.exports.getCurrentPath = (currentFile) => {
|
|
const current = currentFile || DOM.getCurrentFile();
|
|
const [element] = DOM.getByTag('a', current);
|
|
const {prefix} = CloudCmd;
|
|
|
|
return parseHrefAttribute(prefix, element.getAttribute('href'));
|
|
};
|
|
|
|
/**
|
|
* get current direcotory name
|
|
*/
|
|
module.exports.getCurrentDirName = () => {
|
|
const href = DOM
|
|
.getCurrentDirPath()
|
|
.replace(/\/$/, '');
|
|
|
|
const substr = href.substr(href, href.lastIndexOf('/'));
|
|
|
|
return href.replace(`${substr}/`, '') || '/';
|
|
};
|
|
|
|
/**
|
|
* get current direcotory path
|
|
*/
|
|
module.exports.getParentDirPath = (panel) => {
|
|
const path = DOM.getCurrentDirPath(panel);
|
|
const dirName = DOM.getCurrentDirName() + '/';
|
|
const index = path.lastIndexOf(dirName);
|
|
|
|
if (path === '/')
|
|
return path;
|
|
|
|
return path.slice(0, index);
|
|
};
|
|
|
|
/**
|
|
* get not current direcotory path
|
|
*/
|
|
module.exports.getNotCurrentDirPath = () => {
|
|
const panel = DOM.getPanel({
|
|
active: false,
|
|
});
|
|
|
|
return DOM.getCurrentDirPath(panel);
|
|
};
|
|
|
|
/**
|
|
* unified way to get current file
|
|
*
|
|
* @currentFile
|
|
*/
|
|
module.exports.getCurrentFile = () => {
|
|
return DOM.getByClass(CURRENT_FILE);
|
|
};
|
|
|
|
/**
|
|
* get current file by name
|
|
*/
|
|
module.exports.getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => {
|
|
const dataName = 'js-file-' + btoa(encodeURI(encodeNBSP(name)));
|
|
return DOM.getByDataName(dataName, panel);
|
|
};
|
|
|
|
/**
|
|
* private function thet unset currentfile
|
|
*
|
|
* @currentFile
|
|
*/
|
|
function unsetCurrentFile(currentFile) {
|
|
const is = DOM.isCurrentFile(currentFile);
|
|
|
|
if (!is)
|
|
return;
|
|
|
|
currentFile.classList.remove(CURRENT_FILE);
|
|
}
|
|
|
|
/**
|
|
* unified way to set current file
|
|
*/
|
|
module.exports.setCurrentFile = (currentFile, options) => {
|
|
const o = options;
|
|
const currentFileWas = DOM.getCurrentFile();
|
|
|
|
if (!currentFile)
|
|
return DOM;
|
|
|
|
let pathWas = '';
|
|
|
|
if (currentFileWas) {
|
|
pathWas = DOM.getCurrentDirPath();
|
|
unsetCurrentFile(currentFileWas);
|
|
}
|
|
|
|
currentFile.classList.add(CURRENT_FILE);
|
|
|
|
const path = DOM.getCurrentDirPath();
|
|
const name = CloudCmd.config('name');
|
|
|
|
if (path !== pathWas) {
|
|
DOM.setTitle(getTitle({
|
|
name,
|
|
path,
|
|
}));
|
|
|
|
/* history could be present
|
|
* but it should be false
|
|
* to prevent default behavior
|
|
*/
|
|
if (!o || o.history) {
|
|
const historyPath = path === '/' ? path : FS + path;
|
|
DOM.setHistory(historyPath, null, historyPath);
|
|
}
|
|
}
|
|
|
|
/* scrolling to current file */
|
|
const CENTER = true;
|
|
|
|
DOM.scrollIntoViewIfNeeded(currentFile, CENTER);
|
|
|
|
CloudCmd.emit('current-file', currentFile);
|
|
CloudCmd.emit('current-path', path);
|
|
CloudCmd.emit('current-name', DOM.getCurrentName(currentFile));
|
|
|
|
return DOM;
|
|
};
|
|
|
|
this.setCurrentByName = (name) => {
|
|
const current = DOM.getCurrentByName(name);
|
|
return DOM.setCurrentFile(current);
|
|
};
|
|
|
|
/*
|
|
* set current file by position
|
|
*
|
|
* @param layer - element
|
|
* @param - position {x, y}
|
|
*/
|
|
module.exports.getCurrentByPosition = ({x, y}) => {
|
|
const element = document.elementFromPoint(x, y);
|
|
|
|
const getEl = (el) => {
|
|
const {tagName} = el;
|
|
const isChild = /A|SPAN|LI/.test(tagName);
|
|
|
|
if (!isChild)
|
|
return null;
|
|
|
|
if (tagName === 'A')
|
|
return el.parentElement.parentElement;
|
|
|
|
if (tagName === 'SPAN')
|
|
return el.parentElement;
|
|
|
|
return el;
|
|
};
|
|
|
|
const el = getEl(element);
|
|
|
|
if (el && el.tagName !== 'LI')
|
|
return null;
|
|
|
|
return el;
|
|
};
|
|
|
|
/**
|
|
* current file check
|
|
*
|
|
* @param currentFile
|
|
*/
|
|
module.exports.isCurrentFile = (currentFile) => {
|
|
if (!currentFile)
|
|
return false;
|
|
|
|
return DOM.isContainClass(currentFile, CURRENT_FILE);
|
|
};
|
|
|
|
/**
|
|
* set title or create title element
|
|
*
|
|
* @param name
|
|
*/
|
|
module.exports.setTitle = (name) => {
|
|
if (!Title)
|
|
Title = DOM.getByTag('title')[0] || createElement('title', {
|
|
innerHTML: name,
|
|
parent: document.head,
|
|
});
|
|
|
|
Title.textContent = name;
|
|
|
|
return DOM;
|
|
};
|
|
|
|
/**
|
|
* check is current file is a directory
|
|
*
|
|
* @param currentFile
|
|
*/
|
|
module.exports.isCurrentIsDir = (currentFile) => {
|
|
const current = currentFile || DOM.getCurrentFile();
|
|
const path = DOM.getCurrentPath(current);
|
|
const fileType = DOM.getCurrentType(current);
|
|
|
|
const isZip = /\.zip$/.test(path);
|
|
const isDir = /^directory(-link)?/.test(fileType);
|
|
|
|
return isDir || isZip;
|
|
};
|
|
|
|
module.exports.getCurrentType = (currentFile) => {
|
|
const current = currentFile || DOM.getCurrentFile();
|
|
const el = DOM.getByDataName('js-type', current);
|
|
const type = el
|
|
.className
|
|
.split(' ')
|
|
.pop();
|
|
|
|
return type;
|
|
};
|