mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 10:45:47 +00:00
refactor(client) extendProto -> module.exports
This commit is contained in:
parent
95d3cc67cb
commit
9d67bae487
25 changed files with 486 additions and 1127 deletions
|
|
@ -35,7 +35,6 @@
|
|||
"menu": "~1.0.2",
|
||||
"olark": "^1.0.0",
|
||||
"philip": "^1.3.3",
|
||||
"promise-polyfill": "6.0.2",
|
||||
"smalltalk": "2.1.3",
|
||||
"jquery": "3.1.1"
|
||||
}
|
||||
|
|
|
|||
272
client/buffer.js
272
client/buffer.js
|
|
@ -1,142 +1,138 @@
|
|||
/* global Util */
|
||||
/* global DOM */
|
||||
/* global CloudCmd */
|
||||
|
||||
(function(Util, DOM, CloudCmd) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
const jonny = require('jonny');
|
||||
const exec = require('execon');
|
||||
|
||||
const Storage = require('./storage');
|
||||
const Dialog = require('./dialog');
|
||||
const DOM = require('./dom');
|
||||
|
||||
module.exports = new BufferProto(DOM, CloudCmd);
|
||||
|
||||
function BufferProto(DOM, CloudCmd) {
|
||||
const Info = DOM.CurrentInfo,
|
||||
CLASS = 'cut-file',
|
||||
COPY = 'copy',
|
||||
CUT = 'cut',
|
||||
TITLE = 'Buffer',
|
||||
|
||||
Buffer = {
|
||||
cut : callIfEnabled.bind(null, cut),
|
||||
copy : callIfEnabled.bind(null, copy),
|
||||
clear : callIfEnabled.bind(null, clear),
|
||||
paste : callIfEnabled.bind(null, paste)
|
||||
};
|
||||
|
||||
var DOMProto = Object.getPrototypeOf(DOM);
|
||||
|
||||
DOMProto.Buffer = new BufferProto(Util, DOM, CloudCmd);
|
||||
|
||||
function BufferProto(Util, DOM, CloudCmd) {
|
||||
var Storage = DOM.Storage,
|
||||
Info = DOM.CurrentInfo,
|
||||
json = Util.json,
|
||||
|
||||
CLASS = 'cut-file',
|
||||
|
||||
COPY = 'copy',
|
||||
CUT = 'cut',
|
||||
|
||||
TITLE = 'Buffer',
|
||||
|
||||
Buffer = {
|
||||
cut : callIfEnabled.bind(null, cut),
|
||||
copy : callIfEnabled.bind(null, copy),
|
||||
clear : callIfEnabled.bind(null, clear),
|
||||
paste : callIfEnabled.bind(null, paste)
|
||||
};
|
||||
|
||||
function showMessage(msg) {
|
||||
DOM.Dialog.alert(TITLE, msg);
|
||||
}
|
||||
|
||||
function getNames() {
|
||||
var files = DOM.getActiveFiles(),
|
||||
names = DOM.getFilenames(files);
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
function addCutClass() {
|
||||
var files = DOM.getActiveFiles();
|
||||
|
||||
files.forEach(function(element) {
|
||||
element.classList.add(CLASS);
|
||||
});
|
||||
}
|
||||
|
||||
function rmCutClass() {
|
||||
var files = DOM.getByClassAll(CLASS);
|
||||
|
||||
[]
|
||||
.slice.call(files)
|
||||
.forEach(function(element) {
|
||||
element.classList.remove(CLASS);
|
||||
});
|
||||
}
|
||||
|
||||
function callIfEnabled(callback) {
|
||||
var is = CloudCmd.config('buffer');
|
||||
|
||||
if (is)
|
||||
return callback();
|
||||
|
||||
showMessage('Buffer disabled in config!');
|
||||
}
|
||||
|
||||
function copy() {
|
||||
var Storage = DOM.Storage,
|
||||
names = getNames(),
|
||||
from = Info.dirPath;
|
||||
|
||||
clear();
|
||||
|
||||
if (names.length)
|
||||
Storage.remove(CUT)
|
||||
.set(COPY, {
|
||||
from : from,
|
||||
names: names
|
||||
});
|
||||
}
|
||||
|
||||
function cut() {
|
||||
var Storage = DOM.Storage,
|
||||
names = getNames(),
|
||||
from = Info.dirPath;
|
||||
|
||||
clear();
|
||||
|
||||
if (names.length) {
|
||||
addCutClass();
|
||||
|
||||
Storage
|
||||
.set(CUT, {
|
||||
from : from,
|
||||
names: names
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function clear() {
|
||||
Storage.remove(COPY)
|
||||
.remove(CUT);
|
||||
|
||||
rmCutClass();
|
||||
}
|
||||
|
||||
function paste() {
|
||||
var copy = Storage.get.bind(Storage, COPY),
|
||||
cut = Storage.get.bind(Storage, CUT);
|
||||
|
||||
Util.exec.parallel([copy, cut], function(error, cp, ct) {
|
||||
var opStr = cp ? 'copy' : 'move',
|
||||
opData = cp || ct,
|
||||
data = {},
|
||||
Operation = CloudCmd.Operation,
|
||||
msg = 'Path is same!',
|
||||
path = Info.dirPath;
|
||||
|
||||
if (!error && !cp && !ct)
|
||||
error = 'Buffer is empty!';
|
||||
|
||||
if (error) {
|
||||
showMessage(error);
|
||||
} else {
|
||||
data = json.parse(opData);
|
||||
data.to = path;
|
||||
|
||||
if (data.from === path) {
|
||||
showMessage(msg);
|
||||
} else {
|
||||
Operation.show(opStr, data);
|
||||
clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
function showMessage(msg) {
|
||||
Dialog.alert(TITLE, msg);
|
||||
}
|
||||
})(Util, DOM, CloudCmd);
|
||||
|
||||
function getNames() {
|
||||
var files = DOM.getActiveFiles(),
|
||||
names = DOM.getFilenames(files);
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
function addCutClass() {
|
||||
var files = DOM.getActiveFiles();
|
||||
|
||||
files.forEach(function(element) {
|
||||
element.classList.add(CLASS);
|
||||
});
|
||||
}
|
||||
|
||||
function rmCutClass() {
|
||||
var files = DOM.getByClassAll(CLASS);
|
||||
|
||||
[]
|
||||
.slice.call(files)
|
||||
.forEach(function(element) {
|
||||
element.classList.remove(CLASS);
|
||||
});
|
||||
}
|
||||
|
||||
function callIfEnabled(callback) {
|
||||
var is = CloudCmd.config('buffer');
|
||||
|
||||
if (is)
|
||||
return callback();
|
||||
|
||||
showMessage('Buffer disabled in config!');
|
||||
}
|
||||
|
||||
function copy() {
|
||||
const names = getNames();
|
||||
const from = Info.dirPath;
|
||||
|
||||
clear();
|
||||
|
||||
if (!names.length)
|
||||
return;
|
||||
|
||||
Storage.remove(CUT)
|
||||
.set(COPY, {
|
||||
from : from,
|
||||
names: names
|
||||
});
|
||||
}
|
||||
|
||||
function cut() {
|
||||
const names = getNames();
|
||||
const from = Info.dirPath;
|
||||
|
||||
clear();
|
||||
|
||||
if (!names.length)
|
||||
return;
|
||||
|
||||
addCutClass();
|
||||
|
||||
Storage
|
||||
.set(CUT, {
|
||||
from : from,
|
||||
names: names
|
||||
});
|
||||
}
|
||||
|
||||
function clear() {
|
||||
Storage.remove(COPY)
|
||||
.remove(CUT);
|
||||
|
||||
rmCutClass();
|
||||
}
|
||||
|
||||
function paste() {
|
||||
const copy = Storage.get.bind(Storage, COPY);
|
||||
const cut = Storage.get.bind(Storage, CUT);
|
||||
|
||||
exec.parallel([copy, cut], function(error, cp, ct) {
|
||||
var opStr = cp ? 'copy' : 'move',
|
||||
opData = cp || ct,
|
||||
data = {},
|
||||
Operation = CloudCmd.Operation,
|
||||
msg = 'Path is same!',
|
||||
path = Info.dirPath;
|
||||
|
||||
if (!error && !cp && !ct)
|
||||
error = 'Buffer is empty!';
|
||||
|
||||
if (error)
|
||||
return showMessage(error);
|
||||
|
||||
data = jonny.parse(opData);
|
||||
data.to = path;
|
||||
|
||||
if (data.from === path) {
|
||||
showMessage(msg);
|
||||
} else {
|
||||
Operation.show(opStr, data);
|
||||
clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ function CloudCmdProto(Util, DOM, CloudFunc) {
|
|||
|
||||
const {htmlDialogs} = config;
|
||||
|
||||
DOM.Dialog = new DOM.Dialog(prefix, {
|
||||
DOM.Dialog = DOM.Dialog(prefix, {
|
||||
htmlDialogs
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,34 +4,20 @@ window.CloudCmd = (config) => {
|
|||
window.Util = require('../common/util');
|
||||
window.CloudFunc = require('../common/cloudfunc');
|
||||
window.DOM = require('./dom');
|
||||
|
||||
require('./events');
|
||||
require('./storage');
|
||||
require('./files');
|
||||
require('./rest');
|
||||
require('./load');
|
||||
require('./notify');
|
||||
require('./dialog');
|
||||
|
||||
window.CloudCmd = require('./client');
|
||||
|
||||
require('./buffer');
|
||||
require('./listeners');
|
||||
require('./key');
|
||||
require('./directory');
|
||||
require('./sort');
|
||||
|
||||
window.exec = require('execon');
|
||||
window.rendy = require('rendy');
|
||||
const dir = '/dist';
|
||||
|
||||
const modules = '/modules/';
|
||||
|
||||
var moduleFiles = [
|
||||
window.Promise ? '' : 'promise-polyfill/promise.min',
|
||||
const moduleFiles = [
|
||||
window.Promise ? '' : `${dir}/promise`,
|
||||
Object.assign ? '' : `${dir}/object.assign`,
|
||||
].filter((name) => {
|
||||
return name;
|
||||
}).map((name) => {
|
||||
return modules + name;
|
||||
});
|
||||
|
||||
const allFiles = moduleFiles
|
||||
|
|
|
|||
|
|
@ -1,52 +1,50 @@
|
|||
/* global DOM */
|
||||
/* global smalltalk */
|
||||
|
||||
(function(DOM) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
module.exports = Dialog;
|
||||
|
||||
function Dialog(prefix, config) {
|
||||
const self = this;
|
||||
|
||||
DOM.Dialog = Dialog;
|
||||
if (!(this instanceof Dialog))
|
||||
return new Dialog(prefix, config);
|
||||
|
||||
function Dialog(prefix, config) {
|
||||
var self = this;
|
||||
load(config.htmlDialogs);
|
||||
|
||||
function load(htmlDialogs) {
|
||||
var names,
|
||||
name = 'smalltalk',
|
||||
is = window.Promise,
|
||||
js = '.min.js',
|
||||
jsName = is ? js : '.poly' + js,
|
||||
dir = '/modules/' + name + '/dist/';
|
||||
|
||||
if (!(this instanceof Dialog))
|
||||
return new Dialog(config);
|
||||
if (!htmlDialogs)
|
||||
jsName = '.native' + jsName;
|
||||
|
||||
load(config.htmlDialogs);
|
||||
names = [jsName, '.min.css'].map(function(ext) {
|
||||
return prefix + dir + name + ext;
|
||||
});
|
||||
|
||||
function load(htmlDialogs) {
|
||||
var names,
|
||||
name = 'smalltalk',
|
||||
is = window.Promise,
|
||||
js = '.min.js',
|
||||
jsName = is ? js : '.poly' + js,
|
||||
dir = '/modules/' + name + '/dist/';
|
||||
|
||||
if (!htmlDialogs)
|
||||
jsName = '.native' + jsName;
|
||||
|
||||
names = [jsName, '.min.css'].map(function(ext) {
|
||||
return prefix + dir + name + ext;
|
||||
});
|
||||
|
||||
DOM.load.parallel(names, function() {});
|
||||
}
|
||||
|
||||
this.alert = function(title, message) {
|
||||
return smalltalk.alert(title, message);
|
||||
};
|
||||
|
||||
this.prompt = function(title, message, value, options) {
|
||||
return smalltalk.prompt(title, message, value, options);
|
||||
};
|
||||
|
||||
this.confirm = function(title, message, options) {
|
||||
return smalltalk.confirm(title, message, options);
|
||||
};
|
||||
|
||||
this.alert.noFiles = function(title) {
|
||||
return self.alert(title, 'No files selected!');
|
||||
};
|
||||
DOM.load.parallel(names, function() {});
|
||||
}
|
||||
|
||||
})(DOM);
|
||||
this.alert = function(title, message) {
|
||||
return smalltalk.alert(title, message);
|
||||
};
|
||||
|
||||
this.prompt = function(title, message, value, options) {
|
||||
return smalltalk.prompt(title, message, value, options);
|
||||
};
|
||||
|
||||
this.confirm = function(title, message, options) {
|
||||
return smalltalk.confirm(title, message, options);
|
||||
};
|
||||
|
||||
this.alert.noFiles = function(title) {
|
||||
return self.alert(title, 'No files selected!');
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,32 +7,39 @@
|
|||
const itype = require('itype/legacy');
|
||||
const rendy = require('rendy');
|
||||
const exec = require('execon');
|
||||
const jonny = require('jonny');
|
||||
|
||||
const DOMFunc = function() {};
|
||||
const DOMTree = Util.extendProto(DOMTreeProto);
|
||||
const Images = Util.extendProto(ImagesProto);
|
||||
|
||||
const DOMTree = Util.extendProto(DOMTreeProto);
|
||||
const DOMProto = DOMFunc.prototype = new CmdProto();
|
||||
|
||||
Util.extend(DOMProto, [
|
||||
DOMTree, {
|
||||
Images : Images
|
||||
}
|
||||
]);
|
||||
Util.extend(DOMProto, DOMTree);
|
||||
|
||||
const DOM = new DOMFunc();
|
||||
|
||||
DOM.Images = new ImagesProto();
|
||||
|
||||
module.exports = DOM;
|
||||
|
||||
DOM.uploadDirectory = require('./directory');
|
||||
DOM.Buffer = require('./buffer');
|
||||
DOM.Dialog = require('./dialog');
|
||||
DOM.Events = require('./events');
|
||||
DOM.Storage = require('./storage');
|
||||
DOM.Files = require('./files');
|
||||
DOM.RESTful = require('./rest');
|
||||
DOM.load = require('./load');
|
||||
DOM.Notify = require('./notify');
|
||||
|
||||
function ImagesProto() {
|
||||
var Images = new ImageElementProto();
|
||||
const Images = new ImageElementProto();
|
||||
|
||||
function ImageElementProto () {
|
||||
var LOADING = 'loading';
|
||||
var LoadingImage;
|
||||
var HIDDEN = 'hidden';
|
||||
var ERROR = 'error';
|
||||
let LoadingImage;
|
||||
const LOADING = 'loading';
|
||||
const HIDDEN = 'hidden';
|
||||
const ERROR = 'error';
|
||||
|
||||
function getLoadingType() {
|
||||
return DOM.isSVG() ? '-svg' : '-gif';
|
||||
|
|
@ -162,7 +169,7 @@ function ImagesProto() {
|
|||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function DOMTreeProto() {
|
||||
var DOM = this;
|
||||
|
||||
|
|
@ -351,7 +358,7 @@ function CmdProto() {
|
|||
});
|
||||
});
|
||||
|
||||
Util.exec.if(online, funcON, funcOFF);
|
||||
exec.if(online, funcON, funcOFF);
|
||||
});
|
||||
|
||||
return DOM;
|
||||
|
|
@ -444,7 +451,7 @@ function CmdProto() {
|
|||
array = slice.call(files);
|
||||
|
||||
if (n) {
|
||||
Util.exec.eachSeries(array, load, func(files[0].name));
|
||||
exec.eachSeries(array, load, func(files[0].name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -551,10 +558,8 @@ function CmdProto() {
|
|||
*
|
||||
* @currentFile
|
||||
*/
|
||||
this.getCurrentFile = function() {
|
||||
var ret = this.getByClass(CURRENT_FILE);
|
||||
|
||||
return ret;
|
||||
this.getCurrentFile = () => {
|
||||
return DOM.getByClass(CURRENT_FILE);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -648,7 +653,7 @@ function CmdProto() {
|
|||
RESTful.read(link + query, function(error, size) {
|
||||
if (!error) {
|
||||
DOM.setCurrentSize(size, current);
|
||||
Util.exec(callback, current);
|
||||
exec(callback, current);
|
||||
Images.hide();
|
||||
}
|
||||
});
|
||||
|
|
@ -740,7 +745,7 @@ function CmdProto() {
|
|||
|
||||
if (!error) {
|
||||
if (itype.object(data))
|
||||
data = Util.json.stringify(data);
|
||||
data = jonny.stringify(data);
|
||||
|
||||
length = data.length;
|
||||
|
||||
|
|
@ -1171,10 +1176,10 @@ function CmdProto() {
|
|||
*/
|
||||
this.checkStorageHash = function(name, callback) {
|
||||
var Storage = DOM.Storage;
|
||||
var parallel = Util.exec.parallel;
|
||||
var parallel = exec.parallel;
|
||||
var loadHash = DOM.loadCurrentHash;
|
||||
var nameHash = name + '-hash';
|
||||
var getStoreHash = Util.exec.with(Storage.get, nameHash);
|
||||
var getStoreHash = exec.with(Storage.get, nameHash);
|
||||
|
||||
if (typeof name !== 'string')
|
||||
throw Error('name should be a string!');
|
||||
|
|
@ -1210,15 +1215,15 @@ function CmdProto() {
|
|||
var nameData = name + '-data';
|
||||
|
||||
if (!allowed || isDir)
|
||||
return Util.exec(callback);
|
||||
return exec(callback);
|
||||
|
||||
Util.exec.if(hash, function() {
|
||||
exec.if(hash, function() {
|
||||
var Storage = DOM.Storage;
|
||||
|
||||
Storage.set(nameHash, hash);
|
||||
Storage.set(nameData, data);
|
||||
|
||||
Util.exec(callback, hash);
|
||||
exec(callback, hash);
|
||||
}, function(callback) {
|
||||
DOM.loadCurrentHash(function(error, loadHash) {
|
||||
hash = loadHash;
|
||||
|
|
@ -1242,9 +1247,9 @@ function CmdProto() {
|
|||
var isDir = DOM.isCurrentIsDir();
|
||||
|
||||
if (!allowed || isDir)
|
||||
return Util.exec(callback);
|
||||
return exec(callback);
|
||||
|
||||
Util.exec.parallel([
|
||||
exec.parallel([
|
||||
exec.with(Storage.get, nameData),
|
||||
exec.with(Storage.get, nameHash),
|
||||
], callback);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const DOM = require('./dom');
|
||||
const itype = require('itype/legacy');
|
||||
|
||||
var DOMProto = Object.getPrototypeOf(DOM);
|
||||
|
||||
DOMProto.Events = new EventsProto();
|
||||
module.exports = new EventsProto();
|
||||
|
||||
function EventsProto() {
|
||||
const Events = this;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/* global Promise */
|
||||
/* global Util, CloudCmd */
|
||||
/* global CloudCmd */
|
||||
|
||||
'use strict';
|
||||
|
||||
const DOM = require('./dom');
|
||||
|
||||
var DOMProto = Object.getPrototypeOf(DOM);
|
||||
DOMProto.Files = new FilesProto(Util, DOM);
|
||||
module.exports = new FilesProto();
|
||||
|
||||
const itype = require('itype/legacy');
|
||||
const exec = require('execon');
|
||||
|
||||
function FilesProto(Util, DOM) {
|
||||
const Storage = require('./storage');
|
||||
const load = require('./load');
|
||||
const RESTful = require('./rest');
|
||||
|
||||
function FilesProto() {
|
||||
var Promises = {},
|
||||
Storage = DOM.Storage,
|
||||
Files = this,
|
||||
FILES_JSON = 'config|modules',
|
||||
FILES_HTML = 'file|path|link|pathLink|media',
|
||||
|
|
@ -40,7 +41,7 @@ function FilesProto(Util, DOM) {
|
|||
};
|
||||
});
|
||||
|
||||
Util.exec.parallel(funcs, callback);
|
||||
exec.parallel(funcs, callback);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ function FilesProto(Util, DOM) {
|
|||
|
||||
if (!Promises[url])
|
||||
Promises[url] = new Promise(function(resolve, reject) {
|
||||
DOM.load.ajax({
|
||||
load.ajax({
|
||||
url : prefix + url,
|
||||
success : resolve,
|
||||
error : reject
|
||||
|
|
@ -123,8 +124,7 @@ function FilesProto(Util, DOM) {
|
|||
}
|
||||
|
||||
function getConfig(callback) {
|
||||
var is,
|
||||
RESTful = DOM.RESTful;
|
||||
let is;
|
||||
|
||||
if (!Promises.config)
|
||||
Promises.config = new Promise(function(resolve, reject) {
|
||||
|
|
@ -169,3 +169,4 @@ function FilesProto(Util, DOM) {
|
|||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,130 +1,130 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
/* global Util */
|
||||
/* global DOM */
|
||||
/* global Console */
|
||||
/* global exec */
|
||||
|
||||
(function(CloudCmd, Util, DOM) {
|
||||
'use strict';
|
||||
const exec = require('execon');
|
||||
|
||||
CloudCmd.Konsole = ConsoleProto;
|
||||
|
||||
function ConsoleProto() {
|
||||
const config = CloudCmd.config;
|
||||
|
||||
CloudCmd.Konsole = ConsoleProto;
|
||||
var Name = 'Konsole',
|
||||
TITLE = 'Console',
|
||||
|
||||
function ConsoleProto() {
|
||||
var config = CloudCmd.config;
|
||||
var Name = 'Konsole',
|
||||
TITLE = 'Console',
|
||||
|
||||
Element,
|
||||
Loaded,
|
||||
Images = DOM.Images,
|
||||
Dialog = DOM.Dialog,
|
||||
|
||||
Konsole = this;
|
||||
|
||||
function init() {
|
||||
Images.show.load('top');
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
load,
|
||||
create,
|
||||
Konsole.show,
|
||||
]);
|
||||
|
||||
Element = DOM.load({
|
||||
name : 'div',
|
||||
className : 'console'
|
||||
});
|
||||
}
|
||||
Element,
|
||||
Loaded,
|
||||
Images = DOM.Images,
|
||||
Dialog = DOM.Dialog,
|
||||
|
||||
this.hide = function() {
|
||||
CloudCmd.View.hide();
|
||||
Konsole = this;
|
||||
|
||||
function init() {
|
||||
Images.show.load('top');
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
load,
|
||||
create,
|
||||
Konsole.show,
|
||||
]);
|
||||
|
||||
Element = DOM.load({
|
||||
name : 'div',
|
||||
className : 'console'
|
||||
});
|
||||
}
|
||||
|
||||
this.hide = function() {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
|
||||
this.clear = function() {
|
||||
Console.clear();
|
||||
};
|
||||
|
||||
function getPrefix() {
|
||||
return CloudCmd.PREFIX + '/console';
|
||||
}
|
||||
|
||||
function getEnv() {
|
||||
return {
|
||||
ACTIVE_DIR: DOM.getCurrentDirPath.bind(DOM),
|
||||
PASSIVE_DIR: DOM.getNotCurrentDirPath.bind(DOM),
|
||||
CURRENT_NAME: DOM.getCurrentName.bind(DOM),
|
||||
CURRENT_PATH: function() {
|
||||
return DOM.CurrentInfo.path;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function create(callback) {
|
||||
var options = {
|
||||
env: getEnv(),
|
||||
prefix: getPrefix(),
|
||||
socketPath: CloudCmd.PREFIX,
|
||||
};
|
||||
|
||||
this.clear = function() {
|
||||
Console.clear();
|
||||
};
|
||||
Console(Element, options, function(spawn) {
|
||||
spawn.on('connect', exec.with(authCheck, spawn));
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
function getPrefix() {
|
||||
return CloudCmd.PREFIX + '/console';
|
||||
}
|
||||
Console.addShortCuts({
|
||||
'P': function() {
|
||||
var command = Console.getPromptText(),
|
||||
path = DOM.getCurrentDirPath();
|
||||
|
||||
command += path;
|
||||
Console.setPromptText(command);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function authCheck(spawn) {
|
||||
if (!config('auth'))
|
||||
return;
|
||||
|
||||
function getEnv() {
|
||||
return {
|
||||
ACTIVE_DIR: DOM.getCurrentDirPath.bind(DOM),
|
||||
PASSIVE_DIR: DOM.getNotCurrentDirPath.bind(DOM),
|
||||
CURRENT_NAME: DOM.getCurrentName.bind(DOM),
|
||||
CURRENT_PATH: function() {
|
||||
return DOM.CurrentInfo.path;
|
||||
}
|
||||
};
|
||||
}
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
|
||||
function create(callback) {
|
||||
var options = {
|
||||
env: getEnv(),
|
||||
prefix: getPrefix(),
|
||||
socketPath: CloudCmd.PREFIX,
|
||||
};
|
||||
|
||||
Console(Element, options, function(spawn) {
|
||||
spawn.on('connect', exec.with(authCheck, spawn));
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
Console.addShortCuts({
|
||||
'P': function() {
|
||||
var command = Console.getPromptText(),
|
||||
path = DOM.getCurrentDirPath();
|
||||
|
||||
command += path;
|
||||
Console.setPromptText(command);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function authCheck(spawn) {
|
||||
if (!config('auth'))
|
||||
return;
|
||||
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
|
||||
spawn.on('reject', function() {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
this.show = function(callback) {
|
||||
if (Loaded)
|
||||
CloudCmd.View.show(Element, {
|
||||
afterShow: function() {
|
||||
Console.focus();
|
||||
exec(callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function load(callback) {
|
||||
var prefix = getPrefix(),
|
||||
url = prefix + '/console.js';
|
||||
|
||||
DOM.load.js(url, function(error) {
|
||||
if (error) {
|
||||
Dialog.alert(TITLE, error.message);
|
||||
} else {
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
spawn.on('reject', function() {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
this.show = function(callback) {
|
||||
if (Loaded)
|
||||
CloudCmd.View.show(Element, {
|
||||
afterShow: function() {
|
||||
Console.focus();
|
||||
exec(callback);
|
||||
}
|
||||
});
|
||||
|
||||
Util.time(Name + ' load');
|
||||
}
|
||||
};
|
||||
|
||||
function load(callback) {
|
||||
var prefix = getPrefix(),
|
||||
url = prefix + '/console.js';
|
||||
|
||||
if (!CloudCmd.config('console'))
|
||||
return;
|
||||
DOM.load.js(url, function(error) {
|
||||
if (error) {
|
||||
Dialog.alert(TITLE, error.message);
|
||||
} else {
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
exec(callback);
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
Util.time(Name + ' load');
|
||||
}
|
||||
|
||||
})(CloudCmd, Util, DOM);
|
||||
if (!CloudCmd.config('console'))
|
||||
return;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
/* global Util */
|
||||
/* global DOM */
|
||||
|
||||
const DOMProto = Object.getPrototypeOf(DOM);
|
||||
const rendy = require('rendy');
|
||||
const itype = require('itype/legacy');
|
||||
const Emitify = require('emitify');
|
||||
const {Images} = require('./dom');
|
||||
const Events = require('./events');
|
||||
|
||||
DOMProto.load = new LoaderProto(Util, DOM.Images, DOM.Events);
|
||||
module.exports = new LoaderProto(Util, Images, Events);
|
||||
|
||||
function LoaderProto(Util, Images, Events) {
|
||||
/**
|
||||
|
|
@ -269,8 +269,8 @@ function LoaderProto(Util, Images, Events) {
|
|||
|
||||
default:
|
||||
element = load({
|
||||
src : src,
|
||||
func : func
|
||||
src,
|
||||
func,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,16 @@
|
|||
/* global Util */
|
||||
/* global DOM */
|
||||
/* global CloudCmd */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Notify = Util.extendProto(NotifyProto);
|
||||
const DOMProto = Object.getPrototypeOf(DOM);
|
||||
const Events = require('./events');
|
||||
|
||||
Util.extend(DOMProto, {
|
||||
Notify
|
||||
});
|
||||
module.exports = new Notify();
|
||||
|
||||
function NotifyProto() {
|
||||
var Events = DOM.Events,
|
||||
Show,
|
||||
Notify = this,
|
||||
Notification = window.Notification;
|
||||
function Notify() {
|
||||
let Show;
|
||||
|
||||
const Notify = this;
|
||||
const Notification = window.Notification;
|
||||
|
||||
Events.add({
|
||||
'blur': () => {
|
||||
|
|
|
|||
|
|
@ -12,24 +12,32 @@
|
|||
CloudCmd.Operation = OperationProto;
|
||||
|
||||
const currify = require('currify/legacy');
|
||||
const exec = require('execon');
|
||||
const emitify = require('emitify');
|
||||
|
||||
// prevent loading of exec by spero, remedy, ishtar, salam, omnes
|
||||
window.exec = exec;
|
||||
// prevent loading of emitify
|
||||
window.Emitify = emitify;
|
||||
|
||||
const RESTful = require('./rest');
|
||||
|
||||
function OperationProto(operation, data) {
|
||||
let Name = 'Operation',
|
||||
TITLE = CloudCmd.TITLE,
|
||||
config = CloudCmd.config,
|
||||
Loaded,
|
||||
RESTful = DOM.RESTful,
|
||||
|
||||
exec = Util.exec,
|
||||
|
||||
copyFn = RESTful.cp,
|
||||
moveFn = RESTful.mv,
|
||||
deleteFn = RESTful.delete,
|
||||
packFn = RESTful.pack,
|
||||
extractFn = RESTful.extract,
|
||||
|
||||
Images = DOM.Images,
|
||||
Dialog = DOM.Dialog;
|
||||
const Name = 'Operation';
|
||||
const TITLE = CloudCmd.TITLE;
|
||||
const config = CloudCmd.config;
|
||||
const {Dialog, Images} = DOM;
|
||||
|
||||
let Loaded;
|
||||
|
||||
let {
|
||||
cp: copyFn,
|
||||
mv: moveFn,
|
||||
pack: packFn,
|
||||
extract: extractFn,
|
||||
} = RESTful;
|
||||
|
||||
let deleteFn = RESTful.delete;
|
||||
|
||||
const Info = DOM.CurrentInfo;
|
||||
const showLoad = Images.show.load.bind(null, 'top');
|
||||
|
|
@ -38,11 +46,11 @@ function OperationProto(operation, data) {
|
|||
function init() {
|
||||
showLoad();
|
||||
|
||||
Util.exec.series([
|
||||
exec.series([
|
||||
DOM.loadSocket,
|
||||
function(callback) {
|
||||
(callback) => {
|
||||
if (config('progress'))
|
||||
load(function(callback) {
|
||||
load((callback) => {
|
||||
create(CloudCmd.PREFIX, callback);
|
||||
});
|
||||
|
||||
|
|
@ -82,7 +90,7 @@ function OperationProto(operation, data) {
|
|||
});
|
||||
|
||||
copier.on('disconnect', function() {
|
||||
copyFn = DOM.RESTful.cp;
|
||||
copyFn = RESTful.cp;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -101,7 +109,7 @@ function OperationProto(operation, data) {
|
|||
});
|
||||
|
||||
remover.on('disconnect', function() {
|
||||
deleteFn = DOM.RESTful.remove;
|
||||
deleteFn = RESTful.remove;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -119,7 +127,7 @@ function OperationProto(operation, data) {
|
|||
});
|
||||
|
||||
packer.on('disconnect', function() {
|
||||
packFn = RESTful.pack;
|
||||
packFn = RESTful.pack;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -416,11 +424,11 @@ function OperationProto(operation, data) {
|
|||
if (ok)
|
||||
if (!shouldAsk || !sameName)
|
||||
return go;
|
||||
|
||||
const str = `"${ name }" already exist. Overwrite?`;
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(TITLE, str, {cancel}).then(go);
|
||||
|
||||
const str = `"${ name }" already exist. Overwrite?`;
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(TITLE, str, {cancel}).then(go);
|
||||
|
||||
function go() {
|
||||
showLoad();
|
||||
|
|
@ -542,25 +550,24 @@ function OperationProto(operation, data) {
|
|||
}
|
||||
|
||||
function load(callback) {
|
||||
var prefix = CloudCmd.PREFIX,
|
||||
files = [
|
||||
'/spero/spero.js',
|
||||
'/remedy/remedy.js',
|
||||
'/ishtar/ishtar.js',
|
||||
'/salam/salam.js',
|
||||
'/omnes/omnes.js'
|
||||
].map(function(name) {
|
||||
return prefix + name;
|
||||
});
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const files = [
|
||||
'/spero/spero.js',
|
||||
'/remedy/remedy.js',
|
||||
'/ishtar/ishtar.js',
|
||||
'/salam/salam.js',
|
||||
'/omnes/omnes.js'
|
||||
].map((name) => {
|
||||
return prefix + name;
|
||||
});
|
||||
|
||||
DOM.load.parallel(files, function(error) {
|
||||
if (error) {
|
||||
Dialog.alert(TITLE, error.message);
|
||||
} else {
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
Util.exec(callback);
|
||||
}
|
||||
DOM.load.parallel(files, (error) => {
|
||||
if (error)
|
||||
return Dialog.alert(TITLE, error.message);
|
||||
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
Util.time(Name + ' load');
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
|
||||
const itype = require('itype/legacy');
|
||||
|
||||
/* global Util, DOM, CloudFunc, CloudCmd */
|
||||
/* global CloudFunc, CloudCmd */
|
||||
|
||||
const RESTful= Util.extendProto(RESTfulProto);
|
||||
const DOMProto = Object.getPrototypeOf(DOM);
|
||||
module.exports = new RESTful();
|
||||
|
||||
Util.extend(DOMProto, {
|
||||
RESTful
|
||||
});
|
||||
const {Images} = require('./dom');
|
||||
const load = require('./load');
|
||||
const Dialog = require('./dialog');
|
||||
|
||||
function RESTfulProto() {
|
||||
const Images = DOM.Images;
|
||||
|
||||
function RESTful() {
|
||||
this.delete = (url, data, callback) => {
|
||||
var isFunc = itype.function(data);
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
|
|
@ -182,7 +179,7 @@ function RESTfulProto() {
|
|||
*/
|
||||
p.url = p.url.replace('#', '%23');
|
||||
|
||||
DOM.load.ajax({
|
||||
load.ajax({
|
||||
method : p.method,
|
||||
url : p.url,
|
||||
data : p.data,
|
||||
|
|
@ -195,7 +192,7 @@ function RESTfulProto() {
|
|||
|
||||
Images.show.error(text);
|
||||
setTimeout(function() {
|
||||
DOM.Dialog.alert(CloudCmd.TITLE, text);
|
||||
Dialog.alert(CloudCmd.TITLE, text);
|
||||
}, 100);
|
||||
|
||||
p.callback(Error(text));
|
||||
|
|
|
|||
|
|
@ -1,103 +1,90 @@
|
|||
'use strict';
|
||||
|
||||
const itype = require('itype/legacy');
|
||||
const Util = require('../common/util');
|
||||
const DOM = require('./dom');
|
||||
const jonny = require('jonny');
|
||||
const exec = require('execon');
|
||||
|
||||
const Storage = Util.extendProto(StorageProto);
|
||||
const DOMProto = Object.getPrototypeOf(DOM);
|
||||
/* приватный переключатель возможности работы с кэшем */
|
||||
var Allowed;
|
||||
|
||||
Util.extend(DOMProto, {
|
||||
Storage
|
||||
});
|
||||
/* функция проверяет возможно ли работать с кэшем каким-либо образом */
|
||||
module.exports.isAllowed = () => {
|
||||
return Allowed && !!localStorage;
|
||||
};
|
||||
|
||||
function StorageProto() {
|
||||
/* приватный переключатель возможности работы с кэшем */
|
||||
var Allowed;
|
||||
/**
|
||||
* allow Storage usage
|
||||
*/
|
||||
module.exports.setAllowed = (isAllowed) => {
|
||||
Allowed = isAllowed;
|
||||
};
|
||||
|
||||
/** remove element */
|
||||
module.exports.remove = (item, callback) => {
|
||||
if (Allowed)
|
||||
localStorage.removeItem(item);
|
||||
|
||||
/* функция проверяет возможно ли работать с кэшем каким-либо образом */
|
||||
this.isAllowed = () => {
|
||||
return Allowed && !!localStorage;
|
||||
};
|
||||
exec(callback, null, Allowed);
|
||||
|
||||
/**
|
||||
* allow Storage usage
|
||||
*/
|
||||
this.setAllowed = (isAllowed) => {
|
||||
Allowed = isAllowed;
|
||||
};
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
module.exports.removeMatch = (string, callback) => {
|
||||
var reg = RegExp('^' + string + '.*$');
|
||||
|
||||
/** remove element */
|
||||
this.remove = (item, callback) => {
|
||||
var ret = Allowed;
|
||||
Object.keys(localStorage).forEach((name) => {
|
||||
const is = reg.test(name);
|
||||
|
||||
if (ret)
|
||||
localStorage.removeItem(item);
|
||||
|
||||
exec(callback, null, ret);
|
||||
|
||||
return this;
|
||||
};
|
||||
if (is)
|
||||
localStorage.removeItem(name);
|
||||
});
|
||||
|
||||
this.removeMatch = (string, callback) => {
|
||||
var reg = RegExp('^' + string + '.*$');
|
||||
|
||||
Object.keys(localStorage).forEach(function(name) {
|
||||
var is = reg.test(name);
|
||||
|
||||
if (is)
|
||||
localStorage.removeItem(name);
|
||||
exec(callback);
|
||||
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
/** если доступен localStorage и
|
||||
* в нём есть нужная нам директория -
|
||||
* записываем данные в него
|
||||
*/
|
||||
module.exports.set = (name, data, callback) => {
|
||||
var str, error;
|
||||
|
||||
if (itype.object(data))
|
||||
str = jonny.stringify(data);
|
||||
|
||||
if (Allowed && name)
|
||||
error = exec.try(() => {
|
||||
localStorage.setItem(name, str || data);
|
||||
});
|
||||
|
||||
exec(callback);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** если доступен localStorage и
|
||||
* в нём есть нужная нам директория -
|
||||
* записываем данные в него
|
||||
*/
|
||||
this.set = (name, data, callback) => {
|
||||
var str, error;
|
||||
|
||||
if (itype.object(data))
|
||||
str = jonny.stringify(data);
|
||||
|
||||
if (Allowed && name)
|
||||
error = exec.try(() => {
|
||||
localStorage.setItem(name, str || data);
|
||||
});
|
||||
|
||||
exec(callback, error);
|
||||
|
||||
return this;
|
||||
},
|
||||
exec(callback, error);
|
||||
|
||||
/** Если доступен Storage принимаем из него данные*/
|
||||
this.get = function(name, callback) {
|
||||
var ret;
|
||||
|
||||
if (Allowed)
|
||||
ret = localStorage.getItem(name);
|
||||
|
||||
exec(callback, null, ret);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/** функция чистит весь кэш для всех каталогов*/
|
||||
this.clear = function(callback) {
|
||||
var ret = Allowed;
|
||||
|
||||
if (ret)
|
||||
localStorage.clear();
|
||||
|
||||
exec(callback, null, ret);
|
||||
|
||||
return this;
|
||||
};
|
||||
}
|
||||
return module.exports;
|
||||
},
|
||||
|
||||
/** Если доступен Storage принимаем из него данные*/
|
||||
module.exports.get = (name, callback) => {
|
||||
var ret;
|
||||
|
||||
if (Allowed)
|
||||
ret = localStorage.getItem(name);
|
||||
|
||||
exec(callback, null, ret);
|
||||
|
||||
return module.exports;
|
||||
},
|
||||
|
||||
/** функция чистит весь кэш для всех каталогов*/
|
||||
module.exports.clear = (callback) => {
|
||||
var ret = Allowed;
|
||||
|
||||
if (ret)
|
||||
localStorage.clear();
|
||||
|
||||
exec(callback, null, ret);
|
||||
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"name": "promise-polyfill",
|
||||
"version": "6.0.2",
|
||||
"homepage": "https://github.com/taylorhakes/promise-polyfill",
|
||||
"authors": [
|
||||
"Taylor Hakes"
|
||||
],
|
||||
"description": "Lightweight promise polyfill for the browser and node. A+ Compliant.",
|
||||
"main": "promise.js",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"promise",
|
||||
"es6",
|
||||
"polyfill",
|
||||
"html5"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "6.0.2",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "6.0.2",
|
||||
"commit": "3591c457e9999ecf5e5c648ed68d4f21a0ad3d11"
|
||||
},
|
||||
"_source": "https://github.com/taylorhakes/promise-polyfill.git",
|
||||
"_target": "6.0.2",
|
||||
"_originalSource": "promise-polyfill"
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
## 6.0.0 Deprecated `Promise._setImmediateFn` and `Promise._setUnhandledRejectionFn`
|
||||
This allows subclassing Promise without rewriting functions
|
||||
- `Promise._setImmediateFn(<immediateFn>)` has been deprecated. Use `Promise._immediateFn = <immediateFn>` instead.
|
||||
- `Promise._setUnhandledRejectionFn(<rejectionFn>)` has been deprecated. Use `Promise._unhandledRejectionFn = <rejectionFn>` instead.
|
||||
These functions will be removed in the next major version.
|
||||
|
||||
### 5.2.1 setTimeout to 0
|
||||
Fixed bug where setTimeout was set to 1 instead of 0 for async execution
|
||||
|
||||
### 5.2.0 Subclassing
|
||||
Allowed Subclassing. [#27](https://github.com/taylorhakes/promise-polyfill/pull/27)
|
||||
|
||||
### 5.1.0 Fixed reliance on setTimeout
|
||||
Changed possibly unhanded warnings to use asap function instead of setTimeout
|
||||
|
||||
## 5.0.0 Removed multiple params from Promise.all
|
||||
Removed non standard functionality of passing multiple params to Promise.all. You must pass an array now. You must change this code
|
||||
```js
|
||||
Promise.all(prom1, prom2, prom3);
|
||||
```
|
||||
to this
|
||||
```js
|
||||
Promise.all([prom1, prom2, prom3]);
|
||||
```
|
||||
|
||||
### 4.0.4 IE8 console.warn fix
|
||||
IE8 does not have console, unless you open the developer tools. This fix checks to makes sure console.warn is defined before calling it.
|
||||
|
||||
### 4.0.3 Fix case in bower.json
|
||||
bower.json had Promise.js instead of promise.js
|
||||
|
||||
### 4.0.2 promise.js case fix in package.json
|
||||
Fixed promise.js in package.json. It was accidently published as Promise.js
|
||||
|
||||
## 4.0.1 Unhandled Rejections and Other Fixes
|
||||
- Added unhandled rejection warnings to the console
|
||||
- Removed Grunt, jasmine and other unused code
|
||||
- Renamed Promise.js to lowercase promise.js in multiple places
|
||||
|
||||
### 3.0.1 Fixed shadowing issue on setTimeout
|
||||
New version fixing this major bug https://github.com/taylorhakes/promise-polyfill/pull/17
|
||||
|
||||
## 3.0.0 Updated setTimeout to not be affected by test mocks
|
||||
This is considered a breaking change because people may have been using this functionality. If you would like to keep version 2 functionality, set Promise._setImmediateFn on `promise-polyfill` like the code below.
|
||||
|
||||
```js
|
||||
var Promise = require('promise-polyfill');
|
||||
Promise._setImmedateFn(function(fn) {
|
||||
setTimeout(fn, 1);
|
||||
});
|
||||
```
|
||||
|
||||
### 2.1.0 Promise._setImmedateFn
|
||||
Removed dead code Promise.immedateFn and added Promise._setImmediateFn(fn);
|
||||
|
||||
### 2.0.2 Simplified Global detection
|
||||
Simplified attaching to global object
|
||||
|
||||
### 2.0.1 Webworker bugfixes
|
||||
Fixed Webworkers missing window object
|
||||
|
||||
## 2.0.0
|
||||
**Changed the following line**
|
||||
```
|
||||
module.exports = root.Promise ? root.Promise : Promise;
|
||||
```
|
||||
to
|
||||
```
|
||||
module.exports = Promise;
|
||||
```
|
||||
|
||||
This means the library will not use built-in Promise by default. This allows for more consistency.
|
||||
|
||||
You can easily add the functionality back.
|
||||
```
|
||||
var Promise = window.Promise || require('promise-polyfill');
|
||||
```
|
||||
|
||||
**Added Promise.immediateFn to allow changing the setImmedate function**
|
||||
```
|
||||
Promise.immediateFn = window.setAsap;
|
||||
```
|
||||
|
||||
### 1.1.4 Updated Promise to use correct global object in Browser and Node
|
||||
|
||||
### 1.1.3 Fixed browserify issue with `this`
|
||||
|
||||
### 1.1.2 Updated Promise.resolve to resolve with original Promise
|
||||
|
||||
### 1.1.0 Performance Improvements for Modern Browsers
|
||||
|
||||
## 1.0.1 Update README.md
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
Copyright (c) 2014 Taylor Hakes
|
||||
Copyright (c) 2014 Forbes Lindesay
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
<a href="http://promises-aplus.github.com/promises-spec">
|
||||
<img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png"
|
||||
align="right" alt="Promises/A+ logo" />
|
||||
</a>
|
||||
# Promise Polyfill
|
||||
[![travis][travis-image]][travis-url]
|
||||
|
||||
[travis-image]: https://img.shields.io/travis/taylorhakes/promise-polyfill.svg?style=flat
|
||||
[travis-url]: https://travis-ci.org/taylorhakes/promise-polyfill
|
||||
|
||||
|
||||
Lightweight ES6 Promise polyfill for the browser and node. Adheres closely to the spec. It is a perfect polyfill IE, Firefox or any other browser that does not support native promises.
|
||||
|
||||
For API information about Promises, please check out this article [HTML5Rocks article](http://www.html5rocks.com/en/tutorials/es6/promises/).
|
||||
|
||||
It is extremely lightweight. ***< 1kb Gzipped***
|
||||
|
||||
## Browser Support
|
||||
IE8+, Chrome, Firefox, IOS 4+, Safari 5+, Opera
|
||||
|
||||
### NPM Use
|
||||
```
|
||||
npm install promise-polyfill --save-exact
|
||||
```
|
||||
### Bower Use
|
||||
```
|
||||
bower install promise-polyfill
|
||||
```
|
||||
|
||||
## Downloads
|
||||
|
||||
- [Promise](https://raw.github.com/taylorhakes/promise-polyfill/master/promise.js)
|
||||
- [Promise-min](https://raw.github.com/taylorhakes/promise-polyfill/master/promise.min.js)
|
||||
|
||||
## Simple use
|
||||
```js
|
||||
var prom = new Promise(function(resolve, reject) {
|
||||
// do a thing, possibly async, then…
|
||||
|
||||
if (/* everything turned out fine */) {
|
||||
resolve("Stuff worked!");
|
||||
} else {
|
||||
reject(new Error("It broke"));
|
||||
}
|
||||
});
|
||||
|
||||
prom.then(function(result) {
|
||||
// Do something when async done
|
||||
});
|
||||
```
|
||||
|
||||
## Deprecations
|
||||
- `Promise._setImmediateFn(<immediateFn>)` has been deprecated. Use `Promise._immediateFn = <immediateFn>;` instead.
|
||||
- `Promise._setUnhandledRejectionFn(<rejectionFn>)` has been deprecated. Use `Promise._unhandledRejectionFn = <rejectionFn>` instead.
|
||||
These functions will be removed in the next major version.
|
||||
|
||||
## Performance
|
||||
By default promise-polyfill uses `setImmediate`, but falls back to `setTimeout` for executing asynchronously. If a browser does not support `setImmediate` (IE/Edge are the only browsers with setImmediate), you may see performance issues.
|
||||
Use a `setImmediate` polyfill to fix this issue. [setAsap](https://github.com/taylorhakes/setAsap) or [setImmediate](https://github.com/YuzuJS/setImmediate) work well.
|
||||
|
||||
If you polyfill `window.setImmediate` or use `Promise._immediateFn = yourImmediateFn` it will be used instead of `window.setTimeout`
|
||||
```
|
||||
npm install setasap --save
|
||||
```
|
||||
```js
|
||||
var Promise = require('promise-polyfill');
|
||||
var setAsap = require('setasap');
|
||||
Promise._immediateFn = setAsap;
|
||||
```
|
||||
|
||||
## Unhandled Rejections
|
||||
promise-polyfill will warn you about possibly unhandled rejections. It will show a console warning if a Promise is rejected, but no `.catch` is used. You can turn off this behavior by setting `Promise._setUnhandledRejectionFn(<rejectError>)`.
|
||||
If you would like to disable unhandled rejections. Use a noop like below.
|
||||
```js
|
||||
Promise._unhandledRejectionFn = function(rejectError) {};
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
```
|
||||
npm install
|
||||
npm test
|
||||
```
|
||||
|
||||
## License
|
||||
MIT
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name": "promise-polyfill",
|
||||
"version": "2.1.0",
|
||||
"homepage": "https://github.com/taylorhakes/promise-polyfill",
|
||||
"authors": [
|
||||
"Taylor Hakes"
|
||||
],
|
||||
"description": "Lightweight promise polyfill for the browser and node. A+ Compliant.",
|
||||
"main": "promise.js",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"promise",
|
||||
"es6",
|
||||
"polyfill",
|
||||
"html5"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// Karma configuration
|
||||
// Generated on Tue Jan 12 2016 07:56:12 GMT-0500 (EST)
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['mocha', 'browserify'],
|
||||
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'test/promise.js'
|
||||
],
|
||||
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [],
|
||||
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
'test/promise.js': ['browserify']
|
||||
},
|
||||
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['progress'],
|
||||
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['Chrome'],
|
||||
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
singleRun: false,
|
||||
|
||||
// Concurrency level
|
||||
// how many browser should be started simultaneous
|
||||
concurrency: Infinity,
|
||||
|
||||
plugins: [
|
||||
'karma-browserify',
|
||||
'karma-mocha',
|
||||
'karma-chrome-launcher'
|
||||
]
|
||||
})
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"name": "promise-polyfill",
|
||||
"version": "6.0.2",
|
||||
"description": "Lightweight promise polyfill. A+ compliant",
|
||||
"main": "promise.js",
|
||||
"scripts": {
|
||||
"test": "eslint promise.js && mocha && karma start --single-run",
|
||||
"build": "uglifyjs --compress --support-ie8 --mangle -o promise.min.js -- promise.js "
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://taylorhakes@github.com/taylorhakes/promise-polyfill.git"
|
||||
},
|
||||
"author": "Taylor Hakes",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/taylorhakes/promise-polyfill/issues"
|
||||
},
|
||||
"homepage": "https://github.com/taylorhakes/promise-polyfill",
|
||||
"devDependencies": {
|
||||
"eslint": "^2.4.0",
|
||||
"karma": "^0.13.19",
|
||||
"karma-browserify": "^4.4.2",
|
||||
"karma-chrome-launcher": "^0.2.2",
|
||||
"karma-mocha": "^0.2.1",
|
||||
"mocha": "^2.3.4",
|
||||
"promises-aplus-tests": "*",
|
||||
"sinon": "^1.17.2",
|
||||
"uglify-js": "^2.6.2"
|
||||
},
|
||||
"keywords": [
|
||||
"promise",
|
||||
"promise-polyfill",
|
||||
"ES6",
|
||||
"promises-aplus"
|
||||
],
|
||||
"dependencies": {}
|
||||
}
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
(function (root) {
|
||||
|
||||
// Store setTimeout reference so promise-polyfill will be unaffected by
|
||||
// other code modifying setTimeout (like sinon.useFakeTimers())
|
||||
var setTimeoutFunc = setTimeout;
|
||||
|
||||
function noop() {}
|
||||
|
||||
// Polyfill for Function.prototype.bind
|
||||
function bind(fn, thisArg) {
|
||||
return function () {
|
||||
fn.apply(thisArg, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function Promise(fn) {
|
||||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new');
|
||||
if (typeof fn !== 'function') throw new TypeError('not a function');
|
||||
this._state = 0;
|
||||
this._handled = false;
|
||||
this._value = undefined;
|
||||
this._deferreds = [];
|
||||
|
||||
doResolve(fn, this);
|
||||
}
|
||||
|
||||
function handle(self, deferred) {
|
||||
while (self._state === 3) {
|
||||
self = self._value;
|
||||
}
|
||||
if (self._state === 0) {
|
||||
self._deferreds.push(deferred);
|
||||
return;
|
||||
}
|
||||
self._handled = true;
|
||||
Promise._immediateFn(function () {
|
||||
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
|
||||
if (cb === null) {
|
||||
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
|
||||
return;
|
||||
}
|
||||
var ret;
|
||||
try {
|
||||
ret = cb(self._value);
|
||||
} catch (e) {
|
||||
reject(deferred.promise, e);
|
||||
return;
|
||||
}
|
||||
resolve(deferred.promise, ret);
|
||||
});
|
||||
}
|
||||
|
||||
function resolve(self, newValue) {
|
||||
try {
|
||||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
|
||||
if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.');
|
||||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
|
||||
var then = newValue.then;
|
||||
if (newValue instanceof Promise) {
|
||||
self._state = 3;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
return;
|
||||
} else if (typeof then === 'function') {
|
||||
doResolve(bind(then, newValue), self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self._state = 1;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
} catch (e) {
|
||||
reject(self, e);
|
||||
}
|
||||
}
|
||||
|
||||
function reject(self, newValue) {
|
||||
self._state = 2;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
}
|
||||
|
||||
function finale(self) {
|
||||
if (self._state === 2 && self._deferreds.length === 0) {
|
||||
Promise._immediateFn(function() {
|
||||
if (!self._handled) {
|
||||
Promise._unhandledRejectionFn(self._value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0, len = self._deferreds.length; i < len; i++) {
|
||||
handle(self, self._deferreds[i]);
|
||||
}
|
||||
self._deferreds = null;
|
||||
}
|
||||
|
||||
function Handler(onFulfilled, onRejected, promise) {
|
||||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
|
||||
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
|
||||
this.promise = promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a potentially misbehaving resolver function and make sure
|
||||
* onFulfilled and onRejected are only called once.
|
||||
*
|
||||
* Makes no guarantees about asynchrony.
|
||||
*/
|
||||
function doResolve(fn, self) {
|
||||
var done = false;
|
||||
try {
|
||||
fn(function (value) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
resolve(self, value);
|
||||
}, function (reason) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, reason);
|
||||
});
|
||||
} catch (ex) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, ex);
|
||||
}
|
||||
}
|
||||
|
||||
Promise.prototype['catch'] = function (onRejected) {
|
||||
return this.then(null, onRejected);
|
||||
};
|
||||
|
||||
Promise.prototype.then = function (onFulfilled, onRejected) {
|
||||
var prom = new (this.constructor)(noop);
|
||||
|
||||
handle(this, new Handler(onFulfilled, onRejected, prom));
|
||||
return prom;
|
||||
};
|
||||
|
||||
Promise.all = function (arr) {
|
||||
var args = Array.prototype.slice.call(arr);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (args.length === 0) return resolve([]);
|
||||
var remaining = args.length;
|
||||
|
||||
function res(i, val) {
|
||||
try {
|
||||
if (val && (typeof val === 'object' || typeof val === 'function')) {
|
||||
var then = val.then;
|
||||
if (typeof then === 'function') {
|
||||
then.call(val, function (val) {
|
||||
res(i, val);
|
||||
}, reject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
args[i] = val;
|
||||
if (--remaining === 0) {
|
||||
resolve(args);
|
||||
}
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
res(i, args[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Promise.resolve = function (value) {
|
||||
if (value && typeof value === 'object' && value.constructor === Promise) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.reject = function (value) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.race = function (values) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
for (var i = 0, len = values.length; i < len; i++) {
|
||||
values[i].then(resolve, reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Use polyfill for setImmediate for performance gains
|
||||
Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) ||
|
||||
function (fn) {
|
||||
setTimeoutFunc(fn, 0);
|
||||
};
|
||||
|
||||
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
|
||||
if (typeof console !== 'undefined' && console) {
|
||||
console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the immediate function to execute callbacks
|
||||
* @param fn {function} Function to execute
|
||||
* @deprecated
|
||||
*/
|
||||
Promise._setImmediateFn = function _setImmediateFn(fn) {
|
||||
Promise._immediateFn = fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the function to execute on unhandled rejection
|
||||
* @param {function} fn Function to execute on unhandled rejection
|
||||
* @deprecated
|
||||
*/
|
||||
Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {
|
||||
Promise._unhandledRejectionFn = fn;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Promise;
|
||||
} else if (!root.Promise) {
|
||||
root.Promise = Promise;
|
||||
}
|
||||
|
||||
})(this);
|
||||
1
modules/promise-polyfill/promise.min.js
vendored
1
modules/promise-polyfill/promise.min.js
vendored
|
|
@ -1 +0,0 @@
|
|||
!function(e){function n(){}function t(e,n){return function(){e.apply(n,arguments)}}function o(e){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],s(e,this)}function i(e,n){for(;3===e._state;)e=e._value;return 0===e._state?void e._deferreds.push(n):(e._handled=!0,void o._immediateFn(function(){var t=1===e._state?n.onFulfilled:n.onRejected;if(null===t)return void(1===e._state?r:u)(n.promise,e._value);var o;try{o=t(e._value)}catch(i){return void u(n.promise,i)}r(n.promise,o)}))}function r(e,n){try{if(n===e)throw new TypeError("A promise cannot be resolved with itself.");if(n&&("object"==typeof n||"function"==typeof n)){var i=n.then;if(n instanceof o)return e._state=3,e._value=n,void f(e);if("function"==typeof i)return void s(t(i,n),e)}e._state=1,e._value=n,f(e)}catch(r){u(e,r)}}function u(e,n){e._state=2,e._value=n,f(e)}function f(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var n=0,t=e._deferreds.length;n<t;n++)i(e,e._deferreds[n]);e._deferreds=null}function c(e,n,t){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof n?n:null,this.promise=t}function s(e,n){var t=!1;try{e(function(e){t||(t=!0,r(n,e))},function(e){t||(t=!0,u(n,e))})}catch(o){if(t)return;t=!0,u(n,o)}}var a=setTimeout;o.prototype["catch"]=function(e){return this.then(null,e)},o.prototype.then=function(e,t){var o=new this.constructor(n);return i(this,new c(e,t,o)),o},o.all=function(e){var n=Array.prototype.slice.call(e);return new o(function(e,t){function o(r,u){try{if(u&&("object"==typeof u||"function"==typeof u)){var f=u.then;if("function"==typeof f)return void f.call(u,function(e){o(r,e)},t)}n[r]=u,0===--i&&e(n)}catch(c){t(c)}}if(0===n.length)return e([]);for(var i=n.length,r=0;r<n.length;r++)o(r,n[r])})},o.resolve=function(e){return e&&"object"==typeof e&&e.constructor===o?e:new o(function(n){n(e)})},o.reject=function(e){return new o(function(n,t){t(e)})},o.race=function(e){return new o(function(n,t){for(var o=0,i=e.length;o<i;o++)e[o].then(n,t)})},o._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){a(e,0)},o._unhandledRejectionFn=function(e){"undefined"!=typeof console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)},o._setImmediateFn=function(e){o._immediateFn=e},o._setUnhandledRejectionFn=function(e){o._unhandledRejectionFn=e},"undefined"!=typeof module&&module.exports?module.exports=o:e.Promise||(e.Promise=o)}(this);
|
||||
|
|
@ -52,7 +52,6 @@
|
|||
"lint:css": "recess css/*.css",
|
||||
"lint:style": "stylelint css/*.css",
|
||||
"lint:js": "redrun jshint jscs eslint:*",
|
||||
"lint:js:es5": "redrun es5:*",
|
||||
"eslint:bin": "eslint --rule 'no-console:0' bin test server",
|
||||
"fix:eslint:bin": "redrun eslint:bin -- --fix",
|
||||
"jshint": "jshint bin client server",
|
||||
|
|
@ -167,6 +166,7 @@
|
|||
"nsp": "^2.2.1",
|
||||
"nyc": "^9.0.1",
|
||||
"place": "^1.1.4",
|
||||
"promise-polyfill": "^6.0.2",
|
||||
"readjson": "^1.1.3",
|
||||
"recess": "^1.1.9",
|
||||
"redrun": "^5.0.0",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ const {optimize} = webpack
|
|||
const {UglifyJsPlugin} = optimize;
|
||||
|
||||
const dir = './client';
|
||||
const dirExternal = './node_modules';
|
||||
|
||||
const {env} = process;
|
||||
const isDebug = env.NODE_ENV === 'debug';
|
||||
|
|
@ -28,7 +29,9 @@ module.exports = {
|
|||
upload: `${dir}/upload.js`,
|
||||
operation: `${dir}/operation.js`,
|
||||
konsole: `${dir}/konsole.js`,
|
||||
cloud: `${dir}/cloud.js`
|
||||
cloud: `${dir}/cloud.js`,
|
||||
|
||||
promise: `${dirExternal}/promise-polyfill/promise.js`,
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue