diff --git a/client/dom/current-file.js b/client/dom/current-file.js index 8ed027b3..da52d748 100644 --- a/client/dom/current-file.js +++ b/client/dom/current-file.js @@ -1,8 +1,3 @@ -/** - * Parse a `data-name` attribute string back into the original filename - * @param attribute The string we wish to decode - */ - 'use strict'; /* global DOM */ @@ -24,8 +19,8 @@ const { let Title; const CURRENT_FILE = 'current-file'; -const NBSP_REG = RegExp(String.fromCharCode(160), 'g'); -const SPACE = ' '; +const encodeNBSP = (a) => a?.replace('\xa0', ' '); +const decodeNBSP = (a) => a?.replace(' ', '\xa0'); module.exports._CURRENT_FILE = CURRENT_FILE; @@ -81,16 +76,22 @@ const createNameAttribute = (name) => { */ const parseNameAttribute = (attribute) => { attribute = attribute.replace('js-file-', ''); - return decodeURI(atob(attribute)); + 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 - .replace(NBSP_REG, SPACE); + return path.textContent; }; /** @@ -103,12 +104,7 @@ module.exports.getCurrentPath = (currentFile) => { const [element] = DOM.getByTag('a', current); const {prefix} = CloudCmd; - const path = element - .getAttribute('href') - .replace(RegExp('^' + prefix + FS), '') - .replace(NBSP_REG, SPACE); - - return decode(path); + return parseHrefAttribute(prefix, element.getAttribute('href')); }; /** @@ -161,8 +157,9 @@ module.exports.getCurrentFile = () => { /** * get current file by name */ + module.exports.getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => { - const dataName = 'js-file-' + btoa(encodeURI(name)); + const dataName = 'js-file-' + btoa(encodeURI(encodeNBSP(name))); return DOM.getByDataName(dataName, panel); }; diff --git a/client/dom/current-file.spec.js b/client/dom/current-file.spec.js index c82afe04..57702d3d 100644 --- a/client/dom/current-file.spec.js +++ b/client/dom/current-file.spec.js @@ -302,6 +302,23 @@ function getCloudCmd({emit} = {}) { }; } +test('current-file: parseNameAttribute', (t) => { + const result = currentFile._parseNameAttribute('js-file-aGVsbG8mbmJzcDt3b3JsZA=='); + const expected = 'hello\xa0world'; + + t.equal(result, expected); + t.end(); +}); + +test('current-file: parseHrefAttribute', (t) => { + const prefix = '/api/v1'; + const result = currentFile._parseHrefAttribute(prefix, '/api/v1/fs/hello world'); + const expected = '/hello\xa0world'; + + t.equal(result, expected); + t.end(); +}); + function getDOM({ link = {}, getCurrentDirPath = stub(), diff --git a/client/dom/index.js b/client/dom/index.js index fe665336..abc1c607 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -148,16 +148,6 @@ module.exports.getNotCurrentDirPath = () => { return path; }; -/** - * get current file by name - */ -module.exports.getCurrentByName = (name, panel = CurrentInfo.panel) => { - const dataName = 'js-file-' + btoa(encodeURI(name)); - const element = DOM.getByDataName(dataName, panel); - - return element; -}; - /** * unified way to get selected files * diff --git a/client/modules/operation/index.js b/client/modules/operation/index.js index c58e629d..4d7dd527 100644 --- a/client/modules/operation/index.js +++ b/client/modules/operation/index.js @@ -405,18 +405,15 @@ async function _processFiles(options, data) { panelPassive, } = Info; - const setCurrent = () => { - const currentName = name || data.names[0]; - DOM.setCurrentByName(currentName); - }; - if (!Info.isOnePanel) CloudCmd.refresh({ panel: panelPassive, noCurrent: true, }); - CloudCmd.refresh({panel}, setCurrent); + CloudCmd.refresh({ + panel, + }); }); } } diff --git a/common/entity.js b/common/entity.js index bad8ef77..e0e6715e 100644 --- a/common/entity.js +++ b/common/entity.js @@ -1,7 +1,7 @@ 'use strict'; const Entities = { - ' ': ' ', +// ' ': ' ', '<': '<', '>': '>', '"': '"', diff --git a/package.json b/package.json index fcae317a..bcf887f3 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "onezip": "^5.0.0", "open": "^8.0.5", "package-json": "^7.0.0", - "ponse": "^6.0.0", + "ponse": "^7.0.0", "pullout": "^4.0.0", "putout": "^25.0.1", "redzip": "^2.0.0", diff --git a/server/route.spec.js b/server/route.spec.js index 504182ca..c1bde432 100644 --- a/server/route.spec.js +++ b/server/route.spec.js @@ -229,7 +229,7 @@ test('cloudcmd: route: not found', async (t) => { test('cloudcmd: route: sendIndex: encode', async (t) => { const name = '">'; - const nameEncoded = '"><svg onload=alert(3);>'; + const nameEncoded = '"><svg onload=alert(3);>'; const path = '/'; const files = [{ name, diff --git a/test/common/entity.js b/test/common/entity.js index 8e38f46a..20a005f2 100644 --- a/test/common/entity.js +++ b/test/common/entity.js @@ -5,21 +5,21 @@ const entity = require('../../common/entity'); test('cloudcmd: entity: encode', (t) => { const result = entity.encode(' '); - const expected = '<hello> '; + const expected = '<hello> '; t.equal(result, expected, 'should encode entity'); t.end(); }); test('cloudcmd: entity: decode', (t) => { - const result = entity.decode('<hello> '); + const result = entity.decode('<hello> '); const expected = ' '; t.equal(result, expected, 'should decode entity'); t.end(); }); -test('cloudcmd: entity: encode', (t) => { +test('cloudcmd: entity: encode quote', (t) => { const result = entity.encode('"hello"'); const expected = '"hello"';