Safari CSS

先月スマホを iPhone 5S に乗り換えた。
Safari だと自分の本サイトが滅茶苦茶に表示されると気が付いた。

そろそろ CSS に手をつけないと。
このブログ側は問題ないのでこの CSS を参考に。

まず全体の英字フォントが selif になる。
table 部の折り返しができず縮小表示になる。
pre で文字列が折り返さずトンデモ状態に。
chrome や firefox で問題なかった margin 指定で酷い表示状態に。

特に SyntaxHighlighter は深刻だ。
何がどうなったらこんな酷いことになるんだよと。

IMG_0052

英字フォントは全体に font-family: sans-serif; 指定で普通にいける。
SyntaxHighlighter には適用されないので shCore.css に指定。
でも滅茶苦茶なフォントサイズなのは変わらない。

SyntaxHighlighter 2.1.364 を使い続けていたけど 3.0.83 に変更。
配布元にいったけどよくわからなかったのでバックアップを探して適用。
旧版では swf だしタッチパネルじゃ選択し辛いのでコレのほうがいいね。

ちょっぴり良くなったけどフォントズレは変わらない。
CSS を色々弄ってみたけどどうにもならない。

Blogger:SyntaxHighlighter(3)iOS Safariで行番号がずれる問題を解決

検索したら、筆者の設定が悪いのではなかったのか!
-webkit-text-size-adjust: 100%; を入れただけで普通になった。

おまけで shBrushJScript.js の内容を変更。
print, prototype, imports を色分けするように、そう Gjs 用。

shCore.css は overflow: auto !important; でスクロールに。
通常の pre は折り返すというように CSS を指定。

pre {
	border: 1px solid #7c93b2;
	font-family: monospace;
	white-space: pre-wrap;
	word-wrap: break-word;
}

margin は pt 指定していたけど px 指定に変更。
Retina ディスプレイなのが関係あるのかな。
他チマチマと CSS の微調節。

css – Word-wrap in an HTML table – Stack Overflow

これで iPhone でもテーブルからハミ出さなくなった。
と思ったらパソコンで見ると横幅一杯に広がってカッコワルイ。
これは元通りにして今後の課題ということにしておこう。
とはいえ、ぶっちゃけ table タグを使わない方向にするしかなさそう。

他に何をやったかな?覚えていないや。
とにかく iPhone Safari でもゲンナリしない程度にはできたぞと。

Internet Explorer のみ表示確認すればいい時代があったのだけどな。
新たに Web ページ作成を勉強し始める若い人は大変だ。

JavaScript tuple

Gjs では関数の戻り値を配列で2つ以上受け取ることができる。
Python 等の言語仕様に tuple がある言語では常識なのだが。
というか、JavaScript の配列って型が違っても問題ないのね。

Python

#!/usr/bin/env python3

def get_tuple():
    return "CBR", 1000, "RR"

name, cc, ext = get_tuple()
print("{}{}{}".format(name, cc, ext))

Gjs

#!/usr/bin/env gjs

let get_tuple = function() {
    return ["CBR", 1000, "RR"];
}

let [name, cc, ext] = get_tuple();
print(name + cc + ext)

これって Web ページにも使えるのかな?
実験、2014.03.15 現在の最新環境にて。

Google Chrome 33
iPhone 5S Safari
iPhone 5S Google Chrome
FireFox 27
Internet Explorer 11

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tuple Test</title>
<script type="application/javascript"><!--
var get_tuple = function() {
    var name = "iPhone";
    var num  = 6;
    return [true, name, num];
}
function init() {
    var arr = get_tuple();
    if (arr[0]) {
        document.write(arr[1] + arr[2]);
    }
}
//-->
</script>
</head>

<body onLoad="init()">
</body>
</html>

上記ブラウザ全部で関数の戻り値に配列を指定することができた。
しかし tuple のように戻り値を受け入れてくれるのは FireFox のみ。
Gjs は Firefox のエンジンを使っているので同様のようです。

しかし現在のトレンドは書くまでもなくスマートフォン。
Google Chrome, Safari で利用できないのでは使えない。
配列として受け入れるしか選べない。

JavaScript の Array は型が違ってもいいし関数の戻り値にできる。
それを利用すれば構造体を戻す関数やタプルのように扱える、ということで。
今後は解らないけど2つ以上の戻り値が必要な場合はこんな感じにすると便利。

ついでに let について。
FireFox で let 等の JavaScript 1.7 の機能を使うには 1.7 宣言が現時点では必須。
JavaScript 1.7 の新機能 – JavaScript | MDN

<script type="application/javascript;version=1.7"><!--
let get_tuple = function() {
    return ["FireFox", "JavaScript", 1.7];
}
function init() {
    let [name, js, version] = get_tuple();
    document.write(name + js + version)
}
//-->
</script>

Internet Explorer 11 はなんと let 等もそのまま利用可能。
ただしコチラは version=1.7 を書くと動作しない。

<script type="application/javascript"><!--
let get_tuple = function() {
    return ["Internet", "Explorer", 11];
}
function init() {
    let arr = get_tuple();
    document.write(arr.join(" "));
}
//-->
</script>

統一されるまで使い物にならないや。

Gjs I/O Stream

以前下記で Seed, Python で Gio による読み書きをやったのを Gjs にしてみた。
Gio Streaming I/O @ Seed and PyGI | PaePoi

GCancellable 等を指定(null でいい)しないといけなかった。
他色々と Seed より Python に似ていて困惑。

/*
    Gjs Streaming I/O File Read and Write Sample
*/

const Gio = imports.gi.Gio;
const Format = imports.format;

String.prototype.format = Format.format;

let filename = "test_gjs.txt";
const lines = "Japan\n\n日本語";

// Write
let f = Gio.file_new_for_path(filename);
let fstream = f.replace(null, false, Gio.FileCreateFlags.NONE, null);
try {
    // Error, This is no Exception.
    // let dstream = new Gio.DataOutputStream(fstream);
    // g_output_stream_write: assertion 'G_IS_OUTPUT_STREAM (stream)' failed
    let dstream = new Gio.DataOutputStream({base_stream:fstream});
    dstream.put_string(lines, null);
} catch (e) {
    // Without meaning
    log("*** ERROR WRITE: " + e.message);
}
fstream.close(null);

// Read
f = Gio.file_new_for_path(filename);
fstream = f.read(null);
// Same as above
let dstream = new Gio.DataInputStream({base_stream:fstream});
while (1) {
    let [text, len] = dstream.read_line_utf8(null);
    if (text == null) break;
    print("%s(%d)".format(text, len));
    // or print(text + "(" + len + ")");
}
fstream.close(null);

/* output
Japan(5)
(0)
日本語(9)
*/

DataOutputStream 等の引数は json で指定しないと認識してくれない。
現時点では理由が解らない、GOutputStream のサブクラスと認識できないのか?
とにかく Error で困ったら json 指定にすればなんとかなるっぽい。

しかも GError 引数なのに例外にならず普通にエラー。
try ブロックを書いたけど無意味だった、これはちと困る。

おまけで let 変数のスコープは try ブロック内でも有効だと解った。
Python と同様にするには var を利用、注意しよう。

// var is OK
let f = Gio.file_new_for_path("a.txt");
try {
    // var fstream = f.replace(null, false, Gio.FileCreateFlags.NONE, null);
    let fstream = f.replace(null, false, Gio.FileCreateFlags.NONE, null);
} catch (e) {
    //
}
fstream.close(null); // ReferenceError
# Python is OK
f = Gio.file_new_for_path(filename)
try:
    fstream = f.replace("", False, Gio.FileCreateFlags.NONE, None)
except Exception as e:
    pass
fstream.close(None)

Seed にある c_new という意味不明な指定が無いのはちょっぴり嬉しいね。
それ以外は全部 Gjs のほうが面倒臭いけど。

戻り値が Python 同様に 2 つ以上である場合がある。
Python はタプルなんだけど、タプルが無い言語でもこの手があったか。
まあどちらも引数に渡された変数の値を変更できない言語だし。

どうも PyGObject の手段を参考に作っているような気がする。
いや逆かも、というか GLib 側の意向でこうなったのかな?

とにかく Python 屋なら Seed より Gjs のほうがなじみやすいという結論で。

Gjs is JavaScript

最近知ったけどガールフレンド(仮)というスマホゲームって普通にスマホのブラウザ上で動くブラウザ版ってのがあるんだね。
他にも同様なものがあるらしい、つまり HTML5 と JavaScript 製なのか。
スマホアプリは Objective-C, JAVA しかないと思っていたよ。

そういえば Google Chrome エクステンションも JavaScript だ。

ところで筆者のパソコンは Fedora で GNOME を愛用している。
何を今頃と思われそうだけど gnome-documents って Gjs 製なんだね。

gnome_documents

こんなところにも JavaScript が。
知らぬ間にあらゆるものが JavaScript になっていってる。

もう毛嫌いしている場合じゃない、普通に使えるくらいにはならないと。

ということで久々に Gjs を。
Seed プロジェクト側はヤル気が無いみたいだし。

http://ftp.gnome.org/pub/GNOME/sources/seed/
http://ftp.gnome.org/pub/GNOME/sources/gjs/

二年くらい前に少し触った頃と随分変わった気がする。
単に情報が色々出て来ただけだが、やはり日本語情報は皆無に近いけど。
とりあえず gnome-documents のコードを参考にしてウインドウを作ってみる。

const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;

const TestWindow = new Lang.Class({
    Name: 'TestWindow',
    Extends: Gtk.ApplicationWindow,

    _init: function(app) {
        this.parent({
                application: app,
                width_request: 300,
                height_request: 200,
                title: "TitleBar" });
        // or let button = Gtk.Button.new_with_label("Click!");
        let button = new Gtk.Button({ label: "Click!" });
        // or button.connect('clicked', Lang.bind(this, this._onButtonClicked));
        button.connect('clicked', function() {
            button.set_label("DDDone!");
        });
        this.add(button);
        this.show_all();
    },
    /*_onButtonClicked: function (button) {
        button.set_label("Done!");
    }*/
});

const Application = new Lang.Class({
    Name: 'Application',
    Extends: Gtk.Application,

    _init: function() {
        // TaskBar Title
        GLib.set_application_name("Test");
        // property
        this.parent({
                application_id: 'apps.test.Test',
                flags: Gio.ApplicationFlags.FLAGS_NONE });
    },
    // override activate signal
    vfunc_activate: function() {
        new TestWindow(this);
    }
});
let application = new Application();
application.run(ARGV);

GtkApplication は Gjs からも使えるようになったみたい。
というか gnome-documents が普通に使っていた。

class みたいに扱う時 Seed は GType、Gjs は Lang.Class。
Name 指定は必須、継承元は Extends にて指定、コンストラクタが _init ね。
なんとも奇妙だが JavaScript 仕様に class は無いので慣れるしかない。

プロパティセットは Python が __init__ で Gjs が parent にて可能。
普通にドットから代入でもいいけど。

# Python
self.props.title = "new Title"
// Gjs
this.title = "New Title";

シグナルハンドラは Vala のように無名関数が利用できる。
connect でもいいんだけど何故こんなに面倒な書き方なんだろう。
Python でも使えるといい気がするけどインデントが台無しになるお。

オーバーライドは Python が do_ で Gjs が vfunc_ のようだ。
無駄な connect を書かずにすむのは嬉しいね。

const Gtk = imports.gi.Gtk;
const Lang = imports.lang;

const TestWindow = new Lang.Class({
    Name: 'TestWindow',
    Extends: Gtk.Window,

    _init: function() {
        this.parent({ title: "TitleBar" });
        this.show_all();
    },
    vfunc_delete_event: function() {
        Gtk.main_quit();
    }
});
// Initialize the gtk
Gtk.init(null, 0);
new TestWindow();
Gtk.main();

GtkApplication 使用時は不要だけど Gtk.main では init() 必須。
というより Python だと init 呼び出し不要なのが変ということだが。

Gtk.Button.new_with_label が使えたのは何故か不思議な感じ。
そういえば JavaScript は何でもアリだったな。

こんなことをやっても Web やスマホアプリを作りたい時の参考にならない気も。
とはいえまったく文法を知らないよりはマシだからもう少し続けるかも。

iPhone mount in GNOME

iPhone に XPERIA から乗り換えました。
筆者がまず行うことは当然 Linux との接続ですよね。
普通に付属 USB ケーブルで接続してみた。

connect1

connect2

Shotwell で普通に画像を取り込める。
Rhythmbox も多分使えると思う、ごめん音楽を最近まったく聴かないので。
Nautilus で開くことも普通に可能です。

iphone_afc

AFC (Apple File Connection) プロトコルで接続しているようです。
AFC – The iPhone Wiki

やはり別途ドライバ等は不要、接続アイコンまで専用が用意されている。
最近の Linux って超マニアックな周辺機器や業務機器でもなければデフォルト状態でもあたりまえのように認識し接続してしまうよね。
何故ユーザーがあまり増えないのか不思議でしかたがない。

でも [iPhone 上のドキュメント] 部には何もコピーできなかった。
[iPhone] は Media 部をマウントしてるようだけどココは何だろう?

picture

画像は DCIM/100APPLE 内にあった。
ホームボタン + 電源ボタンのスクリーンショットは PNG なんだね。
こちらは Nautilus から普通にコピーできた、私的にはコレさえできれば十分。
Bluetooth 必要ないや。

まあつまり、Linux ユーザーは Mac を用意せずとも iPhone は問題ないよと。