Last active
April 2, 2020 19:02
-
-
Save tsiemens/5d6507590a35ebde833b388e48510862 to your computer and use it in GitHub Desktop.
Google Docs Preview Redirect Tampermonkey Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Preview Google Docs | |
| // @version 1.0.0 | |
| // @description Same you some CPU and RAM | |
| // @author Trevor Siemens | |
| // @homepageUrl https://gist.github.com/tsiemens/5d6507590a35ebde833b388e48510862 | |
| // @match https://docs.google.com/document/d/*/edit* | |
| // @match https://docs.google.com/document/d/*/preview* | |
| // @run-at document-start | |
| // @grant GM_addStyle | |
| // @grant GM_getValue | |
| // @grant GM_setValue | |
| // @grant GM_registerMenuCommand | |
| // @require https://openuserjs.org/src/libs/sizzle/GM_config.min.js | |
| // ==/UserScript== | |
| // *************************************************** | |
| // General utils | |
| // *************************************************** | |
| const logSig = "Preview Google Docs (tamper):"; | |
| // *************************************************** | |
| // GM_config | |
| // https://github.com/sizzlemctwizzle/GM_config/ | |
| // *************************************************** | |
| const settingsFieldDefs = { | |
| 'alwaysRedirectFrom': { | |
| 'section': [GM_config.create("Auto-Redirection Rules"), "One URL regex per line"], | |
| 'label': 'Always redirect to preview when coming from these domains', | |
| 'labelPos': 'top', | |
| 'type': 'textarea', | |
| 'default': 'https?:\/\/aid[\.\/]' | |
| }, | |
| 'neverRedirectFrom': { | |
| 'label': 'Do not ask or redirect to preview when coming from these domains', | |
| 'labelPos': 'top', | |
| 'type': 'textarea', | |
| 'default': '' | |
| }, | |
| 'showPreviewPageSnackbar': { | |
| 'section': "Preview page settings", | |
| 'label': 'Show notification when redirected to preview page', | |
| 'type': 'checkbox', | |
| 'default': true | |
| } | |
| }; | |
| function _addConfigErrorText(doc, parentElemId, id) { | |
| let parentGrp = doc.getElementById(parentElemId); | |
| let errorDiv = doc.createElement("div"); | |
| errorDiv.setAttribute("id", id); | |
| errorDiv.className = "ugm_config_error_msg"; | |
| parentGrp.appendChild(errorDiv); | |
| return errorDiv; | |
| } | |
| function _setConfigErrorMsg(configId, errorDiv) { | |
| let text = GM_config.get(configId); | |
| let res = _parsePatternsFromMultilineText(text); | |
| errorDiv.innerHTML = res.errors.join("\n"); | |
| } | |
| function _getRegexTestMatches(configId, testUrl) { | |
| let text = GM_config.get(configId); | |
| let res = _parsePatternsFromMultilineText(text); | |
| let matches = []; | |
| for (let pattern of res.patterns) { | |
| if (testUrl.search(pattern) >= 0) { | |
| matches.push(pattern.toString()); | |
| } | |
| } | |
| return matches; | |
| } | |
| var _updateRegexTestResult = null; | |
| function _addRegexTestInput(doc) { | |
| let section0Container = doc.getElementById("GM_config_section_0"); | |
| let inputWrapper = doc.createElement("div"); | |
| inputWrapper.className = "config_var"; // Standard GM_config class for config styles | |
| // <input id="GM_config_field_name" type="text" size="25"> | |
| // <label id="GM_config_name_field_label" for="GM_config_field_name" class="field_label">Name</label> | |
| let testInput = doc.createElement("input"); | |
| testInput.setAttribute("id", "GM_config_regex_test_input"); | |
| testInput.setAttribute("type", "text"); | |
| testInput.setAttribute("size", "25"); | |
| testInput.setAttribute("autocomplete", "off"); | |
| inputWrapper.appendChild(testInput); | |
| let label = doc.createElement("label"); | |
| label.className = "field_label"; // Standard GM_config class for config styles | |
| label.setAttribute("for", "GM_config_field_name"); | |
| label.innerHTML = "Enter a URL here to test (save first)"; | |
| inputWrapper.appendChild(label); | |
| section0Container.appendChild(inputWrapper); | |
| let testingResult = doc.createElement("p"); | |
| testingResult.setAttribute("id", "GM_config_regex_test_output"); | |
| section0Container.appendChild(testingResult); | |
| _updateRegexTestResult = () => { | |
| let matchesA = _getRegexTestMatches("alwaysRedirectFrom", testInput.value); | |
| let matchesN = _getRegexTestMatches("neverRedirectFrom", testInput.value); | |
| let matchText = ""; | |
| let lines = []; | |
| if (matchesA.length > 0) { | |
| lines.push("Matches from 'always redirect' patterns:"); | |
| for (let match of matchesA) { | |
| lines.push(match); | |
| } | |
| } | |
| if (matchesN.length > 0) { | |
| lines.push("Matches from 'never redirect' patterns:"); | |
| for (let match of matchesN) { | |
| lines.push(match); | |
| } | |
| } | |
| if (lines.length == 0 && testInput.value.length > 0) { | |
| lines.push("No matching patterns"); | |
| } | |
| testingResult.innerHTML = lines.join("<br>"); | |
| }; | |
| testInput.addEventListener('input', _updateRegexTestResult); | |
| } | |
| function _gmConfigInit() { | |
| // GM_config included from external lib | |
| 'use strict'; | |
| let context = {} | |
| GM_config.init( | |
| { | |
| id: 'GM_config', | |
| title: 'Preview Google Docs Settings', | |
| fields: settingsFieldDefs, | |
| css: `#GM_config_section_1 .config_var, #GM_config_section_2 .config_var, #GM_config_section_3 .config_var { | |
| margin: 5% !important;display: inline !important; | |
| } | |
| .ugm_config_error_msg { | |
| color: #f00; | |
| }`, | |
| events: | |
| { | |
| open: function(doc) { | |
| // Custom modifications to the settings panel can be made here. | |
| let errorDiv = _addConfigErrorText(doc, "GM_config_alwaysRedirectFrom_var", | |
| "GM_config_alwaysRedirectFrom_errors"); | |
| context.alwaysRedirErrorDiv = errorDiv; | |
| errorDiv = _addConfigErrorText(doc, "GM_config_neverRedirectFrom_var", | |
| "GM_config_neverRedirectFrom_errors"); | |
| context.neverRedirErrorDiv = errorDiv; | |
| _addRegexTestInput(doc); | |
| }, | |
| save: function(values) { | |
| // All the values that aren't saved are passed to this function | |
| // for (i in values) alert(values[i]); | |
| _setConfigErrorMsg("alwaysRedirectFrom", context.alwaysRedirErrorDiv); | |
| _setConfigErrorMsg("neverRedirectFrom", context.neverRedirErrorDiv); | |
| _updateRegexTestResult(); | |
| } | |
| } | |
| }); | |
| } | |
| function _parsePatternsFromMultilineText(text) { | |
| let lines = text.split('\n'); | |
| let patterns = []; | |
| let errors = []; | |
| for (let line of lines) { | |
| if (line.length > 0) { | |
| try { | |
| let pat = RegExp(line); | |
| patterns.push(pat); | |
| } catch (e) { | |
| errors.push("Error in \"" + line + "\" : " + e.message); | |
| } | |
| } | |
| } | |
| return {patterns: patterns, errors: errors}; | |
| } | |
| function _getAlwaysRedirectFromList() { | |
| let text = GM_config.get("alwaysRedirectFrom"); | |
| let res = _parsePatternsFromMultilineText(text); | |
| return res.patterns; | |
| } | |
| function _getNeverRedirectFromList() { | |
| let text = GM_config.get("neverRedirectFrom"); | |
| let res = _parsePatternsFromMultilineText(text); | |
| return res.patterns; | |
| } | |
| // *************************************************** | |
| // Preview page functions | |
| // *************************************************** | |
| function _addSnackbarStyles() { | |
| 'use strict'; | |
| GM_addStyle(` | |
| #ugm_snackbar { | |
| visibility: hidden; | |
| min-width: 250px; | |
| margin-left: -125px; | |
| background-color: #333; | |
| color: #fff; | |
| text-align: center; | |
| border-radius: 2px; | |
| padding: 16px; | |
| position: fixed; | |
| z-index: 1000; | |
| left: 50%; | |
| bottom: 30px; | |
| font-size: 17px; | |
| } | |
| #ugm_snackbar.show { | |
| visibility: visible; | |
| // Each part is [ name, duration, delay (absolute) ] | |
| -webkit-animation: ugm_fadein 0.5s, ugm_fadeout 0.5s 2.5s, ugm_stayout 20s 3s; | |
| animation: ugm_fadein 0.5s, ugm_fadeout 0.5s 2.5s, ugm_stayout 20s 3s; | |
| } | |
| @-webkit-keyframes ugm_fadein { | |
| from {bottom: 0; opacity: 0;} | |
| to {bottom: 30px; opacity: 1;} | |
| } | |
| @keyframes ugm_fadein { | |
| from {bottom: 0; opacity: 0;} | |
| to {bottom: 30px; opacity: 1;} | |
| } | |
| @-webkit-keyframes ugm_fadeout { | |
| from {bottom: 30px; opacity: 1;} | |
| to {bottom: 0; opacity: 0;} | |
| } | |
| @keyframes ugm_fadeout { | |
| from {bottom: 30px; opacity: 1;} | |
| to {bottom: 0; opacity: 0;} | |
| } | |
| @-webkit-keyframes ugm_stayout { | |
| from {opacity: 0;} | |
| to {opacity: 0;} | |
| } | |
| @keyframes ugm_stayout { | |
| from {opacity: 0;} | |
| to {opacity: 0;} | |
| } | |
| `); | |
| } | |
| function _showSnackbar(text) { | |
| 'use strict'; | |
| let x = document.createElement("div"); | |
| x.innerHTML = text; | |
| x.setAttribute("id", "ugm_snackbar"); | |
| document.body.appendChild(x); | |
| // let initialDelay = 1000; | |
| let initialDelay = 1000; | |
| setTimeout(() => { | |
| x.className = "show"; | |
| console.log("1"); | |
| setTimeout(() => { | |
| console.log("2"); | |
| x.className = x.className.replace("show", ""); | |
| console.log("no show"); | |
| }, 3000); | |
| }, | |
| initialDelay); | |
| setTimeout(() => { document.body.removeChild(x); }, initialDelay + 5000); | |
| } | |
| function _handlePreviewPage() { | |
| if (!GM_config.get("showPreviewPageSnackbar")) { | |
| return; | |
| } | |
| window.addEventListener('load', function() { | |
| 'use strict'; | |
| _addSnackbarStyles(); | |
| let referrer = document.referrer; | |
| console.log(logSig, "Referrer: \"" + referrer + "\""); | |
| if (referrer.search(RegExp("https://docs.google.com/document/d/.*/edit.*")) >= 0) { | |
| console.log(logSig, "Doc preview page was referred by edit page"); | |
| _showSnackbar("Redirected from Google Doc editor (tampermonkey)"); | |
| } | |
| }, false); | |
| } | |
| // *************************************************** | |
| // Redirection functions | |
| // *************************************************** | |
| function _isRefresh() { | |
| 'use strict'; | |
| if (window.performance) { | |
| // performance is supported | |
| let navEntries = window.performance.getEntriesByType("navigation"); | |
| if (navEntries.length == 0) { | |
| console.log(logSig, "Found no performance nagivation entries"); | |
| return false; | |
| } | |
| let navType = navEntries[0].type; | |
| console.log(logSig, "navigation type: " + navType); | |
| return navType == "reload"; | |
| } | |
| console.log(logSig, "window.performance not supported"); | |
| return false; | |
| } | |
| // *************************************************** | |
| // Script entry point | |
| // *************************************************** | |
| (function() { | |
| 'use strict'; | |
| _gmConfigInit(); | |
| GM_registerMenuCommand('Settings', () => { | |
| console.log(logSig, "Open settings"); | |
| GM_config.open(); | |
| }); | |
| if (window.location.href.match("https://docs.google.com/document/d/.*/preview")) { | |
| _handlePreviewPage(); | |
| return; | |
| } | |
| let referrer = document.referrer; | |
| console.log(logSig, "Referrer: \"" + referrer + "\""); | |
| if (_isRefresh()) { | |
| // Do not apply on refresh. This would most likely just be annoying. | |
| return; | |
| } | |
| let noPrompt = false; | |
| for (let pattern of _getAlwaysRedirectFromList()) { | |
| if (referrer.search(pattern) >= 0) { | |
| console.log(logSig, "Auto-previewing (matched " + pattern + ")"); | |
| noPrompt = true; | |
| break; | |
| } | |
| } | |
| for (let pattern of _getNeverRedirectFromList()) { | |
| if (referrer.search(pattern) >= 0) { | |
| console.log(logSig, "Not previewing (matched " + pattern + ")"); | |
| return; | |
| } | |
| } | |
| if (noPrompt || | |
| window.confirm("Preview Google Docs (Tampermonkey):\n\nOpen Google Doc in preview mode?")) { | |
| var url = window.location.href; | |
| var previewUrl = url.replace(RegExp("(.*/)edit(.*)"), "$1preview$2"); | |
| window.location.replace(previewUrl); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment