ファイルおよびディレクトリエントリ API

共同体グループドラフト報告書

このバージョン:
https://wicg.github.io/entries-api/
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/entries-api
課題追跡:
GitHub
仕様内インライン
編集者:
(Google Inc.)

概要

この仕様は、ウェブブラウザーによるファイルおよびディレクトリのドラッグ&ドロップ操作によるアップロードのサポートを文書化しています。ディレクトリを表す型と非同期トラバーサルのためのメソッドを導入し、HTMLInputElement および DataTransferItem [HTML] を拡張します。

この文書のステータス

この仕様は Web Platform Incubator Community Group によって公開されました。 W3C標準ではなく、W3C標準化トラックにもありません。 W3C Community Contributor License Agreement (CLA) の下では限定的なオプトアウトおよびその他の条件が適用されますのでご注意ください。 W3Cコミュニティ&ビジネスグループ について詳しくは、こちらをご覧ください。

1. 目的

この仕様は、ファイルとディレクトリの階層がページにドラッグ&ドロップされたり、フォーム要素を使って選択されたり、またはそれに類するユーザー操作が行われたとき、ウェブブラウザーがスクリプトに対して利用可能にする型と操作について記述します。

これは、[file-system-api] の初期ドラフトを大きく基にしており、サンドボックス化されたファイルシステムの文脈で同様の型と、ファイルやディレクトリの作成・修正のための操作を定義していますが、ウェブブラウザーによる広範な採用には至っていません。

注: この文書で記述されているAPIは、当初Google Chromeで実装されました。他のブラウザー(現時点ではEdge、Firefox、Safari)はChromeのAPIと挙動の一部をサポートし始めています。本書の目的は、実装間の互換性を確保するため、共通部分を仕様化することです。

2. 概念

2.1. 名前とパス

名前は、次の条件を満たす文字列です:

パスセグメントは、名前、'.'(U+002E FULL STOP)、または '..'(U+002E FULL STOP, U+002E FULL STOP) のいずれかです。

相対パスは、1つ以上の パスセグメント が '/' (U+002F SOLIDUS) で結合された文字列で、先頭が '/' (U+002F SOLIDUS) で始まらないものです。

絶対パスは、'/' (U+002F SOLIDUS) の後に0個以上の パスセグメント が '/' (U+002F SOLIDUS) で結合された文字列です。

パスは、相対パスまたは絶対パスのいずれかです。

有効なパスは、USVString であり、パスであるものです。

2.2. ファイルとディレクトリ

ファイルは、バイナリデータと、名前(非空の名前)から構成されます。

ディレクトリは、名前名前)と、順序付きメンバーリストから構成されます。各メンバーはファイルまたはディレクトリのいずれかです。ディレクトリの各メンバーは、異なる非空の名前を持たなければなりません。

ルートディレクトリは、ディレクトリであり、他のディレクトリのメンバーではありません。ルートディレクトリ名前は空です。

は、ファイルまたはディレクトリの所属するディレクトリです。ルートディレクトリにはがありません。

編集上の注記: ディレクトリファイルの特殊な型として定義し、[HTML]に最小限の変更で済ませるべきか?

注: 多くの場合、ユーザーが選択したファイルとディレクトリは、APIによって「仮想ルート」に含まれているかのように提示されますが、この仮想ルートは実際のネイティブファイルシステム上には実体として存在しません。

ファイルシステムは、名前と、ルート(関連付けられたルートディレクトリ)から構成されます。ファイルシステムの名前は、USVString であり、実装依存ですが、そのファイルシステムに固有です。ルートディレクトリは、1つのファイルシステムにだけ関連付けられます。

注: 実装では、各名前を、各ファイルシステムインスタンスごとにUUIDを生成し、固定のプレフィックスやサフィックス文字列を付加するなどで作成しても構いません。API利用者は、名前の構造や内容について仮定しないことが推奨されます。

2.3. エントリ

エントリは、ファイルエントリまたはディレクトリエントリのいずれかです。

エントリは、名前名前)およびフルパス絶対パス)を持ちます。

エントリは、さらにルート(関連付けられたルートディレクトリ)を持ちます。

注: エントリは、ルートディレクトリを基準としたパスで定義されており、APIとのやりとりの背後にあるネイティブファイルシステムがディレクトリ内容の列挙などの操作中に非同期的に変更される可能性があることを考慮しています。エントリに対して公開される操作は、パスが同じエンティティを参照しなくなった場合、エラーとなります。

ファイルシステムは、エントリが関連付けられているファイルシステムであり、エントリルートに関連付けられています。

3. アルゴリズム

abspath絶対パス)と path絶対パス相対パス、または空文字列)を使って相対パスを解決するには、次の手順を実行します。これらは絶対パスを返します。

  1. path絶対パスなら、path を返す。

  2. abspath segments‘/’(U+002F SOLIDUS)で厳密分割した結果にする。

    注: 最初の文字列は空になります。

  3. path segments‘/’(U+002F SOLIDUS)で厳密分割した結果にする。

  4. path segments の各 segment について、segment で分岐:

    空文字列

    継続する。

    '.' (U+002E FULL STOP)

    継続する。

    '..' (U+002E FULL STOP, U+002E FULL STOP)

    abspath segments の最後のメンバーを削除。ただし、唯一のメンバーの場合は削除しない。

    その他

    segmentabspath segments に追加する。

  5. abspath segments を '/' (U+002F SOLIDUS) で結合して返す。

directoryルートディレクトリ)と path絶対パス)を使ってパスを評価するには、次の手順を実行します。これらはファイルディレクトリ、または失敗を返します。

  1. segments‘/’(U+002F SOLIDUS)で厳密分割した結果にする。

  2. segments の最初の要素を削除する。

    注: path絶対パスなので、最初の要素は必ず空です。

  3. segments の各 segment について、segment で分岐:

    空文字列

    継続する。

    '.' (U+002E FULL STOP)

    継続する。

    '..' (U+002E FULL STOP, U+002E FULL STOP)

    directorydirectoryにする。親がなければ directory のまま。

    その他

    次の手順を実行:

    1. item を、directory名前segment と一致するメンバーとする。見つからなければ失敗を返す。

    2. segmentsegments の最後の要素なら item を返す。

    3. itemファイルの場合は失敗を返す。

    4. directoryitem にする。

4. File インターフェース

編集上の注記: このセクションは完成後、[FileAPI]に統合するべきです。
partial interface File {
    readonly attribute USVString webkitRelativePath;
};

webkitRelativePath ゲッターの手順は、this相対パスを返すか、指定されていなければ空文字列を返します。

5. HTML:フォーム

編集上の注記: このセクションは完成後、[HTML]に統合するべきです。 エントリリストの構築などの手順には webkitRelativePath プロパティを含める必要があります。
partial interface HTMLInputElement {
    attribute boolean webkitdirectory;
    readonly attribute FrozenArray<FileSystemEntry> webkitEntries;
};

input 要素の type 属性が ファイルアップロード状態のとき、このセクションのルールが適用されます。

webkitdirectory 属性は、ユーザーがファイルやファイル群ではなくディレクトリを選択できるかどうかを示すブール属性です。指定された場合、ディレクトリが選択されると、そのディレクトリを祖先にもつすべてのファイルが選択されたかのように動作します。さらに、各webkitRelativePathプロパティは、選択されたディレクトリからファイルへの相対パス(ディレクトリ自身も含む)に設定されます。

次のディレクトリ構成の場合:
documents/
  to_upload/
    a/
      b/
        1.txt
        2.txt
      3.txt
  not_uploaded.txt

to_upload ディレクトリが選択された場合、files には以下が含まれます:

注: ユーザーエージェントは、選択操作時に任意の階層データをディレクトリとして表現できます。例えば、ネイティブファイルシステムを直接ユーザーに公開しないデバイスでは、"image/*"accept 属性に指定されていれば、写真アルバムをディレクトリとして提示することができます。

webkitRelativePath プロパティを、input要素でディレクトリ選択した後に確認する例:
<input id=b type=file webkitdirectory>
document.querySelector('#b').addEventListener('change', e => {
  for (file entry of e.target.files) {
    console.log(file.name, file.webkitRelativePath);
  }
});

webkitEntries IDL属性は、スクリプトが要素の選択されたエントリにアクセスできるようにします。取得時、このIDL属性が適用される場合は現在の選択されたファイル(ディレクトリ含む)を表すFileSystemEntryオブジェクトの配列を返さなければなりません。適用されない場合は null を返します。

webkitEntries でエントリを列挙する例:
<input id=a type=file multiple>
document.querySelector('#a').addEventListener('change', e => {
  for (const entry of e.target.webkitEntries) {
    handleEntry(entry);
  }
});
相互運用性: Chromeでは、webkitEntries はドラッグ&ドロップ操作の結果のみが設定されます。要素をクリックした場合は設定されません。常に設定されるように修正すべきでしょうか?
相互運用性: Chromeでは、webkitdirectoryHTMLInputElement に指定されている場合、webkitEntries は設定されません。ディレクトリ構造の再構築には files コレクションと webkitRelativePath プロパティを使用する必要があります。常に設定されるように修正すべきでしょうか?

6. HTML:ドラッグ&ドロップ

編集上の注記: このセクションは完成後、[HTML]に統合するべきです。

ドラッグ&ドロップ操作中、ファイルおよびディレクトリ項目はエントリに関連付けられます。各エントリは、そのルートディレクトリのメンバーであり、ドラッグデータストアに固有です。

さらに、各ディレクトリ項目は、ドラッグデータストアアイテムリスト内で、kindFileであるアイテムとして表現されます。getAsFile() でアクセスすると、長さ0のFileが返されます。

注: ユーザーエージェントは、ドラッグ&ドロップ操作中に任意の階層データをファイルやディレクトリとして表現できます。例として、アルバムのメタデータとトラックのバイナリが別テーブルに格納されたリレーショナルデータベース内の音声データが、メディアプレーヤーアプリケーションからドラッグされた際にディレクトリやファイルとしてスクリプトへ公開されることが考えられます。

partial interface DataTransferItem {
    FileSystemEntry? webkitGetAsEntry();
};

webkitGetAsEntry() メソッドの手順:

  1. storeを、thisDataTransfer オブジェクトのドラッグデータストアとする。

  2. storeドラッグデータストアモード読取/書込モードまたは読取専用モードでなければ、nullを返して手順を中止する。

  3. itemを、storeドラッグデータストアアイテムリスト内でthis が表すアイテムとする。

  4. itemkindFileでなければ、nullを返して手順を中止する。

  5. エントリを表す新しいFileSystemEntryオブジェクトを返す。

ファイルやディレクトリのドラッグ&ドロップを処理する例:
elem.addEventListener('dragover', e => {
  // ナビゲーション防止
  e.preventDefault();
});
elem.addEventListener('drop', e => {
  // ナビゲーション防止
  e.preventDefault();

  // すべてのアイテムを処理
  for (const item of e.dataTransfer.items) {
    // kindはファイル/ディレクトリエントリの場合 'file'
    if (item.kind === 'file') {
      const entry = item.webkitGetAsEntry();
      handleEntry(entry);
    }
  }
});

7. ファイルとディレクトリ

WEB互換性: レガシーのTypeMismatchError は多くの仕様でTypeErrorに置き換えられていますが、名前が異なります。ここでも切り替えて問題ないでしょうか?
callback ErrorCallback = undefined (DOMException err);

ErrorCallback 関数は、エラーが非同期で返される可能性のある操作で使用されます。

タスクソースについて、以下の手順でタスクをキューに入れる場合に定義されていません。Chromium系ブラウザーは以下を使用しているようです:

7.1. FileSystemEntry インターフェース

[Exposed=Window]
interface FileSystemEntry {
    readonly attribute boolean isFile;
    readonly attribute boolean isDirectory;
    readonly attribute USVString name;
    readonly attribute USVString fullPath;
    readonly attribute FileSystem filesystem;

    undefined getParent(optional FileSystemEntryCallback successCallback,
                   optional ErrorCallback errorCallback);
};

FileSystemEntry には関連付けられたエントリがあります。

isFileゲッターの手順は、thisファイルエントリならtrue、それ以外はfalseを返します。

isDirectoryゲッターの手順は、thisディレクトリエントリならtrue、それ以外はfalseを返します。

nameゲッターの手順は、this名前を返します。

fullPathゲッターの手順は、thisフルパスを返します。

filesystemゲッターの手順は、thisファイルシステムを返します。

getParent(successCallback, errorCallback) メソッドの手順:

  1. 並列で次の手順を実行:

    1. pathを、相対パスを解決するで、thisフルパスと'..'を使って得る。

    2. itemを、パスを評価するで、thisルートpathを使って得る。

    3. itemが失敗の場合、タスクをキューに入れることで、コールバックを呼び出すerrorCallback(指定されていれば)に« 新しく生成された "NotFoundError" DOMException »および"report"を渡し、手順を中止。

    4. entryを、item名前名前pathフルパスとする新しいディレクトリエントリとする。

    5. タスクをキューに入れることで、コールバックを呼び出すsuccessCallbackに« FileSystemDirectoryEntry オブジェクト(entryに関連付け) »および"report"を渡す。

注: FileSystemEntry 作成後にファイルがディスク上で変更されていた場合、エラーになる可能性があります。

エントリを処理する例:
function handleEntry(entry) {
  console.log('name: ' + entry.name);
  console.log('path: ' + entry.fullPath);
  if (entry.isFile) {
    console.log('... ファイルです');
  } else if (entry.isDirectory) {
    console.log('... ディレクトリです');
  }
}
getParent()Promiseで利用できるようにするヘルパー関数の例 [ECMA-262]:
function getParentAsPromise(entry) {
  return new Promise((resolve, reject) => {
    entry.getParent(resolve, reject);
  });
}

7.2. FileSystemDirectoryEntry インターフェース

[Exposed=Window]
interface FileSystemDirectoryEntry : FileSystemEntry {
    FileSystemDirectoryReader createReader();
    undefined getFile(optional USVString? path,
                 optional FileSystemFlags options = {},
                 optional FileSystemEntryCallback successCallback,
                 optional ErrorCallback errorCallback);
    undefined getDirectory(optional USVString? path,
                      optional FileSystemFlags options = {},
                      optional FileSystemEntryCallback successCallback,
                      optional ErrorCallback errorCallback);
};

dictionary FileSystemFlags {
    boolean create = false;
    boolean exclusive = false;
};

callback FileSystemEntryCallback = undefined (FileSystemEntry entry);

注: create メンバーと 関連する挙動は、既存実装との互換性のために含まれていますが、このフラグが指定されても有用な挙動はありません。同様に、exclusive メンバーは明示的に参照されていませんが、getterをもつオブジェクトが渡された場合スクリプトからbinding挙動は観測可能です。

FileSystemDirectoryEntryの関連付けられたエントリディレクトリエントリです。

createReader() メソッドの手順:

  1. 新しく作成されたFileSystemDirectoryReader オブジェクト(ディレクトリエントリに関連付け)を返す。

getFile(path, options, successCallback, errorCallback) メソッドの手順:

  1. 並列で次の手順を実行:

    1. pathが未定義またはnullなら空文字列にする。

    2. path有効なパスでなければ、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "TypeMismatchError" DOMException »および"report"を渡し、手順を中止。

    3. optionscreate メンバーがtrueなら、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "SecurityError" DOMException »および"report"を渡し、手順を中止。

    4. path相対パスを解決するで、thisフルパスpathを使って得る。

    5. itemパスを評価するで、thisルートpathを使って得る。

    6. itemが失敗の場合、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "NotFoundError" DOMException »および"report"を渡し、手順を中止。

    7. itemファイルでなければ、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "TypeMismatchError" DOMException »および"report"を渡し、手順を中止。

    8. entryitem名前名前pathフルパスとする新しいファイルエントリとする。

    9. タスクをキューに入れることでsuccessCallback(指定されていれば)に« FileSystemFileEntry オブジェクト(entryに関連付け) »および"report"を渡す。

getDirectory(path, options, successCallback, errorCallback) メソッドの手順:

  1. 並列で次の手順を実行:

    1. pathが未定義またはnullなら空文字列にする。

    2. path有効なパスでなければ、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "TypeMismatchError" DOMException »および"report"を渡し、手順を中止。

    3. optionscreate メンバーがtrueなら、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "SecurityError" DOMException »および"report"を渡し、手順を中止。

    4. path相対パスを解決するで、thisフルパスpathを使って得る。

    5. itemパスを評価するで、thisルートpathを使って得る。

    6. itemが失敗の場合、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "NotFoundError" DOMException »および"report"を渡し、手順を中止。

    7. itemディレクトリでなければ、コールバックを呼び出すことでerrorCallback(指定されていれば)に« 新しく生成された "TypeMismatchError" DOMException »および"report"を渡し、手順を中止。

    8. entryitem名前名前pathフルパスとする新しいディレクトリエントリとする。

    9. タスクをキューに入れることでsuccessCallback(指定されていれば)に« FileSystemDirectoryEntry オブジェクト(entryに関連付け) »および"report"を渡す。

getFile() および getDirectory()Promiseで利用できるようにするヘルパー関数の例 [ECMA-262]:
function getFileAsPromise(entry, path) {
  return new Promise((resolve, reject) => {
    entry.getFile(path, {}, resolve, reject);
  });
}
function getDirectoryAsPromise(entry, path) {
  return new Promise((resolve, reject) => {
    entry.getDirectory(path, {}, resolve, reject);
  });
}

7.3. FileSystemDirectoryReader インターフェース

[Exposed=Window]
interface FileSystemDirectoryReader {
    undefined readEntries(FileSystemEntriesCallback successCallback,
                     optional ErrorCallback errorCallback);
};
callback FileSystemEntriesCallback = undefined (sequence<FileSystemEntry> entries);
FileSystemDirectoryReader には、 関連付けられた エントリディレクトリエントリ)、 関連付けられた ディレクトリ(初期値はnull)、 読み込みフラグ(初期値はfalse)、 完了フラグ(初期値はfalse)、 リーダーエラー(初期値はnull)があります。

readEntries(successCallback, errorCallback) メソッドの手順:

  1. this読み込みフラグがtrueなら、タスクをキューに入れることでerrorCallbackに« 新しく 生成された "InvalidStateError" DOMException »および"report"を渡し、手順を中止。

  2. thisリーダーエラーがnullでない場合、タスクをキューに入れることでerrorCallback(指定されていれば)に« リーダーエラー »および"report"を渡し、手順を中止。

  3. this完了フラグがtrueなら、タスクをキューに入れることでsuccessCallbackに空のリストおよび"report"を渡し、手順を中止。

  4. this読み込みフラグをtrueに設定する。

  5. 並列で次の手順を実行:

    1. thisディレクトリがnullなら:

      1. dirパスを評価するthisエントリルートおよびフルパスで得る。

      2. dirが失敗の場合:

        1. タスクをキューに入れることで次の手順を実行:

          1. errorを新しく生成された "NotFoundError" DOMExceptionとする。

          2. thisリーダーエラーerrorに設定。

          3. this読み込みフラグをfalseに設定。

          4. コールバックを呼び出すことでerrorCallback(指定されていれば)に« error »および"report"を渡す。

        2. 手順を中止。

      3. thisディレクトリdirに設定する。

    2. entriesを、thisディレクトリから、このFileSystemDirectoryReaderでまだ返されていない非ゼロ件のエントリ(もしあれば)を取得。

    3. 前の手順が失敗した場合(例:ディレクトリが削除された、または権限が拒否された場合):

      1. タスクをキューに入れることで次の手順を実行:

        1. errorを適切なDOMExceptionとする。

        2. thisリーダーエラーerrorに設定。

        3. this読み込みフラグをfalseに設定。

        4. コールバックを呼び出すことでerrorCallback(指定されていれば)に« error »および"report"を渡す。

      2. 手順を中止。

    4. タスクをキューに入れることで次の手順を実行:

      1. entriesが空なら、this完了フラグをtrueに設定。

      2. this読み込みフラグをfalseに設定。

      3. コールバックを呼び出すことでsuccessCallbackに« entries »および"report"を渡す。

注: 読み込みフラグを利用することで、上記の並列手順が同時に複数実行されるのを防いでいます。これにより並列キューの指定が不要となります。

ディレクトリを列挙する例:
const reader = dirEntry.createReader();
const doBatch = () => {

  // バッチを読む
  reader.readEntries(entries => {

    // 完了?
    if (entries.length === 0) {
      return;
    }

    // バッチを処理
    entries.forEach(handleEntry);

    // 次のバッチを読む
    doBatch();

  }, error => console.warn(error));
};

// 読み取り開始
doBatch();
FileSystemDirectoryReaderPromiseで利用できるようにするヘルパー関数の例 [ECMA-262]:
function getEntriesAsPromise(dirEntry) {
  return new Promise((resolve, reject) => {
    const result = [];
    const reader = dirEntry.createReader();
    const doBatch = () => {
      reader.readEntries(entries => {
        if (entries.length > 0) {
          entries.forEach(e => result.push(e));
          doBatch();
        } else { 
          resolve(result);
        }
      }, reject);
    };
    doBatch();
  });
}
FileSystemDirectoryReaderAsyncIteratorで利用できるようにするヘルパー関数の例 [ECMA-262]:
async function* getEntriesAsAsyncIterator(dirEntry) {
  const reader = dirEntry.createReader();
  const getNextBatch = () => new Promise((resolve, reject) => {
    reader.readEntries(resolve, reject);
  });

  let entries;
  do { 
    entries = await getNextBatch();
    for (const entry of entries) {
      yield entry;
    }
  } while (entries.length > 0);
}

これによりfor-await-ofでディレクトリツリーを順序付き非同期でトラバースできます:

async function show(entry) {
  console.log(entry.fullPath);
  if (entry.isDirectory) {
    for await (const e of getEntriesAsAsyncIterator(entry)) {
      await show(e);
    }
  }
}

7.4. FileSystemFileEntry インターフェース

[Exposed=Window]
interface FileSystemFileEntry : FileSystemEntry {
    undefined file(FileCallback successCallback,
              optional ErrorCallback errorCallback);
};
callback FileCallback = undefined (File file);

FileSystemFileEntryの関連付けられたエントリファイルエントリです。

file(successCallback, errorCallback) メソッドの手順:

  1. 並列で次の手順を実行:

    1. itemパスを評価するthisルートフルパスで得る。

    2. itemが失敗の場合、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "NotFoundError" DOMException »および"report"を渡し、手順を中止。

    3. itemディレクトリの場合、タスクをキューに入れることでerrorCallback(指定されていれば)に« 新しく生成された "TypeMismatchError" DOMException »および"report"を渡し、手順を中止。

    4. タスクをキューに入れることでsuccessCallbackに« File オブジェクト(itemを表す) »および"report"を渡す。

FileReaderでドロップされたファイルの内容を読む例:
function readFileEntry(entry) {
  entry.file(file => {
    const reader = new FileReader();
    reader.readAsText(file);
    reader.onerror = error => console.warn(error);
    reader.onload = () => {
      console.log(reader.result);
    };
  }, error => console.warn(error));
}
file()Promiseで利用できるようにするヘルパー関数の例 [ECMA-262]:
function fileAsPromise(entry) {
  return new Promise((resolve, reject) => {
    entry.file(resolve, reject);
  });
}

7.5. FileSystem インターフェース

[Exposed=Window]
interface FileSystem {
    readonly attribute USVString name;
    readonly attribute FileSystemDirectoryEntry root;
};

FileSystem には関連付けられたファイルシステムがあります。

nameゲッターの手順は、this名前を返します。

rootゲッターの手順は、FileSystemDirectoryEntrythisルートに関連付け)が返されます。

8. 謝辞

この仕様は、[file-system-api]におけるEric Uhrhane氏の成果に大きく基づいており、そこでFileSystemEntry 型が導入されました。

仕様作成ツールBikeshedを作成・管理してくださったTab Atkins, Jr.氏に感謝します。

そして Ali Alabbas氏、 Philip Jägenstedt氏、 Marijn Kruisselbrink氏、 Olli Pettay氏、 Kent Tamura氏 にご提案・レビュー・その他のフィードバックをいただき、感謝します。

適合性

文書上の規約

適合性の要件は、記述的な断定とRFC 2119の用語の組み合わせで表現されています。 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、 “MAY”、“OPTIONAL”というキーワードは、 本文の規範的な部分でRFC 2119の定義通りに解釈されます。 ただし、読みやすさのために、本仕様ではこれらの語句はすべて大文字で表記されていません。

本仕様の本文は、明示的に非規範的と示されたセクション、例、および注記を除き、すべて規範的です。[RFC2119]

本仕様中の例は「例えば」で始まるか、class="example"として 規範的な本文から区別して示されます。例えば以下のようになります:

これは情報提供的な例です。

情報提供的な注記は「注記」で始まり、class="note"として 規範的な本文から区別して示されます。例えば以下のようになります:

注記: これは情報提供的な注記です。

索引

本仕様で定義されている用語

参照で定義されている用語

参考文献

規範的参考文献

[FileAPI]
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML Standard. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 現行標準. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. ベストカレントプラクティス. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 現行標準. URL: https://webidl.spec.whatwg.org/

参考情報

[ECMA-262]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FILE-SYSTEM-API]
Eric Uhrhane. File API: Directories and System. URL: https://dev.w3.org/2009/dap/file-system/file-dir-sys.html

IDL索引

partial interface File {
    readonly attribute USVString webkitRelativePath;
};

partial interface HTMLInputElement {
    attribute boolean webkitdirectory;
    readonly attribute FrozenArray<FileSystemEntry> webkitEntries;
};

partial interface DataTransferItem {
    FileSystemEntry? webkitGetAsEntry();
};

callback ErrorCallback = undefined (DOMException err);

[Exposed=Window]
interface FileSystemEntry {
    readonly attribute boolean isFile;
    readonly attribute boolean isDirectory;
    readonly attribute USVString name;
    readonly attribute USVString fullPath;
    readonly attribute FileSystem filesystem;

    undefined getParent(optional FileSystemEntryCallback successCallback,
                   optional ErrorCallback errorCallback);
};

[Exposed=Window]
interface FileSystemDirectoryEntry : FileSystemEntry {
    FileSystemDirectoryReader createReader();
    undefined getFile(optional USVString? path,
                 optional FileSystemFlags options = {},
                 optional FileSystemEntryCallback successCallback,
                 optional ErrorCallback errorCallback);
    undefined getDirectory(optional USVString? path,
                      optional FileSystemFlags options = {},
                      optional FileSystemEntryCallback successCallback,
                      optional ErrorCallback errorCallback);
};

dictionary FileSystemFlags {
    boolean create = false;
    boolean exclusive = false;
};

callback FileSystemEntryCallback = undefined (FileSystemEntry entry);

[Exposed=Window]
interface FileSystemDirectoryReader {
    undefined readEntries(FileSystemEntriesCallback successCallback,
                     optional ErrorCallback errorCallback);
};
callback FileSystemEntriesCallback = undefined (sequence<FileSystemEntry> entries);

[Exposed=Window]
interface FileSystemFileEntry : FileSystemEntry {
    undefined file(FileCallback successCallback,
              optional ErrorCallback errorCallback);
};
callback FileCallback = undefined (File file);

[Exposed=Window]
interface FileSystem {
    readonly attribute USVString name;
    readonly attribute FileSystemDirectoryEntry root;
};

課題インデックス

編集上の注記: ディレクトリファイルの特殊な型として定義し、[HTML]への変更を最小限にすべきか?
編集上の注記: このセクションは完成後、[FileAPI]に統合するべきです。
編集上の注記: このセクションは完成後、[HTML]に統合するべきです。 エントリリストの構築のような手順にwebkitRelativePath プロパティを含める必要があります。
相互運用性: Chromeでは、webkitEntries はドラッグ&ドロップ操作の結果のみ設定され、要素をクリックして選択した場合は設定されません。常に設定されるように修正すべきでしょうか?
相互運用性: Chromeでは、webkitdirectoryHTMLInputElement に指定されている場合、webkitEntries は設定されません。ディレクトリ構造の再構築には files コレクションと webkitRelativePath プロパティを使用する必要があります。常に設定されるように修正すべきでしょうか?
編集上の注記: このセクションは完成後、[HTML]に統合するべきです。
WEB互換性: レガシーのTypeMismatchError は多くの仕様でTypeErrorに置き換えられていますが、名称が異なります。ここでも切り替えて問題ないでしょうか?
タスクソースについて、以下の手順でタスクをキューに入れる場合に定義されていません。Chromium系ブラウザーでは以下を使用しているようです:
MDN

DataTransferItem/webkitGetAsEntry

In all current engines.

Firefox50+Safari11.1+Chrome13+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for AndroidNoneiOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

File/webkitRelativePath

In all current engines.

Firefox50+Safari11.1+Chrome13+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystem/name

In all current engines.

Firefox50+Safari11.1+Chrome7+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystem/root

In all current engines.

Firefox50+Safari11.1+Chrome7+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystem

In all current engines.

Firefox50+Safari11.1+Chrome7+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemDirectoryEntry/createReader

In all current engines.

Firefox50+Safari11.1+Chrome13+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemDirectoryEntry/getDirectory

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemDirectoryEntry/getFile

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemDirectoryEntry

In all current engines.

Firefox50+Safari11.1+Chrome8+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemDirectoryReader/readEntries

In all current engines.

Firefox50+Safari11.1+Chrome8+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemDirectoryReader

In all current engines.

Firefox50+Safari11.1+Chrome8+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry/filesystem

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry/fullPath

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry/getParent

In all current engines.

Firefox52+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry/isDirectory

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry/isFile

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry/name

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemEntry

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemFileEntry/file

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

FileSystemFileEntry

In all current engines.

Firefox50+Safari11.1+Chrome8+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
MDN

HTMLInputElement/webkitdirectory

In all current engines.

Firefox50+Safari11.1+Chrome7+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for AndroidNoneiOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

HTMLInputElement/webkitEntries

In all current engines.

Firefox50+Safari11.1+Chrome22+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for AndroidNoneiOS Safari?Chrome for Android?Android WebViewNoneSamsung Internet?Opera Mobile?