您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Script that visually merges the same event on multiple Google Calendars into one event.
当前为
// ==UserScript== // @name Event Merge for Google Calendar™ (by @imightbeAmy) // @namespace gcal-multical-event-merge // @include https://www.google.com/calendar/* // @include http://www.google.com/calendar/* // @include https://calendar.google.com/* // @include http://calendar.google.com/* // @version 1 // @grant none // @description Script that visually merges the same event on multiple Google Calendars into one event. // ==/UserScript== 'use strict'; console.log("event merge"); const stripesGradient = (colors) => { let gradient = "repeating-linear-gradient( 45deg,"; let pos = 0; colors.forEach(color => { gradient += color + " " + pos + "px,"; pos += 10; gradient += color + " " + pos + "px,"; }); gradient = gradient.slice(0, -1); gradient += ")"; return gradient; }; const dragType = e => parseInt(e.dataset.dragsourceType); const parsePixels = px => parseInt(px.replace('px', '')); const merge = (mainCalender) => { const eventSets = {}; const days = mainCalender.querySelectorAll("[role=\"gridcell\"]"); days.forEach((day, index) => { const events = Array.from(day.querySelectorAll("[role=\"button\"]")); events.forEach(event => { let eventKey = event.querySelector('[aria-hidden="true"]').textContent.replace(/\\s+/g,""); eventKey = index + eventKey; eventSets[eventKey] = eventSets[eventKey] || []; eventSets[eventKey].push(event); }); }); Object.values(eventSets) .forEach(events => { if (events.length > 1) { const colors = events.map(event => event.style.backgroundColor || event.style.borderColor); const gradient = stripesGradient(colors); events.sort((e1, e2) => dragType(e1) - dragType(e2)); const styles = events.map(window.getComputedStyle); const eventToKeep = events.shift(); eventToKeep.style.backgroundImage = gradient; eventToKeep.style.left = Math.min.apply(Math, styles.map(s => parsePixels(s.left))) + 'px'; eventToKeep.style.right = Math.min.apply(Math, styles.map(s => parsePixels(s.right))) + 'px'; eventToKeep.style.visibility = "visible"; eventToKeep.style.width = null; eventToKeep.style.border = "solid 1px #FFF" events.forEach(event => { event.style.visibility = "hidden"; }); } else { events.forEach(event => { event.style.visibility = "visible"; }); } }); } const init = (mutationsList) => { const main = mutationsList && mutationsList .map(mutation => mutation.addedNodes[0] || mutation.target) .filter(node => node.matches && node.matches("[role=\"main\"]"))[0]; if (main) { merge(main); new MutationObserver(() => merge(main)) .observe(main, { childList: true, subtree: true, attributes: true }); } } chrome.runtime.sendMessage({}, response => { if (response.enabled) { const observer = new MutationObserver(init); observer.observe(document.querySelector('body'), { childList: true, subtree: true, attributes: true }); } });