// ==UserScript== // @name nicovideo - wnp // @description windowised nicovideo player. // @author miya2000 // @namespace http://d.hatena.ne.jp/miya2000/ // @version 1.0.0 // @include http://www.nicovideo.jp/* // @exclude http://www.nicovideo.jp/watch/* // @exclude http://*http* // ==/UserScript== /* [usage] Open http://www.nicovideo.jp/ and you can start with the right-bottom button on the page. @see http://d.hatena.ne.jp/kotas/20070925/playlist http://abc.s65.xrea.com/prox/wiki/%A5%D5%A5%A3%A5%EB%A5%BF%A1%A2%A5%EA%A5%B9%A5%C8%B8%F8%B3%AB/nicovideo/#iroiro http://blog.fulltext-search.biz/articles/2008/01/31/nico-nico-player-wrapper http://blog.guron.net/2009/06/04/636.php */ // ==== preparation ==== // (function(f) { if (typeof unsafeWindow == "undefined") return f; return function() { var s = document.createElement('script'); s.setAttribute('type', 'text/javascript'); s.setAttribute('style', 'display: none;'); s.innerHTML = '(' + f.toString() + ')()'; (document.body || document.documentElement).appendChild(s); }; }) // ==== wnp ==== // (function() { if (window.name == 'wnp') return; var WNP = {}; // ==== Prefs ==== // WNP.Prefs = { WIDTH : 610, // startup window size. HEIGHT : 470, // LOOP_ON_STARTUP : false, // "loop" on startup. COMMENT_OFF_ON_STARTUP : false, // "comment-off" on startup. ALWAYS_ON_TOP_ON_STARTUP : false, // "always on top" on startup. PLAYLIST_STYLE_SIMPLE_ON_STARTUP : false, // "playlist style simple" on startup. REMOVE_ON_FINISH_ON_STARTUP : true, // "remove on finish" on startup. USE_HISTORY_ON_STARTUP : true, // "use history" on startup. SKIP_DELETED_MOVIE : true, // skip deleted movie. MENU_WIDTH_RATIO : 50, // (%) menu width ratio when showing menu. OBSERVE_INTERVAL : 500, // (ms) observe interval. PAGE_TIMEOUT : 80, // (sec) page load timeout. VIDEO_TIMEOUT : 60, // (sec) video play timeout. OFFTIMER : 120, // (min) off timer. LOOP_BREAK_COUNT : 3 // exit from loop video by specified count. }; // ==== const ==== // var Consts = { WNP_TITLE : 'WNP', WNP_GLOBAL_NAME : 'WNP', // global name of WNP entry object. WNP_IMAGE_SAVE : 'data:image/gif;base64,R0lGODlhEAAQAIAAAAAAAPD4%2FyH5BAEAAAAALAAAAAAQABAAAAIhhI%2Bpq%2BEPHYo0zAovlscy4BnhMo7N9IHoV6Ytq23pTAMFADs%3D', WNP_IMAGE_PLAY : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAAt0lEQVQ4y2NgoCL4%2F%2F8%2FXnnB0NBQFyAtQA0DJVatWtUPVHALRAP5kpQaqAmUvAzE%2F4D4OxDvB4rZAzE7uQZqASWvQA2EgSchISG5oKAgy4X%2F%2Fv27DMR%2Fgfg%2FDAPBm5UrV07AFQSkuvA%2FoSAgx0BkcAnkE3K8jAxgXn8CTFL56OFJjgvxxjipBr4BpskJ%2BNIkPgO1gV67geZFvEmGkIFKQMntQPyB2ERNTF6WAnoxjdhsR4yBZJU2AAcDLeBOG3M7AAAAAElFTkSuQmCC', WNP_IMAGE_PAUSE : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAAe0lEQVQ4y2NgoCL4%2F%2F8%2FfgWhoaFuxIgRYyDLqlWrooAKfoJoEB%2BHGCOxBnIAJTf9h4BNID4OsYEzkP3fv38b%2F0HARhAfhxjDqJeHsJc5gN7aAdIJomEGYhEj2stsQMl2UGCBaBAfhxjRLgQDYBZrICBGmoG4NOISAxkIAIbuKTCbOZywAAAAAElFTkSuQmCC', ORG_PLAYER_VIEW_WIDTH : 544, ORG_PLAYER_VIEW_HEIGHT : 384, ORG_PLAYER_CONTROL_HEIGHT : 63, ORG_PLAYER_MINIMUM_WIDTH : 561 } WNP.Consts = Consts; Consts.svg_xml_base = [ '', '', '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', '', ' ', ' ', ' ', '', '', ' %t%', ' ', ' ', ' %c%', ' ', '', '', '' ].join('\n'); Consts.svg_mime_type = 'image/svg+xml'; // ==== color settings ==== // var Colors = { item_hover: '#D7EBFF', item_selected: '#B4DAFF', item_dragging: '#FFCCCC', status_error: 'red', control_loop: 'yellow', control_repeat: 'yellow', control_comment_off: 'yellow', control_mute: 'yellow', control_always_on_top: 'yellow' }; WNP.Colors = Colors; // ==== main ==== // var fn = {}; WNP.fn = fn; BUILD_FUNC(fn); var browser = fn.browser; var ie = fn.ie; var $e = fn.$e; var toJSON = fn.toJSON; var getAbsolutePosition = fn.getAbsolutePosition; var addStyle = fn.addStyle; var getStyle = fn.getStyle; var $XS = fn.$XS; var findVideoTitle = fn.findVideoTitle; var createPlayInfo = fn.createPlayInfo; WNP.html = function() { var browser = WNP.fn.browser; return [ '', '', '', '', '', '', '', '' + Consts.WNP_TITLE + '', '', '', '', '
', '
', '
', ' ', ' ', '
', '
', ' <', ' ', ' >', ' ', ' ', ' ', ' ', '
', '
', '
', ' ', '
', '
', '
', '
', '

playlist

', '
    ', ' ', '
    ', '
    ', '

    history

    ', '
      ', ' ', '
      ', '
      ', '
      ', '
      ', '', '', '', '', '' ].join('\n'); }; WNP.pageStyle = function(pref) { return [ '.wnp_tooltip {', ' width: 168px;', ' opacity: 0.4; ', /*@cc_on 'filter:alpha(opacity=40);', @*/ ' position: absolute; ', ' z-index: 999; ', '}', '.wnp_tooltip:hover {', ' opacity: 1; ', /*@cc_on 'filter:alpha(opacity=100);', @*/ '}', '.wnp_tooltip a {', ' cursor: pointer;', ' display: block;', ' width: 54px;', ' height: 0;', ' line-height: 22px;', ' font-family: cursive;', ' font-size: 14px;', ' font-weight: bold;', ' text-align: center;', ' text-decoration: none;', ' color: #F0F0F0;', ' border-style: solid;', ' border-width: 15px 0;', /*@cc_on 'border-width: 15px 0 16px;', @*/ ' border-top-color: #555;', ' border-bottom-color: #000;', ' padding: 0;', ' float: left;', ' margin-right: 2px;', '}', '.wnp_tooltip * span {', ' box-sizing: border-box;', browser.mozilla ? '-moz-box-sizing : border-box;' : '', ' border: 1px solid #DDD;', ' display: inline-block;', ' width: 50px;', /*@cc_on 'width: 48px;', @*/ ' height: 24px;', ' position: relative;', ' top: -15px;', ' margin-top: 3px;', '}', '.wnp_tooltip a:hover {', ' border-top-color: #666;', '}', '.wnp_tooltip a:hover span {', ' color: #FFF;', ' border-color: #FFF;', '}', '.wnp_tooltip a span:active { padding: 1px 0 0 2px; }', ].join('\n'); }; function BUILD_FUNC(T) { if (T == null) T = window; // -- utils -- // browser var browser = { opera : (navigator.appName.indexOf("Opera") >= 0), mozilla : (navigator.userAgent.indexOf("Gecko/") >= 0), ie : /*@cc_on!@*/false }; T.browser = browser; var ie = {}; ie.cssStandard = (document.compatMode && document.compatMode == 'CSS1Compat'); ie.clientWidth = (function() { return ie.cssStandard ? function(d) { return (d || document).documentElement.clientWidth } : function(d) { return (d || document).body.clientWidth } })(); ie.clientHeight = (function() { return ie.cssStandard ? function(d) { return (d || document).documentElement.clientHeight } : function(d) { return (d || document).body.clientHeight } })(); ie.window = function(element) { return element.parentWindow || element.ownerDocument.parentWindow || window; }; T.ie = ie; // event. var $e = (function() { if ('addEventListener' in window) return function(element) { return element }; function preventDefault() { this.returnValue = false; } function stopPropagation() { this.cancelBubble = true; } function compat(e, el) { if (!('preventDefault' in e)) e.preventDefault = preventDefault; if (!('stopPropagation' in e)) e.stopPropagation = stopPropagation; if (!('target' in e)) e.target = e.srcElement; if (!('relatedTarget' in e)) e.relatedTarget = (e.srcElement === e.toElement) ? e.fromElement : e.toElement; if (!('currentTarget' in e)) e.currentTarget = el; var d = el.ownerDocument || el.document || el; if (!('pageX' in e)) e.pageX = (d.body.scrollLeft||d.documentElement.scrollLeft) + e.clientX; if (!('pageY' in e)) e.pageY = (d.body.scrollTop ||d.documentElement.scrollTop ) + e.clientY; if (!e.detail && e.wheelDelta) e.detail = -(e.wheelDelta/120)*4; } function indexOf(listeners, a, b, c) { for (var i = 0, len = listeners.length; i < len; i++) { var l = listeners[i]; if (l.a === a && l.b === b && l.c === c) return i; } return -1; } if ('attachEvent' in window) { return function $e(element) { if ('addEventListener' in element) return element; return (function(el) { var listeners = []; el.addEventListener = function(a, b, c) { if (indexOf(listeners, a, b, c) >= 0) return; var f = function(e) { compat(e, el); b.call(el, e); }; el.attachEvent('on' + a, f); listeners.push({ a: a, b: b, c: c, f: f}); }; el.removeEventListener = function(a, b, c) { var index = indexOf(listeners, a, b, c); if (index < 0) return; el.detachEvent('on' + a, listeners[index].f); listeners.splice(index, 1); }; return el; })(element); } } else { return function(el) { if (el.addEventListener) return el; el.addEventListener = el.removeEventListener = function() {}; throw 'Neither "addEventListener" nor "attachEvent" is supported on this browser.'; } } })(); T.$e = $e; function uescape(s) { return escape(s).replace(/%([0-9A-F]{2})/g, '\\u00$1').replace(/%u/g, '\\u'); } T.uescape = uescape; function toJSON(o) { if (o == null) return 'null'; var c = o.constructor; if (c === Boolean) return o.toString(); if (c === Number ) return isNaN(o) ? '"NaN"' : !isFinite(o) ? '"Infinity"' : o.toString(10); if (c === String ) return '"' + uescape(o) + '"'; if (c === Array ) { var tmp = []; for (var i = 0; i < o.length; i++) { tmp[i] = toJSON(o[i]); } return '[' + tmp.join(',') + ']'; } if (typeof o == 'object') { var tmp = []; for (var i in o) { if (Object.prototype.hasOwnProperty.call(o, i)) { tmp.push('"' + uescape(i) + '":' + toJSON(o[i])); } } return '{' + tmp.join(',') + '}'; } return '\"' + uescape(o.toString()) + '\"'; }; T.toJSON = toJSON; var escapeHTML = (function() { var dv; return function escapeHTML(str, d) { if (dv == null) { dv = (d||document).createElement('div'); setTimeout(function() { dv = null; }, 0); } dv.textContent = /*@cc_on dv.innerText = @*/ str; return dv.innerHTML; }; })(); T.escapeHTML = escapeHTML; function formatNumber(d) { return d.toString().replace(/(\d{1,3})(?=(?:\d\d\d)+$)/g, "$1,"); //http://nanto.asablo.jp/blog/2007/12/07/2479257 }; T.formatNumber = formatNumber; function getAbsolutePosition(el) { var p = el.offsetParent, x = el.offsetLeft, y = el.offsetTop; while (p) { x += p.offsetLeft - p.scrollLeft, y += p.offsetTop - p.scrollTop, p = p.offsetParent; } return { x : x, y : y } }; T.getAbsolutePosition = getAbsolutePosition; function hasClass(el, className) { //http://d.hatena.ne.jp/higeorange/20090613/1244821192 return new RegExp('(?:^|\\s)' + className + '(?:\\s|$)').test(el.className); } T.hasClass = hasClass; function appendClass(el, className) { if (!el) return; if (new RegExp('(?:^|\\s)' + className + '\\s*$').test(el.className)) return; removeClass(el, className); el.className += ' ' + className; } T.appendClass = appendClass; function removeClass(el, className) { if (!el) return; var orgClassName = el.className; var newClassName = orgClassName.replace(new RegExp('(?:^|\\s)' + className + '(?:\\s|$)', 'g'), '').replace(/\s+/g, ' ').replace(/^\s|\s$/, ''); if (orgClassName != newClassName) { el.className = newClassName; } } T.removeClass = removeClass; function addStyle(styleStr, doc) { var document = doc || window.document; var style = document.createElement('style'); style.type = 'text/css'; style.style.display = 'none'; if (/*@cc_on !@*/true) { style.innerHTML = styleStr; } else { style.styleSheet.cssText = styleStr; } document.body.appendChild(style); return style; } T.addStyle = addStyle; function getStyle(element, property, pseudo) { return ( element.currentStyle || element.ownerDocument.defaultView.getComputedStyle(element, pseudo || '') )[property]; } T.getStyle = getStyle; function $XS(xpath, context) { return document.evaluate(xpath,context||document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue; } T.$XS = $XS; function findVideoTitle(a) { var title = ''; if (!/