1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#191 Google Chatの自動書式変換を無効化する

1
Posted at

はじめに

Google Chatで最近、Markdown記法を入力すると自動でリッチテキストに変換されるようになりました。

例えば > を入力すると引用ブロック、- を入力すると箇条書きに自動変換されます。

しかしあまり思い描いたようなキレイな見た目にならず、むしろちょっと余計だと感じることが多いです(2026年4月現在)。
設定 > メッセージとメディア からマークダウンを無効化するとプレビューは崩れなくなりますが、結局投稿時に崩れてしまいます。

そこで、Tampermonkeyスクリプトで自動フォーマットを無効化してみました。

自動変換の挙動

Google Chatの入力欄で、特定の文字を入力した瞬間にリッチテキストへ変換されます。

入力 変換結果
> 引用ブロック(blockquote)
- 箇条書き(ul > li)

before_gt.png

before_hyphen.png

作成物

スクリプトを適用すると、入力がプレーンテキストのまま維持されます。

> 入力
after_gt.png

- 入力
after_hyphen.png

使用方法

1. Tampermonkeyをインストール

ChromeウェブストアからTampermonkeyをインストールします。

2. ユーザースクリプトの実行を許可

chrome://extensions を開き、Tampermonkeyの「詳細」→「ユーザースクリプトを許可する」トグルを有効にしてください。

allow_user_scripts.png

3. スクリプトを登録

Tampermonkeyのダッシュボードを開き、「+」(新規スクリプト作成)をクリックします。
以下のコードを貼り付けて保存してください。

// ==UserScript==
// @name         Google Chat Plain Text
// @namespace    https://chat.google.com
// @version      1.0
// @description  Google Chatの自動書式変換(>, - )を無効化する
// @match        https://chat.google.com/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
  'use strict';

  const ZWSP = '\u200B';

  function beforeInputHandler(e) {
    if (e.inputType !== 'insertText') return;
    const editor = e.target.closest?.('[contenteditable="true"]');
    if (!editor) return;

    const data = e.data;
    if (!data) return;

    const sel = window.getSelection();
    if (!sel.rangeCount) return;
    const range = sel.getRangeAt(0);

    let lineText = '';
    const container = range.startContainer;
    if (container.nodeType === 3) { // テキストノードの場合のみ
      lineText = container.textContent.substring(0, range.startOffset);
    }

    // 行頭で > または - が入力された場合
    if (lineText === '' && (data === '>' || data === '-')) {
      e.preventDefault();
      e.stopImmediatePropagation();
      document.execCommand('insertText', false, ZWSP + data);
      return;
    }
  }

  document.addEventListener('beforeinput', beforeInputHandler, true);
})();

4. 動作確認

Google Chatを開き(既に開いている場合はリロード)、>- を入力して変換されなければ成功です。

コード解説

仕組み: ゼロ幅スペースによるパターンマッチ回避

Google Chatの入力欄は contenteditable="true" なdiv要素で、
DevToolsで確認したところ、Googleの独自フレームワーク(jsaction)が input イベント経由で書式変換を行っているようでした。

通常の addEventListener でイベントを stopPropagation() しても変換を阻止できなかったため、
jsactionフレームワークが通常のイベント伝播とは異なるルートで処理していると思われます。

そこで、beforeinput イベントのキャプチャフェーズでトリガー文字を横取りし、
文字の先頭にゼロ幅スペース(U+200B)を付与して挿入するアプローチを取りました。

通常の入力フロー:
  ">" 入力 → GChatが ">" を検知 → blockquoteに変換

スクリプト適用後:
  ">" 入力 → beforeinputで横取り → "\u200B>" を挿入 → GChatのパターンに一致しない → 変換されない

ゼロ幅スペースは画面上に表示されないため、見た目や送信内容に影響はありません。

キャプチャフェーズの利用

addEventListener の第3引数に true を渡すことで、キャプチャフェーズでリスナーを登録しています。
これにより、GChatの内部ハンドラより先にイベントを受け取れます。

トリガー検知

window.getSelection() でカーソル位置を取得し、カーソルより前のテキストが空(=行頭)かどうかを判定します。

let lineText = '';
const container = range.startContainer;
if (container.nodeType === 3) { // テキストノードの場合のみ
  lineText = container.textContent.substring(0, range.startOffset);
}

行頭で > または - が入力された場合のみ、変換阻止の処理が発動します。

まとめ

Google Chatの自動書式変換は、jsactionフレームワーク経由で処理されているようで、通常のイベントハンドリングでは阻止できませんでしたが、
イベントを抑止するアプローチではなくイベントを先回りして書き換えるアプローチで、動作の変更が実現できました。

応用すれば、テキスト選択中にURLをペーストすることでハイパーリンクにするといったスクリプトも作れるかもしれません。

最後まで読んでいただきありがとうございます。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?