Restore Revision Time Visual Text in Google Apps

Brings back visual last edit text in drive apps due to M3 migration by Google.

  1. // ==UserScript==
  2. // @name Restore Revision Time Visual Text in Google Apps
  3. // @version 1.3
  4. // @description Brings back visual last edit text in drive apps due to M3 migration by Google.
  5. // @author ZachTheDev and happyviking
  6. // @match https://docs.google.com/document*
  7. // @match https://docs.google.com/presentation*
  8. // @match https://docs.google.com/spreadsheets*
  9. // @icon https://cdn-icons-png.flaticon.com/512/1674/1674929.png
  10. // @namespace gdocsrestoreupdatetimestamp
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. const escapeHTMLPolicy = window.trustedTypes ? trustedTypes?.createPolicy("use-raw-string", {
  15. createHTML: (string) => string,
  16. }) : null;
  17.  
  18. function addBackRevisionVisualText() {
  19. const revisionButtonElement = document.getElementById("docs-revisions-appbarbutton");
  20. var textFromRevisionButtonElement = revisionButtonElement.getAttribute("ariel-label");
  21. const menubarElement = document.getElementById("docs-menubar");
  22. const revisionVisualTextHTML = "<div id=\"revisionVisualText\" class=\"menu-button goog-control goog-inline-block\" role=\"menuitem\" style=\"background-color: transparent;text-decoration: underline;\" data-tooltip=\"Open version history\"></div>";
  23. const rangeForRevisionVisualTextHTML = document.createRange();
  24. const fragmentForRevisionVisualTextHTML = rangeForRevisionVisualTextHTML.createContextualFragment(escapeHTMLPolicy?.createHTML(revisionVisualTextHTML) ?? revisionVisualTextHTML);
  25. menubarElement.appendChild(fragmentForRevisionVisualTextHTML);
  26. const revisionVisualTextElement = document.getElementById("revisionVisualText");
  27.  
  28.  
  29. function callback() {
  30. console.log(revisionButtonElement.dataset.tooltip)
  31. textFromRevisionButtonElement = revisionButtonElement.getAttribute("data-tooltip");
  32. revisionVisualTextElement.innerHTML = escapeHTMLPolicy?.createHTML(textFromRevisionButtonElement) ?? textFromRevisionButtonElement;
  33. }
  34.  
  35. const observer = new MutationObserver(callback);
  36. observer.observe(revisionButtonElement, {
  37. attributeFilter: ["tooltip", "data-tooltip"],
  38. attributeOldValue: true,
  39. });
  40.  
  41. revisionVisualTextElement.addEventListener("mousedown", function (event) {
  42. revisionButtonElement.dispatchEvent(new MouseEvent("mousedown"));
  43. revisionButtonElement.classList.remove("jfk-button-hover");
  44. revisionButtonElement.dispatchEvent(new MouseEvent("mouseup"));
  45. event.stopPropagation(); // fixes bug where menus would open on hover after first click of the revisionVisualTextElement
  46. });
  47.  
  48. revisionButtonElement.addEventListener("mouseenter", (event) => { revisionButtonElement.classList.add("jfk-button-hover"); }, false);
  49. }
  50. addBackRevisionVisualText();
  51. })();