mini clock

simple clock for full screen mode

As of 2016-02-20. See the latest version.

// ==UserScript==
// @name        mini clock
// @namespace   gnblizz
// @description simple clock for full screen mode
// @version     2.00
// @compatible  firefox
// @include     *
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_registerMenuCommand
// @icon        data:image/gif;base64,R0lGODlhEAAQAKECABEREe7u7v///////yH5BAEKAAIALAAAAAAQABAAAAIplI+py30Bo5wB2IvzrXDvaoFcCIBeeXaeSY4tibqxSWt2RuWRw/e+UQAAOw==
// ==/UserScript==
"use strict";

/* This user script inserts the system time in the upper right corner of the browser window. This is especially useful 
 * in full screen mode, when the task bar clock is hidden.
 * To change the position, select "clock at bottom" from the context menu of the time display.
 * To set the minimum width for the clock to appear, resize the browser window to that width and select "mini clock set min width" from the "user script commands" sub menu of the greasemonkey menu.
 */

function log(x) {
  //console.log(x);
}

function error(x) {
  console.log(x);
}

var isTop = window.self==window.top,
  div, spn, wrapper,
  ref = 0, fontSize,
  hTimer = 0, hTimer2 = 0, hTimer3 = 0,
  datePattern = (function(){
    switch(navigator.language.slice(0,2)){
    case 'de': return '%A, %e. %B %Y'; // e.g: 'Donnerstag, 16. Juli 2015'
    case 'en': return /-US/i.test(navigator.language) ? '%A%n%B %e, %Y' : '%A%n%e %B %Y';
    }
    return '%A, %x';
  }());
  
function getValue(name, dflt) { return (typeof(GM_getValue)=='function') ? GM_getValue(name, dflt) : dflt; }
function setValue(name, value) { if(typeof(GM_setValue)=='function') GM_setValue(name, value); }
function addStyle(style) { var o = document.createElement("STYLE"); o.innerHTML = style; document.getElementsByTagName('HEAD')[0].appendChild(o); return o; }

function miniClockSetWidth() {
  GM_setValue('miniClockMinWidth', window.outerWidth);
  alert('New treshold width is '+window.outerWidth+' pixel.');
}

function niceTime(d) { return d.toLocaleFormat('%R'); }
function niceDate(d) { return d.toLocaleFormat(datePattern); }

if(isTop) {
  if(typeof(GM_registerMenuCommand)=='function')
    GM_registerMenuCommand('mini clock set min width', miniClockSetWidth, 'w');
  init();
}

document.addEventListener("mozfullscreenchange", function(event) {
 try {
  log('event fullscreenchange with'+(document.mozFullScreen ? '' : 'out')+' FullScreen and FullScreenElement='+(document.mozFullScreenElement ? document.mozFullScreenElement.tagName+(document.mozFullScreenElement.id ? '#'+document.mozFullScreenElement.id : '') : ''));
  if(!ref++)
    init();
  ref--;
 } catch(e) { error(e); }
});

function OnTimer() {
  var dt = new Date(), t = niceTime(dt);
  if(spn.textContent != t) {
    spn.textContent = t;
    if(!div.title || t.slice(-1)=='0')
      div.title = niceDate(dt);
  }
}

function OnMouseMove() {
  clearTimeout(hTimer2);
  hTimer2 = setTimeout(OnTimer2, 3333);
  if(wrapper.style.cursor) {
    wrapper.style.cursor = '';
    document.getElementById('mcwrfsb').style.visibility='';
  }
}

function OnTimer2() {
  hTimer2 = 0;
  wrapper.style.cursor = 'none';
  document.getElementById('mcwrfsb').style.visibility = 'hidden';
}

function OnMouseEnter() {
  hTimer3 = setTimeout(function() {
   try {
    hTimer3 = 0;
    div.style.visibility = 'hidden';
    var res = document.addEventListener("mousemove", OnMouseMove2);
   }catch(e){ error(e);}
  }, 2222);
}

function OnMouseMove2(event) {
 try {
  if(event.clientX+20 < div.offsetLeft || (event.clientY > 80 && event.clientY+80 < window.innerHeight)) {
    div.style.visibility = '';
    document.removeEventListener("mousemove", OnMouseMove2);
  }
 }catch(e){ error(e); }
}

function shouldShow() {
  if(isTop) {
    var minWidth = getValue('miniClockMinWidth', 999);
    if(!minWidth || minWidth >= window.screen.availWidth || window.outerWidth >= minWidth)
      return true;
  } else if(document.mozFullScreenElement)
    return true;
  return false;
}

function OnReSize() {
 try {
  log('ReSize '+window.outerWidth+'x'+window.outerHeight);
  if(shouldShow()) {
    div.style.display = 'block';
    if(!hTimer) {
      OnTimer();
      hTimer = setInterval(OnTimer, 1900);
    }
  } else {
    div.style.display = 'none';
    if(hTimer) {
      clearInterval(hTimer);
      hTimer = 0;
    }
  }
  if(wrapper)
    OnMouseMove();
 } catch(e) { error(e); }
}

function InsertClock(here) {
  div.parentNode.removeChild(div);
  here.appendChild(div);
}

function AtBottomClicked() {
  if(div.style.top == 'unset') {
    div.style.top = '';
    div.style.bottom = '';
    setValue('atbottom', false);
  } else {
    div.style.top = 'unset';
    div.style.bottom = '0px';
    setValue('atbottom', true);
  }
  div.blur();
}

function FontChange(event) {
  var frm = document.createElement('form');
  frm.innerHTML = '<input id="us_MiniClockFontSel" type="number" value="'+fontSize+'" min="3" max="200" maxlength="3" size="3" style="text-align:right;width:84px;"><button type="submit"> OK </button>';
  frm.style = 'position:fixed!important;top:55px;right:10px;color:#222;background-color:#181818;border:1px solid gray;padding:10px 17px;font:18pt normal sans-serif;z-index:2147483647;';
  var inp = frm.firstChild, fse = document.mozFullScreenElement || document.body;
  inp.onchange = function(event){
    div.style.fontSize = inp.value + 'pt';
    div.style.visibility = '';
  }
  frm.lastChild.onclick = function(event){
    setValue('fontsize', fontSize = inp.value);
    fse.removeChild(frm);
  };
  fse.appendChild(frm);
  inp.focus();
}



function MenuCreate(menu) {
  menu.setAttribute('type','context');
  menu.setAttribute('id','us_MiniClockMenu');
  menu.innerHTML='<menuitem label="hide mini clock"></menuitem><menuitem label="adjust clock size"></menuitem><menuitem label="clock at bottom" type="checkbox"></menuitem><menuitem label="allow clock in video tag" type="checkbox"></menuitem>';
  var item = menu.firstChild;
  item.onclick = function(event) { div.style.opacity='0'; };
  item = item.nextSibling;
  item.onclick = FontChange;
  item = item.nextSibling;
  item.onclick = AtBottomClicked;
  if(getValue('atbottom')) {
    div.style.top = 'unset';
    div.style.bottom = '0px';
    item.checked = true;
  }
  item = item.nextSibling;
  item.onclick = function() { setValue('allowAtVideo', !getValue('allowAtVideo')); };
  if(getValue('allowAtVideo')) {
    item.checked = true;
  }
  div.appendChild(menu);
  div.setAttribute('contextmenu','us_MiniClockMenu');
  div.oncontextmenu = function() {
    menu.lastChild.checked = getValue('allowAtVideo')==true;
    if(hTimer3) {
      clearTimeout(hTimer3);
      hTimer3 = 0;
    } else div.style.visibility = '';
  };
}

function create() {
  div = document.createElement('div');
  div.id = 'us_MiniClock';
  div.appendChild(spn = document.createElement('span'));
  document.body.appendChild(div);
  OnReSize();
  if(!document.getElementById('us_MiniClockStyle')) {
    fontSize = getValue('fontsize', 18);
    var style = addStyle('#us_MiniClock{position:fixed!important;top:0px;right:0px;width:auto;color:#E8E8E8;background-color:#181818;border:1px solid gray;padding:1px 7px;font:'
    +fontSize+'pt normal sans-serif;z-index:2147483647;}@media print{#us_MiniClock{display:none!important;}} \
    #mcwrfsb{position:fixed;right:0px;bottom:0px;cursor:pointer;border:1px solid;height:25px;width:25px;}');
    style.id = 'us_MiniClockStyle';
    if(document.body.firstChild.tagName != 'PRE' || !div.offsetTop) {
      window.onresize = OnReSize;
      div.addEventListener("mouseenter", OnMouseEnter, false);
      var menu = MenuCreate(document.createElement('menu'));
    } else {
      clearInterval(hTimer);
      div.parentNode.removeChild(div);
      div = null;
    }
  }
}

function ForceEndFullscreen() {
  var fse = document.mozFullScreenElement;
  if(fse) {
    error('forced end fullscreen');
    var ns = fse.nextSibling, pn = fse.parentNode;
    pn.removeChild(fse);
    pn.insertBefore(fse, ns);
  }
}

function init() {
 try {
  if(!div)
    create();
  var fse = document.mozFullScreenElement || document.body, wrp, st;
  if(fse.contains(div))
    return;
  switch(fse.tagName) {
  case 'VIDEO':
    if(getValue('allowAtVideo')) {
      st = !fse.paused;
      document.mozCancelFullScreen();
      log('CancelFullScreen()');
      wrp = fse.parentNode;
      if(wrp.id != 'miniClockWrapper') {
	wrapper = wrp = document.createElement('div');
	wrp.id = 'miniClockWrapper';
	wrp.innerHTML = '<div id="mcwrfsb">&nbsp;</div>';
	wrp.firstChild.onclick = function(e) { if(document.mozFullScreenElement) document.mozCancelFullScreen(); else wrapper.mozRequestFullScreen(); };
	wrp.appendChild(fse.parentNode.replaceChild(wrp, fse));
	wrp.addEventListener("mousemove", OnMouseMove);
      }
      if(document.mozFullScreenElement)
	ForceEndFullscreen();
      wrp.mozRequestFullScreen();
      InsertClock(wrp);
      if(st && fse.paused) {
	log('video stopped while processed');
	fse.play();
      }
      if(!document.mozFullScreenElement)
	console.log('Clock could not reactivate full screen mode. Make sure, full-screen-api.allow-trusted-requests-only is false in about:config');
    } else console.log('Clock not allowed in video tags. See', 'https://greasyfork.org/de/scripts/11402-mini-clock', 'for details.');
  case 'IFRAME':
    break;
  default:
    InsertClock(fse);
  }
 } catch(e){ error(e); }
}

//public domain by gnblizz