読者です 読者をやめる 読者になる 読者になる

Corredor

ウェブ、プログラミングの勉強メモ。

ブログのテーマを大幅にカスタマイズしてみた

はてなブログ CSS

このブログのテーマを大幅にカスタマイズしてみた。

といっても、基本的なカラーリングやレイアウトはそのままなので、「若干フォント指定が変わったかな?」くらいにしか思われないと思う。

はてブロは色々と動作が重たいので、高速化を目的に CSS を軽量化できないかといじり始めた次第。はてブロは基本的にテンプレート HTML が変更できないので、CSS でのカスタマイズと、余計な JavaScript の読み込みをどれだけ減らすか、というところにかかっている。

で、まずは CSS が重たいのではないかと思い、元のテーマを参考に、はてな公式の Boilerplate.css をカスタマイズした。

はてな公式の Boilerplate.css はレスポンシブデザインに対応したスタイルになっているのだが、レスポンシブデザインに対応させるには、あるコメントを入れないといけないらしい。

以下のコメントを CSS 中に入れておく。

/* Responsive: yes */

これで OK。

さて、これで軽量化できたかというとそこまでの変化はなかった。が、カスタマイズを経てテンプレート HTML が分かってきたので、ココから細かいところで軽量化していけるかもしれない。

Firefox の「最近のブックマーク」を非表示にする

Firefox

Firefox の設定変更、色々なところで記事を見てはアレコレ変更しているので、一体自分のセッティングがデフォルトからどれだけ変わっているのか、いつも分からなくなる。user.js で変更するように習慣付ければいいのだろうけど…。

で、「ブックマーク」メニューの「最近のブックマーク」を非表示にする方法。

about:config を開き、browser.bookmarks.showRecentlyBookmarkedfalse にする。

cloneNode() で複製した select 要素の選択状況がリセットされる

DOM JavaScript

セレクトボックスを cloneNode() して、その要素を appendChild() とか replaceChild() とかすると、複製する前に選択していた状態が再現されなかった。

cloneNode() したフォーム部品が、直前に画面上でどのように操作されていたか、という情報は、ブラウザによって引き継いだり引き継がなかったりするようだ。チェックボックスラジオボタンのチェック状況なんかも同様のことが起こったりするみたい。

で、これをどう回避したらいいかというと、元の select 要素から value 属性を移植 してやれば、プルダウンのどの項目を選択した状態にするかを設定してやれる。

コードで実例

例えば以下のようなプルダウンメニューがあったとして、項目の「その2」とかを画面上で選んだとする。その後に何らかの操作をするとこのセレクトボックスが複製されて隣に表示されるのだが、何にも考慮していないと「指定なし」を選択した状態のプルダウンを表示するブラウザがある。

<div id="parent">
  <select id="select">
    <option value="" selected>指定なし</option>
    <option value="1">その1</option>
    <option value="2">その2</option>
    <option value="3">その3</option>
  </select>
</div>

そこで、cloneNode() するときに value 値をコピーするひと手間を加えてやる。

function cloneSelectBox() {
  // 元の要素を取得しコピーを生成する
  var src = document.getElementById("select");
  var copy = src.cloneNode(true);
  
  // 元の選択状態をコピーする
  copy.value = src.value;
  
  // 元の要素と入れ替える
  var parent = document.getElementById("parent");
  parent.replaceChild(copy, src);
}

これで OK。

select 要素の value 属性と option 要素の selected 属性

select 要素の value 属性は、現在選択されている option 要素の value 属性値を持つのだが、「現在選択されている option 要素」には selected 属性が付与されている

これは HTML ソース上に selected 属性がコーディングされているかどうかではなく、ブラウザ上で選択しているアクティブな項目の情報が、select 要素の value 属性と option 要素の selected 属性とで同時に示されている。

だから、select 要素の value 属性をコピーするのではなく、各 option 要素の selected 属性をコピーしてあげても同様の結果を得られる。

function cloneSelectBox() {
  // 元の要素を取得しコピーを生成する
  var src = document.getElementById("select");
  var copy = src.cloneNode(true);
  
  // option 要素の選択状況をコピーする
  var copyOptions = copy.getElementsByTagName("option");
  var srcOptions = src.getElementsByTagName("option");
  for(var i = 0; i < copyOptions.length; i++) {
    var copyElem = copyOptions[i];
    for(var j = 0; j < srcOptions.length; j++) {
      var srcElem = srcOptions[j];
      // コピー前と要素の value 属性値を比較して
      // 同じなら selected 属性値をコピーしてやる
      if(copyElem.value == srcElem.value) {
        copyElem.selected = srcElem.selected;
      }
    }
  }
  
  // 元の要素と入れ替える
  var parent = document.getElementById("parent");
  parent.replaceChild(copy, src);
}

こんな風にしても意図した動作になってくれる。まぁでも面倒臭いので最初の方のやり方で良いのでは。

自分が試した環境では、チェックボックスラジオボタンは問題なし

先程「チェックボックスラジオボタンのチェック状況なんかも同様のことが起こったりするみたい。」と書いたが、自分が試したいくつかの環境では特に問題なかった。

ただし、ラジオボタンをただ複製して配置した場合は、同じ value 属性のラジオボタンが複数存在することになるので、選択状態がおかしくなる。複製したら value 属性値を変更してから Append するようにしたい。

レガシーな開発環境で Watch っぽいことがしたくて自作したバッチ

Windows バッチ Windows コマンド WebLogic Server

WebLogic Server に WAR ファイルをデプロイして、Java 製アプリケーションを開発している。ワケあって Tomcat は使えず、開発したモジュールは毎度 WLS にデプロイする必要があってゲロ面倒くさかった。

しかし、JSP ファイルであれば、_WL_internal フォルダ配下に JSP ファイルを投げ込めば即反映してくれることを発見した。

パスは /domains/domain_name/servers/AdminServer/tmp/_WL_internal/ とかそんな感じ。WLS が WAR ファイルを解凍して参照している場所みたい。

ココに対して、IDE で編集している JSP ファイルを更新するたびに投げ込めれば、Gulp の Watch っぽいことができるという寸法だ。

というわけでこんな雑な Windows バッチを作ってみた。

Rem IDE で編集しているワークスペースのうち、JSP ファイルが存在するルートディレクトリ
Set SRC_DIR=C:\Workspace\MyProject\pages\

Rem WLS の JSP ファイルが解凍されているルートディレクトリ (hogefuga 部分はランダムな文字列)
Set DIST_DIR=C:\Oracle\MiddleWare\domains\domain_name\servers\AdminServer\tmp\_WL_internal\hogefuga\

:LOOP
Xcopy /d /k /s /y %SRC_DIR%\*.* %DIST_DIR%

Timeout 5
Goto :LOOP

Exit /b

コピー元のファイルがある場所が %SRC_DIR%、コピー先のディレクトリを %DIST_DIR% で変数宣言しておく。場所は適宜設定する。

ファイルのコピーには Xcopy というコマンドを使用した。オプションの意味は以下のとおり。

  • /d : コピー元の更新日時がコピー先よりも新しければコピーする
  • /k : 属性もコピーする
  • /s : サブフォルダも対象にする
  • /y : 上書き前の確認メッセージを出さないようにする
  • /q : コピー中のファイルを表示しないようにする

キモとなるのは /d オプション。コピー元のファイルの方が新しければコピーするので、新しくない場合はコピーが発生しない。普通なら「開発した日時」より「デプロイ後解凍した時刻」の方が新しくなるはずなので、基本的にコピーは発生しない。コピーが発生するということは、デプロイ後に行われた編集ということだ。

そしてコレを Timeout で適当に間隔を開けつつ、無限ループで実行している。実に乱暴だが、ファイルの更新を検知してサーバ側にコピーしていくので、編集した内容を即時確認できる。

…もうこんな乱暴なテクニックを身に付けずに済む仕事がしたい。w

Windows コマンドのヘルプをテキストファイルに書き出してみる

Windows コマンド Windows バッチ

コマンドプロンプト初心者が、コマンドを勉強する時の参考になればと思い、こんなネタをやってみた。

Help コマンドは、引数に与えたコマンドの使い方を教えてくれる。そして、引数を与えずに呼ぶと、コマンドプロンプト標準のコマンド一覧と簡単な説明を返してくれる。

これを利用して、Help コマンドで出てくるコマンドのヘルプ文章を、コマンドごとにテキストファイルに書き出してみる

@Echo Off

Pushd %0\..

For /f "tokens=1*" %%a In ('Help') Do (
  Echo.%%a | Findstr /r "^[A-Z][ABCDEFGHIJKLMNOPQRSTUVWXYZ]" > Nul
  If Not ERRORLEVEL 1 (
    Help %%a > %%a.txt
  )
)

Exit /b

Pushd %0\.. でバッチファイルがあるフォルダをカレントディレクトリにしている。

For コマンドは色んなことができて分かりづらいが、今回は In ('Help') とあるように、Help コマンドの結果を1行ずつ処理するループになっている。tokens=1* とだけ書いてあるので、delims 未指定の場合は1行の内容がスペースで区切られて %%a 以降の変数にセットされていく。コマンドプロンプト%%a とだけ書けば、次の変数名は空気を読んで %%b%%c …と名前を変えていってくれる。ただし今回は tokens=1* としたので、スペースで区切られたあとの値は、行末まで全て %%b にセットされ、%%c は作られない。そして今回は %%b に入る値は不要なので %%b も登場していない。

Help コマンドの一覧は「コマンド 概要」と記述されているのだが、概要の文章が改行されているため、行頭がアルファベットで始まる行のみを取り出し、先頭の単語 = コマンド名を取得しようとしている。

しかし、改行された概要文の中に、説明文として「Windows」という単語が行頭にくる部分がある。そのため、「Windows」から始まる行を除外するために、行頭から大文字のアルファベットが2文字連続で登場する行を探さなくてはならない。

だがここで問題なのは、Findstr の範囲マッチは大文字小文字の区別をしないらしく、^[A-Z][A-Z] と書いても「Windows」を除外できなかった。そこで苦肉の策で、範囲マッチではなくクラスマッチに大文字アルファベットを羅列した。

こうしてコマンドのみを取り出すことができたので、Help コマンドの引数にそのコマンド名を渡し、結果をファイルに出力しているワケである。

テキストファイルにしておけばコマンドプロンプトを叩かずとも読めるので、初めのうちはこんなカンペを作ってみても良いかもしれない。