Skip to content

jeforth.hta manipulates any web page (有說明影片)

H.C. Chen edited this page Jul 26, 2015 · 3 revisions

上回介紹透過 jeforth.hta 來操作 GitHub ,顯示經由 jeforth.hta + git.f + help command 來操作可以有效駕馭難懂的系統,但它的能力遠不止於此。

影片: 抓 jeforth.3we 整包下來執行 jeforth.hta。

Demo : 清理網頁上的 garbage

請先看 demo 影片 http://www.camdemy.com/media/20197

這段 video 介紹透過 jeforth 來揉捏 IE 網頁的方式,範例中咱把網頁上擾人的廣告、遮擋文章的雜物都清除掉,以便列印或閱讀。jeforth 不只扮演automation 的腳色, 還增加了我們本來想做但是做不到的事情。擴大手動操作的能力,可能比 automation 更實用。

jeforth.3hta 是怎麼做到的

  1. Microsoft Windows 都有提供 IE 的 automation interface。取得 IE object 非常容易。
  2. jeforth.3hta 把手伸進 IE 網頁, jQuery 也跟著過去了!(雖然有 bug 希望是我自己了解不夠。)
  3. 疑問:哪個 IE object is the active web page?

以下用到的 jeforth 命令如 js〉〈js〉 :〉 :: // 等用 help -N 《word》即可取得說明。

取得 IE object 非常容易

請看影片 http://www.camdemy.com/media/20214

Windows 下有 shell.application COM object 用 jeforth.3hta 唾手可得:

<js> push(new ActiveXObject("shell.application"))</js>
constant shell.application // ( -- obj ) COM object

上式執行 JavaScript code 取得 shell.application object 把它 push 進 forth stack 之後依原名命名為 forth constant。而 shell.application 有 windows() method 傳回 ShellWindows 它就是所有的 IE 網頁 window 以及 File Manager window 的一整串粽子的 root object。

下式執行 shell.application object 裡的 windows() mentod 取得 ShellWindows 依原名命名為 forth constant。

shell.application :> windows()
constant ShellWindows // ( -- obj ) 

jeforth.3we 會把所有 constant 跟 value 都放進以單一字母 g 為名的 hash table object 裡. 故 js> g.ShellWindows 就是 ShellWindows, 同理 js> g["shell.application"] 就是 shell.application. 所以不論在 forth 或 JavaScript 都很容易 access 它們。

請用以下這個命令,置換 item(0), item(1), item(2) 一一去查看,找出哪個是你的 IE 網頁。我的例子中 item(1) 是 yahoo 網站,

ShellWindows :> item(1).locationUrl .
https://www.yahoo.com/ OK 

接下來我們馬上把手伸進 IE 裡去, 看到了這個網頁的 source code 並且可讀、可寫。到這裡,透過 jeforth.3hta 您已經可以對任何網頁亂玩了!

ShellWindows :> item(1).document.body.innerHTML .

上式也可以寫成,

js> g.ShellWindows.item(1).document.body.innerHTML .

又或者,

s" g.ShellWindows.item(1).document.body.innerHTML" jsEval .

以及

<js> g.ShellWindows.item(1).document.body.innerHTML</jsV> .

這些都等效。

jeforth.3hta 把手伸進 IE 網頁, jQuery 也跟著過去了!

請看影片 http://www.camdemy.com/media/20215

很高興發現 jeforth.hta 裡 include 的 jQuery 也可以對 ShellWindows 下的 IE 網頁工作。

前面已知某個 n 值所指的 g.ShellWindows.item(n).document 就是某 IE 網頁的 DOM document object. 用 list-ie-windows 命令可列出當前所有的 ShellWindows 看看你要操作哪個網頁。我特別用一個 value theIE 來指定默認的 item(theIE) 以免時時牽掛此值。此後即可把 'document' 這個好名字送給 theIE 所指的網頁,是即我們要對它工作的 IE 網頁。

document js> $('table',pop()).length .

把 jeforth.hta 一跑起來直接就可以執行以上這樣一行查看 theIE 網頁有幾個 table. 而以下這行則會把所有的 〈div〉都加上金框,

document <js> $("div",pop()).css("border","1px solid gold")</js>

因為當中有空格,所以不能用 js: 而得用 〈js〉 ... 〈/js〉。

哪個 IE object is the active web page?

我 Google 了好久, 搞不懂。只好引進 theIE 變數讓 user 自己指定。

程式

Copy-paste 這段程式進 jeforth.hta 梢等一會兒看到回覆 OK 就可以開始對 theIE 網頁操作。Mouse cursor 所經之處的 DOM element/node 都會被打上紅框,同時在 jeforth.3hta outputbox 內顯示該 element/node 的種類。針對紅框 node/element 現有下列 hotkey 命令:


Hotkey Description
(f)reeze Toggle,凍結當前紅框,不再對 hover 反應。
(s)elect 把當前紅框列入選擇。加上 class="selected".
(d)elete 把當前打了紅框的 element/node 刪除掉。
(u)nselect 與 (s)elect 相反,把當前紅框從已選擇項內除名。
(v)iew 顯示所有 class="selected" 者都打上綠框。
(c)lear 清除所有 class="selected" 者,以便重新選擇。
< 在曾被標上紅框的 eleemnt/node 之間遊走。
> 在曾被標上紅框的 eleemnt/node 之間遊走。

\ Hover 打紅框, (f)reeze, (s)elect, (d)elete, (u)nselect, (v)iew, (c)lear
\ 還可以用 [<][>] 前進倒退紅框。
--- marker ---
[] value track // ( -- [node,..] ) The history track array of visited DOM nodes
0 value itrack // ( -- int ) index of the track array
0 value freeze // ( -- boolean ) The freezing flag
document 
<js> 
var doc=pop();
var GoOn=false;
$(doc).keydown(function(e){
	e = (e) ? e : event; var keycode = (e.keyCode) ? e.keyCode : (e.which) ? e.which : false;
	switch(keycode) {
		case 67: /* [c]lear */
			for(var i=0; i<g.track.length; i++){
				$(g.track[i])
				.removeAttr('style')
				.removeClass("selected");
			}
			return(!GoOn); 
		case 68: /* [d]elete the highlighted node */
			push(g.track[g.itrack]);
			execute("removeElement");
			return(!GoOn); 
		case 70: /* [f]reeze */
			g.freeze = !g.freeze;
			print("The freezing flag : " + g.freeze); execute("cr");
			return(!GoOn); 
		case 83: /* [s]elect */
			$(g.track[g.itrack])
			.removeAttr('style')
			.css("border","2px solid lime")
			.addClass("selected");
			return(!GoOn); 
		case 85: /* [u]nselect */
			$(g.track[g.itrack])
			.removeAttr('style')
			.removeClass("selected");
			return(!GoOn); 
		case 86: /* [v]iew selected nodes */
			for(var i=0; i<g.track.length; i++){
				$(g.track[i]).removeAttr('style');
				if($(g.track[i]).hasClass("selected"))
					$(g.track[i]).css("border","2px solid lime");
			}
			return(!GoOn); 
		case 188: /* < , */
			$(g.track[g.itrack]).removeAttr('style'); // 無須防呆
			g.itrack = Math.max(0,g.itrack-1);
			$(g.track[g.itrack]).css("border","4px dashed red");						
			return(!GoOn); 
		case 190: /* > . */
			$(g.track[g.itrack]).removeAttr('style'); // 無須防呆
			g.itrack = Math.min(g.track.length-1,g.itrack+1);
			$(g.track[g.itrack]).css("border","4px dashed red");						
			return(!GoOn); 
	}
	return (!GoOn);
});
$("*",doc).mouseenter(function(){
	print("Enter " + this.nodeName + ". ");
	if (g.freeze) return;
	$(g.track[g.itrack]).removeAttr('style'); // 無須防呆
	if (g.track[g.track.length-1]!=this) g.track.push(this);
	g.itrack = g.track.length-1;
	$(g.track[g.itrack]).css("border","4px dashed red");						
});
$("*",doc).mouseleave(function(){
	print("Leave " + this.nodeName + ". ");
	if (g.freeze) return;
	$(this).removeAttr('style'); // 無須防呆
});
</js>

除了寫成 hotkey 針對 class="selected" 者,從 jeforth.3hta 內可以直接操作:

顯示選中了幾個東西,

document js> $(".selected",pop()).length .

把選中的都轉到 outputbox 來顯示,

document <js> $(".selected",pop()).each(function(){
	push($(this).html());
	execute("</o>");
});
</js>		

刪除所有選中的東西,

document <js> $(".selected",pop()).each(function(){
	push(this);
	execute("removeElement");
});
</js>		

刪除所有【選中以外】的東西,

"" value selected 
document <js> 
var doc=pop();
$(".selected",doc).each(function(){
	g.selected += $(this)[0].outerHTML;
});
doc.body.innerHTML = g.selected;
</js>		

這些程式您用用看能用但是有些小地方還十分粗糙,例如 hover 標上紅框的反應就不太靈敏所以你移動 mouse cursor 要慢慢地來回嘗試。我設計了 '<' '>' 這兩個 hotkey 在曾被標上紅框的 eleemnt/node 之間遊走,略補 mouse cursor 不靈光的小毛病。我就讓它保持粗糙也不加包裝、美化就這麼赤裸裸地 copy-paste 來使用。因為 forth 就是有這種【個人專屬】的工具之味道。隨手開發程式來解決腳邊日常生活的的小問題,實際上就是這樣。

-- 完 --