Roll20 Fixes

Some silly fixes and 'improvements' to Roll20 because I'm impatient and a psycho

目前为 2018-09-11 提交的版本。查看 最新版本

// ==UserScript==
// @name         Roll20 Fixes
// @namespace    http://statonions.com/
// @version      0.1
// @description  Some silly fixes and 'improvements' to Roll20 because I'm impatient and a psycho
// @author       Justice Noon
// @match        https://app.roll20.net/editor/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

//Features
var TMp = {
	clickShow: true,
	macroHide: true,
	fullButt: true,
	fixPing: true,
	css: {
		player:	false,
		zoom: false,
		sidebar: false,
		quick: false,
		turns: false,
		macroTok: true
	},
	pfCustomAttr: true,
	splitTokName: true
};

//For *my* players specifically. Activates all css tweaks. I'm too lazy to maintain separate code (in-person touchpad view)
////_.each(TMp.css, (c,i,l) => l[i] = true);
function checkLoaded() {
	if (Campaign.gameFullyLoaded)
		showtime();
	else
		setTimeout(checkLoaded, 1000);
};
checkLoaded();

function showtime() {
	//Display tokenname on touch
	if (TMp.clickShow) {
		var toks = [];
		var callback = function(mutationsList) {
			for(var mutation of mutationsList) {
				if (!_.isEmpty(mutation.addedNodes)) {
					let cct = currentcontexttarget.canvas.lastRenderedObjectWithControlsAboveOverlay.model.attributes;
					if (!cct.showname) {
						cct.showname = true;
						toks.push([cct.page_id, cct.id]);
						Campaign.activePage().loadPageIntoDOM();
					}
					if (cct.gmnotes != 'blank' && TMp.css.macroTok)
						_.each(document.getElementsByClassName('tokenactions')[0].firstElementChild.children, ob => ob.setAttribute('data-blank', 'false'));
				}
				else if (!_.isEmpty(mutation.removedNodes)) {
					_.each(toks, tok => {if (tok[0] == Campaign.activePage().id) _.find(Campaign.activePage().thegraphics.models, tokk => tokk.attributes.id == tok[1]).attributes.showname = false});
					toks = [];
					Campaign.activePage().loadPageIntoDOM();
				}
			}
		};
		var observer = new MutationObserver(callback);
		observer.observe(document.getElementById('editor-wrapper'), {childList: true});
	}

	//Allow Macros to be hidden
	if (TMp.macroHide) {
		var toggleMacro = document.createElement('div');
		toggleMacro.setAttribute('class', 'macrobox');
		var toggleButton = document.createElement('button');
		toggleButton.setAttribute('class', 'btn');
		toggleButton.appendChild(document.createTextNode('Show/Hide'));
		toggleButton.id = 'toggleMacros';
		toggleMacro.appendChild(toggleButton)
		//macrobar is defined by default
		macrobar.appendChild(toggleMacro);
		document.getElementById('toggleMacros').addEventListener('click', () => macrobar.style.left = (macrobar.style.left == '' ? (macrobar.offsetWidth * -1 + 100) + 'px' : ''));
	}

	//Create fullscreen button
	if (TMp.fullButt) {
		var fullScreenLi = document.createElement('li');
		fullScreenLi.setAttribute('tip', 'Toggle Fullscreen');
		fullScreenLi.id = 'fullscreener';
		var fullScreenSpan = document.createElement('span');
		fullScreenSpan.setAttribute('class', 'pictos');
		fullScreenSpan.appendChild(document.createTextNode('`'));
		fullScreenLi.appendChild(fullScreenSpan);
		floatingtoolbar.childNodes[1].appendChild(fullScreenLi);
		fullScreenLi.addEventListener('click', toggleFullScreen);

		function toggleFullScreen() {
			var doc = window.document;
			var docEl = doc.documentElement;

			var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
			var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;

			if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
			requestFullScreen.call(docEl);
			}
			else {
			cancelFullScreen.call(doc);
			}
		}
	}

	//Fix Pings
	if (TMp.fixPing) {
		JSON.parse2 = JSON.parse;
		JSON.parse = function(e) {
			var intercept = JSON.parse2(e);
			if (intercept.type == 'mapping') {
				intercept.currentLayer = 'objects';
				if (intercept.pageid != Campaign.activePage().id)
					intercept.scrollto = false;
			}
			return intercept;
		};
	}

	//CSS override block
	if (_.contains(TMp.css, true)) {
		var style = document.createElement('style');
		style.type = 'text/css';
		//Remove player names/ icons
		if (TMp.css.player)
			style.innerHTML = '.player.ui-droppable {display: none;} ';
		//Remove Zoom Slider
		if (TMp.css.zoom)
			style.innerHTML = '#zoomslider {display:none;} ';
		//Remove sidebar show/ hide button
		if (TMp.css.sidebar)
			style.innerHTML = '#sidebarcontrol {display: none;} ';
		//Increase quickmenu sizes
		if (TMp.css.quick)
			style.innerHTML += '.sheet-roll-cell>a{padding:.5em !important;} ';
		//Permanently hide turn order
		if (TMp.css.turns)
			style.innerHTML += 'div.ui-dialog-buttons[style*="width: 160px;"] {display: none !important;} ';
		//Hide macroTokens by default
		if (TMp.css.macroTok)
			style.innerHTML += 'button[data-type="macro"]:not([data-blank="false"]) {display: none !important;} ';
		document.getElementsByTagName('head')[0].appendChild(style);
	}

	//Character sheets display custom attributes as name
	if (TMp.pfCustomAttr) {
		function cssInjection(charId) {
			var list = [1,2,3,10,11,12];
			var head = 'div.dialog.characterdialog[data-characterid=' + charId + '] {', foot = '';
			_.each(list, function(cK) {
				cK = 'customa' + cK;
				let val = {};
				if (!_.isUndefined(val = _.find(Campaign.characters._byId[charId].attribs.models, at => at.attributes.name == cK + '-name')))
					head += `--${cK}: "${val.attributes.current}"; `
				foot += `input[title="@{buff_${cK}-total}"] + span {visibility: hidden; top: -1.2rem;} input[title="@{buff_${cK}-total}"] + span::after {content: var(--${cK}, "${cK}"); visibility: visible; display: block;} `
			});
			return [head + '} ', foot];
		}
		function newShow(that) {
			var customOver;
			var modCss = cssInjection(that.model.attributes.id);
			if (_.isNull(document.getElementById('customOver'))) {
				customOver = document.createElement('style');
				customOver.type = 'text/css';
				customOver.id = 'customOver';
				customOver.innerHTML = modCss[1];
			}
			else {
				customOver = document.getElementById('customOver');
			}
			customOver.innerHTML += (modCss[0].indexOf('{}') > -1 ? '' : modCss[0]);
			if (that.childWindow)
				_.delay(function() {customOver.innerHTML = modCss.join(' '); window.allChildWindows[0].document.getElementsByTagName('head')[0].appendChild(customOver)}, 2000);
			else
				document.getElementsByTagName('head')[0].appendChild(customOver);
		};
		_.each(Campaign.characters.models, ch => {ch.view.showDialog2 = ch.view.showDialog; ch.view.showDialog = function(e, t) {this.showDialog2(e, t); newShow(this)}});
		_.each(Campaign.characters.models, ch => {ch.view.showPopout2 = ch.view.showPopout; ch.view.showPopout = function(e, t) {this.showPopout2(e, t); newShow(this)}});
		_.each(window.allChildWindows, win => {newShow(Campaign.characters._byId[win.document.getElementsByClassName('dialog characterdialog')[0].getAttribute('data-characterid')].view)});
	}

	//Tokens auto split their name to multiple lines
	if (TMp.splitTokName) {
		var can = document.getElementById('maincanvas').getContext('2d');
		can.fillRect2 = can.fillRect;
		can.fillRect = function(x, y, w, h) {if (this.font != 'bold 14px Arial' && this.fillStyle.indexOf('rgba(255,255,255,0.5') == -1) this.fillRect2(x, y, w, h);};
		can.fillText2 = can.fillText;
		can.fillText = function(t, x, y, m) {
			var g = 14, r = y - 22, n = m;
			var texes = t.split(' ');
			for (var k = 0; k < texes.length; k++) {
				n = this.measureText(texes[k]).width;
				while (this.measureText(texes[k] + ' ' + texes[k+1]).width < r*2 && k+1 < texes.length) {
					texes[k] += ' ' + texes[k+1];
					n = this.measureText(texes[k]).width;
					texes.splice(k+1, 1);
				}
				this.fillStyle = 'rgba(255, 255, 255, 0.50)';
				this.fillRect2(-1 * Math.floor((n + 6) / 2), r + 8 + (g+6)*k, n + 6, g + 6);
				this.fillStyle = 'rgb(0,0,0)';
				this.fillText2(texes[k], x, y + (g+6)*k, n);
			}
		};
	}
}

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址