latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

mofmof.js の上に uupaa.js をどすーん

uupaa.js (uu) は、mofmof.js (mm) をベースに再構築している最中です。
新しい uupaa.js は IE6, IE7 非対応になります、古いIEを切り捨てることでライブラリがシンプルになり、より効率的なコードになっています。

今日は、最近実装した機能のご紹介。

uu.dump(node tree), mm.dump(Object), Array#dump(), uu(node, uu.p())

node tree をダンプできたら便利なので uu.dump() を作りました。

uu.dump(html)

""<html>": {
    "<head>": {
        "<meta>": {
            "charset": "UTF-8"
        },
        "<title>": {

        },
        "<meta>": {
            "name": "viewport",
            "content": "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
        },
        "<script>": {
            "src": "mm.js"
        },
        "<script>": {
            "src": "mm.env.js"
        },
        "<script>": {
            "src": "uu.js"
        },
        "<script>": {
            "src": "uu.css.js"
        }
    },
    "<body>": {
        "title": "hoge",
        "style": "background:url(grid.png)",
        "<script>": {
            "text": "/* uu.main(function() { if ..."
        },
        "<p>": {
            "query": "body>p#a",
            "id": "a"
        }
    }
}"

長いテキストノードは "text": "/* uu.main(function() { if ..." と省略表示します。
場所を特定できるように "query": "body>p#a" といったパス情報も付与しています。
query の値をそのまま document.querySelector("body>p#a") とすることでノードにアクセスできます。

"body>p#a" の属性にアクセスするには、 uu("body>p#a").attr() または uu.attr("body>p#a") とします。

mm.dump(uu.attr("body>p#a"))
{
    "id": "a"
}

オブジェクトツリーをダンプできると便利なので、 mm.dump() を作りました。

mm.dump(mm)

"mm_factory {
    "MessageGroup": MessageGroup {},
    "allow": mm_allow {},
    "arg": mm_arg {},
    "cast": mm_cast {
        "attr": mm_cast_attr {},
        "list": mm_cast_list {},
        "string": mm_cast_dateString {},
        "style": mm_cast_style {}
    },
    "clear": mm_clear {},
    "copy": mm_copy {},
    "count": mm_count {},
    "def": defineClass {},
    "deny": mm_deny {},
    "dump": mm_dump {},
    "each": mm_each {},
    "env": {
    },
    "every": mm_every {},
    "has": mm_has {},
    "iog": mm_iog {
        "reset": mm_iog_reset {}
    },
    "isArray": isArray {},
    "isBool": anonymous {},
    "isBoolean": anonymous {},
    "isDate": anonymous {},
    "isEnum": anonymous {},
    "isFn": anonymous {},
    "isFunction": anonymous {},
    "isHash": anonymous {},
    "isInstance": anonymous {},
    "isInt": anonymous {},
    "isInteger": anonymous {},
    "isList": anonymous {},
    "isNode": anonymous {},
    "isNumber": anonymous {},
    "isObject": anonymous {},
    "isPrimitive": anonymous {},
    "isRegExp": anonymous {},
    "isString": anonymous {},
    "keys": keys {},
    "like": mm_like {},
    "log": mm_log {
        "error": mm_log_error {},
        "local": true,
        "remote": false,
        "url": "",
        "warn": mm_log_warn {}
    },
    "map": mm_map {},
    "mix": mm_mix {},
    "mmm": {
        "clear": anonymous {},
        "copy": anonymous {},
        "count": anonymous {},
        "dump": anonymous {},
        "each": anonymous {},
        "every": anonymous {},
        "has": anonymous {},
        "keys": anonymous {},
        "like": anonymous {},
        "map": anonymous {},
        "mix": anonymous {},
        "pack": anonymous {},
        "some": anonymous {},
        "values": anonymous {}
    },
    "msgg": {},
    "nop": mm_nop {},
    "pack": mm_pack {},
    "pair": mm_pair {},
    "pao": mm_pao {},
    "say": mm_say {},
    "some": mm_some {},
    "strictMode": false,
    "type": mm_type {
        "complex": mm_type_complex {},
        "of": mm_type_of {}
    },
    "uid": mm_uid {},
    "values": mm_values {},
    "wiz": mm_wiz {}
}"

数値の配列を Hex dump できると便利なので Array#dump も作りました

0..to(100).dump()

"[ 
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064 ]"


ノードを直感的にビルドできると便利なので、uu("#target", uu.div(uu.p("id:a"), "::Hello world", "color:red")) とできるようにしました

uu("#target",
    uu.div(
        uu.p("id:a;data-hoge:hoge", "::Hello world", "color:@@", "gold")));

    とすると、以下のノードツリーが生成されます。

<??? id="target">
  <div>
    <p id="a" data-hoge="hoge" style="color:gold">Hello world</p>
  </div>
</???>

uu.p() や uu.div() は、文字列中に @@ を見つけると後続の値をそこに埋め込みます。"color:@@" と "gold" は "color:gold" になります。
また、先頭が :: で始まる文字列はテキストノードになります。


"id:a;data-hoge:hoge" の部分は、{ id: "a", "data-hoge": "hoge" } としても同じ結果になります。

uu("#target",
    uu.div(
        uu.p({ id: "a", "data-hoge": "hoge" }, { color: "gold" }, uu.text("Hello world"))));


イベントを設定したい場合は、途中で clickメソッドを使うか

uu.body(
    uu.div(
        uu.p("::click me").click(fn)));


<body>
  <div>
    <p>click me</p> + addEventListener("click", fn)
  </div>
</body>


あとから、click メソッドや on メソッドでイベントを引っ掛ける事ができます

var p;

uu.body(
    uu.div(
        p = uu.p()));

p.click(fn); // または p.on("click", fn);


HTMLElement#top で、body の先頭に div ノードを挿入し

document.body.top(
    uu.div(
        uu.p()));

HTMLElement#add で、body の最後に div ノードを追加します

document.body.add(
    uu.div("class:b",
        uu.p("id:a", "color:red")));

以下のコードとおなじです

var p = document.createElement("p"),
    div = document.createElement("div"), 

p.id = "a";
p.style.color = "red";
div.className = "b";
div.appendChild(p);
document.body.appendChild(div);

HTMLElement#add の代わりに、 HTMLElement#top を使うと、先頭にノードを挿入する事ができます。

document.body.top(
    uu.div(
        uu.p()));

HTMLElement#cut で、親ノードとの接続をカットします

var div;

document.body.add(
    div = uu.div(
        uu.p()));


div.cut(); // document.body から div を切り離します( div.parentNode が null になる)

HTMLElement#cut の部分は、以下のコードとおなじです

if (div.parentNode) {
  div.parentNode.removeChild(div);
}

(ε・◇・)з IE6 + IE7 のシェアが 2% しかないので、いつまでも古いブラウザをサポートしてても仕方ないのさ
(ε・◇・)っ http://gs.statcounter.com/#browser_version_partially_combined-ww-weekly-201216-201225
(ε・◇・)з おしまい