Skip to content

Instantly share code, notes, and snippets.

@momijizukamori
Last active December 21, 2016 03:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save momijizukamori/c2b108d407e7dd081500e24c8a2db2f5 to your computer and use it in GitHub Desktop.
Save momijizukamori/c2b108d407e7dd081500e24c8a2db2f5 to your computer and use it in GitHub Desktop.
Plurk Helper+
// ==UserScript==
// @name Plurk Helper+
// @version 0.14
// @description Plurk helper functions to enhance web Plurk UI.
// @include https://www.plurk.com/*
// @exclude https://www.plurk.com/_comet/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// Original script (c) 2011 by Skyer
// Forked + updated by momijizukamori
// Reference : http://userscripts-mirror.org/scripts/show/117685
// ver 0.1 (2011/9/16) * First version.
// ver 0.2 (2011/9/17) * Add FireFox support.
// ver 0.3 (2011/9/20) * Support account name for the keyword. Ex: http://www.plurk.com/off60, you can assign off60 for blockList item.
// ver 0.4 (2011/11/01) * Change to Safari extension format. Remove blockList. It will be added outside.
// ver 0.5 (2011/11/04) * Fix error in FF && Chrome
// ver 0.6 (2011/11/05) * Add UI in Plurk. Click Muter in Plurk title to show setting.
// ver 0.7 (2011/11/09) * Name changed. Add Favor function. You can add plurk to favor. The favor is saving in local, and is different than like for Plurk function.
// ver 0.8 (2011/11/09) * The mute will auto refresh to unmute. Fix javascript error.
// ver 0.9 (2011/11/15) * Add import/export. Change some code flow.
// ver 0.10 (2011/11/17) * Add delete favor in settings. Change to use localStorage.
// ver 0.11 (2011/11/17) * Fix JS error in Chrome.
// ver 0.12 (2012/6/05) * Fix JS error in Chrome. ($dp not found)
// ver 0.13 (2012/7/18) * Add: Search keyword in Plurk text. Now keyword searching will apply in Name, ID, Text.
// -------
// ver 0.14 (2016/12/20) * Removed favor code, updated jQuery to function properly, added ability to mute all replurks, switched from timer to mutation observer, temporarily disabled import/export button
// ==/UserScript==
var timeoutID;
var no_replurks;
var myWindow = window;
function updateLocalStorage() {
localStorage.gmgetsetting = JSON.stringify(globalsetting);
}
function fetchKeywords(keyword, ui) {
if (typeof keyword == 'undefined' || keyword.length <= 0) return;
var arr = keyword.split(',');
var list = document.getElementById('keywords');
outSideBlockList = [
];
for (var i = 0; i < arr.length; ++i) {
if (arr[i].length > 0) {
if (ui) {
var option = document.createElement('option');
option.text = arr[i];
list.add(option, null);
}
outSideBlockList.push(arr[i]);
}
}
}
function updateSetting() {
var list = document.getElementById('keywords');
var setting = '';
for (var i = 0; i < list.length; ++i) {
setting = setting + ',' + list.options[i].text;
}
if (setting.length > 0)
setting = setting.substring(1, setting.length);
GM_setValue('keywords', setting);
}
function initEventListener() {
$('button#add').click(function () {
var list = document.getElementById('keywords');
var input = document.getElementById('keyword');
var option = document.createElement('option');
option.text = input.value;
list.add(option, null);
outSideBlockList.push(option.text);
updateSetting();
});
$('button#delkeys').click(function () {
var list = document.getElementById('keywords');
var index = list.selectedIndex;
if (index == - 1) return;
list.remove(index);
outSideBlockList.splice(index, 1);
updateSetting();
});
$('button#close').click(function () {
$('#shelpersetting').css({
'display': 'none'
});
});
$('#plurkmuter').click(function () {
$('#shelpersetting').css('display', '');
});
$('button#edit').click(function () {
var result = myWindow.prompt('Export / Import helper settings.', JSON.stringify(globalsetting));
var parsed = undefined;
try {
parsed = JSON.parse(result);
} catch (exception) {
parsed = undefined;
}
if (typeof parsed != 'undefined') {
globalsetting = parsed;
updateLocalStorage();
}
});
$('#no-replurks').click(function () {
if (document.getElementById('no-replurks').checked) {
no_replurks = 'true';
GM_setValue('no_replurks', 'true');
} else {
no_replurks = 'false';
GM_setValue('no_replurks', 'false')
}
})
}
function injectMuter() {
$('#navbar_top_tab').after('<li id="mute_controls" class="item left"><a id="plurkmuter" href="#" class="pif-volume-mute"></a></li>');
$('body').append('<div id="shelpersetting" class = "popMenu popView" style="color: #000000; position:absolute; top:45px; left:100px; background-color:#FFFFFF; z-index: 5000; display: none;">' +
'<div id="mutertab" class = "popViewContent" style="height:350px; overflow: auto;">' +
'<b>Plurk Auto-Mute</b>' +
'<div id="mutersetting" >' +
'<p>Auto mute plurks with matched keywords</p>' +
'<form id="keyword_form">' +
'Keyword: <input name="keyword" id="keyword" /> <button name="add" id="add" type="button">Add</button> ' +
'<button name="delkey" id="delkeys" type="button">Delete</button><br>' +
'<select name="keywords" id="keywords" multiple="multiple" size="10" width="300" style="width: 300px;"></select> <br>' +
'<input type="checkbox" id="no-replurks" value="no_replurks"> Auto-mute all replurks' +
'</form>' +
'</div>' +
'<button name="close" id="close" type="button">Close</button> ' +
// '<button id="edit" type="button">Export/Import</button>' +
'</div>' +
'</div>');
initEventListener();
no_replurks = GM_getValue('no_replurks');
document.getElementById('no-replurks').checked = (no_replurks == 'true');
fetchKeywords(GM_getValue('keywords'), true);
}
function doRTE() {
console.log("firing doRTE");
var blockList = typeof outSideBlockList == 'undefined' ? undefined : outSideBlockList;
if (typeof blockList == 'undefined') {
timeoutID = myWindow.setTimeout(doRTE, 2000);
return;
}
function do_match(text) {
for (k = 0; k <= blockList.length; k++) {
var keyword = blockList[k];
var r = text && text.match(keyword); // XXX: rule here.
if (r && r[0].length > 0) {
// console.debug( 'match:' , r);
return 1;
}
}
return 0;
}
function set_mute(pid, v) {
$.ajax({
type: 'POST',
url: '/TimeLine/setMutePlurk',
data: 'plurk_id=' + pid + '&value=' + v,
success: function (msg) {
console.log('muted: ' + pid + ', ' + msg);
}
});
}
var plurks = $('.plurk');
plurks.each(function (index) {
var me = $(this);
var plurk = me.get(0).id.match(/p(\d+)/);
if (plurk) {
var plurk_id = plurk[1];
var nameObj = me.find('.name');
var titleObj = me.find('.text_holder');
var urlName = nameObj.attr('href');
var textName = nameObj.html();
var title = titleObj.html();
var muted = me.get(0).className;
var replurk = me.find('.q_replurks').length;
if (do_match(urlName) || do_match(textName) || do_match(title) && !muted.match('muted')) {
console.log('Mute ' + plurk_id + ', ' + textName + ' (' + urlName + ')');
set_mute(plurk_id, 2);
me.removeClass('new').addClass('muted');
myWindow.$dp.mute_link.innerText = myWindow._('unmute');
myWindow.PlurkMetaData.muted[plurk_id] = true;
myWindow.$plurks['p' + plurk_id].obj.is_unread = 2;
}
if (no_replurks == 'true' && replurk && !muted.match('muted')) {
console.log('Mute ' + plurk_id + ', ' + textName + ' (' + urlName + ')');
set_mute(plurk_id, 2);
me.addClass('muted');
me.removeClass('new');
myWindow.$dp.mute_link.innerText = myWindow._('unmute');
myWindow.PlurkMetaData.muted[plurk_id] = true;
myWindow.$plurks['p' + plurk_id].obj.is_unread = 2;
}
}
});
//timeoutID = myWindow.setTimeout(doRTE, 2000);
}
$(function () {
globalsetting = undefined;
try {
globalsetting = JSON.parse(localStorage.gmgetsetting);
} catch (e) {
;
}
if (globalsetting == undefined)
globalsetting = {
};
injectMuter();
//timeoutID = myWindow.setTimeout(doRTE, 100);
// select the target node
var timeline = document.getElementById('timeline_cnt');
// configuration of the observer:
var config = { childList: true, subtree: true};
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var arr = $.makeArray(mutation.addedNodes);
var newplurks = $(arr).filter('.plurk');
if (newplurks.length > 0) {
doRTE();
}
});
});
// pass in the target node, as well as the observer options
observer.observe(timeline, config);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment