// ==UserScript==
// @author @leoncastro
// @namespace https://github.com/leoncastro
// @name cbox-videos
// @version 0.01
// @description Open youtube links in a dialog in cbox chats
// @include https://my.cbox.ws/*
// @include /(https?:)?//(www\d\.)cbox\.ws\/box/
// @compatible firefox+greasemonkey
// @compatible chrome+tampermonkey
// @grant none
// @run-at document-end
// ==/UserScript==
//
(function($){
// @part-name @desktop
// @part-author https://github.com/leoncastro
// @part-license Private use only
// @part-description desktop with moveable and resizable dialogs
// @part-version beta-0.3 (partial content)
// <@desktop>
var minW = 50, minH = 50, minX = 0, maxX = 9999, minY = 0, maxY = 9999,
ks = '-', kh = '#', kp = '.', kc = ',', kn = '>',
prefix_main = 'wdlg',
selector_main = prefix_main + ks + 'main',
selector_tool = prefix_main + ks + 'tool',
selector_head = prefix_main + ks + 'head',
selector_text = prefix_main + ks + 'text',
selector_ctrl = prefix_main + ks + 'ctrl',
selector_exit = prefix_main + ks + 'exit',
selector_body = prefix_main + ks + 'body',
selector_pane = prefix_main + ks + 'pane',
selector_foot = prefix_main + ks + 'foot',
selector_grip = prefix_main + ks + 'grip';
var template_css = `
<style id="###0###" type="text/css">
.wdlg-tool{position:absolute;background-color:#F4F4F4;z-index:910;-moz-box-shadow:3px 3px 8px #818181;-webkit-box-shadow:3px 3px 8px #818181;box-shadow:3px 3px 8px #818181;cursor:default}
.wdlg-tool.selected{z-index:911}
.wdlg-tool>.wdlg-head{display:block;position:relative;height:24px;line-height:24px;padding:8px 32px 0 8px;cursor:move;color:black;background-color:darkgray;font-size:130%;font-weight:normal;overflow:hidden}
.wdlg-tool.selected>.wdlg-head{background-color:white}
.wdlg-tool>.wdlg-head>.wdlg-text{display:block;position:absolute;left:0;right:0;margin:0 32px 0 8px;overflow:hidden}
.wdlg-tool>.wdlg-head>.wdlg-ctrl{display:block;position:absolute;top:0;right:0}
.wdlg-tool>.wdlg-head>.wdlg-ctrl>div{display:block;float:right;width:32px;height:16px;padding:8px;text-align:center;cursor:pointer;color:white;filter:alpha(opacity=50);opacity:0.5;}
.wdlg-tool>.wdlg-head>.wdlg-ctrl>div:hover{filter:alpha(opacity=100);opacity:1}
.wdlg-tool>.wdlg-head>.wdlg-ctrl>.wdlg-exit:hover{background-color:red}
.wdlg-tool>.wdlg-head>.wdlg-ctrl>.wdlg-exit:hover>svg>path{stroke:white}
.wdlg-tool>.wdlg-body{display:block;position:relative;width:100%;margin:0;padding:0;overflow:hidden}
.wdlg-tool>.wdlg-body>.wdlg-pane{display:block;position:relative;width:100%;height:100%;margin:0;padding:0;overflow:hidden}
.wdlg-tool>.wdlg-foot{display:block;position:relative;padding-right:16px}
.wdlg-tool>.wdlg-foot>.wdlg-grip{display:block;position:absolute;bottom:0;right:0;width:16px;height:16px;cursor:se-resize}
</style>
`;
var template_dlg =`
<div id="###1###" class="wdlg-tool" style="width:###2###;height:###3###;left:###4###;top:###5###;">
<div class="wdlg-head">
<div class="wdlg-text"></div>
<div class="wdlg-ctrl">
<div class="wdlg-exit">
<svg width="16" height="16" overflow="hidden"><path d="M 2 2 L 13 13 M 13 2 L 2 13" stroke="#000" stroke-opacity="1" stroke-width="2" fill="none"></path></svg>
</div>
</div>
</div>
<div class="wdlg-body">
<div class="wdlg-pane">
###0###
</div>
</div>
<div class="wdlg-foot">
<div class="wdlg-grip">
<svg width="16" height="16" overflow="hidden"><path d="M 13 2 L 2 13 M 13 6 L 6 13 M 13 10 L 10 13 Z" stroke="#FFF" stroke-opacity="1" stroke-width="0.6" fill="none"></path></svg>
</div>
</div>
</div>
`;
var template_frm = `<iframe frameborder="0" scrolling="no" width="100%" height="100%" src="###0###"></iframe>`;
// Function call:
function safeCall(o,a){if(o[a])o[a]();}
// Node:
function nodeCreate(o,n,c,t){t=t||'div';var e=document.createElement('div');if(n)e.id=n;if(c)e.className=c;if(o)o.appendChild(e);return e;}
function nodeSelect(n,o){return'string'==typeof n?(o||document).querySelector(n):n;}
function nodeInsert(n,t,o){n=nodeSelect(n,o);if(n)n.insertAdjacentHTML('beforeEnd',t);}
function nodeRemove(n,o){n=nodeSelect(n,o);if(n){n.innerHTML='';if(n.parentNode)n.parentNode.removeChild(n);}}
// Class:
function classInsert(n,c){n=nodeSelect(n);if(n){n.className=(n.className?n.className+' ':'')+c;}}
function classRemove(n,c){n=nodeSelect(n);if(n&&n.className){n.className=(' '+n.className+' ').split(' '+c+' ').join(' ').trim();}}
// Event:
function eventInsert(e,n,fn){n=nodeSelect(n);return n.addEventListener(e,fn,0);}
function eventRemove(e,n,fn){n=nodeSelect(n);return n.removeEventListener(e,fn,0);}
function eventCancel(e,c){e.returnValue=!1;safeCall(e,'preventDefault');if(c){e.keyCode=0;e.cancelBubble=!0;e.retainFocus=!0;safeCall(e,'stopPropagation');}}
function eventFilter(e){return((e.which&&(e.which==1))||(e.button&&(e.button==1)));}
// Helpers:
function getFreeId(){var i=1,j;while(document.getElementById(j=(selector_main+ks+([1e4]+i).slice(-4))))i++;return j;}
function getPixels(s){return s+'px';}
function getToolX(n){return parseInt(n.style.left);}
function getToolY(n){return parseInt(n.style.top);}
function getToolW(n){return n.offsetWidth;}
function getToolH(n){return n.offsetHeight;}
// Template:
function templateBuild()
{
var t = null;
if(arguments.length)
{
t = arguments[0];
for(var i = 1; i< arguments.length; i++)
t = t.replace('###' + (i - 1) + '###', arguments[i]);
}
return t;
}
// Desktop:
var desktop = function(n)
{
n = n || document.body;
this.handleDesk = n;
this.selectTool = null;
this.selectItem = null;
this.x = 0;
this.y = 0;
this.w = 0;
this.h = 0;
this.cx = 0;
this.cy = 0;
this.mx = 0;
this.my = 0;
var it = this;
eventInsert('mousedown', n, function(e){it.onMouseDn(e);});
eventInsert('mousemove', n, function(e){it.onMouseMv(e);});
eventInsert('mouseup' , n, function(e){it.onMouseUp(e);});
this.insertWindowHTML = function(html, opt, cx, cy, x, y)
{
var t = prefix_main + ks + 'style';
if( !nodeSelect(kh + t) )
nodeInsert(this.handleDesk, templateBuild(template_css, t));
var n = getFreeId();
opt = opt || {};
opt.title = opt.title || n;
this.w = this.w || 320; // 320, 400, 480, 640, 800, 1024 // TODO
this.h = this.h || 204; // 180, 224, 270, 360, 450, 576 // TODO
cx = cx || opt.cx || opt.height || this.w;
cy = cy || opt.cy || opt.width || this.h - 24;
x = x || opt.x || opt.left || Math.random() * (getToolW(this.handleDesk) - cx);
y = y || opt.y || opt.top || Math.random() * (getToolH(this.handleDesk) - cy);
nodeInsert(this.handleDesk, templateBuild(template_dlg, html, n,
getPixels(cx), getPixels(24 + cy), getPixels(x), getPixels(y)));
if(this.selectTool)
this.selectLeave(1);
this.selectEnter(nodeSelect(kh + n));
var it = this,
c = kh + n + kp + selector_tool + kn + kp + selector_head + kn +
kp + selector_ctrl + kn + kp + selector_exit;
if(nodeSelect(c))
eventInsert('click', c, function(e){
if(it.b)
it.selectLeave(1);
nodeRemove(kh + n);
eventCancel(e, 1);
});
this.onMouseUp();
return n;
};
this.insertWindowLink = function(link, opt, cx, cy, x, y)
{
var html = templateBuild(template_frm, link);
opt = opt || {};
opt.link = link;
this.insertWindowHTML(html, opt, cx, cy, x, y);
};
this.deleteWindowTool = function(n)
{
nodeRemove(kh + n);
};
};
var fn = desktop.prototype;
// Mouse:
fn.onMouseDn = function(e)
{
var o = e.target || e.srcElement, n = null, h = null;
while(o)
{
if(o.className)
{
if( !h && (
~String.prototype.indexOf.call(o.className, selector_grip) ||
~String.prototype.indexOf.call(o.className, selector_head)) )
h = o;
if( ~String.prototype.indexOf.call(o.className, selector_tool) )
{
n = o;
break;
}
}
o = o.parentNode;
}
if(this.selectTool && (this.selectTool != n))
{
this.selectLeave(1);
}
if(n && (!this.selectTool || (n == this.selectTool)))
{
if(h)
eventCancel(e);
this.selectEnter(n);
if(eventFilter(e))
this.selectItem = h;
}
};
fn.onMouseMv = function(e)
{
var mx = e.pageX || e.clientX + document.documentElement.scrollLeft;
var my = e.pageY || e.clientY + document.documentElement.scrollTop;
var x = mx - this.mx + this.cx;
var y = my - this.my + this.cy;
this.cx = this.cy = 0;
this.mx = mx;
this.my = my;
if(!this.selectItem)
return true;
if(this.resizeStep(x, y))
{
if(this.selectTool)
{
var b = nodeSelect(kp + selector_body, this.selectTool);
if(b)
{
b.style.width = getPixels(getToolW(this.selectTool));
b.style.height = getPixels(getToolH(this.selectTool) -
getToolH(nodeSelect(kp + selector_head, this.selectTool)));
}
}
}
else
{
var dX = x, dY = y;
if(this.x + dX < minX)
this.cx = (dX - (x = minX - this.x));
else if(this.x + this.w + dX > maxX)
this.cx = (dX - (x = maxX - this.x - this.w));
if(this.y + dY < minY)
this.cy = (dY - (y = minY - this.y));
else if(this.y + this.h + dY > maxY)
this.cy = (dY - (y = maxY - this.y - this.h));
this.x += x;
this.y += y;
}
this.selectTool.style.left = getPixels(this.x);
this.selectTool.style.top = getPixels(this.y);
this.selectTool.style.width = getPixels(this.w);
this.selectTool.style.height = getPixels(this.h);
eventCancel(e);
};
fn.onMouseUp = function(e)
{
if(this.selectTool)
{
var b = nodeSelect(kp + selector_body, this.selectTool);
if(b)
{
b.style.width = getPixels(getToolW(this.selectTool));
b.style.height = getPixels(getToolH(this.selectTool) -
getToolH(nodeSelect(kp + selector_head, this.selectTool)));
}
}
this.selectLeave(0);
};
// Select:
fn.selectEnter = function(n)
{
if(n && (n != this.selectTool))
{
this.resizeInit(n);
this.x = getToolX(n);
this.y = getToolY(n);
this.w = getToolW(n);
this.h = getToolH(n);
}
};
fn.selectLeave = function(e)
{
if(e)
this.resizeInit(null);
this.selectItem = null;
this.cx = 0;
this.cy = 0;
};
// Resize:
fn.resizeInit = function(n)
{
var s = 'selected';
if(n)
{
this.selectTool = n;
classInsert(this.selectTool, s);
}
else
{
classRemove(this.selectTool, s);
this.selectTool = n;
}
};
fn.resizeStep = function(x, y)
{
var h = '';
if(this.selectItem && this.selectItem.className)
{
if(this.selectItem.className === selector_grip)
h = 'br';
}
var dX = x, dY = y, r = 0;
if(~h.indexOf('b'))
{
if(this.h + dY < minH)
this.cy = (dY - (y = minH - this.h));
else if(this.y + this.h + dY > maxY)
this.cy = (dY - (y = maxY - this.y - this.h));
this.h += y;
r = 1;
}
if(~h.indexOf('r'))
{
if(this.w + dX < minW)
this.cx = (dX - (x = minW - this.w));
else if(this.x + this.w + dX > maxX)
this.cx = (dX - (x = maxX - this.x - this.w));
this.w += x;
r = 1;
}
return r;
};
// </@desktop>
// <@cbox-videos>
var yt_video = '//www.youtube.com/embed/###?wmode=opaque&autoplay=1&modestbranding=1&rel=0&showinfo=1';
var yt_regex = /(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((?:\w|-){11})(?:\S+)?/i;
var deskctrl = new desktop();
var addVideo = function(txt, x, y)
{
var yt_urlid = txt && txt.match(yt_regex);
if( yt_urlid && (yt_urlid = yt_urlid[1]) )
{
deskctrl.insertWindowLink(yt_video.replace('###', yt_urlid), {}, null, null, x, y);
return 1;
}
return 0;
};
document.addEventListener('click', function(e){
e = window.event ? event : e;
var url, obj = window.event ? event.srcElement : e.target;
if( (obj.tagName == 'A' && obj.className && ~obj.className.indexOf('autoLink') && (url = obj.href)) ||
(obj.tagName == 'DIV' && obj.className && ~obj.className.indexOf('body') &&
obj.parentNode && ~obj.parentNode.className.indexOf('msg') && obj.innerHTML &&
(url = obj.innerHTML.match(yt_regex)) && (url = url[0])) )
{
if(addVideo(url, e.clientX, e.clientY))
e.preventDefault();
}
});
// </@cbox-videos>
})();