opera:hige このページをアンテナに追加

2011-06-09

[][] Google 検索を Android デフォルトブラウザ と限りなく同じ表示にします 04:08  Google 検索を Android デフォルトブラウザ と限りなく同じ表示にします - opera:hige を含むブックマーク はてなブックマーク -  Google 検索を Android デフォルトブラウザ と限りなく同じ表示にします - opera:hige

デフォルトの状態で Google 検索にアクセスすると


f:id:higeorange:20110609031803p:image


のようなスマートフォン向けでない携帯表示になる.もちろん PC と同じ表示にもできるのだがそれでは読みにくい.

まずこのような表示になるのはユーザエージェントが Android として認識されていないためである.

opera:config の User Prefs > Custom User-Agent に

Mozilla/5.0 (Linux; U; Android 2.3.2; ja-jp; SonyEricssonSO-01C Build/3.0.D.2.79) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1

を,指定.これは Xperia arc のデフォルトブラウザのユーザエージェントなのだけど,他の機種のものでも多分大丈夫.

これでアクセスすると

f:id:higeorange:20110609032133p:image

おっ,近づいた.でも何かおかしい.

検索入力欄が横に伸びている.これでは入力した後検索ボタンを押すのにスクロールしなくてはならない.

何より醜い.

これをどうにかする.

Opera Dragonfly のリモートデバッグの出番.

body 要素の Computed Style を見てみると width: 850px と出ている.なんぞコレ.

これは Dev.Opera ? Not Found によると

ふつうの Web ページを幅 850px の表示領域 (viewport) で描画します。

ということらしい.

さらに

読み込むページが幅 850px よりも大きい場合、たとえば図1で示した www.nytimes.com のようなページの場合、Opera Mobile はひとつ処理を追加します。幅 850px では収まらない部分が出てしまわないように、さらにズームアウトするのです。こうして、画面領域にうまく収まるように縮小が行われます。

ということは縮小されてうまく表示されそうなものなんだけど,Google 検索のソースを見ると

<meta name="viewport" content="minimum-scale=1.0">

これは,ズームを制御する記述で最低のズーム倍率が1倍.つまり縮小できない.これで検索欄がはみ出して表示されるといううわけである.


さてどうするか.

結論を言うと

<meta name="viewport" content="width=device-width">

を追加してやればいい.これは画面幅を端末の表示幅ぴったりにしてくれるという優れもの.

ここで UserJS の登場.CSSで記述する方法もあるみたいだがうまくいかないっぽいので UserJSで.

// ==UserScript==
// @include http://www.google.com/*
// ==/UserScript==

var head = document.getElementsByTagName("head")[0];
var meta = document.createElement("meta");
	meta.setAttribute("name", "viewport");
	meta.setAttribute("content", "width=device-width");
	head.appendChild(meta);

これを適当なディレクトリに hogefuga.user.js としておいて,そのディレクトリを opera:config の User Prefs > User JavaScriptFile に指定.

これで綺麗な Google 検索がわが手に.


f:id:higeorange:20110609035308p:image


Android デフォルトブラウザと同じ表示なったよ!!

これで Opera mobile の嫌いなところがひとつ減ったね!!

検証環境

Sony Ericcson Xperia arc

Android 2.3.2

Opera mobile 11.00 build: ANDR-1105231029

参考

トラックバック - http://orera.g.hatena.ne.jp/higeorange/20110609

2011-01-20

[][] tweet ボタンにタブキーでフォーカスがあたらない 01:06  tweet ボタンにタブキーでフォーカスがあたらない - opera:hige を含むブックマーク はてなブックマーク -  tweet ボタンにタブキーでフォーカスがあたらない - opera:hige

なぜフォーカスされないかというと a 要素でかかれているから。Opera はタブでフォーム要素*1のみをフォーカスしてくれる*2。それがあだとなったかたち。

それならばと button 要素で囲んでやればいいんじゃないかと思い UserJS を書いた。

// ==UserScript==
// @include http://twitter.com/*
// ==/UserScript==

window.addEventListener('DOMNodeInserted', function c() {
	var tweet_button = document.querySelector('.tweet-button');
	if(tweet_button) {
		window.removeEventListener('DOMNodeInserted', c, false);
		var button = document.createElement('button');
		button.appendChild(tweet_button.cloneNode(true));
		tweet_button.parentNode.replaceChild(button, tweet_button);
	}
}, false);

まず悩んだのが load や DOMContentLoaded のタイミングだと肝心のボタンがなくて動かない。

強引ではあるが、要素が追加されるタイミング(DOMNodeInserted*3 )すべてで実行している。ボタンが追加された時点で DOMNodeInserted をとめて a 要素を button 要素で囲むことにした。

結果、動かない。button 要素で囲んでいるにー。


次、先ほども書いたように通常だとフォーム要素以外はタブキーでフォーカスしないわけだが、tabindex 属性をつけてやるとフォーム要素以外でもフォーカスするようになる。書いてみた。

// ==UserScript==
// @include http://twitter.com/*
// ==/UserScript==

window.addEventListener('DOMNodeInserted', function c() {
	var tweet_button = document.querySelector('.tweet-button');
	if(tweet_button) {
		window.removeEventListener('DOMNodeInserted', c, false);
		tweet_button.setAttribute('tabindex', '1'); // 数字が微妙

	}
}, false);

またしても動かない。tabindex 属性ついてるのにー。


結果

わからん。

解決?

書いた。

// ==UserScript==
// @include http://twitter.com/*
// ==/UserScript==

window.addEventListener('DOMNodeInserted', function c() {
	var textarea = document.querySelector('.twitter-anywhere-tweet-box-editor');
	var tweet_button = document.querySelector('.tweet-button');
	if(tweet_button && textarea) {
		window.removeEventListener('DOMNodeInserted', c, false);
		var textarea_focus = false;
		textarea.addEventListener('focus', function() { textarea_focus = true; }, false);
		textarea.addEventListener('blur', function() { textarea_focus = false; }, false);
		textarea.addEventListener('keyup', function(e) {
			if(e.keyCode == 13 && e.ctrlKey && textarea_focus) {
				e.preventDefault();
				tweet_button.click();
			}
		}, false);
	}
}, false);

動いた。

Replyの時に使う擬似ウィンドウでは動かない。

追記

// ==UserScript==
// @include http://twitter.com/*
// ==/UserScript==

window.addEventListener('DOMNodeInserted', function (e) {
	var f = e.target.firstElementChild;
	if(f && f.className == 'main-content') { 
		addTweetEvent(f.querySelector('.twitter-anywhere-tweet-box-editor'), f.querySelector('.tweet-button'));
	} else if(e.target.className == 'twitter-anywhere-tweet-box-editor') {
		addTweetEvent(e.target, document.querySelector('.twttr-dialog-container').querySelector('.tweet-button'))
	}
	function addTweetEvent(textarea, tweet_button) {
		var textarea_focus = false;
		textarea.addEventListener('focus', function() { textarea_focus = true; }, false);
		textarea.addEventListener('blur', function() { textarea_focus = false; }, false);
		textarea.addEventListener('keyup', function(e) {
			if(e.keyCode == 13 && e.ctrlKey && textarea_focus) {
			e.preventDefault();
				tweet_button.click();
			}
		}, false);
	}
}, false);

リプライダイアログでも動くようにした。 firstElementChild 便利。

firstElementChild などについて

Element Traversal API - 三等兵


OK?

またもや edvakf さんの助言より

// @include http://twitter.com/*
// ==/UserScript==

window.addEventListener('keypress', function(e) {
	if(e.keyCode === 13 && e.ctrlKey && document.activeElement.className === 'twitter-anywhere-tweet-box-editor') {
		var button = document.activeElement.parentNode.parentNode.parentNode.querySelector('.tweet-button');
		button.click();
	}
}, true);
ポイント
  • テキストエリアはイベントが伝播しないので addEventListener の第3引数を true にして window にイベントを渡している。
  • document.activeElement でフォーカスのあたっている要素を取れる*4

*1:input, button textarea etc.

*2Opera のすばらしいところ

*3:初めて知った。便利そう。

*4:知らなかった

トラックバック - http://orera.g.hatena.ne.jp/higeorange/20110120