素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: twitter: @javascripter にどうぞ。

FirefoxでのJavaScriptデバッグテク等

obj.watch("prop", function (id, older, newer) {
  console.log(id, older, newer, arguments.callee.caller);
  return newer;
});

obj.propに値を代入してる関数を調べるテクニックの紹介。
下のスクリプトはFC2Blogではてな記法を使えるようにする(デバッグ前の動かない)スクリプトで、text-hatena.jsについては長いからここに載せるときに削った。

// ==UserScript==
// @name FC2 Hatenation
// @namespace http://oksoftware.blog52.fc2.com/
// @description Use Hatena syntax in FC2 Blog
// @include http://blog*.fc2.com/*
// ==/UserScript==

/* Following codes are based text-hatena.js version 0.5 */
// 省略
/* text-hatena.js end */

/* from here on original code */

window.attachEvent("onload",
	function() {
		var input_elem = document.getElementByTagName("input");

		for(var i = 0; i < input_elem.length; i++){
			if(input_elem.getAttribute("onClick").match(/^postEntry/)){
				input_elem.onclick = function(){
					var textarea_elem = document.getElementById("body");
					var src = textarea_elem.value.replace(/^.*<!-- FC2 HATENATION (.*) END FC2 HATENATION -->.*$/, "$2");

					var hatena = new Hatena({sectionanchor : "「」"});
					hantena.parse(String._unescapeHTML(src));

					textarea_elem.value = hatena.html();

					postEntry();
					return false;
				};
			}
		}
	});
[10/01/31 0:45:04] oksoftware: http://files.oksoftware.info/fc2_hatenation.user.js
[10/01/31 0:45:06] oksoftware: こいつ
[10/01/31 0:45:15] oksoftware: 799行目に}がないとか
[10/01/31 0:45:17] oksoftware: 怒られるんですけど
[10/01/31 0:45:24] oksoftware: さっぱり何がわるいんだかわかなくて
[10/01/31 0:45:32] oksoftware: 多分僕がJSの文法を理解していないのが原因なので
[10/01/31 0:45:33] つっくん(javascripter): Firefox用?
[10/01/31 0:45:34] oksoftware: 添削してください
[10/01/31 0:45:48] oksoftware: OperaでもFirefoxでも動くのを目指してる、さしたる機能は使ってない
[10/01/31 0:46:41] つっくん(javascripter): syntax errorはたぶんない
[10/01/31 0:46:55] oksoftware: まじかよ
[10/01/31 0:47:04] oksoftware: Opera Syntax Error吐きやがる・・・
[10/01/31 0:47:11] つっくん(javascripter): Safariのconsoleで評価したら平気だったし
[10/01/31 0:47:13] oksoftware: Firefoxでは動かない
[10/01/31 0:47:20] oksoftware: うーーーーん
[10/01/31 0:47:44] つっくん(javascripter): ちょいまち
[10/01/31 0:47:47] oksoftware: はい
[10/01/31 0:48:31] つっくん(javascripter): Firebugで
[10/01/31 0:48:39] つっくん(javascripter): warningsを含めてエラーを表示するようにして
[10/01/31 0:48:47] つっくん(javascripter): about:configとかでjavascript.strict?的なやつを
[10/01/31 0:48:55] つっくん(javascripter): オンにする
[10/01/31 0:50:09] oksoftware: はい・・・
[10/01/31 0:53:53] つっくん(javascripter): まず最初に言えるのは
[10/01/31 0:53:58] oksoftware: はい
[10/01/31 0:53:59] つっくん(javascripter): postEntry()はFirefoxでは動かないな
[10/01/31 0:54:17] つっくん(javascripter): postEntry()を
location.href = "javascript:void postEntry()";
[10/01/31 0:54:20] つっくん(javascripter): とかにかえましょう
[10/01/31 0:54:24] oksoftware: はい
[10/01/31 0:55:08] つっくん(javascripter): それから
[10/01/31 0:55:11] つっくん(javascripter): input_elemだけど
[10/01/31 0:55:14] つっくん(javascripter): あれはNodeListであって
[10/01/31 0:55:18] つっくん(javascripter): input_elem[i]とかしないと
[10/01/31 0:55:26] つっくん(javascripter): .onclickのとこ
[10/01/31 0:55:32] つっくん(javascripter): getattributeとかも
[10/01/31 0:55:35] oksoftware: 酷いミスだ
[10/01/31 0:55:38] oksoftware: 添削ありがてえ
[10/01/31 0:56:29] つっくん(javascripter): あと"$2"って
[10/01/31 0:56:33] つっくん(javascripter): $1じゃね?
[10/01/31 0:56:57] つっくん(javascripter): ちげえかな.*にかっこつけわすれてるのかこれは
[10/01/31 0:57:29] つっくん(javascripter): んであとは
[10/01/31 0:57:34] つっくん(javascripter): 文字コードをUTF-8にしてるかどうか
[10/01/31 0:57:44] つっくん(javascripter): 「」を直接埋め込んでるから
[10/01/31 0:57:46] oksoftware: FC2にあわせてeuc-jpにしてる
[10/01/31 0:58:35] rosylilly: Operaとかってuser.jsをUTF-8前提で読み込んでなかったかしら
[10/01/31 0:59:14] つっくん(javascripter): それからあとは
[10/01/31 0:59:22] つっくん(javascripter): userscriptが読み込まれるタイミングはDOM構築後なので
[10/01/31 0:59:30] つっくん(javascripter): たぶんattachEventいらないんじゃねえかっていうのと
[10/01/31 0:59:48] つっくん(javascripter): どうだろfc2見てねえから実際のとこわかんねえけど
[10/01/31 1:00:05] oksoftware: ああっOperaでtokenize error出るのはそれだな>UTF-8
[10/01/31 1:00:22] oksoftware: そんな気がする
[10/01/31 1:09:03] つっくん(javascripter): んでonclickはFirefoxでうごかない
[10/01/31 1:09:24] つっくん(javascripter): textarea_elemが
[10/01/31 1:09:54] つっくん(javascripter): onclick毎に取得する必要があるのかも微妙で
[10/01/31 1:10:21] oksoftware: このボタンは保存ボタンでしてね・・・
[10/01/31 1:10:29] oksoftware: 1ページに3つ保存ボタンがございますんよ
[10/01/31 1:12:56] つっくん(javascripter): まあナウい感じにすると
[10/01/31 1:12:57] つっくん(javascripter): var textarea = document.getElementById("body");
[].forEach.call(document.querySelectorAll('input[onclick*="postEntry"]'), function (input) {
  input.addEventListener("click", function (e) {
    var src = textarea.value.replace(/^.*<!-- FC2 HATENATION (.*) END FC2 HATENATION -->(.*$)/, "$2");
    var h = new Hatena({sectionanchor: "「」"});
    h.parse(String._unescapeHTML(src));
    textarea.value = h.html();
    location.href = "javascript:void postEntry()";
    e.preventDefault();
  }, false);
});
[10/01/31 1:13:05] つっくん(javascripter): たぶんこんなかんじだとおもいますけど
[10/01/31 1:13:13] つっくん(javascripter): ナウさは必要ないですねまずはsyntax errorだ
[10/01/31 1:13:25] oksoftware: ナウい
[10/01/31 1:13:35] oksoftware: クロージャ使っただけでナウ気分になってた俺とは大違いだ
[10/01/31 1:13:44] oksoftware: てか
[10/01/31 1:13:53] つっくん(javascripter): attachEventとかFirefoxにはありませんし
[10/01/31 1:14:11] つっくん(javascripter): onclickに代入するのはグリモンがSandbox化されたコンテキストで実行されてるせいでうまくいかなくて
[10/01/31 1:14:20] つっくん(javascripter): addEventListenerを使いましょう
[10/01/31 1:14:37] oksoftware: ところで
[10/01/31 1:14:39] つっくん(javascripter): はい
[10/01/31 1:14:50] oksoftware: GetElementsByTagNameã‚’
GetElementByTagNameと
[10/01/31 1:14:52] oksoftware: 書いていた事で
[10/01/31 1:14:56] oksoftware: うごいていなかったという事に
[10/01/31 1:14:57] oksoftware: きづいた
[10/01/31 1:15:10] つっくん(javascripter): あれ}がどうとかは
[10/01/31 1:15:12] つっくん(javascripter): どうなったの
[10/01/31 1:15:15] oksoftware: ありゃこれミスだらけだ醜い
[10/01/31 1:15:19] oksoftware: いや、まだ動くに至ってない
[10/01/31 1:15:19] oksoftware: ミスの山
[10/01/31 1:15:29] oksoftware: なんで俺こんな短かいコードでこんなにミス作ってんだ
[10/01/31 1:15:33] oksoftware: 寝ながら書いたんじゃないのか
[10/01/31 1:15:36] oksoftware: まあ寝ながら書いたんですけどね
[10/01/31 1:15:45] つっくん(javascripter): なんか致命的に間違っててほとんど動かない感じで笑えますね
[10/01/31 1:16:03] oksoftware: ここまで動かんコード書いたのも初めてやで
[10/01/31 1:18:20] oksoftware: i = 0の脇にvarとか書いたせいで
[10/01/31 1:18:26] oksoftware: ループすら1回しか走ってない
[10/01/31 1:18:30] oksoftware: なんだこのミスの山
[10/01/31 1:18:31] oksoftware: すごい
[10/01/31 1:18:36] oksoftware: ある意味で天才が書いたとしか
[10/01/31 1:18:38] oksoftware: 思えない
[10/01/31 1:20:10] oksoftware: あれ、そうではないのか
[10/01/31 1:20:13] oksoftware: あっれーーーー
[10/01/31 1:20:38] つっくん(javascripter): 出てるエラーそのままコピペして
[10/01/31 1:26:44] oksoftware: Component is not availableってなんぞ
[10/01/31 1:26:51] つっくん(javascripter): Firefox?
[10/01/31 1:26:55] oksoftware: いぇす
[10/01/31 1:27:04] つっくん(javascripter): まずただのalertとかだけのコードを書いて
[10/01/31 1:27:06] つっくん(javascripter): 動くか確認
[10/01/31 1:27:12] oksoftware: それは動く
[10/01/31 1:27:36] つっくん(javascripter): 発生源はどこ
[10/01/31 1:27:44] つっくん(javascripter): nsSessionStore.jsとかだったら
[10/01/31 1:27:47] つっくん(javascripter): 別にきにせんでもよい
[10/01/31 1:27:48] oksoftware: ああ、そういう事が
[10/01/31 1:27:52] oksoftware: addEventListenerを使いましょうって
[10/01/31 1:27:58] oksoftware: あーJS苦手だ
[10/01/31 1:28:03] oksoftware: また1つ嫌いな物が増えた
[10/01/31 1:29:25] つっくん(javascripter): 第三引数はattachEventみたくしたかったらfalseでいいんだぞ
[10/01/31 1:30:20] oksoftware: addEventListenerって既存のonclickを殺せたりするの?
[10/01/31 1:30:35] つっくん(javascripter): それはできねえな
[10/01/31 1:30:45] oksoftware: うわあああああ胃が痛い
[10/01/31 1:30:50] つっくん(javascripter): じゃあどうしよっかな
[10/01/31 1:31:20] つっくん(javascripter): removeAttribute("onclick")でおk
[10/01/31 1:31:28] oksoftware: ありがとう!!!!!!!!!
[10/01/31 1:33:43] rosylilly: 素敵な愛
[10/01/31 1:35:17] oksoftware: removeAttributeは"onclick"でaddEventListenerはclick?
[10/01/31 1:35:24] つっくん(javascripter): y
[10/01/31 1:54:12] oksoftware: あああああ
[10/01/31 1:54:14] oksoftware: FC2ウザい
[10/01/31 1:54:35] oksoftware: スクリプトが奇怪に入り組んでいて
[10/01/31 1:54:42] oksoftware: 流れが追えない
[10/01/31 1:54:55] oksoftware: なんかtextareaのvalue書き換えると
[10/01/31 1:54:56] oksoftware: 戻される
[10/01/31 1:54:57] oksoftware: なんだこれ
[10/01/31 1:55:12] rosylilly: firebugでstep実行でもしたら?
[10/01/31 1:55:31] つっくん(javascripter): 何らかのタイミングでsetintervalでtextarea.valueに代入してる可能性がある
[10/01/31 1:56:21] oksoftware: setIntervalでgrepしても出てはこなかったから
[10/01/31 1:56:27] oksoftware: イベントかなぁ
[10/01/31 1:57:02] つっくん(javascripter): FirefoxのFirebugとかで
textarea.watch("value", function (id, older, newer) {
  console.log(id, older, newer, arguments.callee.caller);
  return newer;
});
[10/01/31 1:58:30] つっくん(javascripter): んでfirebugで上のを実行して
[10/01/31 1:58:43] つっくん(javascripter): textareano
[10/01/31 1:58:47] つっくん(javascripter): valueを書き換えたりして
[10/01/31 1:58:59] oksoftware: みつかったーーーーーっ
[10/01/31 1:59:02] oksoftware: つっくん神だマジ
[10/01/31 2:00:42] oksoftware:  function updateField() {
381 area.value = mirror.getCode();
382 }
[10/01/31 2:02:04] oksoftware: このイベントを
[10/01/31 2:02:11] oksoftware: 直前に殺してから書けばいいのかな
[10/01/31 2:02:18] oksoftware: もうこの後には送信しかないから殺しても実害ないし
[10/01/31 2:02:41] つっくん(javascripter): にするかあるいは送信formを自作かxmlhttprequestで直接送るとか
[10/01/31 2:03:00] つっくん(javascripter): それからmirror.getCodeを書き換えるか
[10/01/31 2:04:11] oksoftware: 書き換えるのがてっとりばやいな
[10/01/31 2:04:24] つっくん(javascripter): この場合もFirefoxでうごかすために
[10/01/31 2:04:43] つっくん(javascripter): location.href="javascript:void(mirror.getCode=function(){hoge})"
[10/01/31 2:04:46] つっくん(javascripter): とかしなきゃいけなくて
[10/01/31 2:04:56] つっくん(javascripter): それからmirrorは外部からアクセスできる感じですか
[10/01/31 2:05:11] oksoftware: あーーーーー
[10/01/31 2:05:55] つっくん(javascripter): まあupdateFieldを殺すのが手っ取り早い
[10/01/31 2:06:06] oksoftware: http://marijn.haverbeke.nl/codemirror/
[10/01/31 2:06:10] oksoftware: これだった
[10/01/31 2:06:12] oksoftware: mirrorって
[10/01/31 2:07:06] oksoftware: ライブラリって事は
[10/01/31 2:07:12] oksoftware: 止める関数とかが用意されている可能性
[10/01/31 2:07:48] つっくん(javascripter): mirrorに
[10/01/31 2:07:52] oksoftware: setCode(string)
[10/01/31 2:07:52] oksoftware: あったーっ