JavaScript の標準組込みオブジェクトは、日時関連の処理が非常に貧弱だ。
次の水曜日は何月何日? とか、 来週の月曜日は何月何日? といった値を取得しようと思ったら、タイムゾーン周りの処理と合わさって、思いのほか面倒だった。
とりあえず、動くコードができたので、記事にして紹介する。
JavaScript の標準組込みオブジェクトは、日時関連の処理が非常に貧弱だ。
次の水曜日は何月何日? とか、 来週の月曜日は何月何日? といった値を取得しようと思ったら、タイムゾーン周りの処理と合わさって、思いのほか面倒だった。
とりあえず、動くコードができたので、記事にして紹介する。
Puppeteer を使ってファイルをダウンロードする際に、任意のパスと名前で保存したい。
残念ながら、 現時点ではシンプルな方法は提供されていないようだ。
以下の Issue で何年にもわたって議論されているものの、 「コレ!」 という解決方法は無さそう。
Question: How do I get puppeteer to download a file? · Issue #299 · puppeteer/puppeteer
しかし、 この Issue の #issuecomment-668087154 のコメントで、 なかなか泥臭い方法で実現するヒントが書かれていた。
これを参考にして、任意のパスと名前でダウンロードファイルを保存してみよう。
あらかじめ、 puppeteer の npm パッケージをローカルにインストールしておく。
npm install puppeteer --save
その状態で、後述の .js ファイルを nodejs で実行すれば OK だ。
node puppeteer-download-with-specify-name.js
document.location = document.getElementById('page1').toDataURL();
Firefox で PDF 開いて任意のサイズで表示し、 開発者コンソール (F12キー) で上記のコード実行すれば、png 画像になって表示される。
あとはその画像を「名前をつけて保存」すればいい。
TypeScript とは、 いわゆる altJS のひとつで、 ECMAScript (JavaScript) に静的型付けを加えたスーパーセットとなるプログラミング言語だ。
この TypeScript には、 ES6 (ECMAScript 6, Harmony) 相当のコードから ES5, ES3 にコンパイル (トランスパイル) する機能のほか、 ES7 で予定されている一部の機能を先取りし ES6 にコンパイルして使用することもできる。
そんな時代を先取りした機能の一つが "async/await" だ。
"async/await" とは 2012年に C# 5.0 とともに登場した記述方法で、 これを使うと、 非同期な処理を コールバック地獄にならず、 あたかも同期的な処理のように書くことができる。
同様の記述が、最近 Python 3.5 でもサポートされ、これからの非同期処理のスタンダードとなるだろう。
しかし、 TypeScript で async/await を使うには コンパイル後の ECMAScript の実行環境が ES6 をサポートしていなくてはならない。
現行のブラウザのシェアを考えると、 ES6 をサポートしないブラウザ (主に IE, Safari だが) を切り捨てる選択肢はちょっと厳しい。
一方でサーバサイド JavaScript として有名な node.js では、最近になって組織の変更のおかげで開発が活発化し、 ES6 のサポートが入ってきている。
しかし、 node.js はサーバサイドの技術。 クライアントアプリで使えた方がいろいろな用途で使えて夢が広がる気がする。
そこで Electron ですよ。
Electron (旧 Atom-Shell) とは、 Chromium の HTML5 と node.js の技術を使って、クロスプラットフォームのデスクトップアプリを作れるアプリケーションエンジンだ。
JavaScript エンジンごと中に内包しているため、 OS や インストールされたブラウザのバージョンを一切気にせずに HTML5 アプリケーションが作れるという、 IE に苦しめられている諸兄には夢のような技術 (?) だ。
Slack のデスクトップクライアントや、Visual Studio Code なんかも、 Electron を使って作られている。
そしてこの Electron は node.js の技術を使っていると述べたとおり、 ES6 がつかえるではないか!
…ということで、 Electron + TypeScript で async/await を使ってみようと思う。
DOM level3 に対応したブラウザで使える、 javascript の document.evaluate であれば、XPath ですべてのコメントを抜き出すときに、
var result = document.evaluate("//comment()", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
等としておけば問題ないが、一部の HTML パーサでは、HTML の DOCTYPE 宣言もコメントとして扱ってしまうものがある。
…と言うより、 "<!" で始まって、">" で終わるものはすべてコメントとして扱ってしまうような場合について。
JavaScriptでは、varによる変数宣言をしていない場合、グローバルオブジェクト(window)のプロパティとして扱われる。
IEでは、htmlのid属性が、このグローバルオブジェクトのプロパティになってしまうらしい。
以下のコードで、「click!」というアラートが出たら、 window.btn01 に button の DomElement が入っているということになる。(Firefox や Chrome 等では、エラーになってなにも表示されないはず)
<button id="btn01" onclick="alert(btn01.innerHTML);">click!</button>
しかも jQuery が有効な状態で、
btn01 = null;
などとやろうとすると、btn01 変数にはすでに button の DOM が入っているのと、IE8とjQueryの相性の問題で、IEではエラーになってしまう。
まぁ、
var btn01 = null;
と、var つけてやるだけでOKだし、そもそもIE9ではエラーにならないので、古いブラウザ使うなってコトでFAでもよい気がしないでもないけどね…
とはいえ、9/1現在、IE8がシェア35%と圧倒的なので無視できないのよねぇ
参考: 日本のバージョン別ブラウザシェアグラフ (StatCounter Global Statsより)
Google Chart Tools の中に、QRコードを動的に生成するAPIがある。
特定のURLにGETリクエストを渡すだけでPNG画像を返してくれるので、非常に便利だ。
続きを読む
JScriptのString.replaceメソッドは非常に便利だ。
置き換え文字列に、「文字列」ではなく「関数」が使えるところが意外と使える。
"test0 test1".replace(
/\w+(\d)/g,
function($0,$1){return (Number($1)+1).toString();})
てな具合に。
普段はWSHではVBSなんぞ使ったりしないが、
たまにどうしてもVBAやVBSを使わなくてはならない場合がある。
そんなときにそれっぽい動作をする様なのを、
不完全ながら自作してみた。
JScriptで、ダブルクリックしたときにコマンドプロンプトで強制的に起動するとき
こんな感じで起動してやると、
Echoがたくさんあっても大変なことにならず、
しかもエラーコードもしっかり返すことができる。
function CRun(){
if (!(/CSCRIPT\.EXE/i).test(WScript.FullName)){
var WshShell = new ActiveXObject("WScript.Shell");
var strParam = "";
for (var i = 0; i < WScript.Arguments.Count(); i++){
strParam += " \"" + WScript.Arguments(i).replace("\"", "\"\"") + "\"";
}
WScript.Quit(WshShell.Run("cmd.exe /v:on /s /c \"cscript.exe //nologo \""
+ WScript.ScriptFullName + "\""
+ strParam + " & pause & exit /b !ERRORLEVEL!\"", 8, true));
}
}
CRun();
WScript.Echo("CScript!");
WScript.Quit(8);
環境変数の遅延展開をつかって、ERRORLEVELを戻しているのがミソ。
これで、エラーが起きたときの処理もできる。
私は業務を軽減するツールとか作るときに割とよく使う。