// ==UserScript==
// @name Mouse Gestures like Opera
// @namespace https://greasyfork.org/users/37096/
// @homepage https://greasyfork.org/scripts/33398/
// @supportURL https://greasyfork.org/scripts/33398/feedback
// @version 1.1.0
// @description A Mouse Gestures script is the same as in the old Opera
// @author Hồng Minh Tâm
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @icon https://png.icons8.com/ultraviolet/40/000000/mouse-right-click.png
// @include *
// @compatible chrome
// @license GNU GPLv3
// @grant GM_addStyle
// @grant GM_openInTab
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @grant window.close
// @grant window.focus
// @grant unsafeWindow
// @noframes
// ==/UserScript==
(function () {
'use strict';
GM_addStyle([
'[class*="mglo-"], [class*="mglo-"] * { background-color: transparent; color: #333; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 400; line-height: 1.5; padding: 0; margin: 0; min-width: auto; min-height: auto; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }',
'[class*="mglo-"]:before, [class*="mglo-"]:after, [class*="mglo-"] *:before, [class*="mglo-"] *:after { background-color: transparent; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }',
/*main*/
'.mglo { z-index: 10000000000; position: fixed; overflow: hidden; border: 1px solid #CCC; white-space: nowrap; font-family: sans-serif; background-color: rgba(0, 0, 0, 0.7); color: #333; border-radius: 50%; width: 400px; height: 400px; }',
'.mglo .mglo-middle, .mglo .mglo-up, .mglo .mglo-down, .mglo .mglo-left, .mglo .mglo-right { display: table; position: absolute; height: 160px; width: 160px; padding: 0; margin: 0; }',
'.mglo .mglo-middle { top: 50%; left: 50%; margin-top: -20px; margin-left: -80px; width: 160px; height: 160px; text-align: center; }',
'.mglo .mglo-up { top: 0; left: 50%; margin-left: -80px; }',
'.mglo .mglo-down { bottom: 0; left: 50%; margin-left: -80px; }',
'.mglo .mglo-left { top: 50%; left: 0; margin-top: -80px; }',
'.mglo .mglo-right { top: 50%; right: 0; margin-top: -80px; }',
'.mglo .mglo-label { color: #fff; font-family: Arial,"Helvetica Neue",Helvetica,sans-serif; font-weight: 700; font-size: 16px; text-transform: none; letter-spacing: normal; white-space: pre-wrap; padding: 0; margin: 0; -webkit-transition: all .2s; -moz-transition: all .2s; transition: all .2s; line-height: 22px; }',
'.mglo .mglo-up > .mglo-label { display: table-cell; vertical-align: bottom; text-align: center; padding-bottom: 50px; }',
'.mglo .mglo-down > .mglo-label { display: table-cell; vertical-align: top; text-align: center; padding-top: 50px; }',
'.mglo .mglo-left > .mglo-label { display: table-cell; vertical-align: middle; text-align: right; padding-right: 50px; }',
'.mglo .mglo-right > .mglo-label { display: table-cell; vertical-align: middle; text-align: left; padding-left: 50px; }',
'.mglo .mglo-icon { position: absolute; width: initial; display: initial; }',
'.mglo .mglo-middle > .mglo-icon { position: initial; }',
'.mglo .mglo-up > .mglo-icon { bottom: 0; left: 50%; margin-left: -20px; }',
'.mglo .mglo-down > .mglo-icon { top: 0; left: 50%; margin-left: -20px; }',
'.mglo .mglo-left > .mglo-icon { top: 50%; right: 0; margin-top: -20px; }',
'.mglo .mglo-right > .mglo-icon { top: 50%; left: 0; margin-top: -20px; }',
'.mglo .active > .mglo-label { background-color: transparent; color: #ffff00; }',
'.mglo .mglo-up.active > .mglo-label { padding-bottom: 10px; }',
'.mglo .mglo-down.active > .mglo-label { padding-top: 10px; }',
'.mglo .mglo-left.active > .mglo-label { padding-right: 10px; }',
'.mglo .mglo-right.active > .mglo-label { padding-left: 10px; }',
'.mglo .active > .mglo-icon { display: none; }',
'.mglo.hide, .mglo .hide { display: none; }',
/*list icon*/
'.mglo-list-icon { line-height: 0; margin-bottom: 10px; }',
'.mglo-list-icon > .mglo-icon { width: 30px; height: 30px; -webkit-user-drag: none; user-select: none; }',
'.mglo-list-icon-group > label { display: inline-block; margin-bottom: 5px; }',
'.mglo-list-icon-group.inline .mglo-list-icon { display: inline-block; }',
/*dialog*/
'.mglo-dialog { z-index: 9999999999; padding-top: 30px; padding-bottom: 30px; position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0,0,0,0.5); }',
'.mglo-dialog-content { max-height: 100%; min-height: 200px; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -moz-box-orient: vertical; -webkit-flex-flow: column; -ms-flex-direction: column; flex-flow: column; margin: auto; background-color: #fff; position: relative; outline: 0; width: 600px; }',
'.mglo-dialog-form { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -moz-box-orient: vertical; -webkit-flex-flow: column; -ms-flex-direction: column; flex-flow: column; }',
'.mglo-dialog-header { color: #fff; background-color: #2196F3; padding: 15px; font-weight: 700; position: relative; }',
'.mglo-dialog-body { overflow: auto; padding: 15px; }',
'.mglo-dialog-footer { background-color: #f9f9f9; border-top: 1px solid #ddd; padding: 8px 15px; text-align: right; }',
'.mglo-dialog-footer > button + button { margin-left: 8px; }',
'.mglo-dialog-footer:empty { display: none; }',
'.mglo-dialog-footer:before, .mglo-dialog-footer:after { content: ""; display: table; clear: both; }',
'.mglo-dialog .mglo-close { position: absolute; right: 0; top: 0; bottom: 0; padding: 0 20px; border: none; box-shadow: none; border-radius: 0; outline: 0; text-decoration: none; color: inherit; background-color: inherit; font-size: 24px; font-weight: 700; }',
'.mglo-dialog .mglo-close:hover { color: #fff; background-color: #f44336; }',
/*form*/
'.mglo-form-group > label { display: inline-block; margin-bottom: 5px; }',
'.mglo-form-control { padding: 5px 10px; color: #333; background-color: #fff; border: 1px solid #ccc; width: 100%; display: block; margin-bottom: 10px }',
'.mglo-form-group.inline .mglo-form-control { display: inline-block; margin-left: 8px; width: auto; }',
'.mglo-form-control[disabled] { background-color: #eee; color: #888 }',
'.mglo-form-check { display: block; margin-bottom: 10px; }',
'.mglo-form-group.inline .mglo-form-check { display: inline-block; }',
'.mglo-form-group.inline .mglo-form-check + .mglo-form-check { margin-left: 10px; }',
'.mglo-form-check-label { position: relative; padding: 0; margin: 0; display: inline-block; }',
'.mglo-form-check-input { display: none !important; }',
'input.mglo-form-check-input + span, input.mglo-form-check-input + span { padding: 0; margin: 0; }',
'.mglo-form-check-input + span:before { position: relative; top: 5px; display: inline-block; width: 20px; height: 20px; content: ""; border: 2px solid #c0c0c0; margin-right: 8px; background-color: #fff; }',
'.mglo-form-check-input:checked + span:before { border-color: #3e97eb; }',
'.mglo-form-check-input:checked + span:after { content: ""; position: absolute; }',
'.mglo-form-check-input[type="checkbox"] +span:before { border-radius: 2px; }',
'.mglo-form-check-input[type="checkbox"]:checked + span:before { background: #3e97eb; }',
'.mglo-form-check-input[type="checkbox"]:checked + span:after { top: 8px; left: 7px; width: 6px; height: 12px; transform: rotate(45deg); border: 2px solid #fff; border-top: 0; border-left: 0; }',
'.mglo-form-check-input[type="radio"] +span:before { border-radius: 50%; }',
'.mglo-form-check-input[type="radio"]:checked + span:after { top: 10px; left: 5px; width: 10px; height: 10px; border-radius: 50%; background: #3e97eb; }',
'.mglo-form-no-label, .mglo-form-no-label input, .mglo-form-no-label select { margin-bottom: 0; }',
'.mglo-form-no-label .mglo-form-check-input + span:before { margin-right: 0; }',
'.mglo-form-no-label .mglo-form-check-label { height: 30px; }',
'.mglo-form-no-label .mglo-list-icon { margin-bottom: 0; }',
/*button*/
'.mglo-btn { padding: 5px 10px; color: #333; background-color: #fff; border: 1px solid #ccc; }',
'.mglo-btn:hover { color: #333; background-color: #e6e6e6; }',
'.mglo-btn:active { background-color: #c6c6c6; }',
'.mglo-btn.blue { color: #fff; background-color: #2196F3; border-color: #2196F3; }',
'.mglo-btn.red { color: #fff; background-color: #f44336; border-color: #f44336; }',
'.mglo-btn.left { float: left; }',
'.mglo-btn.right { float: right; }',
/*inputmg*/
'.mglo-form-group.mglo-form-group-record { display: flex; }',
'.mglo-form-group.mglo-form-group-record .mglo-btn.mglo-btn-record:before { display: block; content: ""; background-color: #808080; width: 12px; height: 12px; border-radius: 50%; transition: 0.2s; }',
'.mglo-form-group.mglo-form-group-record .mglo-btn.mglo-btn-record:hover:before { background-color: #f44336; transition: 0.2s; }',
'.mglo-form-group.mglo-form-group-record .mglo-form-control { text-transform: uppercase; font-weight: 700; }',
'.mglo-record-backdrop { z-index: 9999999999; position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0,0,0,0.5); }',
'.mglo-record-backdrop .mglo-list-icon { position: absolute; bottom: 0; left: 0; right: 0;text-align: center; background-color: rgba(0,0,0,0.5); }',
'.mglo-record-backdrop .mglo-list-icon > .mglo-icon { margin-top: 20px; margin-bottom: 20px; }',
/*table*/
'.mglo-table { border: 1px solid #c0c0c0; border-collapse: collapse; border-spacing: 0; width: 100%; }',
'.mglo-table th { font-weight: 700; }',
'.mglo-table tr { border-bottom: 1px solid #c0c0c0; }',
'.mglo-table td, .mglo-table th { padding: 8px; vertical-align: top; }',
'.mglo-table tr:nth-child(even) { background-color: #f1f1f1; }',
/*item*/
'.mglo-item { padding: 8px; border: 1px solid #ccc; }',
'.mglo-item + .mglo-item { margin-top: 5px; }',
'.mglo-item>*:last-child, .mglo-item>*:last-child>*:last-child { margin-bottom: 0; }'
].join('\n'));
var varw = (function (context) {
return function (varName, varValue, setEvent) {
var value = varValue;
Object.defineProperty(context, varName, {
get: function () {
return value;
},
set: function (v) {
value = v;
if (setEvent) {
setEvent(v);
}
}
});
};
})(unsafeWindow);
varw('isRecord', false, function (value) {
recordMG(value);
});
var SENSITIVITY = 20;
var startX, startY;
var gesture = '';
var gestures;
var values;
var preventContextMenu = false;
var mouseDownTriggered = false;
var timeoutDelay;
var dialogSetting;
var icon = {
up: getIcons8('ultraviolet', 'up', 40, '000000'),
down: getIcons8('ultraviolet', 'down', 40, '000000'),
left: getIcons8('ultraviolet', 'left', 40, '000000'),
right: getIcons8('ultraviolet', 'right', 40, '000000'),
mouseRightClick: getIcons8('ultraviolet', 'mouse-right-click', 40, '000000')
};
var $contentSetting = $('<div/>');
var $buttonReset = $('<button/>', {
class: 'mglo-btn',
type: 'reset',
text: 'Reset'
});
var $buttonSave = $('<button/>', {
class: 'mglo-btn blue',
text: 'Save'
});
var $buttonFooterSettings = [$buttonReset, $buttonSave];
var $currentInputMG;
var $recordBackdrop = $('<div/>', {
class: 'mglo-record-backdrop'
});
var gestureStrings = {
up: 'u',
down: 'd',
left: 'l',
right: 'r'
};
var defaultActions = {
closeTab: {
label: 'Close tab',
category: 'Tab',
fn: function () {
window.top.close();
}
},
newTab: {
label: 'New tab',
category: 'Tab',
fn: function () {
defaultActions.openInNewTab.fn();
}
},
duplicateTab: {
label: 'Duplicate tab',
category: 'Tab',
fn: function () {
defaultActions.openInNewTab.fn(unsafeWindow.location.href);
}
},
openInNewTab: {
label: 'Open link in new tab',
category: 'Tab',
fn: function (link) {
GM_openInTab(link, false);
},
onLink: true
},
openInNewBackgroundTab: {
label: 'Open link in new background tab',
category: 'Tab',
fn: function (link) {
GM_openInTab(link, true);
},
onLink: true
},
scrollUp: {
label: 'Scroll up',
category: 'Scroll',
fn: function () {
$('html, body').animate({
scrollTop: '-=600'
}, 'slow');
}
},
scrollDown: {
label: 'Scroll down',
category: 'Scroll',
fn: function () {
$('html, body').animate({
scrollTop: '+=600'
}, 'slow');
}
},
scrollToTop: {
label: 'Scroll to top',
category: 'Scroll',
fn: function () {
$('html, body').animate({
scrollTop: 0
}, 'slow');
}
},
scrollToBottom: {
label: 'Scroll to bottom',
category: 'Scroll',
fn: function () {
$('html, body').animate({
scrollTop: $(document).height()
}, 'slow');
}
},
scrollUpOnElement: {
label: 'Scroll up on element',
category: 'Scroll',
fn: function () {
var scrollChange = (values.$vScrollBarUp.is('html, body') ? $(window).height() : values.$vScrollBarUp.innerHeight()) * 5 / 7;
values.$vScrollBarUp.animate({
scrollTop: '-=' + scrollChange
}, 'slow');
}
},
scrollDownOnElement: {
label: 'Scroll down on element',
category: 'Scroll',
fn: function () {
var scrollChange = (values.$vScrollBarDown.is('html, body') ? $(window).height() : values.$vScrollBarDown.innerHeight()) * 5 / 7;
values.$vScrollBarDown.animate({
scrollTop: '+=' + scrollChange
}, 'slow');
}
},
back: {
label: 'Back',
category: 'Navigation',
fn: function () {
unsafeWindow.history.back();
}
},
forward: {
label: 'Forward',
category: 'Navigation',
fn: function () {
unsafeWindow.history.forward();
}
},
reload: {
label: 'Reload',
category: 'Load',
fn: function () {
unsafeWindow.location.reload();
}
},
reloadWithoutCache: {
label: 'Reload without cache',
category: 'Load',
fn: function () {
unsafeWindow.location.reload(true);
}
},
// settingsMGLO: {
// label: 'Settings Mouse Gestures like Opera',
// category: 'Other',
// fn: function () {
// showDialogSetting();
// }
// },
};
var defaultGestures = {
u: {
gesture: 'scrollUpOnElement',
},
d: {
gesture: 'scrollDownOnElement',
},
// u: {
// gesture: 'scrollUp',
// },
// d: {
// gesture: 'scrollDown',
// },
l: {
gesture: 'back',
},
r: {
gesture: 'forward',
},
ud: {
gesture: 'reload',
},
ur: {
gesture: 'newTab',
},
du: {
gesture: 'duplicateTab',
},
dl: {
gesture: 'openInNewTab',
},
dr: {
gesture: 'closeTab',
},
// lu: {
// gesture: 'scrollUpOnElement',
// },
// ld: {
// gesture: 'scrollDownOnElement',
// },
ru: {
gesture: 'scrollToTop',
},
rd: {
gesture: 'scrollToBottom',
},
udu: {
gesture: 'reloadWithoutCache',
},
dld: {
gesture: 'openInNewBackgroundTab',
},
// dudu: {
// gesture: 'settingsMGLO',
// }
};
function getIcons8(style, id, size, color) {
return 'https://png.icons8.com/' + style + '/' + size + '/' + color + '/' + id + '.png';
}
// function setGestures() {
// GM_setValue('gestures', gestures);
// }
// function getGestures() {
// return GM_getValue('gestures');
// }
// function loadGestures() {
// var valueGestures = getGestures();
// if (valueGestures) {
// gestures = valueGestures;
// } else {
// resetGestures();
// }
// }
// function resetGestures() {
// gestures = defaultGestures;
// setGestures();
// }
// loadGestures();
gestures = defaultGestures;
var $mouseGestures = $('<div/>', {
class: 'mglo hide'
}).appendTo(document.body);
var widthMouseGestures = $mouseGestures.width();
var heightMouseGestures = $mouseGestures.height();
var halfWidthMouseGestures = widthMouseGestures / 2;
var halfHeightMouseGestures = heightMouseGestures / 2;
var $up = $('<div/>', {
class: 'mglo-up'
}).appendTo($mouseGestures);
var $upIcon = $('<img/>', {
class: 'mglo-icon',
src: icon.up
}).appendTo($up);
var $upLabel = $('<div/>', {
class: 'mglo-label'
}).appendTo($up);
var $down = $('<div/>', {
class: 'mglo-down'
}).appendTo($mouseGestures);
var $downIcon = $('<img/>', {
class: 'mglo-icon',
src: icon.down
}).appendTo($down);
var $downLabel = $('<div/>', {
class: 'mglo-label'
}).appendTo($down);
var $left = $('<div/>', {
class: 'mglo-left'
}).appendTo($mouseGestures);
var $leftIcon = $('<img/>', {
class: 'mglo-icon',
src: icon.left
}).appendTo($left);
var $leftLabel = $('<div/>', {
class: 'mglo-label'
}).appendTo($left);
var $right = $('<div/>', {
class: 'mglo-right'
}).appendTo($mouseGestures);
var $rightIcon = $('<img/>', {
class: 'mglo-icon',
src: icon.right
}).appendTo($right);
var $rightLabel = $('<div/>', {
class: 'mglo-label'
}).appendTo($right);
var $middle = $('<div/>', {
class: 'mglo-middle'
}).appendTo($mouseGestures);
var $middleIcon = $('<img/>', {
class: 'mglo-icon',
src: icon.mouseRightClick
}).appendTo($middle);
var $middleLabel = $('<div/>', {
class: 'mglo-label'
}).appendTo($middle);
var ListIcon = (function () {
function ListIcon(label, attribute) {
this.gesture = '';
var $control = $('<div/>', {
class: 'mglo-list-icon-group'
});
if (typeof label === 'undefined') {
$control.addClass('mglo-form-no-label');
} else {
var $label = $('<label/>');
$label.text(label);
$label.appendTo($control);
}
var $listIcon = $('<div/>', attribute);
$listIcon.addClass('mglo-list-icon');
$listIcon.appendTo($control);
this.$listIcon = $listIcon;
this.$element = $control;
this.setGesture(attribute.gesture);
}
ListIcon.prototype = {
setGesture: function (gesture) {
var _this = this;
this.gesture = gesture;
this.$listIcon.empty();
this.$listIcon.data('data-gesture', gesture);
gesture.split('').forEach(function (c) {
switch (c) {
case gestureStrings.up:
$upIcon.clone().appendTo(_this.$listIcon);
break;
case gestureStrings.down:
$downIcon.clone().appendTo(_this.$listIcon);
break;
case gestureStrings.left:
$leftIcon.clone().appendTo(_this.$listIcon);
break;
case gestureStrings.right:
$rightIcon.clone().appendTo(_this.$listIcon);
break;
}
});
}
};
return ListIcon;
})();
var Form = {
Control: (function () {
function Control(type, label, attribute, event) {
if (typeof attribute !== 'object') {
attribute = {};
}
if (typeof attribute.id === 'undefined') {
attribute.id = 'mglo-' + type + '-' + new Date().getTime();
}
var $control = $('<div/>', {
class: 'mglo-form-group'
});
if (typeof label === 'undefined') {
$control.addClass('mglo-form-no-label');
} else {
var $label = $('<label/>', {
for: attribute.id
});
$label.text(label);
$label.appendTo($control);
}
var $input = $('<input/>', attribute);
$input.attr({
type: type,
class: 'mglo-form-control'
});
$input.appendTo($control);
this.label = label;
this.id = attribute.id;
this.$input = $input;
this.$element = $control;
if (type === 'number') {
$input.on('input.mglo', function (e) {
e.target.value = parseInt(e.target.value) ? e.target.value.replace(/^0+/, '') : (this.min || 0);
event(e);
});
} else {
$input.on('input.mglo', event);
}
}
Control.prototype = {
oninput: function (event) {
this.$input.on('input.mglo', function (e) {
e.target.value = parseInt(e.target.value) ? e.target.value.replace(/^0+/, '') : (this.min || 0);
event(e);
});
}
};
return Control;
}()),
Select: (function () {
function Select(label, attribute, event) {
var items = [],
itemElements = [],
value;
if (typeof attribute !== 'object') {
attribute = {};
}
if (typeof attribute.id === 'undefined') {
attribute.id = 'mglo-select-' + new Date().getTime();
}
if (typeof attribute.items !== 'undefined') {
items = $.extend(true, [], attribute.items);
delete attribute.items;
}
if (typeof attribute.value !== 'undefined') {
value = attribute.value;
}
var $control = $('<div/>', {
class: 'mglo-form-group',
});
if (typeof label === 'undefined') {
$control.addClass('mglo-form-no-label');
} else {
var $label = $('<label/>', {
for: attribute.id
});
$label.text(label);
$label.appendTo($control);
}
var $select = $('<select/>', attribute);
$select.attr('class', 'mglo-form-control');
$select.appendTo($control);
if (!Array.isArray(items)) {
items = [items];
}
for (var i = 0; i < items.length; i++) {
var text = items[i].label;
var $item = $('<option/>', items[i]);
$item.text(text);
if (value === items[i].value) {
$item.prop('selected', true);
}
if (typeof items[i].optgroup !== 'undefined') {
if ($select.find('optgroup[label="' + items[i].optgroup + '"]').size()) {
$select.find('optgroup[label="' + items[i].optgroup + '"]').append($item);
} else {
var $optgroup = $('<optgroup/>', {
label: items[i].optgroup
});
$optgroup.append($item);
$optgroup.appendTo($select);
}
} else {
$item.appendTo($select);
}
itemElements.push($item);
}
this.label = label;
this.id = attribute.id;
this.$select = $select;
this.$element = $control;
this.items = itemElements;
$select.on('change.mglo', event);
}
Select.prototype = {
onchange: function (event) {
this.$select.on('change.mglo', event);
}
};
return Select;
}()),
CheckInput: (function () {
function CheckInput(type, label, attribute, event) {
if (typeof attribute !== 'object') {
attribute = {};
}
if (typeof attribute.id === 'undefined') {
attribute.id = 'mglo-' + type + '-' + new Date().getTime();
}
var $checkInput = $('<div/>', {
class: 'mglo-form-check',
});
if (typeof label === 'undefined') {
$checkInput.addClass('mglo-form-no-label');
}
var $label = $('<label/>', {
class: 'mglo-form-check-label'
}).appendTo($checkInput);
var $input = $('<input/>', attribute);
$input.attr({
type: type,
class: 'mglo-form-check-input'
});
$input.appendTo($label);
var $text = $('<span/>').text(label);
$text.appendTo($label);
this.label = label;
this.id = attribute.id;
this.$input = $input;
this.$element = $checkInput;
$input.on('change.mglo', event);
}
CheckInput.prototype = {
onchange: function (event) {
this.$input.on('change.mglo', event);
},
};
CheckInput.createGroup = function (name, checkInputs) {
var $checkInputGroup = $('<div/>', {
class: 'mglo-form-group',
id: name
});
for (var i = 0; i < checkInputs.length; i++) {
var checkInput = checkInputs[i];
checkInput.$input.name = name;
$checkInputGroup.append(checkInput.$element);
}
return $checkInputGroup;
};
return CheckInput;
}()),
InputMG: (function () {
function InputMG(label, attribute) {
if (typeof attribute !== 'object') {
attribute = {};
}
if (typeof attribute.id === 'undefined') {
attribute.id = 'mglo-input-mg-' + new Date().getTime();
}
var $control = $('<div/>', {
class: 'mglo-form-group mglo-form-group-record'
});
if (typeof label === 'undefined') {
$control.addClass('mglo-form-no-label');
} else {
var $label = $('<label/>', {
for: attribute.id
});
$label.text(label);
$label.appendTo($control);
}
var $input = $('<input/>', attribute);
$input.attr({
type: 'text',
class: 'mglo-form-control'
});
$input.appendTo($control);
var $recordButton = $('<button/>', {
class: 'mglo-btn mglo-btn-record'
});
$recordButton.on('click.mglo', function (e) {
e.preventDefault();
$currentInputMG = $(this).parent().find('input.mglo-form-control');
isRecord = true;
});
$recordButton.appendTo($control);
this.label = label;
this.id = attribute.id;
this.$input = $input;
this.$element = $control;
this.$recordButton = $recordButton;
$input.on('keypress.mglo', function (e) {
var key = e.keyCode;
key = String.fromCharCode(key);
var regex = /(\b(?:([UDLRudlr])(?!\2{1}))+\b)/g;
if (!regex.test(key)) {
e.returnValue = false;
if (e.preventDefault) e.preventDefault();
}
}).on('input.mglo', function (e) {
$(this).val(function (i, val) {
return val.toLowerCase();
});
});
}
return InputMG;
}()),
};
var recordListIcon = new ListIcon(undefined, {
gesture: gesture
});
function mouseMoveMG(e) {
if (startY - e.clientY > 10 || e.clientY - startY > 10 || startX - e.clientX > 10 || e.clientX - startX > 10) {
preventContextMenu = false;
if (mouseDownTriggered) {
mouseDownTriggered = false;
} else {
clearTimeout(timeoutDelay);
showMG(e);
checkMG(e);
}
}
}
function mouseDownMG(e, data) {
e = data || e;
if (e.which === 3) {
getValues(e);
preventContextMenu = false;
mouseDownTriggered = true;
startX = e.clientX;
startY = e.clientY;
gesture = '';
loadMG();
timeoutDelay = setTimeout(function () {
showMG(e);
}, 500);
$(document).on('mousemove.mglo', mouseMoveMG);
}
}
function mouseUpMG(e) {
clearTimeout(timeoutDelay);
$(document).off('mousemove.mglo');
if (isRecord === false && checkTypeItemMG('link', gesture, true)) {
switch (gesture.slice(-1)) {
case gestureStrings.up:
$down.addClass('hide');
$left.addClass('hide');
$right.addClass('hide');
break;
case gestureStrings.down:
$up.addClass('hide');
$left.addClass('hide');
$right.addClass('hide');
break;
case gestureStrings.left:
$up.addClass('hide');
$down.addClass('hide');
$right.addClass('hide');
break;
case gestureStrings.right:
$up.addClass('hide');
$down.addClass('hide');
$left.addClass('hide');
break;
}
$mouseGestures.delay(300).addClass('hide');
} else {
$mouseGestures.addClass('hide');
if (isRecord === true && gesture) {
isRecord = false;
}
}
gesture = '';
}
function contextMenuMG(e) {
if (preventContextMenu) e.preventDefault();
}
$(document).on('mousedown.mglo', mouseDownMG)
.on('mouseup.mglo', mouseUpMG)
.on('contextmenu.mglo', contextMenuMG);
function showMG(e) {
preventContextMenu = true;
var mouseX = e.pageX - $(window).scrollLeft();
var mouseY = e.pageY - $(window).scrollTop();
$mouseGestures.css({
left: mouseX - halfWidthMouseGestures,
top: mouseY - halfHeightMouseGestures
}).stop(true, true);
$mouseGestures.removeClass('hide');
}
function checkMG(e) {
checkMove(startY - e.clientY, gestureStrings.up, e);
checkMove(e.clientY - startY, gestureStrings.down, e);
checkMove(startX - e.clientX, gestureStrings.left, e);
checkMove(e.clientX - startX, gestureStrings.right, e);
if (isRecord === true) {
recordListIcon.setGesture(gesture);
}
}
function checkMove(p, t, e) {
if (p >= SENSITIVITY) {
startX = e.clientX;
startY = e.clientY;
if (gesture.slice(-1) != t) {
gesture += t;
loadMG();
}
}
}
function loadMG() {
if (checkTypeItemMG('link', gesture + gestureStrings.up)) {
$up.removeClass('active hide');
$upLabel.text(getGesture(gesture + gestureStrings.up, 'label'));
} else {
$up.addClass('hide');
}
if (checkTypeItemMG('link', gesture + gestureStrings.down)) {
$down.removeClass('active hide');
$downLabel.text(getGesture(gesture + gestureStrings.down, 'label'));
} else {
$down.addClass('hide');
}
if (checkTypeItemMG('link', gesture + gestureStrings.left)) {
$left.removeClass('active hide');
$leftLabel.text(getGesture(gesture + gestureStrings.left, 'label'));
} else {
$left.addClass('hide');
}
if (checkTypeItemMG('link', gesture + gestureStrings.right)) {
$right.removeClass('active hide');
$rightLabel.text(getGesture(gesture + gestureStrings.right, 'label'));
} else {
$right.addClass('hide');
}
if (checkTypeItemMG('link', gesture)) {
switch (gesture.slice(-1)) {
case gestureStrings.up:
$up.removeClass('hide').addClass('active');
break;
case gestureStrings.down:
$down.removeClass('hide').addClass('active');
break;
case gestureStrings.left:
$left.removeClass('hide').addClass('active');
break;
case gestureStrings.right:
$right.removeClass('hide').addClass('active');
break;
}
}
}
function recordMG(isTurn) {
if (isTurn === true) {
if (dialogSetting && dialogSetting.isShow) {
$recordBackdrop.insertAfter(dialogSetting.$dialog);
} else {
$recordBackdrop.appendTo(document.body);
}
recordListIcon.$element.appendTo($recordBackdrop);
} else if (isTurn === false && gesture) {
$currentInputMG.val(gesture);
recordListIcon.setGesture('');
$recordBackdrop.remove();
}
}
function getValues(e) {
values = {};
values.$target = $(e.target);
if (values.$target.closest('a').length) {
values.link = values.$target.closest('a').prop('href');
}
values.$vScrollBar = values.$target.vScrollBarParent();
values.$vScrollBarUp = values.$target.vScrollBarParent('up');
values.$vScrollBarDown = values.$target.vScrollBarParent('down');
}
function getGesture(gesture, prototype) {
if (typeof prototype !== 'undefined') {
if (gestures[gesture].gesture !== 'custom') {
return defaultActions[gestures[gesture].gesture][prototype];
} else {
return gestures[gesture].custom[prototype];
}
} else {
if (gestures[gesture].gesture !== 'custom') {
return defaultActions[gestures[gesture].gesture];
} else {
return gestures[gesture].custom;
}
}
}
function checkTypeItemMG(type, gesture, runFunction) {
if (typeof runFunction === 'undefined') {
runFunction = false;
}
if (gestures[gesture]) {
if (getGesture(gesture, 'on' + type.toCapitalize().replace(' ', ''))) {
if (values[type]) {
if (runFunction === true) {
getGesture(gesture, 'fn')(values[type]);
}
return true;
} else {
return false;
}
} else {
if (runFunction === true) {
getGesture(gesture, 'fn')();
}
return true;
}
} else {
return false;
}
}
String.prototype.toCapitalize = function () {
return this.replace(/(\b)([a-zA-Z])/g, function (m) {
return m.toUpperCase();
});
};
var Dialog = (function () {
function Dialog(title, $content, $buttonFooters, isForm, id) {
if (typeof id === 'undefined') {
id = 'dialog-' + new Date().getTime();
}
if (typeof isForm === 'undefined') {
isForm = false;
}
this.title = title;
this.$content = $content.clone(true, true);
this.id = id;
this.isShow = false;
this.status = 'create';
var $dialog = $('<div/>', {
class: 'mglo-dialog',
id: this.id
});
this.$dialog = $dialog;
$dialog.get(0).onclick = this.close.bind(this);
var $dialogContent = $('<div/>', {
class: 'mglo-dialog-content'
});
$dialogContent.appendTo($dialog);
var $dialogForm = $('<form/>', {
class: 'mglo-dialog-form'
});
if (isForm === true) {
$dialogForm.appendTo($dialogContent);
}
var $dialogHeader = $('<div/>', {
class: 'mglo-dialog-header'
});
$dialogHeader.append(this.title);
if (isForm === true) {
$dialogHeader.appendTo($dialogForm);
} else {
$dialogHeader.appendTo($dialogContent);
}
var $buttonClose = $('<button/>', {
class: 'mglo-close'
});
$buttonClose.html('\u00d7');
$buttonClose.get(0).onclick = this.close.bind(this);
$buttonClose.appendTo($dialogHeader);
var $dialogBody = $('<div/>', {
class: 'mglo-dialog-body'
});
$dialogBody.append(this.$content);
if (isForm === true) {
$dialogBody.appendTo($dialogForm);
} else {
$dialogBody.appendTo($dialogContent);
}
var $dialogFooter = $('<div/>', {
class: 'mglo-dialog-footer'
});
if (isForm === true) {
$dialogFooter.appendTo($dialogForm);
} else {
$dialogFooter.appendTo($dialogContent);
}
if (typeof $buttonFooters !== 'undefined') {
if ($buttonFooters instanceof jQuery) {
$buttonFooters.each(function () {
$(this).clone(true, true).appendTo($dialogFooter);
});
} else if ($buttonFooters instanceof Array) {
$.each($buttonFooters, function (index, $button) {
$button.clone(true, true).appendTo($dialogFooter);
});
} else if ($buttonFooters instanceof Object) {
$.each($buttonFooters, function (key, $button) {
$button.clone(true, true).appendTo($dialogFooter);
});
}
}
$dialogContent.click(function (e) {
e.stopPropagation();
});
}
Dialog.prototype = {
show: function () {
if ($mouseGestures.size()) {
this.$dialog.insertBefore($mouseGestures);
} else {
this.$dialog.appendTo(document.body);
}
this.isShow = true;
this.status = 'show';
},
close: function () {
this.$dialog.remove();
this.isShow = false;
this.status = 'close';
}
};
return Dialog;
})();
var ItemMG = (function () {
function ItemMG(gesture, action, options) {
var _this = this;
this.gesture = gesture;
this.action = action;
var $itemMG = $('<div/>', {
class: 'mglo-item'
});
var listIcon = new ListIcon('Gesture', {
gesture: gesture
});
listIcon.$element.appendTo($itemMG);
var itemActions = [];
$.each(defaultActions, function (nameGesture, value) {
if (options.onLink !== true && value.onLink !== true || options.onLink === true && value.onLink === true) {
var item = {};
item.value = nameGesture;
item.label = value.label;
item.optgroup = value.category;
$.each(gestures, function (gesture, value) {
if (value.gesture === nameGesture && nameGesture !== action) {
item.disabled = true;
}
});
itemActions.push(item);
}
});
var inputMG = new Form.InputMG(undefined, {
value: gesture
});
inputMG.$element.appendTo($itemMG);
var selectAction = new Form.Select('Action', {
required: true,
items: itemActions,
value: action
}, function (e) {
return _this.setAction(e.target.value);
});
selectAction.$element.appendTo($itemMG);
this.listIcon = listIcon;
this.inputMG = inputMG;
this.selectAction = selectAction;
this.$element = $itemMG;
}
ItemMG.prototype = {
setGesture: function (gesture) {
this.gesture = gesture;
this.listIcon.setGesture(gesture);
},
setAction: function (action) {
this.action = action;
this.selectAction.$select.val(action);
}
};
return ItemMG;
})();
// var Table = (function () {
// function Table(options) {
// var $table = $('<table/>', {
// class: 'mglo-table'
// });
// var $trHeader = $('<tr/>').appendTo($table);
// options.columns.forEach(function (column) {
// $('<th/>').text(column.header).appendTo($trHeader);
// });
// options.data.forEach(function (row, index) {
// var $trRow = $('<tr/>').appendTo($table);
// options.columns.forEach(function (column) {
// $.each(row, function (key, value) {
// if (column.binding === key) {
// var $td = $('<td/>', column).append(value).appendTo($trRow);
// }
// });
// });
// });
// this.$element = $table;
// }
// return Table;
// }());
function showDialogSetting() {
if (dialogSetting && dialogSetting.isShow) {
dialogSetting.close();
}
dialogSetting = new Dialog('Settings', $contentSetting, $buttonFooterSettings, true);
dialogSetting.show();
}
$contentSetting.append('On Page');
$.each(gestures, function (gesture, value) {
if (getGesture(gesture, 'onLink') !== true) {
var itemMG = new ItemMG(gesture, value.gesture, {});
itemMG.$element.appendTo($contentSetting);
}
});
$contentSetting.append('On Link');
$.each(gestures, function (gesture, value) {
if (getGesture(gesture, 'onLink') === true) {
var itemMG = new ItemMG(gesture, value.gesture, {
onLink: true
});
itemMG.$element.appendTo($contentSetting);
}
});
$buttonSave.on('click.mglo', function (e) {
e.preventDefault();
});
// GM_registerMenuCommand('Settings', function () {
// showDialogSetting();
// });
$.fn.isScrollToTop = function () {
return this.scrollTop() === 0;
};
$.fn.isScrollToBottom = function () {
return this.get(0).scrollHeight - this.scrollTop() <= this.outerHeight();
};
$.fn.hasVScrollBar = function (includeHidden) {
var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
return !(/(HTML)/.test(this.get(0).tagName)) && overflowRegex.test(this.css('overflow')) && overflowRegex.test(this.css('overflow-y')) && this.get(0).scrollHeight > this.innerHeight();
};
$.fn.vScrollBarParent = function (scrollUpOrDown, includeHidden) {
if (this.hasVScrollBar() && (scrollUpOrDown !== 'up' && scrollUpOrDown !== 'down' || scrollUpOrDown === 'up' && !this.isScrollToTop() || scrollUpOrDown === 'down' && !this.isScrollToBottom())) {
return this;
}
var position = this.css('position'),
excludeStaticParent = position === 'absolute',
vScrollBarParent = this.parents().filter(function () {
var parent = $(this);
if (excludeStaticParent && parent.css('position') === 'static' || scrollUpOrDown === 'up' && parent.isScrollToTop() || scrollUpOrDown === 'down' && parent.isScrollToBottom()) {
return false;
}
return parent.hasVScrollBar();
}).eq(0);
return position === 'fixed' || !vScrollBarParent.length ? $('html, body') : vScrollBarParent;
};
})();