hiiragi's ブログ

主にコンピュータ関係の備忘録を書いてます

Chromeで画像を印刷する。

RiSKさん(@sscrisk)がなんでChromeには画像の印刷ボタンが無いのかとつぶやいていたので作ってみた。
https://twitter.com/sscrisk/status/340817615310188545


拡張のダウンロードはこちらからどうぞ。
Chrome ウェブストア - Print Image Menu

ソースはこちらからどうぞ。
s-hiiragi/print-image-menu · GitHub


簡単に実装できると思ったから作ったのだけど、少し悩んだ。印刷ダイアログを閉じたら自動的にタブを閉じたかったのではじめ以下のように書いていたが、タブが開いた瞬間に閉じてうまくいかなかった。

window.print(); window.close();

なんとなく以下のように変更したら望んだ動作になった。window.print()はブロックせず処理が終了した後ダイアログを開くのかな。

window.print(); setTimeout(function() { window.close(); }, 0);

ポップアップウィンドウ内で印刷ダイアログを開こうともしたけど、ポップアップウィンドウ内でコードを実行させるのが面倒だったので新しいタブ内で開くことにした。

ももんが以外の何か on WebBrowser ヾ( l _ l 〃)ノ゙

ももんが Advent Calendar 2012の23日目です。

今年からももんが Advent Calendarに参加しました、@s_hiiragiです。


ももんが Advent Calendar は何を書けばいいのか分からなかったので、さっちゃんのページで確認しました。

コンピュータの得意な方は、コンピュータともももんがと関係の無い事を、コンピュータの得意でない方は、ももんがとは関係無くコンピュータに関する事を書きましょう。ももんがと関係の無い事は、要するにももんがに関する事です。

ももんが Advent Calendar 2012 - c4se記:さっちゃんですよ☆

ももんがと関係の無い事 = ももんがに関する事なので、コンピュータが得意かどうかによらずももんがに関することを書くようです。僕はコンピュータにあまり精通していないので、ももんがとコンピュータに関する事を書くことにしました。

ももんがについて

えー、こちらの画像を見て頂きたい。これは50年前絶滅したといわれるユーラル共和国産のももんがです。この見事な緑の体と赤い鮮血は人の心を惑わすに十分な美しさと言われてきました。それに一番の特徴は、ももんがの世界では一番早く飛ぶことが出来るということです。まるでももんがのようではありませんか。
https://lh3.googleusercontent.com/--lYjY75I7ew/ULoEbO2Iv2I/AAAAAAAABU8/w5Ffy1XjTGE/s400/28%2520%25E3%2582%25AB%25E3%2583%2590%25E3%2583%25BC%25E3%2582%25A2%25E3%2583%25BC%25E3%2583%2588%25E3%2582%2592%25E9%2581%25A9%25E5%25BD%2593%25E3%2581%25AB%25E6%258F%258F%25E3%2581%258F.png

見た目は小トトロに似ています。多分どこかにいるでしょう。だがその他一切のことは分かりません!

ももんが以外の何か

ももんがを見ているうちに、某Go言語のマスコットキャラクターを思い出しました。比べてみると、ももんがの方が可愛いですね。

マスコットといえば伺かというデスクトップマスコットがあります。デスクトップに二次元の女の子とか青色の謎の物体とかが常駐するアレです。役に立つような立たないような機能がたくさん搭載されていますが、眺めて楽しむのが主目的です。

ももんがもデスクトップマスコット化して、その生態を観測出来たら面白いんじゃないかと思いました。ただし、最近はWebブラウザ上で作業することが多くなってきているというのと僕が単にWebブラウザ好きという理由で、ブラウザ拡張で作りました。

残念ながら時間は限られているため、Google Chrome版しか作ることが出来ませんでした。Operaユーザーの皆様ごめんなさい。あとFirefoxユーザーの方も。今度勉強したら作ってみたいと思います。

今のところ、眺めて楽しむという機能と、クリックするとページの一番上までスクロールするという機能しかありません(この機能の名前が分かる人いましたら教えて下さい)。本当は動いたり伸びたりさせようと思ったのですが、HTML5 canvasでの画像のせん断変形の仕方がよく分からなかったので今回は実装出来ませんでした。


以下からももんがをダウンロードできます(Githubで公開しています)。
Google Chromeの設定>拡張機能ページを開き、ダウンロードしたcrxファイルをDrag & Dropしてインストールしてください。

https://github.com/s-hiiragi/webpage-mascot-momonga/blob/master/mOmonga.crx?raw=true

ももんがの画像は以下のページのカバーアートを模写して作りました(二次創作です)
http://c4se.hatenablog.com/entry/2012/12/01/224928

さっちゃんお許し下さい!


明日は@hirune_asakuraさまです(¦3[___]

Jarファイルのパスを取得する

適当なClassとClass.getResource()を使って調べる。
ClassLoader.getResource()では取得できなかった。

import java.util.*;
import java.lang.*;
import java.io.File;
 
class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        final String classFileName = "/" + Main.class.getName().replaceAll("\\.", "/") + ".class";
        System.out.println("classFileName: " + classFileName);
        
        final String classFilePath = Main.class.getResource(classFileName).getPath();
        System.out.println("classFilePath: " + classFilePath);
        
        final File jarFilePath = new File(classFilePath.replaceFirst("!/.*$", ""));
        System.out.println("jarFilePath: " + jarFilePath);
        
        final String jarFileName = jarFilePath.getName().replaceFirst("\\..+$", "");
        System.out.println("jarFileName: " + jarFileName);
    }
}

参考

mouseover, mouseoutのevent.target等について

target, currentTarget, relatedTarget, srcElement, fromElement, toElementが紛らわしいので調べた。

W3C DOM

target イベントが発生した要素
currentTarget イベントリスナを登録した要素
relatedTarget mouseover: 移動元の要素, mouseout: 移動先の要素

Microsoft DHTML

srcElement イベントが発生した要素
fromElement mouseover, mouseoutで移動元の要素
toElement mouseover, mouseoutで移動先の要素


参考にしたリンク, 動作確認サンプルはこちらで
http://jsdo.it/s_hiiragi/xYCP/fullscreen

任意のファイルのメモを作成する/開くコマンド

これは何?

任意のファイルのコンテキストメニュー(右クリックメニュー)からファイルにメモしたり、メモを開いたりするコマンド。

設定方法は?

HKEY_CLASSES_ROOT\*\shell\にcreateNoteキーを作成し、commandサブキーに以下をコピペする。
あとcreateNoteキーの既定値に"ファイルにメモする"をセットしておく。

cmd /c "for %%a in ("%1") do ((if not exist "%%~dpna.README.txt" (copy nul "%%~dpna.README.txt") else echo) && start "" "%%~dpna.README.txt")"

仕組みは?

  1. ファイルと同一のフォルダ内に『ファイル名(拡張子除く).README.txt』というファイルが無ければ作成し、デフォルトのエディタで開く。
  2. 既にある場合は、そのファイルを開く。

備考

  • commandキーに指定するコマンドで変数を使いたいのだけど、使えなかった(なので同じメモファイル名を何度も入力してる)。
    • 誰か教えてください。

動作確認環境

Windows XP SP3

Function.prototype.bindを名前付き引数に対応させる

使えるかどうか分からないけど。
ネイティブメソッドは引数名が取得できないので名前付き引数のbindの有難みが無い…orz

/* bindAny(thisObj[, args][, namedArgs])
 * bindAny(thisObj[, namedArgs][, args]) // Syntax sugar
 */
Function.prototype.bindAny = function(thisObj)
{
    var orig = this;
    
    var boundArgs, boundNamedArgs;
    if (Array.isArray(arguments[1])) {
        boundArgs = arguments[1];
        boundNamedArgs = arguments[2];
    } else {
        boundNamedArgs = arguments[1];
        boundArgs = arguments[2];
    }
    if (!boundArgs) boundArgs = [];
    if (!boundNamedArgs) boundNamedArgs = {};
    
    /* build pre arguments
     * 
     * 元の関数の引数名の列を取得
     * nameに対応する位置にnamedArgs[name]を入れる
     */
    var argNames = orig.toString()
        .match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(/\s*,\s*/);
    var args = [];
    for (var i = 0, l = argNames.length; i < l; ++i) {
        var name = argNames[i];
        if (boundNamedArgs.hasOwnProperty(name)) {
            args[i] = boundNamedArgs[name];
        }
    }
    
    var slice = Array.prototype.slice, 
        news = [];
    function bound()
    {
        /* build actual arguments
         * 
         * pre-argumentsの先頭から順にundefinedにargsを入れる
         * 残ったargsは末尾に追加
         */
        var ta = boundArgs.concat(slice.call(arguments));
        var a = slice.call(args);
        for (var i = 0, l = a.length; 1 <= ta.length && i < l; ++i) {
            if (typeof a[i] === 'undefined')
                a[i] = ta.shift();
        }
        if (ta.length >= 1) a = a.concat(ta);
        
        if (this instanceof bound) { /* I am a constructor! */
            if (!news[l]) {
                var as = [];
                for (var i = 0, l = a.length; i < l; ++i)
                    as.push('a[' + i + ']');
                var evs = 'news[l]=function(){return new orig('
                    + as.join(',')
                    + ');};';
                eval(evs);
            }
            var ret = news[l]();
            if (typeof ret.__proto__ === 'object') {
                ret.__proto__ = bound.prototype;
            }
            return ret;
        } else {
            return orig.apply(thisObj, a);
        }
    }
    
    function fnop() {}
    fnop.prototype = orig.prototype;
    bound.prototype = new fnop();
    return bound;
};


動作確認

function f(a, b, c, d) {
    console.log(arguments);
}

f.bindAny(null, [1, 2], {c: 3, d: 4})(); // f(1, 2, 3, 4)
f.bindAny(null, [1, 2])();               // f(1, 2)
f.bindAny(null, [1, 2])(3, 4);           // f(1, 2, 3, 4)
f.bindAny(null, {c: 3, d: 4})(1, 2);     // f(1, 2, 3, 4)
f.bindAny(null, {c: 3, d: 4})();         // f(undefined, undefined, 3, 4)
f.bindAny(null, {c: 3})(1, 2, 4);        // f(1, 2, 3, 4)


参考