Event Merge for Google Calendar™ (by @imightbeAmy)

Script that visually merges the same event on multiple Google Calendars into one event.

As of 17.02.2018. See ბოლო ვერსია.

// ==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("div:nth-child(2)").textContent.replace(/\\s+/g,"");
      eventKey = index + eventKey;
      eventSets[eventKey] = eventSets[eventKey] || [];
      eventSets[eventKey].push(event);
    });
  });

  Object.values(eventSets)
    .filter(events => events.length > 1)
    .forEach(events => {
      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;

      events.forEach(event => {
        event.style.visibility = "hidden";
      });
    });
}

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) {
    const mainCalender = main.querySelector("[role=\"grid\"] > [role=\"presentation\"][data-type=\"1\"]");
    if (mainCalender) {
      merge(mainCalender);
      new MutationObserver(() => merge(mainCalender))
        .observe(mainCalender, { 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 });
  }
});
长期地址
遇到问题?请前往 GitHub 提 Issues,或加Q群1031348184

赞助商

Fishcpy

广告

Rainyun

注册一下就行

Rainyun

一年攒够 12 元