제어된 프레임 API

커뮤니티 그룹 보고서 초안,

이 버전:
https://wicg.github.io/controlled-frame/
이슈 추적:
GitHub
명세 내 인라인
편집자:
(Google LLC)
(Google LLC)
(Google LLC)

초록

이 문서는 임의의 웹 콘텐츠를 격리된 웹 애플리케이션(IWA)의 컨텍스트 안에서만 삽입하기 위한 API를 정의한다. 삽입된 콘텐츠는 삽입자 안에 있으며 삽입자에 의해 제어되는 새로운 최상위 탐색 컨텍스트이다.

이 문서의 상태

이 명세는 Web Platform Incubator Community Group에서 발행했다. 이는 W3C 표준이 아니며 W3C 표준 트랙에 있지도 않다. W3C Community Contributor License Agreement (CLA)에 따라 제한적인 옵트아웃 및 기타 조건이 적용된다는 점에 유의하라. W3C Community and Business Groups에 대해 더 알아보기.

1. 소개

이 명세는 IWA의 몇 가지 중요한 사용 사례를 충족하는 콘텐츠 삽입 API를 설명하며, iframe은 이를 지원하지 않는다. 이 삽입 환경은 삽입된 사이트의 명시적 허가 없이 모든 콘텐츠를 삽입할 수 있어야 하며, 여기에는 iframe이 삽입할 수 없는 콘텐츠도 포함되고, 삽입하는 사이트가 해당 삽입 콘텐츠를 더 많이 제어할 수 있어야 한다.

이는 특히 강력한 API이므로, 이를 사용하고 사용할 수 있게 되면 앱은 다양한 유형의 해킹 대상이 된다. 그 결과 이 API는 사용자와 개발자를 보호하기 위한 추가 보호 장치가 마련된 격리된 웹 애플리케이션(IWA)에서의 사용으로 제한된다. IWA는 일반적인 웹 애플리케이션이 아니며 특별한 'isolated-app:' 스킴에서만 존재할 수 있다. 이는 설계상 이 API가 일반 웹 페이지에서는 사용할 수 없다는 것을 의미한다.

참고: 이 API는 iframe을 대체하거나 대신하기 위한 것이 아니다. 모든 iframe 사용 사례는 여전히 유효하며, 가능한 경우 IWA를 포함하여 iframe을 계속 사용해야 한다.

2. Fenced Frame 명세

편의를 위해 Controlled Frame 명세는 Fenced Frame 명세가 마련되어 있다고 가정한다. Fenced Frame 명세에서 도입된 개념들, 예를 들어 중첩된 최상위 traversable 같은 것은 Controlled Frame의 컨텍스트에서 참조하기에 폭넓게 유용하다.

Fenced Frame 명세는 HTML 같은 일부 명세를 몽키 패치하여 이러한 개념들을 정의한다. 이 Controlled Frame 명세의 일부 부분에서도 명세에 대한 몽키 패치가 필요하다.

3. controlledframe 요소

카테고리:
플로우 콘텐츠.
구문 콘텐츠.
삽입 콘텐츠.
상호작용 콘텐츠.
감지 가능한 콘텐츠.
이 요소를 사용할 수 있는 컨텍스트:
삽입 콘텐츠가 예상되는 곳.
콘텐츠 모델:
없음.
콘텐츠 속성:
전역 속성
src — 삽입할 콘텐츠 소스 URL
partition — 이 콘텐츠와 관련된 데이터를 보관할 파티션 이름
접근성 고려 사항:
작성자를 위한 것.
구현자를 위한 것.

참고: 이 링크들은 iframe 요소의 접근성 정의로 연결된다. 접근성 관점에서 controlledframe은 iframe과 동일하게 동작해야 한다.

DOM 인터페이스:
[Exposed=Window, IsolatedContext]
interface HTMLControlledFrameElement : HTMLElement {
    [HTMLConstructor] constructor();

    [CEReactions] attribute USVString src;
    attribute DOMString partition;

    readonly attribute WindowProxy? contentWindow;
    readonly attribute ContextMenus contextMenus;
    readonly attribute WebRequest request;

    // Navigation methods.
    Promise<boolean> back();
    Promise<boolean> canGoBack();
    Promise<boolean> forward();
    Promise<boolean> canGoForward();
    Promise<boolean> go(long relativeIndex);
    undefined reload();
    undefined stop();

    // Scripting methods.
    Promise<undefined> addContentScripts(sequence<ContentScriptDetails> contentScriptList);
    Promise<any> executeScript(optional InjectDetails details = {});
    Promise<undefined> insertCSS(optional InjectDetails details = {});
    Promise<undefined> removeContentScripts(optional sequence<DOMString> scriptNameList);

    // Configuration methods.
    Promise<undefined> clearData(
      optional ClearDataOptions options = {},
      optional ClearDataTypeSet types = {});
    Promise<boolean> getAudioState();
    Promise<long> getZoom();
    Promise<DOMString> getZoomMode();
    Promise<boolean> isAudioMuted();
    undefined setAudioMuted(boolean mute);
    Promise<undefined> setZoom(long zoomFactor);
    Promise<undefined> setZoomMode(DOMString zoomMode);

    // Capture methods.
    Promise<undefined> captureVisibleRegion(optional ImageDetails options = {});
    undefined print();

    // Events.
    attribute EventHandler onconsolemessage;
    attribute EventHandler oncontentload;
    attribute EventHandler ondialog;
    attribute EventHandler onloadabort;
    attribute EventHandler onloadcommit;
    attribute EventHandler onloadstart;
    attribute EventHandler onloadstop;
    attribute EventHandler onnewwindow;
    attribute EventHandler onpermissionrequest;
    attribute EventHandler onsizechanged;
    attribute EventHandler onzoomchange;
};

controlledframe 요소는 자신의 삽입된 navigable을 나타낸다.

controlledframe 요소의 자손은 아무것도 나타내지 않는다.

Controlled Frame 요소는 "controlled-frame" 정책 제어 기능을 가진 모든 Document에 노출되며, 그 환경 설정 객체는 격리된 컨텍스트여야 한다.

IDL 속성 src와 partition은 같은 이름의 해당 콘텐츠 속성을 반영해야 한다.

각 controlledframe은 다음을 연결하여 가진다.

contentWindow getter 단계는 this의 contentWindow를 반환하는 것이다.

request getter 단계는 this의 request를 반환하는 것이다.

contextMenus getter 단계는 this의 contextMenus를 반환하는 것이다.

controlledframe 요소 element가 null이 아닌 탐색 컨텍스트를 가진 문서에 삽입될 때, 다음 단계를 실행한다.
  1. element의 src가 비어 있지 않으면, 다음을 실행한다.

    1. element가 주어졌을 때 controlledframe을 초기화한다.

controlledframe 요소 element가 문서에서 제거될 때, 다음 단계를 실행한다.
  1. element의 삽입된 navigable이 주어졌을 때 최상위 traversable을 파괴한다.

  2. element의 삽입된 navigable을 null로 설정한다.

controlledframe 요소 element를 초기화하려면, 다음 단계를 실행한다.
  1. element의 삽입된 navigable이 null임을 단언한다.

  2. group을 새 탐색 컨텍스트 그룹으로 둔다.

  3. document를 element의 노드 문서, element, group이 주어졌을 때 새 탐색 컨텍스트와 문서를 생성한 결과의 두 번째 반환값으로 둔다.

  4. documentState를 새 문서 상태로 두며, 그 문서는 document이다.

  5. traversable을 새 traversable navigable로 둔다.

  6. documentState가 주어졌을 때 traversable navigable을 초기화한다.

  7. traversable의 controlledFrameEmbedderParent를 element로 설정한다.

  8. element의 삽입된 navigable을 traversable로 설정한다.

  9. initialHistoryEntry를 traversable의 활성 세션 기록 항목으로 둔다.

  10. initialHistoryEntry의 step을 0으로 설정한다.

  11. initialHistoryEntry를 traversable의 세션 기록 항목에 추가한다.

    이 단계는 새 navigable 안에서 History.length를 초기화하는 데 필요하다. 이는 HTML Standard에 있는 기존 이슈이다.

  12. element의 contentWindow를 document의 WindowProxy로 설정한다.

  13. element와 element의 src가 주어졌을 때 controlledframe을 탐색한다.

controlledframe 요소 element를 USVString urlString이 주어졌을 때 탐색하려면, 다음 단계를 실행한다.
  1. urlString이 absolute-URL 문자열이 아니면 반환한다.

  2. url을 urlString과 element의 노드 문서가 주어졌을 때 URL을 파싱한 결과로 둔다.

  3. historyHandling을 "auto"로 둔다.

  4. element의 삽입된 navigable의 활성 문서가 완전히 로드됨이 아니면, historyHandling을 "replace"로 설정한다.

  5. element의 삽입된 navigable을 url로 탐색한다. 이때 element의 노드 문서를 사용하고, NavigationHistoryBehavior는 historyHandling이다.

HTMLControlledFrameElement() 생성자 단계는 다음과 같다.
  1. this의 request를 WebRequest의 새 인스턴스로 설정한다.

  2. this의 contextMenus를 ContextMenus의 새 인스턴스로 설정한다.

3.1. 공통 인프라

controlledframe controlledframe, promise promise, 선택적인 value가 주어졌을 때, 삽입자의 promise를 resolve하려면 다음 단계를 실행한다.
  1. controlledframe의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, promise를 value로 resolve한다.

    참고: controlledframe의 관련 전역 객체는 삽입자의 Window 객체이다.

controlledframe controlledframe, promise promise, 선택적인 value가 주어졌을 때, 삽입자의 promise를 reject하려면 다음 단계를 실행한다.
  1. controlledframe의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, promise를 value로 reject한다.

    참고: controlledframe의 관련 전역 객체는 삽입자의 Window 객체이다.

URL url은 다음 단계가 true를 반환하는 경우 pattern인 URLPattern과 일치한다.
  1. result를 pattern과 url이 주어졌을 때 match의 결과로 둔다.

  2. result가 null이면 false를 반환한다.

  3. true를 반환한다.

3.2. 속성

partition 속성은 Controlled Frame의 인스턴스와 관련된 데이터를 어디에 저장할지 지정하는 식별자를 취한다. 식별자는 영숫자 문자로 된 문자열로 구성된다. 삽입된 navigable의 모든 데이터는 이 파티션 문자열과 데이터를 만든 출처를 함께 키로 하는 저장소 선반에 저장되어야 한다.

기본적으로 저장된 모든 데이터는 메모리 내 저장소 파티션에 보관되어야 하며, 주어진 partition 값을 가진 마지막 Controlled Frame 요소가 파괴될 때 데이터도 파괴되도록 해야 한다. 데이터가 이 파티션에 보관되는 동안에는 Controlled Frame의 삽입된 navigable에서 온 어떤 데이터도 지속되어서는 안 된다.

partition 속성 식별자가 "persist:" 접두사를 포함하면, 사용자 에이전트는 메모리 내 저장소 파티션이 아니라 디스크 기반 저장소 환경을 사용해야 한다. 삽입된 콘텐츠는 자신의 저장소가 메모리 내인지 영속적인지 감지할 수 없어야 한다.

여러 Controlled Frame이 같은 파티션 식별자를 공유하면, 그들의 모든 삽입된 navigable 인스턴스는 같은 저장소 파티션을 공유해야 한다.

참고: 아래에서는 partition 속성의 값을 기반으로 저장소를 파티션화하기 위해 [STORAGE] 명세를 몽키 패치한다.

partition IDL 속성 setter 단계는 다음과 같다.
  1. this의 삽입된 navigable이 null이 아니면, 다음을 실행한다.

    1. "NotSupportedError" DOMException을 던진다.

  2. this의 partition을 주어진 값으로 설정한다.

src 속성은 Controlled Frame의 삽입된 navigable의 현재 세션 기록 항목의 URL을 반영한다.

src IDL 속성 setter 단계는 다음과 같다.
  1. this가 문서 트리 안에 있지 않으면 반환한다.

  2. this의 삽입된 navigable이 null이면, 다음을 실행한다.

    1. this가 주어졌을 때 controlledframe을 초기화한다.

  3. 그렇지 않으면, 다음을 실행한다.

    1. this와 주어진 값이 주어졌을 때 controlledframe을 탐색한다.

3.3. 탐색 메서드

back()

Controlled Frame 안의 traversable navigable에 대한 전체 세션 기록 항목 목록에서 한 단계 뒤로 간다.

페이지가 성공적으로 뒤로 탐색되면 true로 resolve되는 promise를 반환하고, 탐색이 실패했거나 이전 단계가 없으면 false로 resolve된다.

canGoBack()

현재 세션 기록 항목이 삽입된 navigable의 세션 기록 항목 중 첫 번째가 아니면 true로 resolve되는 promise를 반환한다. 이는 navigable에 대한 이전 세션 기록 항목이 있음을 의미한다.

forward()

Controlled Frame 안의 traversable navigable에 대한 전체 세션 기록 항목 목록에서 한 단계 앞으로 간다.

페이지가 성공적으로 앞으로 탐색되면 true로 resolve되는 promise를 반환하고, 탐색이 실패했거나 다음 단계가 없으면 false로 resolve된다.

canGoForward()

현재 세션 기록 항목이 삽입된 navigable의 세션 기록 항목 중 마지막이 아니면 true로 resolve되는 promise를 반환한다. 이는 navigable에 대한 다음 세션 기록 항목이 있음을 의미한다.

go()

현재 페이지를 다시 로드한다.

go(relativeIndex)

현재 traversable navigable에 대한 전체 세션 기록 항목 목록에서 relativeIndex 단계 수만큼 뒤로 또는 앞으로 간다.

상대 인덱스가 0이면 현재 페이지를 다시 로드한다.

페이지가 성공적으로 탐색되면 true로 resolve되는 promise를 반환하고, 탐색이 실패했거나 제공된 상대 인덱스가 범위를 벗어나면 false로 resolve된다.

reload()

현재 페이지를 다시 로드한다.

stop()

문서 로드를 취소한다.

controlledframe controlledframe와 정수 delta가 주어졌을 때, 삽입된 navigable의 기록을 delta만큼 순회하려면, 다음 단계를 실행한다.
  1. resultPromise를 새 promise로 둔다.

  2. resultPromise를 반환하고, 나머지 단계는 병렬로 실행한다.

  3. embeddedNavigable을 controlledframe의 삽입된 navigable로 둔다.

  4. embeddedNavigable이 null이면, controlledframe, resultPromise, false가 주어졌을 때 삽입자의 promise를 resolve하고, 이 단계를 중단한다.

  5. embeddedNavigable의 활성 문서가 완전히 활성이 아니면, controlledframe, resultPromise, false가 주어졌을 때 삽입자의 promise를 resolve하고, 이 단계를 중단한다.

  6. embeddedNavigable에 다음 세션 기록 순회 단계를 추가한다.

    1. allSteps를 embeddedNavigable에 대해 모든 사용된 기록 단계를 가져온 결과로 둔다.

    2. currentStepIndex를 allSteps 안에서 embeddedNavigable의 현재 세션 기록 단계의 인덱스로 둔다.

    3. targetStepIndex를 currentStepIndex + delta로 둔다.

    4. allSteps[targetStepIndex]가 존재하지 않으면, controlledframe, resultPromise, false가 주어졌을 때 삽입자의 promise를 resolve하고, 이 단계를 중단한다.

    5. result를 사용자 탐색 관여 "none"이 주어졌을 때 embeddedNavigable에 allSteps[targetStepIndex] 순회 기록 단계를 적용한 결과로 둔다.

    6. result가 "applied"와 같지 않으면, controlledframe, resultPromise, false가 주어졌을 때 삽입자의 promise를 resolve한다.

    7. 그렇지 않으면, controlledframe, resultPromise, true가 주어졌을 때 삽입자의 promise를 resolve한다.

canGoBack() 메서드 단계는 다음과 같다.
  1. result를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. embeddedNavigable를 controlledframe의 삽입된 navigable로 둔다.

  4. embeddedNavigable이 null이면, result를 false로 resolve하고 result를 반환한다.

  5. embeddedNavigable의 노드 문서의 관련 전역 객체의 탐색 및 순회 태스크 소스에 전역 태스크를 큐에 추가하며, 이는 다음 단계를 실행한다.

    1. canGoBack을 embeddedNavigable의 현재 세션 기록 단계가 0보다 크면 true로, 그렇지 않으면 false로 둔다.

    2. controlledframe, result, canGoBack가 주어졌을 때 삽입자의 promise를 Resolve한다.

  6. result를 반환한다.

canGoForward() 메서드 단계는 다음과 같다.
  1. result를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. embeddedNavigable를 controlledframe의 삽입된 navigable로 둔다.

  4. embeddedNavigable이 null이면, result를 false로 resolve하고 result를 반환한다.

  5. embeddedNavigable의 노드 문서의 관련 전역 객체의 탐색 및 순회 태스크 소스에 전역 태스크를 큐에 추가하며, 이는 다음 단계를 실행한다.

    1. step을 embeddedNavigable의 현재 세션 기록 단계로 둔다.

    2. steps를 embeddedNavigable가 주어졌을 때 모든 사용된 기록 단계를 가져온 결과로 둔다.

    3. canGoForward를 step + 1 < steps의 크기이면 true로, 그렇지 않으면 false로 둔다.

    4. controlledframe, result, canGoForward가 주어졌을 때 삽입자의 promise를 Resolve한다.

  6. result를 반환한다.

back() 메서드 단계는 다음과 같다.
  1. this와 -1이 주어졌을 때 삽입된 navigable의 기록을 delta만큼 순회한 결과를 반환한다.

forward() 메서드 단계는 다음과 같다.
  1. this와 1이 주어졌을 때 삽입된 navigable의 기록을 delta만큼 순회한 결과를 반환한다.

go(relativeIndex) 메서드 단계는 다음과 같다.
  1. this와 relativeIndex가 주어졌을 때 삽입된 navigable의 기록을 delta만큼 순회한 결과를 반환한다.

reload() 단계는 다음과 같다.
  1. embeddedNavigable을 this의 삽입된 navigable로 둔다.

  2. embeddedNavigable이 null이면 반환한다.

  3. embeddedNavigable의 노드 문서의 관련 전역 객체의 탐색 및 순회 태스크 소스에 전역 태스크를 큐에 추가하며, 이는 사용자 탐색 관여 "none"이 주어졌을 때 embeddedNavigable을 다시 로드한다.

stop() 단계는 다음과 같다.
  1. embeddedNavigable을 this의 삽입된 navigable로 둔다.

  2. embeddedNavigable이 null이면 반환한다.

  3. embeddedNavigable의 노드 문서의 관련 전역 객체의 탐색 및 순회 태스크 소스에 전역 태스크를 큐에 추가하며, 이는 embeddedNavigable의 로드를 중지한다.

3.4. 스크립팅 메서드

// One of |code| or |file| must be specified but not both.
dictionary InjectDetails {
  DOMString code;
  USVString file;
};

dictionary InjectionItems {
  DOMString code;
  sequence<USVString> files;
};

enum RunAt {
  "document-start",
  "document-end",
  "document-idle",
};

dictionary ContentScriptDetails {
  required DOMString name;
  InjectionItems js;
  InjectionItems css;
  required sequence<(URLPattern or URLPatternInput)> urlPatterns;
  sequence<(URLPattern or URLPatternInput)> excludeURLPatterns;
  boolean allFrames;
  boolean matchAboutBlank;
  RunAt runAt;
};

콘텐츠 스크립트 구성은 다음 항목을 가진 구조체이다.

pendingFetchCount

대기 중인 스크립트/스타일 가져오기 수를 나타내는 long.

js

문서에 삽입될 JavaScript를 포함하는 DOMString의 목록.

css

문서에 삽입될 CSS를 포함하는 DOMString의 목록.

urlPatterns

URLPattern의 목록.

참고: 문서의 URL이 이러한 패턴 중 하나와 일치하면 콘텐츠가 문서에 삽입될 수 있다.

excludeURLPatterns

URLPattern의 목록.

참고: 문서의 URL이 이러한 패턴 중 하나와 일치하면, 콘텐츠는 문서에 삽입되지 않는다. 이는 urlPattern을 재정의한다. 두 목록 모두 문서의 URL이 일치하는 항목을 가지고 있으면, 콘텐츠는 문서에 삽입되지 않는다.

allFrames

콘텐츠를 페이지의 모든 프레임에 삽입해야 하는지, 아니면 최상위 프레임에만 삽입해야 하는지를 나타내는 boolean.

matchAboutBlank

콘텐츠를 about:blank 페이지에 삽입해야 하는지를 나타내는 boolean.

runAt

JavaScript 콘텐츠가 문서의 수명주기 중 언제 실행되어야 하는지를 나타내는 RunAt.

controlledframe controlledframe, USVString urlString, boolean isCss, long index, 그리고 long, boolean, DOMString을 받는 알고리즘 completionSteps가 주어졌을 때 삽입 항목을 가져오려면, 다음 단계를 실행한다.

참고: 여기서는 클래식 스크립트를 가져오기를 사용할 수 없다. 가져오기가 controlledframe의 관련 설정 객체를 사용해야 하지만, 클래식 스크립트는 삽입된 navigable의 활성 문서의 관련 설정 객체를 사용하여 실행되기 때문이다.

  1. urlString이 유효한 URL 문자열이 아니면, 다음을 실행한다.

    1. 0, false, ""가 주어졌을 때 completionSteps를 실행한다.

    2. 반환한다.

  2. request를 다음 필드를 가진 새 요청으로 둔다.

    URL

    urlString과 controlledframe의 노드 문서가 주어졌을 때 URL을 파싱한 결과.

    method

    "GET"

    destination

    isCss가 true이면 "style", 그렇지 않으면 "script"

    client

    controlledframe의 관련 설정 객체

    mode

    "cors"

  3. request를 가져온다. 이때 processResponseConsumeBody는 응답 response와 null, failure 또는 바이트 시퀀스 contents가 주어졌을 때 다음 단계로 설정된다.

    1. response의 상태가 200이 아니거나, contents가 null 또는 failure이면, 0, false, ""가 주어졌을 때 completionSteps를 실행한다.

    2. 그렇지 않으면, index, true, contents가 주어졌을 때 completionSteps를 실행한다.

controlledframe controlledframe와 ContentScriptDetails details가 주어졌을 때 ContentScriptDetails를 검증하고 resolve하려면, 다음 단계를 실행한다.
  1. result를 새 promise로 둔다.

  2. details["js"]와 details["css"]가 둘 다 정의되어 있거나, 둘 다 정의되어 있지 않으면, result를 TypeError로 reject하고 이를 반환한다.

  3. details["urlPatterns"]가 비어 있으면, result를 TypeError로 reject하고 이를 반환한다.

  4. isCss를 details["css"]가 정의되어 있으면 true, 그렇지 않으면 false와 같은 boolean으로 둔다.

  5. isCss가 true이고 details["runAt"]가 "document-start"와 같지 않으면, result를 TypeError로 reject하고 이를 반환한다.

  6. injectionItems를 isCss가 true이면 details["css"]로, 그렇지 않으면 details["js"]로 둔다.

  7. injectionItems["code"]와 injectionItems["files"]가 둘 다 정의되어 있거나, 둘 다 정의되어 있지 않으면, result를 TypeError로 reject하고 이를 반환한다.

  8. result를 반환하고, 나머지 단계를 병렬로 실행한다.

  9. config를 다음 값을 가진 새 콘텐츠 스크립트 구성으로 둔다.

    pendingFetchCount

    0

    urlPatterns

    «»

    excludeURLPatterns

    «»

    allFrames

    정의되어 있으면 details["allFrames"], 그렇지 않으면 false

    matchAboutBlank

    정의되어 있으면 details["matchAboutBlank"], 그렇지 않으면 false

    runAt

    정의되어 있으면 details["runAt"], 그렇지 않으면 document-idle

  10. details["urlPatterns"]의 각 urlPattern에 대해:

    1. urlPattern이 URLPattern이면, urlPattern을 config의 urlPatterns에 추가한다.

    2. 그렇지 않으면, urlPattern이 주어졌을 때 URLPattern의 새 인스턴스를 config의 urlPatterns에 추가한다.

  11. details["excludeURLPatterns"]가 정의되어 있으면, 다음을 실행한다.

    1. details["excludeURLPatterns"]의 각 urlPattern에 대해:

      1. urlPattern이 URLPattern이면, urlPattern을 config의 excludeURLPatterns에 추가한다.

      2. 그렇지 않으면, urlPattern이 주어졌을 때 URLPattern의 새 인스턴스를 config의 excludeURLPatterns에 추가한다.

  12. completionSteps를 long index, boolean success, 그리고 DOMString source를 받는 다음 알고리즘으로 둔다.

    1. success가 false이면, controlledframe, result, TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

    2. isCss이면, 다음을 실행한다.

      1. config의 css[index]를 source로 설정한다.

    3. 그렇지 않으면, 다음을 실행한다.

      1. config의 js[index]를 source로 설정한다.

    4. config의 pendingFetchCount를 감소시킨다.

    5. config의 pendingFetchCount가 0보다 크면 반환한다.

    6. controlledframe의 콘텐츠 스크립트 맵[details[name]]을 config로 설정한다.

    7. controlledframe와 result가 주어졌을 때 삽입자의 promise를 Resolve한다.

  13. injectionItems["code"]가 정의되어 있으면, 다음을 실행한다.

    1. 0, true, injectionItems ["code"]가 주어졌을 때 completionSteps를 실행한다.

  14. 그렇지 않으면, 다음을 실행한다.

    1. injectionItems["files"]가 비어 있으면, controlledframe, result, TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

    2. injectionItems ["files"]의 각 urlString에 대해:

      1. controlledframe, urlString, isCss, config의 pendingFetchCount, 그리고 completionSteps가 주어졌을 때 삽입 항목 가져오기를 실행한다.

      2. config의 pendingFetchCount를 증가시킨다.

콘텐츠 스크립트 구성 config, URL url, 그리고 boolean isTopLevel가 주어졌을 때, 콘텐츠 스크립트 구성이 문서에 적용되는지 판단하려면, 다음 단계를 실행한다.
  1. isTopLevel이 false이고 config의 allFrames가 false이면, false를 반환한다.

  2. url이 about:blank와 일치하고 config의 matchAboutBlank가 false이면, false를 반환한다.

  3. urlString을 url을 직렬화한 결과로 둔다.

  4. match를 false로 둔다.

  5. config의 urlPatterns의 각 pattern에 대해:

    1. urlString이 pattern URLPattern과 일치하면, match를 true로 설정한다.

  6. config의 excludeURLPatterns의 각 pattern에 대해:

    1. urlString이 pattern URLPattern과 일치하면, match를 false로 설정한다.

  7. match를 반환한다.

Document document와 RunAt currentPhase가 주어졌을 때 콘텐츠 스크립트를 문서에 삽입하려면, 다음 단계를 실행한다.
  1. embeddedNavigable를 document의 노드 navigable의 traversable navigable로 둔다.

  2. embeddedNavigable이 null이거나 그 controlledFrameEmbedderParent가 null이면 반환한다.

  3. controlledframe를 embeddedNavigable의 controlledFrameEmbedderParent로 둔다.

  4. url을 document의 URL로 둔다.

  5. isTopLevel을 document의 노드 navigable의 부모가 null이면 true, 그렇지 않으면 false로 둔다.

  6. controlledframe의 콘텐츠 스크립트 맵의 각 config에 대해:

    1. config, url, 그리고 isTopLevel가 주어졌을 때 콘텐츠 스크립트 구성이 문서에 적용되는지 판단한 결과가 false이면, 계속한다.

    2. currentPhase가 document-start와 같고, config의 css가 비어 있지 않으면, 다음을 실행한다.

      1. config의 css의 각 styleSource에 대해, document와 styleSource가 주어졌을 때 스타일시트를 문서에 삽입을 실행한다.

    3. 그렇지 않고 currentPhase가 config의 runAt과 같으면, 다음을 실행한다.

      1. config의 js의 각 scriptSource에 대해, document, scriptSource, 그리고 빈 알고리즘이 주어졌을 때 스크립트를 문서에 삽입을 실행한다.

Document document와 DOMString styleSource가 주어졌을 때 스타일시트를 문서에 삽입하려면, 다음 단계를 실행한다.
  1. styleSheet를 새 CSS 스타일시트 객체로 둔다.

  2. styleSheet와 styleSource가 주어졌을 때 CSSStyleSheet의 규칙을 동기적으로 교체한다.

  3. document의 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, document와 styleSheet가 주어졌을 때 CSS 스타일시트를 추가한다.

다음 알고리즘은 Document의 환경에서 스크립트를 실행하지만, 이는 바람직한 동작이 아니다. 현재 HTML 명세 인프라로는 명세화할 수 없는 목표는 이 알고리즘이 Document의 환경과 격리되고 서로 다른 전역 객체를 가지지만 DOM에 대한 공유 접근권을 가진 환경에서 스크립트를 실행하게 하는 것이다. 이 실행 환경은 Blink에서 Isolated World라고 불리며, 확장에서 콘텐츠 스크립트를 실행하는 데 사용된다. 그 실행 모델에 대한 추가 세부 사항은 이 도표를 참조하라. Gecko는 Xray vision이라는 유사한 접근 방식을 사용한다. 이 알고리즘은 결국 모든 브라우저가 구현할 수 있는, 명세화 가능한 이 격리의 구현을 설명해야 한다.

Document document, DOMString scriptSource, 그리고 completion record를 받는 알고리즘 completionSteps가 주어졌을 때 스크립트를 문서에 삽입하려면, 다음 단계를 실행한다.

참고: document.currentScript는 scriptSource를 실행하는 동안 의도적으로 설정되지 않는다.

  1. script를 scriptSource, document의 관련 설정 객체, document의 URL, 그리고 기본 스크립트 가져오기 옵션이 주어졌을 때 클래식 스크립트를 생성한 결과로 둔다.

  2. document의 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하며, 이는 다음 단계를 실행한다.

    1. completionRecord를 script가 주어졌을 때 클래식 스크립트를 실행한 결과로 둔다.

    2. controlledframe를 document의 노드 navigable의 traversable navigable의 controlledFrameEmbedderParent로 둔다.

    3. controlledframe의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하며, 이는 completionRecord로 completionSteps를 실행한다.

addContentScripts(contentScriptList) 메서드 단계는 다음과 같다.
  1. contentScriptList가 비어 있으면, TypeError로 reject된 새 promise를 반환한다.

  2. promises를 빈 목록으로 둔다.

  3. contentScriptList의 각 contentScript에 대해:

    1. promise를 contentScript가 주어졌을 때 ContentScriptDetails 검증 및 resolve를 호출한 결과로 둔다.

    2. promise를 promises에 추가한다.

  4. promises가 주어졌을 때 모든 promise를 기다리는 promise를 가져온 결과를 반환한다.

removeContentScripts(scriptNameList) 메서드 단계는 다음과 같다.
  1. result를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. result를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. scriptNameList가 undefined이면, 다음을 실행한다.

    1. controlledframe의 콘텐츠 스크립트 맵을 비운다.

  5. 그렇지 않으면, scriptNameList의 각 name에 대해:

    1. controlledframe의 콘텐츠 스크립트 맵[name]을 제거한다.

  6. controlledframe와 result가 주어졌을 때 삽입자의 promise를 Resolve한다.

executeScript(details) 메서드 단계는 다음과 같다.
  1. result를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. result를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. controlledframe의 삽입된 navigable이 null이면, controlledframe, result, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  5. details["code"]와 details"[file"]가 둘 다 정의되어 있거나 둘 다 정의되어 있지 않으면, controlledframe, result, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  6. executionSteps를 long과 DOMString 또는 boolean scriptString을 받는 다음 알고리즘으로 둔다.

    1. scriptString이 DOMString이 아니면, controlledframe, result, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

    2. document를 controlledframe의 삽입된 navigable의 활성 문서로 둔다.

    3. document, scriptString, 그리고 completion record completionRecord를 받는 다음 알고리즘이 주어졌을 때, 스크립트를 문서에 삽입한다.

      1. completionRecord가 normal completion이면, 다음을 실행한다.

        1. controlledframe, result, 그리고 completionRecord.[[Value]]가 주어졌을 때 삽입자의 promise를 Resolve한다.

      2. 그렇지 않으면, 다음을 실행한다.

        1. controlledframe, result, 그리고 completionRecord.[[Value]]가 주어졌을 때 삽입자의 promise를 Reject한다.

  7. details["code"]가 정의되어 있으면, 0과 details["code"]가 주어졌을 때 executionSteps를 실행한다.

  8. 그렇지 않으면, controlledframe, details["file"], false, 0, 그리고 executionSteps가 주어졌을 때 삽입 항목 가져오기를 실행한다.

insertCSS(details) 메서드 단계는 다음과 같다.
  1. result를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. result를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. controlledframe의 삽입된 navigable이 null이면, controlledframe, result, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  5. details["code"]와 details["file"]가 둘 다 정의되어 있거나 둘 다 정의되어 있지 않으면, controlledframe, result, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  6. executionSteps를 long, boolean success, 그리고 DOMString styleString을 받는 다음 알고리즘으로 둔다.

    1. success가 false이면, controlledframe, result, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

    2. document를 controlledframe의 삽입된 navigable의 활성 문서로 둔다.

    3. document와 styleString가 주어졌을 때 스타일시트를 문서에 삽입한다.

    4. controlledframe와 result가 주어졌을 때 삽입자의 promise를 Resolve한다.

  7. details["code"]가 정의되어 있으면, 0, true, 그리고 details["code"]가 주어졌을 때 executionSteps를 실행한다.

  8. 그렇지 않으면, controlledframe, details["file"], false, 0, 그리고 executionSteps가 주어졌을 때 삽입 항목 가져오기를 실행한다.

3.5. 구성 메서드

dictionary ClearDataOptions {
  long since;
};

dictionary ClearDataTypeSet {
  boolean cache;
  boolean cookies;
  boolean fileSystems;
  boolean indexedDB;
  boolean localStorage;
  boolean persistentCookies;
  boolean sessionCookies;
};
저장소 버킷 bucket, 저장소 식별자 identifier, 그리고 long since가 주어졌을 때 저장소 병을 비우려면, 다음 단계를 실행한다.

참고: 가능하면 사용자 에이전트는 epoch 이후의 밀리초 단위 타임스탬프를 나타내는 since 이후에 마지막으로 사용된 데이터만 제거해야 한다. 모든 사용자 에이전트가 모든 브라우징 데이터에 대해 쓰기 또는 접근 시간을 추적하는 것은 아니다. 구현은 가능한 한 since를 존중해야 하지만, 이 API는 그 사용 가능성을 보장하지 않는다.

  1. bottle을 bucket[identifier]로 둔다.

  2. bottle의 map을 비운다.

  3. bottle의 proxy map reference set을 새 set으로 설정한다.

clearData(options, types) 메서드 단계는 다음과 같다.
  1. resultPromise를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. resultPromise를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. clearSince를 0으로 둔다.

  5. options["since"]가 정의되어 있으면, clearSince를 options|["since"]로 설정한다.

  6. embeddingOrigin을 controlledframe의 관련 설정 객체의 최상위 출처로 둔다.

  7. partition을 controlledframe의 partition으로 둔다.

  8. 각 storageKey → shelf에 대해, 이는 사용자 에이전트의 저장소 창고에 속한다.

    1. storageKey의 삽입 출처가 embeddingOrigin과 같지 않거나 storageKey의 partition이 partition과 같지 않으면, 계속한다.

    2. bucket을 shelf["default"]로 둔다.

    3. types["fileSystems"]가 true이면:

      1. bucket, "fileSystem", 그리고 clearSince가 주어졌을 때 저장소 병을 비운다.

    4. types["indexedDB"]가 true이면:

      1. bucket, "indexedDB", 그리고 clearSince가 주어졌을 때 저장소 병을 비운다.

    5. types["localStorage"]가 true이면:

      1. bucket, "localStorage", 그리고 clearSince가 주어졌을 때 저장소 병을 비운다.

  9. types["cookies"], types["persistentCookies"], 또는 types["sessionCookies"]가 true이면, 다음을 실행한다.

    [COOKIES] 명세는 저장소 키 같은 메커니즘을 통한 쿠키 파티션화를 지원하지 않는다. 다음 단계는 모든 쿠키를 지우지만, 의도는 이 Controlled Frame의 현재 partition을 가진 Controlled Frame 안의 콘텐츠가 만든 쿠키만 삭제하는 것이다.

    1. 각 cookie에 대해, 이는 사용자 에이전트의 쿠키 저장소에 있다.

      1. cookie의 persistent-flag가 설정되어 있으면, 다음을 실행한다.

        1. types["cookies"]와 types["persistentCookies"]가 false이면, 계속한다.

      2. 그렇지 않으면, 다음을 실행한다.

        1. types["cookies"]와 types["sessionCookies"]가 false이면, 계속한다.

      3. cookie의 last-access-time을 epoch 이후의 밀리초로 표현한 값이 clearSince보다 작으면, 계속한다.

      4. 사용자 에이전트의 쿠키 저장소에서 cookie를 제거한다.

  10. types["cache"]가 true이면, 다음을 실행한다.

    1. 각 storageKey → cache에 대해, 이는 사용자 에이전트가 관리한다: [HTTP-CACHING]

      1. storageKey의 삽입 출처가 embeddingOrigin과 같지 않거나 storageKey의 partition이 partition과 같지 않으면, 계속한다.

      2. cache를 비운다.

  11. controlledframe와 resultPromise가 주어졌을 때 삽입자의 promise를 Resolve한다.

각 삽입된 navigable은 기본값이 false인 muted boolean을 가진다. muted가 true이면, 사용자 에이전트는 삽입된 navigable 안에서 발생하는 모든 오디오 스트림을 음소거해야 한다. muted 상태는 삽입된 navigable 안의 콘텐츠에 노출되어서는 안 된다. muted가 true이면, 볼륨 상태는 스크립트에 보이는 어떤 방식으로도 변경되어서는 안 되지만, 기반 오디오 스트림은 사용자에게 들리지 않아야 한다.

getAudioState() 메서드 단계는 다음과 같다.
  1. resultPromise를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. resultPromise를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. controlledframe의 삽입된 navigable이 null이면, controlledframe, resultPromise, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  5. playingAudio를, 중첩된 프레임을 포함하여 controlledframe의 삽입된 navigable 안의 콘텐츠가 현재 오디오를 재생하고 있으면 true, 그렇지 않으면 false로 둔다.

  6. controlledframe, resultPromise, 그리고 playingAudio가 주어졌을 때 삽입자의 promise를 Resolve한다.

isAudioMuted() 메서드 단계는 다음과 같다.
  1. resultPromise를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. resultPromise를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. controlledframe의 삽입된 navigable이 null이면, controlledframe, resultPromise, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  5. controlledframe, resultPromise, 그리고 controlledframe의 삽입된 navigable의 muted 플래그가 주어졌을 때 삽입자의 promise를 Resolve한다.

setAudioMuted(mute) 메서드 단계는 다음과 같다.
  1. this의 삽입된 navigable이 null이면, TypeError를 던진다.

  2. this의 삽입된 navigable의 muted 플래그를 mute로 설정한다.

3.5.1. 확대/축소

enum ZoomMode {
  "per-origin",
  "per-view",
  "disabled"
};

사용자 에이전트는 Controlled Frame 확대/축소 맵을 가지며, 이는 맵이다. 그 키는 튜플이고, 값은 float이다.

각 HTMLControlledFrameElement는 기본값이 per-origin인 ZoomMode zoomMode를 가진다.

각 HTMLControlledFrameElement는 처음에 1.0f로 설정되는 float 숫자 currentZoom을 가진다.

float zoomLevel이 주어졌을 때 문서에 확대/축소 수준이 적용되는 방식은 구현별이다.

이 절은 비규범이다.

유효한 ZoomMode 값은 다음과 같이 동작한다.

per-origin

확대/축소 변경은 삽입된 문서의 출처에 지속된다. 즉, 같은 partition에 있고 같은 출처로 탐색된 다른 모든 HTMLControlledFrameElement도 함께 확대/축소된다.

per-view

확대/축소 변경은 이 HTMLControlledFrameElement에만 영향을 미치며, 다른 HTMLControlledFrameElement의 확대/축소 변경은 이 HTMLControlledFrameElement의 확대/축소에 영향을 주지 않는다.

disabled

HTMLControlledFrameElement에서 모든 확대/축소를 비활성화한다. 콘텐츠는 기본 확대/축소 수준으로 되돌아가며, 시도된 모든 확대/축소 변경은 무시된다.

HTMLControlledFrameElement e가 주어졌을 때 per-origin 확대/축소 수준을 가져오려면, 다음 단계를 실행한다.

  1. result를 처음에 1.0f로 설정된 float로 둔다.

  2. key를 e의 삽입된 navigable의 활성 문서의 현재 설정 객체와 관련된 환경이 주어졌을 때 Controlled Frame 저장소 키를 얻은 결과로 둔다.

  3. Controlled Frame 확대/축소 맵[key]가 존재하면, key가 주어졌을 때 Controlled Frame 확대/축소 맵의 값을 가져온 결과로 result를 설정한다.

  4. result를 반환한다.

HTMLControlledFrameElement e와 float zoomLevel가 주어졌을 때 per-origin 확대/축소 수준을 설정하려면, 다음 단계를 실행한다.

  1. key를 e의 삽입된 navigable의 활성 문서의 현재 설정 객체와 관련된 환경이 주어졌을 때 Controlled Frame 저장소 키를 얻은 결과로 둔다.

  2. key와 값 zoomLevel가 주어졌을 때 Controlled Frame 확대/축소 맵의 값을 설정한다.

HTMLControlledFrameElement e가 주어졌을 때 현재 문서가 per-origin 확대/축소 수준을 가지는지 판단하려면, 다음 단계를 실행한다.

  1. key를 e의 삽입된 navigable의 활성 문서의 현재 설정 객체와 관련된 환경이 주어졌을 때 Controlled Frame 저장소 키를 얻은 결과로 둔다.

  2. Controlled Frame 확대/축소 맵[key]가 존재하면 true를 반환한다.

  3. false를 반환한다.

getZoomMode() 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. controlledframe, p, 그리고 controlledframe의 zoomMode가 주어졌을 때 삽입자의 promise를 Resolve한다.

setZoomMode(zoomMode) 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. currentZoomMode를 controlledframe가 주어졌을 때 getZoomMode의 결과로 둔다.

  5. currentZoomMode가 zoomMode와 같으면, controlledframe와 p가 주어졌을 때 삽입자의 promise를 resolve한다.

  6. controlledframe의 zoomMode를 zoomMode로 설정한다.

  7. zoomMode가 per-origin이면:

    1. controlledframe가 주어졌을 때 현재 문서가 per-origin 확대/축소 수준을 가지는지가 true이면:

      1. oldZoomFactor를 controlledframe의 currentZoom으로 둔다.

      2. controlledframe의 currentZoom을 controlledframe가 주어졌을 때 per-origin 확대/축소 수준을 가져온 결과로 설정한다.

      3. oldZoomFactor가 controlledframe의 currentZoom과 같지 않으면:

        1. controlledframe의 currentZoom가 주어졌을 때 controlledframe의 삽입된 문서에 확대/축소 수준을 적용한다.

        2. controlledframe, oldZoomFactor, controlledframe의 currentZoom와 함께 "zoomchange" 이벤트를 발화한다.

  8. zoomMode가 disabled이면:

    1. oldZoomFactor를 controlledframe의 currentZoom으로 둔다.

    2. controlledframe의 currentZoom을 1.0f로 설정한다.

    3. oldZoomFactor가 controlledframe의 currentZoom과 같지 않으면:

      1. controlledframe의 currentZoom가 주어졌을 때 controlledframe의 삽입된 문서에 확대/축소 수준을 적용한다.

      2. controlledframe, oldZoomFactor, controlledframe의 currentZoom와 함께 "zoomchange" 이벤트를 발화한다.

  9. controlledframe와 p가 주어졌을 때 삽입자의 promise를 Resolve한다.

getZoom() 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. embeddedNavigable를 controlledframe의 삽입된 navigable로 둔다.

  5. embeddedNavigable이 null이면, controlledframe, p, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  6. controlledframe, p, 그리고 controlledframe의 currentZoom이 주어졌을 때 삽입자의 promise를 Resolve한다.

setZoom(zoomFactor) 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. embeddedNavigable를 controlledframe의 삽입된 navigable로 둔다.

  5. embeddedNavigable이 null이면, controlledframe, p, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  6. controlledframe의 ZoomMode가 disabled이면:

    1. controlledframe, p, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 Reject하고, 이 단계를 중단한다.

  7. controlledframe의 ZoomMode가 per-origin이면:

    1. oldZoomFactor를 controlledframe의 currentZoom으로 둔다.

    2. controlledframe와 zoomFactor가 주어졌을 때 per-origin 확대/축소 수준을 설정한다.

    3. 사용자 에이전트의 탐색 컨텍스트 그룹 집합 안의 각 탐색 컨텍스트 그룹 group에 대해:

      1. group 안의 각 최상위 탐색 컨텍스트 browsingContext에 대해:

        1. embeddedDocument를 browsingContext의 활성 문서로 둔다.

        2. embedder를 embeddedDocument의 노드 navigable의 controlledFrameEmbedderParent로 둔다.

        3. embedder가 null이면 계속한다.

        4. match를 다음 조건이 모두 true이면 true로 둔다.

        5. match가 true이면, 다음을 실행한다.

          1. embedder의 currentZoom을 zoomFactor로 설정한다.

          2. zoomFactor가 주어졌을 때 embeddedDocument에 확대/축소 수준을 적용한다.

          3. embedder, oldZoomFactor, 그리고 zoomFactor와 함께 "zoomchange" 이벤트를 발화한다.

  8. controlledframe의 ZoomMode가 per-view이면:

    1. oldZoomFactor를 controlledframe의 currentZoom으로 둔다.

    2. controlledframe의 currentZoom을 zoomFactor로 설정한다.

    3. oldZoomFactor가 controlledframe의 currentZoom과 같지 않으면:

      1. controlledframe의 currentZoom가 주어졌을 때 controlledframe의 삽입된 문서에 확대/축소 수준을 적용한다.

      2. controlledframe, oldZoomFactor, controlledframe의 currentZoom와 함께 "zoomchange" 이벤트를 발화한다.

  9. controlledframe와 p가 주어졌을 때 삽입자의 promise를 Resolve한다.

3.6. 캡처 메서드

// One of |code| or |file| must be specified but not both.
dictionary ImageDetails {
  DOMString format;
  DOMString quality;
};
captureVisibleRegion(options) 메서드 단계는 다음과 같다.
  1. resultPromise를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. resultPromise를 반환하고, 나머지 단계를 병렬로 실행한다.

  4. controlledframe의 삽입된 navigable이 null이면, controlledframe, resultPromise, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  5. optionsFormat를 기본값 "JPEG"로 둔다.

  6. optionsQuality를 기본값 100으로 둔다.

  7. options에 "format" 필드가 있으면:

    1. optionsFormat를 options["format"]으로 둔다.

  8. optionsFormat가 인식할 수 없는 형식이면, controlledframe, resultPromise, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  9. options에 "quality" 필드가 있으면:

    1. optionsQuality를 options["quality"]로 둔다.

  10. optionsQuality가 정수가 아니거나 0 이상 100 이하가 아니면, controlledframe, resultPromise, 그리고 TypeError가 주어졌을 때 삽입자의 promise를 reject하고, 이 단계를 중단한다.

  11. imageData를 optionsQuality 품질로 optionsFormat에 인코딩된, 삽입된 콘텐츠의 보이는 영역을 보여주는 이미지로 둔다.

    참고: 지원되는 이미지 형식의 집합은 구현 정의이지만, 적어도 "JPEG"와 "PNG"를 지원하는 것이 권장된다.

  12. controlledframe, resultPromise, 그리고 imageData를 포함하는 data: URL이 주어졌을 때 삽입자의 promise를 Resolve한다.

print() 메서드 단계는 다음과 같다.
  1. this의 삽입된 navigable이 null이면, TypeError를 던진다.

  2. 삽입된 콘텐츠에 대한 브라우저 인쇄 페이지 기능을 시작한다.

3.7. 이벤트

HTMLControlledFrameElement는 EventTarget을 구현하며, 다음 이벤트 핸들러와 그에 대응하는 이벤트 핸들러 이벤트 타입을 지원한다.

이벤트 핸들러 이벤트 핸들러 이벤트 타입
onconsolemessage consolemessage
oncontentload contentload
ondialog dialog
onloadabort loadabort
onloadcommit loadcommit
onloadstart loadstart
onloadstop loadstop
onnewwindow newwindow
onpermissionrequest permissionrequest
onsizechanged sizechanged
onzoomchange zoomchange

상호작용 이벤트:

UI 변경 이벤트:

탐색 이벤트:

각 HTMLControlledFrameElement는 처음에 0인 숫자인 load counter를 가진다.

onloadstart 이벤트가 발화될 때마다, load counter는 1만큼 증가한다.

onloadabort 이벤트가 발화될 때마다, load counter는 1만큼 감소한다.

onloadcommit 이벤트가 발화될 때마다, load counter는 1만큼 감소한다.

load counter가 0이 아닌 숫자에서 0으로 변경되면, "loadstop" 이벤트를 발화한다.

3.7.1. consolemessage

[Exposed=Window, IsolatedContext]
interface ConsoleMessage {
  readonly attribute long level;
  readonly attribute DOMString message;
};

[Exposed=Window, IsolatedContext]
interface ConsoleMessageEvent : Event {
  constructor(DOMString type, optional ConsoleMessageEventInit eventInitDict = {});
  readonly attribute ConsoleMessage consoleMessage;
};

dictionary ConsoleMessageEventInit: EventInit {
  ConsoleMessage? consoleMessage;
};

controlledframe 요소 target, long logLevel 그리고 DOMString message가 주어졌을 때 e인 ConsoleMessageEvent를 발화하려면, 다음 단계를 실행한다.

  1. consoleMessage를 새 ConsoleMessage 객체로 둔다.

  2. consoleMessage의 다음 필드를 설정한다.

    level

    logLevel.

    message

    message.

  3. e의 consoleMessage를 consoleMessage로 설정한다.

  4. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.2. dialog

enum DialogType {
  "alert",
  "confirm",
  "prompt"
};

[Exposed=Window, IsolatedContext]
interface DialogController {
  undefined okay(optional DOMString response);
  undefined cancel();
};

[Exposed=Window, IsolatedContext]
interface DialogMessage {
  readonly attribute DialogType messageType;
  readonly attribute DOMString messageText;
  readonly attribute DialogController dialog;
};

[Exposed=Window, IsolatedContext]
interface DialogEvent : Event {
  constructor(DOMString type, optional DialogEventInit eventInitDict = {});
  readonly attribute DialogMessage dialogMessage;
};

dictionary DialogEventInit: EventInit {
  DialogMessage? dialogMessage;
};

각 DialogController는 다음을 가진다.

okay(response) 메서드 단계는 다음과 같다.

  1. accept를 true로 설정한다.

  2. response를 response로 설정한다.

cancel() 메서드 단계는 다음과 같다.

  1. accept를 false로 설정한다.

controlledframe 요소 target, simple-dialogs 타입 dialogType, 그리고 message message가 주어졌을 때 e인 DialogEvent를 발화하려면, 다음 단계를 실행한다.

  1. e["dialogMessage"]["dialog"]["accept"]가 false와 같음을 단언한다.

  2. dialogMessage를 새 DialogMessage 객체로 둔다.

  3. dialog를 새 DialogController 객체로 둔다.

  4. dialogMessage의 다음 필드를 설정한다.

    messageType

    dialogType.

    messageText

    message.

    dialog

    dialog.

  5. e의 dialogMessage를 dialogMessage로 설정한다.

  6. complete를 false로 둔다.

  7. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

    1. e를 target에 디스패치한다.

    2. complete를 true로 설정한다.

  8. complete가 true가 될 때까지 동기적으로 기다린다.

    참고: "dialog" 이벤트가 나타내는 alert, confirm, prompt 대화상자는 메인 스레드를 차단하고, 여기에서 호출하는 이벤트 핸들러가 반환값에 영향을 줄 수 있으므로, 여기서의 차단은 의도된 것이다.

  9. e["dialogMessage"]["dialog"]["accept"] 및 e["dialogMessage"]["dialog"]["response"]를 반환한다.

3.7.3. newwindow

enum WindowOpenDisposition {
  "ignore",
  "save_to_disk",
  "current_tab",
  "new_background_tab",
  "new_foreground_tab",
  "new_window",
  "new_popup"
};

[Exposed=Window, IsolatedContext]
interface NewWindowController {
  undefined attach(HTMLControlledFrameElement newControlledFrame);
  undefined discard();
};

[Exposed=Window, IsolatedContext]
interface NewWindow {
  readonly attribute NewWindowController window;
  readonly attribute USVString targetUrl;
  readonly attribute DOMString name;
  readonly attribute WindowOpenDisposition windowOpenDisposition;
};

[Exposed=Window, IsolatedContext]
interface NewWindowEvent : Event {
  constructor(DOMString type, optional NewWindowEventInit eventInitDict = {});
  readonly attribute NewWindow newWindow;
};

dictionary NewWindowEventInit: EventInit {
  NewWindow? newWindow;
};

각 NewWindowController는 처음에 null인 대상 navigable에 대한 참조를 가진다.

attach(newControlledFrame) 메서드 단계는 다음과 같다.

  1. newControlledFrame의 삽입된 navigable을 this의 대상 navigable로 설정한다.

discard() 메서드 단계는 다음과 같다.

  1. this의 대상 navigable이 null이 아니면, 최상위 traversable을 닫는다. 이때 this의 대상 navigable이 주어진다.

controlledframe 요소 controlledFrame, USVString url, DOMString target, navigable targetNavigable, 그리고 WindowOpenDisposition windowOpenDisposition가 주어졌을 때 e인 NewWindowEvent를 발화하려면, 다음 단계를 실행한다.

  1. controller를 새 NewWindowController 객체로 둔다.

  2. controller의 대상 navigable을 targetNavigable로 설정한다.

  3. newWindow를 새 NewWindow 객체로 둔다.

  4. newWindow의 다음 필드를 설정한다.

    window

    controller

    targetUrl

    url

    name

    target.

    windowOpenDisposition

    windowOpenDisposition

  5. e의 newWindow를 newWindow로 설정한다.

  6. controlledFrame의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 controlledFrame에 디스패치한다.

3.7.4. permissionrequest

enum PermissionType {
  "media",
  "geolocation",
  "pointerLock",
  "download",
  "filesystem",
  "fullscreen",
  "hid",
};

[Exposed=Window, IsolatedContext]
interface PermissionRequestControllerBase {
  undefined allow();
  undefined cancel();
};

[Exposed=Window, IsolatedContext]
interface MediaPermissionRequestController: PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface GeolocationPermissionRequestController: PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface PointerLockPermissionRequestController: PermissionRequestControllerBase {
  readonly attribute boolean lastUnlockedBySelf;
  readonly attribute boolean userGesture;
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface DownloadPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute DOMString requestMethod;
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface FileSystemPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface FullscreenPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute USVString origin;
};

[Exposed=Window, IsolatedContext]
interface HidPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface PermissionRequest {
  readonly attribute PermissionType permission;
  readonly attribute PermissionRequestControllerBase request;
};

[Exposed=Window, IsolatedContext]
interface PermissionRequestEvent : Event {
  constructor(DOMString type, optional PermissionRequestEventInit eventInitDict = {});
  readonly attribute PermissionRequest permissionRequest;
};

dictionary PermissionRequestEventInit: EventInit {
  PermissionRequest? permissionRequest;
};

각 PermissionRequestControllerBase는 처음에 false인 boolean 값 allow를 가진다.

allow() 메서드 단계는 다음과 같다.

  1. allow를 true로 설정한다.

cancel() 메서드 단계는 다음과 같다.

  1. allow를 false로 설정한다.

문서 embeddedDocument, controlledframe 요소 target, DOMString type, USVString url, 선택적인 dictionary options, 그리고 boolean을 받는 알고리즘 completionSteps가 주어졌을 때 e인 PermissionRequestEvent를 발화하려면, 다음 단계를 실행한다.

  1. permissionRequest를 새 PermissionRequest 객체로 둔다.

  2. type이 "media"이면:

    1. requestController를 다음 속성을 가진 새 MediaPermissionRequestController로 둔다.

      url

      url

  3. type이 "geolocation"이면:

    1. requestController를 다음 속성을 가진 새 GeolocationPermissionRequestController로 둔다.

      url

      url

  4. type이 "pointerLock"이면:

    1. requestController를 다음 속성을 가진 새 PointerLockPermissionRequestController로 둔다.

      lastUnlockedBySelf

      options["lastUnlockedBySelf"]

      userGesture

      options["userGesture"]

      url

      url

  5. type이 "download"이면:

    1. requestController를 다음 속성을 가진 새 DownloadPermissionRequestController로 둔다.

      requestMethod

      options["requestMethod"]

      url

      url

  6. type이 "filesystem"이면:

    1. requestController를 다음 속성을 가진 새 FileSystemPermissionRequestController로 둔다.

      url

      url

  7. type이 "fullscreen"이면:

    1. requestController를 다음 속성을 가진 새 FullscreenPermissionRequestController로 둔다.

      origin

      url의 origin

  8. type이 "hid"이면:

    1. requestController를 다음 속성을 가진 새 HidPermissionRequestController로 둔다.

      url

      url

  9. permissionRequest의 다음 필드를 설정한다.

    request

    requestController

    permission

    type.

  10. e의 permissionRequest를 permissionRequest로 설정한다.

  11. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

    1. e를 target에 디스패치한다.

    2. embeddedDocument의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e["permissionRequest"]["permission"]["allow"]와 함께 completionSteps를 실행한다.

3.7.5. sizechanged

[Exposed=Window, IsolatedContext]
interface SizeChange {
  readonly attribute unsigned long oldWidth;
  readonly attribute unsigned long oldHeight;
  readonly attribute unsigned long newWidth;
  readonly attribute unsigned long newHeight;
};

[Exposed=Window, IsolatedContext]
interface SizeChangedEvent : Event {
  constructor(DOMString type, optional SizeChangedEventInit eventInitDict = {});
  readonly attribute SizeChange sizeChange;
};

dictionary SizeChangedEventInit: EventInit {
  SizeChange? sizeChange;
};

controlledframe 요소 target, 음이 아닌 숫자 4개 oldWidth, oldHeight, newWidth, newHeight가 주어졌을 때 SizeChangedEvent e를 발화하려면:

  1. sizeChange를 새 SizeChange 객체로 둔다.

  2. sizeChange의 다음 필드를 설정한다.

    oldWidth

    oldWidth.

    oldHeight

    oldHeight.

    newWidth

    newWidth.

    newHeight

    newHeight.

  3. e의 sizeChange를 sizeChange로 설정한다.

  4. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.6. zoomchange

[Exposed=Window, IsolatedContext]
interface ZoomChange {
  readonly attribute float oldZoomFactor;
  readonly attribute float newZoomFactor;
};

[Exposed=Window, IsolatedContext]
interface ZoomChangeEvent : Event {
  constructor(DOMString type, optional ZoomChangeEventInit eventInitDict = {});
  readonly attribute ZoomChange zoomChange;
};

dictionary ZoomChangeEventInit: EventInit {
  ZoomChange? zoomChange;
};

controlledframe 요소 target, float 숫자 2개 oldZoomFactor, newZoomFactor가 주어졌을 때 e인 ZoomChangeEvent를 발화하려면:

  1. zoomChange를 새 ZoomChange 객체로 둔다.

  2. zoomChange의 다음 필드를 설정한다.

    oldZoomFactor

    oldZoomFactor.

    newZoomFactor

    newZoomFactor.

  3. e의 zoomChange를 zoomChange로 설정한다.

  4. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.7. contentload

[Exposed=Window, IsolatedContext]
interface ContentLoadEvent : Event {
  constructor(DOMString type, optional EventInit eventInitDict = {});
};

controlledframe 요소 target가 주어졌을 때 e인 ContentLoadEvent를 발화하려면, 다음 단계를 실행한다.

  1. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.8. loadabort

[Exposed=Window, IsolatedContext]
interface LoadInfo {
  readonly attribute USVString url;
  readonly attribute boolean isTopLevel;
};

[Exposed=Window, IsolatedContext]
interface LoadAbortInfo : LoadInfo{
  readonly attribute long code;
  readonly attribute DOMString reason;
};

[Exposed=Window, IsolatedContext]
interface LoadRedirectInfo{
  readonly attribute USVString oldUrl;
  readonly attribute USVString newUrl;
  readonly attribute boolean isTopLevel;
};

[Exposed=Window, IsolatedContext]
interface LoadAbortEvent : Event {
  constructor(DOMString type, optional LoadAbortEventInit eventInitDict = {});
  readonly attribute LoadAbortInfo loadAbortInfo;
};

dictionary LoadAbortEventInit: EventInit {
  LoadAbortInfo? loadAbortInfo;
};

LoadAbortEvent e를 발화하려면, 주어진 controlledframe 요소 target, USVString url, boolean isTopLevel, long code, 그리고 DOMString reason에 대해 다음 단계를 실행한다.

  1. info를 다음 속성을 가진 새 LoadAbortInfo로 둔다.

    url

    url

    isTopLevel

    isTopLevel

    code

    code

    reason

    reason

  2. e의 loadAbortInfo를 info로 설정한다.

  3. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.9. loadcommit

[Exposed=Window, IsolatedContext]
interface LoadCommitEvent : Event {
  constructor(DOMString type, optional LoadCommitEventInit eventInitDict = {});
  readonly attribute LoadInfo loadInfo;
};

dictionary LoadCommitEventInit: EventInit {
  LoadInfo? loadInfo;
};

LoadCommitEvent e를 발화하려면, 주어진 controlledframe 요소 target, USVString url, 그리고 boolean isTopLevel에 대해 다음 단계를 실행한다.

  1. info를 다음 속성을 가진 새 LoadInfo로 둔다.

    url

    url

    isTopLevel

    isTopLevel

  2. e의 loadInfo를 info로 설정한다.

  3. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.10. loadstart

[Exposed=Window, IsolatedContext]
interface LoadStartEvent : Event {
  constructor(DOMString type, optional LoadStartEventInit eventInitDict = {});
  readonly attribute LoadInfo loadInfo;
};

dictionary LoadStartEventInit: EventInit {
  LoadInfo? loadInfo;
};

LoadStartEvent e를 발화하려면, 주어진 controlledframe 요소 target, USVString url, 그리고 boolean isTopLevel에 대해 다음 단계를 실행한다.

  1. info를 다음 속성을 가진 새 LoadInfo로 둔다.

    url

    url

    isTopLevel

    isTopLevel

  2. e의 loadInfo를 info로 설정한다.

  3. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.11. loadstop

[Exposed=Window, IsolatedContext]
interface LoadStopEvent : Event {
  constructor(DOMString type, optional LoadStopEventInit eventInitDict = {});
};

dictionary LoadStopEventInit: EventInit {
};

controlledframe 요소 target가 주어졌을 때 e인 LoadStopEvent를 발화하려면, 다음 단계를 실행한다.

  1. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.12. loadredirect

[Exposed=Window, IsolatedContext]
interface LoadRedirectEvent : Event {
  constructor(DOMString type, optional LoadRedirectEventInit eventInitDict = {});
  readonly attribute LoadRedirectInfo loadRedirectInfo;
};

dictionary LoadRedirectEventInit: EventInit {
  LoadRedirectInfo? loadRedirectInfo;
};

controlledframe 요소 target, URL oldUrl, URL newUrl, 그리고 boolean isTopLevel이 주어졌을 때 e인 LoadRedirectEvent를 발화하려면, 다음 단계를 실행한다.

  1. info를 다음 속성을 가진 새 LoadInfo로 둔다.

    oldUrl

    oldUrl이 주어졌을 때 URL을 직렬화한 결과

    newUrl

    newUrl이 주어졌을 때 URL을 직렬화한 결과

    isTopLevel

    isTopLevel

  2. e의 loadRedirectInfo를 info로 설정한다.

  3. target의 관련 전역 객체의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여, e를 target에 디스패치한다.

3.7.13. 몽키 패치

3.7.13.1. [HTML]

alert에 대해:

  1. message를 message를 선택적으로 잘라낸 결과로 설정한다.

  2. controlledFrameEmbedderParent를 window의 navigable의 controlledFrameEmbedderParent로 둔다. .
  3. controlledFrameEmbedderParent가 HTMLControlledFrameElement이면, controlledFrameEmbedderParent, "alert" 그리고 message와 함께 "dialog" 이벤트를 발화하고 반환한다.

confirm에 대해:

  1. message를 message를 선택적으로 잘라낸 결과로 설정한다.

  2. controlledFrameEmbedderParent를 window의 navigable의 controlledFrameEmbedderParent로 둔다. .
  3. controlledFrameEmbedderParent가 HTMLControlledFrameElement이면, controlledFrameEmbedderParent, "confirm", 그리고 message와 함께 "dialog" 이벤트를 발화한 결과를 반환한다.

prompt에 대해:

  1. default를 default를 선택적으로 잘라낸 결과로 설정한다.

  2. controlledFrameEmbedderParent를 window의 navigable의 controlledFrameEmbedderParent로 둔다. .
  3. controlledFrameEmbedderParent가 HTMLControlledFrameElement이면, 다음을 실행한다.
    1. accept와 response를 controlledFrameEmbedderParent, "prompt" 그리고 message와 함께 "dialog" 이벤트를 발화한 결과로 둔다.
    2. accept가 false와 같으면 null을 반환한다.
    3. response를 반환한다.

window open steps에 대해:

  1. windowOpenDisposition를 "ignore"로 둔다.
  2. controlledFrameEmbedderParent를 sourceDocument의 node navigable의 controlledFrameEmbedderParent로 둔다.

...

14. If targetNavigable is null, then return null.
  1. targetNavigable이 null이면:
    1. controlledFrameEmbedderParent가 null이 아니면:
      1. controlledFrameEmbedderParent, url, target, targetNavigable, 그리고 windowOpenDisposition와 함께 "newwindow" 이벤트를 발화한다.
    2. null을 반환한다.
  2. windowType이 "new and unrestricted" 또는 "new with no opener" 중 하나이면, 다음을 실행한다.

    1. windowOpenDisposition를 "new_background_tab", "new_foreground_tab", 또는 "new_window" 중 하나로 설정한다.

    참고: 값은 사용자 에이전트의 동작 지원 및 사용자 설정에 따라 달라진다.

    1. tokenizedFeatures가 주어졌을 때 popup 창이 요청되었는지 검사한 결과로 targetNavigable의 활성 탐색 컨텍스트의 is popup을 설정한다.

    2. targetNavigable의 활성 탐색 컨텍스트의 is popup이 true이면, windowOpenDisposition를 "new_popup"로 설정한다.

    ...

  3. 그렇지 않으면:

    1. windowOpenDisposition를 "current_tab"로 설정한다.

    ...

참고: 단계 15와 16도 targetNavigable을 탐색한다. 탐색 중에는 windowOpenDisposition도 갱신될 수 있다. 예를 들어 탐색이 방지되면, windowOpenDisposition는 "ignore"로 설정될 수 있다. 탐색 응답이 다운로드를 초래한 경우, windowOpenDisposition는 "save_to_disk"로 설정될 수 있다.

  1. controlledFrameEmbedderParent가 null이 아니면:
    1. controlledFrameEmbedderParent, url, target, targetNavigable, 그리고 windowOpenDisposition와 함께 "newwindow" 이벤트를 발화한다.

completely finish loading에 대해:

  1. 그렇지 않고 container가 null이 아니면, container가 주어졌을 때 DOM 조작 태스크 소스에 element task를 큐에 추가하여 container에서 load라는 이름의 이벤트를 발화한다.

  2. controlledFrameEmbedderParent를 document의 node navigable의 controlledFrameEmbedderParent로 둔다.
  3. controlledFrameEmbedderParent가 HTMLControlledFrameElement이면, controlledFrameEmbedderParent와 함께 "contentload" 이벤트를 발화한다.

loadstart, loadabort, loadcommit에 대한 몽키 패치는 다음과 같다.

  1. loadstart -> 탐색 진입점: 일반 탐색, 다시 로드, 순회에서.

  2. loadcommit -> 공통 탐색 완료 지점에서.

  3. loadabort -> loadstart와 loadcommit 사이의 알고리즘의 각 조기 종료 지점에서.

이들 각각에 대해 navigable의 top-level traversable이 HTMLControlledFrameElement의 controlledFrameEmbedderParent를 가지는지 확인하고, 그렇다면 입력 인수와 함께 해당 이벤트를 발화한다.

3.7.13.2. [FETCH]

HTTP fetch(loadredirect)에 대해:

  1. internalResponse의 status가 redirect status이면:

    1. request의 window window가 environment settings object이고, 그 전역 객체가 Window 객체이면:
      1. currentNavigable를 window의 관련 navigable로 둔다.
      2. controlledFrameEmbedderParent를 currentNavigable의 top-level traversable의 controlledFrameEmbedderParent로 둔다.
      3. controlledFrameEmbedderParent가 HTMLControlledFrameElement이면:

        1. oldUrl를 request의 관련 URL로 둔다.

        1. newUrl를 response의 location url로 둔다.

        1. isTopLevel를 false로 두고, currentNavigable의 parent가 null이면 isTopLevel를 true로 설정한다.

        1. controlledFrameEmbedderParent, oldUrl, newUrl, 그리고 isTopLevel와 함께 "loadredirect" 이벤트를 발화한다.

3.7.13.3. [Permissions]

새 알고리즘을 정의한다.

Document document가 DOMString permission, 선택적인 dictionary options, 그리고 boolean을 받는 알고리즘 completionSteps가 주어졌을 때 삽입자에 의해 permission을 사용하도록 허용되는지를 판단하려면, 다음 단계를 실행한다.

  1. controlledFrameEmbedderParent를 document의 node navigable의 controlledFrameEmbedderParent로 둔다.

  2. controlledFrameEmbedderParent가 HTMLControlledFrameElement가 아니면, true를 반환한다.

  3. document, controlledFrameEmbedderParent, permission, document의 URL, options, 그리고 completionSteps와 함께 "permissionrequest" 이벤트를 발화한다.

request a position (geolocation)에 대해:

  1. document가 "geolocation" 기능을 사용하도록 허용되지 않으면:

    1. watchId가 전달되었으면, watchIDs에서 watchId를 제거한다.

    2. errorCallback과 PERMISSION_DENIED를 전달하여 error로 콜백한다.

    3. 이 알고리즘을 종료한다.

  2. blockedByEmbedder를 false로 둔다.
  3. document가 "geolocation" 기능을 삽입자에 의해 사용하도록 허용되는지를 확인한다. 이때 자신의 boolean 인수를 blockedByEmbedder에 할당하고 이 단계들의 나머지를 계속하는 알고리즘이 주어진다.
  4. blockedByEmbedder가 true이면:
    1. watchId가 전달되었으면, watchIDs에서 watchId를 제거한다.
    2. errorCallback과 PERMISSION_DENIED를 전달하여 error로 콜백한다.
    3. 이 알고리즘을 종료한다.
  5. controlledFrameEmbedderParent를 document의 node navigable의 controlledFrameEmbedderParent로 둔다.
  6. controlledFrameEmbedderParent가 HTMLControlledFrameElement이면:
    1. nodeDocument를 controlledFrameEmbedderParent의 node document로 둔다.

    2. nodeDocument가 null이면:
      1. watchId가 전달되었으면, watchIDs에서 watchId를 제거한다.
      2. errorCallback과 PERMISSION_DENIED를 전달하여 error로 콜백한다.
      3. 이 알고리즘을 종료한다.
    3. embedderNavigator를 nodeDocument의 전역 객체의 관련 Navigator로 둔다.
    4. embedderGeolocation를 embedderNavigator의 geolocation으로 둔다.
    5. embedderGeolocation, successCallback, errorCallback, options, 그리고 whatchId와 함께 request a position한 결과를 반환한다.

참고: 다른 권한도 geolocation과 유사하게 몽키 패치될 것이다. 그러나 이 문서에서는 간결성을 위해 세부 사항을 생략한다.

3.7.13.4. [Console]

Logger에 대해:

  1. 그렇지 않으면, Printer(logLevel, Formatter(args))를 수행한다.

  2. logLevel, Formatter(args)와 함께 "consolemessage" 이벤트를 발화한다.

참고: Console은 기본적으로 document와의 관련성이 없으므로, 관련 HTMLControlledFrameElement를 추적할 수 없다.

3.8. 다른 명세와의 통합

이 명세는 Controlled Frame의 요구 사항을 수용하기 위해 명세들에 일부 수정을 가할 것이다.

3.8.1. 몽키 패치

3.8.1.1. [HTML]

각 navigable은 다음을 가진다.

navigable navigable와 선택적인 navigable-or-null parent (기본값 null)가 주어졌을 때의 initialize the navigable 알고리즘은 다음과 같이 몽키 패치된다.

  1. navigable의 parent를 parent로 설정한다.

  2. parent가 null이 아니면(navigable이 top-level traversable이 아니면), 다음을 실행한다.
    1. topLevelTraversable를 navigable이 자손인 top-level traversable로 둔다.
    2. navigable의 frameId를 topLevelTraversable의 next frameId로 설정한다.
    3. topLevelTraversable의 next frameId를 증가시킨다.

Document document에 대한 update the current document readiness를 readinessValue로 하는 알고리즘은 다음과 같이 몽키 패치된다.

  1. runAt를 readinessValue에 다음 매핑을 적용한 결과로 둔다.
    "loading"

    "document-start"

    "interactive"

    "document-end"

    "complete"

    "document-idle"

  2. document와 runAt가 주어졌을 때 콘텐츠 스크립트를 문서에 삽입한다.
  3. document에서 readystatechange 라는 이름의 이벤트를 발화한다.

3.8.1.2. [FETCH]

determine the network partition key 알고리즘은 Controlled Frame의 삽입된 navigable에서 시작되는 네트워크 요청에 대해 double-keying을 요구하도록 몽키 확장된다.

environment environment가 주어졌을 때, network partition key를 결정하려면:
  1. topLevelOrigin이 주어졌을 때 site를 얻은 결과를 topLevelSite로 둔다.

  2. secondKey를 null 또는 구현 정의 값 로 둔다.

  3. controlledFrameEmbedderParent를 environment가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과로 둔다.
  4. controlledFrameEmbedderParent가 null이 아니면, secondKey를 controlledFrameEmbedderParent의 관련 설정 객체의 최상위 출처와 controlledFrameEmbedderParent의 partition으로 구성된 튜플로 설정한다.
  5. (topLevelSite, secondKey)를 반환한다.

3.8.1.3. [STORAGE]

Storage keys는 다음과 같이 재정의된다.

storage key는 embedding origin (origin 또는 null), partition (DOMString 또는 null), 그리고 origin (origin)으로 구성된 튜플이다.

참고: 이 정의는 storage partitioning이 완전히 명세화되면 앞으로 origin에 더해 삽입된 콘텐츠의 최상위 출처를 포함하도록 확장되어야 한다.

참고: Controlled Frame 데이터는 Controlled Frame 요소를 소유하는 최상위 문서가 아니라, Controlled Frame 요소를 소유하는 문서의 출처와 함께 triple keyed된다.

obtain a storage key for non-storage purposes 알고리즘은 controlledframe의 삽입된 navigable에 속하는 모든 storage에 대해 double-keying을 요구하도록 확장된다.

environment environment가 주어졌을 때 비-storage 목적을 위한 storage key를 얻으려면, 다음 단계를 실행한다.
  1. environment가 environment settings object이면 environment의 origin을, 그렇지 않으면 environment의 creation URL의 origin을 origin으로 둔다.

  2. origin으로 구성된 튜플을 반환한다.
  3. topLevelOrigin과 partition을 null로 둔다.
  4. controlledFrameEmbedderParent를 environment가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과로 둔다.
  5. controlledFrameEmbedderParent가 null이 아니면:
    1. topLevelOrigin을 controlledFrameEmbedderParent의 관련 설정 객체의 최상위 출처로 설정한다.
    2. partition을 controlledFrameEmbedderParent의 partition으로 설정한다.
  6. topLevelOrigin, partition, 그리고 origin으로 구성된 튜플을 반환한다.
environment environment가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻으려면, 다음 단계를 실행한다.
  1. environment가 environment settings object이고, 그 전역 객체가 Window 객체이면:

    이 알고리즘은 Shared Worker나 Service Worker에 대해 작동하지 않는다. controlledFrameEmbedderParent는 navigable에만 정의되어 있고, 비-Window environment에서 navigable로 가는 것이 항상 가능하지는 않기 때문이다.

    1. navigable을 environment의 전역 객체의 navigable로 둔다.

    2. top을 navigable의 top-level traversable로 둔다.

    3. top의 controlledFrameEmbedderParent가 null이 아니면, top의 controlledFrameEmbedderParent를 반환한다.

  2. null을 반환한다.

4. Web Request API

enum ResourceType {
  "main-frame",
  "sub-frame",
  "stylesheet",
  "script",
  "image",
  "font",
  "object",
  "xmlhttprequest",
  "ping",
  "csp-report",
  "media",
  "websocket",
  "other",
};

enum RequestedHeaders {
  "none",
  "cors",
  "all",
};

enum ConnectionState {
  "broken", "insecure", "secure"
};

dictionary Fingerprint {
  required DOMString sha256;
};

dictionary CertificateInfo {
  required Fingerprint fingerprint;
  Uint8Array rawDER;
};

dictionary SecurityInfo {
  required sequence<CertificateInfo> certificates;
  required ConnectionState state;
};

dictionary WebRequestInterceptorOptions {
  required sequence<(URLPattern or URLPatternInput)> urlPatterns;
  sequence<ResourceType> resourceTypes = [];
  boolean blocking = false;
  boolean includeRequestBody = false;
  RequestedHeaders includeHeaders = "none";
  boolean securityInfo = false;
  boolean securityInfoRawDer = false;
};

[Exposed=Window, IsolatedContext]
interface WebRequest {
  WebRequestInterceptor createWebRequestInterceptor(
      WebRequestInterceptorOptions options);
};

[Exposed=Window, IsolatedContext]
interface WebRequestInterceptor : EventTarget {
  attribute EventHandler onauthrequired;
  attribute EventHandler onbeforeredirect;
  attribute EventHandler onbeforerequest;
  attribute EventHandler onbeforesendheaders;
  attribute EventHandler oncompleted;
  attribute EventHandler onerroroccurred;
  attribute EventHandler onheadersreceived;
  attribute EventHandler onsendheaders;
  attribute EventHandler onresponsestarted;
};

enum DocumentLifecycle {
  "prerender",
  "active",
  "cached",
  "pending-deletion",
};

enum FrameType {
  "outermost-frame",
  "fenced-frame",
  "sub-frame",
};

[Exposed=Window, IsolatedContext]
interface UploadData {
  readonly attribute ArrayBuffer? bytes;
  readonly attribute DOMString? file;
};

[Exposed=Window, IsolatedContext]
interface RequestBody {
  readonly attribute DOMString? error;
  readonly attribute any formData;
  readonly attribute FrozenArray<UploadData>? raw;
};

[Exposed=Window, IsolatedContext]
interface WebRequestRequest {
  readonly attribute DOMString method;
  readonly attribute DOMString id;
  readonly attribute ResourceType type;
  readonly attribute USVString url;
  readonly attribute USVString? initiator;
  readonly attribute Headers? headers;
  readonly attribute RequestBody? body;
};

[Exposed=Window, IsolatedContext]
interface AuthChallenger {
  readonly attribute DOMString host;
  readonly attribute long port;
};

[Exposed=Window, IsolatedContext]
interface WebRequestAuthDetails {
  readonly attribute AuthChallenger challenger;
  readonly attribute boolean isProxy;
  readonly attribute DOMString scheme;
  readonly attribute DOMString? realm;
};

[Exposed=Window, IsolatedContext]
interface WebRequestResponse {
  readonly attribute long statusCode;
  readonly attribute DOMString statusLine;
  readonly attribute boolean fromCache;
  readonly attribute Headers? headers;
  readonly attribute DOMString? ip;
  readonly attribute USVString? redirectURL;
  readonly attribute WebRequestAuthDetails? auth;
};

[Exposed=Window, IsolatedContext]
interface WebRequestEvent : Event {
  readonly attribute WebRequestRequest request;
  readonly attribute long frameId;
  readonly attribute FrameType? frameType;
  readonly attribute DOMString? documentId;
  readonly attribute DocumentLifecycle? documentLifecycle;
  readonly attribute DOMString? parentDocumentId;
  readonly attribute long? parentFrameId;
};

dictionary WebRequestAuthCredentials {
  required DOMString username;
  required DOMString password;
};

dictionary WebRequestAuthOptions {
  AbortSignal signal;
};

[Exposed=Window, IsolatedContext]
interface WebRequestAuthRequiredEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;

  undefined setCredentials(
    Promise<WebRequestAuthCredentials> credentials,
    optional WebRequestAuthOptions options = {});
};

[Exposed=Window, IsolatedContext]
interface WebRequestBeforeRedirectEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
};

[Exposed=Window, IsolatedContext]
interface WebRequestBeforeRequestEvent : WebRequestEvent {
  undefined redirect(USVString redirectURL);
};

[Exposed=Window, IsolatedContext]
interface WebRequestBeforeSendHeadersEvent : WebRequestEvent {
  undefined setRequestHeaders((Headers or HeadersInit) requestHeaders);
};

[Exposed=Window, IsolatedContext]
interface WebRequestCompletedEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
};

[Exposed=Window, IsolatedContext]
interface WebRequestErrorOccurredEvent : WebRequestEvent {
  readonly attribute DOMString error;
};

[Exposed=Window, IsolatedContext]
interface WebRequestHeadersReceivedEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
  readonly attribute SecurityInfo? securityInfo;

  undefined redirect(USVString redirectURL);
  undefined setResponseHeaders((Headers or HeadersInit) responseHeaders);
};

[Exposed=Window, IsolatedContext]
interface WebRequestResponseStartedEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
};

[Exposed=Window, IsolatedContext]
interface WebRequestSendHeadersEvent : WebRequestEvent {};

각 WebRequest는 관련된 다음을 가진다.

참고: Interceptors는 controlledframe 요소의 이벤트 루프에 있는 태스크에서 쓰여지지만, fetch 중에는 병렬로 읽힌다.

적용 가능한 WebRequestInterceptors의 스냅샷은 WebRequest 이벤트를 디스패치하기 전에 생성된다. 이벤트를 처리하는 동안 WebRequestInterceptor에 등록된 이벤트 리스너는 해당 이벤트에 대해 발화되지 않는다.

각 WebRequestInterceptor는 관련된 다음을 가진다.

각 UploadData는 관련된 다음을 가진다.

각 RequestBody는 관련된 다음을 가진다.

각 WebRequestRequest는 관련된 다음을 가진다.

각 AuthChallenger는 관련된 다음을 가진다.

각 WebRequestAuthDetails는 관련된 다음을 가진다.

각 WebRequestResponse는 관련된 다음을 가진다.

각 WebRequestEvent는 관련된 다음을 가진다.

각 WebRequestAuthRequiredEvent는 관련된 다음을 가진다.

각 WebRequestBeforeRedirectEvent는 관련된 다음을 가진다.

각 WebRequestCompletedEvent는 관련된 다음을 가진다.

각 WebRequestErrorOccurredEvent는 관련된 다음을 가진다.

각 WebRequestHeadersReceivedEvent는 관련된 다음을 가진다.

각 WebRequestResponseStartedEvent는 관련된 다음을 가진다.

createWebRequestInterceptor(options) 메서드 단계는 다음과 같다.
  1. interceptor를 새 WebRequestInterceptor 객체로 둔다.

  2. interceptor에 다음 필드를 설정한다.

    resourceTypes

    options["resourceTypes"]

    blocking

    options["blocking"]

    includeRequestBody

    options["includeRequestBody"]

    includeHeaders

    options["includeHeaders"]

    securityInfo

    options["securityInfo"]

    securityInfoRawDer

    options["securityInfoRawDer"]

  3. options["urlPatterns"] 안의 각 urlPattern에 대해 반복한다.

    1. urlPattern이 URLPattern이면, urlPattern을 interceptor의 urlPatterns에 append한다.

    2. 그렇지 않으면, urlPattern가 주어졌을 때 새 URLPattern을 interceptor의 urlPatterns에 append한다.

  4. interceptor를 this의 interceptors에 append한다.

  5. interceptor를 반환한다.

request request에 대한 적용 가능한 WebRequestInterceptor들을 얻으려면, 다음 단계를 실행한다.
  1. client를 request의 client로 둔다.

  2. client가 null이면, 빈 list와 false를 반환한다.

  3. window를 client가 주어졌을 때 environment settings object의 소유 Window로 둔다.

  4. window가 null이면, 빈 list와 false를 반환한다.

  5. navigable를 window의 navigable로 둔다.

  6. navigable 또는 그 controlledFrameEmbedderParent가 null이면, 빈 list와 false를 반환한다.

  7. controlledFrame를 navigable의 controlledFrameEmbedderParent로 둔다.

  8. applicableInterceptors를 빈 list로 둔다.

  9. controlledFrame의 request의 interceptors 안의 각 interceptor에 대해:

    1. request가 interceptor에 의해 intercepted되어서는 안 되면, continue한다.

    2. interceptor를 applicableInterceptors에 append한다.

  10. applicableInterceptors를 반환한다.

request request가 WebRequestInterceptor에 의해 intercepted되어야 하는지 판단하려면, 다음 단계를 실행한다.
  1. types를 interceptor의 resourceTypes로 둔다.

  2. types가 비어 있지 않고 request가 주어졌을 때 request의 ResourceType을 얻은 결과를 types가 contain하지 않으면, false를 반환한다.

  3. urlPatterns를 interceptor의 urlPatterns로 둔다.

  4. urlPatterns 안의 각 urlPattern에 대해:

    1. request의 URL이 urlPattern가 주어졌을 때 URLPattern과 일치하면, true를 반환한다.

  5. false를 반환한다.

environment settings object environment가 주어졌을 때, environment settings object의 소유 Window를 얻으려면, 다음 단계를 실행한다.
  1. global를 environment의 전역 객체로 둔다.

  2. global이 Window 객체이면, global를 반환한다.

  3. global이 DedicatedWorkerGlobalScope 객체이면, 다음을 실행한다.

    1. owner를 global로 둔다.

    2. owner가 DedicatedWorkerGlobalScope 객체인 동안:

      1. owner를 owner의 owner set[0]로 둔다.

    3. owner가 Document 객체이면, owner의 관련 전역 객체를 반환한다.

  4. null을 반환한다.

4.1. 이벤트

WebRequestInterceptor는 다음 이벤트를 발화한다.

이벤트 이름 인터페이스 발화되는 경우...
authrequired WebRequestAuthRequiredEvent intercepted된 request가 HTTP 401 (Unauthorized) 407 (Proxy Authentication Required) status를 가진 response를 받을 때.
beforeredirect WebRequestBeforeRedirectEvent intercepted된 request가 redirect response를 받을 때.
beforerequest WebRequestBeforeRequestEvent intercepted된 request가 처리되기 시작하려고 할 때.
beforesendheaders WebRequestBeforeSendHeadersEvent intercepted된 request의 request headers가 전송되려고 할 때.
completed WebRequestCompletedEvent intercepted된 request가 완료되었을 때.
erroroccurred WebRequestErrorOccurredEvent intercepted된 request를 처리하는 동안 오류가 발생했을 때.
headersreceived WebRequestHeadersReceivedEvent intercepted된 request가 response headers를 받을 때.
sendheaders WebRequestSendHeadersEvent intercepted된 request가 자신의 request headers를 전송할 때.
responsestarted WebRequestResponseStartedEvent intercepted된 request가 자신의 response를 받기 시작했을 때.

WebRequestInterceptor는 event handler IDL attributes로서, 다음 event handlers와 그에 대응하는 event handler event types를 지원한다.

Event handlers Event handler event types
onauthrequired authrequired
onbeforeredirect beforeredirect
onbeforerequest beforerequest
onbeforesendheaders beforesendheaders
oncompleted completed
onerroroccurred erroroccurred
onheadersreceived headersreceived
onsendheaders sendheaders
onresponsestarted responsestarted

각 WebRequestAuthRequiredEvent는 관련된 다음을 가진다.

WebRequestAuthRequiredEvent의 setCredentials(credentials, options) 메서드 단계는 다음과 같다.
  1. this의 authCredentials를 credentials로 설정한다.

  2. this의 options를 options로 설정한다.

WebRequestAuthRequiredEvent의 preventDefault() 메서드 단계는 this의 cancel을 true로 설정하는 것이다.

각 WebRequestBeforeRequestEvent는 관련된 다음을 가진다.

WebRequestBeforeRequestEvent의 redirect(redirectURL) 메서드 단계는 this의 redirectURL을 redirectURL로 설정하는 것이다.
WebRequestBeforeRequestEvent의 preventDefault() 메서드 단계는 this의 cancel을 true로 설정하는 것이다.

각 WebRequestBeforeSendHeadersEvent는 관련된 다음을 가진다.

WebRequestBeforeSendHeadersEvent의 setRequestHeaders(requestHeaders) 메서드 단계는 this의 requestHeaders를 requestHeaders로 설정하는 것이다.
WebRequestBeforeSendHeadersEvent의 preventDefault() 메서드 단계는 this의 cancel을 true로 설정하는 것이다.

각 WebRequestHeadersReceivedEvent는 관련된 다음을 가진다.

WebRequestHeadersReceivedEvent의 redirect(redirectURL) 메서드 단계는 this의 redirectURL을 redirectURL로 설정하는 것이다.
WebRequestHeadersReceivedEvent의 setResponseHeaders(responseHeaders) 메서드 단계는 this의 responseHeaders를 responseHeaders로 설정하는 것이다.
WebRequestHeadersReceivedEvent의 preventDefault() 메서드 단계는 this의 cancel을 true로 설정하는 것이다.

WebRequestEvent result는 다음 items를 가진 struct이다.

cancel

boolean, 처음에 false

redirectURL

USVString, 처음에 ""

authCredentials

WebRequestAuthCredentials 또는 null, 처음에 null

requestHeaders

header list, 처음에 «»

responseHeaders

header list, 처음에 «»

request request가 주어졌을 때 beforeRequest 이벤트를 처리하려면, 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. result를 WebRequestEvent result로 둔다.

  3. pendingHandlerCount를 0으로 둔다.

  4. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  5. controlledFrameEmbedderGlobal가 null이면 반환한다.

  6. interceptors 안의 각 interceptor에 대해:

    1. interceptor의 blocking이 true이면, pendingHandlerCount를 증가시킨다.

    2. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 beforerequest인 새 WebRequestBeforeRequestEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. interceptor의 includeRequestBody가 true이고 request의 body가 null이 아니면:

        1. requestBody를 새 RequestBody로 둔다.

        2. body를 request의 body로 둔다.

          TODO: 존재하는 경우 body의 stream을 직렬화한다.

        3. body의 source에 대해 switch한다.

          byte sequence

          직렬화된 body의 source와 같은 bytes를 가진 새 UploadData를 requestBody의 raw에 append한다.

          Blob

          직렬화된 body의 source와 같은 bytes를 가진 새 UploadData를 requestBody의 raw에 append한다.

          FormData
          1. formData를 «[]»로 둔다.

          2. body의 source의 entry list 안의 각 entry에 대해 반복한다.

            1. entry[1]에 대해 switch한다.

            File

            entry[1]의 name과 같은 file을 가진 새 UploadData를 requestBody의 raw에 append한다.

            USVString
            1. formData[entry[0]]이 존재하지 않으면, formData[entry[0]]을 빈 list와 같도록 설정한다.

            2. entry[1]을 formData[entry[0]]에 append한다.

          3. requestBody의 formData를 formData로 설정한다.

        4. event의 request의 body를 requestBody로 설정한다.

      4. event를 interceptor에 dispatch한다.

      5. event의 cancel이 true이면, result의 cancel을 true로 설정한다.

      6. event의 redirectURL이 null이 아니고 result의 redirectURL이 ""이면, result의 redirectURL을 event의 redirectURL로 설정한다.

      7. interceptor의 blocking이 true이면, pendingHandlerCount를 감소시킨다.

  7. pendingHandlerCount > 0이면, pendingHandlerCount가 0과 같아질 때까지 병렬로 기다린 다음, 이 단계들이 병렬로 가기 전에 어떻게 실행되었는지에 따라 request의 client의 전역 객체의 네트워킹 태스크 소스 또는 이 단계들이 처음 호출된 병렬 컨텍스트 중 하나에서 이 알고리즘의 나머지 단계를 계속할 전역 태스크를 큐에 추가한다.

  8. result를 반환한다.

request request가 주어졌을 때 beforeSendHeaders 이벤트를 처리하려면, 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. result를 WebRequestEvent result로 둔다.

  3. pendingHandlerCount를 0으로 둔다.

  4. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  5. controlledFrameEmbedderGlobal가 null이면 반환한다.

  6. interceptors 안의 각 interceptor에 대해:

    1. interceptor의 blocking이 true이면, pendingHandlerCount를 증가시킨다.

    2. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 beforesendheaders인 새 WebRequestBeforeSendHeadersEvent로 둔다.

      2. event, request, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestEvent를 채운다.

      3. event를 interceptor에 dispatch한다.

      4. event의 cancel이 true이면, result의 cancel을 true로 설정한다.

      5. event의 requestHeaders가 null이 아니면:

        1. result의 requestHeaders가 null이면, 이를 새 Headers로 설정한다.

        2. event의 requestHeaders 안의 각 header에 대해:

          1. header를 result의 requestHeaders에 append한다.

      6. interceptor의 blocking이 true이면, pendingHandlerCount를 감소시킨다.

  7. pendingHandlerCount > 0이면, pendingHandlerCount가 0과 같아질 때까지 병렬로 기다린 다음, 이 단계들이 병렬로 가기 전에 어떻게 실행되었는지에 따라 request의 client의 전역 객체의 네트워킹 태스크 소스 또는 이 단계들이 처음 호출된 병렬 컨텍스트 중 하나에서 이 알고리즘의 나머지 단계를 계속할 전역 태스크를 큐에 추가한다.

  8. result를 반환한다.

request request가 주어졌을 때 sendHeaders 이벤트를 처리하려면, 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  3. controlledFrameEmbedderGlobal가 null이면 반환한다.

  4. interceptors 안의 각 interceptor에 대해:

    1. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 sendheaders인 새 WebRequestSendHeadersEvent로 둔다.

      2. event, request, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestEvent를 채운다.

      3. event를 interceptor에 dispatch한다.

request request와 response response가 주어졌을 때 headersReceived 이벤트를 처리하려면, 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. result를 WebRequestEvent result로 둔다.

  3. pendingHandlerCount를 interceptor의 size로 둔다.

  4. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  5. controlledFrameEmbedderGlobal가 null이면 반환한다.

  6. interceptors 안의 각 interceptor에 대해:

    1. interceptor의 blocking이 true이면, pendingHandlerCount를 증가시킨다.

    2. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 headersreceived인 새 WebRequestHeadersReceivedEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. event의 response를 request, response, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestResponse 객체를 생성한 결과로 설정한다.

      4. interceptor의 securityInfo가 true이거나 interceptor의 securityInfoRawDer가 true이면:

        1. info를 response와 interceptor의 securityInfoRawDer가 주어졌을 때 보안 정보를 얻은 결과로 둔다.

        2. event의 securityInfo를 info로 설정한다.

      5. event를 interceptor에 dispatch한다.

      6. event의 cancel이 true이면, result의 cancel을 true로 설정한다.

      7. event의 redirectURL이 null이 아니고 result의 redirectURL이 ""이면, result의 redirectURL을 event의 redirectURL로 설정한다.

      8. event의 responseHeaders가 null이 아니면:

        1. result의 responseHeaders가 null이면, 이를 새 Headers로 설정한다.

        2. event의 responseHeaders 안의 각 header에 대해:

          1. header를 result의 responseHeaders에 append한다.

      9. interceptor의 blocking이 true이면, pendingHandlerCount를 감소시킨다.

  7. pendingHandlerCount > 0이면, pendingHandlerCount가 0과 같아질 때까지 병렬로 기다린 다음, 이 단계들이 병렬로 가기 전에 어떻게 실행되었는지에 따라 request의 client의 전역 객체의 네트워킹 태스크 소스 또는 이 단계들이 처음 호출된 병렬 컨텍스트 중 하나에서 이 알고리즘의 나머지 단계를 계속할 전역 태스크를 큐에 추가한다.

  8. result를 반환한다.

request request와 response response가 주어졌을 때 authRequired 이벤트를 처리하려면, 다음 단계를 실행한다.
  1. challenger를 response의 URL의 host 및 port와 같은 host 및 port를 가진 새 AuthChallenger로 둔다.

  2. response의 status가 401이면:

    1. isProxy를 false로 둔다.

    2. scheme을 response의 WWW-Authenticate 헤더에서 온 scheme으로 두되, [HTML] 명세에 정의된 대로 파싱하고, 헤더가 없거나 유효하지 않으면 null로 둔다.

    3. realm을 response의 WWW-Authenticate 헤더에서 온 realm으로 두되, [HTML] 명세에 정의된 대로 파싱한다.

  3. 그렇지 않으면:

    1. isProxy를 true로 둔다.

    2. scheme을 response의 Proxy-Authenticate 헤더에서 온 scheme으로 두되, [HTML] 명세에 정의된 대로 파싱하고, 헤더가 없거나 유효하지 않으면 null로 둔다.

    3. realm을 response의 Proxy-Authenticate 헤더에서 온 realm으로 두되, [HTML] 명세에 정의된 대로 파싱한다.

  4. scheme이 null이면 null을 반환한다.

  5. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  6. result를 WebRequestEvent result로 둔다.

  7. pendingHandlerCount를 0으로 둔다.

  8. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  9. controlledFrameEmbedderGlobal가 null이면 반환한다.

  10. interceptors 안의 각 interceptor에 대해:

    1. interceptor의 blocking이 true이면, pendingHandlerCount를 증가시킨다.

    2. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 authrequired인 새 WebRequestAuthRequiredEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. event의 response를 request, response, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestResponse 객체를 생성한 결과로 설정한다.

      4. event의 response의 auth를 새 WebRequestAuthDetails로 설정한다. 이때 그 challenger, isProxy, scheme, 그리고 realm 필드의 값은 각각 challenger, isProxy, scheme, 그리고 realm이다.

      5. event를 interceptor에 dispatch한다.

      6. credentials를 event의 authCredentials로 둔다.

      7. event의 cancel이 true이면, result의 cancel을 true로 설정한다.

      8. 그렇지 않고, credentials가 Promise이면, 다음을 실행한다.

        1. signal을 event의 options["signal"]로 둔다.

        2. done을 false로 둔다.

        3. signal이 AbortSignal이면, 다음 abort 알고리즘을 signal에 추가한다.

          1. result의 cancel을 true로 설정한다.

          2. done을 true로 설정한다.

        4. credentials가 이행되면, resolvedValue를 받는 다음 단계를 실행한다.

          1. resolvedValue가 "username"과 "password"와 같은 두 keys를 포함하는 dictionary이고, result의 authCredentials가 undefined이면, result의 authCredentials를 resolvedValue로 설정한다.

          2. done을 true로 설정한다.

        5. credentials가 거부되면, 다음 단계를 실행한다.

          1. done을 true로 설정한다.

          참고: 거부된 promise는 request를 취소하지 않지만, credentials는 서버에 제공되지 않는다.

        6. done이 true와 같아질 때까지 병렬로 기다린 다음, controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 이 알고리즘의 나머지 단계를 계속 실행한다.

      9. interceptor의 blocking이 true이면, pendingHandlerCount를 감소시킨다.

  11. pendingHandlerCount > 0이면, pendingHandlerCount가 0과 같아질 때까지 병렬로 기다린 다음, 이 단계들이 병렬로 가기 전에 어떻게 실행되었는지에 따라 request의 client의 전역 객체의 네트워킹 태스크 소스 또는 이 단계들이 처음 호출된 병렬 컨텍스트 중 하나에서 이 알고리즘의 나머지 단계를 계속할 전역 태스크를 큐에 추가한다.

  12. result를 반환한다.

request request와 response response가 주어졌을 때, beforeRedirect 이벤트를 처리하려면 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  3. controlledFrameEmbedderGlobal가 null이면 반환한다.

  4. interceptors 안의 각 interceptor에 대해:

    1. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 beforeredirect인 새 WebRequestBeforeRedirectEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. event의 response를 request, response, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestResponse 객체를 생성한 결과로 설정한다.

      4. response가 filtered response가 아니면 internalResponse를 response로 두고, 그렇지 않으면 response의 internal response로 둔다.

      5. event의 response의 redirectURL을 request의 current URL의 fragment가 주어졌을 때 internalResponse의 location URL로 설정한다.

      6. event를 interceptor에 dispatch한다.

request request와 response response가 주어졌을 때, responseStarted 이벤트를 처리하려면 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  3. controlledFrameEmbedderGlobal가 null이면 반환한다.

  4. interceptors 안의 각 interceptor에 대해:

    1. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 responsestarted인 새 WebRequestResponseStartedEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. event의 response를 request, response, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestResponse 객체를 생성한 결과로 설정한다.

      4. event를 interceptor에 dispatch한다.

request request와 response response가 주어졌을 때, completed 이벤트를 처리하려면 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  3. controlledFrameEmbedderGlobal가 null이면 반환한다.

  4. interceptors 안의 각 interceptor에 대해:

    1. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 completed인 새 WebRequestCompletedEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. event의 response를 request, response, 그리고 interceptor의 includeHeaders가 주어졌을 때 WebRequestResponse 객체를 생성한 결과로 설정한다.

      4. event를 interceptor에 dispatch한다.

request request와 response response가 주어졌을 때, errorOccurred 이벤트를 처리하려면 다음 단계를 실행한다.
  1. interceptors를 request의 적용 가능한 WebRequestInterceptors를 얻은 결과로 둔다.

  2. controlledFrameEmbedderGlobal를 request의 client가 주어졌을 때 environment의 controlledFrameEmbedderParent를 얻은 결과의 관련 전역 객체로 둔다.

  3. controlledFrameEmbedderGlobal가 null이면 반환한다.

  4. interceptors 안의 각 interceptor에 대해:

    1. controlledFrameEmbedderGlobal의 DOM 조작 태스크 소스에 전역 태스크를 큐에 추가하여 다음 단계를 실행한다.

      1. event를 이름이 erroroccurred인 새 WebRequestErrorOccurredEvent로 둔다.

      2. event, request, 그리고 "none"이 주어졌을 때 WebRequestEvent를 채운다.

      3. event의 error를 response 안의 오류를 설명하는 구현 정의 오류 메시지로 설정한다.

      4. event를 interceptor에 dispatch한다.

WebRequestEvent event, request request, 그리고 RequestedHeaders requestedHeaders가 주어졌을 때 WebRequestEvent를 채우려면, 다음 단계를 실행한다.
  1. environmentSettingsObject를 request의 client로 둔다.

  2. event에 다음 필드를 설정한다.

    frameId

    -1

  3. window를 environmentSettingsObject가 주어졌을 때 environment settings object의 소유 Window로 둔다.

  4. window가 null이 아니면:

    1. parentNavigable를 window의 navigable의 parent로 둔다.

    2. event의 다음 필드를 갱신한다.

      documentId

      environmentSettingsObject의 id.

      documentLifecycle

      window의 associated document가 주어졌을 때 Document의 DocumentLifecycle을 얻은 결과.

      frameId

      window의 navigable의 frameId.

      frameType

      window의 browsing context의 fenced frame config instance가 null이 아니면 "fenced-frame", parentNavigable가 null이면 "outermost-frame", 그렇지 않으면 "sub-frame".

    3. parentNavigable가 null이 아니면, event의 다음 값을 갱신한다.

      parentDocumentId

      parentNavigable의 활성 문서의 관련 전역 객체의 id.

      parentFrameId

      parentNavigable의 frameId.

  5. event의 request를 다음 필드를 가진 새 WebRequestRequest로 설정한다.

    url

    request의 URL list의 마지막 요소.

    method

    request의 method.

    initiator

    request의 origin이 주어졌을 때 origin의 직렬화.

    참고: opaque origin은 initiator가 DOMString "null"로 설정되는 결과를 낳는다.

    type

    request가 주어졌을 때 request의 ResourceType을 얻는 것을 호출한 결과.

    id

    request의 requestId.

  6. requestedHeaders가 "none"이 아니면, event의 request의 headers를 request의 header list, requestedHeaders, 그리고 isRequest가 true와 같음이 주어졌을 때 header list를 Headers 객체로 변환을 호출한 결과로 설정한다.

Document document가 주어졌을 때, 그 DocumentLifecycle을 얻으려면, 다음 단계를 실행한다.
  1. document의 unload counter > 0이면, "pending-deletion"을 반환한다.

  2. document의 node navigable이 null이 아니고 prerendering navigable이면, "prerender"을 반환한다.

  3. document가 salvageable이고 그 page showing을 가지지 않으면, "cached"를 반환한다.

  4. "active"를 반환한다.

request request, response response, 그리고 RequestedHeaders requestedHeaders가 주어졌을 때, WebRequestResponse 객체를 생성하려면 다음 단계를 실행한다.
  1. response를 다음 필드를 가진 새 WebRequestResponse로 둔다.

    statusCode

    response의 status.

    statusLine

    response의 status message.

    fromCache

    response의 cache state가 "local"이면 true, 그렇지 않으면 false.

    ip

    request가 네트워크 request를 포함한 경우, response가 수신된 ip address.

    [FETCH] 명세는 현재 request를 전송할 때 사용된 원격 IP 주소 저장을 명세하지 않는다.

  2. requestedHeaders가 "none"이 아니면, response의 headers를 response의 header list, requestedHeaders, 그리고 isRequest가 false와 같음이 주어졌을 때 header list를 Headers 객체로 변환을 호출한 결과로 설정한다.

  3. response를 반환한다.

response response와 boolean includeRawDER가 주어졌을 때 보안 정보를 얻으려면, 다음 단계를 실행한다.
  1. info를 새 SecurityInfo로 둔다.

  2. scheme을 response의 url의 scheme으로 둔다.

  3. scheme이 "http" 또는 "ws"이면:

    1. info["state"]를 "insecure"로 설정한다.

    2. info를 반환한다.

  4. info["state"]를 "secure"로 설정한다.

    참고: 브라우저는 일반적으로 인증서 오류가 발생한 연결을 중단한다. 사용자가 명시적으로 허용한 경우, state는 대신 "broken"으로 설정될 수 있다.

  5. leafCert를 response와 관련된 서버의 X.509 인증서([RFC5280]에 정의된 대로)로 둔다.

  6. derBytes를 leafCert를 DER-인코딩한 결과([X.690]에 정의된 대로)로 둔다.

  7. certInfo를 새 CertificateInfo로 둔다.

  8. fingerprint를 새 Fingerprint로 둔다.

  9. fingerprint 문자열을 계산한다.

    1. hashBytes를 derBytes에 SHA-256 알고리즘([RFC6234]에 정의된 대로)을 수행한 결과로 둔다.

    2. hexString을 빈 문자열로 둔다.

    3. hashBytes 안의 각 byte byte에 대해:

      1. hexString이 비어 있지 않으면, U+003A (:)를 hexString에 append한다.

      2. hexPair를 byte를 나타내는 두 ASCII 대문자 16진 숫자로 구성된 문자열로 둔다.

      3. hexPair를 hexString에 append한다.

    4. fingerprint["sha256"]을 hexString으로 설정한다.

  10. certInfo["fingerprint"]를 fingerprint로 설정한다.

  11. includeRawDER가 true이면:

    1. arrayBuffer를 derBytes에서 ArrayBuffer를 생성한 결과로 둔다.

    2. certInfo["rawDER"]를 arrayBuffer를 보는 새 Uint8Array 객체로 설정한다.

  12. certList를 빈 list로 둔다.

  13. certInfo를 certList에 append한다.

  14. info["certificates"]를 certList로 설정한다.

  15. info를 반환한다.

header list fetchHeaders, RequestedHeaders requestedHeaders, 그리고 boolean isRequest가 주어졌을 때, header list를 Headers 객체로 변환하려면, 다음 단계를 실행한다.
  1. requestedHeaders가 "none"이 아니라고 assert한다.

  2. headers를 새 Headers 객체로 둔다.

  3. fetchHeaders 안의 각 fetchHeader에 대해:

    1. 다음 조건이 모두 충족되면 continue한다.

    2. 다음 조건이 모두 충족되면 continue한다.

    3. fetchHeader를 headers에 append한다.

  4. headers를 반환한다.

request request가 주어졌을 때 request의 ResourceType을 얻으려면, 다음 단계를 실행한다.
  1. request의 url의 scheme이 "ws" 또는 "wss"와 같으면, "websocket"을 반환한다.

  2. request의 initiator가 "fetch" 또는 "xmlhttprequest"와 같으면, "xmlhttprequest"를 반환한다.

  3. request의 destination이 "document"와 같으면, "main-frame"을 반환한다.

  4. request의 destination이 "frame" 또는 "iframe"과 같으면, "sub-frame"을 반환한다.

  5. request의 destination이 "style" 또는 "xslt"와 같으면, "stylesheet"을 반환한다.

  6. request의 destination이 "script", "json", "audioworklet", "paintworklet", "serviceworker", "sharedworker", 또는 "worker"와 같으면, "script"를 반환한다.

  7. request의 destination이 "image"와 같으면, "image"를 반환한다.

  8. request의 destination이 "font"와 같으면, "font"를 반환한다.

  9. request의 destination이 "object" 또는 "embed"와 같으면, "object"를 반환한다.

  10. request의 destination이 "audio", "track", 또는 "video"와 같으면, "media"를 반환한다.

  11. request의 destination이 "report"와 같으면, "csp-report"를 반환한다.

  12. request의 destination이 ""와 같고 request의 keepalive가 true이면, "ping"을 반환한다.

  13. "other"를 반환한다.

DOMString redirectUrl이 주어졌을 때 redirect response를 생성하려면, 다음 필드를 가진 response를 반환한다.
status

301

header list

« ("Location", redirectUrl) »

4.2. 몽키 패치

4.2.1. Fetch

request는 관련된 requestId를 가지며, 이는 request 생성 시 무작위로 할당되는 opaque 문자열이다.

main fetch 알고리즘은 다음과 같이 몽키 패치된다.

  1. request를 fetchParams의 request로 둔다.

  2. response를 null로 둔다.

  3. webRequestResult를 request가 주어졌을 때 beforeRequest 이벤트를 처리를 호출한 결과로 둔다.
  4. webRequestResult가 null이 아니면:
    1. webRequestResult의 cancel이 true이면, response를 network error로 설정한다.
    2. 그렇지 않고, webRequestResult의 redirectURL이 빈 DOMString이 아니면, response를 webRequestResult의 redirectURL이 주어졌을 때 redirect response를 생성한 결과로 설정한다.

fetch response handover 알고리즘은 다음과 같이 몽키 패치된다.

  1. response가 network error가 아니면, fetchParams의 request와 response가 주어졌을 때 responseStarted 이벤트를 처리를 호출한다.
  2. timingInfo를 fetchParams의 timing info로 둔다.

⋮

  1. fetchParams의 process response consume body가 null이 아니면:

    …

  2. response가 network error가 아니면, fetchParams의 request와 response가 주어졌을 때 completed 이벤트를 처리를 호출한다.
  3. 그렇지 않으면, fetchParams의 request와 response가 주어졌을 때 errorOccurred 이벤트를 처리를 호출한다.

HTTP-network-or-cache fetch 알고리즘은 다음과 같이 몽키 패치된다.

  1. revalidatingFlag를 설정되지 않은 상태로 둔다.

  2. webRequestResult를 request가 주어졌을 때 beforeSendHeaders 이벤트를 처리를 호출한 결과로 설정한다.
  3. webRequestResult가 null이 아니면:
    1. webRequestResult의 cancel이 true이면, response를 network error로 설정한다.
    2. 그렇지 않고, webRequestResult의 requestHeaders가 비어 있지 않은 list이면, request의 header list를 webRequestResult의 requestHeaders의 header list로 설정한다.
  4. response가 null이 아니면, 이 단계들을 실행하되, fetchParams가 취소되면 중단한다.

    ⋮

  5. 중단되었으면, fetchParams에 대한 적절한 network error를 반환한다.

  6. response가 null이면:

    1. httpRequest의 cache mode가 "only-if-cached"이면, network error를 반환한다.

    2. request가 주어졌을 때 sendHeaders 이벤트를 처리를 호출한다.
    3. forwardResponse를 httpFetchParams, includeCredentials, 그리고 isNewConnectionFetch가 주어졌을 때 HTTP-network fetch를 실행한 결과로 둔다.

    4. webRequestResult를 forwardResponse가 network error가 아니면 request와 forwardResponse가 주어졌을 때 headersReceived 이벤트를 처리를 호출한 결과로 두고, 그렇지 않으면 null로 둔다.
    5. webRequestResult가 null이 아니면:
      1. webRequestResult의 cancel이 true이면, response를 network error로 설정한다.
      2. 그렇지 않고, webRequestResult의 redirectURL이 빈 DOMString이 아니면, forwardResponse를 webRequestResult의 redirectURL이 주어졌을 때 redirect response를 생성한 결과로 설정한다.
      3. 그렇지 않고, webRequestResult의 responseHeaders가 비어 있지 않은 list이면, forwardResponse의 header list를 webRequestResult의 responseHeaders의 header list로 설정한다.

⋮

  1. response의 status가 401이고, httpRequest의 response tainting이 "cors"가 아니며, includeCredentials가 true이고, request의 window가 environment settings object이면:

    ⋮

    1. request의 use-URL-credentials flag가 설정되어 있지 않거나 isAuthenticationFetch가 true이면:

      1. fetchParams가 취소되었으면, fetchParams에 대한 적절한 network error를 반환한다.

      2. username과 password를 null로 둔다.

      3. webRequestResult를 request와 response가 주어졌을 때 authRequired 이벤트를 처리를 호출한 결과로 둔다.
      4. webRequestResult가 null이 아니면:
        1. webRequestResult의 cancel이 true이면, response를 network error로 설정한다.
        2. 그렇지 않고, webRequestResult의 authCredentials가 object이면:
          1. username을 webRequestResult의 authCredentials["username"]으로 설정한다.
          2. password를 webRequestResult의 authCredentials["password"]로 설정한다.
      5. username과 password가 null이면, 이를 request의 window에서 최종 사용자에게 username과 password를 각각 요청한 결과로 설정한다.
  2. response의 status가 407이면:

    1. webRequestResult를 request와 response가 주어졌을 때 authRequired 이벤트를 처리를 호출한 결과로 둔다.
    2. webRequestResult가 null이 아니면:
      1. webRequestResult의 cancel이 true이면, response를 network error로 설정한다.
      2. 그렇지 않고, webRequestResult의 authCredentials가 object이면:
        1. webRequestResult의 authCredentials를 proxy-authentication entry로 저장한다.
    3. 그렇지 않으면, 적절하게 최종 사용자에게 요청한다 ...

HTTP-redirect fetch 알고리즘은 다음과 같이 몽키 패치된다.

  1. request와 response가 주어졌을 때 beforeRedirect 이벤트를 처리를 호출한다.
  2. request를 fetchParams의 request로 둔다.

5. 컨텍스트 메뉴 API

enum ContextType {
    "all",
    "page",
    "frame",
    "selection",
    "link",
    "editable",
    "image",
    "video",
    "audio",
};

enum ItemType {
    "normal",
    "checkbox",
    "radio",
    "separator",
};

dictionary ContextMenusProperties {
    boolean checked;
    sequence<ContextType> contexts;
    sequence<(URLPattern or URLPatternInput)> documentURLPatterns;
    boolean enabled;
    DOMString parentId;
    sequence<(URLPattern or URLPatternInput)> targetURLPatterns;
    DOMString title;
    ItemType type;
};

dictionary ContextMenusCreateProperties : ContextMenusProperties {
    required DOMString id;
};

[Exposed=Window, IsolatedContext]
interface ContextMenus : EventTarget {
    Promise<undefined> create(ContextMenusCreateProperties properties);
    Promise<undefined> remove(DOMString id);
    Promise<undefined> removeAll();
    Promise<undefined> update(DOMString id, optional ContextMenusProperties properties = {});

    attribute EventHandler onclick;
    attribute EventHandler onshow;
};

[Exposed=Window, IsolatedContext]
interface MenuItemDetails {
    readonly attribute DOMString id;
    readonly attribute DOMString? parentMenuId;
    readonly attribute boolean? checked;
    readonly attribute boolean? wasChecked;
};

[Exposed=Window, IsolatedContext]
interface ContextMenusClickEvent : Event {
  readonly attribute MenuItemDetails menuItem;

  // Details about the frame the context menu is opened within.
  readonly attribute long frameId;
  readonly attribute USVString frameURL;
  readonly attribute USVString pageURL;

  // Details about the element the context menu is opened within the context of.
  readonly attribute boolean editable;
  readonly attribute USVString? linkURL;
  readonly attribute DOMString? mediaType;
  readonly attribute DOMString? selectionText;
  readonly attribute USVString? srcURL;
};

각 controlledframe는 contextMenus 멤버를 가지며, 이는 ContextMenus이다. 각 ContextMenus는 context menu map을 관리한다. 그 keys는 menu item id를 나타내는 DOMString이고, 그 values는 ContextMenusProperties이다.

context menu map의 각 entry는 context menu item을 나타낸다. context menu item은 context menu 안의 항목을 나타낸다. 각 context menu item은 관련된 다음을 가진다.

context menu는 context menu items를 사용자에게 표시할 수 있는 구현 정의 인터페이스를 나타낸다. 각 context menu는 관련된 context element를 가지며, 이는 context menu가 그 컨텍스트 안에서 열린 HTMLElement이다.

context menu item item은 item이 주어졌을 때 context menu item이 표시될지 판단한 결과가 true를 반환하면, 구현 정의 동작의 결과로 사용자에게 표시되어야 한다.

참고: 이 API의 의도는 context-dependent 추가 동작을 사용자에게 노출하는 것이다. 데스크톱 플랫폼에서는 Controlled Frame 안의 콘텐츠를 오른쪽 클릭하여 접근하는 context menu의 항목 형태일 수 있고, 모바일 장치에서는 Controlled Frame 안의 항목을 길게 눌러 접근할 수 있다. 이 예들에서 context menu의 context element는 사용자가 오른쪽 클릭하거나 길게 누른 요소가 된다.

context menu map의 values인 ContextMenusProperties 객체들은 context menu items가 표시되는 조건뿐 아니라 항목의 기능과 동작도 제어한다.

이 섹션은 비규범적이다.

ContextMenusProperties는 다음 필드를 가진다.

contexts

서로 다른 ContextType의 list. 이것이 비어 있지 않으면, context menu를 열기 위해 클릭된 요소가 list items 중 하나와 같지 않는 한 context menu item은 표시되지 않는다. 이것이 비어 있으면, 이 검사는 무시된다.

documentURLPatterns

URLPattern들 또는 URLPatternInput들의 list. 이것이 비어 있지 않으면, 삽입된 문서의 URL이 URLPattern과 일치하되 그 패턴이 list items 중 하나인 경우가 아니면 context menu item은 표시되지 않는다. 이것이 비어 있으면, 이 검사는 무시된다.

targetURLPatterns

URLPattern들 또는 URLPatternInput들의 list. 이것이 비어 있지 않으면, context menu의 대상의 URL이 URLPattern과 일치하되 그 패턴이 list items 중 하나인 경우가 아니면 context menu item은 표시되지 않는다. 이것이 비어 있으면, 이 검사는 무시된다.

참고: Target은 img/audio/video 태그의 "src" 속성과 anchor 태그의 "href"이다.

parentId

부모 context menu item의 ID. 해당 context menu item은 부모의 하위 메뉴 아래에 나타날 수 있다.

title

menu item의 제목. 이는 type이 "separator"가 아닌 한 필수이다.

type

menu item의 타입.

checked

type이 checkbox인 경우, context menu item이 초기에 체크되어 있는지 여부.

enabled

context menu item이 활성화되어 있는지 여부.

create(properties) 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고 다음 단계를 병렬로 실행한다.

  4. contextMenusMap을 controlledframe의 context menu map으로 둔다.

  5. id를 properties["id"]로 둔다.

  6. contextMenusMap[id]가 존재하면, controlledframe, p, 그리고 TypeError가 주어졌을 때 embedder promise를 거부하고, 이 단계를 중단한다.

  7. contextMenusMap[id]를 properties로 설정한다.

  8. controlledframe와 p가 주어졌을 때 embedder promise를 해결한다.

remove(id) 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고 다음 단계를 병렬로 실행한다.

  4. contextMenusMap을 controlledframe의 context menu map으로 둔다.

  5. contextMenusMap[id]를 제거한다.

  6. controlledframe와 p가 주어졌을 때 embedder promise를 해결한다.

removeAll() 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고 다음 단계를 병렬로 실행한다.

  4. contextMenusMap을 controlledframe의 context menu map으로 둔다.

  5. contextMenusMap을 비운다.

  6. controlledframe와 p가 주어졌을 때 embedder promise를 해결한다.

update(id, properties) 메서드 단계는 다음과 같다.

  1. p를 새 promise로 둔다.

  2. controlledframe를 this로 둔다.

  3. p를 반환하고 다음 단계를 병렬로 실행한다.

  4. contextMenusMap을 controlledframe의 context menu map으로 둔다.

  5. contextMenusMap[id]가 존재하지 않으면, controlledframe, p, 그리고 TypeError가 주어졌을 때 embedder promise를 거부하고, 이 단계를 중단한다.

  6. contextMenusMap[id]를 properties로 설정한다.

  7. controlledframe와 p가 주어졌을 때 embedder promise를 해결한다.

이 섹션은 비규범적이다.

ContextType들은 context menu의 컨텍스트를 나타내며, 다음 값을 가질 수 있다.

frame

사용자가 iframe과 같은 중첩 frame 안에서 context-click할 때 적용된다.

selection

문서의 일부가 선택되었을 때 적용된다.

link

사용자가 링크를 context-click할 때 적용된다.

editable

사용자가 textarea와 같은 편집 가능한 요소를 context-click할 때 적용된다.

image

사용자가 이미지를 context-click할 때 적용된다.

video

사용자가 video 요소를 context-click할 때 적용된다.

audio

사용자가 audio 요소를 context-click할 때 적용된다.

page

사용자가 페이지 안에서 context-click했지만, 다른 page context가 적용되지 않을 때 적용된다(예를 들어 클릭이 이미지나 중첩 iframe 또는 링크 위에서 발생하지 않은 경우).

all

all을 지정하는 것은 다른 모든 context의 조합과 동일하다.

context menu item item이 주어졌을 때 context menu item이 표시될지 판단 하려면:

  1. properties를 item의 properties로 둔다.

  2. element를 item의 menu의 context element로 둔다.

  3. controlledframe를 element의 node navigable의 controlledFrameEmbedderParent로 둔다.

  4. controlledframe가 null이면 false를 반환한다.

  5. documentUrl를 controlledframe의 삽입된 navigable의 활성 문서의 URL로 둔다.

  6. targetUrl를 빈 문자열로 둔다.

  7. element가 HTMLImageElement의 인스턴스이면, targetUrl를 element의 src 속성으로 설정한다.

  8. element가 HTMLMediaElement의 인스턴스이면, targetUrl를 element의 src 속성으로 설정한다.

  9. element가 HTMLAnchorElement의 인스턴스이면, targetUrl를 element의 href 속성으로 설정한다.

  10. properties["contexts"]가 비어 있지 않으면:

    1. matchesContext를 처음에 false인 boolean 값으로 둔다.

    2. properties["contexts"] 안의 각 context에 대해:

      1. element가 context와 일치하면, matchesContext를 true로 설정하고 break한다.

        ContextType 일치 동작은 명세되어 있지 않지만, 위 참고에는 원하는 동작에 관한 일부 정보가 있다.

    3. matchesContext가 false이면 false를 반환한다.

  11. properties["documentURLPatterns"]가 비어 있지 않으면:

    1. matchesDocumentUrl를 처음에 false인 boolean 값으로 둔다.

    2. properties["documentURLPatterns"] 안의 각 urlPattern에 대해:

      1. urlPattern이 URLPatternInput이면, urlPattern를 urlPattern가 주어졌을 때 새 URLPattern으로 설정한다.

      2. urlPattern가 주어졌을 때 documentUrl이 URLPattern과 일치하면, matchesDocumentUrl를 true로 설정하고 break한다.

    3. matchesDocumentUrl가 false이면 false를 반환한다.

  12. properties["targetURLPatterns"]가 비어 있지 않으면:

    1. matchesTargetUrl를 처음에 false인 boolean 값으로 둔다.

    2. properties["targetURLPatterns"] 안의 각 urlPattern에 대해:

      1. urlPattern이 URLPatternInput이면, urlPattern를 urlPattern가 주어졌을 때 새 URLPattern으로 설정한다.

      2. urlPattern가 주어졌을 때 targetUrl이 URLPattern과 일치하면, matchesTargetUrl를 true로 설정하고 break한다.

    3. matchesTargetUrl가 false이면 false를 반환한다.

  13. true를 반환한다.

5.1. 이벤트

ContextMenus는 다음 이벤트를 발화한다.

이벤트 이름 인터페이스 발화되는 경우...
show Event context menu가 사용자에게 표시될 때.
click ContextMenusClickEvent context menu item이 사용자에 의해 선택될 때.

ContextMenus는 event handler IDL attributes로서, 다음 event handlers와 그에 대응하는 event handler event types를 지원한다.

Event handlers Event handler event types
onshow show
onclick click

ContextMenus contextMenus의 하나 이상의 context menu items가 사용자에게 표시될 때, contextMenus에 show 이벤트를 dispatch한다.

context menu item item이 사용자에 의해 선택될 때, item이 주어졌을 때 click 이벤트를 dispatch한다.

ContextMenus contextMenus가 주어졌을 때 dispatch a show event를 하려면, 새 Event 를 show라는 이름으로 contextMenus에 dispatch한다.
context menu item item이 주어졌을 때 dispatch a click event를 하려면, 다음 단계를 실행한다.
  1. properties를 item의 properties로 둔다.

  2. menu를 item의 menu로 둔다.

  3. element를 menu의 context element로 둔다.

  4. event를 새 ContextMenusClickEvent로 두고, 그 이름은 click이다.

  5. event["menuItem"]를 다음 필드를 가진 새 MenuItemDetails로 설정한다.

    id

    item의 id.

    parentMenuId

    properties["parentId"].

    checked

    context menu item이 체크되어 있는지 여부.

    wasChecked

    클릭되기 전 checkbox 또는 radio item의 상태.

  6. event의 다음 필드를 설정한다.

    frameId

    element의 node navigable의 frameId.

    frameURL

    element의 node navigable의 URL.

    pageURL

    element의 traversable navigable의 URL.

    editable

    선택된 element가 텍스트 input처럼 편집 가능한지 여부.

    linkURL

    element가 HTMLAnchorElement의 인스턴스이면, element의 href attribute.

    mediaType

    element에 따라, 있는 경우 "image", "video", 또는 "audio" 중 하나.

    selectionText

    있는 경우 context selection의 텍스트.

    srcURL

    존재하는 경우 element의 "src" 속성.

  7. event를 menu에서 dispatch한다.

6. 사용 개요

Lorem ipsum. 여기에 기본 정보와 예제를 삽입한다.

7. 동기 부여 애플리케이션

이 섹션은 비규범적이다.

7.1. 가상화 세션의 지연 시간에 민감한 애플리케이션

가상화 환경에서 사용자는 일반적으로 전체 가상 데스크톱을 렌더링하는 로컬 씬 클라이언트를 가진다. 실제 데스크톱 실행 환경은 원격 가상화 서버에서 실행된다. 사용자의 브라우저가 지연 시간에 민감한 애플리케이션(예: 비디오 앱)으로 탐색하면, 렌더링된 콘텐츠에는 추가 지연 시간("lag")이 발생하여 사용자가 경험하기 어렵거나 불가능해진다. 이는 화상 회의 애플리케이션처럼 사용자를 녹화하는 애플리케이션에도 적용된다. 이러한 지연 시간에 민감한 애플리케이션에서 가상 데스크톱 애플리케이션은 지연 시간에 민감한 콘텐츠를 로컬에서 렌더링하고 이를 렌더링된 원격 콘텐츠 위에 오버레이하여 이 지연 시간을 줄일 수 있다. 이 사용 사례는 "browser content redirection"이라고도 알려져 있다.

7.2. 제한 없이 서드 파티 웹 콘텐츠 삽입

키오스크 환경에서 애플리케이션은 서드 파티의 콘텐츠를 로드하고 해당 콘텐츠를 애플리케이션 내부의 화면에 표시해야 한다. 교사가 navigation 이벤트를 트리거할 수도 있고, 쇼핑몰 관리자와 같은 관리자가 구성할 수도 있다. 콘텐츠는 X-Frame-Options와 CSP 사용을 통해 iframe에 의한 삽입을 금지할 수 있다. 그러나 controlled frame은 iframe에 의한 삽입을 금지하는 콘텐츠라도 모든 콘텐츠를 로드할 수 있어야 한다.

7.3. 웹 콘텐츠의 원격 표시와 조작

키오스크 환경에서 애플리케이션은 콘텐츠가 화면에 계속 표시되도록 해야 하며, 자신이 제공한 동작으로 콘텐츠를 중단해야 할 수도 있다. 이 동작은 관리자가 현장에 없어도 작동해야 하며, 이상적으로는 네트워크를 통해 원격으로 관리될 수 있다. 예를 들어 콘텐츠가 크래시되면, 이러한 애플리케이션은 콘텐츠를 새 삽입 뷰에서 다시 로드하여 크래시를 관찰하고 대응해야 한다.

7.4. 각 세션 후 사용자 콘텐츠 지우기

일부 환경에서는 누군가가 식당에서 주문하는 것처럼, 작업을 완료하기 위해 짧은 시간 동안만 단일 장치를 사용한다. 작업이 완료되면 임베더 애플리케이션은 작업과 관련된 모든 로컬 사용자 데이터를 지운 다음 삽입된 인스턴스를 다시 시작할 수 있어야 한다.

7.5. 유휴 세션 모니터링

사용자가 삽입된 콘텐츠와 상호 작용하는 동안, 사용자는 자신의 세션을 명시적으로 종료하지 않을 수 있다. 이 콘텐츠는 사용자가 실제로 작업을 완료했거나 완료하지 않고 떠났는데도 사용자가 있다고 가정할 수 있다. 임베더 애플리케이션은 사용자가 해당 사례의 임계값을 넘어 유휴 상태가 되는 시점을 감지하고 새 세션을 시작하기를 원한다.

7.6. 임의로 탐색 차단

임베더가 작성하지 않은 삽입된 웹 콘텐츠를 표시하는 동안, 페이지는 허용되지 않는 서드 파티 웹 콘텐츠로 링크될 수 있다. 임베더가 웹 콘텐츠에 대한 임의의 스크립트 삽입을 통해 삽입된 콘텐츠의 요소를 편집할 수 있도록 하면, 차단된 페이지로 navigation이 발생하지 않도록 보장할 수 있다. 임베더는 또한 Controlled Frame API를 사용하여 navigation 이벤트를 캡처하고 승인된 사이트의 페이지만 해당 controlled frame 안에 로드될 수 있도록 보장할 수 있다.

8. 보안, 개인정보 보호 및 접근성 고려 사항

이 섹션은 비규범적이다.

8.1. 보안

Controlled Frame은 [Isolated-Web-Apps] (IWA)에 기반하며 핵심 보안 명세와 통합된다

Controlled Frame은 특히 강력한 API이기 때문에, 이를 사용하거나 심지어 사용할 수 있게 하는 것만으로도 앱은 다양한 유형의 해킹 대상이 된다. 그 결과 이 API는 애플리케이션 개발자와 사용자를 보호하기 위한 추가 안전 장치가 마련된 IWA에서의 사용으로 제한된다. Isolated Web App 설명서는 다음과 같이 말한다.

"개발자가 애플리케이션을 XSS 또는 서버 측 공격의 매력적인 대상으로 만들 수 있는 API에 접근해야 하는 경우, 사용자 에이전트는 애플리케이션이 이 위협 모델을 채택하도록 강제할 수도 있다."

Controlled Frame은 바로 그러한 매력적인 대상이 되며, 이를 신중하게 노출하기 위해 특정 공격으로부터 보호하도록 IWA를 선택한다. 일반적으로 IWA는 애플리케이션의 각 리소스가 저장 중과 전송 중 모두 안전하다는 강력한 보안 보장을 제공한다. IWA 설명서와 IWA [High-Watermark-Permissions] 설명서에서 IWA 보안 및 권한에 대해 더 읽을 수 있다.

Controlled Frame은 [Permissions-Policy] 및 [Permissions]와 통합된다. Permissions Policy § 12. Privacy and Security 및 Permissions § E Security considerations에서 더 읽을 수 있다(해당 항목은 현재 내용이 적다는 점에 유의).

공격하는 웹 사이트는 원래 자신을 삽입할 수 없도록 하는 콘텐츠를 표시하고 non-IWA에서 사용자를 속일 수 있다.

계획된 완화책:

IWA는 Controlled Frame을 통해 또 다른 IWA(또는 자신)를 삽입하여 우리의 IWA 정책을 어떻게든 조작할 수 있다(예: Controlled Frame에 삽입된 IWA가 "controlled-frame" policy-controlled feature의 부재로 인해 자신이 삽입되었음을 감지할 수 있다).

계획된 완화책:

Controlled Frame은 강력한 <controlledframe> 요소에 접근할 수 있다.

Controlled Frame을 사용할 것으로 예상되지 않는 IWA가 콘텐츠를 삽입하려고 시도할 수 있다.

계획된 완화책:

IWA는 'http:' 또는 'isolated-app:' 같은 non-https scheme의 콘텐츠를 삽입하려고 시도할 수 있다

계획된 완화책:

악의적인 Controlled Frame은 임베더의 실행 중인 프로세스에 접근할 수 있다(예: Spectre 공격)

계획된 완화책:

주어진 "https origin"에 대한 Controlled Frame은 해당 https origin에 대한 사용자 자신의 storage 데이터와 상호 작용하거나 간섭할 수 있다

계획된 완화책:

악의적인 Controlled Frame은 임베더의 저장된 데이터를 덮어쓸 수 있다

계획된 완화책:

악의적인 Controlled Frame은 자신이 삽입되었음을 감지하고 임베더 애플리케이션을 공격하려고 시도할 수 있다

계획된 완화책:

아이디어:

사용자는 Controlled Frame에서 보고 있는 페이지의 origin을 확인하지 못할 수 있다

아이디어:

Controlled Frame은 오래된 브라우저 엔진의 취약점을 악용할 수 있다

이미 다음으로 해결됨:

8.2. 개인정보 보호

Controlled Frame은 Permissions Policy 및 Permissions와 통합된다. Permissions Policy § 12. Privacy and Security에서 더 읽을 수 있다. Permissions § E Security considerations에서 더 읽을 수 있다.

Controlled Frame에 대해 구체적으로, 우리는 다음 개인정보 보호 고려 사항을 식별했다.

8.3. 접근성

Controlled Frame에 대해, 우리는 다음 접근성 고려 사항을 식별했다.

9. 감사의 말

다음 사람들은 이 문서의 개발에 기여했다.

준수

문서 규칙

준수 요구 사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현된다. 이 문서의 규범적 부분에 있는 키워드 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, 그리고 “OPTIONAL”은 RFC 2119에 설명된 대로 해석되어야 한다. 그러나 가독성을 위해, 이 명세에서 이러한 단어가 모두 대문자로 나타나지는 않는다.

이 명세의 모든 텍스트는 규범적이다. 단, 명시적으로 비규범적이라고 표시된 섹션, 예제 및 참고는 제외된다. [RFC2119]

이 명세의 예제는 “for example”이라는 단어로 도입되거나, 다음과 같이 class="example"을 사용하여 규범적 텍스트와 구분된다.

이는 정보 제공용 예제의 예이다.

정보 제공용 참고는 “Note”라는 단어로 시작하며, 다음과 같이 class="note"를 사용하여 규범적 텍스트와 구분된다.

Note, 이는 정보 제공용 참고이다.

색인

이 명세에서 정의하는 용어

참고 문헌에서 정의하는 용어

참고 문헌

규범 참고 문헌

[Console]
Dominic Farolino; Robert Kowalski; Terin Stock. Console Standard. Living Standard. URL: https://console.spec.whatwg.org/
[CSS-PAGE-FLOATS-3]
Johannes Wilm. CSS Page Floats. URL: https://drafts.csswg.org/css-page-floats/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). URL: https://drafts.csswg.org/cssom/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FENCED-FRAME]
Fenced Frame. 커뮤니티 그룹 보고서 초안. URL: https://wicg.github.io/fenced-frame/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/
[GEOLOCATION]
Marcos Caceres; Reilly Grant. Geolocation. URL: https://w3c.github.io/geolocation/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[ISOLATED-CONTEXTS]
Isolated Contexts. 커뮤니티 그룹 보고서 초안. URL: https://wicg.github.io/isolated-web-apps/isolated-contexts.html
[MANIFEST-APP-INFO]
Aaron Gustafson. Web App Manifest - Application Information. URL: https://w3c.github.io/manifest-app-info/
[Permissions]
Marcos Caceres; Mike Taylor. Permissions. URL: https://w3c.github.io/permissions/
[Permissions-Policy]
Ian Clelland. Permissions Policy. URL: https://w3c.github.io/webappsec-permissions-policy/
[RFC2119]
S. Bradner. RFC에서 요구 수준을 나타내는 핵심 단어. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC5280]
D. Cooper; et al. Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. URL: https://datatracker.ietf.org/doc/html/rfc5280
[RFC6234]
D. Eastlake 3rd; T. Hansen. US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF). URL: https://datatracker.ietf.org/doc/html/rfc6234
[STORAGE]
Anne van Kesteren. Storage Standard. Living Standard. URL: https://storage.spec.whatwg.org/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[URLPATTERN]
Ben Kelly; Jeremy Roman; 宍戸俊哉 (Shunya Shishido). URL Pattern Standard. Living Standard. URL: https://urlpattern.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/
[X.690]
Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER). URL: https://www.itu.int/rec/T-REC-X.690
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/

정보 참고 문헌

[COOKIES]
A. Barth. HTTP State Management Mechanism. 2011년 4월. Proposed Standard. URL: https://httpwg.org/specs/rfc6265.html
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. URL: https://drafts.csswg.org/css-cascade-5/
[High-Watermark-Permissions]
Robbie McElrath. Isolated Web Apps High Watermark Permissions Explainer. URL: https://github.com/WICG/isolated-web-apps/blob/main/Permissions.md
[HTTP-CACHING]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Caching. 2022년 6월. Internet Standard. URL: https://httpwg.org/specs/rfc9111.html
[Isolated-Web-Apps]
Reilly Grant. Isolated Web Apps Explainer. URL: https://github.com/WICG/isolated-web-apps/blob/main/README.md

IDL 색인

[Exposed=Window, IsolatedContext]
interface HTMLControlledFrameElement : HTMLElement {
    [HTMLConstructor] constructor();

    [CEReactions] attribute USVString src;
    attribute DOMString partition;

    readonly attribute WindowProxy? contentWindow;
    readonly attribute ContextMenus contextMenus;
    readonly attribute WebRequest request;

    // Navigation methods.
    Promise<boolean> back();
    Promise<boolean> canGoBack();
    Promise<boolean> forward();
    Promise<boolean> canGoForward();
    Promise<boolean> go(long relativeIndex);
    undefined reload();
    undefined stop();

    // Scripting methods.
    Promise<undefined> addContentScripts(sequence<ContentScriptDetails> contentScriptList);
    Promise<any> executeScript(optional InjectDetails details = {});
    Promise<undefined> insertCSS(optional InjectDetails details = {});
    Promise<undefined> removeContentScripts(optional sequence<DOMString> scriptNameList);

    // Configuration methods.
    Promise<undefined> clearData(
      optional ClearDataOptions options = {},
      optional ClearDataTypeSet types = {});
    Promise<boolean> getAudioState();
    Promise<long> getZoom();
    Promise<DOMString> getZoomMode();
    Promise<boolean> isAudioMuted();
    undefined setAudioMuted(boolean mute);
    Promise<undefined> setZoom(long zoomFactor);
    Promise<undefined> setZoomMode(DOMString zoomMode);

    // Capture methods.
    Promise<undefined> captureVisibleRegion(optional ImageDetails options = {});
    undefined print();

    // Events.
    attribute EventHandler onconsolemessage;
    attribute EventHandler oncontentload;
    attribute EventHandler ondialog;
    attribute EventHandler onloadabort;
    attribute EventHandler onloadcommit;
    attribute EventHandler onloadstart;
    attribute EventHandler onloadstop;
    attribute EventHandler onnewwindow;
    attribute EventHandler onpermissionrequest;
    attribute EventHandler onsizechanged;
    attribute EventHandler onzoomchange;
};

// One of |code| or |file| must be specified but not both.
dictionary InjectDetails {
  DOMString code;
  USVString file;
};

dictionary InjectionItems {
  DOMString code;
  sequence<USVString> files;
};

enum RunAt {
  "document-start",
  "document-end",
  "document-idle",
};

dictionary ContentScriptDetails {
  required DOMString name;
  InjectionItems js;
  InjectionItems css;
  required sequence<(URLPattern or URLPatternInput)> urlPatterns;
  sequence<(URLPattern or URLPatternInput)> excludeURLPatterns;
  boolean allFrames;
  boolean matchAboutBlank;
  RunAt runAt;
};

dictionary ClearDataOptions {
  long since;
};

dictionary ClearDataTypeSet {
  boolean cache;
  boolean cookies;
  boolean fileSystems;
  boolean indexedDB;
  boolean localStorage;
  boolean persistentCookies;
  boolean sessionCookies;
};

enum ZoomMode {
  "per-origin",
  "per-view",
  "disabled"
};


// One of |code| or |file| must be specified but not both.
dictionary ImageDetails {
  DOMString format;
  DOMString quality;
};

[Exposed=Window, IsolatedContext]
interface ConsoleMessage {
  readonly attribute long level;
  readonly attribute DOMString message;
};

[Exposed=Window, IsolatedContext]
interface ConsoleMessageEvent : Event {
  constructor(DOMString type, optional ConsoleMessageEventInit eventInitDict = {});
  readonly attribute ConsoleMessage consoleMessage;
};

dictionary ConsoleMessageEventInit: EventInit {
  ConsoleMessage? consoleMessage;
};


enum DialogType {
  "alert",
  "confirm",
  "prompt"
};

[Exposed=Window, IsolatedContext]
interface DialogController {
  undefined okay(optional DOMString response);
  undefined cancel();
};

[Exposed=Window, IsolatedContext]
interface DialogMessage {
  readonly attribute DialogType messageType;
  readonly attribute DOMString messageText;
  readonly attribute DialogController dialog;
};

[Exposed=Window, IsolatedContext]
interface DialogEvent : Event {
  constructor(DOMString type, optional DialogEventInit eventInitDict = {});
  readonly attribute DialogMessage dialogMessage;
};

dictionary DialogEventInit: EventInit {
  DialogMessage? dialogMessage;
};


enum WindowOpenDisposition {
  "ignore",
  "save_to_disk",
  "current_tab",
  "new_background_tab",
  "new_foreground_tab",
  "new_window",
  "new_popup"
};

[Exposed=Window, IsolatedContext]
interface NewWindowController {
  undefined attach(HTMLControlledFrameElement newControlledFrame);
  undefined discard();
};

[Exposed=Window, IsolatedContext]
interface NewWindow {
  readonly attribute NewWindowController window;
  readonly attribute USVString targetUrl;
  readonly attribute DOMString name;
  readonly attribute WindowOpenDisposition windowOpenDisposition;
};

[Exposed=Window, IsolatedContext]
interface NewWindowEvent : Event {
  constructor(DOMString type, optional NewWindowEventInit eventInitDict = {});
  readonly attribute NewWindow newWindow;
};

dictionary NewWindowEventInit: EventInit {
  NewWindow? newWindow;
};


enum PermissionType {
  "media",
  "geolocation",
  "pointerLock",
  "download",
  "filesystem",
  "fullscreen",
  "hid",
};

[Exposed=Window, IsolatedContext]
interface PermissionRequestControllerBase {
  undefined allow();
  undefined cancel();
};

[Exposed=Window, IsolatedContext]
interface MediaPermissionRequestController: PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface GeolocationPermissionRequestController: PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface PointerLockPermissionRequestController: PermissionRequestControllerBase {
  readonly attribute boolean lastUnlockedBySelf;
  readonly attribute boolean userGesture;
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface DownloadPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute DOMString requestMethod;
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface FileSystemPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface FullscreenPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute USVString origin;
};

[Exposed=Window, IsolatedContext]
interface HidPermissionRequestController : PermissionRequestControllerBase {
  readonly attribute USVString url;
};

[Exposed=Window, IsolatedContext]
interface PermissionRequest {
  readonly attribute PermissionType permission;
  readonly attribute PermissionRequestControllerBase request;
};

[Exposed=Window, IsolatedContext]
interface PermissionRequestEvent : Event {
  constructor(DOMString type, optional PermissionRequestEventInit eventInitDict = {});
  readonly attribute PermissionRequest permissionRequest;
};

dictionary PermissionRequestEventInit: EventInit {
  PermissionRequest? permissionRequest;
};


[Exposed=Window, IsolatedContext]
interface SizeChange {
  readonly attribute unsigned long oldWidth;
  readonly attribute unsigned long oldHeight;
  readonly attribute unsigned long newWidth;
  readonly attribute unsigned long newHeight;
};

[Exposed=Window, IsolatedContext]
interface SizeChangedEvent : Event {
  constructor(DOMString type, optional SizeChangedEventInit eventInitDict = {});
  readonly attribute SizeChange sizeChange;
};

dictionary SizeChangedEventInit: EventInit {
  SizeChange? sizeChange;
};


[Exposed=Window, IsolatedContext]
interface ZoomChange {
  readonly attribute float oldZoomFactor;
  readonly attribute float newZoomFactor;
};

[Exposed=Window, IsolatedContext]
interface ZoomChangeEvent : Event {
  constructor(DOMString type, optional ZoomChangeEventInit eventInitDict = {});
  readonly attribute ZoomChange zoomChange;
};

dictionary ZoomChangeEventInit: EventInit {
  ZoomChange? zoomChange;
};


[Exposed=Window, IsolatedContext]
interface ContentLoadEvent : Event {
  constructor(DOMString type, optional EventInit eventInitDict = {});
};


[Exposed=Window, IsolatedContext]
interface LoadInfo {
  readonly attribute USVString url;
  readonly attribute boolean isTopLevel;
};

[Exposed=Window, IsolatedContext]
interface LoadAbortInfo : LoadInfo{
  readonly attribute long code;
  readonly attribute DOMString reason;
};

[Exposed=Window, IsolatedContext]
interface LoadRedirectInfo{
  readonly attribute USVString oldUrl;
  readonly attribute USVString newUrl;
  readonly attribute boolean isTopLevel;
};

[Exposed=Window, IsolatedContext]
interface LoadAbortEvent : Event {
  constructor(DOMString type, optional LoadAbortEventInit eventInitDict = {});
  readonly attribute LoadAbortInfo loadAbortInfo;
};

dictionary LoadAbortEventInit: EventInit {
  LoadAbortInfo? loadAbortInfo;
};


[Exposed=Window, IsolatedContext]
interface LoadCommitEvent : Event {
  constructor(DOMString type, optional LoadCommitEventInit eventInitDict = {});
  readonly attribute LoadInfo loadInfo;
};

dictionary LoadCommitEventInit: EventInit {
  LoadInfo? loadInfo;
};


[Exposed=Window, IsolatedContext]
interface LoadStartEvent : Event {
  constructor(DOMString type, optional LoadStartEventInit eventInitDict = {});
  readonly attribute LoadInfo loadInfo;
};

dictionary LoadStartEventInit: EventInit {
  LoadInfo? loadInfo;
};


[Exposed=Window, IsolatedContext]
interface LoadStopEvent : Event {
  constructor(DOMString type, optional LoadStopEventInit eventInitDict = {});
};

dictionary LoadStopEventInit: EventInit {
};


[Exposed=Window, IsolatedContext]
interface LoadRedirectEvent : Event {
  constructor(DOMString type, optional LoadRedirectEventInit eventInitDict = {});
  readonly attribute LoadRedirectInfo loadRedirectInfo;
};

dictionary LoadRedirectEventInit: EventInit {
  LoadRedirectInfo? loadRedirectInfo;
};


enum ResourceType {
  "main-frame",
  "sub-frame",
  "stylesheet",
  "script",
  "image",
  "font",
  "object",
  "xmlhttprequest",
  "ping",
  "csp-report",
  "media",
  "websocket",
  "other",
};

enum RequestedHeaders {
  "none",
  "cors",
  "all",
};

enum ConnectionState {
  "broken", "insecure", "secure"
};

dictionary Fingerprint {
  required DOMString sha256;
};

dictionary CertificateInfo {
  required Fingerprint fingerprint;
  Uint8Array rawDER;
};

dictionary SecurityInfo {
  required sequence<CertificateInfo> certificates;
  required ConnectionState state;
};

dictionary WebRequestInterceptorOptions {
  required sequence<(URLPattern or URLPatternInput)> urlPatterns;
  sequence<ResourceType> resourceTypes = [];
  boolean blocking = false;
  boolean includeRequestBody = false;
  RequestedHeaders includeHeaders = "none";
  boolean securityInfo = false;
  boolean securityInfoRawDer = false;
};

[Exposed=Window, IsolatedContext]
interface WebRequest {
  WebRequestInterceptor createWebRequestInterceptor(
      WebRequestInterceptorOptions options);
};

[Exposed=Window, IsolatedContext]
interface WebRequestInterceptor : EventTarget {
  attribute EventHandler onauthrequired;
  attribute EventHandler onbeforeredirect;
  attribute EventHandler onbeforerequest;
  attribute EventHandler onbeforesendheaders;
  attribute EventHandler oncompleted;
  attribute EventHandler onerroroccurred;
  attribute EventHandler onheadersreceived;
  attribute EventHandler onsendheaders;
  attribute EventHandler onresponsestarted;
};

enum DocumentLifecycle {
  "prerender",
  "active",
  "cached",
  "pending-deletion",
};

enum FrameType {
  "outermost-frame",
  "fenced-frame",
  "sub-frame",
};

[Exposed=Window, IsolatedContext]
interface UploadData {
  readonly attribute ArrayBuffer? bytes;
  readonly attribute DOMString? file;
};

[Exposed=Window, IsolatedContext]
interface RequestBody {
  readonly attribute DOMString? error;
  readonly attribute any formData;
  readonly attribute FrozenArray<UploadData>? raw;
};

[Exposed=Window, IsolatedContext]
interface WebRequestRequest {
  readonly attribute DOMString method;
  readonly attribute DOMString id;
  readonly attribute ResourceType type;
  readonly attribute USVString url;
  readonly attribute USVString? initiator;
  readonly attribute Headers? headers;
  readonly attribute RequestBody? body;
};

[Exposed=Window, IsolatedContext]
interface AuthChallenger {
  readonly attribute DOMString host;
  readonly attribute long port;
};

[Exposed=Window, IsolatedContext]
interface WebRequestAuthDetails {
  readonly attribute AuthChallenger challenger;
  readonly attribute boolean isProxy;
  readonly attribute DOMString scheme;
  readonly attribute DOMString? realm;
};

[Exposed=Window, IsolatedContext]
interface WebRequestResponse {
  readonly attribute long statusCode;
  readonly attribute DOMString statusLine;
  readonly attribute boolean fromCache;
  readonly attribute Headers? headers;
  readonly attribute DOMString? ip;
  readonly attribute USVString? redirectURL;
  readonly attribute WebRequestAuthDetails? auth;
};

[Exposed=Window, IsolatedContext]
interface WebRequestEvent : Event {
  readonly attribute WebRequestRequest request;
  readonly attribute long frameId;
  readonly attribute FrameType? frameType;
  readonly attribute DOMString? documentId;
  readonly attribute DocumentLifecycle? documentLifecycle;
  readonly attribute DOMString? parentDocumentId;
  readonly attribute long? parentFrameId;
};

dictionary WebRequestAuthCredentials {
  required DOMString username;
  required DOMString password;
};

dictionary WebRequestAuthOptions {
  AbortSignal signal;
};

[Exposed=Window, IsolatedContext]
interface WebRequestAuthRequiredEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;

  undefined setCredentials(
    Promise<WebRequestAuthCredentials> credentials,
    optional WebRequestAuthOptions options = {});
};

[Exposed=Window, IsolatedContext]
interface WebRequestBeforeRedirectEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
};

[Exposed=Window, IsolatedContext]
interface WebRequestBeforeRequestEvent : WebRequestEvent {
  undefined redirect(USVString redirectURL);
};

[Exposed=Window, IsolatedContext]
interface WebRequestBeforeSendHeadersEvent : WebRequestEvent {
  undefined setRequestHeaders((Headers or HeadersInit) requestHeaders);
};

[Exposed=Window, IsolatedContext]
interface WebRequestCompletedEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
};

[Exposed=Window, IsolatedContext]
interface WebRequestErrorOccurredEvent : WebRequestEvent {
  readonly attribute DOMString error;
};

[Exposed=Window, IsolatedContext]
interface WebRequestHeadersReceivedEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
  readonly attribute SecurityInfo? securityInfo;

  undefined redirect(USVString redirectURL);
  undefined setResponseHeaders((Headers or HeadersInit) responseHeaders);
};

[Exposed=Window, IsolatedContext]
interface WebRequestResponseStartedEvent : WebRequestEvent {
  readonly attribute WebRequestResponse response;
};

[Exposed=Window, IsolatedContext]
interface WebRequestSendHeadersEvent : WebRequestEvent {};

enum ContextType {
    "all",
    "page",
    "frame",
    "selection",
    "link",
    "editable",
    "image",
    "video",
    "audio",
};

enum ItemType {
    "normal",
    "checkbox",
    "radio",
    "separator",
};

dictionary ContextMenusProperties {
    boolean checked;
    sequence<ContextType> contexts;
    sequence<(URLPattern or URLPatternInput)> documentURLPatterns;
    boolean enabled;
    DOMString parentId;
    sequence<(URLPattern or URLPatternInput)> targetURLPatterns;
    DOMString title;
    ItemType type;
};

dictionary ContextMenusCreateProperties : ContextMenusProperties {
    required DOMString id;
};

[Exposed=Window, IsolatedContext]
interface ContextMenus : EventTarget {
    Promise<undefined> create(ContextMenusCreateProperties properties);
    Promise<undefined> remove(DOMString id);
    Promise<undefined> removeAll();
    Promise<undefined> update(DOMString id, optional ContextMenusProperties properties = {});

    attribute EventHandler onclick;
    attribute EventHandler onshow;
};

[Exposed=Window, IsolatedContext]
interface MenuItemDetails {
    readonly attribute DOMString id;
    readonly attribute DOMString? parentMenuId;
    readonly attribute boolean? checked;
    readonly attribute boolean? wasChecked;
};

[Exposed=Window, IsolatedContext]
interface ContextMenusClickEvent : Event {
  readonly attribute MenuItemDetails menuItem;

  // Details about the frame the context menu is opened within.
  readonly attribute long frameId;
  readonly attribute USVString frameURL;
  readonly attribute USVString pageURL;

  // Details about the element the context menu is opened within the context of.
  readonly attribute boolean editable;
  readonly attribute USVString? linkURL;
  readonly attribute DOMString? mediaType;
  readonly attribute DOMString? selectionText;
  readonly attribute USVString? srcURL;
};

이슈 색인

이 단계는 새 navigable에서 History.length를 초기화하는 데 필요하다. 이는 HTML Standard에 있는 기존 이슈이다. ↵
이 알고리즘은 Shared Workers 또는 Service Workers에 대해서는 작동하지 않는다. 왜냐하면 controlledFrameEmbedderParent는 navigable에만 정의되며, non-Window environment에서 navigable로 이동하는 것이 항상 가능한 것은 아니기 때문이다. ↵
ContextType 일치 동작은 명세되어 있지 않지만, 위 참고에는 원하는 동작에 관한 일부 정보가 있다. ↵