- // Copyright (c) 2013, heyeshuang. (MIT Licensed)
- // ==UserScript==
- // @id userscripts.org-a861f8c9-2981-4747-a244-a40ace20e46f@scriptish
- // @name SFW
- // @namespace https://github.com/heyeshuang/SFW
- // @version 0.2.0
- // @description an anti-procrastination user script;拖延症矫正脚本
- // @include http*://*
- // @run-at document-end
- // ==/UserScript==
- if (window.top != window.self) return; //don't run on frames or iframes
- (function( win, undefined ){
-
- var doc = win.document,
- docElem = doc.documentElement;
-
- var easyDialog = function(){
-
- var body = doc.body,
- isIE = !-[1,], // 判断IE6/7/8 不能判断IE9
- isIE6 = isIE && /msie 6/.test( navigator.userAgent.toLowerCase() ), // 判断IE6
- uuid = 1,
- expando = 'cache' + ( +new Date() + "" ).slice( -8 ), // 生成随机数
- cacheData = {
- /**
- * 1 : {
- * eclick : [ handler1, handler2, handler3 ];
- * clickHandler : function(){ //... };
- * }
- */
- };
-
- var Dialog = function(){};
-
- Dialog.prototype = {
- // 参数设置
- getOptions : function( arg ){
- var i,
- options = {},
- // 默认参数
- defaults = {
- container: null, // string / object 弹处层内容的id或内容模板
- overlay: true, // boolean 是否添加遮罩层
- drag: true, // boolean 是否绑定拖拽事件
- fixed: true, // boolean 是否静止定位
- follow: null, // string / object 是否跟随自定义元素来定位
- followX: 0, // number 相对于自定义元素的X坐标的偏移
- followY: 0, // number 相对于自定义元素的Y坐标的偏移
- autoClose: 0, // number 自动关闭弹出层的时间
- lock: false, // boolean 是否允许ESC键来关闭弹出层
- callback: null // function 关闭弹出层后执行的回调函数
- /**
- * container为object时的参数格式
- * container : {
- * header : '弹出层标题',
- * content : '弹出层内容',
- * yesFn : function(){}, // 确定按钮的回调函数
- * noFn : function(){} / true, // 取消按钮的回调函数
- * yesText : '确定', // 确定按钮的文本,默认为‘确定’
- * noText : '取消' // 取消按钮的文本,默认为‘取消’
- * }
- */
- };
-
- for( i in defaults ){
- options[i] = arg[i] !== undefined ? arg[i] : defaults[i];
- }
- Dialog.data( 'options', options );
- return options;
- },
-
- // 防止IE6模拟fixed时出现抖动
- setBodyBg : function(){
- if( body.currentStyle.backgroundAttachment !== 'fixed' ){
- body.style.backgroundImage = 'url(about:blank)';
- body.style.backgroundAttachment = 'fixed';
- }
- },
-
- // 防止IE6的select穿透
- appendIframe : function(elem){
- elem.innerHTML = '<iframe style="position:absolute;left:0;top:0;width:100%;height:100%;z-index:-1;border:0 none;filter:alpha(opacity=0)"></iframe>';
- },
-
- /**
- * 设置元素跟随定位
- * @param { Object } 跟随的DOM元素
- * @param { String / Object } 被跟随的DOM元素
- * @param { Number } 相对于被跟随元素的X轴的偏移
- * @param { Number } 相对于被跟随元素的Y轴的偏移
- */
- setFollow : function( elem, follow, x, y ){
- follow = typeof follow === 'string' ? doc.getElementById( follow ) : follow;
- var style = elem.style;
- style.position = 'absolute';
- style.left = Dialog.getOffset( follow, 'left') + x + 'px';
- style.top = Dialog.getOffset( follow, 'top' ) + y + 'px';
- },
-
- /**
- * 设置元素固定(fixed) / 绝对(absolute)定位
- * @param { Object } DOM元素
- * @param { Boolean } true : fixed, fasle : absolute
- */
- setPosition : function( elem, fixed ){
- var style = elem.style;
- style.position = isIE6 ? 'absolute' : fixed ? 'fixed' : 'absolute';
- if( fixed ){
- if( isIE6 ){
- style.setExpression( 'top','fuckIE6=document.documentElement.scrollTop+document.documentElement.clientHeight/2+"px"' );
- }
- else{
- style.top = '50%';
- }
- style.left = '50%';
- }
- else{
- if( isIE6 ){
- style.removeExpression( 'top' );
- }
- style.top = docElem.clientHeight/2 + Dialog.getScroll( 'top' ) + 'px';
- style.left = docElem.clientWidth/2 + Dialog.getScroll( 'left' ) + 'px';
- }
- },
-
- /**
- * 创建遮罩层
- * @return { Object } 遮罩层
- */
- createOverlay : function(){
- var overlay = doc.createElement('div'),
- style = overlay.style;
-
- style.cssText = 'margin:0;padding:0;border:none;width:100%;height:100%;background:#333;opacity:0.6;filter:alpha(opacity=60);z-index:9999;position:fixed;top:0;left:0;';
-
- // IE6模拟fixed
- if(isIE6){
- body.style.height = '100%';
- style.position = 'absolute';
- style.setExpression('top','fuckIE6=document.documentElement.scrollTop+"px"');
- }
-
- overlay.id = 'overlay';
- return overlay;
- },
-
- /**
- * 创建弹出层
- * @return { Object } 弹出层
- */
- createDialogBox : function(){
- var dialogBox = doc.createElement('div');
- dialogBox.style.cssText = 'margin:0;padding:0;border:none;z-index:10000;';
- dialogBox.id = 'easyDialogBox';
- return dialogBox;
- },
-
- /**
- * 创建默认的弹出层内容模板
- * @param { Object } 模板参数
- * @return { Object } 弹出层内容模板
- */
- createDialogWrap : function( tmpl ){
- // 弹出层标题
- var header = tmpl.header ?
- '<h4 class="easyDialog_title" id="easyDialogTitle"><a href="javascript:void(0)" title="关闭窗口" class="close_btn" id="closeBtn">×</a>' + tmpl.header + '</h4>' :
- '',
- // 确定按钮
- yesBtn = typeof tmpl.yesFn === 'function' ?
- '<button class="btn_highlight" id="easyDialogYesBtn">' + ( typeof tmpl.yesText === 'string' ? tmpl.yesText : '确定' ) + '</button>' :
- '',
- // 取消按钮
- noBtn = typeof tmpl.noFn === 'function' || tmpl.noFn === true ?
- '<button class="btn_normal" id="easyDialogNoBtn">' + ( typeof tmpl.noText === 'string' ? tmpl.noText : '取消' ) + '</button>' :
- '',
- // footer
- footer = yesBtn === '' && noBtn === '' ? '' :
- '<div class="easyDialog_footer">' + noBtn + yesBtn + '</div>',
-
- dialogTmpl = [
- '<div class="easyDialog_content">',
- header,
- '<div class="easyDialog_text">' + tmpl.content + '</div>',
- footer,
- '</div>'
- ].join(''),
-
- dialogWrap = doc.getElementById( 'easyDialogWrapper' ),
- rScript = /<[\/]*script[\s\S]*?>/ig;
-
- if( !dialogWrap ){
- dialogWrap = doc.createElement( 'div' );
- dialogWrap.id = 'easyDialogWrapper';
- dialogWrap.className = 'easyDialog_wrapper';
- }
- dialogWrap.innerHTML = dialogTmpl.replace( rScript, '' );
- return dialogWrap;
- }
- };
-
- /**
- * 设置并返回缓存的数据 关于缓存系统详见:http://stylechen.com/cachedata.html
- * @param { String / Object } 任意字符串或DOM元素
- * @param { String } 缓存属性名
- * @param { Anything } 缓存属性值
- * @return { Object }
- */
- Dialog.data = function( elem, val, data ){
- if( typeof elem === 'string' ){
- if( val !== undefined ){
- cacheData[elem] = val;
- }
- return cacheData[elem];
- }
- else if( typeof elem === 'object' ){
- // 如果是window、document将不添加自定义属性
- // window的索引是0 document索引为1
- var index = elem === win ? 0 :
- elem.nodeType === 9 ? 1 :
- elem[expando] ? elem[expando] :
- (elem[expando] = ++uuid),
-
- thisCache = cacheData[index] ? cacheData[index] : ( cacheData[index] = {} );
-
- if( data !== undefined ){
- // 将数据存入缓存中
- thisCache[val] = data;
- }
- // 返回DOM元素存储的数据
- return thisCache[val];
- }
- };
-
- /**
- * 删除缓存
- * @param { String / Object } 任意字符串或DOM元素
- * @param { String } 要删除的缓存属性名
- */
- Dialog.removeData = function( elem, val ){
- if( typeof elem === 'string' ){
- delete cacheData[elem];
- }
- else if( typeof elem === 'object' ){
- var index = elem === win ? 0 :
- elem.nodeType === 9 ? 1 :
- elem[expando];
-
- if( index === undefined ) return;
- // 检测对象是否为空
- var isEmptyObject = function( obj ) {
- var name;
- for ( name in obj ) {
- return false;
- }
- return true;
- },
- // 删除DOM元素所有的缓存数据
- delteProp = function(){
- delete cacheData[index];
- if( index <= 1 ) return;
- try{
- // IE8及标准浏览器可以直接使用delete来删除属性
- delete elem[expando];
- }
- catch ( e ) {
- // IE6/IE7使用removeAttribute方法来删除属性(document会报错)
- elem.removeAttribute( expando );
- }
- };
-
- if( val ){
- // 只删除指定的数据
- delete cacheData[index][val];
- if( isEmptyObject( cacheData[index] ) ){
- delteProp();
- }
- }
- else{
- delteProp();
- }
- }
- };
-
- // 事件处理系统
- Dialog.event = {
-
- bind : function( elem, type, handler ){
- var events = Dialog.data( elem, 'e' + type ) || Dialog.data( elem, 'e' + type, [] );
- // 将事件函数添加到缓存中
- events.push( handler );
- // 同一事件类型只注册一次事件,防止重复注册
- if( events.length === 1 ){
- var eventHandler = this.eventHandler( elem );
- Dialog.data( elem, type + 'Handler', eventHandler );
- if( elem.addEventListener ){
- elem.addEventListener( type, eventHandler, false );
- }
- else if( elem.attachEvent ){
- elem.attachEvent( 'on' + type, eventHandler );
- }
- }
- },
-
- unbind : function( elem, type, handler ){
- var events = Dialog.data( elem, 'e' + type );
- if( !events ) return;
-
- // 如果没有传入要删除的事件处理函数则删除该事件类型的缓存
- if( !handler ){
- events = undefined;
- }
- // 如果有具体的事件处理函数则只删除一个
- else{
- for( var i = events.length - 1, fn = events[i]; i >= 0; i-- ){
- if( fn === handler ){
- events.splice( i, 1 );
- }
- }
- }
- // 删除事件和缓存
- if( !events || !events.length ){
- var eventHandler = Dialog.data( elem, type + 'Handler' );
- if( elem.addEventListener ){
- elem.removeEventListener( type, eventHandler, false );
- }
- else if( elem.attachEvent ){
- elem.detachEvent( 'on' + type, eventHandler );
- }
- Dialog.removeData( elem, type + 'Handler' );
- Dialog.removeData( elem, 'e' + type );
- }
- },
-
- // 依次执行事件绑定的函数
- eventHandler : function( elem ){
- return function( event ){
- event = Dialog.event.fixEvent( event || win.event );
- var type = event.type,
- events = Dialog.data( elem, 'e' + type );
-
- for( var i = 0, handler; handler = events[i++]; ){
- if( handler.call(elem, event) === false ){
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- },
-
- // 修复IE浏览器支持常见的标准事件的API
- fixEvent : function( e ){
- // 支持DOM 2级标准事件的浏览器无需做修复
- if ( e.target ) return e;
- var event = {}, name;
- event.target = e.srcElement || document;
- event.preventDefault = function(){
- e.returnValue = false;
- };
- event.stopPropagation = function(){
- e.cancelBubble = true;
- };
- // IE6/7/8在原生的window.event中直接写入自定义属性
- // 会导致内存泄漏,所以采用复制的方式
- for( name in e ){
- event[name] = e[name];
- }
- return event;
- }
- };
-
- /**
- * 首字母大写转换
- * @param { String } 要转换的字符串
- * @return { String } 转换后的字符串 top => Top
- */
- Dialog.capitalize = function( str ){
- var firstStr = str.charAt(0);
- return firstStr.toUpperCase() + str.replace( firstStr, '' );
- };
-
- /**
- * 获取滚动条的位置
- * @param { String } 'top' & 'left'
- * @return { Number }
- */
- Dialog.getScroll = function( type ){
- var upType = this.capitalize( type );
- return docElem['scroll' + upType] || body['scroll' + upType];
- };
-
- /**
- * 获取元素在页面中的位置
- * @param { Object } DOM元素
- * @param { String } 'top' & 'left'
- * @return { Number }
- */
- Dialog.getOffset = function( elem, type ){
- var upType = this.capitalize( type ),
- client = docElem['client' + upType] || body['client' + upType] || 0,
- scroll = this.getScroll( type ),
- box = elem.getBoundingClientRect();
-
- return Math.round( box[type] ) + scroll - client;
- };
-
- /**
- * 拖拽效果
- * @param { Object } 触发拖拽的DOM元素
- * @param { Object } 要进行拖拽的DOM元素
- */
- Dialog.drag = function( target, moveElem ){
- // 清除文本选择
- var clearSelect = 'getSelection' in win ? function(){
- win.getSelection().removeAllRanges();
- } : function(){
- try{
- doc.selection.empty();
- }
- catch( e ){};
- },
-
- self = this,
- event = self.event,
- isDown = false,
- newElem = isIE ? target : doc,
- fixed = moveElem.style.position === 'fixed',
- _fixed = Dialog.data( 'options' ).fixed;
-
- // mousedown
- var down = function( e ){
- isDown = true;
- var scrollTop = self.getScroll( 'top' ),
- scrollLeft = self.getScroll( 'left' ),
- edgeLeft = fixed ? 0 : scrollLeft,
- edgeTop = fixed ? 0 : scrollTop;
-
- Dialog.data( 'dragData', {
- x : e.clientX - self.getOffset( moveElem, 'left' ) + ( fixed ? scrollLeft : 0 ),
- y : e.clientY - self.getOffset( moveElem, 'top' ) + ( fixed ? scrollTop : 0 ),
- // 设置上下左右4个临界点的位置
- // 固定定位的临界点 = 当前屏的宽、高(下、右要减去元素本身的宽度或高度)
- // 绝对定位的临界点 = 当前屏的宽、高 + 滚动条卷起部分(下、右要减去元素本身的宽度或高度)
- el : edgeLeft, // 左临界点
- et : edgeTop, // 上临界点
- er : edgeLeft + docElem.clientWidth - moveElem.offsetWidth, // 右临界点
- eb : edgeTop + docElem.clientHeight - moveElem.offsetHeight // 下临界点
- });
-
- if( isIE ){
- // IE6如果是模拟fixed在mousedown的时候先删除模拟,节省性能
- if( isIE6 && _fixed ){
- moveElem.style.removeExpression( 'top' );
- }
- target.setCapture();
- }
-
- event.bind( newElem, 'mousemove', move );
- event.bind( newElem, 'mouseup', up );
-
- if( isIE ){
- event.bind( target, 'losecapture', up );
- }
-
- e.stopPropagation();
- e.preventDefault();
-
- };
-
- event.bind( target, 'mousedown', down );
-
- // mousemove
- var move = function( e ){
- if( !isDown ) return;
- clearSelect();
- var dragData = Dialog.data( 'dragData' ),
- left = e.clientX - dragData.x,
- top = e.clientY - dragData.y,
- et = dragData.et,
- er = dragData.er,
- eb = dragData.eb,
- el = dragData.el,
- style = moveElem.style;
-
- // 设置上下左右的临界点以防止元素溢出当前屏
- style.marginLeft = style.marginTop = '0px';
- style.left = ( left <= el ? el : (left >= er ? er : left) ) + 'px';
- style.top = ( top <= et ? et : (top >= eb ? eb : top) ) + 'px';
- e.stopPropagation();
- };
-
- // mouseup
- var up = function( e ){
- isDown = false;
- if( isIE ){
- event.unbind( target, 'losecapture', arguments.callee );
- }
- event.unbind( newElem, 'mousemove', move );
- event.unbind( newElem, 'mouseup', arguments.callee );
- if( isIE ){
- target.releaseCapture();
- // IE6如果是模拟fixed在mouseup的时候要重新设置模拟
- if( isIE6 && _fixed ){
- var top = parseInt( moveElem.style.top ) - self.getScroll( 'top' );
- moveElem.style.setExpression('top',"fuckIE6=document.documentElement.scrollTop+" + top + '+"px"');
- }
- }
- e.stopPropagation();
- };
- };
-
- var timer, // 定时器
- // ESC键关闭弹出层
- escClose = function( e ){
- if( e.keyCode === 27 ){
- extend.close();
- }
- },
- // 清除定时器
- clearTimer = function(){
- if( timer ){
- clearTimeout( timer );
- timer = undefined;
- }
- };
-
- var extend = {
- open : function(){
- var $ = new Dialog(),
- options = $.getOptions( arguments[0] || {} ), // 获取参数
- event = Dialog.event,
- docWidth = docElem.clientWidth,
- docHeight = docElem.clientHeight,
- self = this,
- overlay,
- dialogBox,
- dialogWrap,
- boxChild;
-
- clearTimer();
-
- // ------------------------------------------------------
- // ---------------------插入遮罩层-----------------------
- // ------------------------------------------------------
-
- // 如果页面中已经缓存遮罩层,直接显示
- if( options.overlay ){
- overlay = doc.getElementById( 'overlay' );
- if( !overlay ){
- overlay = $.createOverlay();
- body.appendChild( overlay );
- if( isIE6 ){
- $.appendIframe( overlay );
- }
- }
- overlay.style.display = 'block';
- }
-
- if(isIE6){
- $.setBodyBg();
- }
-
- // ------------------------------------------------------
- // ---------------------插入弹出层-----------------------
- // ------------------------------------------------------
-
- // 如果页面中已经缓存弹出层,直接显示
- dialogBox = doc.getElementById( 'easyDialogBox' );
- if( !dialogBox ){
- dialogBox = $.createDialogBox();
- body.appendChild( dialogBox );
- }
-
- if( options.follow ){
- var follow = function(){
- $.setFollow( dialogBox, options.follow, options.followX, options.followY );
- };
-
- follow();
- event.bind( win, 'resize', follow );
- Dialog.data( 'follow', follow );
- if( overlay ){
- overlay.style.display = 'none';
- }
- options.fixed = false;
- }
- else{
- $.setPosition( dialogBox, options.fixed );
- }
- dialogBox.style.display = 'block';
-
- // ------------------------------------------------------
- // -------------------插入弹出层内容---------------------
- // ------------------------------------------------------
-
- // 判断弹出层内容是否已经缓存过
- dialogWrap = typeof options.container === 'string' ?
- doc.getElementById( options.container ) :
- $.createDialogWrap( options.container );
-
- boxChild = dialogBox.getElementsByTagName('*')[0];
-
- if( !boxChild ){
- dialogBox.appendChild( dialogWrap );
- }
- else if( boxChild && dialogWrap !== boxChild ){
- boxChild.style.display = 'none';
- body.appendChild( boxChild );
- dialogBox.appendChild( dialogWrap );
- }
-
- dialogWrap.style.display = 'block';
-
- var eWidth = dialogWrap.offsetWidth,
- eHeight = dialogWrap.offsetHeight,
- widthOverflow = eWidth > docWidth,
- heigthOverflow = eHeight > docHeight;
-
- // 强制去掉自定义弹出层内容的margin
- dialogWrap.style.marginTop = dialogWrap.style.marginRight = dialogWrap.style.marginBottom = dialogWrap.style.marginLeft = '0px';
-
- // 居中定位
- if( !options.follow ){
- dialogBox.style.marginLeft = '-' + (widthOverflow ? docWidth/2 : eWidth/2) + 'px';
- dialogBox.style.marginTop = '-' + (heigthOverflow ? docHeight/2 : eHeight/2) + 'px';
- }
- else{
- dialogBox.style.marginLeft = dialogBox.style.marginTop = '0px';
- }
-
- // 防止select穿透固定宽度和高度
- if( isIE6 && !options.overlay ){
- dialogBox.style.width = eWidth + 'px';
- dialogBox.style.height = eHeight + 'px';
- }
-
- // ------------------------------------------------------
- // --------------------绑定相关事件----------------------
- // ------------------------------------------------------
- var closeBtn = doc.getElementById( 'closeBtn' ),
- dialogTitle = doc.getElementById( 'easyDialogTitle' ),
- dialogYesBtn = doc.getElementById('easyDialogYesBtn'),
- dialogNoBtn = doc.getElementById('easyDialogNoBtn');
-
- // 绑定确定按钮的回调函数
- if( dialogYesBtn ){
- event.bind( dialogYesBtn, 'click', function( event ){
- if( options.container.yesFn.call(self, event) !== false ){
- self.close();
- }
- });
- }
-
- // 绑定取消按钮的回调函数
- if( dialogNoBtn ){
- var noCallback = function( event ){
- if( options.container.noFn === true || options.container.noFn.call(self, event) !== false ){
- self.close();
- }
- };
- event.bind( dialogNoBtn, 'click', noCallback );
- // 如果取消按钮有回调函数 关闭按钮也绑定同样的回调函数
- if( closeBtn ){
- event.bind( closeBtn, 'click', noCallback );
- }
- }
- // 关闭按钮绑定事件
- else if( closeBtn ){
- event.bind( closeBtn, 'click', self.close );
- }
-
- // ESC键关闭弹出层
- if( !options.lock ){
- event.bind( doc, 'keyup', escClose );
- }
- // 自动关闭弹出层
- if( options.autoClose && typeof options.autoClose === 'number' ){
- timer = setTimeout( self.close, options.autoClose );
- }
- // 绑定拖拽(如果弹出层内容的宽度或高度溢出将不绑定拖拽)
- if( options.drag && dialogTitle && !widthOverflow && !heigthOverflow ){
- dialogTitle.style.cursor = 'move';
- Dialog.drag( dialogTitle, dialogBox );
- }
-
- // 确保弹出层绝对定位时放大缩小窗口也可以垂直居中显示
-
- if( !options.follow && !options.fixed ){
- var resize = function(){
- $.setPosition( dialogBox, false );
- };
- // 如果弹出层内容的宽度或高度溢出将不绑定resize事件
- if( !widthOverflow && !heigthOverflow ){
- event.bind( win, 'resize', resize );
- }
- Dialog.data( 'resize', resize );
- }
-
- // 缓存相关元素以便关闭弹出层的时候进行操作
- Dialog.data( 'dialogElements', {
- overlay : overlay,
- dialogBox : dialogBox,
- closeBtn : closeBtn,
- dialogTitle : dialogTitle,
- dialogYesBtn : dialogYesBtn,
- dialogNoBtn : dialogNoBtn
- });
- },
-
- close : function(){
- var options = Dialog.data( 'options' ),
- elements = Dialog.data( 'dialogElements' ),
- event = Dialog.event;
-
- clearTimer();
- // 隐藏遮罩层
- if( options.overlay && elements.overlay ){
- elements.overlay.style.display = 'none';
- }
- // 隐藏弹出层
- elements.dialogBox.style.display = 'none';
- // IE6清除CSS表达式
- if( isIE6 ){
- elements.dialogBox.style.removeExpression( 'top' );
- }
-
- // ------------------------------------------------------
- // --------------------删除相关事件----------------------
- // ------------------------------------------------------
- if( elements.closeBtn ){
- event.unbind( elements.closeBtn, 'click' );
- }
-
- if( elements.dialogTitle ){
- event.unbind( elements.dialogTitle, 'mousedown' );
- }
-
- if( elements.dialogYesBtn ){
- event.unbind( elements.dialogYesBtn, 'click' );
- }
-
- if( elements.dialogNoBtn ){
- event.unbind( elements.dialogNoBtn, 'click' );
- }
-
- if( !options.follow && !options.fixed ){
- event.unbind( win, 'resize', Dialog.data('resize') );
- Dialog.removeData( 'resize' );
- }
-
- if( options.follow ){
- event.unbind( win, 'resize', Dialog.data('follow') );
- Dialog.removeData( 'follow' );
- }
-
- if( !options.lock ){
- event.unbind( doc, 'keyup', escClose );
- }
- // 执行callback
- if(typeof options.callback === 'function'){
- options.callback.call( extend );
- }
- // 清除缓存
- Dialog.removeData( 'options' );
- Dialog.removeData( 'dialogElements' );
- }
- };
-
- return extend;
-
- };
-
- // ------------------------------------------------------
- // ---------------------DOM加载模块----------------------
- // ------------------------------------------------------
- var loaded = function(){
- win.easyDialog = easyDialog();
- },
-
- doScrollCheck = function(){
- if ( doc.body ) return;
-
- try {
- docElem.doScroll("left");
- } catch(e) {
- setTimeout( doScrollCheck, 1 );
- return;
- }
- loaded();
- };
-
- (function(){
- if( doc.body ){
- loaded();
- }
- else{
- if( doc.addEventListener ){
- doc.addEventListener( 'DOMContentLoaded', function(){
- doc.removeEventListener( 'DOMContentLoaded', arguments.callee, false );
- loaded();
- }, false );
- win.addEventListener( 'load', loaded, false );
- }
- else if( doc.attachEvent ){
- doc.attachEvent( 'onreadystatechange', function(){
- if( doc.readyState === 'complete' ){
- doc.detachEvent( 'onreadystatechange', arguments.callee );
- loaded();
- }
- });
- win.attachEvent( 'onload', loaded );
- var toplevel = false;
- try {
- toplevel = win.frameElement == null;
- } catch(e) {}
-
- if ( docElem.doScroll && toplevel ) {
- doScrollCheck();
- }
- }
- }
- })();
-
- })( window, undefined );
-
- // 2012-04-12 修复跟随定位缩放浏览器时无法继续跟随的BUG
- // 2012-04-22 修复弹出层内容的尺寸大于浏览器当前屏尺寸的BUG
- (function() {
- var cssContainer, cssContent, error;
-
- cssContent = ' .pinned{\n padding:3px;\n line-height:0;\n opacity:0.7;\n background: #afb4db;\n border-radius: 20px;\n border:0px solid red;\n position:fixed;\n left:10px;\n bottom:10px;\n }\n\n .invisible{\n display:none;\n cursor: default;\n }\n #configBox{\n width:320px;\n }\n\nbutton::-moz-focus-inner{\nborder:0;\npadding:0;\nmargin:0;\n}\n\n.easyDialog_wrapper{\ncolor:#444;\nborder:3px solid rgba(0,0,0,0);\n-webkit-border-radius:5px;\n-moz-border-radius:5px;\nborder-radius:5px;\n-webkit-box-shadow:0 0 10px rgba(0,0,0,0.4);\n-moz-box-shadow:0 0 10px rgba(0,0,0,0.4);\nbox-shadow:0 0 10px rgba(0,0,0,0.4);\ndisplay:none;\nfont-family:"Microsoft yahei", Arial;\n}\n\n.easyDialog_wrapper .easyDialog_content{\n-webkit-border-radius:4px;\n-moz-border-radius:4px;\nborder-radius:4px;\nbackground:#fff;\nborder:1px solid #e5e5e5;\n}\n\n.easyDialog_wrapper .easyDialog_title{\nheight:30px;\nline-height:30px;\noverflow:hidden;\ncolor:#666;\npadding:0 10px;\nfont-size:14px;\nborder-bottom:1px solid #e5e5e5;\nbackground:#f7f7f7;\nborder-radius:4px 4px 0 0;\n}\n\n.easyDialog_wrapper .close_btn{\nfont-family:arial;\nfont-size:18px;\n_font-size:12px;\nfont-weight:700;\ncolor:#999;\ntext-decoration:none;\nfloat:right;\n}\n\n.easyDialog_wrapper .close_btn:hover{\ncolor:#333;\n}\n\n.easyDialog_wrapper .easyDialog_text{\npadding:25px 10px;\nfont-size:13px;\nline-height:22px;\n}\n\n.easyDialog_wrapper .easyDialog_footer{\npadding:0 10px;\n*zoom:1;\n}\n\n.easyDialog_wrapper .easyDialog_footer:after{\ncontent:\'\';\ndisplay:block;\nheight:0;\noverflow:hidden;\nvisibility:hidden;\nclear:both;\n}\n\n.easyDialog_wrapper .btn_highlight,\n.easyDialog_wrapper .btn_normal{\nborder:1px solid;\nborder-radius:2px;\ncursor:pointer;\nfont-family:"Microsoft yahei", Arial;\nfloat:right;\nfont-size:12px;\npadding:0 12px;\nheight:24px;\nline-height:24px;\nmargin-bottom:10px;\n}\n\n.easyDialog_wrapper .btn_highlight{\nbackground:#4787ed;\nbackground:-webkit-gradient(linear,center bottom,center top,from(#4787ed),to(#4d90fe));\nbackground:-moz-linear-gradient(90deg, #4787ed, #4d90fe);\nborder-color:#3079ed;\ncolor:#fff;\n}\n\n.easyDialog_wrapper .btn_normal{\nmargin-left:10px;\nborder-color:#c3c3c3;\nbackground:#ececec;\ncolor:#333;\nbackground:-webkit-gradient(linear,center bottom,center top,from(#ececec),to(#f4f4f4));\nbackground:-moz-linear-gradient(90deg,#ececec,#f4f4f4);\n}\n\n#alarmHead{\n font-size:120%;\n }';
-
- cssContainer = document.createElement("style");
-
- cssContainer.type = "text/css";
-
- cssContainer.textContent = cssContent;
-
- try {
- document.getElementsByTagName("head")[0].appendChild(cssContainer);
- } catch (_error) {
- error = _error;
- console.log(error);
- }
-
- }).call(this);
-
- (function() {
- var alarmBox, cancelClock, configBox, dateToWork, divToAppend, fridgeMagnet, img64, longWords, msToCoolDown, msToWork, pulseCount, setClock, startPulse, timeoutAlarm;
-
- img64 = 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90HFg8CKzDwrf0AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAA1VJREFUOMudlE9o22UYxz/P82bJ0jZU1M60TZtDVWbA+ifpiCnSoZYJEw87qAdRmH8OguguguBhpx7Eo0wPXkVhuwkWO3EoNkkbOqW0VdYq2LRdalxobYvNn9/v8ZJJbdox/d5eeJ4P7/v9Pu8jtErS6fSAqo6qagroA44AmNk68KOZTW1vb0/Pzs7utDTvPWQymQjwrIicFZE0UAVKwB+AB3QAx4CamY2b2cVqtZqfmZmptwAHBwfbOzo63lDV182sU0Qu+74/3mg0rppZRVXN87xgMBi8V0SeFpEXzOy653kX6vX6ZzehAYBkMnkkFAq9pKrvAL8BH1Sr1UuFQuHGAZYU4/F4LhaLzYvIm8658865XeAiYA4gHo8/5px718x+9zzvfC6Xu7S2trbDIdrc3GwUi8W5/v7+deAJETne3d19dXV1dV0TiURQVZ8BjpnZhXw+P9H0q8XjffIqlcqXwOfAw4FA4DSgbmBg4CFVPQdc2djY+LBcLlebAfXEYrFTXV1dG6VSaesgYrlc9qLR6JpzLiMiD0Sj0ayq6gkRiQKXFxYWtv9JS6RLVV8Oh8Njw8PDJ5sT0KJCobBoZleA+wOBwCMKHAe2arXa/N7CycnJOTMbAxrAGHAunU7feQDTzGwKaIjIfaqq/Wa2Cfy536NsNpur1+vvmdmkqo465/oONNPzfgX+MrOoNmeuTUQChzypJCITZrbNbUhF5AZwh4jcc1iRiNRuBWne/KiIlNTMrgERVU3yP6WqjwLOzBYVmAV8EXkymUze/V9hqVSqDxgxs8VGo/GDep43aWbfqepT4XD4OcDdLiyRSARDodArInIC+GJ6evpnzefzq77vfwpUgLOZTObUyMhIYF+KdWDH8zx/L6yzs/OMiLwIzJvZOOA7gPb29mI4HBYROS0iQ2YW7unpWV5ZWdkC6O3trTnnrqvqT8vLy7upVKqvra3tLefc20DI87z3c7nc14D9a31FIpHXRORVIGZm35vZN8Bco9FYuZlmM4AREXkcKJrZR+vr6x8vLS1VWz5/MplsC4VCJ4HnRWRURCLADrDbLDkKRMxMgW993/9ERL7KZrNb3GqbDA0N3RUIBNIikhaRB0WkF4gAFd/3rwFTwEQ2m/1lf+/fxPttOfXp2toAAAAASUVORK5CYII=';
-
- fridgeMagnet = '<div class="pinned">\n <img id="boxOpen" src="data:image/png;base64,' + img64 + '"></div>';
-
- alarmBox = '<div id="alarmBox">\n <div id="alarmHead">工作时间到</div>\n <div id="hiddenExit">\n <div>请输入以下文字:</div>\n <canvas id="captcha" width="400" height="30"></canvas><br>\n <input type="text" name="captchaIn" id="captchaIn" size="30" style="width:80%;">\n </div>\n</div>';
-
- configBox = '<div id="configBox">\n <div>我就休息\n <input type="number" name="minuteField" id="minuteField" min="1" size="3"\n value="1" onkeyup="this.value=this.value.replace(/[^0-9.]/g,\'\')" />\n 分钟</div>\n</div>';
-
- dateToWork = 0;
-
- pulseCount = 0;
-
- msToCoolDown = 1 * 3600 * 1000;
-
- longWords = ["我荒废的今日,正是昨日殒身之人祈求的明日", "Procrastination", "拖延的基础实际上是对自身不切实际的期望", "the longer you wait the worse it gets", "停止空谈,开始行动", "Lorem ipsum dolor sit amet.", "吃葡萄不吐葡萄皮不吃葡萄倒吐葡萄皮"];
-
- '不要超过20个中文字符\n上面都是我编的,我编不下去了';
-
- setClock = function() {
- '设置休息时间并开始计时';
- var dateClicking, msToWork, relaxMinutes;
- relaxMinutes = parseFloat(document.getElementById("minuteField").value);
- console.log(relaxMinutes);
- if (isNaN(relaxMinutes)) {
- return false;
- }
- if (relaxMinutes <= 0) {
- return false;
- }
- dateClicking = new Date();
- dateToWork = new Date();
- msToWork = dateClicking.getTime() + relaxMinutes * 60 * 1000;
- dateToWork.setTime(parseInt(msToWork));
- localStorage.setItem("msToWork", msToWork);
- console.log(dateClicking);
- console.log(dateToWork);
- console.log(msToWork);
- startPulse();
- return true;
- };
-
- startPulse = function() {
- '每秒检测一次,频率可以更低\n我不喜欢轮询……有更好的方法吗?';
- var dateNow;
- clearTimeout(pulseCount);
- dateNow = new Date();
- if (dateNow >= dateToWork) {
- return timeoutAlarm();
- } else {
- return pulseCount = setTimeout(startPulse, 1000);
- }
- };
-
- cancelClock = function() {
- '干掉pulse,删掉storage';
- clearTimeout(pulseCount);
- localStorage.removeItem("msToWork");
- try {
- easyDialog.close();
- } catch (_error) {}
- return true;
- };
-
- timeoutAlarm = function() {
- '......';
- var c, cxt, longWord;
- longWord = longWords[Math.floor(Math.random() * longWords.length)];
- setTimeout(cancelClock, msToCoolDown);
- easyDialog.open({
- container: {
- content: alarmBox,
- yesFn: function() {
- if (longWord === document.getElementById("captchaIn").value) {
- return cancelClock();
- } else {
- return false;
- }
- }
- }
- });
- c = document.getElementById("captcha");
- cxt = c.getContext("2d");
- cxt.font = "20px serif";
- cxt.textBaseline = "top";
- return cxt.fillText(longWord, 0, 5, 600);
- };
-
- divToAppend = document.createElement("div");
-
- divToAppend.innerHTML = fridgeMagnet;
-
- document.body.appendChild(divToAppend);
-
- document.getElementById("boxOpen").onclick = function() {
- return easyDialog.open({
- container: {
- content: configBox,
- yesFn: setClock,
- noFn: true,
- yesText: "真的!",
- noText: "逗你玩"
- }
- });
- };
-
- '页面间通信';
-
- window.addEventListener("storage", function(e) {
- console.log(e);
- if (e.key === "msToWork") {
- if (e.newValue != null) {
- dateToWork = new Date();
- dateToWork.setTime(parseInt(e.newValue));
- startPulse();
- } else {
- cancelClock();
- }
- }
- }, false);
-
- '页面加载时检测';
-
- if ((msToWork = localStorage.getItem("msToWork")) != null) {
- console.log(msToWork);
- dateToWork = new Date();
- dateToWork.setTime(parseInt(msToWork));
- startPulse();
- }
-
- /*
- TODO
- # 用GM-keys实现部分跨域
- # 取消已开始的计时
- # 树形菜单设置界面
- # 改变颜色
- # 让图标变得可动!!!
- DONE
- # 多标签状态共享
- # 本地存储
- # 有趣的关闭手段
- */
-
-
- }).call(this);