Google Docs Comment Toggler

Toggles comments (useful for word counts)

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name           Google Docs Comment Toggler
// @namespace      www.arthaey.com
// @description    Toggles comments (useful for word counts)
// @include        https://docs.google.com/Doc?id=*
// @include        https://docs.google.com/Doc?docid=*
//
// Backed up from http://userscripts.org/scripts/review/36719
// Last updated on 2009-08-17
// @version 0.0.1.20140612212413
// ==/UserScript==

window.addEventListener("load", function() {

    // variables that are determined by Google (and thus may need to be updated)
    var EDITOR_FRAME_ID = "wys_frame";
        var toolbar = document.getElementById("editor-toolbar");
        var wordCountMenuItem = document.getElementById("m-wcount");

    var BUTTON_CSS = "goog-toolbar-toggle-button goog-toolbar-button goog-inline-block";
    var BUTTON_OUTER_CSS = "goog-toolbar-button-outer-box goog-inline-block";
    var BUTTON_INNER_CSS = "goog-toolbar-button-inner-box goog-inline-block";

    var BUTTON_SEPARATOR_HTML = "<div id=':t' class='goog-toolbar-separator goog-inline-block' style='-moz-user-select: none;' role='separator'> </div>";

    var MENU_ITEM_CSS = "writely-menubar-item goog-menuitem";
    var MENU_CONTENT_CSS = "goog-menuitem-content";

    var COMMENTS_ONLY_XPATH = "//span[@class='writely-comment']";
    var COMMENTS_H3_XPATH   = "//span[@class='writely-comment'] | //h3 | //h4 | //h5";
    var COMMENTS_H2_XPATH   = "//span[@class='writely-comment'] | //h2 | //h3 | //h4 | //h5";

    // save references to toolbar buttons and menu items that will be created
    var BUTTONS = [];
    var MENU_ITEMS = [];

    function toggleComments(xpath, triggerElement) {
        var editorFrame = document.getElementById(EDITOR_FRAME_ID);
        if (!editorFrame)
            return;

        var editorDocument = editorFrame.contentDocument;
        if (!editorDocument)
            return;

        var comments = editorDocument.evaluate(
            xpath,
            editorDocument,
            null,
            XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
            null
        );

        var hidden = false;
        for (var i = 0; i < comments.snapshotLength; i++) {
            var comment = comments.snapshotItem(i);

            if (comment.innerHTML) {
                if (!comment.title) // never clobber a non-empty title!
                    comment.title = comment.innerHTML;
                comment.innerHTML = '';
                comment.style.display = "none";
                hidden = true;
            }
            else {
                comment.innerHTML = comment.title;
                comment.title = '';
                comment.style.display = "";
            }
        }

        // rename toolbar buttons
        var button;
        for (var i = 0; i < BUTTONS.length; i++ ) {
            button = BUTTONS[i];
            if (hidden) {
                button.textContent = button.textContent.replace(/Hide/, "Show");
            }
            else {
                button.textContent = button.textContent.replace(/Show/, "Hide");
            }
            button.title = button.textContent;
        }

        // rename menu items
        var menuItem;
        for (var i = 0; i < MENU_ITEMS.length; i++ ) {
            menuItem = MENU_ITEMS[i];
            if (hidden) {
                menuItem.textContent = menuItem.textContent.replace(/Hide/, "Show");
            }
            else {
                menuItem.textContent = menuItem.textContent.replace(/Show/, "Hide");
            }
        }

        // toggle font weight of element
        var fontWeight = triggerElement.style.fontWeight;
        triggerElement.style.fontWeight = (fontWeight == "bold" ? "normal" : "bold");
    }

    function insertAfter(anchorNode, newNode) {
        if (!anchorNode || !newNode) return;
        anchorNode.parentNode.insertBefore(newNode, anchorNode.nextSibling);
    }

    function addGoogleDocsToolbarButtons() {
        var toolbar = document.getElementById("editor-toolbar");
        if (!toolbar) return;

        var button   = createGoogleDocsToolbarButton("Hide Comments", "toggleComments", COMMENTS_ONLY_XPATH);
        var buttonH3 = createGoogleDocsToolbarButton("+H3", "toggleCommentsH3", COMMENTS_H3_XPATH);
        var buttonH2 = createGoogleDocsToolbarButton("+H2", "toggleCommentsH2", COMMENTS_H2_XPATH);

        insertAfter(toolbar.lastChild, button);
        insertAfter(toolbar.lastChild, buttonH3);
        insertAfter(toolbar.lastChild, buttonH2);
    }

    function addGoogleDocsMenuItems() {
        var wordCountMenuItem = document.getElementById("m-wcount");
        if (!wordCountMenuItem) return;

        var menuItem =   createGoogleDocsMenuItem("Hide Comments", "m-togglecomments", COMMENTS_ONLY_XPATH);
        var menuItemH3 = createGoogleDocsMenuItem("Hide Comments + H3", "m-togglecomments-h3", COMMENTS_H3_XPATH);
        var menuItemH2 = createGoogleDocsMenuItem("Hide Comments + H2", "m-togglecomments-h2", COMMENTS_H2_XPATH);

        MENU_ITEMS = [ menuItem, menuItemH3, menuItemH2 ];

        insertAfter(wordCountMenuItem, menuItemH2);
        insertAfter(wordCountMenuItem, menuItemH3);
        insertAfter(wordCountMenuItem, menuItem);
    }

    function createGoogleDocsToolbarButton(text, id, xpath) {
        // create all these elements DOM-wise because...
        var buttonDiv = document.createElement("div");

        buttonDiv.id = id;
        buttonDiv.title = text;
        buttonDiv.className = BUTTON_CSS;

        // attributes specific to Google Docs
        buttonDiv["aria-disabled"] = false;
        buttonDiv.role = "button";

        var outerBox = document.createElement("div");
        outerBox.className = BUTTON_OUTER_CSS;

        var innerBox = document.createElement("div");
        innerBox.className = BUTTON_INNER_CSS;

        // ...we need to call addEventListener on the innermost div element
        var toggleButton = document.createElement("div");
        toggleButton.textContent = text;
        toggleButton.addEventListener("click", function() { toggleComments(xpath, toggleButton) }, true);

        // add a separator to the end of the toolbar
        toolbar.innerHTML += BUTTON_SEPARATOR_HTML;

        // compose and add the "Toggle Comments" button
        innerBox.appendChild(toggleButton);
        outerBox.appendChild(innerBox);
        buttonDiv.appendChild(outerBox);

        BUTTONS.push(toggleButton);
        return buttonDiv;
    }

    function createGoogleDocsMenuItem(text, id, xpath) {
        var toggleMenuItem = document.createElement("div");

        toggleMenuItem.id = id;
        toggleMenuItem.className = MENU_ITEM_CSS;

        var toggleContent = document.createElement("div");
        toggleContent.className = MENU_CONTENT_CSS;

        toggleContent.appendChild(document.createTextNode(text));
        toggleMenuItem.appendChild(toggleContent);

        // attributes specific to Google Docs
        toggleMenuItem.role = "menuitem";
        toggleMenuItem["aria-pressed"] = "false";

        toggleMenuItem.addEventListener("click", function() { toggleComments(xpath, toggleContent) }, true);

        MENU_ITEMS.push(toggleContent);
        return toggleMenuItem;
    }

    function init() {
        addGoogleDocsToolbarButtons();
        addGoogleDocsMenuItems();
    }

    init();

}, true);