Skip to content

Instantly share code, notes, and snippets.

@sunnylost
Last active August 22, 2016 10:11
Show Gist options
  • Save sunnylost/9a1312549f89a5e7608e to your computer and use it in GitHub Desktop.
Save sunnylost/9a1312549f89a5e7608e to your computer and use it in GitHub Desktop.
Tampermonkey scripts
// ==UserScript==
// @name ShowMeTheData
// @namespace http://tampermonkey.net/
// @version 0.1
// @description display page's data
// @author sunnylost
// @match http://*.meilishuo.com/*
// @match https://*.meilishuo.com/*
// @exclude https://email.meilishuo.com/*
// @grant none
// @require https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser-polyfill.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser.min.js
// ==/UserScript==
/* jshint ignore:start */
var inline_src = (<><![CDATA[
/* jshint ignore:end */
/* jshint esnext:true, lastsemic:true, asi:true */
function showData() {
var now = new Date(),
url = location.href,
searchStr = '__pd__=/rb/' + ( now.getDate() + now.getMonth() + 1 )
if ( location.hash ) {
url = url.replace( location.hash, '' )
}
url = url.replace( /__pd__=\/rb\/\d+/g, '' )
url += ( location.search.length ? '&' : '?' ) + searchStr
window.open( url, '_blank' )
}
window.addEventListener( 'keypress', function( e ){
if ( e.ctrlKey && e.key === 'q' ) {
showData()
}
})
/* jshint ignore:start */
]]></>).toString();
var c = babel.transform(inline_src);
eval(c.code);
/* jshint ignore:end */
/**
* 进入 http://gitlab.xxxx.com/groups/xxxx/group_members
* 激活身份选择列表
*/
$('.js-toggle-container')
.find('.pull-right .js-toggle-button')
.click()
/**
* 选择用户权限
* 20 reporter
* 30 dev
* 40 master
*/
$('.js-toggle-container')
.find('.form-control option[value="40"]').prop('selected',true)
//提交修改
$('.js-toggle-container .btn-save').click()
// ==UserScript==
// @name PrePublish
// @namespace sunnylost
// @version 0.1
// @description try to take over the world!
// @author sunnylost
// @match http://deployment.mogujie.org/*
// @grant GM_addStyle
// ==/UserScript==
/* jshint esnext:true, lastsemic:true, asi:true, expr: true */
/* globals GM_addStyle, $ */
(function () {
'use strict'
//http://deployment.mogujie.org/deploy/queryRelease.do?orderId=51795&env=pre
//build 页面被激活的 panel
var $activeTab,
minTimeout = 500,
classPre = 'pre-script-',
scriptPre = 'js-pre-script-',
globalBtnHook = `${ scriptPre }hook`,
$body = $( document.body ),
rRouter = /#\/([^?/]+)(?:\/(\d+))?/,
maxTop = 1e6,
globalConfigType, $logWindow, $log, $show, orderID,
eventHandler = {
jumpToConfig() {
sessionStorage.setItem( globalConfigType, this.dataset.type )
location.href = this.dataset.link
},
close() {
$show.show()
$logWindow.hide()
},
show() {
$show.hide()
$logWindow.show()
}
},
App = {
_isRunning: false,
isRunning() {
return this._isRunning
},
begin() {
this._isRunning = true
},
finish() {
this._isRunning = false
}
}
/**
* 初始化基础内容
* 绑定 hashchange 事件
* 执行 run 函数
*/
function init() {
initInfrastructure()
$logWindow = $body.find( `.${ scriptPre}log-window` )
$log = $logWindow.find( `.${ scriptPre }log` )
$show = $body.find( `.${ scriptPre }show` )
$body.on( 'click', '.' + globalBtnHook, function () {
eventHandler[ this.dataset.action ].call( this )
} )
$( window ).on( 'hashchange', run )
delay( run )
}
function initInfrastructure() {
GM_addStyle( `
.${ classPre }log-window {
display: flex;
width: 300px;
height: 200px;
position: fixed;
left: 75px;
bottom: 10px;
background: #232c32;
}
.${ classPre }log-content {
margin: auto;
width: 92%;
height: 90%;
line-height: 18px;
font-size: 13px;
overflow: scroll;
color: #fff;
word-wrap: break-word;
}
.${ classPre }log-content p {
margin: 0 0 5px;
}
.${ classPre }current {
background: #fff;
color: #232c32;
}
.${ classPre }close {
position: absolute;
top: 0;
right: 10px;
padding: 2px 5px;
color: #fff;
font-style: normal;
font-size: 20px;
z-index: 10;
cursor: pointer;
}
.${ classPre }show {
display: none;
position: relative;
color: #fff;
top: 50px;
font-size: 12px;
margin: auto;
cursor: pointer;
}
.${ classPre }text-highlight {
font-weight: bold;
color: #27ae60;
}
.${ classPre }text-warn {
font-weight: bold;
color: #ef4706;
}
.${ classPre }hint {
position: absolute;
top: -25px;
left: -20px;
padding: 2px 5px;
background: #232c32;
color: #fff;
font-size: 12px;
white-space: nowrap;
animation: bubble 1.5s ease-in 0s infinite;
}
.${ classPre }hint::before {
content: "";
position: absolute;
left: 40px;
bottom: -12px;
border: 6px solid;
border-color: #232c32 transparent transparent transparent;
}
@-webkit-keyframes bubble {
0% {
top: -25px;
}
50% {
top: -35px;
}
100% {
top: -25px;
}
}
` )
//log window
$body.append( `
<div class="${ classPre }log-window ${ scriptPre }log-window">
<i class="${ classPre }close ${ globalBtnHook }" data-action="close">x</i>
<div class="${ classPre }log-content ${ scriptPre }log"></div>
</div>
` )
$( '#col-left' ).append( `<div class="${ classPre }show ${ globalBtnHook } ${ scriptPre }show" data-action="show">显示控制台</div>` )
}
function log( content ) {
$log
.find( `.${ classPre }current` ).removeClass()
.end()
.append( `<p class="${ classPre }current">${ content }</p>` )
.scrollTop( maxTop )
}
function delay( fn, time ) {
setTimeout( fn, time || minTimeout )
}
function readyAndGo( option, callback ) {
var type = typeof option
if ( type === 'string' ) {
if ( $( option ).length ) {
return callback()
}
} else if ( type === 'function' ) {
if ( option() ) {
return callback()
}
} else if ( type === 'object' ) { //jQuery
if ( option.length ) {
return callback()
}
}
delay( function () {
readyAndGo( option, callback )
} )
}
function generateButtons() {
log( '生成预发与上线按钮' )
//pre & online button
readyAndGo( function () {
return $( 'tbody tr' ).length > 1
}, function () {
if ( $body.find( 'tbody tr' ).length <= 1 ) {
log( '执行失败, 再次尝试执行' )
delay( generateButtons, 500 )
}
$body.find( 'tbody tr' )
.each( function () {
//发布按钮
var $td = $( this ).find( 'td' ).last(),
btn = $td.find( 'a' ).last(),
href = btn.attr( 'href' )
btn.hide()
$td.append( `
<a href="javascript: void 0;" class="${ globalBtnHook }" data-action="jumpToConfig" data-link="${ href }" data-type="pre">
<button type="button" class="btn btn-success">预发</button>
</a>
<a href="javascript: void 0;" class="${ globalBtnHook }" data-action="jumpToConfig" data-link="${ href }" data-type="online">
<button type="button" class="btn btn-success">上线</button>
</a>
` )
} )
App.finish()
} )
}
function click( selector ) {
readyAndGo( selector, function () {
log( `点击 ${ selector } 元素` )
$body.find( selector ).trigger( 'click' )
} )
}
function check() {
return $( '.form-control[label="git commit"]' ).val().length > 10
}
function getOrderID() {
return orderID || location.hash.match( rRouter )[ 2 ]
}
function task( fn ) {
return new Promise( function ( resolve ) {
delay( function () {
fn()
resolve()
} )
} )
}
function checkPackState() {
return $.ajax( {
url : 'http://deployment.mogujie.org/deploy/pack.do',
data : {
orderId: getOrderID(),
first : 1,
env : sessionStorage.getItem( globalConfigType )
},
dataType: 'json'
} ).done( function ( data ) {
if ( !data.success ) {
log( data.errorMsg )
}
} )
}
function checkReleaseState( type ) {
return new Promise( function ( resolve ) {
function check() {
$.ajax( {
url : 'http://deployment.mogujie.org/deploy/queryRelease.do',
data : {
env : sessionStorage.getItem( globalConfigType ),
orderId: getOrderID()
},
dataType: 'json'
} ).done( function ( data ) {
if ( data.success && data.data ) {
if ( type === 'build' ) {
data.data[ 0 ].status === '打包成功' && resolve()
} else {
data.data[ data.data.length - 1 ].status === '发布完成' && resolve()
}
} else {
delay( check )
}
} )
}
check()
} )
}
function jumpToPublishPage() {
if ( check() ) {
//版本号获取成功,准备跳转
click( '.contion-fooder button' )
readyAndGo( '.war-modal', function () {
var text = $( '.war-modal' ).text()
if ( text.indexOf( '已在发布' ) !== -1 ) {
log( `当前版本已经在发布了, 请去<span class="${ classPre }text-highlight">发布任务</span>页面将前面的任务停掉` )
$( '.war-btn.primary' ).click()
location.href = $( '#sidebar-nav a' ).last().attr( 'href' )
}
} )
App.finish()
} else {
delay( jumpToPublishPage )
}
}
/**
* 上线与预发的配置
*/
function publishConfig() {
switch ( sessionStorage.getItem( globalConfigType ) ) {
case 'online':
log( `准备配置<span class="${ classPre }text-highlight">上线</span>环境` )
delay( jumpToPublishPage )
break
case 'pre':
log( `准备配置<span class="${ classPre }text-highlight">预发</span>环境` )
log( `请手动点击<span class="${ classPre }text-warn">pre</span>标签` )
$( '.nav-tabs li:eq(2)' ).append( `<div class="${ classPre }hint ${ scriptPre }hint">请手动点击这里</div>` )
delay( function () {
$( '.nav-tabs li:eq(2) a' ).on( 'click', jumpToPublishPage )
} )
break
}
delay( function () {
//选择 master
$( '.form-control' ).first().find( 'option' ).each( function ( i, v ) {
if ( v.value === 'master' ) {
$( v ).prop( 'selected', true )
click( '.checkbox input' )//获取最新版本号
}
} )
} )
}
/**
* 开始发布
*/
function beginPublish() {
var matches = location.hash.match( /(#\/[^?/]+\/\d+\/)(\d+)(\?.*)/ ),
newHash = matches[ 1 ] + '2' + matches[ 3 ]
switch ( sessionStorage.getItem( globalConfigType ) ) {
case 'online':
$activeTab = $( '.tab-pane.active' )
if ( checkBuildSuccess() ) {
task( publishOnline )
} else {
task( function () {
//build 按钮
log( '点击 build 按钮' )
click( $activeTab.find( '.bown-btn button:eq(0)' ) )
} )
.then( function () {
return task( function () {
log( '填写上线表单' )
delay( function () {
var $dialog = $( '.modal-dialog' )
//默认选择“业务需求”
$dialog.find( '.modal-reason select option' )
.each( function () {
if ( this.innerText.indexOf( '业务需求' ) !== -1 ) {
$( this ).prop( 'selected', true )
}
} )
//发布说明写 “发布代码上线”
$dialog.find( '.modal-explain textarea' ).val( '发布代码上线' )
//回滚方案默认
$dialog.find( '.modal-rollback textarea' ).val( '正常回滚' )
$dialog.find( '.modal-footer .btn-primary' )
.on( 'click', function () {
//todo, 弹出对话框, 点击确定后开始打包、上线
} )
} )
} )
} )
.then( function () {
delay( function () {
log( '点击“任务下发”成功的按钮' )
click( '.war-btn.primary' )
publishOnline()
} )
} )
}
break
case 'pre':
//预发是第二个面板
if ( matches[ 2 ] != '2' ) {
location.href = location.href.replace( location.hash, newHash )
location.reload()
} else {
$activeTab = $( '.tab-pane.active' )
if ( checkBuildSuccess() ) {
task( publishPre )
} else {
task( function () {
//build 按钮
log( '点击 build 按钮' )
click( $activeTab.find( '.bown-btn button:eq(0)' ) )
} )
.then( function () {
return task( function () {
log( '确定开始 build' )
delay( function () {
checkPackState()
.then( function ( isFinish ) {
//打包失败, 可能有任务正在进行中
if ( !isFinish.success ) {
location.hash = $( '#col-left-inner li a' ).last().attr( 'href' )
}
} )
click( '.war-btn.primary' )
} )
} )
} )
.then( function () {
delay( function () {
log( '点击“任务下发”成功的按钮' )
click( '.war-btn.primary' )
publishPre()
} )
} )
}
}
break
}
}
function publishPre() {
//添加任务成功, 检测打包状态
checkReleaseState( 'build' )
.then( function () {
log( '点击 "pre 发布" 按钮' )
click( $activeTab.find( '.btn-success:eq(1)' ) )
delay( function () {
log( '点击 "确定 pre 发布" 按钮' )
click( '.war-btn.primary' )
delay( function () {
log( '点击 "发布成功" 按钮' )
click( '.war-btn.primary' )
checkReleaseState()
.then( function () {
log( '发布成功!!!' )
App.finish()
} )
} )
} )
} )
}
//TODO
function publishOnline() {
}
function checkBuildSuccess() {
return $activeTab.find( 'table tbody tr td' ).eq( 4 ).html() === '打包成功'
}
function run() {
if ( App.isRunning() ) {
return
}
App.begin()
var matches = location.hash.match( rRouter )
if ( !matches || matches.length < 2 ) {
return
}
orderID = matches[ 2 ]
switch ( matches[ 1 ] ) {
//首页
case 'itemslist':
generateButtons()
break
//配置 ip、git version
case 'issue':
publishConfig()
break
//real work!!!
case 'itemdetails':
beginPublish()
break
default:
App.finish()
}
}
setTimeout( init, minTimeout )
})()
// ==UserScript==
// @name Scroll To Top
// @namespace sunnylost
// @version v1.3.2
// @grant unsafeWindow
// @grant GM_addStyle
// @include http://*
// @include https://*
// ==/UserScript==
/* jshint esnext:true, lastsemic:true, asi:true */
(function(global) {
if(global !== window) return;
function _(id) {
return document.getElementById(id);
}
function bind(context, name) {
return function() {
return context[name].apply(context, arguments);
}
}
unsafeWindow.addEventListener('scroll', scrollHandler, false);
function scrollHandler() {
!scroll.isScrolling && ((scroll.getScrollY() > 0) ? scroll.showBtn() : scroll.hideBtn());
}
var scroll = {
__scrollY : 0,
isScrolling : false, //is scrolling
imgBtn : null,
isBtnShow : false,
pageHeight : 0,
speed : 0.75,
init : function() {
var document = global.document,
div = document.createElement('div'),
css;
css = '#__scrollToTop{font:12px/1em Arial,Helvetica,sans-serif;margin:0;padding:0;position:fixed;display:none;left:92%;top:80%;text-align:center;z-index:999999; width:74px;height:50px;' +
'cursor:pointer;opacity:0.5;padding:2px;}' +
'#__scrollToTop:hover{opacity:1;}' +
'#__scrollToTop span.__scroll__arrow{ position:relative;top:20px;background:none repeat scroll 0 0 #eee;border-style:solid; border-width:1px;' +
'border-color:#ccc #ccc #aaa; border-radius:5px;color:#333;font-size:36px;padding:5px 8px 2px;}' +
' #__scroll__scroll{height:50px;width:50px;float:left;z-index:100001;position:absolute;} ' +
'#__scroll__util{font:12px/1em Arial,Helvetica,sans-serif;text-align:center;height:44px;width:20px;float:right;position:absolute;left:54px;z-index:100000; ' +
'border-style:solid; border-width:1px;border-color:#ccc #ccc #aaa; border-radius:2px;top:5px;display:none;}' +
'#__scroll__util span{display:block;height:18px;padding-top:4px;text-align:center;text-shadow:2px 2px 2px #888;font-size:16px;} ' +
'#__scroll__util span:hover{background-color: #fc9822;}';
GM_addStyle(css);
div.id = '__scrollToTop';
div.title = 'Back To Top';
div.innerHTML = '<div id="__scroll__scroll">' +
'<span class="__scroll__arrow">▲</span>' +
'</div>' +
'<div id="__scroll__util">' +
'<span name="__hide" title="Hide the Button">x</span>' +
'<span name="__bottom" title="Scroll to the bottom">▼</span>' +
'</div>';
document.body.appendChild(div);
div.addEventListener('mousedown', bind(this, 'control'),false);
div.addEventListener('mouseover', bind(this, 'showUtil'),false);
div.addEventListener('mouseout', bind(this, 'hideUtil'),false);
this.util = _('__scroll__util');
this.pageUtil = _('__scroll__page');
this.pageHeight = document.body.scrollHeight;
return this.imgBtn = div;
},
getImgBtn : function() {
return this.imgBtn || this.init();
},
show : function(elem) {
elem.style.display = 'block';
},
hide : function(elem) {
elem.style.display = 'none';
},
showBtn : function() {
if(this.isBtnShow) return;
this.isBtnShow = true;
this.show(this.getImgBtn());
},
hideBtn : function() {
if(!this.isBtnShow) return;
this.isBtnShow = false;
this.hide(this.getImgBtn());
},
getScrollY : function() {
//this piece of code is from John Resig's book 'Pro JavaScript Techniques'
var de = document.documentElement;
return this.__scrollY = (self.pageYOffset ||
( de && de.scrollTop ) ||
document.body.scrollTop);
},
closeBtn : function(event) {
event.preventDefault();
event.stopPropagation();
this.hideBtn();
unsafeWindow.removeEventListener('scroll', scrollHandler, false);
},
showUtil : function() {
this.show(this.util);
},
hideUtil : function() {
this.hide(this.util);
},
scroll : function() {
if(!this.isScrolling) {
this.isScrolling = true;
}
var isStop = false,
scrollY = this.__scrollY;
if(this.direction === 'top') {
isStop = scrollY > 0;
this.__scrollY = Math.floor(scrollY * this.speed);
} else {
isStop = scrollY < this.pageHeight;
this.__scrollY += Math.ceil((this.pageHeight - scrollY) * (1 - this.speed)) + 10;
}
this.isScrolling = isStop;
unsafeWindow.scrollTo(0, this.__scrollY);
isStop ? setTimeout(bind(scroll, 'scroll'), 20) : (this.direction === 'top' && this.hideBtn());
},
control : function(e) {
var t = e.target, name = t.getAttribute('name');
switch(name) {
case '__bottom':
this.scrollToBottom();
break;
case '__hide' :
this.closeBtn(e);
break;
default :
this.scrollToTop();
break;
}
},
scrollToTop : function() {
this.direction = 'top';
this.scroll();
},
scrollToBottom : function() {
this.direction = 'bottom';
var bodyHeight = global.document.body.scrollHeight,
documentElementHeight = global.document.documentElement.scrollHeight;
this.pageHeight = Math.max(bodyHeight, documentElementHeight);
this.scroll();
}
};
//Autoscroll
(function() {
var isAutoScroll = false;
var autoScroll = {
__autoScrollID : 0,
isAutoScroll : false,
defaultSpeed : 1,
currentSpeed : 1,
intervalTime : 100,
reset : function() {
this.isAutoScroll && (this.currentSpeed = this.defaultSpeed);
},
startOrStop : function() {
var that = this;
if(that.isAutoScroll) {
that.isAutoScroll = false;
clearInterval(that.__autoScrollID);
} else {
that.isAutoScroll = true;
that.__autoScrollID = setInterval(function() {
global.scrollBy(0, that.currentSpeed);
}, that.intervalTime);
}
},
fast : function() {
this.isAutoScroll && this.currentSpeed <= 10 && this.currentSpeed++;
},
slow : function() {
this.isAutoScroll && this.currentSpeed > 1 && this.currentSpeed--;
},
keyControl : function(e) {
if(e.target != global.document.body && e.target != global.document.documentElement) return false; // only when the cursor focus on the page rather than the input area can trigger this event.
var charCode = e.charCode,
key = this.keyMap[charCode];
key && this[key]();
},
keyMap : {
'100' : 'slow', // press 'd', slow the speed of the scroll
'102' : 'fast', // press 'f', speed scroll
'114' : 'reset', // press 'r', reset the autoscroll's speed
'115' : 'startOrStop' //when you click 's' at the first time, the autoscroll is begin, and then you click again, it will stop.
}
};
global.addEventListener('keypress', bind(autoScroll, 'keyControl'), false);
}())
}(window.top))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment