compareTreePosition

compareDocumentPosition

[3] Node オブジェクトcompareDocumentPosition メソッドは、2つの節点文書順的な意味での関係を返します。

仕様書

[4] 現時点では Web DOM Core には存在することだけで実質的な規定がまだされていません。

引数

[15] このメソッドは引数を1つだけ取ります。 >>2

[16] 第1引数 other は、比較対象となる Node オブジェクトです。 >>2

返し値

[17] このメソッドは2節点間の関係を表すビットマスクを返します。データ型としては unsigned short です >>2

DocumentPosition

[11] 驚くべきことに DOM3 仕様上は関係がほのめかされているだけで明示されていないのですが、 compareDocumentPosition定義群 DocumentPosition に属する定数によるビットマスク値を返します。

[12] 界面 Node定義群 DocumentPosition には、 データ型unsigned short である以下の定数があります >>13

DOCUMENT_POSITION_DISCONNECTED (0x01)
節点連結ではありません。 (連結していない節点の順序は常に実装規定です。)
DOCUMENT_POSITION_PRECEDING (0x02)
与えられた節点参照節点に先行する節点です。
DOCUMENT_POSITION_FOLLOWING (0x04)
与えられた節点参照節点に後続する節点です。
DOCUMENT_POSITION_CONTAINS (0x08)
与えられた節点は、参照節点を含んでいます。 (含む節点は常に先行する節点でもあります。)
DOCUMENT_POSITION_CONTAINED_BY (0x10)
与えられた節点は、参照節点に含まれています。 (含まれる節点は常に後続する節点でもあります。)
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC (0x20)
どちらが先行でどちらが後続かは実装規定です。

処理モデル

[8] このメソッドがよばれた節点参照節点 (reference node) とするとき、 参照節点と第1引数に与えられた節点についての文書中での位置を文書順に基づき調べてビットマスクとして返します >>2

ビットマスクの決定

[18] このメソッドは2節点間の文書中の相対位置を表すビットマスクを返します。 この値は次のようにして決定されます。 >>13

  1. [19] 2節点同じ節点なら、フラグは何も設定せずに返します。
  2. [20] そうでなければ、共通の包含子 (両節点含む (contains) 節点) を探します。
    1. [24] 共通の包含子節点がなければ、
    2. [28] 一方が他方の節点を含んでいるなら、包含子が含まれている節点に先行し、含まれている節点包含子の後続となっています。
    3. [29] >>24>>28 のいずれでもない場合には、両方の節点のどちらの包含子でもあって、最も「直接」的である節点が存在するはずです。この場合、そのような節点が直接含む節点に、比較対象の節点または比較対象の節点を含んでいる節点が丁度1つずつ、合計2つ存在するので、その順序によって比較対象の節点の順序が決まります。
      1. [30] 両者がともに子供節点なら、自然な DOM 上の順序を返します。
      2. [31] どちらかが子供で他方がそうでないなら、子供である方が子供で無い方に後続するものとします。例えば子要素属性に後続する (属性が先行する) とします。
      3. [32] どちらも子供でなく、 nodeType が異なるなら、大きい順とします。
      4. [33] どちらも子供でなく、 nodeType も同じなら、順序は実装依存です。

[35] >>33 が「実装規定」ではなく「実装依存」なのは、typo なのか意図的なのかどうなのでしょうね。

[44] Firefox でも Chrome でも、同じ要素属性節点同士だと DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | (DOCUMENT_POSITION_PRECEDING または DOCUMENT_POSITION_FOLLOWING が返されるようです。違う要素属性ならその所属する要素の関係で決まるようです。

文書順

[6]文書順」は通常の DOM 節点に対しては DOM 仕様で定義されていますが、 DOM XPath 仕様では XPathNamespace 節点が追加されているため、 それに対応した拡張された「文書順」が定義されています。 DOM XPath に対応している場合には拡張された定義に基づき結果を返さなければなりません >>5

[7] という規定が2004年の DOM XPath 仕様では compareTreePosition という現存しないメソッド名についてなされていますw
[36] でも、 >>18 の処理モデルは「文書順」の定義を使わずに規定されていますね。

異なる実装からの節点の比較

[9] DOM3 は異なる DOM の実装が混在する環境を扱っています。異なる DOM 実装からの節点の比較であっても、両実装の間で「実装規定」 となっている部分の動作について協調して決定できるのであれば、それに従った結果を返すべきであるようです。

[10] 節点が異なる DOM 実装のものであり、 「実装規定」の部分について一貫した結果となるよう協調して動作できない場合、 例外 NOT_SUPPORTED_ERR投げます>>2

実装

[41] GeckoWebKitOpera のいずれも実装しています。

[38] WinIE9 以降は IE9モードでのみ対応しています。

テスト・ケース

関連

[39] 要素の包含関係を調べるメソッドには他に contains があります。 containscompareDocumentPosition とは違って同じ要素 (自分自身) は「含んでいる」と判断します。

[40] 要素の順序は sourceIndex 属性の値の比較でも求められます。

[42] IRC logs: freenode / #whatwg / 20121015 ( ( 版)) <http://krijnhoetmer.nl/irc-logs/whatwg/20121015#l-365>

[45] Make Attr inherit from Node again (annevk著, ) <https://github.com/whatwg/dom/commit/625a0747f137454c155a7b577a9e45be1aa35a34>

[46] Further Attr node fixes for compareDocumentPosition() (annevk著, ) <https://github.com/whatwg/dom/commit/0e17e05b7b0273799b853c4782b2eac9a88fdea1>