mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-24 03:05:41 +00:00
221 lines
No EOL
7.4 KiB
JavaScript
221 lines
No EOL
7.4 KiB
JavaScript
'use strict';
|
|
|
|
(function (global) {
|
|
'use strict';
|
|
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = SmallTalk();else global.smalltalk = SmallTalk();
|
|
|
|
function SmallTalk(callback) {
|
|
if (!(this instanceof SmallTalk)) return new SmallTalk(callback);
|
|
|
|
var remove = bind(removeEl, '.smalltalk');
|
|
|
|
var BUTTON_OK = ['OK'];
|
|
var BUTTON_OK_CANCEL = ['OK', 'Cancel'];
|
|
|
|
this.alert = function (title, msg, options) {
|
|
return showDialog(title, msg, '', BUTTON_OK, options);
|
|
};
|
|
|
|
this.prompt = function (title, msg, value, options) {
|
|
var val = value || '';
|
|
var valueStr = '<input type="text" value="' + val + '" data-name="js-input">';
|
|
|
|
return showDialog(title, msg, valueStr, BUTTON_OK_CANCEL, options);
|
|
};
|
|
|
|
this.confirm = function (title, msg, options) {
|
|
return showDialog(title, msg, '', BUTTON_OK_CANCEL, options);
|
|
};
|
|
|
|
function getTemplate(title, msg, value, buttons) {
|
|
if (!Array.isArray(buttons)) throw Error('buttons should be array!');
|
|
|
|
return '<div class="page">\n <div data-name="js-close" class="close-button"></div>\n <header>' + title + '</header>\n <div class="content-area">\n ' + msg + '\n ' + value + '\n </div>\n <div class="action-area">\n <div class="button-strip"> ' + buttons.map(function (name, i) {
|
|
return '<button tabindex=' + i + ' data-name="js-' + name.toLowerCase() + '">' + name + '</button>';
|
|
}).join('') + '\n </div>\n </div>\n </div>';
|
|
}
|
|
|
|
function showDialog(title, msg, value, buttons, options) {
|
|
var dialog = document.createElement('div'),
|
|
closeButtons = ['cancel', 'close', 'ok'],
|
|
ok = undefined,
|
|
cancel = undefined,
|
|
promise = new Promise(function (resolve, reject) {
|
|
var noCancel = options && !options.cancel;
|
|
var empty = function empty() {};
|
|
|
|
ok = resolve;
|
|
cancel = reject;
|
|
|
|
if (noCancel) cancel = empty;
|
|
}),
|
|
tmpl = getTemplate(title, msg, value, buttons);
|
|
|
|
dialog.innerHTML = tmpl;
|
|
dialog.className = 'smalltalk';
|
|
|
|
document.body.appendChild(dialog);
|
|
|
|
find(dialog, ['ok', 'input']).forEach(function (el) {
|
|
return el.focus();
|
|
});
|
|
|
|
find(dialog, ['input']).forEach(function (el) {
|
|
el.setSelectionRange(0, value.length);
|
|
});
|
|
|
|
addListeterAll('click', dialog, closeButtons, function (event) {
|
|
return closeDialog(event.target, dialog, ok, cancel);
|
|
});
|
|
|
|
['click', 'contextmenu'].forEach(function (event) {
|
|
return dialog.addEventListener(event, function () {
|
|
return find(dialog, ['ok', 'input']).forEach(function (el) {
|
|
return el.focus();
|
|
});
|
|
});
|
|
});
|
|
|
|
dialog.addEventListener('keydown', keyDown(dialog, ok, cancel));
|
|
|
|
return promise;
|
|
}
|
|
|
|
function keyDown(dialog, ok, cancel) {
|
|
return function (event) {
|
|
var KEY = {
|
|
ENTER: 13,
|
|
ESC: 27,
|
|
TAB: 9,
|
|
LEFT: 37,
|
|
UP: 38,
|
|
RIGHT: 39,
|
|
DOWN: 40
|
|
};
|
|
|
|
var keyCode = event.keyCode,
|
|
el = event.target;
|
|
|
|
var namesAll = ['ok', 'cancel', 'input'],
|
|
names = find(dialog, namesAll).map(function (el) {
|
|
return getDataName(el);
|
|
});
|
|
|
|
switch (keyCode) {
|
|
case KEY.ENTER:
|
|
closeDialog(el, dialog, ok, cancel);
|
|
event.preventDefault();
|
|
break;
|
|
|
|
case KEY.ESC:
|
|
remove();
|
|
cancel();
|
|
break;
|
|
|
|
case KEY.TAB:
|
|
if (event.shiftKey) tab(dialog, names);
|
|
|
|
tab(dialog, names);
|
|
event.preventDefault();
|
|
break;
|
|
|
|
default:
|
|
var is = ['left', 'right', 'up', 'down'].some(function (name) {
|
|
return keyCode === KEY[name.toUpperCase()];
|
|
});
|
|
|
|
if (is) changeButtonFocus(dialog, names);
|
|
|
|
break;
|
|
}
|
|
|
|
event.stopPropagation();
|
|
};
|
|
}
|
|
|
|
function getDataName(el) {
|
|
return el.getAttribute('data-name').replace('js-', '');
|
|
}
|
|
|
|
function changeButtonFocus(dialog, names) {
|
|
var name = '',
|
|
active = document.activeElement,
|
|
activeName = getDataName(active),
|
|
isButton = /ok|cancel/.test(activeName),
|
|
count = names.length - 1;
|
|
|
|
if (activeName !== 'input' && count && isButton) {
|
|
if (activeName === 'cancel') name = 'ok';else name = 'cancel';
|
|
|
|
find(dialog, [name]).forEach(function (el) {
|
|
return el.focus();
|
|
});
|
|
}
|
|
}
|
|
|
|
function tab(dialog, names) {
|
|
var active = document.activeElement,
|
|
activeName = getDataName(active),
|
|
count = names.length - 1,
|
|
index = names.indexOf(activeName);
|
|
|
|
if (index === count) index = 0;else if (index < count) ++index;
|
|
|
|
var name = names[index];
|
|
|
|
find(dialog, [name]).forEach(function (el) {
|
|
return el.focus();
|
|
});
|
|
}
|
|
|
|
function closeDialog(el, dialog, ok, cancel) {
|
|
var value = undefined,
|
|
name = el.getAttribute('data-name').replace('js-', '');
|
|
|
|
if (/close|cancel/.test(name)) {
|
|
cancel();
|
|
} else {
|
|
value = find(dialog, ['input']).reduce(function (value, el) {
|
|
return el.value;
|
|
}, null);
|
|
|
|
ok(value);
|
|
}
|
|
|
|
remove();
|
|
}
|
|
|
|
function find(element, names) {
|
|
var elements = names.map(function (name) {
|
|
return element.querySelector('[data-name="js-' + name + '"]');
|
|
}).filter(function (el) {
|
|
return el;
|
|
});
|
|
|
|
return elements;
|
|
}
|
|
|
|
function addListeterAll(event, parent, elements, fn) {
|
|
find(parent, elements).forEach(function (el) {
|
|
return el.addEventListener(event, fn);
|
|
});
|
|
}
|
|
|
|
function removeEl(name) {
|
|
var el = document.querySelector(name);
|
|
|
|
el.parentElement.removeChild(el);
|
|
}
|
|
|
|
function bind(fn) {
|
|
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
args[_key - 1] = arguments[_key];
|
|
}
|
|
|
|
return function () {
|
|
return fn.apply(undefined, args);
|
|
};
|
|
}
|
|
}
|
|
})(typeof window !== 'undefined' && window); |