ProtoViewLogic: collectElements()

対象の DOM 要素から特定条件を満たす要素を収集します。

この関数は引数 rootElement がプロミスでなければ同期関数、プロミスであれば非同期関数です。

構文

protoViewLogic.collectElements(rootElement) => object | Promise<object>
protoViewLogic.collectElements(rootElement, filter) => object | Promise<object>

引数

  • rootElement: Element

    収集対象の要素を子孫に含む DOM 要素または解決時に要素を返すプロミスです。

  • filter: function | undefined (省略可)

    収集対象とする要素の条件を表す関数です。

    この関数は、収集する候補の要素 (Element) を引数とし、それが収集対象であれば true を、そうでなければ false を返す関数でなければなりません。 候補の要素としては、引数 rootElement の子孫で、id 属性を持ち、親文書の中で定義済み(:defined)の要素が与えられます。つまり rootElement.querySelectorAll(":defined[id]") の結果に含まれる要素すべてが引数 filter に渡されます。

    指定のない場合、data-ui-component カスタムデータ属性が定義されているか、AlierCustomElement のインスタンスであることを条件とします。

返値: object | Promise<object>

収集された要素を値とし、その id 属性値をキャメルケースに変換した文字列をキーとするプロパティを持ったオブジェクト、または履行時にそれを与える Promise です。

得られたオブジェクトは、キーが id 属性値、値が収集された要素となります。

例外

  • TypeError

    • 引数 rootElementElement でなかった場合。
  • SyntaxError

    • 収集対象の要素の id 属性が不正な値を持つ場合。以下の条件のいずれかを満たすと不正な値となります:

      • 値に JavaScript の識別子として使用できない文字を値に含む。

      • 値にドット "." を含む。

      • 値に角括弧 "[]" が複数組含まれている。

      • 値が空文字列または未定義。

      • 対象の ProtoViewLogic のプロトタイプチェーンに同名のプロパティが存在する。

        これは id 属性値をキャメルケース変換した結果によって判断されます。

  • Error

    • 引数 filter に指定された関数を呼び出した際、何らかのエラーを起こした場合。

      発生する Error は原因となったエラー情報を cause プロパティに持ちます。

解説

この関数は引数 filter として関数が指定されたかどうかによって異なる動作をします。

この関数は、filter として関数が提供されなかった場合、以下の条件をすべて満たす要素を収集します:

  • id 属性が定義されている
  • ブラウザ組み込みの要素または定義済みのカスタム要素である
  • data-ui-component カスタムデータ属性が定義されているか、 AlierCustomElement のインスタンスである

ここでカスタムデータ属性 data-ui-component はブラウザ組み込みの要素(<input><button> など)や AlierCustomElement 以外から派生したカスタム要素に対するマーカとして機能します。

引数 filter として関数が提供された場合、代わりに以下のすべて満たす要素を収集します:

  • id 属性が定義されている
  • ブラウザ組み込みの要素または定義済みのカスタム要素である
  • 関数 filter() がその要素に対して true を返す
//  NOTE:
//  以下ではカスタム要素 <my-element> が定義済みであるとします。
//  また <my-element> は AlierCustomElement のインスタンスであるとします。

const vl = new ProtoViewLogic();

const rootElement = document.createElement("div");
const textarea    = document.createElement("textarea");
const field       = document.createElement("input");
const button      = document.createElement("button");
const myElement   = new MyElement();

rootElement.append(textarea, field, button, myElement);

//  id のみを設定する
textarea.setAttribute("id", "textarea");

//  data-ui-component のみを設定する
field.setAttribute("data-ui-component", "");

//  id と data-ui-component を設定する
button.setAttribute("id", "button");
button.setAttribute("data-ui-component", "");

//  カスタム要素に id を設定する
myElement.setAttribute("id", "my-element");

//  id と data-ui-component を持つ Element を収集する
const collected = vl.collectElements(rootElement);

//  button と myElement が収集される
//  my-element の id はケバブケースのため、結果のキーはキャメルケースへ変換されている。
//  (my-element ==> myElement)
console.log(Object.keys(collected));
//  => [ "button", "myElement" ]

//  id が textarea または my-element の要素を収集する
const collected2 = vl.collectElements(rootElement, element => (
    element.id === "textarea" || element.id === "my-element"
));

console.log(Object.keys(collected2));
//  => [ "textarea", "myElement" ]

id 属性値が Base64 形式で符号化されている場合、元の文字列へ復号されます。

また、id 属性の値がケバブケース[^kebab-case]の場合、キャメルケース[^camel-case]へ変換した文字列をキーとします。