cbox-videos

Open youtube links in a dialog in cbox chats

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==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>

})();