您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show do not disturb button on main Google Voice page
- // ==UserScript==
- // @name GVoice DND
- // @namespace http://boris.joff3.com
- // @version 1.0
- // @description Show do not disturb button on main Google Voice page
- // @match https://*.google.com/voice*
- // @copyright 2012, 2013, 2015 Boris Joffe
- // @grant GM_xmlhttpRequest
- // ==/UserScript==
- /*
- Copyright (C) 2012, 2013, 2015 Boris Joffe
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- // Global Strings
- const ENABLE_DND = "Enable DND";
- const TOGGLE_TO_ENABLED = "Success! - Enabled Do Not Disturb";
- // Global URLs
- //const ENABLE_DND_URL = 'https://www.google.com/voice/settings/editGeneralSettings/';
- const ENABLE_DND_URL = 'https://www.google.com/voice/b/0/service/post'; // new URL
- // Search and Regexp strings
- //const FIND_IF_DND_DISABLED_1 = '<span id="gc-dnd-static" style="display: none;">"Do Not Disturb" is enabled.'; // For DND with no end
- //const FIND_IF_DND_DISABLED_2 = '<span id="gc-dnd-until" style="display: none;">"Do Not Disturb" is enabled'; // For DND until
- // Other Global const
- const TOGGLE_TIMEOUT = 300;
- const DEFAULT_DND_MINUTES = 20;
- const OPACITY_PERCENT = 0.65;
- // Colors
- //const FATALERR_COLOR = '#f00';
- const ERR_COLOR = '#f31';
- const WARN_COLOR = '#ffaa00';
- const INFO_COLOR = '#999';
- const BUTTON_BG_COLOR = '#f0f0ff';
- // Globar DOM vars
- var dndDiv;
- var debugDiv;
- var dndEnable, dndExp;
- // URL Params
- var _rnr_se;
- // Global boolean vars
- var DBG = false;
- var ERR_VAL = -1;
- window.addEventListener('load',
- function() {
- main();
- function main() {
- if (DBG) addDebugPane();
- // Initialization
- //dbgInfol(document.getElementsByName('_rnr_se')[0].value);
- _rnr_se = name0('_rnr_se').value;
- dbgInfol('_rnr_se: ' + _rnr_se);
- makeDNDdiv(isDNDenabled());
- document.body.appendChild(dndDiv);
- if (DBG && debugDiv != null) document.body.appendChild(debugDiv);
- }
- // Return true if DND is enabled; otherwise return false
- // TODO - fix console error below as a result of elIDstyle
- // Error: uncaught exception: [Exception... "Operation is not supported" code: "9" nsresult: "0x80530009 (NS_ERROR_DOM_NOT_SUPPORTED_ERR)" location: "resource://greasemonkey/runScript.js Line: 118"]
- function isDNDenabled() {
- const FIND_STATIC_DND = 'gc-dnd-display';
- var s = elIDstyle(FIND_STATIC_DND);
- if (s == null || s == ERR_VAL) {
- dbgErrl('isDNDenabled/elIDstyle - s is: ' + s);
- return ERR_VAL;
- }
- s = s.display;
- if (s == ERR_VAL) {
- dbgErrl('isDNDenabled/elIDstyle returned err');
- return ERR_VAL;
- }
- //dbgInfol('display: ' + s);
- return s.indexOf('none') != -1;
- }
- // Create DND Div
- function makeDNDdiv(isEnabled) {
- if (DBG && isEnabled) dbgInfol("dnd enabled but making div anyway");
- dndDiv = document.createElement('div');
- dndDiv.id = "dndDiv";
- dndDiv.style.position = 'fixed';
- dndDiv.style.top = "23%";
- dndDiv.style.right = "10%";
- //dndDiv.style.border = "1px solid blue";
- dndDiv.style.padding = "7px";
- dndDiv.style.backgroundColor = "#002"; //"#f0f0ff";
- dndDiv.style.opacity = OPACITY_PERCENT;
- dndDiv.style.zIndex="100"; // put it in front of other elements
- dndDiv.style.minWidth = "200px";
- dndEnable = document.createElement('button');
- dndEnable.style.padding = '1px';
- dndEnable.style.border = '1px solid blue';
- dndEnable.style.margin = '5px';
- dndEnable.style.backgroundColor = BUTTON_BG_COLOR;
- dndEnable.textContent = ENABLE_DND;
- // Expiration Time Field - in unixtime
- dndExp = document.createElement('input');
- dndExp.id = "dndExp";
- dndExp.type = "text";
- dndExp.size = 13;
- dndExp.style.display = "none";
- //dndExp.style.visible = "none";
- if (DBG) dndExp.style.display = "inline";
- // How long to set DND for
- var dndExpDate = document.createElement('input');
- dndExpDate.id = "dndExpDate";
- dndExpDate.type = "text";
- dndExpDate.size = 4;
- //var expValue = new Date( dndExp.value );
- dndExpDate.value = DEFAULT_DND_MINUTES;
- // Units of time to set DND for
- var dndExpUnit = document.createElement('select');
- dndExpUnit.id = "dndExpUnit";
- var minOpt = document.createElement('option');
- minOpt.value = minOpt.text = 'Min';
- var hrOpt = document.createElement('option');
- hrOpt.value = hrOpt.text = 'Hr';
- dndExpUnit.add(minOpt);
- dndExpUnit.add(hrOpt);
- dndExpUnit.selectedIndex = 0;
- //dndExpUnit.size = 2;
- var dndFutureDate = document.createElement('span');
- dndFutureDate.id = "dndFutureDate";
- dndFutureDate.innerHTML = "";
- dndFutureDate.style.color = "#fc0";
- dndFutureDate.style.fontSize = 8;
- //dndFutureDate.style.margin = "2px";
- //dndFutureDate.style.padding = "2px";
- dndDiv.appendChild(dndExpDate);
- dndDiv.appendChild(dndExpUnit);
- dndDiv.appendChild(dndEnable);
- if (DBG) dndDiv.appendChild( document.createElement('br') );
- dndDiv.appendChild(dndExp);
- dndDiv.appendChild( document.createElement('br') );
- dndDiv.appendChild(dndFutureDate);
- // Create event listener toggle
- dndEnable.addEventListener('click', enableDND, true);
- dndExpDate.addEventListener('change', expChange, true);
- dndExpDate.addEventListener('click', expChange, true);
- dndExpUnit.addEventListener('change', expChange, true);
- // When Do Not Distrub expiration date changes
- // Update seconds
- function expChange() {
- var addMin = 0;
- var addHr = 0;
- var futureDate = new Date();
- if ( dndExpUnit.selectedIndex == 0 ) { // minutes selected
- addMin = dndExpDate.value;
- addMin = addMin * 60 * 1000; // convert to UNIX ms
- futureDate.setTime( futureDate.getTime() + addMin );
- } else if ( dndExpUnit.selectedIndex == 1 ) { // hours selected
- addHr = dndExpDate.value;
- addHr = addHr * 60 * 60 * 1000; // convert to UNIX ms
- futureDate.setTime( futureDate.getTime() + addHr );
- } else {
- dbgErrl('expChange evt: could not get selectedIndex');
- return ERR_VAL;
- }
- dndExp.value = futureDate.getTime(); // update unix time
- dbgInfol('futureDate: ' + futureDate);
- dndFutureDate.innerHTML = futureDate;
- }
- // send AJAX POST request to enable DND for unspecified amt of time
- function enableDND() {
- dbgInfol('enabling');
- var actualReq1, actualReq2;
- //var oldReq = "doNotDisturb=1&_rnr_se=";
- actualReq1 = 'sid=3&mid=5&req=%5Bnull%2C%5Bnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cfalse%2C';
- actualReq2 = '%5D%5D&_rnr_se=';
- expChange();
- var myFullReq = actualReq1 + dndExp.value + actualReq2 + encodeURIComponent(_rnr_se);
- GM_xmlhttpRequest({
- method: "POST",
- url: ENABLE_DND_URL,
- data: myFullReq,
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- },
- onload: function(/*response*/) {
- //dndEnable.innerHTML = TOGGLE_TO_ENABLED;
- dndFutureDate.innerHTML = TOGGLE_TO_ENABLED;
- //dbgInfol( 'Sending request:\n\n' + myFullReq);
- setTimeout(window.location.reload(true), TOGGLE_TIMEOUT); // is this useless like the dev console says??? - gv does a 2nd get request to update the page
- },
- onerror: function(response) {
- if (DBG) alert('Err: \n\n' + response);
- }
- });
- }
- }
- // Helper Functions
- function el(elStr) {
- var x = document.getElementById(elStr); // get el by ID
- if (x == null) {
- dbgErrl("el: no el by id: " + elStr);
- return ERR_VAL;
- } else
- return x;
- }
- /*function elStyle(el) {
- var x = window.getComputedStyle(el, null); // get computed style of el
- if (x == null) {
- dbgErrl('elStyle: no el style for: ' + el);
- return ERR_VAL;
- } else
- return x;
- }*/
- function elIDstyle(elStr) {
- var x = el(elStr);
- if (x==ERR_VAL) {
- dbgErrl('elIDStyle/el - el by ID returned error');
- return ERR_VAL;
- }
- x = window.getComputedStyle( x, null ); // get computed style from el ID str
- //dbgInfol("computed style:\n"+x.content);
- if (x == null) {
- dbgErrl('elIDStyle: could not get el style from elbyId: ' + elStr);
- return ERR_VAL;
- } else
- return x;
- }
- function name0(elStr) {
- var x = document.getElementsByName(elStr); // get first element of a certain name
- if (x == null) {
- dbgErrl("name0: no el by name: " + elStr);
- return ERR_VAL;
- } else if (x[0]==null) {
- dbgErrl('name0: el exists but el[0] doesnt');
- return ERR_VAL;
- } else if (x[0].value==null) {
- dbgWarnl('name0: el[0].value is null');
- return x[0];
- } else
- return x[0];
- }
- // ========== DEBUGGING SECTION =========
- // Adds a fixed div at the top right with debug info
- function addDebugPane() {
- debugDiv = document.createElement('div');
- debugDiv.id = "debugDiv";
- //Some CSS stuff
- debugDiv.style.position = "fixed";
- debugDiv.style.top = "38%";
- debugDiv.style.right = "5%";
- debugDiv.style.padding = "5px";
- debugDiv.style.border = "2px solid red";
- debugDiv.style.backgroundColor = "white";
- //debugDiv.style.minWidth = "20%";
- debugDiv.style.zIndex="100"; // put it in front of other elements
- debugDiv.innerHTML = "<b><u>Debug Info</u></b><br>";
- }
- // Add info to debug div
- function dbgAdd(htmlText) {
- if (DBG && debugDiv != null)
- debugDiv.innerHTML += htmlText;
- else if (DBG) {
- var tmpDiv = document.createElement('div');
- tmpDiv.innerHTML = htmlText;
- alert('DBG info:\n\t' + tmpDiv.textContent + ' \n\n\n(Note: debugDiv is null)');
- }
- }
- function dbgAddl(htmlText) { dbgAdd(htmlText + "<br>"); }
- //function dbgFatal(htmlText) { dbgAdd('<b style="color:' + FATALERR_COLOR + ';">Fatal Err:</b> ' + htmlText);}
- //function dbgFatall(htmlText) { dbgAddl('<b style="color:' + FATALERR_COLOR + ';">Fatal Err:</b> ' + htmlText);}
- //function dbgErr(htmlText) { dbgAdd('<b style="color:' + ERR_COLOR + ';">Err:</b> ' + htmlText); }
- function dbgErrl(htmlText) { dbgAddl('<b style="color:' + ERR_COLOR + ';">Err:</b> ' + htmlText); }
- //function dbgWarn(htmlText) { dbgAdd('<i style="color:' + WARN_COLOR + ';">Warning:</i> ' + htmlText); }
- function dbgWarnl(htmlText) { dbgAddl('<i style="color:' + WARN_COLOR + ';">Warning:</i> ' + htmlText); }
- //function dbgInfo(htmlText) { dbgAdd('<i style="color:' + INFO_COLOR + ';">Info:</i> ' + htmlText); }
- function dbgInfol(htmlText) { dbgAddl('<i style="color:' + INFO_COLOR + ';">Info:</i> ' + htmlText); }
- }, true);