WebDriver BiDi

W3C 작업 초안,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/WD-webdriver-bidi-20261008/
최신 공개 버전:
https://www.w3.org/TR/webdriver-bidi/
편집자 초안:
https://w3c.github.io/webdriver-bidi/
이전 버전:
이력:
https://www.w3.org/standards/history/webdriver-bidi/
구현 보고서:
https://wpt.fyi/results/webdriver/tests/bidi
테스트 스위트:
https://github.com/web-platform-tests/wpt/tree/master/webdriver/tests/bidi
피드백:
GitHub
명세 내 인라인
편집자:
James Graham (Mozilla)
Alex Rudenko (Google)
Maksim Sadym (Google)
채널:
irc.w3.org의 #webdriver
위키:
W3C WebDriver 위키

초록

이 문서는 사용자 에이전트를 원격 제어하기 위한 메커니즘인 양방향 WebDriver 프로토콜을 정의한다.

이 문서의 상태

이 절은 이 문서가 공개된 시점의 상태를 설명한다. 현재 W3C 공개 문서 및 이 기술 보고서의 최신 개정판 목록은 W3C 표준 및 초안 색인에서 찾을 수 있다.

이 명세에 관한 논의에는 GitHub 이슈가 권장된다. 또는 Browser Testing and Tools Working Group의 메일링 리스트인 public-browser-tools-testing@w3.org로 의견을 보낼 수 있다 (아카이브).

이 문서는 Browser Testing and Tools Working Group이 Recommendation 트랙을 사용하여 작업 초안으로 공개하였다.

작업 초안으로 공개되었다고 해서 W3C와 그 회원들의 승인을 의미하지는 않는다.

이 문서는 초안 문서이며 언제든지 다른 문서에 의해 갱신, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성하였다. W3C는 그룹의 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허 공개 방법에 관한 지침도 포함되어 있다. 개인이 필수 청구항을 포함한다고 믿는 특허에 대해 실제 지식을 가진 경우, 그 개인은 W3C 특허 정책 제6절에 따라 해당 정보를 공개해야 한다.

이 문서는 2025년 8월 18일 W3C Process Document의 적용을 받는다.

1. 소개

이 절은 비규범적이다.

WebDriver는 사용자 에이전트의 내부 상태 조사 및 원격 제어를 위한 프로토콜을 정의한다. 이 명세는 양방향 통신을 도입하여 WebDriver를 확장한다. WebDriver의 엄격한 명령/응답 형식 대신, 이를 통해 이벤트가 사용자 에이전트에서 제어 소프트웨어로 스트리밍될 수 있으므로, 브라우저 DOM의 이벤트 기반 특성에 더 잘 부합한다.

2. 인프라스트럭처

이 명세는 Infra Standard에 의존한다. [INFRA]

네트워크 프로토콜 메시지는 CDDL을 사용하여 정의한다. [RFC8610]

이 명세는 맵인 대기 큐를 정의한다.

이 "이벤트 대기" 작업을 수행하는 더 나은 메커니즘이 분명히 있을 것이다.

병렬로 실행 중인 알고리즘 algorithm이 이벤트 집합 events 및 resume id를 대기할 때:

  1. algorithm의 실행을 일시 중지한다.

  2. 단언: 대기 큐는 resume id를 포함하지 않는다.

  3. 대기 큐[resume id]를 (events, algorithm)으로 설정한다.

주어진 name, id 및 parameters로 재개하려면:
  1. 대기 큐가 id를 포함하지 않으면, 반환한다.

  2. (events, algorithm)을 대기 큐[id]로 둔다.

  3. events의 각 event에 대해:

    1. event가 name과 같으면:

      1. 대기 큐에서 id를 제거한다.

      2. algorithm의 단계들을 일시 중지된 지점부터 계속 실행하며, name 및 parameters를 대기의 결과로 전달한다.

        이것이 이벤트 루프의 다른 어떤 작업보다 먼저 실행되도록 보장하기 위해 마이크로태스크 같은 것이 있어야 하는가?

WebDriver 구성은 다음을 가진 구조체이다:

WebDriver 구성은 타입인 연관 타입을 가진다.

WebDriver 구성의 값은 그 구성의 연관 타입인 타입을 가진 값이거나 설정되지 않음이다.

설정되지 않음은 특정 구성 값이 설정되지 않았음을 나타내는 값이다.

참고: 이 알고리즘은 주어진 navigable에 대한 WebDriver 구성에 접근할 수 있게 하며, navigables의 값을 확인한 다음, user contexts를 확인하고 마지막으로 global을 확인한다. 구성이 설정되어 있지 않으면 설정되지 않음을 반환한다.

WebDriver 구성 configuration의 navigable navigable에 대한 WebDriver 구성 값 가져오기를 하려면:

  1. top-level traversable을 navigable의 최상위 traversable로 둔다.

  2. configuration의 navigables가 top-level traversable을 포함하면:

    1. navigable configuration value를 configuration의 navigables[top-level traversable]로 둔다.

    2. navigable configuration value가 설정되지 않음이 아니면, navigable configuration value를 반환한다.

  3. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

  4. configuration의 user contexts가 user context를 포함하면:

    1. user context configuration value를 configuration의 user contexts[user context]로 둔다.

    2. user context configuration value가 설정되지 않음이 아니면, user context configuration value를 반환한다.

  5. configuration의 global을 반환한다.

참고: 이는 target별로 WebDriver 구성을 저장하기 위한 일반 알고리즘이다. target은 navigable, 사용자 컨텍스트 중 하나일 수 있으며, target이 null이거나 생략된 경우 전역으로 저장한다.

제공되지 않은 경우 null인 선택적 target에 WebDriver 구성 configuration의 값 value를 저장하려면, 여기서 target은 navigable, 사용자 컨텍스트 또는 null이다:

  1. target이 null이면, configuration의 global을 value로 설정한다.

  2. target이 사용자 컨텍스트이면, configuration의 user contexts[target]를 value로 설정한다.

  3. target이 navigable이면, configuration의 navigables[target]를 value로 설정한다.

참고: 이 일반 알고리즘은 command parameters에 "userContexts"와 "contexts"가 있는지에 따라 WebDriver 구성의 값을 global, user contexts, 또는 navigables에 저장한다. 이 매개변수들은 서로 배타적이다. 둘 다 제공되지 않으면, 구성은 전역으로 저장된다.

주어진 command parameters에 대해 WebDriver 구성 configuration의 값 value를 WebDriver 구성 저장하려면:

  1. command parameters가 "userContexts"를 포함하고 command parameters가 "contexts"를 포함하면, 오류를 반환하되, 오류 코드는 invalid argument로 한다.

  2. affected navigables를 빈 집합으로 둔다.

  3. command parameters가 "contexts"를 포함하면:

    1. navigables를 command parameters["contexts"]를 사용하여 id로 유효한 최상위 traversable 가져오기를 시도한 결과로 둔다.

    2. navigables의 각 navigable에 대해:

      1. navigable을 affected navigables에 추가한다.

      2. configuration의 value를 navigable에 저장한다.

  4. 그렇지 않고, command parameters가 "userContexts"를 포함하면:

    1. user contexts를 command parameters["userContexts"]를 사용하여 유효한 사용자 컨텍스트 가져오기를 시도한 결과로 둔다.

    2. user contexts의 각 user context에 대해:

      1. 각 top-level traversable에 대해, 그 연관된 사용자 컨텍스트가 user context인 모든 최상위 traversable의 목록에서:

        1. top-level traversable을 affected navigables에 추가한다.

      2. configuration의 value를 user context에 저장한다.

  5. 그렇지 않으면:

    1. 모든 최상위 traversable의 각 top-level traversable에 대해, top-level traversable을 affected navigables에 추가한다.

    2. configuration의 value를 저장한다.

  6. affected navigables를 반환한다.

3. 프로토콜

이 절은 WebDriver BiDi 프로토콜의 기본 개념을 정의한다. 이러한 용어는 전송 계층에서의 표현과는 구별된다.

이 프로토콜은 CDDL 정의를 사용하여 정의한다. 구현자의 편의를 위해 두 개의 별도 CDDL 정의를 정의한다. 즉, 로컬 끝에서 생성되고 원격 끝에서 소비되는 메시지의 형식을 정의하는 원격 끝 정의와, 원격 끝에서 생성되고 로컬 끝에서 소비되는 메시지의 형식을 정의하는 로컬 끝 정의이다.

3.1. 정의

이것은 부록이어야 하는가?

이 절은 원격 끝 정의 및 로컬 끝 정의의 초기 내용을 제공한다. 이들은 명세의 나머지 부분에서 정의된 정의 조각들에 의해 보강된다.

원격 끝 정의

Command = {
  id: js-uint,
  CommandData,
  Extensible,
}

CommandData = (
  BrowserCommand //
  BrowsingContextCommand //
  EmulationCommand //
  InputCommand //
  NetworkCommand //
  ScriptCommand //
  SessionCommand //
  StorageCommand //
  WebExtensionCommand
)

EmptyParams = {
   Extensible
}

Local end definition

Message = (
  CommandResponse /
  ErrorResponse /
  Event
)

CommandResponse = {
  type: "success",
  id: js-uint,
  result: ResultData,
  Extensible
}

ErrorResponse = {
  type: "error",
  id: js-uint / null,
  error: ErrorCode,
  message: text,
  ? stacktrace: text,
  Extensible
}

ResultData = (
  BrowserResult /
  BrowsingContextResult /
  EmulationResult /
  InputResult /
  NetworkResult /
  ScriptResult /
  SessionResult /
  StorageResult /
  WebExtensionResult
)

EmptyResult = {
  Extensible
}

Event = {
  type: "event",
  EventData,
  Extensible
}

EventData = (
  BrowsingContextEvent //
  InputEvent //
  LogEvent //
  NetworkEvent //
  ScriptEvent
)

EmptyResult는 필수 필드가 없는 결과 타입으로, 결과 데이터를 생성하지 않는 명령의 반환 타입으로 사용된다.

원격 끝 정의 및 로컬 끝 정의

Extensible = (*text => any)

js-int = -9007199254740991..9007199254740991
js-uint = 0..9007199254740991

3.2. 세션

WebDriver BiDi는 세션 개념을 WebDriver로부터 확장한다.

세션은 BiDi 플래그를 가지며, 달리 명시되지 않는 한 그 값은 false이다.

BiDi 세션은 세션이며, BiDi 플래그가 true로 설정된 것이다.

활성 BiDi 세션의 목록은 다음으로 주어진다:
  1. BiDi sessions를 새 목록으로 둔다.

  2. 활성 세션의 각 session에 대해:

    1. session이 BiDi 세션이면, session을 BiDi sessions에 추가한다.

  3. BiDi sessions를 반환한다.

3.3. 모듈

WebDriver BiDi 프로토콜은 모듈로 구성된다.

각 모듈은 사용자 에이전트의 특정 측면과 관련된 명령 및 이벤트의 모음을 나타낸다. 예를 들어, 모듈은 DOM을 검사하고 조작하는 기능이나 스크립트 실행 기능을 포함할 수 있다.

각 모듈은 문자열인 모듈 이름을 가진다. 모듈에 정의된 명령과 이벤트의 명령 이름 및 이벤트 이름은 모듈 이름으로 시작하고 그 뒤에 마침표 "."가 온다.

명령을 포함하는 모듈은 원격 끝 정의 조각을 정의한다. 이 조각은 모듈의 명령에 대해 CommandData 그룹에 선택지를 제공하며, 추가 정의 속성도 정의할 수 있다. 또한 모듈의 명령 결과에 대해 ResultData 그룹에 추가 선택지를 제공하는 로컬 끝 정의 조각을 정의할 수도 있다.

이벤트를 포함하는 모듈은 모듈의 이벤트에 대해 Event 그룹의 선택지인 로컬 끝 정의 조각을 정의한다.

구현은 확장 모듈을 정의할 수 있다. 이러한 모듈은 단일 콜론 ":" 문자를 포함하는 모듈 이름을 가져야 한다. 콜론 앞부분은 접두사이며, 이는 일반적으로 주어진 구현에 특화된 모든 확장 모듈에서 동일하고, 주어진 구현에 대해 고유해야 한다.

다른 명세는 프로토콜을 확장하는 자체 WebDriver-BiDi 모듈을 정의할 수 있다. 그러한 모듈은 콜론(:) 문자를 포함하는 이름을 가져서는 안 되며, 해당 문자를 포함하는 명령 이름, 이벤트 이름, 또는 속성 이름을 정의해서도 안 된다.

외부 명세의 저자는 기존 모듈을 확장하기보다 새 모듈을 추가하는 것이 권장된다. 기존 모듈을 확장하고자 하는 경우에는, 해당 확장을 원래 모듈 정의를 포함하는 명세에 직접 통합하는 것이 바람직하다.

3.4. 명령

명령은 비동기 동작으로, 로컬 끝에서 요청하고 원격 끝에서 실행되며, 그 결과로 결과 또는 오류가 로컬 끝에 반환된다. 여러 명령은 동시에 실행될 수 있으며, 명령은 잠재적으로 오래 실행될 수 있다. 그 결과, 명령은 순서와 다르게 완료될 수 있다.

각 명령은 다음으로 정의된다:

활성 세션 없이 실행될 수 있는 명령은 정적 명령이다. 정의에서 명시하지 않는 한 명령은 정적 명령이 아니다.

명령이 로컬 끝에서 전송될 때, 명령은 명령 id를 가진다. 이는 특정 명령의 응답을 식별하기 위해 로컬 끝이 사용하는 식별자이다. 원격 끝의 관점에서 이 식별자는 불투명하며, 명령을 식별하기 위해 내부적으로 사용할 수 없다.

참고: 이는 명령 id가 전적으로 로컬 끝에 의해 제어되고, 세션 과정에서 반드시 고유한 것은 아니기 때문이다. 예를 들어 모든 응답을 무시하는 로컬 끝은 각 명령에 동일한 명령 id를 사용할 수 있다.

모든 명령 이름의 집합은 정의된 모든 명령 이름을 포함하는 집합이며, 확장 모듈에 속한 것도 포함한다.

3.5. 오류

WebDriver BiDi는 WebDriver의 오류 코드 집합을 다음 추가 코드로 확장한다:

invalid web extension
유효하지 않은 웹 확장을 설치하려고 했다.
no such client window
알 수 없는 클라이언트 창과 상호작용하려고 했다.
no such handle
알 수 없는 RemoteObjectReference를 역직렬화하려고 했다.
no such history entry
알 수 없는 세션 히스토리 항목으로 이동하려고 했다.
no such network collector
알 수 없는 컬렉터를 제거하려고 했다.
no such intercept
알 수 없는 네트워크 인터셉트를 제거하려고 했다.
no such network data
알 수 없는 네트워크 데이터를 참조하려고 했다.
no such node
알 수 없는 SharedReference를 역직렬화하려고 했다.
no such request
알 수 없는 요청을 계속하려고 했다.
해당 스크린캐스트 없음
알 수 없는 스크린캐스트 녹화를 중지하려고 했다.
no such script
알 수 없는 프리로드 스크립트를 제거하려고 했다.
no such storage partition
존재하지 않는 저장소 파티션의 데이터에 접근하려고 했다.
no such user context
알 수 없는 사용자 컨텍스트를 참조하려고 했다.
no such web extension
알 수 없는 웹 확장을 참조하려고 했다.
unable to close browser
브라우저를 닫으려고 했지만 실패했다.
unable to set cookie
쿠키를 만들려고 했지만 사용자 에이전트가 거부했다.
underspecified storage partition
충분히 지정되지 않은 저장소 파티션의 데이터와 상호작용하려고 했다.
unable to set file input
파일 입력을 설정하려고 했지만 실패했다.
unavailable network data
수집되지 않았거나 이미 제거된 네트워크 데이터를 가져오려고 했다.
ErrorCode = "invalid argument" /
            "invalid selector" /
            "invalid session id" /
            "invalid web extension" /
            "move target out of bounds" /
            "no such alert" /
            "no such network collector" /
            "no such element" /
            "no such frame" /
            "no such handle" /
            "no such history entry" /
            "no such intercept" /
            "no such network data" /
            "no such node" /
            "no such request" /
            "no such screencast" /
            "no such script" /
            "no such storage partition" /
            "no such user context" /
            "no such web extension" /
            "session not created" /
            "unable to capture screen" /
            "unable to close browser" /
            "unable to set cookie" /
            "unable to set file input" /
            "unavailable network data" /
            "underspecified storage partition" /
            "unknown command" /
            "unknown error" /
            "unsupported operation"

3.6. 이벤트

이벤트는 원격 끝에서 로컬 끝으로 전송되는 알림으로, 원격 끝에서 관심 있는 일이 발생했음을 알린다.

BiDi 세션은 구독의 목록인 구독을 가진다.

BiDi 세션은 로컬 끝에 발급되었지만 아직 구독 해제되지 않은 모든 구독 id의 집합인 알려진 구독 id를 가진다.

구독은 구조체이며, 구독 id(문자열), 이벤트 이름(이벤트 이름의 집합), 최상위 traversable id(최상위 traversable ID의 집합) 및 사용자 컨텍스트 id(사용자 컨텍스트 ID의 집합)로 구성된다.

구독 subscription은 subscription의 최상위 traversable id가 빈 집합이고 subscription의 사용자 컨텍스트 id가 빈 집합이면 전역이다.

event name 및 navigables가 주어졌을 때 이벤트가 활성화된 세션의 집합은 다음과 같다:

  1. sessions를 새 집합으로 둔다.

  2. 활성 BiDi 세션의 각 session에 대해:

    1. session, event name 및 navigables로 이벤트가 활성화되어 있으면, session을 sessions에 추가한다.

  3. sessions를 반환한다.

주어진 session, event name 및 navigables에 대해 이벤트가 활성화되어 있는지 결정하려면:

참고: 공유 워커는 여러 컨텍스트와 연관될 수 있으므로, navigables는 집합이다.

  1. top-level traversables를 navigables로 최상위 traversable 가져오기를 수행한 결과로 둔다.

  2. session의 구독에 있는 각 subscription에 대해:

    1. subscription의 이벤트 이름이 event name을 포함하지 않으면, 계속한다.

    2. subscription이 전역이면 true를 반환한다.

    3. 사용자 컨텍스트 id가 비어 있지 않으면:

      1. top-level traversables의 각 navigable에 대해:

        1. subscription의 사용자 컨텍스트 id가 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id를 포함하면, true를 반환한다.

    4. 그렇지 않으면:

      1. subscription top-level traversables를 subscription의 최상위 traversable id로 id로 navigable 가져오기를 수행한 결과로 둔다.

      2. top-level traversables와 subscription top-level traversables의 교집합이 비어 있지 않으면 true를 반환한다.

  3. false를 반환한다.

event name 및 session이 주어졌을 때 이벤트가 활성화된 최상위 traversable의 집합은 다음과 같다:

  1. result를 새 집합으로 둔다.

  2. session의 구독에 있는 각 subscription에 대해:

    1. subscription의 이벤트 이름이 event name을 포함하지 않으면, 계속한다.

    2. subscription이 전역이면:

      1. 원격 끝의 최상위 traversable에 있는 각 traversable에 대해:

        1. traversable을 result에 추가한다.

      2. 중단한다.

    3. 그렇지 않고, 사용자 컨텍스트 id가 비어 있지 않으면:

      1. 원격 끝의 최상위 traversable에 있는 각 traversable에 대해:

        1. subscription의 사용자 컨텍스트 id가 traversable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id를 포함하면, traversable을 result에 추가한다.

    4. 그렇지 않으면:

      1. top-level traversables를 subscription의 최상위 traversable id로 id로 navigable 가져오기를 수행한 결과로 둔다.

      2. top-level traversables의 각 항목을 result에 추가한다.

  3. result를 반환한다.

주어진 name에 대해 이벤트 이름 집합 얻기를 하려면:
  1. events를 빈 집합으로 둔다.

  2. name이 U+002E(마침표)를 포함하면:

    1. name이 이벤트의 이벤트 이름이면, name을 events에 추가하고 데이터 events와 함께 성공을 반환한다.

    2. 오류를 반환하되, 오류 코드는 invalid argument로 한다.

  3. 그렇지 않으면 name은 모듈의 모든 이벤트를 나타내는 것으로 해석된다. name이 모듈 이름이 아니면, 오류를 반환하되, 오류 코드는 invalid argument로 한다.

  4. 이름이 name인 모듈의 각 이벤트에 대한 이벤트 이름을 events에 추가한다.

  5. 데이터 events와 함께 성공을 반환한다.

4. 전송

메시지 전송은 WebSocket 프로토콜을 사용하여 제공된다. [RFC6455]

참고: WebSocket 프로토콜의 용어로는, 로컬 끝이 클라이언트이고 원격 끝이 서버 / 원격 호스트이다.

참고: 명령과 이벤트를 메시지로 인코딩하는 방식은 JSON-RPC와 유사하지만, 이 명세는 이를 규범적으로 참조하지 않는다. [JSON-RPC] 대신 원격 끝에 대한 규범적 요구사항은 정밀한 처리 모델로 주어지며, 로컬 끝에 대해서는 규범적 요구사항이 주어지지 않는다.

WebSocket 리스너는 들어오는 WebSocket 연결을 받아들일 수 있는 네트워크 엔드포인트이다.

WebSocket 리스너는 호스트, 포트, 보안 플래그, 그리고 WebSocket 리소스 목록을 가진다.

WebSocket 리스너 listener가 생성될 때, 원격 끝은 listener의 호스트 및 포트로 주어진 호스트와 포트에서 WebSocket 연결 수신을 시작해야 한다. listener의 보안 플래그가 설정되어 있으면, listener에서 수립된 연결은 TLS로 암호화되어야 한다.

원격 끝은 집합인 WebSocket 리스너의 활성 리스너를 가지며, 이는 처음에 비어 있다.

원격 끝은 집합인 세션과 연결되지 않은 WebSocket 연결을 가지며, 이는 처음에 비어 있다.

WebSocket 연결은 WebSocket 프로토콜의 요구사항을 따르는 네트워크 연결이다

BiDi 세션은 그 원소가 WebSocket 연결인 집합의 세션 WebSocket 연결을 가진다. 이는 처음에 비어 있다.

BiDi 세션 session은 session의 세션 WebSocket 연결이 connection을 포함하면 connection과 연결되어 있다.

참고: 각 WebSocket 연결은 최대 하나의 BiDi 세션과 연결된다.

클라이언트가 WebSocket 연결을 수립하여 활성 리스너 집합 중 하나인 listener에 연결할 때, 구현은 WebSocket 서버 측 요구사항에 따라 진행해야 하며, 들어오는 연결을 수락할지 결정할 때 다음 단계를 실행한다:

  1. resource name을 클라이언트의 opening handshake 읽기에서 얻은 리소스 이름으로 둔다. resource name이 listener의 WebSocket 리소스 목록에 없으면, 이 단계의 실행을 중지하고 요청된 서비스를 사용할 수 없는 것처럼 동작한다.

  2. resource name이 바이트 문자열 "/session"이고, 구현이 BiDi 전용 세션을 지원하면:

    1. 연결을 수락할지 결정하기 위해 구현 정의의 다른 단계를 실행하고, 수락하지 않으면 이 단계의 실행을 중지하고 요청된 서비스를 사용할 수 없는 것처럼 동작한다.

    2. 연결을 세션과 연결되지 않은 WebSocket 연결에 추가한다.

    3. 반환한다.

  3. resource name으로 WebSocket 리소스에 대한 세션 ID 가져오기를 수행하고, session id를 그 값으로 둔다. session id가 null이면 이 단계의 실행을 중지하고 요청된 서비스를 사용할 수 없는 것처럼 동작한다.

  4. 활성 세션 목록에 session id를 그 세션 ID로 가지는 세션이 있으면, session을 그 세션으로 둔다. 그렇지 않으면 이 단계들의 실행을 중지하고, 요청된 서비스를 사용할 수 없는 것처럼 동작한다.

  5. 연결을 수락할지 결정하기 위해 구현 정의의 다른 단계를 실행하고, 수락하지 않으면 이 단계의 실행을 중지하고 요청된 서비스를 사용할 수 없는 것처럼 동작한다.

  6. 그렇지 않으면 connection을 session의 세션 WebSocket 연결에 추가하고, 서버가 들어오는 연결을 수락하기로 선택할 때의 WebSocket 서버 측 요구사항으로 진행한다.

하나의 세션에 대해 둘 이상의 연결을 지원하는가?

WebSocket 메시지가 수신되었을 때, 타입 type 및 데이터 data를 가진 WebSocket 연결 connection에 대해, 원격 끝은 connection, type, data가 주어졌을 때 들어오는 메시지 처리를 해야 한다.

WebSocket closing handshake가 시작될 때 또는 WebSocket 연결이 닫힐 때, WebSocket 연결 connection에 대해, 원격 끝은 connection이 주어졌을 때 연결 닫힘 처리를 해야 한다.

참고: closing handshake 없이 WebSocket 연결이 닫힐 수 있으므로 두 조건이 모두 필요하다.

세션 session이 주어졌을 때 WebSocket 리소스 이름을 구성하려면:

  1. session이 null이면, "/session"을 반환한다

  2. 문자열 "/session/"과 session의 세션 ID를 연결한 결과를 반환한다.

WebSocket 리스너 listener와 세션 session이 주어졌을 때 WebSocket URL을 구성하려면:

  1. resource name을 session으로 WebSocket 리소스 이름을 구성한 결과로 둔다.

  2. listener의 host로 host를 설정하고, listener의 port로 port를 설정하며, path를 resource name으로 설정하고, listener의 secure flag가 설정되어 있으면 wss-URI 구성을 따르고 그렇지 않으면 ws-URL 구성을 따르는 방식으로 구성된 WebSocket URI를 반환한다.

resource name이 주어졌을 때 WebSocket 리소스의 세션 ID를 얻으려면:

  1. resource name이 바이트 문자열 "/session/"로 시작하지 않으면, null을 반환한다.

  2. session id를 resource name에서 "/session/" 접두사 뒤에 오는 바이트들로 둔다.

  3. session id가 UUID의 문자열 표현이 아니면, null을 반환한다.

  4. session id를 반환한다.

세션 session이 주어졌을 때 WebSocket 연결을 수신 대기하기 시작하려면:
  1. 원격 끝이 재사용하고자 하는 기존 WebSocket 리스너가 활성 리스너 안에 있으면, listener를 그 리스너로 둔다. 그렇지 않으면 listener를 구현 정의 host, port, secure flag, 그리고 빈 WebSocket 리소스 목록을 갖는 새 WebSocket 리스너로 둔다.

  2. resource name을 session으로 WebSocket 리소스 이름을 구성한 결과로 둔다.

  3. resource name을 listener의 WebSocket 리소스 목록에 추가한다.

  4. listener를 원격 끝의 활성 리스너에 추가한다.

  5. listener를 반환한다.

참고: 여러 세션을 처리하는 중개 노드는 하나 또는 여러 WebSocket 리스너를 사용할 수 있다. WebDriver는 엔드포인트 노드가 한 번에 최대 하나의 세션을 지원한다고 정의하므로, 단일 리스너만 가질 것으로 예상된다.

참고: 엔드포인트 노드의 경우 위 단계의 호스트는 일반적으로 "localhost"이다.

WebSocket 연결 connection, 타입 type, 데이터 data가 주어졌을 때 들어오는 메시지 처리를 하려면:
  1. type이 text가 아니면, connection, null 및 invalid argument가 주어졌을 때 오류 응답 전송을 하고, 마지막으로 반환한다.

  2. 단언: data는 스칼라 값 문자열이다. 그렇지 않으면 WebSocket의 UTF-8로 인코딩된 데이터의 오류 처리가 이미 WebSocket 연결을 실패시켰을 것이기 때문이다.

    UTF-8 오류에 어떤 상태 코드를 사용하는지는 아무것도 정의하지 않는 듯하다.

  3. connection과 연결된 BiDi 세션이 있으면, session을 그 세션으로 둔다. 그렇지 않고 connection이 세션과 연결되지 않은 WebSocket 연결에 있으면, session을 null로 둔다. 그렇지 않으면 반환한다.

  4. parsed를 data가 주어졌을 때 JSON을 Infra 값으로 파싱한 결과로 둔다. 이것이 예외를 던지면, connection, null 및 invalid argument가 주어졌을 때 오류 응답 전송을 하고, 마지막으로 반환한다.

  5. session이 null이 아니고 활성 세션에 없으면 반환한다.

  6. parsed를 원격 끝 정의와 대조한다. 이것이 일치하면:

    1. matched를 일치한 데이터를 나타내는 맵으로 둔다.

    2. 단언: matched는 "id", "method" 및 "params"를 포함한다.

    3. command id를 matched["id"]로 둔다.

    4. method를 matched["method"]로 둔다

    5. command를 method라는 명령 이름을 가진 명령으로 둔다.

    6. session이 null이고 command가 정적 명령이 아니면, connection, command id, 그리고 invalid session id가 주어졌을 때 오류 응답 전송을 하고 반환한다.

    7. 다음 단계를 병렬로 실행한다:

      1. result를 session 및 명령 매개변수 matched["params"]가 주어졌을 때 command의 원격 끝 단계를 실행한 결과로 둔다.

      2. result가 오류이면, connection, command id, 그리고 result의 오류 코드가 주어졌을 때 오류 응답 전송을 하고, 마지막으로 반환한다.

      3. value를 result의 데이터로 둔다.

      4. 단언: value는 method라는 명령 이름을 가진 명령에 대응하는 결과 타입의 정의와 일치한다.

      5. method가 "session.new"이면, session을 활성 세션 목록에서 그 세션 ID가 value의 "sessionId" 속성과 같은 항목으로 두고, connection을 session의 세션 WebSocket 연결에 추가하며, connection을 세션과 연결되지 않은 WebSocket 연결에서 제거한다.

      6. response를 로컬 끝 정의의 CommandResponse 생성규칙과 일치하는 새 맵으로 둔다. 이때 id 필드는 command id로 설정하고 value 필드는 value로 설정한다.

      7. serialized를 response가 주어졌을 때 infra 값을 JSON 바이트로 직렬화한 결과로 둔다.

      8. serialized로 구성된 WebSocket 메시지를 전송하되, connection을 통해 전송한다.

  7. 그렇지 않으면:

    1. command id를 null로 둔다.

    2. parsed가 맵이고 parsed["id"]가 존재하며 0 이상의 정수이면, command id를 그 정수로 설정한다.

    3. error code를 invalid argument로 둔다.

    4. parsed가 맵이고 parsed["method"]가 존재하며 문자열이지만, parsed["method"]가 모든 명령 이름의 집합에 없으면, error code를 unknown command로 설정한다.

    5. connection, command id, 그리고 error code가 주어졌을 때 오류 응답 전송을 한다.

settings 객체 settings가 주어졌을 때 관련 navigable 가져오기를 하려면:

  1. related navigables를 빈 집합으로 둔다.

  2. settings의 관련 전역 객체가 Window이면:

    1. navigable을 관련 전역 객체의 연관된 Document의 node navigable로 둔다.

    2. navigable이 null이 아니면, navigable을 related navigables에 추가한다.

  3. 그렇지 않고 settings로 지정된 전역 객체가 WorkerGlobalScope이면, 그 전역 객체의 소유자 집합의 각 owner에 대해:

    1. navigable을 null로 둔다.

    2. owner가 Document이면, navigable을 owner의 node navigable로 설정한다.

    3. navigable이 null이 아니면, navigable을 related navigables에 추가한다.

  4. related navigables를 반환한다.

컨텍스트 id의 목록 navigable ids가 주어졌을 때 id로 navigable 가져오기를 하려면:

  1. result를 빈 집합으로 둔다.

  2. navigable ids의 각 navigable id에 대해:

    1. 그러한 navigable이 존재하면 navigable을 id가 navigable id인 navigable로 두고, 그렇지 않으면 null로 둔다.

    2. navigable이 null이 아니면 navigable을 result에 추가한다.

  3. result를 반환한다.

navigable의 목록 navigables가 주어졌을 때 최상위 traversable 가져오기를 하려면:

  1. result를 빈 집합으로 둔다.

  2. navigables의 각 navigable에 대해:

    1. navigable의 최상위 traversable을 result에 추가한다.

  3. result를 반환한다.

컨텍스트 id의 목록 navigable ids가 주어졌을 때 id로 유효한 navigable 가져오기를 하려면:

  1. result를 빈 집합으로 둔다.

  2. navigable ids의 각 navigable id에 대해:

    1. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

    2. navigable을 result에 추가한다.

  3. 데이터 result와 함께 성공을 반환한다.

컨텍스트 id의 목록 navigable ids가 주어졌을 때 id로 유효한 최상위 traversable 가져오기를 하려면:

  1. result를 빈 집합으로 둔다.

  2. navigable ids의 각 navigable id에 대해:

    1. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

    2. navigable이 최상위 traversable이 아니면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

    3. navigable을 result에 추가한다.

  3. 데이터 result와 함께 성공을 반환한다.

session 및 body가 주어졌을 때 이벤트 방출을 하려면:
  1. 단언: body는 Event 생성규칙과 일치한다.

  2. serialized를 body가 주어졌을 때 infra 값을 JSON 바이트로 직렬화한 결과로 둔다.

  3. session의 세션 WebSocket 연결에 있는 각 connection에 대해:

    1. serialized로 구성된 WebSocket 메시지를 전송하되, connection을 통해 전송한다.

WebSocket 연결 connection, command id, 그리고 error code가 주어졌을 때 오류 응답 전송을 하려면:
  1. error data를 로컬 끝 정의의 ErrorResponse 생성규칙과 일치하는 새 맵으로 둔다. 이때 id 필드는 command id로 설정하고, error 필드는 error code로 설정하며, message 필드는 발생한 오류에 대한 사람이 읽을 수 있는 정의를 포함하는 구현 정의 문자열로 설정하고, stacktrace 필드는 오류가 발생한 시점의 활성 스택 프레임에 대한 스택 추적 보고서를 포함하는 구현 정의 문자열로 선택적으로 설정한다.

  2. response를 error data가 주어졌을 때 infra 값을 JSON 바이트로 직렬화한 결과로 둔다.

    참고: command id는 null일 수 있으며, 이 경우 id 필드도 response에서 생략되지 않고 null로 설정된다.

  3. response로 구성된 WebSocket 메시지를 전송하되, connection을 통해 전송한다.

WebSocket 연결 connection이 주어졌을 때 연결 닫힘 처리를 하려면:

  1. connection과 연결된 BiDi 세션이 있으면:

    1. session을 connection과 연결된 BiDi 세션으로 둔다.

    2. connection을 session의 세션 WebSocket 연결에서 제거한다.

  2. 그렇지 않고, 세션과 연결되지 않은 WebSocket 연결이 connection을 포함하면, connection을 그 집합에서 제거한다.

참고: 이는 어떤 세션도 종료하지 않는다.

UA가 원할 경우 리스너를 닫을 수 있도록 세션 종료에 연결해야 한다.

session이 주어졌을 때 WebSocket 연결 닫기를 하려면:

  1. session의 세션 WebSocket 연결에 있는 각 connection에 대해:

    1. connection으로 WebSocket closing handshake를 시작한다.

      참고: 이는 connection에 대해 연결 닫힘 처리 단계가 실행되도록 하며, 이 단계는 connection과 관련된 리소스를 정리한다.

4.1. 연결 수립

WebDriver 클라이언트는 값이 true인 WebSocket URL 기능을 요청하여 양방향 연결을 선택한다.

이 명세에서 정의하는 WebDriver 새 세션 알고리즘은 매개변수 session, capabilities, flags에 대해 다음과 같다:
  1. flags가 "bidi"를 포함하면 반환한다.

  2. webSocketUrl을 capabilities에서 "webSocketUrl"이라는 이름의 속성 가져오기를 수행한 결과로 둔다.

  3. webSocketUrl이 undefined이면 반환한다.

  4. 단언: webSocketUrl은 true이다.

  5. listener를 session이 주어졌을 때 WebSocket 연결 수신 시작을 수행한 결과로 둔다.

  6. webSocketUrl을 listener 및 session으로 WebSocket URL 구성을 수행한 결과로 설정한다.

  7. capabilities에 "webSocketUrl"이라는 이름의 속성 설정을 하여 webSocketUrl로 설정한다.

  8. session의 BiDi 플래그를 true로 설정한다.

  9. "bidi"를 flags에 추가한다.

구현은 클라이언트가 BiDi 세션이면서 HTTP 세션이 아닌 세션을 수립할 수도 있게 해야 한다. 이 경우 WebSocket 서버의 URL은 대역 외로 전달된다. 이를 허용하는 구현은 BiDi 전용 세션을 지원한다. 그러한 구현이 WebDriver 세션을 시작하는 요청을 받아들일 준비가 된 시점에, 다음을 해야 한다:

  1. null이 주어졌을 때 WebSocket 연결 수신 시작을 한다.

5. 샌드박스화된 스크립트 실행

자동화 도구의 일반적인 요구사항은 문서의 DOM에 접근할 수 있지만, 해당 문서를 포함하는 navigable에서 실행 중인 스크립트가 DOM API에 적용한 변경에 관한 정보는 갖지 않는 스크립트를 실행하는 것이다.

BiDi 세션은 샌드박스 맵을 가지며, 이는 키가 Window 객체이고, 값이 문자열과 SandboxWindowProxy 객체 사이의 맵인 약한 맵이다.

참고: 여기서의 샌드박스 정의는 기존 구현의 동작을 성문화하려는 시도이다. 이는 이전에 명세에서 내부적인 것으로 간주되던 구현의 일부, 특히 플랫폼 객체의 내부 상태(일반적으로 브라우저 엔진의 주 구현 언어에서 네이티브 객체로 구현됨)와 ECMAScript에서 보이는 상태 사이의 구별을 드러낸다. 기존 샌드박스 구현은 엔진의 낮은 수준에서 이루어지기 때문에, 구현들이 명세의 모든 세부사항으로 수렴하는 것은 느린 과정일 수 있다. 그동안 구현자는 명세와의 차이에 대한 자세한 문서를 제공하는 것이 권장되며, 이 기능의 사용자는 샌드박스에서 실행되는 스크립트가 모든 구현에서 작동하는지 명시적으로 테스트하는 것이 권장된다.

5.1. 샌드박스 렐름

각 샌드박스는 고유한 ECMAScript Realm이다. 그러나 샌드박스 렐름은 Window 렐름에 있는 플랫폼 객체에 SandboxProxy 객체를 통해 접근할 수 있게 한다.

name 및 navigable이 주어졌을 때 샌드박스 렐름 가져오기 또는 생성을 하려면:
  1. name이 빈 문자열이면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  2. window를 navigable의 활성 window로 둔다.

  3. 샌드박스 맵이 window를 포함하지 않으면, 샌드박스 맵[window]을 새 맵으로 설정한다.

  4. sandboxes를 샌드박스 맵[window]로 둔다.

  5. sandboxes가 name을 포함하지 않으면, sandboxes[name]을 navigable로 샌드박스 렐름 생성을 수행한 결과로 설정한다.

  6. 데이터 sandboxes[name]와 함께 성공을 반환한다.

window로 샌드박스 렐름 생성을 하려면:

샌드박스 렐름의 생성을 정의한다. 이는 window를 래핑하는 SandboxWindowProxy를 반환하게 된다.

target realm이 주어졌을 때 샌드박스 이름 가져오기를 하려면:

  1. realms maps를 값 가져오기를 샌드박스 맵에 수행한 결과로 둔다.

  2. realms maps의 각 realms map에 대해:

    1. realms map의 각 name → realm에 대해:

      1. realm이 target realm이면, name을 반환한다.

  3. null을 반환한다.

5.2. 샌드박스 프록시 객체

SandboxProxy 객체는 다른 렐름의 객체에 대한 샌드박스화된 접근을 중재하는 이국적 객체이다. 샌드박스 프록시 객체는 다음 제한을 강제하도록 설계되어 있다:

SandboxProxy 인터페이스 객체는 없다.

SandboxProxy가 어떻게 동작하는지 자세히 정의한다

object의 래핑 해제된 것을 얻으려면:
  1. object가 SandboxProxy 또는 SandboxWindowProxy인 동안, object를 그것의 래핑된 객체로 설정한다.

  2. object를 반환한다.

5.3. SandboxWindowProxy

SandboxWindowProxy는 Window 객체가 SandboxProxy 객체로 래핑된 것을 나타내는 이국적 객체이다. 이는 Window 전역에서 해당 데이터에 대한 샌드박스화된 접근을 제공한다.

이것이 어떻게 동작하는지 정의한다.

6. 사용자 컨텍스트

사용자 컨텍스트는 원격 끝 내의 0개 이상의 최상위 traversable 모음을 나타낸다. 각 사용자 컨텍스트는 연관된 저장소 파티션을 가지므로, 원격 끝 데이터는 서로 다른 사용자 컨텍스트 사이에서 공유되지 않는다.

이것이 사용자 컨텍스트 개념이나 저장소와의 상호작용을 형식적으로 정의하는 최선의 방법인지 불분명하다.

참고: Infra 명세는 "user agent"라는 용어를 사용자 컨텍스트와 같은 개념을 지칭하는 데 사용한다. 그러나 이는 여러 사용자 컨텍스트를 가진 전체 웹 클라이언트를 의미하는 "user agent"라는 용어의 사용과 호환되지 않는다. 이 차이는 웹 콘텐츠에는 보이지 않지만, WebDriver를 통해 관찰되므로, 여기서는 이 용어 사용을 피한다.

사용자 컨텍스트는 사용자 컨텍스트 id를 가지며, 이는 사용자 컨텍스트 생성 시 설정되는 고유한 문자열이다.

navigable은 연관된 사용자 컨텍스트를 가지며, 이는 사용자 컨텍스트이다.

새 최상위 traversable이 생성될 때, 그 연관된 사용자 컨텍스트는 사용자 컨텍스트 집합의 한 사용자 컨텍스트로 설정된다.

참고: 어떤 경우에는 최상위 traversable이 생성될 때 사용자 컨텍스트가 명세에 의해 설정된다. 그러나 그러한 요구사항이 없는 경우, 연관된 사용자 컨텍스트는 최상위 traversable에 대해 구현 정의이다.

null이 아닌 opener를 가진 최상위 traversable이 opener와 동일한 연관된 사용자 컨텍스트를 가진다고 명시해야 하는가? 기존 구현이 이를 강제하는지 확인해야 한다.

자식 navigable의 연관된 사용자 컨텍스트는 그것의 부모의 연관된 사용자 컨텍스트이다.

어떤 사용자 컨텍스트가 어떠한 최상위 traversable의 연관된 사용자 컨텍스트도 아니면, 이는 빈 사용자 컨텍스트이다.

기본 사용자 컨텍스트는 사용자 컨텍스트이며, 사용자 컨텍스트 id가 "default"이다.

구현은 사용자 컨텍스트 집합을 가지며, 이는 사용자 컨텍스트의 집합이다. 처음에는 기본 사용자 컨텍스트를 포함한다.

구현은 예를 들어 사용자 동작에 대한 응답으로 언제든지 새 사용자 컨텍스트를 사용자 컨텍스트 집합에 추가할 수 있다.

참고: 여기서 "언제든지"는 구현 시작 중도 포함하므로, 주어진 구현은 항상 사용자 컨텍스트 집합에 여러 항목을 가질 수 있다.

구현은 기본 사용자 컨텍스트를 제외하고, 빈 사용자 컨텍스트를 언제든지 사용자 컨텍스트 집합에서 제거할 수 있다. 그러나 그러한 사용자 컨텍스트를 제거해야 하는 것은 아니다. 사용자 컨텍스트가 빈 사용자 컨텍스트가 아니면 사용자 컨텍스트 집합에서 제거되어서는 안 된다.

BiDi 세션은 사용자 컨텍스트에서 안전하지 않은 인증서 허용 재정의로의 맵을 가지며, 이는 사용자 컨텍스트와 boolean 사이의 맵이다.

BiDi 세션은 사용자 컨텍스트에서 프록시 구성으로의 맵을 가지며, 이는 사용자 컨텍스트와 프록시 구성 사이의 맵이다.

에뮬레이트된 네트워크 조건 구조체는 다음을 가진 구조체이다:

BiDi 세션은 에뮬레이트된 네트워크 조건을 가지며, 이는 구조체로, 에뮬레이트된 네트워크 조건 구조체 또는 null인 기본 네트워크 조건이라는 이름의 항목, 사용자 컨텍스트와 에뮬레이트된 네트워크 조건 구조체 사이의 약한 맵인 사용자 컨텍스트 네트워크 조건이라는 이름의 항목, 그리고 navigable과 에뮬레이트된 네트워크 조건 구조체 사이의 약한 맵인 navigable 네트워크 조건이라는 이름의 항목을 가진다.

사용자 컨텍스트가 사용자 컨텍스트 집합에서 제거되면, 사용자 컨텍스트 구독 제거를 한다.

사용자 컨텍스트 구독 제거를 하려면:

  1. 활성 세션의 각 session에 대해:

    1. subscriptions to remove를 집합으로 둔다.

    2. session의 구독에 있는 각 subscription에 대해:

      1. subscription의 사용자 컨텍스트 id가 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id를 포함하면:

        1. navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id를 subscription의 사용자 컨텍스트 id에서 제거한다.

        2. subscription의 사용자 컨텍스트 id가 비어 있으면:

          1. subscription을 subscriptions to remove에 추가한다.

    3. subscriptions to remove를 session의 구독에서 제거한다.

user context id가 주어졌을 때 사용자 컨텍스트 가져오기를 하려면:
  1. 사용자 컨텍스트 집합의 각 user context에 대해:

  2. user context의 사용자 컨텍스트 id가 user context id와 같으면:

    1. user context를 반환한다.

  3. null을 반환한다.

user context ids가 주어졌을 때 유효한 사용자 컨텍스트 가져오기를 하려면:

  1. result를 빈 집합으로 둔다.

  2. user context ids의 각 user context id에 대해:

    1. user context를 user context id로 사용자 컨텍스트 가져오기를 수행한 결과로 설정한다.

    2. user context가 null이면, 오류를 반환하되 오류 코드는 no such user context로 한다.

    3. user context를 result에 추가한다.

  3. result를 반환한다.

7. 모듈

7.1. session 모듈

session 모듈은 원격 끝의 상태를 모니터링하기 위한 명령 및 이벤트를 포함한다.

7.1.1. 정의

원격 끝 정의

SessionCommand = (
  session.End //
  session.New //
  session.Status //
  session.Subscribe //
  session.Unsubscribe
)

로컬 끝 정의

SessionResult = (
  session.EndResult /
  session.NewResult /
  session.StatusResult /
  session.SubscribeResult /
  session.UnsubscribeResult
)
session이 주어졌을 때 세션 종료를 하려면:
  1. session을 활성 세션에서 제거한다.

  2. 활성 세션이 비어 있으면, webdriver-active 플래그를 false로 설정한다.

session이 주어졌을 때 세션 정리를 하려면:

  1. session으로 WebSocket 연결 닫기를 한다.

  2. 사용자 컨텍스트 집합의 각 user context에 대해:

    1. session의 사용자 컨텍스트에서 안전하지 않은 인증서 허용 재정의로의 맵[user context]를 제거한다.

    2. session의 사용자 컨텍스트에서 프록시 구성으로의 맵[user context]를 제거한다.

  3. session의 차단된 요청 맵에 있는 각 request id → (request, phase, response)에 대해:

    1. "continue request", request id 및 (response, "incomplete")로 재개한다.

  4. session의 네트워크 컬렉터에 있는 각 collector에 대해:

    1. collector id를 collector의 컬렉터로 둔다.

    2. 수집된 네트워크 데이터의 각 collected data에 대해, collected data 및 collector id로 데이터에서 컬렉터 제거를 한다.

  5. session의 스크린캐스트 녹화 맵에 있는 각 screencast recording에 대해:

    1. screencast recording이 주어졌을 때 스크린캐스트 녹화를 중지한다.

    2. 제거: screencast recording을 스크린캐스트 녹화 맵에서 제거한다.

  6. 활성 세션이 비어 있으면, 원격 끝 상태 정리를 한다.

  7. 구현별 정리 단계를 수행한다.

원격 끝 상태 정리를 하려면.
  1. before request sent 맵을 비운다.

  2. 기본 캐시 동작을 "default"로 설정한다.

  3. navigable 캐시 동작 맵을 비운다.

  4. 현재 원격 끝 구성에서 일반적으로 활성화되는 구현별 리소스 캐시를 활성화하기 위해 구현 정의 단계를 수행한다.

7.1.2. 타입

7.1.2.1. session.CapabilitiesRequest 유형
session.CapabilitiesRequest = {
  ? alwaysMatch: session.CapabilityRequest,
  ? firstMatch: [*session.CapabilityRequest]
}

session.CapabilitiesRequest 유형은 세션에 대해 요청된 기능을 나타냅니다.

7.1.2.2. session.CapabilityRequest 유형

원격 엔드 정의 및 로컬 엔드 정의

session.CapabilityRequest = {
  ? acceptInsecureCerts: bool,
  ? browserName: text,
  ? browserVersion: text,
  ? platformName: text,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler,
  Extensible
}

session.CapabilityRequest 유형은 요청된 특정 기능 집합을 나타냅니다.

WebDriver BiDi는 추가 WebDriver 기능을 정의합니다. 다음 표에는 각 구현이 WebDriver BiDi를 위해 지원해야 하는 기능이 나열되어 있습니다.

기능: WebSocket URL
키: "webSocketUrl"
값 유형: boolean
설명: 현재 세션의 양방향 연결 지원 여부를 정의합니다.
"webSocketUrl" 기능의 추가 기능 역직렬화 알고리즘은 매개변수 value를 사용하며 다음과 같습니다:
  1. value가 boolean이 아닌 경우, 오류를 코드 잘못된 인수와 함께 반환합니다.

  2. 데이터 value와 함께 성공을 반환합니다.

"webSocketUrl" 기능의 일치하는 기능 직렬화 알고리즘은 매개변수 value를 사용하며 다음과 같습니다:
  1. value가 false인 경우, 데이터 null과 함께 성공을 반환합니다.

  2. 데이터 true와 함께 성공을 반환합니다.

7.1.2.3. session.CapabilityResponse 유형
session.CapabilityResponse = {
  acceptInsecureCerts: bool,
  browserName: text,
  browserVersion: text,
  platformName: text,
  setWindowRect: bool,
  userAgent: text,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler,
  ? webSocketUrl: text,
  Extensible
}

session.CapabilityResponse 유형은 새 세션에 대해 협상된 모든 기능을 나타냅니다.

7.1.2.4. session.ProxyConfiguration 유형

원격 엔드 정의 및 로컬 엔드 정의

session.ProxyConfiguration = {
   session.AutodetectProxyConfiguration //
   session.DirectProxyConfiguration //
   session.ManualProxyConfiguration //
   session.PacProxyConfiguration //
   session.SystemProxyConfiguration
}

session.AutodetectProxyConfiguration = (
   proxyType: "autodetect",
   Extensible
)

session.DirectProxyConfiguration = (
   proxyType: "direct",
   Extensible
)

session.ManualProxyConfiguration = (
   proxyType: "manual",
   ? httpProxy: text,
   ? sslProxy: text,
   ? session.SocksProxyConfiguration,
   ? noProxy: [*text],
   Extensible
)

session.SocksProxyConfiguration = (
   socksProxy: text,
   socksVersion: 0..255,
)

session.PacProxyConfiguration = (
   proxyType: "pac",
   proxyAutoconfigUrl: text,
   Extensible
)

session.SystemProxyConfiguration = (
   proxyType: "system",
   Extensible
)
7.1.2.5. session.UserPromptHandler 유형

원격 엔드 정의 및 로컬 엔드 정의

session.UserPromptHandler = {
  ? alert: session.UserPromptHandlerType,
  ? beforeUnload: session.UserPromptHandlerType,
  ? confirm: session.UserPromptHandlerType,
  ? default: session.UserPromptHandlerType,
  ? file: session.UserPromptHandlerType,
  ? prompt: session.UserPromptHandlerType,
}

session.UserPromptHandler 유형은 사용자 프롬프트 처리기의 구성을 나타냅니다.

참고: file은 파일 선택기를 처리합니다. "accept" 및 "dismiss"는 선택기를 닫습니다. "ignore"는 선택기를 열린 상태로 유지합니다.

7.1.2.6. session.UserPromptHandlerType 유형

원격 엔드 정의 및 로컬 엔드 정의

session.UserPromptHandlerType = "accept" / "dismiss" / "ignore";

session.UserPromptHandlerType 유형은 사용자 프롬프트 처리기의 동작을 나타냅니다.

7.1.2.7. session.Subscription 유형
session.Subscription = text

session.Subscription 유형은 고유한 구독 식별자를 나타냅니다.

7.1.2.8. session.SubscribeParameters 유형
session.SubscribeParameters = {
  events: [+text],
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

session.SubscribeParameters 유형은 특정 이벤트 집합을 구독하기 위한 요청을 나타냅니다.

7.1.2.9. session.UnsubscribeByIDRequest 유형
session.UnsubscribeByIDRequest = {
  subscriptions: [+session.Subscription],
}

session.UnsubscribeByIDRequest 유형은 구독 ID로 식별되는 이벤트 구독을 제거하기 위한 요청을 나타냅니다.

7.1.2.10. session.UnsubscribeByAttributesRequest 유형
session.UnsubscribeByAttributesRequest = {
  events: [+text],
}

session.UnsubscribeByAttributesRequest 유형은 구독 속성을 사용하여 구독을 취소하기 위한 요청을 나타냅니다.

7.1.3. 명령

7.1.3.1. session.status 명령

session.status 명령은 원격 끝이 새 세션을 만들 수 있는 상태인지에 관한 정보를 반환하지만, 추가로 구현에 특화된 임의의 메타 정보를 포함할 수도 있다.

이는 정적 명령이다.

명령 타입
session.Status = (
  method: "session.status",
  params: EmptyParams,
)
반환 타입
session.StatusResult = {
  ready: bool,
  message: text,
}

session 및 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같다:

  1. body를 다음 속성을 가진 새 맵으로 둔다:

    "ready"
    원격 끝의 준비 상태.
    "message"
    원격 끝의 준비 상태를 설명하는 구현 정의 문자열.
  2. 데이터 body와 함께 성공을 반환한다

7.1.3.2. session.new 명령

session.new 명령은 새 BiDi 세션을 만들 수 있게 한다.

참고: 이 방식으로 생성된 세션은 HTTP를 통해 접근할 수 없다.

이는 정적 명령이다.

명령 타입
session.New = (
  method: "session.new",
  params: session.NewParameters
)

session.NewParameters = {
  capabilities: session.CapabilitiesRequest
}
반환 타입
session.NewResult = {
  sessionId: text,
  capabilities: session.CapabilityResponse
}

session 및 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같다:

  1. session이 null이 아니면, 오류 코드 session not created인 오류를 반환한다.

  2. 어떤 이유로든 구현이 새 세션을 시작할 수 없으면, 오류 코드 session not created인 오류를 반환한다.

  3. flags를 "bidi"를 포함하는 집합으로 둔다.

  4. capabilities json을 command parameters 및 flags로 기능 처리를 시도한 결과로 둔다.

  5. capabilities를 capabilities json으로 JSON 파생 JavaScript 값을 Infra 값으로 변환한 결과로 둔다.

  6. session을 capabilities 및 flags로 세션 생성을 시도한 결과로 둔다.

  7. session의 BiDi 플래그를 true로 설정한다.

    참고: 이 세션에 대한 연결은 호출자에 의해 현재 연결로 설정된다.

  8. body를 session.NewResult 생성규칙과 일치하는 새 맵으로 둔다. 이때 sessionId 필드는 session의 세션 ID로 설정하고, capabilities 필드는 capabilities로 설정한다.

  9. 데이터 body와 함께 성공을 반환한다.

7.1.3.3. session.end 명령

session.end 명령은 현재 세션을 종료한다.

명령 타입
session.End = (
  method: "session.end",
  params: EmptyParams
)

반환 타입
session.EndResult = EmptyResult

session 및 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같다:

  1. session으로 세션 종료를 한다.

  2. 데이터 null과 함께 성공을 반환하고, 병렬로 다음 단계를 실행한다:

    1. 이 명령에 대한 응답으로 WebSocket 메시지 전송 단계가 호출될 때까지 기다린다.

      이는 다소 부정확한 표현이지만, 의도는 연결 종료를 시작하기 전에 명령에 대한 응답을 전송한다는 점이 명확하기를 바란다.

    2. session으로 세션 정리를 한다.

7.1.3.4. session.subscribe 명령

session.subscribe 명령은 특정 이벤트를 전역으로 또는 navigable 집합에 대해 활성화한다.

이는 realm에도 동작하도록 일반화되어야 한다.

명령 타입
session.Subscribe = (
  method: "session.subscribe",
  params: session.SubscribeParameters
)
반환 타입
session.SubscribeResult = {
  subscription: session.Subscription,
}
session 및 command parameters로 원격 끝 단계는 다음과 같다:
  1. event names를 빈 집합으로 둔다.

  2. command parameters["events"]의 각 항목 name에 대해, event names를 event names와 name으로 이벤트 이름 집합 얻기를 시도한 결과의 합집합으로 둔다.

  3. input user context ids를 command parameters[userContexts]로 집합 생성을 수행한 결과로 둔다.

  4. input context ids를 command parameters[contexts]로 집합 생성을 수행한 결과로 둔다.

  5. input user context ids가 비어 있지 않고 input context ids도 비어 있지 않으면, 오류를 반환하되, 오류 코드는 invalid argument로 한다.

  6. subscription navigables를 집합으로 둔다.

  7. top-level traversable context ids를 집합으로 둔다.

  8. input context ids가 비어 있지 않으면:

    1. navigables를 input context ids로 id로 유효한 navigable 가져오기를 시도한 결과로 둔다.

    2. subscription navigables를 navigables로 최상위 traversable 가져오기를 수행한 결과로 설정한다.

    3. subscription navigables의 각 navigable에 대해:

      1. navigable의 navigable id를 top-level traversable context ids에 추가한다.

  9. 그렇지 않고, input user context ids가 비어 있지 않으면:

    1. input user context ids의 각 user context id에 대해:

      1. user context를 user context id로 사용자 컨텍스트 가져오기를 수행한 결과로 둔다.

      2. user context가 null이면, 오류를 반환하되, 오류 코드는 no such user context로 한다.

      3. 연관된 사용자 컨텍스트가 user context인 모든 최상위 traversable의 목록에 있는 각 top-level traversable에 대해:

        1. top-level traversable을 subscription navigables에 추가한다.

  10. 그렇지 않으면, subscription navigables를 원격 끝의 모든 최상위 traversable의 집합으로 설정한다.

  11. subscription을 구독으로 둔다. 이때 구독 id는 UUID의 문자열 표현으로 설정하고, 이벤트 이름은 event names로 설정하며, 최상위 traversable id는 top-level traversable context ids로 설정하고 사용자 컨텍스트 id는 input user context ids로 설정한다.

  12. subscribe step events를 새 맵으로 둔다.

  13. event names의 각 event name에 대해:

    1. event name이라는 이벤트 이름을 가진 이벤트가 원격 끝 구독 단계를 정의하지 않으면, 계속한다;

    2. existing navigables를 session 및 event name으로 이벤트가 활성화된 최상위 traversable의 집합을 수행한 결과로 둔다.

    3. subscribe step events[event name]을 subscription navigables와 existing navigables의 차집합으로 설정한다.

  14. subscription을 session의 구독에 추가한다.

  15. subscription의 구독 id를 session의 알려진 구독 id에 추가한다.

  16. 키가 event name one 및 event name two인 두 항목이 주어졌을 때, 다음 less than 알고리즘을 사용하여 subscribe step events를 오름차순으로 정렬한다:

    1. event one을 이름이 event name one인 이벤트로 둔다

    2. event two를 이름이 event name two인 이벤트로 둔다

    3. event one의 구독 우선순위가 event two의 구독 우선순위보다 작으면 true를 반환하고, 그렇지 않으면 false를 반환한다.

  17. subscription이 전역이면 include global을 true로 두고, 그렇지 않으면 include global을 false로 둔다.

  18. subscribe step events의 각 event name → navigables에 대해:

    1. event name이라는 이벤트 이름을 가진 이벤트에 대한 원격 끝 구독 단계를 session, navigables 및 include global이 주어졌을 때 실행한다.

  19. body를 session.SubscribeResult 생성규칙과 일치하는 새 맵으로 둔다. 이때 subscription 필드는 subscription의 구독 id로 설정한다.

  20. 데이터 body와 함께 성공을 반환한다.

7.1.3.5. session.unsubscribe 명령

session.unsubscribe 명령은 이벤트를 전역으로 또는 navigable 집합에 대해 비활성화한다.

이는 realm에도 동작하도록 일반화되어야 한다.

명령 타입
session.Unsubscribe = (
  method: "session.unsubscribe",
  params: session.UnsubscribeParameters,
)

session.UnsubscribeParameters = session.UnsubscribeByAttributesRequest / session.UnsubscribeByIDRequest
반환 타입
session.UnsubscribeResult = EmptyResult
session 및 command parameters로 원격 끝 단계는 다음과 같다:
  1. command parameters가 "subscriptions"를 포함하지 않으면:

    참고: 이 조건은 command parameters가 session.UnsubscribeByAttributesRequest 생성규칙과 일치함을 의미한다.

    1. event names를 빈 집합으로 둔다.

    2. command parameters["events"]의 각 항목 name에 대해, event names를 event names와 name으로 이벤트 이름 집합 얻기를 시도한 결과의 합집합으로 둔다.

    3. new subscriptions를 목록으로 둔다.

    4. matched events를 집합으로 둔다.

    5. session의 구독의 각 subscription에 대해:

      1. subscription의 이벤트 이름과 event names의 교집합이 빈 집합이면:

        1. subscription을 new subscriptions에 추가한다.

        2. 계속한다.

      2. subscription이 전역이 아니면:

        1. subscription을 new subscriptions에 추가한다.

        2. 계속한다.

      3. subscription event names를 subscription의 이벤트 이름의 복제로 둔다.

      4. event names의 각 event name에 대해:

        1. subscription event names가 event name을 포함하면:

          1. event name을 matched events에 추가한다.

          2. event name을 subscription event names에서 제거한다.

      5. subscription event names가 비어 있지 않으면:

        1. cloned subscription을 구독으로 둔다. 이때 구독 id는 subscription의 구독 id로 설정하고, 이벤트 이름은 subscription event names를 포함하는 새 집합으로 설정한다.

        2. cloned subscription을 new subscriptions에 추가한다.

    6. matched events와 동등하지 않은 event names라면, 오류를 반환하며 오류 코드는 invalid argument입니다.

    7. session의 구독을 new subscriptions로 설정한다.

  2. 그렇지 않으면:

    1. subscriptions를 command parameters[subscriptions]로 집합 생성을 수행한 결과로 둔다.

    2. unknown subscription ids를 subscriptions와 session의 알려진 구독 id의 차집합으로 둔다.

    3. unknown subscription ids가 비어 있지 않으면:

      1. 오류를 반환하되, 오류 코드는 invalid argument로 한다.

    4. subscriptions to remove를 빈 집합으로 둔다.

    5. session의 구독에 있는 각 subscription에 대해:

      1. subscriptions가 subscription의 구독 id를 포함하면:

        1. subscription을 subscriptions to remove에 추가한다.

    6. session의 알려진 구독 id를 session의 알려진 구독 id와 subscriptions의 차집합으로 설정한다.

    7. subscriptions to remove의 각 항목을 session의 구독에서 제거한다.

  3. 데이터 null과 함께 성공을 반환한다.

7.2. browser 모듈

browser 모듈은 원격 끝 브라우저 프로세스를 관리하기 위한 명령을 포함한다.

7.2.1. 정의

원격 끝 정의

BrowserCommand = (
  browser.Close //
  browser.CreateUserContext //
  browser.GetClientWindows //
  browser.GetUserContexts //
  browser.RemoveUserContext //
  browser.SetClientWindowState //
  browser.SetDownloadBehavior
)

로컬 끝 정의

BrowserResult = (
  browser.CloseResult /
  browser.CreateUserContextResult /
  browser.GetClientWindowsResult /
  browser.GetUserContextsResult /
  browser.RemoveUserContextResult /
  browser.SetClientWindowStateResult /
  browser.SetDownloadBehaviorResult
)

7.2.2. 창

각 최상위 traversable은 하나의 클라이언트 창과 연관되며, 이는 해당 최상위 traversable의 활성 문서를 렌더링하는 데 사용될 뷰포트를 포함하는 직사각형 영역을 나타낸다. 이는 그 가시성 상태가 "visible"일 때 적용되며, traversable 표시와 관련된 브라우저별 사용자 인터페이스 요소 (예: URL 바, 도구 모음, 또는 OS 창 장식)도 포함한다.

클라이언트 창은 그 창을 고유하게 식별하는 문자열인 클라이언트 창 id를 가진다.

클라이언트 창은 x 좌표를 가지며, 이는 웹에 노출된 화면 영역의 왼쪽 가장자리와 창의 왼쪽 가장자리 사이의 CSS 픽셀 수이거나, 특정 창에 대해 그것이 의미가 없으면 0이다.

클라이언트 창은 y 좌표를 가지며, 이는 웹에 노출된 화면 영역의 위쪽 가장자리와 창의 위쪽 가장자리 사이의 CSS 픽셀 수이거나, 특정 창에 대해 그것이 의미가 없으면 0이다.

클라이언트 창은 너비를 가지며, 이는 창 직사각형의 너비를 CSS 픽셀 단위로 나타낸다.

클라이언트 창은 높이를 가지며, 이는 창 직사각형의 높이를 CSS 픽셀 단위로 나타낸다.

window인 클라이언트 창 최대화를 하려면 구현은 플랫폼의 window 최대화 개념에 해당하는 단계를 수행하거나, window의 x 좌표가 가능한 한 0에 가깝고, 그 y 좌표가 가능한 한 0에 가까우며, 그 너비가 웹에 노출된 화면 영역의 너비에 가능한 한 가깝고, 그 높이가 웹에 노출된 화면 영역의 높이에 가능한 한 가깝도록 window의 위치를 지정해야 한다. 이 옵션 중 하나가 지원되면 클라이언트 창 최대화가 지원됨이다.

window인 클라이언트 창 최소화를 하려면 구현은 플랫폼의 window 최소화 개념에 해당하는 단계를 수행하거나, 그렇지 않으면 window를 숨겨 window와 연관된 최상위 traversable의 모든 활성 문서가 가시성 상태 "hidden"을 가지며, window의 너비와 높이가 둘 다 가능한 한 0에 가깝도록 해야 한다. 이 옵션 중 하나가 지원되면 클라이언트 창 최소화가 지원됨이다.

window인 클라이언트 창 복원을 하려면 구현은 그것이 플랫폼 정의의 최대화 상태도, 플랫폼 정의의 최소화 상태도 아니며, window와 연관된 하나 이상의 최상위 traversable이 있는 경우 그중 적어도 하나가 "visible" 상태의 활성 문서를 가지도록 보장해야 한다. 이것이 지원되면 클라이언트 창 복원이 지원됨이다.

window가 주어졌을 때 클라이언트 창 상태 가져오기를 하려면:

  1. documents를 빈 목록으로 둔다.

  2. visible documents를 빈 목록으로 둔다.

  3. 각 최상위 traversable traversable에 대해:

    1. traversable의 클라이언트 창이 window가 아니면 계속한다.

    2. document를 traversable의 활성 문서로 둔다.

    3. document를 documents에 추가한다.

    4. document의 가시성 상태가 "visible"이면, document를 visible documents에 추가한다.

  4. visible documents의 각 document에 대해:

    1. document의 fullscreen 요소가 null이 아니면 "fullscreen"을 반환한다.

  5. visible documents가 비어 있고 documents가 비어 있지 않으면, 또는 window가 그 밖에 OS별 최소화 상태이면, "minimized"를 반환한다.

    참고: 이는 일반적으로, 하지만 반드시 그런 것은 아니지만, window의 너비와 높이가 0과 같음을 의미한다.

  6. window가 OS별 최대화 상태이면 "maximized"를 반환한다.

    참고: 이는 일반적으로, 하지만 반드시 그런 것은 아니지만, window의 너비가 웹에 노출된 화면 영역의 너비와 같고 window의 높이가 웹에 노출된 화면 영역의 높이와 같음을 의미한다.

  7. "normal"을 반환한다.

window 및 state가 주어졌을 때 클라이언트 창 상태 설정을 하려면:

  1. current state를 window로 클라이언트 창 상태 가져오기를 수행한 결과로 둔다.

  2. current state가 "fullscreen", "maximized" 또는 "minimized"이고 state와 같으면, 데이터 null과 함께 성공을 반환한다.

  3. 다음 조건과 연관된 단계의 목록에서, 연관된 조건이 true인 첫 번째 단계 집합을 실행한다:

    "fullscreen"
    fullscreen이 지원됨이 아니면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.
    "normal"
    window에 대해 클라이언트 창 복원이 지원됨이 아니면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.
    "maximize"
    window에 대해 클라이언트 창 최대화가 지원됨이 아니면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.
    "minimize"
    window에 대해 클라이언트 창 최소화가 지원됨이 아니면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.
  4. documents를 빈 목록으로 둔다.

  5. 각 최상위 traversable traversable에 대해:

    1. traversable의 연관된 클라이언트 창이 window가 아니면 계속한다.

    2. document를 traversable의 활성 문서로 둔다.

    3. document를 documents에 추가한다.

  6. documents가 비어 있으면, 오류를 반환하되 오류 코드는 no such client window로 한다.

  7. current state가 "fullscreen"이면:

    1. documents의 각 document에 대해:

      1. document로 fullscreen 완전 종료를 한다.

        참고: 이는 fullscreen이 아닌 창의 문서에 대해서는 아무 작업도 하지 않는다.

  8. current state가 "maximized" 또는 "minimized"이면:

    1. window를 클라이언트 창 복원한다.

  9. state의 값에 따라 전환한다:

    "fullscreen"
    1. documents의 각 document에 대해:

      1. document의 가시성 상태가 "visible"이면, document의 document 요소로 요소를 fullscreen으로 만들기를 한다.

      2. 중단한다.

    "maximize"
    1. window를 클라이언트 창 최대화한다.
    "minimize"
    1. window를 클라이언트 창 최소화한다.
  10. 데이터 null과 함께 성공을 반환한다.

7.2.3. 타입

7.2.3.1. browser.ClientWindow 타입
browser.ClientWindow = text;

browser.ClientWindow는 클라이언트 창을 고유하게 식별한다.

7.2.3.2. browser.ClientWindowInfo 타입
browser.ClientWindowInfo = {
  active: bool,
  clientWindow: browser.ClientWindow,
  height: js-uint,
  state: "fullscreen" / "maximized" / "minimized" / "normal",
  width: js-uint,
  x: js-int,
  y: js-int,
}

browser.ClientWindowInfo 타입은 클라이언트 창의 속성을 나타낸다.

client window가 주어졌을 때 클라이언트 창 정보 가져오기를 하려면:
  1. client window id를 client window에 대한 클라이언트 창 id로 둔다.

  2. state를 client window로 클라이언트 창 상태 가져오기를 수행한 결과로 둔다.

  3. client window가 운영체제로부터 전달되는 키보드 입력을 받을 수 있으면 active를 true로 두고, 그렇지 않으면 active를 false로 둔다.

    참고: 이는 최상위 traversable 중 그 클라이언트 창이 client window인 것이 시스템 포커스를 가진다는 의미일 수 있으며, 또는 브라우저 자체의 사용자 인터페이스가 현재 포커스를 가진다는 의미일 수도 있다.

  4. client window info를 clientWindow 필드는 client window id로, state 필드는 state로, x 필드는 client window의 x 좌표로, y 필드는 client window의 y 좌표로, width 필드는 client window의 너비로, height 필드는 client window의 높이로, 그리고 active 필드는 active로 설정한 browser.ClientWindowsInfo 생성규칙과 일치하는 맵으로 둔다.

  5. client window info를 반환한다

7.2.3.3. browser.UserContext 타입
browser.UserContext = text;

browser.UserContext는 사용자 컨텍스트를 고유하게 식별한다.

7.2.3.4. browser.UserContextInfo 타입
browser.UserContextInfo = {
  userContext: browser.UserContext
}

browser.UserContextInfo 타입은 사용자 컨텍스트의 속성을 나타낸다.

7.2.4. 명령

7.2.4.1. browser.close 명령

browser.close 명령은 모든 WebDriver 세션을 종료하고 원격 브라우저 인스턴스의 자동화 상태를 정리한다.

명령 타입
browser.Close = (
  method: "browser.close",
  params: EmptyParams,
)
반환 타입
browser.CloseResult = EmptyResult
session 및 command parameters로 원격 끝 단계는 다음과 같다:
  1. session으로 세션 종료를 한다.

  2. 활성 세션이 비어 있지 않으면, 구현은 unable to close browser 오류 코드의 오류를 반환할 수 있으며, 그 후 다음 단계를 병렬로 실행한다:

    1. 이 명령에 대한 응답으로 WebSocket 메시지 전송 단계가 호출될 때까지 기다린다.

    2. session으로 세션 정리를 한다.

    참고: 브라우저가 여러 자동화 세션을 가진 경우의 동작은 현재 지정되어 있지 않다. 어느 세션이든 브라우저를 닫을 수 있을 수도 있고, 실제로는 마지막으로 열린 세션만 브라우저를 닫을 수 있을 수도 있으며, 또는 처음 시작된 세션만 그럴 수도 있다. 이 동작은 이 명세의 향후 버전에서 완전히 지정될 수 있다.

  3. 활성 세션의 각 active session에 대해:

    1. active session으로 세션 종료를 한다.

    2. active session으로 세션 정리를 한다

  4. 데이터 null과 함께 성공을 반환하고, 다음 단계를 병렬로 실행한다.

    1. 이 명령에 대한 응답으로 WebSocket 메시지 전송 단계가 호출될 때까지 기다린다.

    2. session으로 세션 정리를 한다.

    3. 최상위 traversable을 언로드 프롬프트 없이 닫는다.

    4. 자동화 중인 원격 끝과 관련된 리소스를 정리하기 위해 구현 정의 단계를 수행한다.

      참고: 예를 들어 여기에는 자동화 중인 브라우저와 관련된 OS 수준 프로세스를 깨끗하게 종료하거나, 원격 끝이 자동화 중에 생성한 사용자 프로필 데이터 같은 임시 상태를 제거하거나, WebSocket 리스너를 종료하는 것이 포함될 수 있다. 브라우저와 운영체제 간의 차이 때문에, 여기서 로컬 끝이 의존할 수 있는 정확한 불변 조건을 자세히 지정하는 것은 불가능하다.

7.2.4.2. browser.createUserContext 명령

browser.createUserContext 명령은 사용자 컨텍스트를 생성한다.

명령 타입
browser.CreateUserContext = (
  method: "browser.createUserContext",
  params: browser.CreateUserContextParameters,
)

browser.CreateUserContextParameters = {
  ? acceptInsecureCerts: bool,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler
}
반환 타입
browser.CreateUserContextResult = browser.UserContextInfo

session 및 command parameters로 원격 끝 단계는 다음과 같다:

  1. user context를 새 사용자 컨텍스트로 둔다.

  2. command parameters가 "acceptInsecureCerts"를 포함하면:

    참고: "acceptInsecureCerts"가 설정되면, 안전하지 않은 TLS 허용 플래그의 동작을 재정의한다.

    1. acceptInsecureCerts를 command parameters["acceptInsecureCerts"]로 둔다:

    2. acceptInsecureCerts가 true이고 엔드포인트 노드가 안전하지 않은 TLS 연결 허용을 지원하지 않으면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.

    3. session의 사용자 컨텍스트에서 안전하지 않은 인증서 허용 재정의로의 맵[user context]을 acceptInsecureCerts로 설정한다.

  3. command parameters가 "unhandledPromptBehavior"를 포함하면, 처리되지 않은 프롬프트 동작 재정의 맵[user context]을 command parameters["unhandledPromptBehavior"]로 설정한다.

  4. command parameters가 "proxy"를 포함하면:

    1. proxy configuration을 command parameters["proxy"]로 둔다.

    2. 원격 끝이 사용자 컨텍스트별 프록시 설정을 구성할 수 없거나, proxy configuration으로 프록시를 구성할 수 없으면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.

    3. session의 사용자 컨텍스트에서 프록시 구성으로의 맵[user context]을 proxy configuration으로 설정한다.

  5. user context를 사용자 컨텍스트 집합에 추가한다.

  6. user context info를 userContext 필드가 user context의 사용자 컨텍스트 id로 설정된 browser.UserContextInfo 생성규칙과 일치하는 맵으로 둔다.

  7. 데이터 user context info와 함께 성공을 반환한다.

7.2.4.3. browser.getClientWindows 명령

browser.getClientWindows 명령은 클라이언트 창의 목록을 반환한다.

명령 타입
browser.GetClientWindows = (
  method: "browser.getClientWindows",
  params: EmptyParams,
)
반환 타입
browser.GetClientWindowsResult = {
  clientWindows: [ * browser.ClientWindowInfo]
}

원격 끝 단계는 다음과 같다:

  1. client window ids를 빈 집합으로 둔다.

  2. client windows를 빈 목록으로 둔다.

  3. 각 최상위 traversable traversable에 대해:

    1. client window를 traversable의 연관된 클라이언트 창으로 둔다

    2. client window id를 client window에 대한 클라이언트 창 id로 둔다.

    3. client window ids가 client window id를 포함하면 계속한다.

    4. client window id를 client window ids에 추가한다.

    5. client window info를 client window로 클라이언트 창 정보 가져오기를 수행한 결과로 둔다.

    6. client window info를 client windows에 추가한다.

  4. result를 clientWindows 필드가 client windows로 설정된 browser.GetClientWindowsResult 생성규칙과 일치하는 맵으로 둔다.

  5. 데이터 result와 함께 성공을 반환한다.

7.2.4.4. browser.getUserContexts 명령

browser.getUserContexts 명령은 사용자 컨텍스트의 목록을 반환한다.

명령 타입
browser.GetUserContexts = (
  method: "browser.getUserContexts",
  params: EmptyParams,
)
반환 타입
browser.GetUserContextsResult = {
  userContexts: [ + browser.UserContextInfo]
}

원격 끝 단계는 다음과 같다:

  1. user contexts를 빈 목록으로 둔다.

  2. 사용자 컨텍스트 집합의 각 user context에 대해:

    1. user context info를 userContext 필드가 user context의 사용자 컨텍스트 id로 설정된 browser.UserContextInfo 생성규칙과 일치하는 맵으로 둔다.

    2. user context info를 user contexts에 추가한다.

  3. result를 userContexts 필드가 user contexts로 설정된 browser.GetUserContextsResult 생성규칙과 일치하는 맵으로 둔다.

  4. 데이터 result와 함께 성공을 반환한다.

7.2.4.5. browser.removeUserContext 명령

browser.removeUserContext 명령은 beforeunload 핸들러를 실행하지 않고 사용자 컨텍스트와 그 안의 모든 navigable을 닫는다.

명령 타입
browser.RemoveUserContext = (
  method: "browser.removeUserContext",
  params: browser.RemoveUserContextParameters
)

browser.RemoveUserContextParameters = {
  userContext: browser.UserContext
}
반환 타입
browser.RemoveUserContextResult = EmptyResult

command parameters로 원격 끝 단계는 다음과 같다:

  1. user context id를 command parameters["userContext"]로 둔다.

  2. user context id가 "default"이면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  3. user context를 user context id로 사용자 컨텍스트 가져오기를 수행한 결과로 설정한다.

  4. user context가 null이면, 오류를 반환하되 오류 코드는 no such user context로 한다.

  5. 각 최상위 traversable navigable에 대해:

    1. navigable의 연관된 사용자 컨텍스트가 user context이면:

      1. navigable을 언로드 프롬프트 없이 닫는다.

  6. user context를 사용자 컨텍스트 집합에서 제거한다.

  7. 데이터 null과 함께 성공을 반환한다.

7.2.4.6. browser.setClientWindowState 명령

browser.setClientWindowState 명령은 클라이언트 창의 치수를 설정한다.

명령 타입
browser.SetClientWindowState = (
  method: "browser.setClientWindowState",
  params: browser.SetClientWindowStateParameters
)

browser.SetClientWindowStateParameters = {
  clientWindow: browser.ClientWindow,
  (browser.ClientWindowNamedState // browser.ClientWindowRectState)
}

browser.ClientWindowNamedState = (
  state: "fullscreen" / "maximized" / "minimized"
)

browser.ClientWindowRectState = (
  state: "normal",
  ? width: js-uint,
  ? height: js-uint,
  ? x: js-int,
  ? y: js-int,
)
반환 타입
browser.SetClientWindowStateResult = browser.ClientWindowInfo

session 및 command parameters로 원격 끝 단계는 다음과 같다:

  1. 구현이 클라이언트 창 상태 설정을 전혀 지원하지 않으면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.

  2. command parameters["clientWindow"]를 클라이언트 창 id로 가지는 클라이언트 창이 있으면, client window를 그 클라이언트 창으로 둔다. 그렇지 않으면 오류를 반환하되 오류 코드는 no such client window로 한다.

  3. client window 및 command parameters["state"]로 시도하여 클라이언트 창 상태 설정을 수행한다.

  4. command parameters["state"]가 "normal"이면:

    1. command parameters가 "x"를 포함하고 구현이 클라이언트 창 위치 지정을 지원하면, client window의 x 좌표를 command parameters["x"]에 가능한 한 가까운 값으로 설정한다.

    2. command parameters가 "y"를 포함하고 구현이 클라이언트 창 위치 지정을 지원하면, client window의 y 좌표를 command parameters["y"]에 가능한 한 가까운 값으로 설정한다.

    3. command parameters가 "width"를 포함하고 구현이 클라이언트 창 크기 조정을 지원하면, client window의 너비를 command parameters["width"]에 가능한 한 가까운 값으로 설정한다.

    4. command parameters가 "width"를 포함하고 구현이 클라이언트 창 크기 조정을 지원하면, client window의 너비를 command parameters["width"]에 가능한 한 가까운 값으로 설정한다.

  5. client window info를 client window로 클라이언트 창 정보 가져오기를 수행한 결과로 둔다.

  6. 데이터 client window info와 함께 성공을 반환한다.

참고: 단순화를 위해 이는 모든 클라이언트 창 조작을 동기적으로 모델링한다. 따라서 반환된 클라이언트 창 치수는 창이 새 상태에 도달한 뒤의 값일 것으로 예상된다.

7.2.4.7. browser.setDownloadBehavior 명령

다운로드 동작 구조체는 다음을 가진 구조체이다:

원격 끝은 다운로드 동작을 가지며, 이는 구조체로서 다운로드 동작 구조체 또는 null인 기본 다운로드 동작이라는 이름의 항목과, 사용자 컨텍스트와 다운로드 동작 구조체 사이의 약한 맵인 사용자 컨텍스트 다운로드 동작이라는 이름의 항목을 가진다.

명령 타입
browser.SetDownloadBehavior = (
  method: "browser.setDownloadBehavior",
  params: browser.SetDownloadBehaviorParameters
)

browser.SetDownloadBehaviorParameters = {
  downloadBehavior: browser.DownloadBehavior / null,
  ? userContexts: [+browser.UserContext]
}

browser.DownloadBehavior = {
  (
    browser.DownloadBehaviorAllowed //
    browser.DownloadBehaviorDenied
  )
}

browser.DownloadBehaviorAllowed = (
  type: "allowed",
  destinationFolder: text
)

browser.DownloadBehaviorDenied = (
  type: "denied"
)
반환 타입
browser.SetDownloadBehaviorResult = EmptyResult
navigable이 주어졌을 때 다운로드 동작 가져오기를 하려면:
  1. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

  2. 다운로드 동작의 사용자 컨텍스트 다운로드 동작이 user context를 포함하면, 다운로드 동작의 사용자 컨텍스트 다운로드 동작[user context]을 반환한다.

  3. 다운로드 동작의 기본 다운로드 동작을 반환한다.

session 및 command parameters로 원격 끝 단계는 다음과 같다:

  1. command parameters["downloadBehavior"]가 null이면, download behavior를 null로 둔다.

  2. 그렇지 않으면:

    1. command parameters["downloadBehavior"]["type"]이 "allowed"이면 allowed를 true로 두고, 그렇지 않으면 allowed를 false로 둔다.

    2. command parameters["downloadBehavior"]가 "destinationFolder"를 포함하면, destinationFolder를 command parameters["downloadBehavior"]["destinationFolder"]로 두고, 그렇지 않으면 destinationFolder를 null로 둔다.

    3. download behavior를 allowed가 allowed로 설정되고 destinationFolder가 destinationFolder로 설정된 다운로드 동작 구조체로 둔다.

  3. 구현이 요구된 download behavior를 지원하지 않으면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.

  4. command parameters의 userContexts 필드가 있으면:

    1. user contexts를 command parameters["userContexts"]로 유효한 사용자 컨텍스트 가져오기를 시도한 결과로 둔다.

    2. user contexts의 각 user context에 대해:

      1. download behavior가 null이면, 다운로드 동작의 사용자 컨텍스트 다운로드 동작에서 user context를 제거한다.

      2. 그렇지 않으면, 다운로드 동작의 사용자 컨텍스트 다운로드 동작[user context]을 download behavior로 설정한다.

  5. 그렇지 않으면, 다운로드 동작의 기본 다운로드 동작을 download behavior로 설정한다.

  6. 데이터 null과 함께 성공을 반환한다.

7.3. browsingContext 모듈

browsingContext 모듈은 navigable과 관련된 명령 및 이벤트를 포함한다.

참고: 역사적인 이유로 이 모듈은 navigable이 아니라 browsingContext라고 불리며, 프로토콜은 navigable을 지칭하기 위해 context라는 용어를 사용한다. 특히 명령 및 응답 매개변수의 필드에서 그렇게 사용된다.

탐색 진행 상황은 불변 구조체 WebDriver BiDi 탐색 상태를 사용하여 전달되며, 이는 다음 항목을 가진다:

id
탐색에 대한 탐색 id, 또는 탐색이 진행되기 전에 취소된 경우 null.
status
"canceled", "pending", 또는 "complete" 중 하나인 상태 코드.
url
탐색에서 로드 중인 URL
suggestedFilename
탐색이 다운로드이면 제안된 파일 이름, 그렇지 않으면 null.
downloadedFilepath
탐색이 완료된 다운로드이고 다운로드된 파일을 사용할 수 있으면 다운로드된 파일의 절대 파일 경로, 그렇지 않으면 null.
downloadResponse
탐색이 다운로드인 경우 응답, 그렇지 않으면 null.

7.3.1. 정의

원격 끝 정의

BrowsingContextCommand = (
  browsingContext.Activate //
  browsingContext.CaptureScreenshot //
  browsingContext.Close //
  browsingContext.Create //
  browsingContext.GetTree //
  browsingContext.HandleUserPrompt //
  browsingContext.LocateNodes //
  browsingContext.Navigate //
  browsingContext.Print //
  browsingContext.Reload //
  browsingContext.SetBypassCSP //
  browsingContext.SetViewport //
  browsingContext.StartScreencast //
  browsingContext.StopScreencast //
  browsingContext.TraverseHistory
)

로컬 끝 정의

BrowsingContextResult = (
  browsingContext.ActivateResult /
  browsingContext.CaptureScreenshotResult /
  browsingContext.CloseResult /
  browsingContext.CreateResult /
  browsingContext.GetTreeResult /
  browsingContext.HandleUserPromptResult /
  browsingContext.LocateNodesResult /
  browsingContext.NavigateResult /
  browsingContext.PrintResult /
  browsingContext.ReloadResult /
  browsingContext.SetBypassCSPResult /
  browsingContext.SetViewportResult /
  browsingContext.StartScreencastResult /
  browsingContext.StopScreencastResult /
  browsingContext.TraverseHistoryResult
)

BrowsingContextEvent = (
  browsingContext.ContextCreated //
  browsingContext.ContextDestroyed //
  browsingContext.DomContentLoaded //
  browsingContext.DownloadEnd //
  browsingContext.DownloadWillBegin //
  browsingContext.FragmentNavigated //
  browsingContext.HistoryUpdated //
  browsingContext.Load //
  browsingContext.NavigationAborted //
  browsingContext.NavigationCommitted //
  browsingContext.NavigationFailed //
  browsingContext.NavigationStarted //
  browsingContext.UserPromptClosed //
  browsingContext.UserPromptOpened
)

원격 끝은 device pixel ratio 재정의를 가지며, 이는 navigable과 device pixel ratio 재정의 사이의 약한 맵이다. 이는 처음에 비어 있다.

참고: 이 맵은 마지막 세션이 종료될 때 비워지지 않는다. 즉 device pixel ratio 재정의는 어떤 WebDriver 세션보다 오래 지속된다.

뷰포트 치수는 다음을 가진 구조체이다:

뷰포트 구성은 다음을 가진 구조체이다:

처리되지 않은 프롬프트 동작 구조체는 다음을 가진 구조체이다:

원격 끝은 뷰포트 재정의 맵을 가지며, 이는 사용자 컨텍스트와 뷰포트 구성 사이의 약한 맵이다.

원격 끝은 로케일 재정의 맵을 가지며, 이는 navigable 또는 사용자 컨텍스트와 문자열 사이의 약한 맵이다.

화면 설정은 정수인 height라는 이름의 항목, 정수인 width라는 이름의 항목, 정수인 x라는 이름의 항목, 정수인 y라는 이름의 항목을 가진 구조체이다.

원격 끝은 화면 설정 재정의를 가지며, 이는 구조체로서 사용자 컨텍스트와 화면 설정 사이의 약한 맵인 사용자 컨텍스트 화면 설정이라는 이름의 항목과, navigable과 화면 설정 사이의 약한 맵인 navigable 화면 설정이라는 이름의 항목을 가진다.

원격 끝은 시간대 재정의 맵을 가지며, 이는 navigable 또는 사용자 컨텍스트와 문자열 사이의 약한 맵이다.

원격 끝은 처리되지 않은 프롬프트 동작 재정의 맵을 가지며, 이는 사용자 컨텍스트와 처리되지 않은 프롬프트 동작 구조체 사이의 약한 맵이다.

원격 끝은 스크립팅 활성화 재정의 맵을 가지며, 이는 navigable 또는 사용자 컨텍스트와 boolean 사이의 약한 맵이다.

A 원격 엔드는 다운로드 ID 맵을 가지며, 이는 응답과 다운로드 ID 사이의 weak map이다. 처음에는 비어 있다.

스크린캐스트 스트림은 최상위 traversable의 뷰포트에 대한 추상 스트림으로, 비디오 트랙으로 구성되며, 최상위 traversable의 문서 뷰포트의 렌더링된 시각적 출력을 포함하고, 선택적으로 오디오 트랙을 포함할 수 있으며, 이는 최상위 traversable의 문서의 오디오 출력을 포함한다.

BiDi 세션은 스크린캐스트 녹화 맵을 가지며, 이는 키가 UUID이고 값이 스크린캐스트 녹화인 맵이다. 스크린캐스트 녹화는 구조체이며, 항목으로, 스크린캐스트 스트림인 stream, 문자열인 path라는 이름의 항목, "recording", "stopping", "stopped" 중 하나인 state라는 이름의 항목, 그리고 문자열 또는 null인 writeError라는 이름의 항목을 가진다.

스크린캐스트 녹화 recording과 mime type이 주어졌을 때 스크린캐스트 녹화를 시작하려면:
  1. 다음 단계를 병렬로 실행한다:

    1. mime type을 사용하여 recording의 stream 인코딩을 시작하고, 인코딩된 데이터의 연속 청크를 바이트 시퀀스로 생성한다. recording의 state가 "recording"인 동안 구현 정의 간격으로 새 청크를 생성한다.

    2. recording에 대해 생성된 각 청크 bytes에 대해, 다음 단계를 실행한다:

      1. bytes를 recording의 path에 있는 파일에 추가한다. 이것이 실패하면:

        1. recording의 writeError를 쓰기 실패를 설명하는 구현 정의 문자열로 설정한다.

        2. recording이 주어졌을 때 스크린캐스트 녹화를 중지한다.

스크린캐스트 녹화 recording이 주어졌을 때 스크린캐스트 녹화를 중지하려면:
  1. recording의 state가 "recording"이 아니면 반환한다.

  2. recording의 state를 "stopping"으로 설정한다.

  3. recording에 대한 새 청크 생성을 중지하고, 남아 있는 인코딩된 데이터를 최종 청크로 플러시하며(스크린캐스트 녹화 시작에서처럼 처리됨), recording의 stream에서 캡처를 중지하고 그 비디오 트랙과, 있는 경우 그 오디오 트랙을 해제한 다음, recording의 state를 "stopped"로 설정한다.

  4. recording의 state가 "stopped"가 될 때까지 기다린다.

7.3.2. 타입

7.3.2.1. browsingContext.BrowsingContext 타입

원격 끝 정의 및 로컬 끝 정의

browsingContext.BrowsingContext = text;

각 navigable은 연관된 navigable id를 가지며, 이는 해당 navigable을 고유하게 식별하는 문자열이다. 이는 navigable이 생성될 때 암묵적으로 설정된다. 연관된 WebDriver 창 핸들을 가진 navigable의 경우, navigable id는 창 핸들과 같아야 한다.

각 navigable은 또한 연관된 저장소 파티션을 가지며, 이는 데이터를 지속시키기 위해 사용하는 저장소 파티션이다.

각 navigable은 또한 연관된 원래 opener를 가지며, 이는 해당 navigable이 열리도록 한 navigable 또는 null이고, 처음에는 null로 설정된다.

navigable id가 주어졌을 때 navigable 가져오기를 하려면:
  1. navigable id가 null이면, 데이터 null과 함께 성공을 반환한다.

  2. navigable id가 navigable id인 navigable이 없으면 오류를 반환하되 오류 코드는 no such frame으로 한다.

  3. navigable을 id가 navigable id인 navigable로 둔다.

  4. 데이터 navigable과 함께 성공을 반환한다.

7.3.2.2. browsingContext.Info 타입

로컬 끝 정의

browsingContext.InfoList = [*browsingContext.Info]

browsingContext.BaseInfo = (
  children: browsingContext.InfoList / null,
  clientWindow: browser.ClientWindow,
  context: browsingContext.BrowsingContext,
  originalOpener: browsingContext.BrowsingContext / null,
  url: text,
  userContext: browser.UserContext,
  ? parent: browsingContext.BrowsingContext / null,
)

browsingContext.Info = {
  browsingContext.BaseInfo
}

browsingContext.Info 타입은 navigable의 속성을 나타낸다.

navigable이 주어졌을 때 자식 navigable 가져오기를 하려면:

TODO: 이를 문서 순서의 목록을 반환하도록 만든다

  1. child navigables를 navigable의 자식 navigable인 모든 navigable을 포함하는 집합으로 둔다.

  2. child navigables를 반환한다.

navigable, max depth 및 include parent id가 주어졌을 때 navigable 정보 가져오기를 하려면:
  1. navigable id를 navigable에 대한 navigable id로 둔다.

  2. parent navigable을 navigable의 부모로 둔다.

  3. parent navigable이 null이 아니면 parent id를 parent navigable의 navigable id로 둔다. 그렇지 않으면 parent id를 null로 둔다.

  4. document를 navigable의 활성 문서로 둔다.

  5. url을 document의 URL이 주어졌을 때 URL 직렬화기를 실행한 결과로 둔다.

    참고: 이는 URL의 fragment 컴포넌트를 포함한다.

  6. child infos를 null로 둔다.

  7. max depth가 null이거나 max depth가 0보다 크면:

    1. child navigables를 navigable이 주어졌을 때 자식 navigable 가져오기를 수행한 결과로 둔다.

    2. max depth가 null이 아니면 child depth를 max depth - 1로, 그렇지 않으면 null로 둔다.

    3. child infos를 빈 목록으로 설정한다.

    4. child navigables의 각 child navigable에 대해:

      1. info를 child navigable, child depth, false가 주어졌을 때 navigable 정보 가져오기를 수행한 결과로 둔다.

      2. info를 child infos에 추가한다

  8. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

  9. navigable의 원래 opener가 null이 아니면 opener id를 navigable의 원래 opener에 대한 navigable id로 두고, 그렇지 않으면 null로 둔다.

  10. top-level traversable을 navigable의 최상위 traversable로 둔다.

  11. client window id를 top-level traversable의 연관된 클라이언트 창에 대한 클라이언트 창 id로 둔다.

  12. navigable info를 context 필드는 navigable id로, include parent id가 true이면 parent 필드는 parent id로 설정하고 그렇지 않으면 설정하지 않으며, url 필드는 url로, userContext 필드는 user context의 사용자 컨텍스트 id로, originalOpener 필드는 opener id로, children 필드는 child infos로, 그리고 clientWindow 필드는 client window id로 설정한 browsingContext.Info 생성규칙과 일치하는 맵으로 둔다.

  13. navigable info를 반환한다.

navigable, request, wait condition, 그리고 선택적으로 history handling(기본값: "default") 및 ignore cache(기본값: false)가 주어졌을 때 탐색 대기를 하려면:
  1. navigation id를 진정한 난수 또는 의사 난수에 기반한 UUID의 문자열 표현으로 둔다.

  2. navigable을 리소스 request로 탐색하되, navigable의 활성 문서를 소스 Document로 사용하고, 탐색 id navigation id 및 히스토리 처리 동작 history handling을 사용한다. ignore cache가 true이면, 탐색은 HTTP 캐시에서 리소스를 로드해서는 안 된다.

    ignore cache 플래그가 어떻게 동작하는지 정확히 지정한다. 이는 리소스의 첫 번째 로드만 캐시를 우회하는지(즉, 처음에 캐시를 비우고 일반적으로 진행하는 것과 같은지), 또는 HTML 파서가 직접 로드하지 않은 리소스(예: 스크립트나 스타일시트에 의해 시작된 로드)도 캐시를 우회하는지 고려해야 한다.

  3. (event received, navigation status)를 «"navigation started", "navigation failed", "fragment navigated"» 및 navigation id가 주어졌을 때 대기한 결과로 둔다.

  4. 단언: navigation status의 id는 navigation id이다.

  5. navigation status의 status가 "complete"이면:

    1. body를 navigation 필드는 navigation id로 설정하고, url 필드는 navigation status의 url이 주어졌을 때 URL 직렬화기를 수행한 결과로 설정한 browsingContext.NavigateResult 생성규칙과 일치하는 맵으로 둔다.

    2. 데이터 body와 함께 성공을 반환한다.

    참고: 이는 탐색이 fragment 변경만 일으킨 경우이다.

  6. navigation status의 status가 "canceled"이면 오류를 반환하되 오류 코드는 unknown error로 한다.

    TODO: 여기서 오류를 처리하는 올바른 방식인가?

  7. 단언: navigation status의 status는 "pending"이고 navigation id는 null이 아니다.

  8. wait condition이 "committed"이면, event name을 "committed"로 둔다.

  9. 그렇지 않고, wait condition이 "interactive"이면, event name을 "domContentLoaded"로 둔다.

  10. 그렇지 않으면, event name을 "load"로 둔다.

  11. (event received, status)를 «event name, "download started", "navigation aborted", "navigation failed"» 및 navigation id가 주어졌을 때 대기한 결과로 둔다.

  12. event received가 "navigation failed"이면 오류를 반환하되 오류 코드는 unknown error로 한다.

    무엇이 왜 실패했는지에 대한 충분한 정보를 여기서 오류로 드러내고 있는가? 어떤 오류 코드를 원하는가? 로컬 끝이 실제로 무엇이 잘못되었는지 알아내기 위해 구현 정의 문자열을 파싱하는 문제가 생길 수 있는가?

  13. body를 navigation 필드는 status의 id로 설정하고, url 필드는 status의 url이 주어졌을 때 URL 직렬화기를 수행한 결과로 설정한 browsingContext.NavigateResult 생성규칙과 일치하는 맵으로 둔다.

  14. 데이터 body와 함께 성공을 반환한다.

7.3.2.3. browsingContext.Locator 타입

원격 끝 정의 및 로컬 끝 정의

browsingContext.Locator = (
   browsingContext.AccessibilityLocator /
   browsingContext.CssLocator /
   browsingContext.ContextLocator /
   browsingContext.InnerTextLocator /
   browsingContext.XPathLocator
)

browsingContext.AccessibilityLocator = {
   type: "accessibility",
   value: {
    ? name: text,
    ? role: text,
   }
}

browsingContext.CssLocator = {
   type: "css",
   value: text
}

browsingContext.ContextLocator = {
  type: "context",
  value: {
    context: browsingContext.BrowsingContext,
  }
}

browsingContext.InnerTextLocator = {
   type: "innerText",
   value: text,
   ? ignoreCase: bool
   ? matchType: "full" / "partial",
   ? maxDepth: js-uint,
}

browsingContext.XPathLocator = {
   type: "xpath",
   value: text
}

browsingContext.Locator 타입은 문서에서 노드를 찾기 위한 전략에 대한 세부사항을 제공한다.

7.3.2.4. browsingContext.Navigation 타입

원격 끝 정의 및 로컬 끝 정의

browsingContext.Navigation = text;

browsingContext.Navigation 타입은 진행 중인 탐색을 식별하는 고유한 문자열이다.

TODO: HTML 명세의 정의에 링크한다.

7.3.2.5. browsingContext.Download 타입

원격 엔드 정의 및 로컬 엔드 정의

browsingContext.Download = text;

browsingContext.Download 타입은 다운로드를 식별하는 고유 문자열이다.

7.3.2.6. browsingContext.NavigationInfo 타입

로컬 엔드 정의:

browsingContext.BaseNavigationInfo = (
  context: browsingContext.BrowsingContext,
  navigation: browsingContext.Navigation / null,
  timestamp: js-uint,
  url: text,
  ? userContext: browser.UserContext,
)

browsingContext.NavigationInfo = {
  browsingContext.BaseNavigationInfo
}

browsingContext.NavigationInfo 타입은 진행 중인 탐색의 세부사항을 제공한다.

navigable navigable 및 탐색 상태 navigation status가 주어졌을 때 탐색 정보 가져오기를 하려면:
  1. navigable id를 navigable에 대한 navigable id로 둔다.

  2. navigation id를 navigation status의 id로 둔다.

  3. timestamp를 현재 날짜와 시간을 UTC로 나타내는 시간 값으로 둔다.

  4. url을 navigation status의 url로 둔다.

  5. user context id를 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id로 둔다.

  6. context 필드는 navigable id로, navigation 필드는 navigation id로, timestamp 필드는 timestamp로, url 필드는 url이 주어졌을 때 URL 직렬화기를 수행한 결과로, 그리고 userContext 필드는 user context id로 설정한 browsingContext.NavigationInfo 생성규칙과 일치하는 맵을 반환한다.

7.3.2.7. browsingContext.ReadinessState 타입
browsingContext.ReadinessState = "none" / "interactive" / "complete"

browsingContext.ReadinessState 타입은 탐색 명령이 반환될 문서 로딩 단계를 나타낸다.

7.3.2.8. browsingContext.UserPromptType 타입

원격 엔드 정의 및 로컬 엔드 정의

browsingContext.UserPromptType = "alert" / "beforeunload" / "confirm" / "prompt";

browsingContext.UserPromptType 타입은 가능한 사용자 프롬프트 타입을 나타낸다.

7.3.3. 명령

7.3.3.1. browsingContext.activate 명령

browsingContext.activate 명령은 주어진 최상위 traversable을 활성화하고 포커스한다.

명령 타입
browsingContext.Activate = (
  method: "browsingContext.activate",
  params: browsingContext.ActivateParameters
)

browsingContext.ActivateParameters = {
  context: browsingContext.BrowsingContext
}
반환 타입
browsingContext.ActivateResult = EmptyResult

command parameters로 원격 끝 단계는 다음과 같다:

  1. navigable id를 command parameters["context"] 필드의 값으로 둔다.

  2. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

  3. navigable이 최상위 traversable이 아니면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  4. navigable로 navigable 활성화를 수행한 결과를 반환한다.

navigable이 주어졌을 때 navigable 활성화를 하려면:
  1. navigable의 시스템 가시성 상태가 visible이 되도록 구현별 단계를 실행한다. 이것이 가능하지 않으면, 오류 코드 unsupported operation인 오류를 반환한다.

    참고: 이는 현재 visible인 navigable을 hidden으로 만드는 부작용을 가질 수 있다.

    참고: 이는 창의 최소화 상태를 해제하거나 시스템 가시성 상태 변경과 관련된 다른 부작용을 일으켜 기본 OS 상태를 변경할 수 있다.

  2. 포커스되어 있지 않으면 navigable에 시스템 포커스를 설정하기 위해 구현별 단계를 실행한다.

    참고: 이는 다른 명세가 요구하는 경우를 제외하고 문서의 포커스된 영역을 변경하지 않는다.

  3. 데이터 null과 함께 성공을 반환한다.

7.3.3.2. browsingContext.captureScreenshot 명령

browsingContext.captureScreenshot 명령은 주어진 navigable의 이미지를 캡처하고, 이를 Base64로 인코딩된 문자열로 반환한다.

명령 타입
browsingContext.CaptureScreenshot = (
  method: "browsingContext.captureScreenshot",
  params: browsingContext.CaptureScreenshotParameters
)

browsingContext.CaptureScreenshotParameters = {
  context: browsingContext.BrowsingContext,
  ? origin: ("viewport" / "document") .default "viewport",
  ? format: browsingContext.ImageFormat,
  ? clip: browsingContext.ClipRectangle,
  ? imageSize: browsingContext.ImageSize,
}

browsingContext.ImageFormat = {
   type: text,
   ? quality: 0.0..1.0,
}

browsingContext.ImageSize = {
   ? maxWidth: (js-uint .ge 1),
   ? maxHeight: (js-uint .ge 1),
}

browsingContext.ClipRectangle = (
  browsingContext.BoxClipRectangle /
  browsingContext.ElementClipRectangle
)

browsingContext.ElementClipRectangle = {
  type: "element",
  element: script.SharedReference
}

browsingContext.BoxClipRectangle = {
   type: "box",
   x: float,
   y: float,
   width: float,
   height: float
}
반환 타입
browsingContext.CaptureScreenshotResult = {
  data: text
}
rect가 주어졌을 때 rect 정규화를 하려면:

참고: 이는 결과 rect가 양의 너비 치수 및 높이 치수를 가지도록 보장한다.

  1. x를 rect의 x 좌표로 둔다.

  2. y를 rect의 y 좌표로 둔다.

  3. width를 rect의 너비 치수로 둔다.

  4. height를 rect의 높이 치수로 둔다.

  5. width가 0보다 작으면, x를 x + width로 설정한 다음 width를 -width로 설정한다.

  6. height가 0보다 작으면, y를 y + height로 설정한 다음 height를 -height로 설정한다.

  7. x 좌표가 x, y 좌표가 y, 너비 치수가 width, 높이 치수가 height인 새 DOMRectReadOnly를 반환한다.

rect1 및 rect2가 주어졌을 때 직사각형 교차를 하려면
  1. rect1를 rect1로 rect 정규화를 수행한 결과로 둔다.

  2. rect2를 rect2로 rect 정규화를 수행한 결과로 둔다.

  3. x1_0를 rect1의 x 좌표로 둔다.

  4. x2_0를 rect2의 x 좌표로 둔다.

  5. x1_1를 rect1의 x 좌표에 rect1의 너비 치수를 더한 값으로 둔다.

  6. x2_1를 rect2의 x 좌표에 rect2의 너비 치수를 더한 값으로 둔다.

  7. x_0를 «x1_0, x2_0»의 최댓값으로 둔다.

  8. x_1를 «x1_1, x2_1»의 최솟값으로 둔다.

  9. y1_0를 rect1의 y 좌표로 둔다.

  10. y2_0를 rect2의 y 좌표로 둔다.

  11. y1_1를 rect1의 y 좌표에 rect1의 높이 치수를 더한 값으로 둔다.

  12. y2_1를 rect2의 y 좌표에 rect2의 높이 치수를 더한 값으로 둔다.

  13. y_0를 «y1_0, y2_0»의 최댓값으로 둔다.

  14. y_1를 «y1_1, y2_1»의 최솟값으로 둔다.

  15. x_1이 x_0보다 작으면, width를 0으로 둔다. 그렇지 않으면 width를 x_1 - x_0으로 둔다.

  16. y_1이 y_0보다 작으면, height를 0으로 둔다. 그렇지 않으면 height를 y_1 - y_0으로 둔다.

  17. x 좌표가 x_0, y 좌표가 y_0, 너비 치수가 width, 높이 치수가 height인 새 DOMRectReadOnly를 반환한다.

주어진 number를 반올림하려면:
  1. number가 유한하지 않거나 number가 정수 Number이면, number를 반환합니다.

  2. number < 0.5𝔽이고 number > +0𝔽이면, +0𝔽을 반환합니다.

  3. number < -0𝔽이고 n ≥ -0.5𝔽이면, -0𝔽을 반환합니다.

  4. number에 가장 가까운 정수 Number를 반환하며, 동률인 경우에는 +∞에 더 가까운 Number를 선택합니다.

주어진 document, rect 및 image size에 대해 문서를 캔버스에 렌더링하려면:
  1. ratio를 document의 기본 뷰가 주어졌을 때 기기 픽셀 비율 결정의 결과로 설정합니다.

  2. framebuffer width를 rect의 너비 치수에 ratio를 곱한 값으로 설정하여, 기기 픽셀 단위로 rect의 너비와 일치하게 합니다.

  3. framebuffer height를 rect의 높이 치수에 ratio를 곱한 값으로 설정하여, 기기 픽셀 단위로 rect의 높이와 일치하게 합니다.

  4. scale을 1로 설정합니다.

  5. image size가 null이 아니면:

    1. max width를 image size의 maxWidth 필드가 있으면 그 값으로, 그렇지 않으면 null로 설정합니다.

    2. max height를 image size의 maxHeight 필드가 있으면 그 값으로, 그렇지 않으면 null로 설정합니다.

    3. max width가 null이 아니고 max width를 framebuffer width로 나눈 값이 scale보다 작으면, scale을 max width를 framebuffer width로 나눈 값으로 설정합니다.

    4. max height가 null이 아니고 max height를 framebuffer height로 나눈 값이 scale보다 작으면, scale을 max height를 framebuffer height로 나눈 값으로 설정합니다.

  6. scale이 1보다 작으면:

    1. scale width를 framebuffer width에 scale을 곱한 값이 주어졌을 때 수를 반올림한 값으로 설정합니다.

    2. scale height를 framebuffer height에 scale을 곱한 값이 주어졌을 때 수를 반올림한 값으로 설정합니다.

    3. paint width를 1과 scale width 중 최댓값으로 설정합니다.

    4. paint height를 1과 scale height 중 최댓값으로 설정합니다.

  7. 그렇지 않으면:

    1. paint width를 framebuffer width로 설정합니다.

    2. paint height를 framebuffer height로 설정합니다.

  8. canvas를 HTMLCanvasElement 의 새 인스턴스로 두고, width를 paint width로, height를 paint height로 합니다.

  9. canvas context를 canvas와 null을 사용하여 2D 컨텍스트 생성 알고리즘을 실행한 결과로 설정합니다.

  10. canvas의 컨텍스트 모드를 2D로 설정합니다.

  11. source x를 rect의 x 좌표에 ratio를 곱한 값으로 설정하고, source y를 rect의 y 좌표에 ratio를 곱한 값으로 설정합니다.

  12. source rectangle을 네 꼭짓점이 (source x, source y), (source x + framebuffer width, source y), (source x + framebuffer width, source y + framebuffer height), 그리고 (source x, source y + framebuffer height)인 직사각형으로 설정합니다.

  13. destination rectangle을 네 꼭짓점이 (0, 0), (paint width, 0), (paint width, paint height), 그리고 (0, paint height)인 직사각형으로 설정합니다.

  14. source rectangle로 지정된 document의 프레임버퍼 영역을 destination rectangle로 지정된 canvas context의 출력 비트맵 영역에 그리는 것과 동등한 구현별 단계를 완료합니다.

    destination rectangle의 치수가 source rectangle보다 작으면, destination rectangle의 한 지점에 그려지는 값은 document의 프레임버퍼 데이터를 필터링하여 계산합니다. 사용자 에이전트는 임의의 필터링 알고리즘(예: 이중선형 보간 또는 최근접 이웃)을 사용할 수 있습니다. 필터링 알고리즘에 프레임버퍼 외부의 픽셀 값이 필요한 경우, 대신 가장 가까운 가장자리 픽셀의 값을 사용해야 합니다. (즉, 필터는 "가장자리로 고정" 동작을 사용합니다.) 필터링 알고리즘에 source rectangle 외부이지만 프레임버퍼 내부인 픽셀 값이 필요한 경우, 프레임버퍼의 값을 사용해야 합니다.

  15. canvas를 반환합니다.

주어진 canvas와 format을 사용하여 캔버스를 Base64로 인코딩하려면:
  1. format이 null이 아니면, type을 format의 type 필드로 설정하고, quality를 format의 quality 필드로 설정합니다.

  2. 그렇지 않으면, type을 "image/png"로 설정하고 quality를 undefined로 설정합니다.

  3. file을 canvas에 대해 type과 quality를 사용한 비트맵의 파일 직렬화로 설정합니다.

  4. encoded string을 file의 관대한 Base64 인코딩으로 설정합니다.

  5. 데이터 encoded string과 함께 성공을 반환합니다.

주어진 document와 origin을 사용하여 원점 사각형을 가져오려면:
  1. origin이 "viewport"이면:

    1. viewport를 document의 시각적 뷰포트로 설정합니다.

    2. viewport rect를 DOMRectReadOnly로 설정하며, x 좌표는 viewport의 페이지 왼쪽, y 좌표는 viewport의 페이지 위쪽, 너비 치수는 viewport 너비, 높이 치수는 viewport 높이로 설정합니다.

    3. 데이터 viewport rect와 함께 성공을 반환합니다.

  2. 단언: origin은 "document"입니다.

  3. document element를 document의 문서 요소로 설정합니다.

  4. document rect를 DOMRectReadOnly로 설정하며, x 좌표는 0, y 좌표는 0, 너비 치수는 document element의 스크롤 높이, 그리고 높이 치수는 document element의 스크롤 너비로 설정합니다.

  5. 데이터 document rect와 함께 성공을 반환합니다.

session 및 command parameters를 사용하는 원격 끝 단계는 다음과 같습니다:

  1. navigable id를 command parameters의 context 필드 값이 있으면 해당 값으로 설정하고, 그렇지 않으면 null로 설정합니다.

  2. navigable을 navigable id를 사용하여 탐색 가능 항목을 가져오는 것을 시도한 결과로 설정합니다.

  3. 구현이 어떠한 이유로든 navigable의 스크린샷을 캡처할 수 없는 경우에는 오류 코드가 오류 코드 지원되지 않는 작업인 오류를 반환합니다.

  4. document를 navigable의 활성 문서로 설정합니다.

  5. document에 대한 애니메이션 프레임 콜백 실행 알고리즘의 다음 호출 직후:

    이는 더 명시적인 방식으로 업데이트 렌더링 알고리즘에 통합되어야 합니다. [w3c/webdriver-bidi 이슈 #1131]

  6. origin을 command parameters의 context 필드 값이 있으면 해당 값으로 설정하고, 그렇지 않으면 "viewport"로 설정합니다.

  7. origin rect를 origin과 document를 사용하여 원점 사각형을 가져오는 것을 시도한 결과로 설정합니다.

  8. clip rect를 origin rect로 설정합니다.

  9. command parameters에 "clip"이 포함되어 있으면:

    1. clip을 command parameters["clip"]으로 설정합니다.

    2. 처음 일치하는 조건에 해당하는 단계를 실행합니다:

      clip이 browsingContext.ElementClipRectangle 프로덕션과 일치하는 경우:
      1. environment settings를 환경 설정 객체로 설정합니다. 이 객체의 관련 전역 객체의 연결된 Document는 document입니다.

      2. realm을 environment settings의 realm 실행 컨텍스트의 Realm 구성 요소로 설정합니다.

      3. element를 clip["element"], realm, 및 session을 사용하여 원격 참조를 역직렬화하는 것을 시도한 결과로 설정합니다.

      4. element가 Element를 구현하지 않으면 오류 코드가 해당 요소 없음인 오류를 반환합니다.

      5. element의 노드 문서가 document가 아니면, 오류 코드가 해당 요소 없음인 오류를 반환합니다.

      6. viewport rect를 "viewport"와 document를 사용하여 원점 사각형을 가져온 값으로 설정합니다.

      7. element rect를 element에 대해 경계 상자를 가져온 값으로 설정합니다.

      8. clip rect를 DOMRectReadOnly로 설정하며, x 좌표는 element rect["x"] + viewport rect["x"], y 좌표는 element rect["y"] + viewport rect["y"], 너비는 element rect["width"], 높이는 element rect["height"]로 설정합니다.

      clip이 browsingContext.BoxClipRectangle 프로덕션과 일치하는 경우:
      1. clip x를 clip["x"]에 origin rect의 x 좌표를 더한 값으로 설정합니다.

      2. clip y를 clip["y"]에 origin rect의 y 좌표를 더한 값으로 설정합니다.

      3. clip rect를 DOMRectReadOnly로 설정하며, x 좌표는 clip x, y 좌표는 clip y, 너비는 clip["width"], 높이는 clip["height"]로 설정합니다.

  10. 참고: 이제 모든 좌표는 문서의 원점을 기준으로 측정됩니다.

  11. rect를 origin rect와 clip rect의 사각형 교차 영역으로 설정합니다.

  12. rect의 너비 치수가 0이거나 rect의 높이 치수가 0이면, 오류 코드가 화면 캡처 불가인 오류를 반환합니다.

  13. image size를 command parameters의 imageSize 필드 값이 있으면 해당 값으로 설정하고, 그렇지 않으면 null로 설정합니다.

  14. canvas를 document, rect 및 image size를 사용하여 문서를 캔버스에 렌더링한 값으로 설정합니다.

  15. format을 command parameters의 format 필드로 설정합니다.

  16. encoding result를 canvas와 format을 사용하여 캔버스를 Base64로 인코딩하는 것을 시도한 결과로 설정합니다.

  17. body를 browsingContext.CaptureScreenshotResult 프로덕션과 일치하고 data 필드가 encoding result로 설정된 맵으로 설정합니다.

  18. 데이터 body와 함께 성공을 반환합니다.

7.3.3.3. browsingContext.close 명령

browsingContext.close 명령은 최상위 traversable을 닫는다.

명령 타입
browsingContext.Close = (
  method: "browsingContext.close",
  params: browsingContext.CloseParameters
)

browsingContext.CloseParameters = {
  context: browsingContext.BrowsingContext,
  ? promptUnload: bool .default false
}
반환 타입
browsingContext.CloseResult = EmptyResult
command parameters로 원격 끝 단계는 다음과 같다:
  1. navigable id를 command parameters의 context 필드 값으로 둔다.

  2. prompt unload를 command parameters의 promptUnload 필드 값으로 둔다.

  3. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

  4. 단언: navigable은 null이 아니다.

  5. navigable이 최상위 traversable이 아니면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  6. prompt unload가 true이면:

    1. navigable을 닫는다.

  7. 그렇지 않으면:

    1. 언로드 프롬프트 없이 navigable을 닫는다.

  8. 데이터 null과 함께 성공을 반환한다.

마지막 최상위 traversable을 닫을 때의 동작에 대한 공개 논의가 있다. 브라우저를 닫거나, 세션을 닫거나, 이를 구현에 맡기는 것을 예상할 수 있다. [w3c/webdriver-bidi Issue #170]

7.3.3.4. browsingContext.create 명령

browsingContext.create 명령은 새 탭 또는 새 창에 새 navigable을 만들고, 그 navigable id를 반환한다.

명령 타입
browsingContext.Create = (
  method: "browsingContext.create",
  params: browsingContext.CreateParameters
)

browsingContext.CreateType = "tab" / "window"

browsingContext.CreateParameters = {
  type: browsingContext.CreateType,
  ? referenceContext: browsingContext.BrowsingContext,
  ? background: bool .default false,
  ? userContext: browser.UserContext
}
반환 타입
browsingContext.CreateResult = {
  context: browsingContext.BrowsingContext,
  ? userContext: browser.UserContext
}
command parameters로 원격 끝 단계는 다음과 같다:
  1. type을 command parameters의 type 필드 값으로 둔다.

  2. reference navigable id를 command parameters의 referenceContext 필드 값으로 둔다. 존재하지 않으면 null로 둔다.

  3. reference navigable id가 null이 아니면, reference navigable을 reference navigable id로 시도하여 navigable 가져오기를 수행한 결과로 둔다. 그렇지 않으면 reference navigable을 null로 둔다.

  4. reference navigable이 null이 아니고 최상위 traversable이 아니면, 오류를 오류 코드 invalid argument와 함께 반환한다.

  5. 구현이 어떤 이유로든 새 최상위 traversable을 만들 수 없으면, 오류를 오류 코드 unsupported operation과 함께 반환한다.

  6. reference navigable이 null이면 user context를 기본 사용자 컨텍스트로 두고, 그렇지 않으면 reference navigable의 연관된 사용자 컨텍스트로 둔다.

  7. user context id를 command parameters의 userContext 필드 값으로 둔다. 존재하지 않으면 null로 둔다.

  8. user context id가 null이 아니면, user context를 user context id로 시도하여 사용자 컨텍스트 가져오기를 수행한 결과로 설정한다.

  9. user context가 null이면, 오류를 오류 코드 해당 사용자 컨텍스트 없음과 함께 반환한다.

  10. 구현이 어떤 이유로든 최상위 traversable을 연관된 사용자 컨텍스트 user context와 함께 만들 수 없으면, 오류를 오류 코드 unsupported operation과 함께 반환한다.

  11. traversable을 null, 빈 문자열, null 및 false를 사용하여 새 최상위 순회 가능 항목을 생성하는 단계를 시도한 결과로 하고, 새로 생성된 연결된 사용자 컨텍스트를 최상위 순회 가능 항목의 user context로 설정합니다. 새 최상위 순회 가능 항목이 생성되는 OS 창은 type 및 reference navigable에 따라 달라집니다:

  12. command parameters의 background 필드 값이 false이면:

    1. activate result를 새로 만들어진 navigable로 navigable 활성화를 수행한 결과로 둔다.

    2. activate result가 오류이면, activate result를 반환한다.

    참고: background가 true이면 만들어진 navigable에 대해 포커싱 단계를 호출하지 않는다.

  13. body를 browsingContext.CreateResult 생성식과 일치하는 맵으로 두고, context 필드는 traversable의 navigable ID로, userContext 속성은 traversable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 ID로 설정한다.

  14. body 데이터를 가진 성공을 반환한다.

7.3.3.5. browsingContext.getTree 명령

browsingContext.getTree 명령은 주어진 부모 자체를 포함한 모든 자손 navigable의 트리, 또는 부모가 제공되지 않은 경우 모든 최상위 context를 반환한다.

명령 타입
browsingContext.GetTree = (
  method: "browsingContext.getTree",
  params: browsingContext.GetTreeParameters
)

browsingContext.GetTreeParameters = {
  ? maxDepth: js-uint,
  ? root: browsingContext.BrowsingContext,
}
반환 타입
browsingContext.GetTreeResult = {
  contexts: browsingContext.InfoList
}
session 및 command parameters로 원격 끝 단계는 다음과 같다:
  1. root id를 command parameters의 root 필드 값으로 두되, 있으면 그 값으로, 그렇지 않으면 null로 둔다.

  2. max depth를 command parameters의 maxDepth 필드 값으로 두되, 있으면 그 값으로, 그렇지 않으면 null로 둔다.

  3. navigables를 빈 목록으로 둔다.

  4. root id가 null이 아니면, root id가 주어졌을 때 navigable 가져오기를 시도한 결과를 navigables에 추가한다. 그렇지 않으면 모든 최상위 traversable을 navigables에 추가한다.

  5. navigables infos를 빈 목록으로 둔다.

  6. navigables의 각 navigable에 대해:

    1. info를 navigable, max depth, true가 주어졌을 때 navigable 정보 가져오기를 수행한 결과로 둔다.

    2. info를 navigables infos에 추가한다

  7. body를 contexts 필드가 navigables infos로 설정된 browsingContext.GetTreeResult 생성규칙과 일치하는 맵으로 둔다.

  8. 데이터 body와 함께 성공을 반환한다.

7.3.3.6. browsingContext.handleUserPrompt 명령

browsingContext.handleUserPrompt 명령은 열린 프롬프트를 닫을 수 있게 한다

명령 타입
browsingContext.HandleUserPrompt = (
  method: "browsingContext.handleUserPrompt",
  params: browsingContext.HandleUserPromptParameters
)

browsingContext.HandleUserPromptParameters = {
  context: browsingContext.BrowsingContext,
  ? accept: bool,
  ? userText: text,
}
반환 타입
browsingContext.HandleUserPromptResult = EmptyResult

session 및 command parameters로 원격 끝 단계는 다음과 같다:

  1. navigable id를 command parameters의 context 필드 값으로 둔다.

  2. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

  3. accept를 command parameters의 accept 필드 값으로 두되, 있으면 그 값으로, 그렇지 않으면 true로 둔다.

  4. userText를 command parameters의 userText 필드 값으로 두되, 있으면 그 값으로, 그렇지 않으면 빈 문자열로 둔다.

  5. navigable이 현재 alert 호출에서 온 단순 대화상자를 표시 중이면 프롬프트를 확인한다.

    그렇지 않고 navigable이 현재 confirm 호출에서 온 단순 대화상자를 표시 중이면, accept가 true일 때 긍정적으로 응답하고, accept가 false일 때 부정적으로 응답한다.

    그렇지 않고 navigable이 현재 prompt 호출에서 온 단순 대화상자를 표시 중이면, accept가 true일 때 문자열 값 userText로 응답하고, accept가 false일 때 중단한다.

    그렇지 않고, navigable이 현재 언로드 프롬프트 단계의 일부로 프롬프트를 표시 중이면, accept가 true일 때 탐색을 확인하고, 그렇지 않으면 탐색을 거부한다.

    그렇지 않으면 오류를 반환하되 오류 코드는 no such alert로 한다.

  6. 데이터 null과 함께 성공을 반환한다.

7.3.3.7. browsingContext.locateNodes 명령

browsingContext.locateNodes 명령은 지정된 locator와 일치하는 모든 노드의 목록을 반환한다.

명령 타입
browsingContext.LocateNodes = (
  method: "browsingContext.locateNodes",
  params: browsingContext.LocateNodesParameters
)

browsingContext.LocateNodesParameters = {
   context: browsingContext.BrowsingContext,
   locator: browsingContext.Locator,
   ? maxNodeCount: (js-uint .ge 1),
   ? serializationOptions: script.SerializationOptions,
   ? startNodes: [ + script.SharedReference ]
}
반환 타입
browsingContext.LocateNodesResult = {
    nodes: [ * script.NodeRemoteValue ]
}
주어진 navigable, context nodes, selector, maximum returned node count, session로 CSS를 사용하여 노드 찾기를 하려면:
  1. returned nodes를 빈 목록으로 둔다.

  2. parse result를 selector가 주어졌을 때 selector 파싱을 수행한 결과로 둔다.

  3. parse result가 실패이면, 오류를 반환하되 오류 코드는 invalid selector로 한다.

  4. context nodes의 각 context node에 대해:

    1. elements를 parse result 및 navigable의 활성 문서의 루트로 scoping root context node를 사용하여 selector를 트리와 대조한 결과로 둔다.

    2. elements의 각 element에 대해:

      1. element를 returned nodes에 추가한다.

      2. maximum returned node count가 null이 아니고 returned nodes의 크기가 maximum returned node count와 같으면, 데이터 returned nodes와 함께 성공을 반환한다.

  5. 데이터 returned nodes와 함께 성공을 반환한다.

navigable이 주어졌을 때 컨테이너 요소 찾기를 하려면:
  1. returned nodes를 빈 목록으로 둔다.

  2. navigable의 컨테이너가 null이 아니면, navigable의 컨테이너를 returned nodes에 추가한다.

  3. returned nodes를 반환한다.

주어진 navigable, context nodes, selector, maximum returned node count로 XPath를 사용하여 노드 찾기를 하려면:

참고: XPath 명세가 유지보수되지 않는 상태이므로 이 알고리즘은 XPath DOM API를 호출하는 것처럼 표현되어 있다. 그러나 이는 ECMAScript 런타임을 거치지 않고 기반 알고리즘에 직접 접근하는 명세 내부 호출과 동등한 것으로 이해해야 한다.

  1. returned nodes를 빈 목록으로 둔다.

  2. context nodes의 각 context node에 대해:

    1. evaluate result를 navigable의 활성 문서에서, 인수 selector, context node, null, ORDERED_NODE_SNAPSHOT_TYPE, null로 evaluate를 호출한 결과로 둔다. 이것이 "SyntaxError" DOMException을 던지면, 오류를 반환하되 오류 코드는 invalid selector로 한다; 그렇지 않고, 이것이 다른 예외를 던지면 오류를 반환하되 오류 코드는 unknown error로 한다.

    2. index를 0으로 둔다.

    3. length를 evaluate result에서 snapshotLength 속성을 가져온 결과로 둔다.

    4. index가 length보다 작은 동안 반복한다:

      1. node를 evaluate result를 this로, index를 인수로 하여 snapshotItem을 호출한 결과로 둔다.

      2. node를 returned nodes에 추가한다.

      3. maximum returned node count가 null이 아니고 returned nodes의 크기가 maximum returned node count와 같으면, 데이터 returned nodes와 함께 성공을 반환한다.

      4. index를 index + 1로 설정한다.

  3. 데이터 returned nodes와 함께 성공을 반환한다.

주어진 context nodes, selector, max depth, match type, ignore case, maximum returned node count로 inner text를 사용하여 노드 찾기를 하려면:
  1. selector가 빈 문자열이면, 오류를 반환하되 오류 코드는 invalid selector로 한다.

  2. returned nodes를 빈 목록으로 둔다.

  3. ignore case가 false이면, search text를 selector로 둔다. 그렇지 않으면, search text를 selector에 대해 Unicode Default Case Conversion 알고리즘에 따라 toUppercase를 수행한 결과로 둔다.

  4. context nodes의 각 context node에 대해:

    1. context node가 Document 또는 DocumentFragment를 구현하면:

      참고: 문서 또는 문서 fragment를 순회할 때, document와 document.documentElement로 검색한 결과가 같아지도록 max depth는 의도적으로 감소시키지 않는다.

      1. child nodes를 빈 목록으로 둔다.

      2. context node의 자식에 있는 각 노드 child에 대해.

        1. child를 child nodes에 추가한다.

      3. returned nodes를 child nodes, selector, max depth, match type, ignore case, maximum returned node count로 inner text를 사용하여 노드 찾기를 시도한 결과로 확장한다.

    2. context node가 HTMLElement를 구현하지 않으면 계속한다.

    3. node inner text를 context node를 this 값으로 하여 innerText getter 단계를 호출한 결과로 둔다.

    4. ignore case가 false이면, node text를 node inner text로 둔다. 그렇지 않으면, node text를 node inner text에 대해 Unicode Default Case Conversion 알고리즘에 따라 toUppercase를 수행한 결과로 둔다.

    5. search text가 node text의 코드 포인트 부분 문자열이면, 다음 단계를 수행한다:

      1. child nodes를 빈 목록으로 두고, context node의 자식에 있는 각 노드 child에 대해:

        1. child를 child nodes에 추가한다.

      2. child nodes의 크기가 0과 같거나 max depth가 0과 같으면, 다음 단계를 수행한다:

        1. match type이 "full"이고 node text가 search text와 같으면, context node를 returned nodes에 추가한다.

        2. 그렇지 않고, match type이 "partial"이면, context node를 returned nodes에 추가한다.

      3. 그렇지 않으면, 다음 단계를 수행한다:

        1. max depth가 null이면 child max depth를 null로, 그렇지 않으면 max depth - 1로 둔다.

        2. child node matches를 child nodes, selector, child max depth , match type, ignore case, maximum returned node count로 inner text를 사용하여 노드 찾기를 수행한 결과로 둔다.

        3. child node matches의 크기가 0과 같고 match type이 "partial"이면 context node를 returned nodes에 추가한다. 그렇지 않으면, returned nodes를 child node matches로 확장한다.

  5. maximum returned node count가 null이 아니면, returned nodes에서 인덱스가 maximum returned node count 이상인 모든 항목을 제거한다.

  6. 데이터 returned nodes와 함께 성공을 반환한다.

주어진 context nodes, selector, maximum returned node count, returned nodes로 접근성 속성을 사용하여 노드 수집을 하려면:
  1. returned nodes가 null이면:

    1. returned nodes를 빈 목록으로 설정한다.

  2. context nodes의 각 context node에 대해:

    1. match를 true로 둔다.

    2. context node가 Element를 구현하면:

      1. selector가 "role"를 포함하면:

        1. role을 context node의 계산된 역할로 둔다.

        2. selector["role"]가 role과 같지 않으면:

          1. match를 false로 설정한다.

      2. selector가 "name"을 포함하면:

        1. name을 context node의 접근 가능한 이름으로 둔다.

        2. selector["name"]이 name과 같지 않으면:

          1. match를 false로 설정한다.

    3. 그렇지 않으면, match를 false로 설정한다.

    4. match가 true이면:

      1. maximum returned node count가 null이 아니고 returned nodes의 크기가 maximum returned node count와 같으면, 중단한다.

      2. context node를 returned nodes에 추가한다.

    5. child nodes를 빈 목록으로 두고, context node의 자식에 있는 각 노드 child에 대해:

      1. child가 Element를 구현하면, child를 child nodes에 추가한다.

    6. child nodes, selector, maximum returned node count, returned nodes로 접근성 속성을 사용하여 노드 수집을 시도한다.

  3. returned nodes를 반환한다.

주어진 context nodes, selector, maximum returned node count로 접근성 속성을 사용하여 노드 찾기를 하려면:
  1. selector가 "role"을 포함하지 않고 selector가 "name"을 포함하지 않으면, 오류를 반환하되 오류 코드는 invalid selector로 한다.

  2. context nodes, selector, maximum returned node count, null로 접근성 속성을 사용하여 노드 수집을 수행한 결과를 반환한다.

session 및 command parameters로 원격 끝 단계는 다음과 같다:
  1. navigable id를 command parameters["context"]로 둔다.

  2. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

  3. 단언: navigable은 null이 아니다.

  4. realm을 navigable의 navigable id와 null로 navigable에서 realm 가져오기를 시도한 결과로 둔다.

  5. locator를 command parameters["locator"]로 둔다.

  6. command parameters가 "startNodes"를 포함하면, start nodes parameter를 command parameters["startNodes"]로 둔다. 그렇지 않으면 start nodes parameter를 null로 둔다.

  7. command parameters가 "maxNodeCount"를 포함하면, maximum returned node count를 command parameters["maxNodeCount"]로 둔다. 그렇지 않으면 maximum returned node count를 null로 둔다.

  8. context nodes를 빈 목록으로 둔다.

  9. start nodes parameter가 null이면, navigable의 활성 문서를 context nodes에 추가한다. 그렇지 않으면, start nodes parameter의 각 serialized start node에 대해:

    1. start node를 serialized start node, realm, session가 주어졌을 때 공유 참조 역직렬화를 시도한 결과로 둔다.

    2. start node를 context nodes에 추가한다.

  10. context nodes의 크기가 0보다 크다고 단언한다.

  11. type을 locator["type"]로 둔다.

  12. 다음 조건 및 관련 단계 목록에서, 관련 조건이 true인 첫 번째 단계 집합을 실행한다:

    type이 문자열 "css"인 경우
    1. selector를 locator["value"]로 둔다.

    2. result nodes를 navigable, context nodes, selector, maximum returned nodes가 주어졌을 때 css를 사용하여 노드 찾기를 시도한 결과로 둔다.

    type이 문자열 "xpath"인 경우
    1. selector를 locator["value"]로 둔다.

    2. result nodes를 navigable, context nodes, selector, maximum returned nodes가 주어졌을 때 xpath를 사용하여 노드 찾기를 시도한 결과로 둔다.

    type이 문자열 "innerText"인 경우
    1. selector를 locator["value"]로 둔다.

    2. locator가 maxDepth를 포함하면, max depth를 locator["maxDepth"]로 둔다. 그렇지 않으면 max depth를 null로 둔다.

    3. locator가 ignoreCase를 포함하면, ignore case를 locator["ignoreCase"]로 둔다. 그렇지 않으면 ignore case를 false로 둔다.

    4. locator가 matchType을 포함하면, match type를 locator["matchType"]로 둔다. 그렇지 않으면 match type를 "full"로 둔다.

    5. result nodes를 context nodes, selector, max depth, match type, ignore case, maximum returned node count가 주어졌을 때 inner text를 사용하여 노드 찾기를 시도한 결과로 둔다.

    type이 문자열 "accessibility"인 경우
    1. selector를 locator["value"]로 둔다.

    2. result nodes를 context nodes, selector, maximum returned node count가 주어졌을 때 접근성 속성을 사용하여 노드 찾기를 수행한 결과로 둔다.

    type이 문자열 "context"인 경우
    1. start nodes parameter가 null이 아니면, 오류를 반환하되 오류 코드는 "invalid argument"로 한다.

    2. selector를 locator["value"]로 둔다.

    3. context id를 selector["context"]로 둔다.

    4. child navigable을 context id로 navigable 가져오기를 시도한 결과로 둔다.

    5. child navigable의 부모가 navigable이 아니면, 오류를 반환하되 오류 코드는 "invalid argument"로 한다.

    6. result nodes를 child navigable이 주어졌을 때 컨테이너 요소 찾기를 수행한 결과로 둔다.

    7. 단언: result nodes의 각 node에 대해, node의 노드 navigable은 navigable이다.

  13. 단언: maximum returned node count는 null이거나 result nodes의 크기가 maximum returned node count 이하이다.

  14. command parameters가 "serializationOptions"를 포함하면, serialization options를 command parameters["serializationOptions"]로 둔다. 그렇지 않으면, serialization options를 필드가 기본값으로 설정된 script.SerializationOptions 생성규칙과 일치하는 맵으로 둔다.

  15. result ownership을 "none"으로 둔다.

  16. serialized nodes를 빈 목록으로 둔다.

  17. result nodes의 각 result node에 대해:

    1. serialized node를 result node, serialization options, result ownership, 직렬화 내부 맵으로서 새 맵, realm, session로 remote value로 직렬화를 수행한 결과로 둔다.

    2. serialized node를 serialized nodes에 추가한다.

  18. result를 nodes 필드가 serialized nodes로 설정된 browsingContext.LocateNodesResult 생성규칙과 일치하는 맵으로 둔다.

  19. 데이터 result와 함께 성공을 반환한다.

7.3.3.8. browsingContext.navigate 명령

browsingContext.navigate 명령은 navigable을 주어진 URL로 탐색한다.

명령 타입
browsingContext.Navigate = (
  method: "browsingContext.navigate",
  params: browsingContext.NavigateParameters
)

browsingContext.NavigateParameters = {
  context: browsingContext.BrowsingContext,
  url: text,
  ? wait: browsingContext.ReadinessState,
}
반환 타입
browsingContext.NavigateResult = {
  navigation: browsingContext.Navigation / null,
  url: text,
}
session 및 command parameters로 원격 끝 단계는 다음과 같다:
  1. navigable id를 command parameters의 context 필드 값으로 둔다.

  2. navigable을 navigable id로 navigable 가져오기를 시도한 결과로 둔다.

  3. 단언: navigable은 null이 아니다.

  4. wait condition을 "committed"로 둔다.

  5. command parameters가 wait를 포함하고 command parameters[wait]가 "none"이 아니면, wait condition을 command parameters[wait]로 설정한다.

  6. url을 command parameters의 url 필드 값으로 둔다.

  7. document를 navigable의 활성 문서로 둔다.

  8. base를 document의 base URL로 둔다.

  9. url record를 url에 base URL base로 URL 파서를 적용한 결과로 둔다.

  10. url record가 실패이면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  11. request를 URL이 url record인 새 요청으로 둔다.

  12. navigable, request, wait condition으로 탐색 대기를 수행한 결과를 반환한다.

7.3.3.9. browsingContext.print 명령

browsingContext.print 명령은 문서의 페이지화된 표현을 만들고, 이를 Base64로 인코딩된 문자열로 표현된 PDF 문서로 반환한다.

명령 타입
browsingContext.Print = (
  method: "browsingContext.print",
  params: browsingContext.PrintParameters
)

browsingContext.PrintParameters = {
  context: browsingContext.BrowsingContext,
  ? background: bool .default false,
  ? margin: browsingContext.PrintMarginParameters,
  ? orientation: ("portrait" / "landscape") .default "portrait",
  ? page: browsingContext.PrintPageParameters,
  ? pageRanges: [*(js-uint / text)],
  ? scale: (0.1..2.0) .default 1.0,
  ? shrinkToFit: bool .default true,
}

browsingContext.PrintMarginParameters = {
  ? bottom: (float .ge 0.0) .default 1.0,
  ? left: (float .ge 0.0) .default 1.0,
  ? right: (float .ge 0.0) .default 1.0,
  ? top: (float .ge 0.0) .default 1.0,
}

; Minimum size is 1pt x 1pt. Conversion follows from
; https://www.w3.org/TR/css3-values/#absolute-lengths
browsingContext.PrintPageParameters = {
  ? height: (float .ge 0.0352) .default 27.94,
  ? width: (float .ge 0.0352) .default 21.59,
}
반환 타입
browsingContext.PrintResult = {
  data: text
}

session 및 command parameters가 주어진 원격 엔드 단계는 다음과 같다:

  1. navigable id를 command parameters의 context 필드 값으로 둔다.

  2. navigable을 navigable id로 시도하여 navigable 가져오기를 수행한 결과로 둔다.

  3. 구현이 어떤 이유로든 navigable의 페이지가 매겨진 표현을 제공할 수 없으면, 오류를 오류 코드 unsupported operation과 함께 반환한다.

  4. margin을 command parameters의 margin 필드 값으로 둔다. 존재하지 않으면 필드가 기본값으로 설정된 browsingContext.PrintMarginParameters와 일치하는 맵으로 둔다.

  5. page size를 command parameters의 page 필드 값으로 둔다. 존재하지 않으면 필드가 기본값으로 설정된 browsingContext.PrintPageParameters와 일치하는 맵으로 둔다.

참고: 최소 페이지 크기는 1포인트이며, 이는 절대 길이에 따르면 (2.54 / 72) cm이다.

  1. page ranges를 command parameters의 pageRanges 필드 값으로 둔다. 존재하지 않으면 빈 리스트로 둔다.

  2. document를 navigable의 활성 문서로 둔다.

  3. document에 대한 애니메이션 프레임 콜백 실행 알고리즘의 다음 호출 직후:

    이는 렌더링 업데이트 알고리즘에 좀 더 명시적인 방식으로 통합되어야 한다. [w3c/webdriver-bidi 이슈 #1131]

    1. pdf data를 UA별 단계를 수행하여 document의 페이지가 매겨진 표현을 생성한 결과로 둔다. 이때 CSS 미디어 타입을 print로 설정하고, PDF로 인코딩하며, 다음 용지 설정을 사용한다:

      속성 값
      cm 단위 너비 command parameters["orientation"]이 "portrait"이면 page size["width"], 그렇지 않으면 page size["height"]
      cm 단위 높이 command parameters["orientation"]이 "portrait"이면 page size["height"], 그렇지 않으면 page size["width"]
      cm 단위 위쪽 여백 margin["top"]
      cm 단위 아래쪽 여백 margin["bottom"]
      cm 단위 왼쪽 여백 margin["left"]
      cm 단위 오른쪽 여백 margin["right"]

      또한 UA는 다음 서식 지정 힌트를 적용해야 한다:

      command parameters["scale"]이 1과 같지 않으면:
      콘텐츠 크기를 command parameters["scale"] 배율만큼 확대/축소한다
      command parameters["background"]가 false이면:
      배경 이미지 출력을 억제한다
      command parameters["shrinkToFit"]가 true이면:
      콘텐츠에 지정된 모든 페이지 너비를 재정의하여, 콘텐츠 크기를 페이지 너비에 맞게 조정한다
    2. page ranges가 비어 있지 않으면, pages를 page ranges와 pdf data에 포함된 페이지 수로 시도하여 페이지 범위 파싱을 수행한 결과로 두고, 그런 다음 1부터 시작하는 인덱스가 pages에 포함되지 않는 모든 페이지를 pdf data에서 제거한다.

    3. encoding result를 pdf data에 대해 Base64 인코딩을 호출한 결과로 둔다.

    4. encoded data를 encoding result의 데이터로 둔다.

    5. body를 browsingContext.PrintResult 생성식과 일치하는 맵으로 두고, data 필드를 encoded data로 설정한다.

    6. body 데이터를 가진 성공을 반환한다.

7.3.3.10. browsingContext.reload 명령

browsingContext.reload 명령은 navigable을 다시 로드한다.

명령 타입
browsingContext.Reload = (
  method: "browsingContext.reload",
  params: browsingContext.ReloadParameters
)

browsingContext.ReloadParameters = {
  context: browsingContext.BrowsingContext,
  ? ignoreCache: bool,
  ? wait: browsingContext.ReadinessState,
}
반환 타입
browsingContext.ReloadResult = browsingContext.NavigateResult
command parameters로 원격 끝 단계는 다음과 같다:
  1. navigable id를 command parameters의 context 필드 값으로 둔다.

  2. navigable을 navigable id로 시도하여 navigable 가져오기를 수행한 결과로 둔다.

  3. 단언: navigable은 null이 아니다.

  4. ignore cache를 command parameters의 ignoreCache 필드 값이 있으면 그 값으로, 그렇지 않으면 false로 둔다.

  5. wait condition을 "committed"로 둔다.

  6. command parameters가 포함하는 wait가 있고 command parameters[wait]가 "none"이 아니면, wait condition을 command parameters[wait]로 설정한다.

  7. document를 navigable의 활성 문서로 둔다.

  8. url을 document의 URL로 둔다.

  9. request를 URL이 url인 새 요청으로 둔다.

  10. navigable, request, wait condition, history handling "reload", 그리고 ignore cache ignore cache로 탐색 대기를 수행한 결과를 반환한다.

7.3.3.11. browsingContext.setBypassCSP 명령

browsingContext.setBypassCSP 명령은 Content Security Policy 적용을 우회할 수 있게 한다.

참고: CSP 우회가 활성화되면, eval(), new Function(), 인라인 스크립트 및 리소스 로딩을 일반적으로 차단하는 지시자를 포함하여 모든 CSP 지시자가 우회된다.

명령 타입
browsingContext.SetBypassCSP = (
  method: "browsingContext.setBypassCSP",
  params: browsingContext.SetBypassCSPParameters
)

browsingContext.SetBypassCSPParameters = {
  bypass: true / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 타입
browsingContext.SetBypassCSPResult = EmptyResult

원격 끝은 CSP 우회 구성을 가지며, 이는 WebDriver 구성으로서 연관 타입 boolean을 가진다.

navigable navigable이 주어졌을 때 WebDriver BiDi CSP가 우회되는지 단계는 다음과 같다:

  1. top-level traversable을 navigable의 최상위 traversable로 둔다.

  2. bypass CSP enabled를 top-level traversable에 대한 CSP 우회 구성의 WebDriver 구성 값 가져오기 결과로 둔다.

  3. 단언: bypass CSP enabled는 true 또는 unset이다.

  4. bypass CSP enabled가 unset이면 false를 반환한다.

  5. true를 반환한다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같다:

  1. bypass를 command parameters["bypass"]로 둔다.

  2. bypass가 null이면, bypass를 unset으로 설정한다.

  3. command parameters에 대해 CSP 우회 구성 bypass인 WebDriver 구성 저장을 시도한다.

  4. 데이터 null과 함께 성공을 반환한다.

7.3.3.12. browsingContext.setViewport 명령

browsingContext.setViewport 명령은 주어진 최상위 traversable의 특정 뷰포트 특성(예: viewport width 및 viewport height)을 수정한다.

명령 타입
browsingContext.SetViewport = (
  method: "browsingContext.setViewport",
  params: browsingContext.SetViewportParameters
)

browsingContext.SetViewportParameters = {
  ? context: browsingContext.BrowsingContext,
  ? viewport: browsingContext.Viewport / null,
  ? devicePixelRatio: (float .gt 0.0) / null,
  ? userContexts: [+browser.UserContext],
}

browsingContext.Viewport = {
  width: js-uint,
  height: js-uint,
}
반환 타입
browsingContext.SetViewportResult = EmptyResult
navigable 및 device pixel ratio가 주어졌을 때 device pixel ratio 재정의 설정을 하려면:
  1. device pixel ratio가 null이 아니면:

    1. 지정된 navigable에 현재 로드된 문서에 대해:

      1. source set에서 이미지 소스 선택 단계가 실행될 때, 이미지를 선택할 때 구현의 픽셀 밀도가 device pixel ratio로 설정된 것처럼 동작한다.

      2. resolution media feature의 목적상, 구현의 해상도가 페이지 줌으로 스케일된 device pixel ratio dppx인 것처럼 동작한다.

    2. 설정한다. device pixel ratio overrides[navigable]를 device pixel ratio로 설정한다.

      참고: 이는 § 8.3.1 Device pixel ratio 결정의 패치 때문에 효과를 가진다.

  2. 그렇지 않으면:

    1. 지정된 navigable에 현재 로드된 문서에 대해:

      1. source set에서 이미지 소스 선택 단계가 실행될 때, 이전의 이 단계 호출로 이루어진 변경 없이 구현의 기본 동작을 사용한다.

      2. resolution media feature의 목적상, 이전의 이 단계 호출로 이루어진 변경 없이 구현의 기본 동작을 사용한다.

    2. 제거한다. navigable을 device pixel ratio overrides에서 제거한다.

  3. 지정된 navigable에 현재 로드된 문서에 대해 media query 평가 및 변경 보고를 실행한다.

navigable navigable 및 viewport viewport가 주어졌을 때 viewport 설정을 하려면:
  1. viewport가 null이 아니면, navigable의 layout viewport의 너비를 CSS 픽셀 단위인 viewport의 width로 설정하고, navigable의 layout viewport의 높이를 CSS 픽셀 단위인 viewport의 height로 설정한다.

  2. 그렇지 않으면, navigable의 layout viewport를 구현 정의 기본값으로 설정한다.

새 navigable navigable 안에 문서를 생성한 뒤, WebDriver BiDi 프리로드 스크립트 실행 알고리즘이 호출되기 전에:

TODO: 대신 이를 html 명세의 훅으로 이동한다.

  1. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

  2. navigable이 최상위 traversable이면:

    1. navigable에 대해 geolocation 재정의 갱신을 한다.

    2. navigable에 대해 에뮬레이트된 forced colors 테마 갱신을 한다.

    3. screen orientation overrides map이 user context를 포함하면, navigable 및 screen orientation overrides map[user context]으로 에뮬레이트된 화면 방향 설정을 한다.

  3. viewport overrides map이 user context를 포함하면:

    1. navigable이 최상위 traversable이고 viewport overrides map[user context]의 viewport가 null이 아니면:

      1. navigable 및 viewport overrides map[user context]의 viewport로 viewport 설정을 한다.

    2. viewport overrides map[user context]의 devicePixelRatio가 null이 아니면:

      1. navigable 및 viewport overrides map[user context]의 devicePixelRatio로 device pixel ratio 재정의 설정을 한다.

  4. navigable에 대해 scrollbar type 재정의 갱신을 한다.

  5. 텍스트 레이아웃 모드 재정의 업데이트를 navigable에 대해 수행합니다.

command parameters로 원격 끝 단계는 다음과 같다:

  1. 구현이 어떤 이유로든 주어진 command parameters로 layout viewport 매개변수를 조정할 수 없으면, 오류를 반환하되 오류 코드는 unsupported operation으로 한다.

  2. command parameters가 "userContexts"를 포함하고 command parameters가 "context"를 포함하면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  3. navigables를 집합으로 둔다.

  4. command parameters의 context 필드가 있으면:

    1. navigable id를 command parameters의 context 필드 값으로 둔다.

    2. navigable을 navigable id로 시도하여 navigable 가져오기를 수행한 결과로 둔다.

    3. navigable이 최상위 traversable이 아니면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

    4. navigable을 navigables에 추가한다.

  5. 그렇지 않고, command parameters의 userContexts 필드가 있으면:

    1. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트 가져오기를 수행한 결과로 둔다.

    2. user contexts의 각 user context에 대해:

      1. 설정한다. viewport overrides map[user context]을 구조체로 설정한다.

      2. command parameters가 "viewport"를 포함하면:

        1. viewport overrides map[user context]의 viewport를 command parameters["viewport"]로 설정한다.

      3. command parameters가 "devicePixelRatio"를 포함하면:

        1. viewport overrides map[user context]의 devicePixelRatio를 command parameters["devicePixelRatio"]로 설정한다.

      4. 각 최상위 traversable 중 그 연관된 사용자 컨텍스트가 user context인 모든 목록의 top-level traversable에 대해:

        1. top-level traversable을 navigables에 추가한다.

  6. 그렇지 않으면, 오류를 반환하되 오류 코드는 invalid argument로 한다.

  7. command parameters가 viewport 필드를 포함하면:

    1. viewport를 command parameters["viewport"]로 둔다.

    2. navigables의 각 navigable에 대해:

      1. navigable 및 viewport로 viewport 설정을 한다.

      2. navigable의 활성 문서로 CSSOM View § 13.1 Resizing viewports 단계를 실행한다.

  8. command parameters가 devicePixelRatio 필드를 포함하면:

    1. device pixel ratio를 command parameters["devicePixelRatio"]로 둔다.

    2. navigables의 각 navigable에 대해:

      1. navigable 및 모든 자손 navigable에 대해:

        1. navigable 및 device pixel ratio로 device pixel ratio 재정의 설정을 한다.

  9. 데이터 null과 함께 성공을 반환한다.

7.3.3.13. browsingContext.startScreencast 명령

browsingContext.startScreencast 명령은 주어진 navigable의 스크린캐스트를 시작하고 이를 파일에 쓴다.

참고: 원격 엔드는 스크린캐스트 파일을 만들고 쓰지만, 이를 삭제하지는 않는다. 파일 정리는 로컬 엔드에 맡겨진다. 일부 구성에서는 이것이 불가능할 수 있다 — 예를 들어 원격 엔드가 파일 시스템에 대한 읽기/쓰기 접근 권한을 가지지만 로컬 엔드는 읽기 전용 접근 권한만 가지는 경우이다.

명령 타입
browsingContext.StartScreencast = (
  method: "browsingContext.startScreencast",
  params: browsingContext.StartScreencastParameters
)

browsingContext.StartScreencastParameters = {
  context: browsingContext.BrowsingContext,
  ? destinationFolder: text,
  ? mimeType: text,
  ? video: browsingContext.MediaTrackConstraints,
  ? audio: bool .default false,
}

browsingContext.MediaTrackConstraints = {
   ? width: js-uint,
   ? height: js-uint,
   ? frameRate: js-uint,
}

반환 타입
browsingContext.StartScreencastResult = {
   screencast: browsingContext.Screencast,
   path: text
}

browsingContext.Screencast = text
원격 끝 단계는 session과 command parameters가 주어졌을 때 다음과 같습니다:
  1. navigable id를 command parameters["context"]로 둡니다.

  2. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

  3. navigable이 최상위 순회 가능 항목이 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  4. command parameters가 destinationFolder 필드를 포함하는 경우:

    1. destination folder를 command parameters["destinationFolder"]로 둡니다.

    2. destination folder entry를 항목 찾기에 경로 destination folder와 파일 시스템의 루트에 해당하는 루트를 주어 수행한 결과로 둡니다.

    3. destination folder entry가 null이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

    4. path를 녹화가 저장될 destination folder entry 내의 새 파일에 대한 구현 정의 파일 경로로 둡니다.

  5. 그렇지 않으면, path를 녹화가 저장될 구현 정의 파일 경로로 둡니다.

  6. command parameters가 mimeType 필드를 포함하는 경우:

    1. mime type을 command parameters["mimeType"]으로 둡니다.

  7. 그렇지 않으면, mime type을 구현 정의 기본 형식으로 설정합니다.

  8. 구현이 어떤 이유로든 navigable의 스크린캐스트를 녹화할 수 없으면 오류를 오류 코드 지원되지 않는 작업과 함께 반환합니다.

  9. stream을 navigable에 대한 새 스크린캐스트 스트림으로 두고, 다음과 같이 구성합니다:

    1. 브라우저의 디스플레이 표면을 실시간 캡처하는 video track을 생성합니다. 이 디스플레이 표면은 관련 전역 객체의 연결된 `Document`의 navigable의 뷰포트입니다.

    2. command parameters가 "video"를 포함하는 경우:

      1. video를 command parameters["video"]로 둡니다.

      2. video가 width를 포함하는 경우:

        1. 사용자 에이전트는 하드웨어의 기능과 지정된 다른 제약 조건을 고려하여 너비가 가능한 한 video["width"]에 가까운 미디어를 얻으려고 시도해야 합니다.

      3. video가 height를 포함하는 경우:

        1. 사용자 에이전트는 하드웨어의 기능과 지정된 다른 제약 조건을 고려하여 높이가 가능한 한 video["height"]에 가까운 미디어를 얻으려고 시도해야 합니다.

      4. video가 frameRate를 포함하는 경우:

        1. 사용자 에이전트는 하드웨어의 기능과 지정된 다른 제약 조건을 고려하여 프레임 속도가 가능한 한 video["frameRate"]에 가까운 미디어를 얻으려고 시도해야 합니다.

    3. video track을 stream[비디오 트랙]으로 설정합니다.

    4. command parameters["audio"]가 true인 경우:

      1. 관련 전역 객체의 연결된 `Document`의 navigable의 활성 문서와, 관련 전역 객체의 연결된 `Document`의 navigable의 중첩된 브라우징 컨텍스트에 있는 모든 활성 문서가 생성한 오디오의 합을 결합하여 포함하는 audio track을 생성합니다.

      2. audio track을 stream[오디오 트랙]으로 설정합니다.

    5. 구현이 stream을 생성할 수 없으면, 오류를 오류 코드 알 수 없는 오류와 함께 반환합니다.

  10. screencast를 UUID의 문자열 표현으로 둡니다.

  11. recording을 스크린캐스트 녹화 스트림 stream, 경로 path, 상태 "recording", writeError null인 새로운 것으로 둡니다.

  12. session의 스크린캐스트 녹화 맵[screencast]을 recording으로 설정합니다.

  13. recording과 mime type이 주어졌을 때 스크린캐스트 녹화를 시작합니다.

  14. body를 screencast 필드가 screencast로 설정되고 path 필드가 path로 설정된 browsingContext.StartScreencastResult와 일치하는 새로운 맵으로 둡니다.

  15. 데이터 body와 함께 성공을 반환합니다.

7.3.3.14. browsingContext.stopScreencast 명령

browsingContext.stopScreencast 명령은 스크린캐스트를 중지한다.

명령 타입
browsingContext.StopScreencast = (
  method: "browsingContext.stopScreencast",
  params: browsingContext.StopScreencastParameters
)

browsingContext.StopScreencastParameters = {
  screencast: browsingContext.Screencast
}
반환 타입
browsingContext.StopScreencastResult = {
   path: text,
   ? error: text
}
session 및 command parameters가 주어진 원격 엔드 단계는 다음과 같다:
  1. screencast를 command parameters 안의 "screencast" 필드 값으로 둔다.

  2. session의 스크린캐스트 녹화 맵이 screencast를 포함하지 않으면, 오류를 오류 코드 해당 스크린캐스트 없음과 함께 반환합니다.

  3. screencast recording을 session의 스크린캐스트 녹화 맵[screencast]으로 둔다.

  4. screencast recording이 주어졌을 때 스크린캐스트 녹화를 중지한다.

  5. screencast를 session의 스크린캐스트 녹화 맵에서 제거한다.

  6. error를 screencast recording의 writeError로 둔다.

  7. path를 screencast recording의 path로 둔다.

  8. body를 browsingContext.StopScreencastResult와 일치하는 새 맵으로 두고, path 필드는 path로, error 필드는 error가 null이 아니면 error로 설정하고, 그렇지 않으면 생략한다.

  9. body 데이터를 가진 성공을 반환한다.

7.3.3.15. browsingContext.traverseHistory 명령

browsingContext.traverseHistory 명령은 주어진 navigable의 이력을 delta만큼 순회한다.

명령 타입
browsingContext.TraverseHistory = (
  method: "browsingContext.traverseHistory",
  params: browsingContext.TraverseHistoryParameters
)

browsingContext.TraverseHistoryParameters = {
  context: browsingContext.BrowsingContext,
  delta: js-int,
}
반환 타입
browsingContext.TraverseHistoryResult = EmptyResult
command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. navigable을 command parameters["context"]로 시도하여 내비게이블을 가져온 결과로 둡니다.

  2. navigable이 최상위 순회 가능 항목이 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  3. 단언: navigable은 null이 아닙니다.

  4. delta를 command parameters["delta"]로 둡니다.

  5. resume id를 고유한 문자열로 둡니다.

  6. navigable의 세션 기록 순회 큐에 다음 단계를 실행하도록 태스크를 큐에 추가합니다:

    1. all steps를 navigable에 대해 사용된 모든 기록 단계를 가져온 결과로 둡니다.

    2. current index를 all steps 내에서 navigable의 현재 세션 기록 단계의 인덱스로 둡니다.

    3. target index를 current index에 delta를 더한 값으로 둡니다.

    4. all steps[target index]가 존재하지 않으면 valid entry를 false로, 그렇지 않으면 true로 둡니다.

    5. "check history", resume id, 그리고 valid entry로 재개합니다.

  7. is valid entry를 «"check history"»와 resume id로 대기한 결과로 둡니다.

  8. is valid entry가 false이면, 오류 코드 해당 기록 항목 없음과 함께 오류를 반환합니다.

  9. delta와 navigable이 주어졌을 때 델타만큼 기록을 순회합니다.

    작성된 알고리즘에는 경쟁 조건이 있습니다. 탐색을 시도할 시점에는 대상 세션 기록 항목이 더 이상 존재하지 않을 수도 있기 때문입니다. 기록 탐색을 기다리는 기능을 지원하게 되면 이를 더 견고하게 처리할 수 있습니다.

  10. TODO: 기록 순회가 완료될 때까지 기다리는 기능을 지원합니다.

  11. body를 browsingContext.TraverseHistoryResult 생성 규칙과 일치하는 맵으로 둡니다.

  12. 데이터 body와 함께 성공을 반환합니다.

context 및 navigation status navigation status가 주어졌을 때 WebDriver BiDi page show 단계는 다음과 같다:

`browsingContext.pageShow` 이벤트를 노출할 것인가? 이 경우 이를 bfcache 복원 시뿐 아니라 `pageshow`가 방출될 때마다 호출해야 하며, persisted 상태도 데이터에 추가해야 한다.

  1. navigation id를 navigation status의 id로 둔다.

  2. "page show", navigation id, 그리고 navigation status로 재개한다.

context 및 navigation status navigation status가 주어졌을 때 WebDriver BiDi pop state 단계는 다음과 같다:

  1. navigation id를 navigation status의 id로 둔다.

  2. "pop state", navigation id, 그리고 navigation status로 재개한다.

7.3.4. 이벤트

7.3.4.1. browsingContext.contextCreated 이벤트
이벤트 타입
browsingContext.ContextCreated = (
 method: "browsingContext.contextCreated",
 params: browsingContext.ContextCreatedParameters
)

browsingContext.ContextCreatedParameters = {
 browsingContext.BaseInfo,
 hasPlannedNavigation: bool,
}

browsingContext.ContextCreatedParameters의 hasPlannedNavigation은 browsingContext.contextCreated 이벤트가 디스패치된 후 탐색 가능 항목이 탐색을 수행할 예정인지 여부를 나타냅니다.

session 및 navigable이 주어졌을 때 컨텍스트 생성 이벤트를 재귀적으로 발생시키려면:

  1. session, navigable 및 false를 사용하여 컨텍스트 생성 이벤트를 발생시킵니다.

  2. navigable의 각 자식 탐색 가능 항목 child에 대해:

    1. session 및 child이 주어졌을 때 컨텍스트 생성 이벤트를 재귀적으로 발생시킵니다.

session, navigable 및 has planned navigation이 주어졌을 때 컨텍스트 생성 이벤트를 발생시키려면:

  1. params를 navigable, 0 및 true가 주어졌을 때 탐색 가능 항목 정보를 가져온 결과로 설정합니다.

  2. params["hasPlannedNavigation"]을 has planned navigation으로 설정합니다.

  3. 단언: params는 browsingContext.ContextCreated 생성 규칙과 일치합니다.

  4. body를 params 필드가 params로 설정된, browsingContext.ContextCreated 생성 규칙과 일치하는 맵으로 설정합니다.

  5. session 및 body를 사용하여 이벤트를 발생시킵니다.

원격 종단 이벤트 트리거는 탐색 가능 항목 navigable, 불리언 has planned navigation 및 선택적 탐색 가능 항목 opener navigable (기본값: null)이 주어졌을 때의 WebDriver BiDi 탐색 가능 항목 생성됨 단계입니다:

  1. navigable의 원래 opener를 opener navigable로 설정합니다.

  2. navigable에 대한 탐색 가능 항목 캐시 동작이 "bypass"이면, navigable에서 시작되는 네트워크 요청에 대한 구현별 리소스 캐시를 비활성화하기 위해 구현 정의 단계를 수행합니다.

  3. related navigables를 navigable을 포함하는 집합으로 설정합니다.

  4. "browsingContext.contextCreated" 및 related navigables이 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. session, navigable 및 has planned navigation이 주어졌을 때 컨텍스트 생성 이벤트를 발생시킵니다.

session, navigables 및 include global이 주어졌을 때, 구독 우선순위가 1인 원격 종단 구독 단계는 다음과 같습니다:

  1. navigables의 각 navigable에 대해:

    1. session 및 navigable이 주어졌을 때 컨텍스트 생성 이벤트를 재귀적으로 발생시킵니다.

7.3.4.2. browsingContext.contextDestroyed 이벤트
이벤트 타입
browsingContext.ContextDestroyed = (
 method: "browsingContext.contextDestroyed",
 params: browsingContext.Info
)
원격 끝 이벤트 트리거는 다음과 같다:

원격 끝 이벤트 트리거는 navigable navigable이 주어졌을 때의 WebDriver BiDi navigable destroyed 단계이다:

  1. params를 navigable, null, true가 주어졌을 때 navigable 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.ContextDestroyed 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. related navigables를 navigable의 부모가 null이 아니면 그것을 포함하는 집합으로, 그렇지 않으면 빈 집합으로 둔다.

  4. "browsingContext.contextDestroyed" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

    2. subscriptions to remove를 집합으로 둔다.

    3. session의 구독에 있는 각 subscription에 대해:

      1. subscription의 최상위 traversable id가 navigable의 navigable id를 포함하면;

        1. navigable의 navigable id를 subscription의 최상위 traversable id에서 제거한다.

        2. subscription의 최상위 traversable id가 비어 있으면:

          1. subscription을 subscriptions to remove에 추가한다.

    4. subscriptions to remove를 session의 구독에서 제거한다.

이 이벤트를 활성 문서를 가진 browsing context에 대해서만 발생시켜야 하는지는 명확하지 않다. 탐색은 context가 접근 불가능해지게 할 수도 있지만, bfcache 때문에 아직 폐기되지 않을 수도 있다.

7.3.4.3. browsingContext.navigationStarted 이벤트
이벤트 타입
browsingContext.NavigationStarted = (
 method: "browsingContext.navigationStarted",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi navigation started 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.NavigationStarted 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. navigation id를 navigation status의 id로 둔다.

  4. related navigables를 navigable을 포함하는 집합으로 둔다.

  5. "navigation started", navigation id, 그리고 navigation status로 재개한다.

  6. "browsingContext.navigationStarted" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.4. browsingContext.fragmentNavigated 이벤트
이벤트 타입
browsingContext.FragmentNavigated = (
 method: "browsingContext.fragmentNavigated",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi fragment navigated 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.FragmentNavigated 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. navigation id를 navigation status의 id로 둔다.

  4. related navigable를 navigable을 포함하는 집합으로 둔다.

  5. "fragment navigated", navigation id, 그리고 navigation status로 재개한다.

  6. "browsingContext.fragmentNavigated" 및 related navigable가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.5. browsingContext.historyUpdated 이벤트
이벤트 타입
browsingContext.HistoryUpdated = (
  method: "browsingContext.historyUpdated",
  params: browsingContext.HistoryUpdatedParameters
)

browsingContext.HistoryUpdatedParameters = {
  context: browsingContext.BrowsingContext,
  timestamp: js-uint,
  url: text,
  ? userContext: browser.UserContext
}
원격 엔드 이벤트 트리거는 navigable navigable이 주어졌을 때의 WebDriver BiDi 히스토리 업데이트됨 단계이다:
  1. url을 navigable의 활성 브라우징 컨텍스트의 활성 문서의 URL이 주어졌을 때, URL 직렬화기를 실행한 결과로 둔다.

  2. user context id를 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 ID로 둔다.

  3. timestamp를 UTC의 현재 날짜와 시간을 나타내는 시간 값으로 둔다.

  4. params를 browsingContext.HistoryUpdatedParameters 생성식과 일치하는 맵으로 두고, url 필드는 url로, timestamp 필드는 timestamp로, context 필드는 navigable의 navigable ID로, userContext 필드는 user context id로 설정한다.

  5. body를 browsingContext.HistoryUpdated 생성식과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  6. related browsing contexts를 navigable의 활성 브라우징 컨텍스트를 포함하는 집합으로 둔다.

  7. "browsingContext.historyUpdated" 및 related browsing contexts가 주어졌을 때 이벤트가 활성화된 세션들의 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트를 방출한다.

7.3.4.6. browsingContext.domContentLoaded 이벤트
이벤트 타입
browsingContext.DomContentLoaded = (
 method: "browsingContext.domContentLoaded",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi DOM content loaded 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.DomContentLoaded 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. related navigables를 navigable을 포함하는 집합으로 둔다.

  4. navigation id를 navigation status의 id로 둔다.

  5. "domContentLoaded", navigation id, 그리고 navigation status로 재개한다.

  6. "browsingContext.domContentLoaded" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.7. browsingContext.load 이벤트
이벤트 타입
browsingContext.Load = (
 method: "browsingContext.load",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi load complete 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.Load 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. related navigables를 navigable을 포함하는 집합으로 둔다.

  4. navigation id를 navigation status의 id로 둔다.

  5. "load", navigation id 및 navigation status로 재개한다.

  6. "browsingContext.load" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.8. browsingContext.downloadWillBegin 이벤트
이벤트 타입
browsingContext.DownloadWillBegin = (
 method: "browsingContext.downloadWillBegin",
 params: browsingContext.DownloadWillBeginParams
)

browsingContext.DownloadWillBeginParams = {
  download: browsingContext.Download,
  suggestedFilename: text,
  browsingContext.BaseNavigationInfo
}
원격 엔드 이벤트 트리거는 navigable navigable 및 탐색 상태 navigation status가 주어졌을 때의 WebDriver BiDi 다운로드 시작 예정 단계이다:
  1. navigation info를 navigable 및 navigation status가 주어졌을 때 탐색 정보 가져오기를 수행한 결과로 둔다.

  2. download를 UUID의 문자열 표현으로 둔다.

  3. 다운로드 ID 맵[navigation status의 downloadResponse]를 download로 설정한다.

  4. params를 browsingContext.DownloadWillBeginParams 생성식과 일치하는 맵으로 두고, context 필드는 navigation info["context"]로, navigation 필드는 navigation info["navigation"]로, timestamp 필드는 navigation info["timestamp"]로, url 필드는 navigation info["url"]로, download 필드는 download로, suggestedFilename 필드는 navigation status의 suggestedFilename으로 설정한다.

  5. body를 browsingContext.DownloadWillBegin 생성식과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  6. navigation id를 navigation status의 id로 둔다.

  7. related navigables를 navigable을 포함하는 집합으로 둔다.

  8. "download started", navigation id, 및 navigation status로 재개한다.

  9. "browsingContext.downloadWillBegin" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션들의 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트를 방출한다.

  10. download behavior를 navigable로 다운로드 동작 가져오기를 수행한 결과로 둔다.

  11. download behavior를 반환한다.

7.3.4.9. browsingContext.downloadEnd 이벤트
이벤트 타입
browsingContext.DownloadEnd = (
  method: "browsingContext.downloadEnd",
  params: browsingContext.DownloadEndParams
)

browsingContext.DownloadEndParams = {
  (
    browsingContext.DownloadCanceledParams //
    browsingContext.DownloadCompleteParams
  )
}

browsingContext.DownloadCanceledParams = (
  status: "canceled",
  download: browsingContext.Download,
  browsingContext.BaseNavigationInfo
)

browsingContext.DownloadCompleteParams = (
  status: "complete",
  download: browsingContext.Download,
  filepath: text / null,
  browsingContext.BaseNavigationInfo
)
원격 엔드 이벤트 트리거는 navigable navigable 및 탐색 상태 navigation status가 주어졌을 때의 WebDriver BiDi 다운로드 종료 단계이다:
  1. navigation info를 navigable 및 navigation status가 주어졌을 때 탐색 정보 가져오기를 수행한 결과로 둔다.

  2. 단언: navigation info["status"]는 "complete" 또는 "canceled"와 같아야 한다.

  3. download response를 navigation status의 downloadResponse로 둔다.

  4. 다운로드 ID 맵이 download response를 포함하면, download를 다운로드 ID 맵[download response]으로 두고, 그렇지 않으면 download를 UUID의 문자열 표현으로 둔다.

  5. navigation info["status"]가 "complete"이면, params를 browsingContext.DownloadCompleteParams 생성식과 일치하는 맵으로 두고, download 필드는 download로, filepath 필드는 navigation status의 downloadedFilepath로, context 필드는 navigation info["context"]로, navigation 필드는 navigation info["navigation"]로, timestamp 필드는 navigation info["timestamp"]로, url 필드는 navigation info["url"]로 설정한다.

    참고: 완료된 다운로드에서 filepath를 어떤 이유로든 사용할 수 없는 경우 filepath는 null일 수 있다.

  6. 그렇지 않으면, params를 browsingContext.DownloadCanceledParams 생성식과 일치하는 맵으로 두고, download 필드는 download로, context 필드는 navigation info["context"]로, navigation 필드는 navigation info["navigation"]로, timestamp 필드는 navigation info["timestamp"]로, url 필드는 navigation info["url"]로 설정한다.

  7. body를 browsingContext.DownloadEnd 생성식과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  8. related navigables를 navigable을 포함하는 집합으로 둔다.

  9. "browsingContext.downloadEnd" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션들의 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트를 방출한다.

7.3.4.10. browsingContext.navigationAborted 이벤트
이벤트 타입
browsingContext.NavigationAborted = (
 method: "browsingContext.navigationAborted",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi navigation aborted 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.NavigationAborted 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. navigation id를 navigation status의 id로 둔다.

  4. related navigables를 navigable을 포함하는 집합으로 둔다.

  5. "navigation aborted", navigation id, 그리고 navigation status로 재개한다.

  6. "browsingContext.navigationAborted" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.11. browsingContext.navigationCommitted 이벤트
이벤트 타입
browsingContext.NavigationCommitted = (
 method: "browsingContext.navigationCommitted",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi navigation committed 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.NavigationCommitted 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. related navigables를 navigable을 포함하는 집합으로 둔다.

  4. navigation id를 navigation status의 id로 둔다.

  5. "navigation committed", navigation id, 그리고 navigation status로 재개한다.

  6. "browsingContext.navigationCommitted" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.12. browsingContext.navigationFailed 이벤트
이벤트 타입
browsingContext.NavigationFailed = (
 method: "browsingContext.navigationFailed",
 params: browsingContext.NavigationInfo
)
원격 끝 이벤트 트리거는 navigable navigable 및 navigation status navigation status가 주어졌을 때의 WebDriver BiDi navigation failed 단계이다:
  1. params를 navigable 및 navigation status가 주어졌을 때 navigation 정보 가져오기를 수행한 결과로 둔다.

  2. body를 browsingContext.NavigationFailed 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  3. navigation id를 navigation status의 id로 둔다.

  4. related navigables를 navigable을 포함하는 집합으로 둔다.

  5. "navigation failed", navigation id, 그리고 navigation status로 재개한다.

  6. "browsingContext.navigationFailed" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.13. browsingContext.userPromptClosed 이벤트
이벤트 타입
browsingContext.UserPromptClosed = (
  method: "browsingContext.userPromptClosed",
  params: browsingContext.UserPromptClosedParameters
)

browsingContext.UserPromptClosedParameters = {
  context: browsingContext.BrowsingContext,
  accepted: bool,
  type: browsingContext.UserPromptType,
  ? userContext: browser.UserContext,
  ? userText: text
}
원격 끝 이벤트 트리거는 Window window, 문자열 type, boolean accepted 및 선택적 text user text (기본값: null)가 주어졌을 때의 WebDriver BiDi user prompt closed 단계이다.
  1. navigable을 window의 navigable로 둔다.

  2. navigable id를 navigable에 대한 navigable id로 둔다.

  3. user context id를 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id로 둔다.

  4. params를 browsingContext.UserPromptClosedParameters 생성규칙과 일치하는 맵으로 두고, context 필드를 navigable id로 설정하고, userContext 필드를 user context id로 설정하고, accepted 필드를 accepted로 설정하고, type 필드를 type로 설정하고, user text가 null이 아니면 userText 필드를 user text로 설정하며, 그렇지 않으면 생략한다.

  5. body를 BrowsingContextUserPromptClosedEvent 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  6. related navigables를 navigable을 포함하는 집합으로 둔다.

  7. "browsingContext.userPromptClosed" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

7.3.4.14. browsingContext.userPromptOpened 이벤트
이벤트 타입
browsingContext.UserPromptOpened = (
  method: "browsingContext.userPromptOpened",
  params: browsingContext.UserPromptOpenedParameters
)

browsingContext.UserPromptOpenedParameters = {
  context: browsingContext.BrowsingContext,
  handler: session.UserPromptHandlerType,
  message: text,
  type: browsingContext.UserPromptType,
  ? userContext: browser.UserContext,
  ? defaultValue: text
}
type 및 navigable이 주어졌을 때 navigable의 사용자 프롬프트 핸들러 가져오기를 하려면:
  1. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

  2. 처리되지 않은 프롬프트 동작 재정의 맵이 user context를 포함하면:

    1. unhandled prompt behavior override를 처리되지 않은 프롬프트 동작 재정의 맵[user context]로 둔다.

    2. unhandled prompt behavior override[type]가 null이 아니면, unhandled prompt behavior override[type]를 반환한다.

    3. unhandled prompt behavior override["default"]가 null이 아니면, unhandled prompt behavior override["default"]를 반환한다.

  3. handler configuration을 type으로 프롬프트 핸들러 가져오기를 수행한 결과로 둔다.

  4. handler configuration의 handler를 반환한다.

원격 끝 이벤트 트리거는 Window window, 문자열 type, 문자열 message, 및 선택적 text default value (기본값: null)가 주어졌을 때의 WebDriver BiDi user prompt opened 단계이다.
  1. navigable을 window의 navigable로 둔다.

  2. navigable id를 navigable에 대한 navigable id로 둔다.

  3. user context id를 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id로 둔다.

  4. handler를 type 및 navigable로 navigable의 사용자 프롬프트 핸들러 가져오기를 수행한 결과로 둔다.

  5. params를 browsingContext.UserPromptOpenedParameters 생성규칙과 일치하는 맵으로 두고, context 필드를 navigable id로 설정하고, userContext 필드를 user context id로 설정하고, type 필드를 type로 설정하고, message 필드를 message로 설정하고, default value가 null이 아니면 defaultValue 필드를 default value로 설정하며, 그렇지 않으면 생략하고, handler 필드를 handler로 설정한다.

  6. body를 browsingContext.UserPromptOpened 생성규칙과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

  7. related navigables를 navigable을 포함하는 집합으로 둔다.

  8. "browsingContext.userPromptOpened" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합에 있는 각 session에 대해:

    1. session 및 body로 이벤트 방출을 한다.

  9. handler가 "ignore"이면, handler를 "none"으로 설정한다.

  10. handler를 반환한다.

7.4. emulation 모듈

emulation 모듈은 브라우저 API의 에뮬레이션과 관련된 명령 및 이벤트를 포함한다.

7.4.1. 정의

원격 끝 정의

EmulationCommand = (
  emulation.SetForcedColorsModeThemeOverride //
  emulation.SetGeolocationOverride //
  emulation.SetLocaleOverride //
  emulation.SetMediaFeaturesOverride //
  emulation.SetNetworkConditions //
  emulation.SetScreenOrientationOverride //
  emulation.SetScreenSettingsOverride //
  emulation.SetScriptingEnabled //
  emulation.SetScrollbarTypeOverride //
  emulation.SetTextLayoutModeOverride //
  emulation.SetTimezoneOverride //
  emulation.SetTouchOverride //
  emulation.SetUserAgentOverride //
  emulation.SetViewportMetaOverride
)

EmulationResult = (
  emulation.SetForcedColorsModeThemeOverrideResult /
  emulation.SetGeolocationOverrideResult /
  emulation.SetLocaleOverrideResult /
  emulation.SetMediaFeaturesOverrideResult /
  emulation.SetScreenOrientationOverrideResult /
  emulation.SetScriptingEnabledResult /
  emulation.SetScrollbarTypeOverrideResult /
  emulation.SetTextLayoutModeOverrideResult /
  emulation.SetTimezoneOverrideResult /
  emulation.SetTouchOverrideResult /
  emulation.SetUserAgentOverrideResult /
  emulation.SetViewportMetaOverrideResult
)

BiDi 세션은 에뮬레이트된 사용자 에이전트를 가지며, 이는 구조체로, 항목 중 기본 사용자 에이전트라는 이름의 항목을 가지며, 이는 문자열 또는 null이고, 항목 중 사용자 컨텍스트 사용자 에이전트라는 이름의 항목을 가지며, 이는 사용자 컨텍스트와 문자열 사이의 weak map이고, 항목 중 navigable 사용자 에이전트라는 이름의 항목을 가지며, 이는 navigable과 문자열 사이의 weak map이다.

BiDi 세션은 에뮬레이트된 maxTouchPoints를 가지며, 이는 구조체로, 항목 중 default라는 이름의 항목을 가지며, 이는 정수 또는 null이고, 처음에는 null이다; 항목 중 사용자 컨텍스트라는 이름의 항목을 가지며, 이는 사용자 컨텍스트와 정수 사이의 weak map이고, 처음에는 비어 있다; 그리고 항목 중 navigable이라는 이름의 항목을 가지며, 이는 navigable과 정수 사이의 weak map이고, 처음에는 비어 있다.

화면 방향 재정의는 다음을 가진 구조체이다:

원격 엔드는 화면 방향 재정의 맵을 가지며, 이는 사용자 컨텍스트와 화면 방향 재정의 사이의 weak map이다.

7.4.2. 명령

7.4.2.1. emulation.setForcedColorsModeThemeOverride 명령

emulation.setForcedColorsModeThemeOverride 명령은 주어진 최상위 순회 가능 객체 또는 사용자 컨텍스트의 강제 색상 모드 테마 특성을 수정한다.

명령 유형
emulation.SetForcedColorsModeThemeOverride = (
  method: "emulation.setForcedColorsModeThemeOverride",
  params: emulation.SetForcedColorsModeThemeOverrideParameters
)

emulation.SetForcedColorsModeThemeOverrideParameters = {
  theme: emulation.ForcedColorsModeTheme / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.ForcedColorsModeTheme = "light" / "dark"
반환 유형
emulation.SetForcedColorsModeThemeOverrideResult = EmptyResult

참고: CSS 명세에서 대응하는 열거형 매핑은 ForcedColorsModeAutomationTheme을 참조한다.

원격 엔드에는 강제 색상 모드 테마 재정의 구성이 있으며, 이는 WebDriver 구성으로, 연결된 유형은 문자열이다.

순회 가능 객체 navigable에 대해 에뮬레이션된 강제 색상 테마를 업데이트하려면:
  1. theme을 navigable에 대한 강제 색상 모드 테마 재정의 구성의 WebDriver 구성 값 가져오기 결과로 둔다.

  2. 단언: theme은 "light", "dark" 또는 설정되지 않음이다.

  3. theme이 설정되지 않음이면, theme을 "none"으로 설정한다.

  4. navigable 및 theme으로 에뮬레이션된 강제 색상 테마 데이터 설정을 수행한다.

command parameters가 주어졌을 때 원격 엔드 단계는 다음과 같다:

  1. theme을 command parameters["theme"]으로 둔다.

  2. theme이 null이면, theme을 설정되지 않음으로 설정한다.

  3. 구현이 theme 설정을 지원하지 않으면, 오류를 오류 코드 지원되지 않는 작업과 함께 반환한다.

  4. affected navigables를 command parameters에 대해 강제 색상 모드 테마 재정의 구성 theme을 WebDriver 구성 저장하도록 시도한 결과로 둔다.

  5. affected navigables의 각 navigable에 대해:

    1. navigable에 대해 에뮬레이션된 강제 색상 테마를 업데이트한다.

  6. 데이터 null과 함께 성공을 반환한다.

7.4.2.2. emulation.setGeolocationOverride 명령

emulation.setGeolocationOverride 명령은 주어진 최상위 순회 가능 객체 또는 사용자 컨텍스트의 지리 위치 특성을 수정한다.

명령 유형
emulation.SetGeolocationOverride = (
  method: "emulation.setGeolocationOverride",
  params: emulation.SetGeolocationOverrideParameters
)

emulation.SetGeolocationOverrideParameters = {
  (
    (coordinates: emulation.GeolocationCoordinates / null) //
    (error: emulation.GeolocationPositionError)
  ),
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.GeolocationCoordinates = {
   latitude: -90.0..90.0,
   longitude: -180.0..180.0,
   ? accuracy: (float .ge 0.0) .default 1.0,
   ? altitude: float / null .default null,
   ? altitudeAccuracy: (float .ge 0.0) / null .default null,
   ? heading: (0.0...360.0) / null .default null,
   ? speed: (float .ge 0.0) / null .default null,
}

emulation.GeolocationPositionError = {
   type: "positionUnavailable"
}
반환 유형
emulation.SetGeolocationOverrideResult = EmptyResult

지리 위치 재정의는 다음을 갖는 구조체이다:

원격 엔드에는 지리 위치 재정의 구성이 있으며, 이는 WebDriver 구성으로, 연결된 유형은 지리 위치 재정의이다.

순회 가능 객체 navigable에 대해 지리 위치 재정의를 업데이트하려면:
  1. emulated position data를 navigable에 대한 지리 위치 재정의 구성의 WebDriver 구성 값 가져오기 결과로 둔다.

  2. emulated position data가 설정되지 않음이면, emulated position data를 null로 설정한다.

  3. navigable 및 emulated position data로 에뮬레이션된 위치 데이터 설정을 수행한다.

command parameters가 주어졌을 때 원격 엔드 단계는 다음과 같다:

  1. command parameters가 "coordinates"를 포함하고 command parameters["coordinates"]가 "altitudeAccuracy"를 포함하며 command parameters["coordinates"]가 "altitude"를 포함하지 않으면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. command parameters가 "error"를 포함하는 경우:

    1. command parameters["error"]["type"]이 "positionUnavailable"와 같다고 단언합니다.

    2. emulated position data를 GeolocationPositionError 생성 규칙과 일치하고, code 필드가 POSITION_UNAVAILABLE로 설정되고 message 필드가 빈 문자열로 설정된 맵으로 둡니다.

      참고: message는 지리 위치 명세에 따라 구현에서 무시됩니다.

  3. 그렇지 않으면, emulated position data를 command parameters["coordinates"]로 둡니다.

  4. emulated position data가 null이면, emulated position data를 설정되지 않음으로 설정합니다.

  5. affected navigables를 command parameters에 대해 지리 위치 재정의 구성 emulated position data를 시도하여 WebDriver 구성을 저장한 결과로 둡니다.

  6. affected navigables의 각 navigable에 대해:

    1. navigable에 대해 지리 위치 재정의를 업데이트합니다.

  7. 데이터 null과 함께 성공을 반환합니다.

7.4.2.3. emulation.setLocaleOverride 명령

emulation.setLocaleOverride 명령은 주어진 최상위 순회 가능 객체 또는 사용자 컨텍스트의 로캘을 수정한다.

명령 유형
emulation.SetLocaleOverride = (
  method: "emulation.setLocaleOverride",
  params: emulation.SetLocaleOverrideParameters
)

emulation.SetLocaleOverrideParameters = {
  locale: text / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetLocaleOverrideResult = EmptyResult

환경 설정 객체 environment settings가 주어졌을 때 WebDriver BiDi 에뮬레이션 언어 단계는 다음과 같습니다:

  1. related navigables를 environment settings가 주어졌을 때 관련 내비게이블 가져오기의 결과로 둡니다.

  2. related navigables의 각 navigable에 대해:

    1. top-level traversable을 navigable의 최상위 순회 가능 항목으로 둡니다.

    2. user context를 top-level traversable의 연결된 사용자 컨텍스트로 둡니다.

    3. 로캘 재정의 맵이 top-level traversable을 포함하면, 로캘 재정의 맵[top-level traversable]을 반환합니다.

    4. 로캘 재정의 맵이 user context를 포함하면, 로캘 재정의 맵[user context]을 반환합니다.

  3. null을 반환합니다

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. command parameters가 "userContexts"를 포함하고 command parameters가 "contexts"를 포함하면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. command parameters가 "userContexts"를 포함하지 않고 command parameters가 "contexts"도 포함하지 않으면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  3. emulated locale을 command parameters["locale"]로 둡니다.

  4. emulated locale이 null이 아니고 IsStructurallyValidLanguageTag(emulated locale)이 false를 반환하면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  5. navigables를 집합으로 둡니다.

  6. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

  7. 그렇지 않은 경우:

    1. command parameters의 userContexts 필드가 존재한다고 단언합니다.

    2. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    3. user contexts의 각 user context에 대해:

      1. emulated locale이 null이면, 제거합니다: 로캘 재정의 맵에서 user context를.

      2. 그렇지 않으면, 로캘 재정의 맵[user context]을 emulated locale로 설정합니다.

      3. 각각에 대해, 최상위 순회 가능 항목의 전체 목록에서 연결된 사용자 컨텍스트가 user context인 각 top-level traversable에 대해:

        1. top-level traversable을 navigables에 추가합니다.

  8. navigables의 각 navigable에 대해:

    1. emulated locale이 null이면, 제거합니다: 로캘 재정의 맵에서 navigable을.

    2. 그렇지 않으면, 로캘 재정의 맵[navigable]을 emulated locale로 설정합니다.

  9. 데이터 null과 함께 성공을 반환합니다.

7.4.2.4. emulation.setMediaFeaturesOverride 명령

emulation.setMediaFeaturesOverride 명령은 다양한 미디어 기능의 값을 재정의할 수 있게 한다.

명령 유형
emulation.SetMediaFeaturesOverride = (
  method: "emulation.setMediaFeaturesOverride",
  params: emulation.SetMediaFeaturesOverrideParameters
)

emulation.SetMediaFeaturesOverrideParameters = {
  features: emulation.MediaFeatures / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.MediaFeatures = {
  ? "any-hover": "none" / "hover" / null,
  ? "any-pointer": "none" / "coarse" / "fine" / null,
  ? "color": js-uint / null,
  ? "color-gamut": "srgb" / "p3" / "rec2020" / null,
  ? "color-index": js-uint / null,
  ? "display-mode": "fullscreen" / "standalone" / "minimal-ui" / "browser" / "picture-in-picture" / null,
  ? "dynamic-range": "standard" / "high" / null,
  ? "environment-blending": "opaque" / "additive" / "subtractive" / null,
  ? "forced-colors": "none" / "active" / null,
  ? "grid": 0 / 1 / null,
  ? "horizontal-viewport-segments": js-uint / null,
  ? "hover": "none" / "hover" / null,
  ? "inverted-colors": "none" / "inverted" / null,
  ? "monochrome": js-uint / null,
  ? "nav-controls": "none" / "back" / null,
  ? "overflow-block": "none" / "scroll" / "optional-paged" / "paged" / null,
  ? "overflow-inline": "none" / "scroll" / null,
  ? "pointer": "none" / "coarse" / "fine" / null,
  ? "prefers-color-scheme": "light" / "dark" / null,
  ? "prefers-contrast": "no-preference" / "more" / "less" / "custom" / null,
  ? "prefers-reduced-data": "no-preference" / "reduce" / null,
  ? "prefers-reduced-motion": "no-preference" / "reduce" / null,
  ? "prefers-reduced-transparency": "no-preference" / "reduce" / null,
  ? "scan": "interlace" / "progressive" / null,
  ? "scripting": "none" / "initial-only" / "enabled" / null,
  ? "update": "none" / "slow" / "fast" / null,
  ? "vertical-viewport-segments": js-uint / null,
  ? "video-color-gamut": "srgb" / "p3" / "rec2020" / null,
  ? "video-dynamic-range": "standard" / "high" / null,
}

반환 유형
emulation.SetMediaFeaturesOverrideResult = EmptyResult

원격 엔드에는 미디어 기능 재정의 구성이 있으며, 이는 WebDriver 구성으로, 연결된 유형은 맵이다.

Document document와 미디어 기능 이름 name에 대한 WebDriver BiDi 미디어 기능 값을 가져오려면:
  1. navigable을 document의 노드 순회 가능 객체로 둔다.

  2. media features override map을 navigable에 대한 미디어 기능 재정의 구성의 WebDriver 구성 값 가져오기 결과로 둔다.

  3. media features override map이 설정되지 않음이 아니고 media features override map이 name을 포함하면, media features override map[name]을 반환한다.

  4. null을 반환한다.

command parameters가 주어졌을 때 원격 엔드 단계는 다음과 같다:

  1. media features override를 command parameters["features"]로 둔다.

  2. media features override가 null이면, media features override를 설정되지 않음으로 설정한다.

  3. media features override map을 빈 맵으로 둔다.

  4. media features override의 각 media feature에 대해:

    1. media features override map[media feature["name"]]을 media feature["value"]로 설정한다.

  5. 구현이 media features override map의 미디어 기능 중 어느 것도 재정의할 수 없는 경우, 오류를 오류 코드 지원되지 않는 작업과 함께 반환한다.

  6. affected navigables를 command parameters에 대한 미디어 기능 재정의 구성 media features override map을 WebDriver 구성 저장한 결과로 둔다.

  7. affected navigables의 각 navigable에 대해:

    1. 각각에 대해, 현재 navigable 또는 그 하위 순회 가능 객체에 로드된 document:

      1. document에 대해 미디어 쿼리를 평가하고 변경 사항을 보고한다.

  8. 데이터 null과 함께 성공을 반환한다.

7.4.2.5. emulation.setNetworkConditions 명령

emulation.setNetworkConditions 명령은 주어진 브라우징 컨텍스트 또는 사용자 컨텍스트에 대해 특정 네트워크 조건을 에뮬레이션한다.

명령 유형
emulation.SetNetworkConditions = (
  method: "emulation.setNetworkConditions",
  params: emulation.SetNetworkConditionsParameters
)

emulation.SetNetworkConditionsParameters = {
  networkConditions: emulation.NetworkConditions / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.NetworkConditions = emulation.NetworkConditionsOffline

emulation.NetworkConditionsOffline = {
  type: "offline"
}
반환 유형
emulation.SetNetworkConditionsResult = EmptyResult

네트워크 조건을 적용하려면:

  1. 각 WebSocket 객체 webSocket에 대해:

    1. realm을 webSocket의 관련 Realm으로 둔다.

    2. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둔다.

    3. environment settings로 WebDriver BiDi 네트워크가 오프라인인지를 확인한 결과가 true이면:

      1. webSocket의 WebSocket 연결을 실패시킨다.

  2. 각 WebTransport 객체 webTransport에 대해:

    1. realm을 webSocket의 관련 Realm으로 둔다.

    2. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둔다.

    3. environment settings로 WebDriver BiDi 네트워크가 오프라인인지를 확인한 결과가 true이면:

      1. webTransport에 대해 WebTransport 정리를 수행한다.

command parameters와 session이 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. command parameters가 포함하고 "userContexts"를 command parameters가 포함하면 "context"를, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. emulated network conditions를 null로 둡니다.

  3. command parameters["networkConditions"]가 null이 아니고 command parameters["networkConditions"]["type"]이 "offline"과 같으면, emulated network conditions를 에뮬레이션된 네트워크 조건 구조체 중 오프라인이 true로 설정된 새 구조체로 설정합니다.

  4. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

    2. navigables의 각 navigable에 대해:

      1. emulated network conditions가 null이면, session의 에뮬레이션된 네트워크 조건의 내비게이블 네트워크 조건에서 navigable을 제거합니다

      2. 그렇지 않으면, session의 에뮬레이션된 네트워크 조건의 내비게이블 네트워크 조건[navigable]을 emulated network conditions로 설정합니다.

  5. command parameters의 userContexts 필드가 존재하는 경우:

    1. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    2. user contexts의 각 user context에 대해:

      1. emulated network conditions가 null이면, session의 에뮬레이션된 네트워크 조건의 사용자 컨텍스트 네트워크 조건에서 user context를 제거합니다.

      2. 그렇지 않으면, session의 에뮬레이션된 네트워크 조건의 사용자 컨텍스트 네트워크 조건[user context]을 emulated network conditions로 설정합니다.

  6. command parameters가 포함하지 않고 "userContexts"를 command parameters가 포함하지 않으면 "context"도, session의 에뮬레이션된 네트워크 조건의 기본 네트워크 조건을 emulated network conditions로 설정합니다.

  7. 네트워크 조건을 적용합니다.

  8. 데이터 null과 함께 성공을 반환합니다.

7.4.2.6. emulation.setScreenSettingsOverride 명령

emulation.setScreenSettingsOverride 명령은 주어진 최상위 순회 가능 객체 또는 사용자 컨텍스트의 웹에 노출된 화면 영역 및 웹에 노출된 사용 가능한 화면 영역을 에뮬레이션한다.

명령 유형
emulation.SetScreenSettingsOverride = (
  method: "emulation.setScreenSettingsOverride",
  params: emulation.SetScreenSettingsOverrideParameters
)

emulation.ScreenArea = {
  width: js-uint,
  height: js-uint
}

emulation.SetScreenSettingsOverrideParameters = {
  screenArea: emulation.ScreenArea / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetScreenSettingsOverrideResult = EmptyResult

내비게이블 navigable이 주어졌을 때 WebDriver BiDi 에뮬레이션된 사용 가능 화면 영역 단계는 다음과 같습니다:

  1. top-level traversable을 navigable의 최상위 순회 가능 항목으로 둡니다.

  2. user context를 top-level traversable의 연결된 사용자 컨텍스트로 둡니다.

  3. 화면 설정 재정의가 top-level traversable을 포함하면, 화면 설정 재정의[top-level traversable]을 반환합니다.

  4. 화면 설정 재정의가 user context를 포함하면, 화면 설정 재정의[user context]을 반환합니다.

  5. null을 반환합니다

내비게이블 navigable이 주어졌을 때 WebDriver BiDi 에뮬레이션된 전체 화면 영역 단계는 다음과 같습니다:

  1. top-level traversable을 navigable의 최상위 순회 가능 항목으로 둡니다.

  2. user context를 top-level traversable의 연결된 사용자 컨텍스트로 둡니다.

  3. 화면 설정 재정의가 top-level traversable을 포함하면, 화면 설정 재정의[top-level traversable]을 반환합니다.

  4. 화면 설정 재정의가 user context를 포함하면, 화면 설정 재정의[user context]을 반환합니다.

  5. null을 반환합니다

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. command parameters가 포함하고 "userContexts"를 command parameters가 포함하면 "contexts"를, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. command parameters가 포함하지 않고 "userContexts"를 command parameters가 포함하지 않으면 "contexts"도, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  3. emulated screen area를 command parameters["screenArea"]로 둡니다.

  4. emulated screen area가 null이 아닌 경우:

    1. emulated screen area["x"]를 0으로 설정합니다.

    2. emulated screen area["y"]를 0으로 설정합니다.

  5. navigables를 집합으로 둡니다.

  6. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

    2. target을 내비게이블 화면 설정으로 둡니다.

    3. navigables의 각 navigable에 대해:

      1. emulated screen area가 null이면, target에서 navigable을 제거합니다.

      2. 그렇지 않으면, target[navigable]을 emulated screen area로 설정합니다.

    4. 데이터 null과 함께 성공을 반환합니다.

  7. 그렇지 않은 경우:

    1. command parameters의 userContexts 필드가 존재한다고 단언합니다.

    2. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    3. target을 사용자 컨텍스트 화면 설정으로 둡니다.

    4. user contexts의 각 user context에 대해:

      1. emulated screen area가 null이면, target에서 user context를 제거합니다.

      2. 그렇지 않으면, target[user context]을 emulated screen area로 설정합니다.

    5. 데이터 null과 함께 성공을 반환합니다.

7.4.2.7. emulation.setScreenOrientationOverride 명령

emulation.setScreenOrientationOverride 명령은 주어진 최상위 순회 가능 객체 또는 사용자 컨텍스트의 화면 방향을 에뮬레이션한다.

명령 유형
emulation.SetScreenOrientationOverride = (
  method: "emulation.setScreenOrientationOverride",
  params: emulation.SetScreenOrientationOverrideParameters
)

emulation.ScreenOrientationNatural = "portrait" / "landscape"
emulation.ScreenOrientationType = "portrait-primary" / "portrait-secondary" / "landscape-primary" / "landscape-secondary"

emulation.ScreenOrientation = {
  natural: emulation.ScreenOrientationNatural,
  type: emulation.ScreenOrientationType
}

emulation.SetScreenOrientationOverrideParameters = {
  screenOrientation: emulation.ScreenOrientation / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetScreenOrientationOverrideResult = EmptyResult

navigable 및 emulated screen orientation이 주어졌을 때 에뮬레이션된 화면 방향을 설정하려면:

이 알고리즘을 화면 방향 명세로 이동한다.

  1. emulated screen orientation이 null이면:

    1. navigable의 현재 방향 각도를 구현 정의 기본값으로 설정한다.

    2. navigable의 현재 방향 유형을 구현 정의 기본값으로 설정한다.

  2. 그렇지 않으면:

    1. emulated orientation type을 emulated screen orientation["type"]으로 둔다.

    2. emulated orientation angle을 화면 방향 값 목록에 정의된 대로, emulated screen orientation["natural"] 방향을 갖는 화면에서 emulated orientation type과 연결된 각도로 둔다.

    3. 현재 방향 각도를 emulated orientation angle로 설정한다.

    4. 현재 방향 유형을 emulated orientation type으로 설정한다.

  3. navigable의 활성 문서로 화면 방향 변경 단계를 실행한다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. 구현이 어떤 이유로든 주어진 command parameters로 화면 방향 매개변수를 조정할 수 없으면, 오류를 오류 코드 지원되지 않는 작업과 함께 반환합니다.

  2. command parameters가 포함하고 "userContexts"를 command parameters가 포함하면 "contexts"를, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  3. command parameters가 포함하지 않고 "userContexts"를 command parameters가 포함하지 않으면 "contexts"도, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  4. emulated screen orientation을 command parameters["screenOrientation"]으로 둡니다.

  5. navigables를 집합으로 둡니다.

  6. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

  7. 그렇지 않고, command parameters의 userContexts 필드가 존재하는 경우:

    1. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    2. user contexts의 각 user context에 대해:

      1. emulated screen orientation이 null이면, 제거합니다: 화면 방향 재정의 맵에서 user context를.

      2. 그렇지 않으면, 화면 방향 재정의 맵[user context]을 emulated screen orientation으로 설정합니다.

      3. 각각에 대해, 최상위 순회 가능 항목의 전체 목록에서 연결된 사용자 컨텍스트가 user context인 각 top-level traversable에 대해:

        1. top-level traversable을 navigables에 추가합니다.

  8. navigables의 각 navigable에 대해:

    1. user context를 navigable의 연결된 사용자 컨텍스트로 둡니다.

    2. emulated screen orientation이 null이고 화면 방향 재정의 맵이 user context를 포함하면, navigable과 화면 방향 재정의 맵[user context]으로 에뮬레이션된 화면 방향을 설정합니다.

    3. 그렇지 않으면, navigable과 emulated screen orientation으로 에뮬레이션된 화면 방향을 설정합니다.

  9. 데이터 null과 함께 성공을 반환합니다.

7.4.2.8. emulation.setUserAgentOverride 명령

emulation.setUserAgentOverride 명령은 주어진 최상위 순회 가능 객체, 사용자 컨텍스트 또는 전역적으로 User-Agent를 수정한다.

명령 유형
emulation.SetUserAgentOverride = (
  method: "emulation.setUserAgentOverride",
  params: emulation.SetUserAgentOverrideParameters
)

emulation.SetUserAgentOverrideParameters = {
  userAgent: text / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetUserAgentOverrideResult = EmptyResult
환경 설정 객체 environment settings가 주어졌을 때 WebDriver BiDi 에뮬레이션된 User-Agent 단계는 다음과 같다:
  1. related navigables를 environment settings으로 관련 순회 가능 객체 가져오기의 결과로 둔다.

  2. related navigables의 각 navigable에 대해:

    1. top-level navigable을 navigable의 최상위 순회 가능 객체로 둔다.

    2. user context를 top-level navigable의 연결된 사용자 컨텍스트로 둔다.

    3. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 사용자 에이전트의 순회 가능 객체 사용자 에이전트가 top-level navigable을 포함하면, session의 에뮬레이션된 사용자 에이전트의 순회 가능 객체 사용자 에이전트[top-level navigable]을 반환한다.

    4. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 사용자 에이전트의 사용자 컨텍스트 사용자 에이전트가 user context를 포함하면, session의 에뮬레이션된 사용자 에이전트의 사용자 컨텍스트 사용자 에이전트[user context]를 반환한다.

  3. 활성 BiDi 세션의 각 session에 대해:

    1. default emulated user agent를 session의 에뮬레이션된 사용자 에이전트의 기본 사용자 에이전트로 둔다.

    2. default emulated user agent가 null이 아니면, default emulated user agent를 반환한다.

  4. null을 반환한다.

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. command parameters가 포함하고 "userContexts"를 command parameters가 포함하면 "contexts"를, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. emulated user agent를 command parameters["userAgent"]로 둡니다.

  3. command parameters가 포함하는 경우 "contexts":

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

    2. navigables의 각 navigable에 대해:

      1. emulated user agent가 null이면, session의 에뮬레이션된 사용자 에이전트의 내비게이블 사용자 에이전트에서 navigable을 제거합니다.

      2. 그렇지 않으면, session의 에뮬레이션된 사용자 에이전트의 내비게이블 사용자 에이전트[navigable]를 emulated user agent로 설정합니다.

    3. 데이터 null과 함께 성공을 반환합니다.

  4. command parameters가 포함하는 경우 "userContexts":

    1. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    2. user contexts의 각 user context에 대해:

      1. emulated user agent가 null이면, session의 에뮬레이션된 사용자 에이전트의 사용자 컨텍스트 사용자 에이전트에서 user context를 제거합니다.

      2. 그렇지 않으면, session의 에뮬레이션된 사용자 에이전트의 사용자 컨텍스트 사용자 에이전트[user context]를 emulated user agent로 설정합니다.

    3. 데이터 null과 함께 성공을 반환합니다.

  5. session의 에뮬레이션된 사용자 에이전트의 기본 사용자 에이전트를 emulated user agent로 설정합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.4.2.9. emulation.setViewportMetaOverride 명령

emulation.setViewportMetaOverride 명령은 브라우저가 <meta name=viewport> 태그를 준수하는지 여부를 수정한다.

명령 유형
emulation.SetViewportMetaOverride = (
  method: "emulation.setViewportMetaOverride",
  params: emulation.SetViewportMetaOverrideParameters
)

emulation.SetViewportMetaOverrideParameters = {
  viewportMeta: true / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetViewportMetaOverrideResult = EmptyResult

원격 엔드에는 viewport 메타 재정의 구성이 있으며, 이는 WebDriver 구성으로, 연결된 유형은 불리언이다.

Document document가 주어졌을 때 WebDriver BiDi viewport 메타 상태 단계는 다음과 같다:

  1. navigable을 document의 노드 순회 가능 객체로 둔다.

  2. viewport meta override를 navigable에 대한 viewport 메타 재정의 구성의 WebDriver 구성 값 가져오기 결과로 둔다.

  3. viewport meta override가 설정되지 않음이면, null을 반환한다.

  4. viewport meta override를 반환한다.

command parameters가 주어졌을 때 원격 엔드 단계는 다음과 같다:

  1. viewport meta override를 command parameters["viewportMeta"]로 둔다.

  2. viewport meta override가 null이면, viewport meta override를 설정되지 않음으로 설정한다.

  3. affected navigables를 command parameters에 대해 viewport 메타 재정의 구성 viewport meta override를 WebDriver 구성 저장하도록 시도한 결과로 둔다.

  4. affected navigables의 각 navigable에 대해, 지정된 navigable에 현재 로드된 문서에 대해 미디어 쿼리를 평가하고 변경 사항을 보고한다.

  5. 데이터 null과 함께 성공을 반환한다.

7.4.2.10. emulation.setScriptingEnabled 명령

emulation.setScriptingEnabled 명령은 웹 페이지에서 JavaScript가 비활성화된 상태를 에뮬레이션한다.

명령 유형
emulation.SetScriptingEnabled = (
  method: "emulation.setScriptingEnabled",
  params: emulation.SetScriptingEnabledParameters
)

emulation.SetScriptingEnabledParameters = {
  enabled: false / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetScriptingEnabledResult = EmptyResult

참고: 비활성화된 JavaScript의 에뮬레이션만 지원된다.

환경 설정 객체 settings가 주어졌을 때 WebDriver BiDi 스크립팅이 활성화되어 있음 단계는 다음과 같다:
  1. navigable을 settings의 관련 전역 객체의 연결된 Document의 노드 순회 가능 객체로 둔다.

  2. top-level traversable을 navigable의 최상위 순회 가능 객체로 둔다.

  3. 스크립팅 활성화 재정의 맵이 top-level traversable을 포함하면, 스크립팅 활성화 재정의 맵[top-level traversable]을 반환한다.

  4. user context를 top-level traversable의 연결된 사용자 컨텍스트로 둔다.

  5. 스크립팅 활성화 재정의 맵이 user context를 포함하면, 스크립팅 활성화 재정의 맵[user context]을 반환한다.

  6. true를 반환한다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. command parameters가 다음을 포함하고 "userContexts" command parameters가 다음을 포함하면 "contexts", 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. command parameters가 다음을 포함하지 않고 "userContexts" command parameters가 다음을 포함하지 않으면 "contexts", 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  3. emulated scripting enabled status를 command parameters["enabled"]로 둡니다.

  4. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

    2. navigables의 각 navigable에 대해:

      1. emulated scripting enabled status가 null이면, 제거합니다: 스크립팅 활성화 재정의 맵에서 navigable을.

      2. 그렇지 않으면, 설정합니다: 스크립팅 활성화 재정의 맵[navigable]을 emulated scripting enabled status로.

  5. command parameters의 userContexts 필드가 존재하는 경우:

    1. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    2. user contexts의 각 user context에 대해:

      1. emulated scripting enabled status가 null이면, 제거합니다: 스크립팅 활성화 재정의 맵에서 user context를.

      2. 그렇지 않으면 설정합니다: 스크립팅 활성화 재정의 맵[user context]을 emulated scripting enabled status로.

  6. 데이터 null과 함께 성공을 반환합니다.

7.4.2.11. emulation.setScrollbarTypeOverride 명령

emulation.setScrollbarTypeOverride 명령은 주어진 최상위 순회 가능 객체, 사용자 컨텍스트 또는 전역적으로 스크롤바 유형을 수정한다.

명령 유형
emulation.SetScrollbarTypeOverride = (
  method: "emulation.setScrollbarTypeOverride",
  params: emulation.SetScrollbarTypeOverrideParameters
)

emulation.SetScrollbarTypeOverrideParameters = {
  scrollbarType: "classic" / "overlay" / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetScrollbarTypeOverrideResult = EmptyResult

원격 엔드에는 스크롤바 유형 재정의 구성이 있으며, 이는 WebDriver 구성으로, 연결된 유형은 문자열이다.

순회 가능 객체 navigable에 대해 스크롤바 유형 재정의를 업데이트하려면:
  1. scrollbar type override를 navigable에 대한 스크롤바 유형 재정의 구성의 WebDriver 구성 값 가져오기 결과로 둔다.

  2. 단언: scrollbar type override는 "classic", "overlay" 또는 설정되지 않음이다.

  3. scrollbar type override가 "classic"이면, navigable의 활성 문서가 클래식 스크롤바를 사용하도록 구현 정의 단계를 실행하고 반환한다.

  4. scrollbar type override가 "overlay"이면, navigable의 활성 문서가 오버레이 스크롤바를 사용하도록 구현 정의 단계를 실행하고 반환한다.

  5. 단언: scrollbar type override는 설정되지 않음이다.

  6. navigable의 활성 문서가 구현 정의 기본 스크롤바 유형을 사용하도록 구현 정의 단계를 실행한다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. scrollbar type override를 command parameters["scrollbarType"]로 둡니다.

  2. scrollbar type override가 null이면, scrollbar type override를 설정되지 않음으로 설정합니다.

  3. 구현이 scrollbar type override 설정을 지원하지 않으면, 오류를 오류 코드 지원되지 않는 작업과 함께 반환합니다.

  4. affected navigables를 command parameters에 대해 스크롤바 유형 재정의 구성 scrollbar type override를 시도하여 WebDriver 구성을 저장한 결과로 둡니다.

  5. affected navigables의 각 navigable에 대해:

    1. navigable에 대해 스크롤바 유형 재정의를 업데이트합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.4.2.12. emulation.setTextLayoutModeOverride 명령

emulation.setTextLayoutModeOverride 명령은 지정된 최상위 순회 가능 항목, 사용자 컨텍스트 또는 전역적으로 텍스트 레이아웃 모드를 수정합니다.

명령 유형
emulation.SetTextLayoutModeOverride = (
  method: "emulation.setTextLayoutModeOverride",
  params: emulation.SetTextLayoutModeOverrideParameters
)

emulation.SetTextLayoutModeOverrideParameters = {
  textLayoutMode: emulation.TextLayoutMode / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.TextLayoutMode = "mobile"
반환 유형
emulation.SetTextLayoutModeOverrideResult = EmptyResult

원격 끝에는 텍스트 레이아웃 모드 재정의 구성이 있으며, 이는 WebDriver 구성이고 연결된 유형은 문자열입니다.

내비게이블 navigable에 대해 텍스트 레이아웃 모드 재정의를 업데이트하려면:

참고: 텍스트 레이아웃 모드 "mobile"은 텍스트 자동 크기 조정(글꼴 확대)을 활성화하며, 이는 주로 모바일 기기에서 텍스트 블록을 작은 뷰포트에 맞출 때 가독성을 높이기 위해 사용되는 알고리즘입니다. 이를 통해 사용자가 확대하지 않아도 콘텐츠를 읽을 수 있습니다. 이 동작은 흔히 text-size-adjust CSS 속성을 통해 제어됩니다. [CSS-SIZE-ADJUST-1]을 참조하십시오.

  1. text layout mode override를 navigable에 대한 텍스트 레이아웃 모드 재정의 구성의 WebDriver 구성 값 가져오기 결과로 둡니다.

  2. 단언: text layout mode override는 "mobile"이거나 설정되지 않음입니다.

  3. text layout mode override가 "mobile"이면, 구현 정의 단계를 실행하여 navigable의 활성 문서가 "mobile" 텍스트 레이아웃 모드를 사용하도록 합니다.

  4. 그렇지 않으면, 구현 정의 단계를 실행하여 navigable의 활성 문서가 구현 정의 기본 텍스트 레이아웃 모드를 사용하도록 합니다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. text layout mode override를 command parameters["textLayoutMode"]로 둡니다.

  2. text layout mode override가 null이면, text layout mode override를 설정되지 않음으로 설정합니다.

  3. text layout mode override가 설정되지 않음이 아니고 구현이 텍스트 레이아웃 모드 재정의 설정을 지원하지 않으면, 오류를 오류 코드 지원되지 않는 작업과 함께 반환합니다.

  4. affected navigables를 command parameters에 대해 텍스트 레이아웃 모드 재정의 구성 text layout mode override를 시도하여 WebDriver 구성을 저장한 결과로 둡니다.

  5. affected navigables의 각 navigable에 대해:

    1. navigable에 대해 텍스트 레이아웃 모드 재정의를 업데이트합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.4.2.13. emulation.setTimezoneOverride 명령

emulation.setTimezoneOverride 명령은 지정된 최상위 순회 가능 항목 또는 사용자 컨텍스트의 시간대를 수정합니다.

명령 유형
emulation.SetTimezoneOverride = (
  method: "emulation.setTimezoneOverride",
  params: emulation.SetTimezoneOverrideParameters
)

emulation.SetTimezoneOverrideParameters = {
  timezone: text / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetTimezoneOverrideResult = EmptyResult
SystemTimeZoneIdentifier 알고리즘은 구현 정의입니다. WebDriver-BiDi 원격 끝에는 다음 단계를 실행하는 구현이 있어야 합니다:
  1. emulated timezone을 null로 둡니다.

  2. realm을 현재 Realm 레코드로 둡니다.

  3. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둡니다.

  4. related navigables를 environment settings가 주어졌을 때 관련 내비게이블 가져오기의 결과로 둡니다.

  5. related navigables의 각 navigable에 대해:

    1. top-level traversable을 navigable의 최상위 순회 가능 항목으로 둡니다.

    2. user context를 top-level traversable의 연결된 사용자 컨텍스트로 둡니다.

    3. 시간대 재정의 맵이 top-level traversable을 포함하면, emulated timezone을 시간대 재정의 맵[top-level traversable]으로 설정합니다.

    4. 그렇지 않고, 시간대 재정의 맵이 user context를 포함하면, emulated timezone을 시간대 재정의 맵[user context]으로 설정합니다.

  6. emulated timezone이 null이 아니면, emulated timezone을 반환합니다.

  7. SystemTimeZoneIdentifier 명세의 요구 사항에 따른 구현 정의 단계의 결과를 반환합니다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. command parameters가 포함하고 "userContexts" command parameters가 포함하면 "contexts", 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. command parameters가 포함하지 않고 "userContexts" command parameters가 포함하지 않으면 "contexts", 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  3. emulated timezone을 command parameters["timezone"]으로 둡니다.

  4. emulated timezone이 null이 아니고 IsTimeZoneOffsetString(emulated timezone)이 false를 반환하며 AvailableNamedTimeZoneIdentifiers가 emulated timezone을 포함하지 않으면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  5. navigables를 집합으로 둡니다.

  6. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

  7. 그렇지 않은 경우:

    1. command parameters의 userContexts 필드가 존재한다고 단언합니다.

    2. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    3. user contexts의 각 user context에 대해:

      1. emulated timezone이 null이면, 제거합니다: 시간대 재정의 맵에서 user context를.

      2. 그렇지 않으면, 설정합니다: 시간대 재정의 맵[user context]을 emulated timezone으로.

      3. 각각에 대해, 최상위 순회 가능 항목의 전체 목록에서 연결된 사용자 컨텍스트가 user context인 각 top-level traversable에 대해:

        1. top-level traversable을 navigables에 추가합니다.

  8. navigables의 각 navigable에 대해:

    1. emulated timezone이 null이면, 제거합니다: 시간대 재정의 맵에서 navigable을.

    2. 그렇지 않으면, 설정합니다: 시간대 재정의 맵[navigable]을 emulated timezone으로.

  9. 데이터 null과 함께 성공을 반환합니다.

7.4.2.14. emulation.setTouchOverride 명령

emulation.setTouchOverride 명령은 웹 페이지에서 활성화된 터치 입력을 에뮬레이션합니다.

명령 유형
emulation.SetTouchOverride = (
  method: "emulation.setTouchOverride",
  params: emulation.SetTouchOverrideParameters
)

emulation.SetTouchOverrideParameters = {
  maxTouchPoints: (js-uint .ge 1) / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 유형
emulation.SetTouchOverrideResult = EmptyResult
환경 설정 객체 environment settings가 주어졌을 때 WebDriver BiDi 에뮬레이션된 최대 터치 포인트 수 단계는 다음과 같습니다:
  1. related navigables를 environment settings로 관련 내비게이블 가져오기의 결과로 둡니다.

  2. related navigables의 각 navigable에 대해:

    1. top-level navigable을 navigable의 최상위 순회 가능 항목으로 둡니다.

    2. user context를 top-level navigable의 연결된 사용자 컨텍스트로 둡니다.

    3. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 maxTouchPoints의 내비게이블이 top-level navigable을 포함하면, session의 에뮬레이션된 maxTouchPoints의 내비게이블[top-level navigable]을 반환합니다.

    4. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 maxTouchPoints의 사용자 컨텍스트가 user context를 포함하면, session의 에뮬레이션된 maxTouchPoints의 사용자 컨텍스트[user context]를 반환합니다.

  3. 활성 BiDi 세션의 각 session에 대해:

    1. emulated maxTouchPoints를 session의 에뮬레이션된 maxTouchPoints의 기본값으로 둡니다.

    2. emulated maxTouchPoints가 null이 아니면, emulated maxTouchPoints를 반환합니다.

  4. null을 반환합니다.

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

참고: 레거시 레거시 터치 이벤트 API 노출이 있으며, 일부 기존 웹 콘텐츠에서는 여전히 사용자 에이전트가 터치가 활성화된 "모바일" 기기라는 신호로 이를 사용할 수 있습니다. API가 레거시이더라도, 사용자 에이전트는 구현 정의 단계를 실행하여 에뮬레이션된 maxTouchPoints 상태를 레거시 터치 이벤트 API 노출에서 반영할 수 있습니다.

  1. command parameters가 포함하고 "userContexts"를, command parameters가 포함하면 "contexts"를, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. maxTouchPoints를 command parameters["maxTouchPoints"]로 둡니다.

  3. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

    2. navigables의 각 navigable에 대해:

      1. maxTouchPoints가 null이면, session의 에뮬레이션된 maxTouchPoints의 내비게이블에서 navigable을 제거합니다.

      2. 그렇지 않으면, session의 에뮬레이션된 maxTouchPoints의 내비게이블[navigable]을 maxTouchPoints로 설정합니다.

    3. 데이터 null과 함께 성공을 반환합니다.

  4. command parameters의 userContexts 필드가 존재하는 경우:

    1. user contexts를 command parameters["userContexts"]로 시도하여 유효한 사용자 컨텍스트를 가져온 결과로 둡니다.

    2. user contexts의 각 user context에 대해:

      1. maxTouchPoints가 null이면, session의 에뮬레이션된 maxTouchPoints의 사용자 컨텍스트에서 user context를 제거합니다.

      2. 그렇지 않으면 session의 에뮬레이션된 maxTouchPoints의 사용자 컨텍스트[user context]를 maxTouchPoints로 설정합니다.

    3. 데이터 null과 함께 성공을 반환합니다.

  5. session의 에뮬레이션된 maxTouchPoints의 기본값을 maxTouchPoints로 설정합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.5. network 모듈

network 모듈은 네트워크 요청과 관련된 명령 및 이벤트를 포함한다.

7.5.1. 정의

원격 엔드 정의

NetworkCommand = (
  network.AddDataCollector //
  network.AddIntercept //
  network.ContinueRequest //
  network.ContinueResponse //
  network.ContinueWithAuth //
  network.DisownData //
  network.FailRequest //
  network.GetData //
  network.ProvideResponse //
  network.RemoveDataCollector //
  network.RemoveIntercept //
  network.SetCacheBehavior //
  network.SetExtraHeaders
)

로컬 엔드 정의

NetworkResult = (
  network.AddDataCollectorResult /
  network.AddInterceptResult /
  network.ContinueRequestResult /
  network.ContinueResponseResult /
  network.ContinueWithAuthResult /
  network.DisownDataResult /
  network.FailRequestResult /
  network.GetDataResult /
  network.ProvideResponseResult /
  network.RemoveDataCollectorResult /
  network.RemoveInterceptResult /
  network.SetCacheBehaviorResult /
  network.SetExtraHeadersResult
)

NetworkEvent = (
    network.AuthRequired //
    network.BeforeRequestSent //
    network.FetchError //
    network.ResponseCompleted //
    network.ResponseStarted
)

원격 끝에는 요청 전송 전 맵이 있으며, 이는 처음에는 빈 맵입니다. 이는 network.beforeRequestSent 이벤트가 이미 전송된 네트워크 이벤트를 추적하는 데 사용됩니다.

원격 끝에는 문자열인 기본 캐시 동작이 있습니다. 이는 처음에는 "default"입니다.

원격 끝에는 내비게이블 캐시 동작 맵이 있으며, 이는 최상위 순회 가능 항목과 캐시 동작을 나타내는 문자열 사이의 약한 맵입니다. 이는 처음에는 비어 있습니다.

BiDi 세션에는 추가 헤더가 있으며, 이는 기본 헤더라는 이름의 항목을 가진 구조체입니다. 이 항목은 헤더 목록이며(처음에는 빈 헤더 목록으로 설정됩니다), 또한 사용자 컨텍스트 헤더라는 이름의 항목이 있으며, 이는 사용자 컨텍스트와 헤더 목록 사이의 약한 맵이고, 또 내비게이블 헤더라는 이름의 항목이 있으며, 이는 내비게이블과 헤더 목록 사이의 약한 맵입니다.

7.5.2. 네트워크 데이터 수집

네트워크 데이터는 다음을 가진 구조체이다:

수집기는 다음을 가진 구조체이다:

참고: 최대 인코딩 항목 크기는 항목별 제한(응답 또는 요청)을 정의하며, 특정 수집기가 수집하는 크기를 제한하지 않는다. 수집된 모든 리소스의 총 크기는 최대 총 수집 크기로 제한된다.

BiDi 세션에는 네트워크 수집기가 있으며, 이는 network.Collector 와 수집기 간의 맵이다. 초기에는 비어 있다.

원격 엔드에는 수집된 네트워크 데이터가 있으며, 이는 네트워크 데이터의 목록이다. 초기에는 비어 있다.

원격 엔드에는 최대 총 수집 크기가 있으며, 이는 수집된 네트워크 데이터에서 네트워크 데이터를 수집하기 위해 할당된 크기를 나타내는 js-uint이다. 그 값은 구현 정의이다.

참고: 이는 구현이 리소스 사용 제한을 설정할 수 있게 한다. 사용자가 웹페이지에서 사용되는 이미지 및 폰트와 같이, 브라우저가 완전히 디코딩하고 처리한 데이터의 수집에 의존할 수 있을 만큼 그 제한은 충분히 클 것으로 기대된다.

request가 주어졌을 때 request에 대한 navigable 가져오기를 하려면:
  1. navigable을 null로 둔다.

  2. request의 client가 환경 설정 객체이면:

    1. environment settings를 request의 client로 둔다

    2. 그 활성 window가 environment settings의 전역 객체인 navigable이 있으면, navigable을 그 navigable로 설정한다.

  3. navigable을 반환한다.

collector 및 navigable이 주어졌을 때 navigable에 대해 collector 일치를 하려면:
  1. collector의 contexts가 비어 있지 않으면:

    1. collector의 contexts가 navigable의 navigable id를 포함하면 true를 반환한다.

    2. 그렇지 않으면, false를 반환한다.

  2. collector의 user contexts가 비어 있지 않으면:

    1. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

    2. collector의 user contexts가 user context의 사용자 컨텍스트 id를 포함하면 true를 반환한다.

    3. 그렇지 않으면, false를 반환한다.

  3. true를 반환한다.

request request가 주어졌을 때 WebDriver BiDi 네트워크 request body 복제 단계는 다음과 같다:
  1. request의 body가 null이면, 반환한다.

  2. 활성 BiDi 세션 안의 각 session에 대해:

    1. session의 network collectors가 비어 있지 않으면:

      1. collected data를 네트워크 데이터로 두고, bytes는 null로 설정하고, 복제된 body는 request의 body의 clone으로 설정하고, collectors는 빈 목록으로 설정하고, pending은 true로 설정하고, request는 request의 request id로 설정하고, size는 null로 설정하고, type은 "request"로 설정한다.

      2. collected data를 수집된 네트워크 데이터에 추가한다.

      3. 반환한다.

request 및 response body가 주어졌을 때 WebDriver BiDi 네트워크 response body 복제 단계는 다음과 같다:
  1. response body가 null이면, 반환한다.

  2. 활성 BiDi 세션 안의 각 session에 대해:

    1. session의 network collectors가 비어 있지 않으면:

      1. collected data를 네트워크 데이터로 두고, bytes는 null로 설정하고, 복제된 body는 response body의 clone으로 설정하고, collectors는 빈 목록으로 설정하고, pending은 true로 설정하고, request는 request의 request id로 설정하고, size는 null로 설정하고, type은 "response"로 설정한다.

      2. collected data를 수집된 네트워크 데이터에 추가한다.

      3. 반환한다.

request id 및 data type이 주어졌을 때 수집된 데이터 가져오기를 하려면.
  1. 수집된 네트워크 데이터의 각 collected data에 대해:

    1. collected data의 request가 request id이고 collected data의 type이 data type이면, collected data를 반환한다.

  2. null을 반환한다.

request가 주어졌을 때 네트워크 response body 수집 중단 여부 처리를 하려면:
  1. collected data를 request의 request id 및 "response"로 수집된 데이터 가져오기를 수행한 결과로 둔다.

  2. collected data가 null이면, 반환한다.

  3. collected data의 pending을 false로 설정한다.

  4. "network data collected" 및 (request의 request id, "response")로 재개한다.

request가 주어졌을 때 네트워크 request body 수집 여부 처리를 하려면:
  1. collected data를 request의 request id 및 "request"로 수집된 데이터 가져오기를 수행한 결과로 둔다.

  2. collected data가 null이면, 반환한다.

    참고: 이는 요청이 생성될 때 collector가 설정되어 있지 않고 WebDriver BiDi 네트워크 request body 복제가 대응하는 body를 복제하지 않은 경우 발생할 수 있다. 또는 처음부터 body가 null인 경우에도 발생할 수 있다.

  3. request, collected data, null 및 "request"로 네트워크 데이터 수집 여부 처리를 한다.

request 및 response가 주어졌을 때 네트워크 response body 수집 여부 처리를 하려면:
  1. response의 status가 redirect status이면, 반환한다.

    참고: 리디렉션의 경우 최종 응답 body만 저장된다.

  2. collected data를 request의 request id 및 "response"로 수집된 데이터 가져오기를 수행한 결과로 둔다.

  3. collected data가 null이면, 반환한다.

    참고: 이는 응답이 생성될 때 collector가 설정되어 있지 않고 WebDriver BiDi 네트워크 response body 복제가 대응하는 body를 복제하지 않은 경우 발생할 수 있다. 또는 처음부터 body가 null인 경우에도 발생할 수 있다.

  4. size를 response의 response body info의 encoded size로 둔다.

    참고: fetch 스트림에서 검색된 bytes가 디코딩된 데이터에 해당한다는 사실과, 크기 제한을 계산하기 위해 인코딩된(네트워크) 크기가 사용된다는 사실 사이에는 불일치가 있다. 구현은 getData에서 클라이언트에 반환되는 데이터가 디코딩된 데이터와 동일하기만 하다면, 디코딩된 데이터를 저장하는 것보다 더 적은 크기를 사용하는 저장 모델을 사용할 수 있다. 저장소와 성능 사이의 잠재적 절충은 구현에 달려 있다.

  5. request, collected data, size 및 "response"로 네트워크 데이터 수집 여부 처리를 한다.

request request, 네트워크 데이터 collected data, js-uint size 및 network.DataType data type이 주어졌을 때 네트워크 데이터 수집 여부 처리를 하려면:
  1. collected data의 pending을 false로 설정한다.

  2. navigable을 request로 request에 대한 navigable 가져오기를 수행한 결과로 둔다.

  3. navigable이 null이면:

    1. collected data를 수집된 네트워크 데이터에서 제거한다.

    2. "network data collected" 및 (request의 request id, data type)로 재개한다.

    3. 반환한다.

    이는 navigable과 관련되지 않은 데이터 수집을 방지한다. collector 구성을 확인하려면 여전히 navigable을 검색해야 하지만, 여기서 null도 허용할 수 있다.

  4. top-level navigable을 navigable의 최상위 traversable로 둔다.

  5. collectors를 빈 목록으로 둔다.

  6. 활성 BiDi 세션 안의 각 session에 대해:

    1. session의 network collectors 안의 각 collector에 대해:

      1. collector의 data types가 data type을 포함하고, collector 및 top-level navigable로 navigable에 대해 collector 일치를 수행한 결과가 true이면:

        1. collector를 collectors에 추가한다.

  7. collectors가 비어 있으면:

    1. collected data를 수집된 네트워크 데이터에서 제거한다.

    2. "network data collected" 및 (request의 request id, data type)로 재개한다.

    3. 반환한다.

  8. bytes를 null로 둔다.

  9. nullOrBytes가 주어졌을 때의 processBody를 이 단계로 둔다:

    1. nullOrBytes가 null이 아니면:

      1. bytes를 nullOrBytes로 프로토콜 bytes 직렬화를 수행한 결과로 설정한다.

      2. size가 null이면, size를 bytes의 길이로 설정한다.

  10. processBodyError를 이 단계로 둔다: 아무것도 하지 않는다.

  11. processBody 및 processBodyError가 주어졌을 때 collected data의 복제된 body를 완전히 읽는다.

  12. bytes가 null이 아니면:

    1. collectors 안의 각 collector에 대해:

      1. size가 collector의 max encoded item size보다 작거나 같으면, collector의 collector를 collected data의 collectors에 추가한다.

    2. collected data의 collectors가 비어 있지 않으면:

      1. size가 주어졌을 때 데이터 기록을 위한 크기 할당을 한다.

      2. collected data의 bytes를 bytes로 설정한다.

      3. collected data의 size를 size로 설정한다.

    3. 그렇지 않으면, collected data를 수집된 네트워크 데이터에서 제거한다.

  13. "network data collected" 및 (request의 request id, data type)로 재개한다.

size가 주어졌을 때 데이터 기록을 위한 크기 할당을 하려면:
  1. available size를 max total collected size로 둔다.

  2. already collected data를 빈 목록으로 둔다.

  3. 수집된 네트워크 데이터 안의 각 collected data에 대해:

    1. collected data의 bytes가 null이 아니면:

      1. available size를 collected data의 size만큼 감소시킨다.

      2. collected data를 already collected data에 추가한다

  4. size가 available size보다 크면:

    1. already collected data 안의 각 collected data에 대해:

      1. available size를 collected data의 size만큼 증가시킨다.

      2. collected data의 bytes 필드를 null로 설정한다.

      3. collected data의 size 필드를 null로 설정한다.

      4. available size가 size보다 크거나 같으면, 반환한다.

collected data 및 collector id가 주어졌을 때 데이터에서 collector 제거를 하려면:
  1. collected data의 collectors가 collector id를 포함하면:

    1. collector id를 collected data의 collectors에서 제거한다.

    2. collected data의 collectors가 비어 있으면:

      1. collected data를 수집된 네트워크 데이터에서 제거한다.

7.5.3. 네트워크 인터셉트

네트워크 인터셉트 는 원격 엔드가 네트워크 요청과 응답을 가로채고 수정할 수 있도록 하는 메커니즘이다.

BiDi 세션에는 인터셉트 맵이 있으며, 이는 인터셉트 id와 활성 네트워크 인터셉트의 속성을 정의하는 url patterns, phases, contexts 필드를 가진 구조체 간의 맵이다. 초기에는 비어 있다.

BiDi 세션에는 차단된 요청 맵이 있으며, 현재 적극적으로 차단되고 있는 요청을 추적하는 데 사용된다. 이는 요청 id 와 request, phase, response 필드를 가진 구조체 간의 맵이다. 초기에는 비어 있다.

session, event, request, 및 navigable id가 주어졌을 때 네트워크 인터셉트 가져오기를 수행하려면:

  1. session intercepts를 session의 인터셉트 맵으로 둔다.

  2. intercepts를 빈 리스트로 둔다.

  3. 처음으로 일치하는 조건 아래의 단계를 실행한다:

    event가 "network.beforeRequestSent"인 경우
    phase를 "beforeRequestSent"로 설정한다.
    event가 "network.responseStarted"인 경우
    phase를 "responseStarted"로 설정한다.
    event가 "network.authRequired"인 경우
    phase를 "authRequired"로 설정한다.
    event가 "network.responseCompleted"인 경우
    intercepts를 반환한다.
  4. url을 request의 URL로 URL 직렬화기를 실행한 결과로 둔다.

  5. session intercepts의 각 intercept id → intercept에 대해:

    1. intercept의 contexts가 null이 아니면:

      1. intercept의 contexts가 navigable id를 포함하지 않으면:

        1. 계속한다.

    2. intercept의 phases가 phase를 포함하면:

      1. url patterns를 intercept의 url patterns로 둔다.

      2. url patterns가 비어 있으면:

        1. intercept id를 intercepts에 추가한다.

        2. 계속한다.

      3. url patterns 안의 각 url pattern에 대해:

        1. url pattern 및 url로 URL 패턴 일치를 수행한 결과가 true이면:

          1. intercept id를 intercepts에 추가한다.

          2. 중단한다.

  6. intercepts를 반환한다.

session, command 및 command parameters가 주어졌을 때 응답을 업데이트하려면:
  1. blocked requests를 session의 차단된 요청 맵으로 둡니다.

  2. request id를 command parameters["request"]로 둡니다.

  3. blocked requests가 request id를 포함하지 않으면 오류를 오류 코드 해당 요청 없음과 함께 반환합니다.

  4. (request, phase, response)를 blocked requests[request id]로 둡니다.

  5. phase가 "beforeRequestSent"이고 command가 "continueResponse"이면, 오류를 오류 코드 "invalid argument"와 함께 반환합니다.

    TODO: 다른 오류를 고려합니다

  6. response가 null인 경우:

    1. 단언: phase는 "beforeRequestSent"입니다.

    2. response를 새로운 응답으로 설정합니다.

  7. command parameters가 "statusCode"를 포함하는 경우:

    1. responses의 상태를 command parameters["statusCode"]로 설정합니다.

  8. command parameters가 "reasonPhrase"를 포함하는 경우:

    1. responses의 상태 메시지를 command parameters["reasonPhrase"]로 UTF-8 인코딩한 값으로 설정합니다.

  9. command parameters가 "headers"를 포함하는 경우:

    1. headers를 command parameters["headers"]로 시도하여 헤더 목록을 생성한 결과로 둡니다.

    2. response의 헤더 목록을 headers로 설정합니다.

  10. command parameters가 "cookies"를 포함하는 경우:

    1. command parameters가 "headers"를 포함하면, headers를 response의 헤더 목록으로 둡니다.

      그렇지 않으면:

      1. headers를 빈 헤더 목록으로 둡니다.

      2. response의 헤더 목록에 있는 각 header에 대해:

        1. name을 header의 이름으로 둡니다.

        2. name을 바이트 소문자화한 값이 `set-cookie`가 아닌 경우:

          1. header를 headers에 추가합니다

    2. command parameters["cookies"]의 각 cookie에 대해:

      1. header value를 cookie로 set-cookie 헤더를 직렬화한 값으로 둡니다.

      2. (`Set-Cookie`, header value)를 headers에 추가합니다.

      3. response의 헤더 목록을 headers로 설정합니다.

  11. command parameters가 "credentials"를 포함하는 경우:

    여기에는 인증을 취소할 방법이 없습니다.

    1. credentials를 command parameters["credentials"]로 둡니다.

    2. 단언: credentials["type"]은 "password"입니다.

    3. response의 인증 자격 증명을 (credentials["username"], credentials["password"])로 설정합니다

  12. response를 반환합니다

7.5.4. 타입

7.5.4.1. network.AuthChallenge 타입
network.AuthChallenge = {
  scheme: text,
  realm: text,
}

response가 주어졌을 때 challenges 추출을 하려면:

realm 이외의 매개변수를 포함해야 하는가?

  1. response의 status가 401이면 header name을 `WWW-Authenticate`로 둔다. 그렇지 않고 response의 status가 407이면 header name을 `Proxy-Authenticate`로 둔다. 그렇지 않으면 null을 반환한다.

  2. challenges를 새 목록으로 둔다.

  3. response의 header list 안의 각 (name, value)에 대해:

    Fetch에서처럼, 이것이 여러 header, 파싱 문제 등을 처리하는 올바른 방식인지 명확하지 않다.

    1. name이 header name에 대해 byte-case-insensitive 일치이면:

      1. header challenges를 value를 파싱하여, 각각 scheme과 매개변수 목록으로 이루어진 challenges의 목록으로 만든 결과로 둔다. 각 매개변수는 [RFC9110]의 규칙에 따라 튜플 (name, value)이다.

      2. header challenges 안의 각 header challenge에 대해:

        1. scheme을 header challenge의 scheme으로 둔다.

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

        3. header challenge의 parameters 안의 각 (param name, param value)에 대해:

          1. param name이 `realm`과 같으면 realm을 param value를 UTF-8 decode한 결과로 둔다.

        4. challenge를 network.AuthChallenge production과 일치하는 새 맵으로 두고, scheme 필드는 scheme으로 설정하고 realm 필드는 realm으로 설정한다.

      3. challenge를 challenges에 추가한다.

  4. challenges를 반환한다.

7.5.4.2. network.AuthCredentials 타입
network.AuthCredentials = {
  type: "password",
  username: text,
  password: text,
}

network.AuthCredentials 타입은 authorization credentials 요청에 대한 응답을 나타낸다.

7.5.4.3. network.BaseParameters 타입
network.BaseParameters = (
    context: browsingContext.BrowsingContext / null,
    isBlocked: bool,
    navigation: browsingContext.Navigation / null,
    redirectCount: js-uint,
    request: network.RequestData,
    timestamp: js-uint,
    ? userContext: browser.UserContext / null,
    ? intercepts: [+network.Intercept]
)

network.BaseParameters 타입은 모든 네트워크 이벤트에 공통인 데이터를 나타내는 추상 타입이다.

context에 더해 요청을 시작한 document 노드의 `sharedId`를 포함하는 것을 고려한다.

session, event, 및 request가 주어졌을 때 네트워크 이벤트 처리를 하려면:
  1. request data를 request로 request data 가져오기를 수행한 결과로 둔다.

  2. navigation을 request의 navigation id로 둔다.

  3. navigable id를 null로 둔다.

  4. top-level navigable id를 null로 둔다.

  5. user context id를 null로 둔다.

  6. request의 client가 환경 설정 객체이면:

    1. environment settings를 request의 client로 둔다.

    2. 그 활성 window가 environment settings의 전역 객체인 navigable이 있으면, navigable id를 그 navigable의 navigable id로 설정하고, top-level navigable id를 그 navigable의 최상위 traversable의 navigable id로 설정하고, user context id를 그 navigable의 연관된 사용자 컨텍스트의 사용자 컨텍스트 id로 설정한다.

  7. intercepts를 session, event, request, 및 top-level navigable id로 network intercept 가져오기를 수행한 결과로 둔다.

  8. redirect count를 request의 redirect count로 둔다.

  9. timestamp를 UTC에서 현재 날짜와 시간을 나타내는 time value로 둔다.

  10. intercepts가 비어 있지 않으면 is blocked를 true로 두고, 그렇지 않으면 is blocked를 false로 둔다.

  11. params를 network.BaseParameters production과 일치하는 맵으로 두고, request 필드는 request data로 설정하고, navigation 필드는 navigation으로 설정하고, context 필드는 navigable id로 설정하고, userContext 필드는 user context id로 설정하고, timestamp 필드는 timestamp로 설정하고, redirectCount 필드는 redirect count로 설정하고, isBlocked 필드는 is blocked로 설정하고, intercepts 필드는 is blocked가 true이면 intercepts로 설정하거나, 그렇지 않으면 생략한다.

  12. params를 반환한다

7.5.4.4. network.BytesValue 타입
network.BytesValue = network.StringValue / network.Base64Value;

network.StringValue = {
  type: "string",
  value: text,
}

network.Base64Value = {
  type: "base64",
  value: text,
}

network.BytesValue 타입은 네트워크를 통해 전송되는 바이너리 데이터를 나타낸다. 유효한 UTF-8은 network.StringValue 타입으로 표현되고, 그 외의 데이터는 Base64로 인코딩된 형식인 network.Base64Value로 표현된다.

protocol bytes가 주어졌을 때 프로토콜 bytes 역직렬화를 하려면:

참고: 이는 network.BytesValue로 인코딩된 bytes를 받아 byte sequence를 반환한다.

  1. protocol bytes가 network.StringValue production과 일치하면, bytes를 protocol bytes["value"]를 UTF-8 encode한 결과로 둔다.

  2. 그렇지 않고 protocol bytes가 network.Base64Value production과 일치하면, bytes를 protocol bytes["value"]를 forgiving-base64 decode한 결과로 둔다.

  3. bytes를 반환한다.

bytes가 주어졌을 때 프로토콜 바이트 직렬화를 수행하려면:

참고: 이는 바이트 시퀀스를 받아 network.BytesValue를 반환한다.

  1. text를 bytes에 대해 BOM 없이 UTF-8 디코딩하거나 실패한 결과로 둔다.

  2. text가 실패이면, network.Base64Value 생성 규칙과 일치하는 맵을 반환하되, value는 bytes를 관대한 base64 인코딩한 값으로 설정한다.

  3. network.StringValue 생성 규칙과 일치하는 맵을 반환하되, value는 text로 설정한다.

7.5.4.5. network.Collector 타입

원격 엔드 정의 및 로컬 엔드 정의

network.Collector = text

network.Collector 타입은 수집기의 ID를 나타낸다.

7.5.4.6. network.CollectorType 타입

원격 엔드 정의 및 로컬 엔드 정의

network.CollectorType = "blob"

참고: 향후에는 주어진 수집기가 수집한 데이터를 스트림을 통해 읽으려는 클라이언트를 위해 "stream" 수집기 타입도 지원할 수 있다.

network.CollectorType 타입은 추가할 수 있는 데이터 수집기의 여러 타입을 나타낸다.

원격 엔드 정의 및 로컬 엔드 정의

network.SameSite = "strict" / "lax" / "none" / "default"


network.Cookie = {
    name: text,
    value: network.BytesValue,
    domain: text,
    path: text,
    size: js-uint,
    httpOnly: bool,
    secure: bool,
    sameSite: network.SameSite,
    ? expiry: js-uint,
    Extensible,
}

network.Cookie 타입은 쿠키를 나타낸다.

stored cookie가 주어졌을 때 쿠키 직렬화를 수행하려면:
  1. name을 stored cookie의 name 필드로 UTF-8 디코드한 결과로 둔다.

  2. value를 stored cookie의 value로 프로토콜 바이트 직렬화를 수행한 결과로 둔다.

  3. domain을 stored cookie의 domain 필드로 둔다.

  4. path를 stored cookie의 path 필드로 둔다.

  5. expiry를 stored cookie의 expiry-time 필드가 설정되어 있으면 Unix 타임스탬프로 표현한 값으로, 그렇지 않으면 null로 둔다.

  6. size를 Cookie 헤더에서 표현되는 방식대로 stored cookie를 직렬화한 결과의 바이트 길이로 둔다.

  7. http only를 stored cookie의 http-only-flag가 true이면 true로, 그렇지 않으면 false로 둔다.

  8. secure를 stored cookie의 secure-only-flag가 true이면 true로, 그렇지 않으면 false로 둔다.

  9. same site를 stored cookie의 same-site-flag가 "None"이면 "none"으로, "Lax"이면 "lax"로, "Strict"이면 "strict"로, 또는 "Default"이면 "default"로 둔다

  10. network.Cookie 생성식과 일치하는 맵을 반환하고, name 필드는 name로, value 필드는 value로, domain 필드는 domain로, path 필드는 path로, expiry 필드는 null이 아니면 expiry로 설정하고 그렇지 않으면 생략하며, size 필드는 size로, httpOnly 필드는 http only로, secure 필드는 secure로, sameSite 필드는 same site로 설정한다.

7.5.4.8. network.CookieHeader 타입

원격 엔드 정의

network.CookieHeader = {
    name: text,
    value: network.BytesValue,
}

network.CookieHeader 타입은 Cookie 요청 헤더에 있는 쿠키 데이터의 부분집합을 나타낸다.

protocol cookie가 주어졌을 때 쿠키 헤더 직렬화를 수행하려면:
  1. name을 protocol cookie["name"]를 UTF-8 인코딩한 결과로 둔다.

  2. value를 protocol cookie["value"]로 프로토콜 바이트 역직렬화를 수행한 결과로 둔다.

  3. header value를 name, `=`, 및 value를 연결하여 형성된 바이트 시퀀스로 둔다

  4. header value를 반환한다.

7.5.4.9. network.DataType 타입

원격 엔드 정의 및 로컬 엔드 정의

network.DataType = "request" / "response"

network.DataType 타입은 수집할 수 있는 네트워크 데이터의 여러 타입을 나타낸다.

7.5.4.10. network.FetchTimingInfo 타입

원격 엔드 정의 및 로컬 엔드 정의

network.FetchTimingInfo = {
    timeOrigin: float,
    requestTime: float,
    redirectStart: float,
    redirectEnd: float,
    fetchStart: float,
    dnsStart: float,
    dnsEnd: float,
    connectStart: float,
    connectEnd: float,
    tlsStart: float,

    requestStart: float,
    responseStart: float,

    responseEnd: float,
}

network.FetchTimingInfo 타입은 요청의 클라이언트의 시간 원점을 기준으로 한, 요청 각 부분의 시간을 나타낸다.

request가 주어졌을 때 fetch 타이밍 가져오기를 수행하려면:
  1. global을 request의 클라이언트로 둔다.

  2. global이 null이면, 모든 필드가 0으로 설정된 network.FetchTimingInfo 생성식과 일치하는 맵을 반환한다.

  3. time origin을 global로 시간 원점 타임스탬프 가져오기를 수행한 결과로 둔다.

  4. timings를 request의 fetch 타이밍 정보로 둔다.

  5. connection timing을 timings의 최종 연결 타이밍 정보가 null이 아니면 그것으로, 그렇지 않으면 새 연결 타이밍 정보로 둔다.

  6. request time을 timings의 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  7. redirect start를 timings의 리다이렉트 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  8. redirect end를 timings의 리다이렉트 종료 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  9. fetch start를 timings의 post-redirect 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  10. DNS start를 connection timing의 도메인 조회 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  11. DNS end를 connection timing의 도메인 조회 종료 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  12. TLS start를 connection timing의 보안 연결 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  13. connect start를 connection timing의 연결 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  14. connect end를 connection timing의 연결 종료 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  15. request start를 timings의 최종 네트워크 요청 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  16. response start를 timings의 최종 네트워크 응답 시작 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  17. response end를 timings의 종료 시간 및 global이 주어졌을 때 fetch 타임스탬프 변환을 수행한 결과로 둔다.

  18. network.FetchTimingInfo 생성식과 일치하는 맵을 반환하고, timeOrigin 필드는 time origin으로, requestTime 필드는 request time으로, redirectStart 필드는 redirect start로, redirectEnd 필드는 redirect end로, fetchStart 필드는 fetch start로, dnsStart 필드는 DNS start로, dnsEnd 필드는 DNS end로, connectStart 필드는 connect start로, connectEnd 필드는 connect end로, tlsStart 필드는 TLS start로, requestStart 필드는 request start로, responseStart 필드는 response start로, 그리고 responseEnd 필드는 response end로 설정한다.

TODO: service worker 필드를 추가한다

7.5.4.11. network.Header 타입

원격 엔드 정의 및 로컬 엔드 정의

network.Header = {
  name: text,
  value: network.BytesValue,
}

network.Header 타입은 단일 요청 헤더를 나타낸다.

name bytes 및 value bytes가 주어졌을 때 헤더 직렬화를 수행하려면:
  1. name을 name bytes로 UTF-8 디코드한 결과로 둔다.

    단언: 헤더 이름은 ASCII 전용으로 제한되므로 이는 실패할 수 없다.

  2. value를 value bytes로 프로토콜 바이트 직렬화를 수행한 결과로 둔다.

  3. network.Header 생성식과 일치하는 맵을 반환하고, name 필드는 name로, value 필드는 value로 설정한다.

protocol header가 주어졌을 때 헤더 역직렬화를 수행하려면:
  1. name을 protocol header["name"]를 UTF-8 인코딩한 결과로 둔다.

  2. value를 protocol header["value"]로 프로토콜 바이트 역직렬화를 수행한 결과로 둔다.

  3. 헤더 (name, value)를 반환한다.

protocol headers가 주어졌을 때 헤더 목록을 생성하려면:
  1. headers를 빈 헤더 목록으로 둡니다.

  2. protocol headers의 각 header에 대해:

    1. deserialized header를 header로 헤더를 역직렬화한 결과로 둡니다.

    2. deserialized header의 이름이 필드 이름 토큰 생성 규칙과 일치하지 않으면, 오류를 오류 코드 "invalid argument"와 함께 반환합니다.

    3. deserialized header의 값이 헤더 값 생성 규칙과 일치하지 않으면, 오류를 오류 코드 "invalid argument"와 함께 반환합니다.

    4. deserialized header를 headers에 추가합니다.

  3. 데이터 headers와 함께 성공을 반환합니다

7.5.4.12. network.Initiator 타입

원격 엔드 정의 및 로컬 엔드 정의

network.Initiator = {
    ? columnNumber: js-uint,
    ? lineNumber: js-uint,
    ? request: network.Request,
    ? stackTrace: script.StackTrace,
    ? type: "parser" / "script" / "preflight" / "other"
}

network.Initiator 타입은 네트워크 요청의 출처를 나타낸다.

참고: type 필드는 하위 호환성을 위해 정의에 포함되어 있지만, initiator 가져오기 단계에서는 더 이상 설정되지 않으며, 이 명세의 향후 개정에서 제거될 것이다. 그 사용은 network.RequestData의 initiatorType 및 destination으로 대체될 것으로 예상된다.

참고: request 필드는 하위 호환성을 위해 정의에 포함되어 있지만, initiator 가져오기 단계에서는 더 이상 설정되지 않으며, 이 명세의 향후 개정에서 제거될 것이다. network.Initiator는 동일한 요청 ID도 포함하는 network.BeforeRequestSentParameters에 포함되므로, 이 정보는 중복된다. 다음을 참조하라: § 7.5.4.3 network.BaseParameters 타입.

request가 주어졌을 때 initiator 가져오기를 수행하려면:
  1. request의 initiator 타입이 "fetch" 또는 "xmlhttprequest"이면:

    1. stack trace를 현재 스택 추적으로 둔다.

    2. stack trace의 크기가 1 이상이면, line number를 stack trace[0]의 lineNumber 필드 값으로 두고, column number를 stack trace[0]의 columnNumber 필드 값으로 둔다. 그렇지 않으면 line number와 column number를 0으로 둔다.

    그렇지 않으면, stack trace, column number, 및 line number를 모두 null로 둔다.

    TODO: Chrome은 parser 삽입 리소스에 대해 현재 파서 위치를 column number / line number로 포함한다.

  2. network.Initiator 생성식과 일치하는 맵을 반환하고, columnNumber 필드는 null이 아니면 column number로 설정하고 그렇지 않으면 생략하며, lineNumber 필드는 null이 아니면 line number로 설정하고 그렇지 않으면 생략하며, stackTrace 필드는 null이 아니면 stack trace로 설정하고 그렇지 않으면 생략한다.

7.5.4.13. network.Intercept 타입

원격 엔드 정의 및 로컬 엔드 정의

network.Intercept = text

network.Intercept 타입은 네트워크 인터셉트의 ID를 나타낸다.

7.5.4.14. network.Request 타입

원격 엔드 정의 및 로컬 엔드 정의

network.Request = text;

각 네트워크 요청은 연관된 요청 ID를 가지며, 이는 해당 요청을 고유하게 식별하는 문자열이다. 리다이렉트로 인해 생긴 요청의 식별자는 이를 시작한 요청의 식별자와 일치한다.

7.5.4.15. network.RequestData 타입

원격 엔드 정의 및 로컬 엔드 정의

network.RequestData = {
    request: network.Request,
    url: text,
    method: text,
    headers: [*network.Header],
    cookies: [*network.Cookie],
    headersSize: js-uint,
    bodySize: js-uint / null,
    destination: text,
    initiatorType: text / null,
    timings: network.FetchTimingInfo,
}

network.RequestData 타입은 진행 중인 네트워크 요청을 나타낸다.

request가 주어졌을 때 요청 데이터 가져오기를 수행하려면:

  1. request id를 request의 요청 ID로 둔다.

  2. url을 request의 URL로 URL 직렬화기를 실행한 결과로 둔다.

  3. method를 request의 메서드로 둔다.

  4. body size를 null로 둔다.

  5. body를 request의 본문으로 둔다.

  6. body가 바이트 시퀀스이면, body size를 그 시퀀스의 길이로 설정한다. 그렇지 않고, body가 본문이면 body size를 그 본문의 길이로 설정한다.

  7. headers size를 [HTTP11]에서 요구하는 방식으로 직렬화했을 때 request의 헤더 리스트의 바이트 크기로 둔다.

    참고: 헤더 압축을 허용하는 프로토콜의 경우, 이는 네트워크를 통해 전송된 헤더의 압축된 크기이다.

  8. headers를 빈 리스트로 둔다.

  9. cookies를 빈 리스트로 둔다.

  10. request의 헤더 리스트 안의 각 (name, value)에 대해:

    1. name 및 value로 헤더 직렬화를 수행한 결과를 headers에 추가한다.

    2. name이 "Cookie"와 바이트 대소문자 무시 일치하면:

      1. request에 포함되는 사용자 에이전트의 쿠키 저장소 안의 각 cookie에 대해:

        참고: [COOKIES]는 저장소 안의 어떤 쿠키가 요청에 포함될 수 있는지에 대한 일부 기본 요구사항을 정의하지만, 사용자 에이전트는 추가 제약을 부과할 자유가 있다.

        1. cookie가 주어졌을 때 쿠키 직렬화를 수행한 결과를 cookies에 추가한다.

  11. destination을 request의 목적지로 둔다.

  12. initiator type을 request의 initiator 타입으로 둔다.

  13. timings를 request로 fetch 타이밍 가져오기를 수행한 결과로 둔다.

  14. network.RequestData 생성식과 일치하는 맵을 반환하고, request 필드는 request id로, url 필드는 url로, method 필드는 method로, headers 필드는 headers로, cookies 필드는 cookies로, headersSize 필드는 headers size로, bodySize 필드는 body size로, destination 필드는 destination로, initiatorType 필드는 initiator type으로, timings 필드는 timings로 설정한다.

7.5.4.16. network.ResponseContent 타입

원격 엔드 정의 및 로컬 엔드 정의

network.ResponseContent = {
    size: js-uint
}

network.ResponseContent 타입은 네트워크 요청에 대한 디코딩된 응답을 나타낸다.

response가 주어졌을 때 응답 콘텐츠 정보 가져오기를 수행하려면.
  1. network.ResponseContent 생성식과 일치하는 새 맵을 반환하고, size 필드는 response의 응답 본문 정보의 디코딩된 크기로 설정한다

7.5.4.17. network.ResponseData 타입

원격 엔드 정의 및 로컬 엔드 정의

network.ResponseData = {
    url: text,
    protocol: text,
    status: js-uint,
    statusText: text,
    fromCache: bool,
    headers: [*network.Header],
    mimeType: text,
    bytesReceived: js-uint,
    headersSize: js-uint / null,
    bodySize: js-uint / null,
    content: network.ResponseContent,
    ?authChallenges: [*network.AuthChallenge],
}

network.ResponseData 타입은 네트워크 요청에 대한 응답을 나타낸다.

response가 주어졌을 때 프로토콜 가져오기를 수행하려면:

  1. protocol을 빈 문자열로 둔다.

  2. response의 최종 연결 타이밍 정보가 null이 아니면, protocol을 response의 최종 연결 타이밍 정보의 ALPN 협상 프로토콜로 설정한다.

  3. protocol이 빈 문자열이거나 "unknown"와 같으면:

    1. protocol을 response의 url의 스킴으로 설정한다

    2. protocol이 "http" 또는 "https" 중 하나와 같고 response가 연관된 HTTP Response를 가지면.

      참고: [FETCH]는 HTTP 네트워크 응답과 응답 객체 사이의 관계에 대해 명확하지 않다.

      1. http version을 HTTP Response의 Status line의 HTTP-version [HTTP11]로 둔다.

      2. http version이 "HTTP/"로 시작하면:

        1. version을 http version의 5부터 http version의 길이까지의 코드 단위 부분 문자열로 둔다.

        2. version이 "0.9"이면 protocol을 "http/0.9"로 설정하고, 그렇지 않고 version이 "1.0"이면 protocol을 "http/1.0"으로 설정하고, 그렇지 않고 version이 "1.1"이면 protocol을 "http/1.1"로 설정한다.

  4. protocol을 반환한다.

response가 주어졌을 때 응답 데이터 가져오기를 수행하려면:
  1. url을 response의 URL로 URL 직렬화기를 실행한 결과로 둔다.

  2. protocol을 response가 주어졌을 때 프로토콜 가져오기를 수행한 결과로 설정한다.

  3. status를 response의 상태로 둔다.

  4. status text를 response의 상태 메시지로 둔다.

  5. response의 캐시 상태가 "local"이면, from cache를 true로 두고, 그렇지 않으면 false로 둔다.

  6. headers를 빈 리스트로 둔다.

  7. mime type을 response에 대한 계산된 MIME 타입의 essence로 둔다.

    참고: 이는 브라우저가 실제로 사용하는 MIME 타입이 무엇이든 그 값이며, [MIMESNIFF] 명세의 정확한 알고리즘을 따르지 않는 경우에도 그렇다.

  8. response의 헤더 리스트 안의 각 (name, value)에 대해:

    1. name 및 value로 헤더 직렬화를 수행한 결과를 headers에 추가한다.

  9. bytes received를 response와 연관된 HTTP 응답의 일부로 전송된 총 바이트 수로 둔다.

  10. headers size를 HTTP 응답의 헤더 필드 섹션의 일부로 전송된 바이트 수로 둔다.

  11. body size를 response의 응답 본문 정보의 인코딩된 크기로 둔다.

  12. content를 response로 응답 콘텐츠 정보 가져오기를 수행한 결과로 둔다.

  13. auth challenges를 response로 챌린지 추출을 수행한 결과로 둔다.

  14. network.ResponseData 생성식과 일치하는 맵을 반환하고, url 필드는 url로, protocol 필드는 protocol로, status 필드는 status로, statusText 필드는 status text로, fromCache 필드는 from cache로, headers 필드는 headers로, mimeType 필드는 mime type로, bytesReceived 필드는 bytes received로, headersSize 필드는 headers size로, bodySize 필드는 body size로, content 필드는 content로, 그리고 authChallenges 필드는 null이 아니면 auth challenges로 설정하고 그렇지 않으면 생략한다.

7.5.4.18. network.SetCookieHeader 타입

Remote end definition

network.SetCookieHeader = {
    name: text,
    value: network.BytesValue,
    ? domain: text,
    ? httpOnly: bool,
    ? expiry: text,
    ? maxAge: js-int,
    ? path: text,
    ? sameSite: network.SameSite,
    ? secure: bool,
}

network.SetCookieHeader는 Set-Cookie response header 안의 데이터를 나타낸다.

정수인 input이 주어졌을 때 정수 직렬화를 하려면:

참고: 이는 input을 십진 숫자의 문자열로 나타내는 가장 짧은 표현을 만든다.

  1. serialized를 빈 문자열로 둔다.

  2. value를 input으로 둔다.

  3. value가 0보다 큰 동안:

    1. x를 value를 10으로 나눈 값으로 둔다.

    2. most significant digits를 x의 정수 부분으로 둔다.

    3. y를 most significant digits에 10을 곱한 값으로 둔다.

    4. least significant digit를 value - y로 둔다.

    5. 단언: least significant digit는 0부터 9까지의 범위에 있는 정수이다. 양 끝값을 포함한다.

    6. codepoint를 그 value가 U+0030 DIGIT ZERO의 value + least significant digit인 code point로 둔다.

    7. codepoint를 serialized 앞에 추가한다.

    8. value를 most significant digits로 설정한다.

  4. serialized를 반환한다.

주어진 protocol cookie에 대해 set-cookie 헤더 직렬화를 하려면:
  1. name을 protocol cookie["name"]을 UTF-8 인코딩한 값으로 둡니다.

  2. value를 protocol cookie["value"]로 프로토콜 바이트를 역직렬화한 결과로 둡니다.

  3. header value를 name, `=`, 그리고 value를 연결하여 형성된 바이트 시퀀스로 둡니다.

  4. protocol cookie가 "expiry"를 포함하는 경우:

    1. attribute를 `;Expires=`로 둡니다

    2. protocol cookie["expiry"]를 UTF-8 인코딩한 값을 attribute에 추가합니다.

    3. attribute를 header value에 추가합니다.

  5. protocol cookie가 "maxAge"를 포함하는 경우:

    1. attribute를 `;Max-Age=`로 둡니다

    2. max age string을 protocol cookie["maxAge"]를 정수로 직렬화한 값으로 둡니다.

    3. max age string을 UTF-8 인코딩한 값을 attribute에 추가합니다.

    4. attribute를 header value에 추가합니다.

  6. protocol cookie가 "domain"을 포함하는 경우:

    1. attribute를 `;Domain=`으로 둡니다

    2. protocol cookie["domain"]을 UTF-8 인코딩한 값을 attribute에 추가합니다.

    3. attribute를 header value에 추가합니다.

  7. protocol cookie가 "path"를 포함하는 경우:

    1. attribute를 `;Path=`로 둡니다

    2. protocol cookie["path"]를 UTF-8 인코딩한 값을 attribute에 추가합니다.

    3. attribute를 header value에 추가합니다.

  8. protocol cookie가 "secure"를 포함하고 protocol cookie["secure"]가 true인 경우:

    1. `;Secure`를 header value에 추가합니다.

  9. protocol cookie가 "httpOnly"를 포함하고 protocol cookie["httpOnly"]가 true인 경우:

    1. `;HttpOnly`를 header value에 추가합니다.

  10. protocol cookie가 "sameSite"를 포함하는 경우:

    1. attribute를 `;SameSite=`로 둡니다

    2. protocol cookie["sameSite"]를 UTF-8 인코딩한 값을 attribute에 추가합니다.

    3. attribute를 header value에 추가합니다.

  11. header value를 반환합니다.

7.5.4.19. network.UrlPattern 타입

Remote end definition

network.UrlPattern = (
  network.UrlPatternPattern /
  network.UrlPatternString
)

network.UrlPatternPattern = {
    type: "pattern",
    ?protocol: text,
    ?hostname: text,
    ?port: text,
    ?pathname: text,
    ?search: text,
}


network.UrlPatternString = {
    type: "string",
    pattern: text,
}

network.UrlPattern은 network intercept에 대해 request URL을 일치시키는 데 사용되는 pattern을 나타낸다.

URL이 network.UrlPattern과 일치되는 경우 URL은 파싱되고, 각 컴포넌트는 pattern 안의 대응하는 필드가 존재하면 그 필드와 동등한지 비교된다. pattern에서 누락된 필드는 항상 일치한다.

참고: 이 구문은 향후 확장성을 염두에 두고 설계되었다. 특히 이 구문은 [URLPattern] 명세에서 특별하게 취급되는 문자를 금지한다. 이러한 문자는 앞에 U+005C (\) 문자를 붙여 이스케이프할 수 있다.

pattern이 주어졌을 때 URL 패턴의 이스케이프를 해제하려면
  1. forbidden characters를 코드 포인트 «U+0028 ((), U+0029 ()), U+002A (*), U+007B ({), U+007D (})»의 집합으로 둡니다

  2. result를 빈 문자열로 둡니다.

  3. is escaped character를 false로 둡니다.

  4. pattern의 각 codepoint에 대해:

    1. is escaped character가 false인 경우:

      1. forbidden characters가 codepoint를 포함하면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      2. codepoint가 U+005C (\)인 경우:

        1. is escaped character를 true로 설정합니다.

        2. 계속합니다.

    2. codepoint를 result에 추가합니다.

    3. is escaped character를 false로 설정합니다.

  5. 데이터 result와 함께 성공을 반환합니다.

pattern이 주어졌을 때 URL 패턴을 구문 분석하려면:
  1. has protocol을 true로 둡니다.

  2. has hostname을 true로 둡니다.

  3. has port를 true로 둡니다.

  4. has pathname을 true로 둡니다.

  5. has search를 true로 둡니다.

  6. pattern이 network.UrlPatternPattern 생성 규칙과 일치하는 경우:

    1. pattern url을 빈 문자열로 둡니다.

    2. pattern이 "protocol"을 포함하는 경우:

      1. pattern["protocol"]이 빈 문자열이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      2. protocol을 pattern["protocol"]로 시도하여 URL 패턴의 이스케이프를 해제한 결과로 둡니다.

      3. protocol의 각 codepoint에 대해:

        1. codepoint가 ASCII 영숫자가 아니고 «U+002B (+), U+002D (-), U+002E (.)»가 codepoint를 포함하지 않는 경우:

          1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      4. protocol을 pattern url에 추가합니다.

    3. 그렇지 않으면:

      1. has protocol을 false로 설정합니다.

      2. "http"를 pattern url에 추가합니다.

    4. scheme을 pattern url에 ASCII 소문자화를 적용한 값으로 둡니다.

    5. ":"를 pattern url에 추가합니다.

    6. scheme이 특수 스킴이면, "//"를 pattern url에 추가합니다.

    7. pattern이 "hostname"을 포함하는 경우:

      1. pattern["hostname"]이 빈 문자열이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      2. scheme이 "file"이면 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      3. hostname을 pattern["hostname"]로 시도하여 URL 패턴의 이스케이프를 해제한 결과로 둡니다.

      4. inside brackets를 false로 둡니다.

      5. hostname의 각 codepoint에 대해:

        1. «U+002F (/), U+003F (?), U+0023 (#)»가 codepoint를 포함하는 경우:

          1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

        2. inside brackets가 false이고 codepoint가 U+003A (:)인 경우:

          1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

        3. codepoint가 U+005B ([)이면, inside brackets를 true로 설정합니다.

        4. codepoint가 U+005D (])이면, inside brackets를 false로 설정합니다.

      6. hostname을 pattern url에 추가합니다.

    8. 그렇지 않으면:

      1. scheme이 "file"이 아니면, "placeholder"를 pattern url에 추가합니다.

      2. has hostname을 false로 설정합니다.

    9. pattern이 "port"를 포함하는 경우:

      1. pattern["port"]가 빈 문자열이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      2. port를 pattern["port"]로 시도하여 URL 패턴의 이스케이프를 해제한 결과로 둡니다.

      3. ":"를 pattern url에 추가합니다.

      4. port의 각 codepoint에 대해:

        1. codepoint가 ASCII 숫자가 아닌 경우:

          1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      5. port를 pattern url에 추가합니다.

    10. 그렇지 않으면:

      1. has port를 false로 설정합니다.

    11. pattern이 "pathname"을 포함하는 경우:

      1. pathname을 pattern["pathname"]로 시도하여 URL 패턴의 이스케이프를 해제한 결과로 둡니다.

      2. pathname이 U+002F (/)로 시작하지 않으면, "/"를 pattern url에 추가합니다.

      3. pathname의 각 codepoint에 대해:

        1. «U+003F (?), U+0023 (#)»가 codepoint를 포함하는 경우:

          1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      4. pathname을 pattern url에 추가합니다.

    12. 그렇지 않으면:

      1. has pathname을 false로 설정합니다.

    13. pattern이 "search"를 포함하는 경우:

      1. search를 pattern["search"]로 시도하여 URL 패턴의 이스케이프를 해제한 결과로 둡니다.

      2. search가 U+003F (?)로 시작하지 않으면, "?"를 pattern url에 추가합니다.

      3. search의 각 codepoint에 대해:

        1. codepoint가 U+0023 (#)인 경우:

          1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      4. search를 pattern url에 추가합니다.

    14. 그렇지 않으면:

      1. has search를 false로 설정합니다.

  7. 그렇지 않고, pattern이 network.UrlPatternString 생성 규칙과 일치하는 경우:

    1. pattern url을 pattern["pattern"]로 시도하여 URL 패턴의 이스케이프를 해제한 결과로 둡니다.

  8. url을 pattern url을 구문 분석한 결과로 둡니다.

  9. url이 실패이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  10. parsed를 다음 필드를 가진 구조체로 둡니다:

    protocol
    has protocol이 true이면 url의 스킴, 그렇지 않으면 null입니다.
    hostname
    has hostname이 true이면 url의 호스트, 그렇지 않으면 null입니다.
    port
    1. has port가 false인 경우:

      1. null.

    2. 그렇지 않으면:

      1. url의 스킴이 특수 스킴이고, url의 스킴의 기본 포트가 null이 아니며, url의 포트가 null이거나 스킴의 기본 포트와 같은 경우:

        1. 빈 문자열.

      2. 그렇지 않고, url의 포트가 null이 아닌 경우:

        1. url의 포트로 정수를 직렬화합니다.

      3. 그렇지 않으면:

        1. null.

    pathname
    1. has pathname이 false인 경우:

      1. null.

    2. 그렇지 않으면:

      1. url의 경로가 빈 문자열이 아니고 비어 있지 않으면 url로 URL 경로 직렬화기를 실행한 결과이고, 그렇지 않으면 null입니다.

    search
    1. has search가 false인 경우:

      1. null.

    2. 그렇지 않으면:

      1. url의 쿼리가 null이면 빈 문자열이고, 그렇지 않으면 url의 쿼리입니다.

  11. 데이터 parsed와 함께 성공을 반환합니다.

url pattern 및 url string이 주어졌을 때 URL 패턴 일치를 수행하려면:
  1. url을 url string을 파싱한 결과로 둔다.

  2. url pattern의 protocol이 null이 아니고 url의 스킴과 같지 않으면, false를 반환한다.

  3. url pattern의 hostname이 null이 아니고 url의 호스트와 같지 않으면, false를 반환한다.

  4. url pattern의 port가 null이 아니면:

    1. port를 null로 둔다.

    2. url의 스킴이 특수 스킴이고 url의 스킴의 기본 포트가 null이 아니며, url의 포트가 null이거나 스킴의 기본 포트와 같으면:

      1. port를 빈 문자열로 설정한다.

    3. 그렇지 않고, url의 포트가 null이 아니면:

      1. port를 url의 포트로 정수 직렬화를 수행한 결과로 설정한다.

    4. url pattern의 port가 port와 같지 않으면, false를 반환한다.

  5. url pattern의 pathname이 null이 아니고 url로 URL 경로 직렬화기를 실행한 결과와 같지 않으면, false를 반환한다.

  6. url pattern의 search가 null이 아니면:

    1. url query를 url의 쿼리로 둔다.

    2. url query가 null이면, url query를 빈 문자열로 설정한다.

    3. url pattern의 search가 url query와 같지 않으면, false를 반환한다.

  7. true를 반환한다.

7.5.5. 명령

7.5.5.1. network.addDataCollector 명령

network.addDataCollector는 collector를 추가한다.

명령 타입
network.AddDataCollector = (
  method: "network.addDataCollector",
  params: network.AddDataCollectorParameters
)

network.AddDataCollectorParameters = {
  dataTypes: [+network.DataType],
  maxEncodedDataSize: js-uint,
  ? collectorType: network.CollectorType .default "blob",
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}
반환 타입
network.AddDataCollectorResult = {
  collector: network.Collector
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. collector id를 UUID의 문자열 표현으로 둡니다.

  2. input context ids를 빈 집합으로 둡니다.

  3. command parameters의 contexts 필드가 존재하면, input context ids를 command parameters[contexts]로 집합을 생성한 결과로 설정합니다.

  4. data types를 command parameters["dataTypes"]로 집합을 생성한 결과로 둡니다.

  5. max encoded item size를 command parameters ["maxEncodedDataSize"]로 둡니다.

    참고: maxEncodedDataSize 매개변수는 최대 인코딩된 항목 크기를 나타내며 지정된 수집기가 수집하는 각 요청의 크기를 제한합니다. 이는 수집기가 수집한 전체 크기를 제한하는 것이 아닙니다.

    참고: 구현마다 서로 다른 인코딩을 지원할 수 있으며, 이는 브라우저마다 인코딩된 크기가 다를 수 있음을 의미합니다. 따라서 동일한 데이터 수집기 구성에서도 일부 네트워크 데이터는 일부 구현에서만 최대 인코딩된 항목 크기에 맞을 수 있습니다.

  6. collector type을 command parameters ["collectorType"]으로 둡니다.

  7. input user context ids를 빈 집합으로 둡니다.

  8. command parameters의 userContexts 필드가 존재하면, input user context ids를 command parameters[userContexts]로 집합을 생성한 결과로 설정합니다.

  9. input user context ids가 비어 있지 않고 input context ids도 비어 있지 않으면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  10. max encoded item size가 0이거나 max encoded item size가 최대 전체 수집 크기보다 크면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  11. input context ids가 비어 있지 않은 경우:

    1. navigables를 input context ids로 시도하여 ID별 유효한 내비게이블을 가져온 결과로 둡니다.

    2. navigables의 각 navigable에 대해:

      1. navigable이 최상위 순회 가능 항목이 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  12. 그렇지 않고, input user context ids가 비어 있지 않은 경우:

    1. input user context ids의 각 user context id에 대해 각각 수행합니다:

      1. user context를 user context id로 사용자 컨텍스트를 가져온 결과로 둡니다.

      2. user context가 null이면, 오류를 오류 코드 해당 사용자 컨텍스트 없음과 함께 반환합니다.

  13. collector를 최대 인코딩된 항목 크기 필드가 max encoded item size로 설정되고, 데이터 유형 필드가 data types로 설정되고, 수집기 필드가 collector id로 설정되고, 수집기 유형 필드가 collector type으로 설정되고, 컨텍스트 필드가 input context ids로 설정되고, 사용자 컨텍스트 필드가 input user context ids로 설정된 수집기로 둡니다.

  14. session의 네트워크 수집기[collector id]를 collector로 설정합니다.

  15. collector 필드가 collector id로 설정된 network.AddDataCollectorResult 생성 규칙과 일치하는 새로운 맵을 반환합니다.

7.5.5.2. network.addIntercept 명령

network.addIntercept 명령은 network intercept를 추가한다.

명령 타입
network.AddIntercept = (
  method: "network.addIntercept",
  params: network.AddInterceptParameters
)

network.AddInterceptParameters = {
  phases: [+network.InterceptPhase],
  ? contexts: [+browsingContext.BrowsingContext],
  ? urlPatterns: [*network.UrlPattern],
}

network.InterceptPhase = "beforeRequestSent" / "responseStarted" /
                         "authRequired"
반환 타입
network.AddInterceptResult = {
  intercept: network.Intercept
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. intercept를 UUID의 문자열 표현으로 둡니다.

  2. url patterns를 command parameters의 urlPatterns 필드가 존재하면 그 필드로, 그렇지 않으면 빈 목록으로 둡니다.

  3. navigables를 null로 둡니다.

  4. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 빈 집합으로 설정합니다.

    2. command parameters["contexts"]의 각 navigable id에 대해

      1. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

      2. navigable이 최상위 순회 가능 항목이 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      3. navigable을 navigables에 추가합니다.

    3. navigables가 빈 집합이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  5. intercept map을 session의 가로채기 맵으로 둡니다.

  6. parsed patterns를 빈 목록으로 둡니다.

  7. url patterns의 각 url pattern에 대해:

    1. parsed를 url pattern으로 시도하여 URL 패턴을 구문 분석한 결과로 둡니다.

    2. parsed를 parsed patterns에 추가합니다.

  8. intercept map[intercept]을 url patterns parsed patterns, phases command parameters["phases"] 및 browsingContexts navigables를 가진 구조체로 설정합니다.

  9. intercept 필드가 intercept로 설정된 network.AddInterceptResult 생성 규칙과 일치하는 새로운 맵을 반환합니다.

7.5.5.3. network.continueRequest 명령

network.continueRequest 명령은 네트워크 인터셉트에 의해 차단된 요청을 계속한다.

명령 타입
network.ContinueRequest = (
  method: "network.continueRequest",
  params: network.ContinueRequestParameters
)

network.ContinueRequestParameters = {
  request: network.Request,
  ?body: network.BytesValue,
  ?cookies: [*network.CookieHeader],
  ?headers: [*network.Header],
  ?method: text,
  ?url: text,
}
반환 타입
network.ContinueRequestResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. blocked requests를 session의 차단된 요청 맵으로 둡니다.

  2. request id를 command parameters["request"]로 둡니다.

  3. blocked requests가 request id를 포함하지 않으면 오류를 오류 코드 해당 요청 없음과 함께 반환합니다.

  4. (request, phase, response)를 blocked requests[request id]로 둡니다.

  5. phase가 "beforeRequestSent"가 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

    "request already sent" 오류를 고려합니다.

  6. command parameters가 "url"을 포함하는 경우:

    1. url record를 command parameters["url"]에 URL 파서를 적용하고, 기준 URL을 null로 하여 얻은 결과로 둡니다.

    2. url record가 실패이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      TODO: 여기에서도 재개해야 합니까?

    3. request의 url을 url record로 둡니다.

  7. command parameters가 "method"를 포함하는 경우:

    1. method를 command parameters["method"]로 둡니다.

    2. method가 메서드 토큰 생성 규칙과 일치하지 않으면, 오류를 오류 코드 "invalid argument"와 함께 반환합니다.

    3. request의 메서드를 method로 둡니다.

  8. command parameters가 "headers"를 포함하는 경우:

    1. headers를 빈 헤더 목록으로 둡니다.

    2. command parameters["headers"]의 각 header에 대해:

      1. deserialized header를 header로 헤더를 역직렬화한 결과로 둡니다.

      2. deserialized header의 이름이 필드 이름 토큰 생성 규칙과 일치하지 않으면, 오류를 오류 코드 "invalid argument"와 함께 반환합니다.

      3. deserialized header의 값이 헤더 값 생성 규칙과 일치하지 않으면, 오류를 오류 코드 "invalid argument"와 함께 반환합니다.

      4. deserialized header를 headers에 추가합니다.

    3. request의 헤더 목록을 headers로 설정합니다.

  9. command parameters가 "cookies"를 포함하는 경우:

    1. cookie header를 빈 바이트 시퀀스로 둡니다.

    2. command parameters["cookies"]의 각 cookie에 대해:

      1. cookie header가 비어 있지 않으면, `;`를 cookie header에 추가합니다.

      2. cookie로 쿠키 헤더를 직렬화한 값을 cookie header에 추가합니다.

    3. found cookie header를 false로 둡니다.

    4. request의 헤더 목록에 있는 각 header에 대해:

      1. name을 header의 이름으로 둡니다.

      2. name을 바이트 소문자화한 값이 `cookie`인 경우:

        1. header의 값을 cookie header로 설정합니다.

        2. found cookie header를 true로 설정합니다.

        3. 중단합니다.

    5. found cookie header가 false인 경우:

      1. 헤더 (`Cookie`, cookie header)를 request의 헤더 목록에 추가합니다.

  10. command parameters가 "body"를 포함하는 경우:

    1. body를 command parameters["body"]로 프로토콜 바이트를 역직렬화한 결과로 둡니다.

    2. request의 본문을 body로 설정합니다.

  11. "continue request", request id, 그리고 (null, "incomplete")로 재개합니다.

  12. 데이터 null과 함께 성공을 반환합니다.

7.5.5.4. network.continueResponse 명령

network.continueResponse 명령은 네트워크 인터셉트에 의해 차단된 응답을 계속한다. 이는 responseStarted 단계에서 호출할 수 있으며, 응답의 상태 및 헤더를 수정하면서도 네트워크 응답 본문은 그대로 제공한다.

명령 타입
network.ContinueResponse = (
  method: "network.continueResponse",
  params: network.ContinueResponseParameters
)

network.ContinueResponseParameters = {
  request: network.Request,
  ?cookies: [*network.SetCookieHeader]
  ?credentials: network.AuthCredentials,
  ?headers: [*network.Header],
  ?reasonPhrase: text,
  ?statusCode: js-uint,
}
반환 타입
network.ContinueResponseResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. request id를 command parameters["request"]로 둡니다.

  2. response를 session, "continueResponse" 및 command parameters로 시도하여 응답을 업데이트한 결과로 둡니다.

  3. "continue request", request id, 그리고 (response, "incomplete")로 재개합니다.

  4. 데이터 null과 함께 성공을 반환합니다.

7.5.5.5. network.continueWithAuth 명령

network.continueWithAuth 명령은 authRequired 단계에서 network intercept에 의해 차단된 response를 계속한다.

명령 타입
network.ContinueWithAuth = (
  method: "network.continueWithAuth",
  params: network.ContinueWithAuthParameters
)

network.ContinueWithAuthParameters = {
  request: network.Request,
  (network.ContinueWithAuthCredentials // network.ContinueWithAuthNoCredentials)
}

network.ContinueWithAuthCredentials = (
  action: "provideCredentials", 
  credentials: network.AuthCredentials
)

network.ContinueWithAuthNoCredentials = (
  action: "default" / "cancel"
)
반환 타입
network.ContinueWithAuthResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. blocked requests를 session의 차단된 요청 맵으로 둡니다.

  2. request id를 command parameters["request"]로 둡니다.

  3. blocked requests가 request id를 포함하지 않으면 오류를 오류 코드 해당 요청 없음과 함께 반환합니다.

  4. (request, phase, response)를 blocked requests[request id]로 둡니다.

  5. phase가 "authRequired"가 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  6. command parameters "action"이 "cancel"이면, response의 인증 자격 증명을 "cancelled"로 설정합니다.

  7. command parameters "action"이 "provideCredentials"인 경우:

    1. credentials를 command parameters["credentials"]로 둡니다.

    2. 단언: credentials["type"]은 "password"입니다.

    3. response의 인증 자격 증명을 (credentials["username"], credentials["password"])로 설정합니다

  8. "continue request", request id, 그리고 (response, "incomplete")로 재개합니다.

  9. 데이터 null과 함께 성공을 반환합니다.

7.5.5.6. network.disownData 명령

network.disownData 명령은 주어진 수집기에 대해 수집된 네트워크 데이터를 해제한다.

명령 타입
network.DisownData = (
  method: "network.disownData",
  params: network.DisownDataParameters
)

network.DisownDataParameters = {
  dataType: network.DataType,
  collector: network.Collector,
  request: network.Request,
}
반환 타입
network.DisownDataResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. data type을 command parameters의 "dataType" 필드 값으로 둡니다.

  2. collector id를 command parameters의 "collector" 필드 값으로 둡니다.

  3. request id를 command parameters의 "request" 필드 값으로 둡니다.

  4. collectors를 session의 네트워크 수집기로 둡니다.

  5. collectors가 collector id를 포함하지 않으면, 오류를 오류 코드 해당 네트워크 수집기 없음과 함께 반환합니다.

  6. collected data를 request id와 data type으로 수집된 데이터를 가져온 결과로 둡니다.

  7. collected data가 null이면, 오류를 오류 코드 해당 네트워크 데이터 없음과 함께 반환합니다.

  8. collected data와 collector id로 데이터에서 수집기를 제거합니다.

  9. 데이터 null과 함께 성공을 반환합니다.

7.5.5.7. network.failRequest 명령

network.failRequest 명령은 네트워크 인터셉트에 의해 차단된 fetch를 실패시킨다.

명령 타입
network.FailRequest = (
  method: "network.failRequest",
  params: network.FailRequestParameters
)

network.FailRequestParameters = {
  request: network.Request,
}
반환 타입
network.FailRequestResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. blocked requests를 session의 차단된 요청 맵으로 둡니다.

  2. request id를 command parameters["request"]로 둡니다.

  3. blocked requests가 request id를 포함하지 않으면 오류를 오류 코드 해당 요청 없음과 함께 반환합니다.

  4. (request, phase, response)를 blocked requests[request id]로 둡니다.

  5. phase가 "authRequired"이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  6. response를 새로운 네트워크 오류로 둡니다.

    정확한 오류 종류를 설정할 수 있도록 합니다 [이슈 #508]

  7. "continue request", request id, 그리고 (response, "complete")로 재개합니다.

  8. 데이터 null과 함께 성공을 반환합니다.

7.5.5.8. network.getData 명령

network.getData 명령은 사용 가능한 경우 네트워크 데이터를 가져온다.

명령 타입
network.GetData = (
  method: "network.getData",
  params: network.GetDataParameters
)

network.GetDataParameters = {
  dataType: network.DataType,
  ? collector: network.Collector,
  ? disown: bool .default false,
  request: network.Request,
}
반환 타입
network.GetDataResult = {
  bytes: network.BytesValue,
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. data type을 command parameters["dataType"]으로 둡니다.

  2. request id를 command parameters["request"]로 둡니다.

  3. collector id를 null로 둡니다.

  4. command parameters가 포함하는 경우 "collector":

    1. collectors를 session의 네트워크 수집기로 둡니다.

    2. collectors가 collector id를 포함하지 않으면, 오류를 오류 코드 해당 네트워크 수집기 없음과 함께 반환합니다.

    3. collector id를 command parameters["collector"]로 설정합니다.

  5. disown을 command parameters["disown"]으로 둡니다.

  6. disown이 true이고 collector id가 null이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  7. collected data를 request id와 data type이 주어졌을 때 수집된 데이터를 가져온 결과로 둡니다.

  8. collected data가 null인 경우:

    1. 오류를 오류 코드 해당 네트워크 데이터 없음과 함께 반환합니다.

  9. collected data의 대기 중이 true인 경우:

    1. "network data collected"와 (request id, data type)으로 대기합니다.

  10. collector id가 null이 아니고 collected data의 수집기가 collector id를 포함하지 않는 경우:

    1. 오류를 오류 코드 해당 네트워크 데이터 없음과 함께 반환합니다.

  11. bytes를 collected data의 바이트로 둡니다.

  12. bytes가 null이면,

    1. 오류를 오류 코드 사용할 수 없는 네트워크 데이터와 함께 반환합니다.

  13. body를 bytes 필드가 bytes로 설정된 network.GetDataResult 생성 규칙과 일치하는 맵으로 둡니다.

  14. disown이 true이면, collected data와 collector id로 데이터에서 수집기를 제거합니다.

  15. 데이터 body와 함께 성공을 반환합니다.

7.5.5.9. network.provideResponse 명령

network.provideResponse 명령은 완전한 응답을 제공하여, 네트워크 인터셉트에 의해 차단된 요청을 계속한다.

참고: 이는 요청이 일반 요청 생명주기를 거쳐 진행되는 것을 막지 않으며, 따라서 진행됨에 따라 다른 이벤트를 방출한다.

명령 타입
network.ProvideResponse = (
  method: "network.provideResponse",
  params: network.ProvideResponseParameters
)

network.ProvideResponseParameters = {
  request: network.Request,
  ?body: network.BytesValue,
  ?cookies: [*network.SetCookieHeader],
  ?headers: [*network.Header],
  ?reasonPhrase: text,
  ?statusCode: js-uint,
}
반환 타입
network.ProvideResponseResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. request id를 command parameters["request"]로 둡니다.

  2. response를 session, "provideResponse", 그리고 command parameters로 시도하여 응답을 업데이트한 결과로 둡니다.

  3. command parameters가 "body"를 포함하는 경우:

    1. body를 command parameters["body"]로 프로토콜 바이트를 역직렬화한 결과로 둡니다.

    2. response의 본문을 body를 본문으로 한 값으로 설정합니다.

  4. "continue request", request id, 그리고 (response,"complete")로 재개합니다.

  5. 데이터 null과 함께 성공을 반환합니다.

7.5.5.10. network.removeDataCollector 명령

network.removeDataCollector 명령은 컬렉터를 제거한다.

명령 타입
network.RemoveDataCollector = (
  method: "network.removeDataCollector",
  params: network.RemoveDataCollectorParameters
)

network.RemoveDataCollectorParameters = {
  collector: network.Collector
}
반환 타입
network.RemoveDataCollectorResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. collector id를 command parameters의 "collector" 필드 값으로 둡니다.

  2. collectors를 session의 네트워크 수집기로 둡니다.

  3. collectors가 collector id를 포함하지 않으면, 오류를 오류 코드 해당 네트워크 수집기 없음과 함께 반환합니다.

  4. session의 네트워크 수집기에서 collector id를 제거합니다.

  5. 수집된 네트워크 데이터의 각 collected data에 대해, collected data와 collector id로 데이터에서 수집기를 제거합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.5.5.11. network.removeIntercept 명령

network.removeIntercept 명령은 네트워크 인터셉트를 제거한다.

명령 타입
network.RemoveIntercept = (
  method: "network.removeIntercept",
  params: network.RemoveInterceptParameters
)

network.RemoveInterceptParameters = {
  intercept: network.Intercept
}
반환 타입
network.RemoveInterceptResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. intercept를 command parameters의 "intercept" 필드 값으로 둡니다.

  2. intercept map을 session의 가로채기 맵으로 둡니다.

  3. intercept map이 intercept를 포함하지 않으면, 오류를 오류 코드 해당 가로채기 없음과 함께 반환합니다.

  4. intercept map에서 intercept를 제거합니다.

참고: 가로채기를 제거해도 이 가로채기에 의해 이미 차단된 요청에는 영향을 주지 않습니다. 향후 요청이나 기존 요청의 향후 단계에만 영향을 줍니다.

  1. 데이터 null과 함께 성공을 반환합니다.

7.5.5.12. network.setCacheBehavior 명령

network.setCacheBehavior 명령은 특정 요청에 대한 네트워크 캐시 동작을 구성한다.

명령 타입
network.SetCacheBehavior = (
  method: "network.setCacheBehavior",
  params: network.SetCacheBehaviorParameters
)

network.SetCacheBehaviorParameters = {
  cacheBehavior: "default" / "bypass",
  ? contexts: [+browsingContext.BrowsingContext]
}
반환 타입
network.SetCacheBehaviorResult = EmptyResult
요청 request가 주어졌을 때 WebDriver BiDi 캐시 동작 단계는 다음과 같습니다:
  1. navigable을 null로 둡니다.

  2. request의 클라이언트가 환경 설정 객체인 경우:

    1. environment settings를 request의 클라이언트로 둡니다.

    2. 활성 창이 environment settings의 전역 객체인 내비게이블이 있으면, navigable을 해당 내비게이블의 최상위 순회 가능 항목으로 설정합니다.

  3. navigable이 null이 아니고 내비게이블 캐시 동작 맵이 navigable을 포함하면, 내비게이블 캐시 동작 맵[navigable]을 반환합니다.

  4. 기본 캐시 동작을 반환합니다.

navigable이 주어졌을 때 내비게이블 캐시 동작 단계는 다음과 같습니다:
  1. top-level navigable을 navigable의 최상위 순회 가능 항목으로 둡니다.

  2. 내비게이블 캐시 동작 맵이 top-level navigable을 포함하면, 내비게이블 캐시 동작 맵[top-level navigable]을 반환합니다.

  3. 기본 캐시 동작을 반환합니다.

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. behavior를 command parameters["cacheBehavior"]로 둡니다.

  2. command parameters가 "contexts"를 포함하지 않는 경우:

    1. 기본 캐시 동작을 behavior로 설정합니다.

    2. 내비게이블 캐시 동작 맵을 비웁니다.

    3. behavior의 값에 따라 분기합니다:

      "bypass"
      구현별 리소스 캐시를 모두 비활성화하는 구현 정의 단계를 수행합니다.
      "default"
      현재 원격 끝 구성에서 일반적으로 활성화되는 구현별 리소스 캐시를 모두 활성화하는 구현 정의 단계를 수행합니다.
    4. 데이터 null과 함께 성공을 반환합니다.

  3. navigables를 빈 집합으로 둡니다.

  4. command parameters["contexts"]의 각 navigable id에 대해:

    1. context를 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

    2. context가 최상위 브라우징 컨텍스트가 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

    3. context를 navigables에 추가합니다.

  5. navigables의 각 navigable에 대해:

    1. 내비게이블 캐시 동작 맵이 navigable을 포함하고, 내비게이블 캐시 동작 맵[navigable]이 behavior와 같으면 계속합니다.

    2. behavior의 값에 따라 분기합니다:

      "bypass"
      navigable이 최상위 브라우징 컨텍스트인 모든 브라우징 컨텍스트에서 시작된 네트워크 요청에 대해 구현별 리소스 캐시를 모두 비활성화하는 구현 정의 단계를 수행합니다.
      "default"
      navigable이 최상위 브라우징 컨텍스트인 모든 브라우징 컨텍스트에서 시작된 네트워크 요청에 대해 현재 원격 끝 구성에서 일반적으로 활성화되는 구현별 리소스 캐시를 모두 활성화하는 구현 정의 단계를 수행합니다.
    3. behavior가 기본 캐시 동작과 같은 경우:

      1. 내비게이블 캐시 동작 맵이 navigable을 포함하면, 내비게이블 캐시 동작 맵[navigable]을 제거합니다.

    4. 그렇지 않으면:

      1. 내비게이블 캐시 동작 맵[navigable]을 behavior로 설정합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.5.5.13. network.setExtraHeaders 명령

network.setExtraHeaders 명령은 기존 요청 헤더를 확장하거나 덮어쓸 헤더를 지정할 수 있게 한다.

명령 타입
network.SetExtraHeaders = (
  method: "network.setExtraHeaders",
  params: network.SetExtraHeadersParameters
)

network.SetExtraHeadersParameters = {
  headers: [*network.Header]
  ? contexts: [+browsingContext.BrowsingContext]
  ? userContexts: [+browser.UserContext]
}
반환 타입
network.SetExtraHeadersResult = EmptyResult
request 및 headers가 주어졌을 때 헤더 업데이트를 수행하려면:
  1. request headers를 request의 헤더 리스트로 둔다.

  2. headers 안의 각 header에 대해:

    1. request headers 안에 header를 설정한다.

      참고: 이는 항상 기존 값이 있으면 덮어쓴다. 특히 기존 `Set-Cookie` 헤더에 쿠키를 추가하지 않는다.

session, request 및 related navigables가 주어졌을 때 요청 헤더를 업데이트하려면:
  1. 단언: related navigables의 크기는 0 또는 1이다.

    참고: 이는 여러 순회 가능 객체와 연결된 워커에서는 작동하지 않음을 의미한다. 이 경우 어떤 순서로 헤더를 재정의해야 하는지 명확하지 않다.

  2. request 및 session의 추가 헤더의 기본 헤더로 헤더를 업데이트한다.

  3. user context headers를 session의 추가 헤더의 사용자 컨텍스트 헤더로 둔다.

  4. related navigables의 각 navigable에 대해:

    1. user context를 navigable의 연결된 사용자 컨텍스트로 둔다.

    2. user context headers가 user context를 포함하면 request 및 user context headers[user context]로 헤더를 업데이트한다.

  5. navigable headers를 session의 추가 헤더의 순회 가능 객체 헤더로 둔다.

  6. related navigables의 각 navigable에 대해:

    1. top-level traversable을 navigable의 최상위 순회 가능 객체로 둔다.

    2. navigable headers가 top-level traversable을 포함하면 request 및 navigable headers[top-level traversable]로 헤더를 업데이트한다.

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. command parameters가 포함하고 "userContexts" command parameters가 포함하면 "contexts", 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. headers를 command parameters["headers"]로 시도하여 헤더 목록을 생성한 결과로 둡니다.

  3. command parameters가 포함하는 경우 "userContexts":

    1. user contexts를 빈 목록으로 둡니다.

    2. command parameters["userContexts"]의 각 user context id에 대해:

      1. user context를 user context id로 사용자 컨텍스트를 가져온 결과로 둡니다.

      2. user context가 null이면, 오류를 오류 코드 해당 사용자 컨텍스트 없음과 함께 반환합니다.

      3. user context를 user contexts에 추가합니다.

    3. target을 session의 추가 헤더의 사용자 컨텍스트 헤더로 둡니다.

    4. user contexts의 각 user context에 대해:

      1. target[user context]을 headers로 설정합니다.

    5. 데이터 null과 함께 성공을 반환합니다.

  4. command parameters가 포함하는 경우 "contexts":

    1. navigables를 command parameters["contexts"]로 시도하여 ID별 유효한 최상위 순회 가능 항목을 가져온 결과로 둡니다.

    2. target을 session의 추가 헤더의 내비게이블 헤더로 둡니다.

    3. navigables의 각 navigable에 대해:

      1. target[navigable]을 headers로 설정합니다.

    4. 데이터 null과 함께 성공을 반환합니다.

  5. session의 추가 헤더의 기본 헤더를 headers로 설정합니다.

  6. 데이터 null과 함께 성공을 반환합니다.

7.5.6. 이벤트

7.5.6.1. network.authRequired 이벤트
이벤트 타입
network.AuthRequired = (
  method: "network.authRequired",
  params: network.AuthRequiredParameters
)

network.AuthRequiredParameters = {
  network.BaseParameters,
  response: network.ResponseData
}

이 이벤트는 사용자 에이전트가 인증 자격 증명을 요청하려고 할 때 방출된다.

원격 엔드 이벤트 트리거는 요청 request 및 응답 response가 주어졌을 때의 WebDriver BiDi 인증 필요 단계이다:
  1. redirect count를 request의 리다이렉트 횟수로 둔다.

  2. 단언: 요청 전송 전 맵[request]은 redirect count와 같다.

    참고: 이는 모든 호출자가 이 단계 전에 WebDriver BiDi 요청 전송 전 단계가 request로 호출되도록 보장해야 함을 의미한다.

  3. request의 클라이언트가 null이 아니면, related navigables를 request의 클라이언트로 관련 navigable 가져오기를 수행한 결과로 둔다. 그렇지 않으면 related navigables를 빈 집합으로 둔다.

  4. "network.authRequired" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션의 집합 안의 각 session에 대해:

    1. params를 session "network.authRequired", 및 request로 네트워크 이벤트 처리를 수행한 결과로 둔다.

    2. response data를 response로 응답 데이터 가져오기를 수행한 결과로 둔다.

    3. 단언: response data는 "authChallenges"를 포함한다.

    4. params의 response 필드를 response data로 설정한다.

    5. 단언: params는 network.AuthRequiredParameters 생성식과 일치한다.

    6. body를 network.AuthRequired 생성식과 일치하는 맵으로 두고, params 필드를 params로 설정한다.

    7. session 및 body로 이벤트를 방출한다.

    8. params["isBlocked"]가 true이면:

      1. blocked requests를 session의 차단된 요청 맵으로 둔다.

      2. request id를 request의 요청 ID로 둔다.

      3. blocked requests[request id]를 (request, "authRequired", response)로 설정한다.

      4. «"continue request"» 및 request id로 대기한다.

      5. blocked requests[request id]를 제거한다.

7.5.6.2. network.beforeRequestSent 이벤트
이벤트 타입
network.BeforeRequestSent = (
  method: "network.beforeRequestSent",
  params: network.BeforeRequestSentParameters
 )

network.BeforeRequestSentParameters = {
  network.BaseParameters,
  ? initiator: network.Initiator,
}

이 이벤트는 요청이 전송되기 전(네트워크를 통해 전송되기 전이거나 serviceworker 또는 로컬 캐시에서 처리되기 전)에 방출된다.

request와 user context가 주어졌을 때 요청이 사용자 컨텍스트에서 비롯되는지 확인하는 단계는 다음과 같다:
  1. settings를 request의 클라이언트로 둔다.

  2. related navigables를 settings로 관련 navigable 가져오기를 수행한 결과로 둔다.

  3. related navigables의 각 navigable에 대해:

    1. navigable의 연관된 사용자 컨텍스트가 user context이면 true를 반환한다.

  4. false를 반환한다.

related navigables가 주어졌을 때 에뮬레이션된 네트워크 조건 가져오기 단계는 다음과 같다:
  1. related navigables의 각 navigable에 대해:

    1. top-level traversable을 navigable의 최상위 순회 가능 객체로 둔다.

    2. user context를 top-level traversable의 연결된 사용자 컨텍스트로 둔다.

    3. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 네트워크 조건의 순회 가능 객체 네트워크 조건이 top-level traversable을 포함하면, session의 에뮬레이션된 네트워크 조건의 순회 가능 객체 네트워크 조건[top-level traversable]을 반환한다.

    4. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 네트워크 조건의 사용자 컨텍스트 네트워크 조건이 user context를 포함하면, session의 에뮬레이션된 네트워크 조건의 사용자 컨텍스트 네트워크 조건[user context]을 반환한다.

    5. 활성 BiDi 세션의 각 session에 대해:

      1. session의 에뮬레이션된 네트워크 조건의 기본 네트워크 조건이 null이 아니면, session의 에뮬레이션된 네트워크 조건의 기본 네트워크 조건을 반환한다.

  2. null을 반환한다.

환경 설정 객체 settings가 주어졌을 때 WebDriver BiDi 네트워크가 오프라인임 단계는 다음과 같다:
  1. navigable을 settings의 관련 전역 객체의 연결된 Document의 노드 순회 가능 객체로 둔다.

  2. emulated network conditions을 [navigable]로 에뮬레이션된 네트워크 조건 가져오기를 수행한 결과로 둔다.

  3. emulated network conditions이 null이 아니고 emulated network conditions의 offline이 true이면, true를 반환한다.

  4. false를 반환한다.

요청 request가 주어졌을 때 원격 엔드 이벤트 트리거는 WebDriver BiDi 요청 전송 전 단계이다:
  1. 사용자 컨텍스트 집합의 각 user context에 대해:

    1. request 및 user context로 사용자 컨텍스트에서 요청이 시작됨 단계를 수행한 결과가 true이면:

      1. 활성 BiDi 세션의 각 session에 대해:

        참고: user context는 하나 이하의 사용자 컨텍스트-안전하지 않은 인증서 허용 재정의 맵에 포함될 수 있다.

        1. session의 사용자 컨텍스트-안전하지 않은 인증서 허용 재정의 맵이 user context를 포함하면:

          1. accept insecure certificates를 session의 사용자 컨텍스트-안전하지 않은 인증서 허용 재정의 맵[user context]으로 둔다.

          2. accept insecure certificates가 true이면:

            1. 엔드포인트 노드가 안전하지 않은 TLS 연결 허용을 지원함을 단언한다.

            2. request에 대해 기본 인증서 처리 단계를 실행할 때, 단계 a와 그 밖의 모든 구현 정의 인증서 검증 단계를 건너뛴다.

          3. 그렇지 않으면, request에 대해 기본 인증서 처리 단계를 실행할 때, 모든 단계와 모든 구현 정의 인증서 검증 단계를 수행한다.

        참고: user context는 하나 이하의 사용자 컨텍스트-프록시 구성 맵에 포함될 수 있다.

        1. session의 사용자 컨텍스트-프록시 구성 맵이 user context를 포함하면:

          1. proxy configuration을 session의 사용자 컨텍스트-프록시 구성 맵[user context]으로 둔다.

          2. request가 proxy configuration에 정의된 프록시 설정을 사용하도록 보장하기 위해 구현 정의 단계를 수행한다.

            참고: 이 설정은 사용자 컨텍스트가 생성될 때 검증되므로 이 단계에서는 유효하다고 가정한다. 프록시에 접근할 때 발생하는 모든 오류는 요청을 처리할 때 네트워크 오류로 보고된다.

  2. request로 네트워크 요청 본문을 수집할 수도 있음을 수행한다.

  3. 요청 전송 전 맵이 request를 포함하지 않으면, 요청 전송 전 맵[request]을 새 집합으로 설정한다.

  4. redirect count를 request의 리디렉션 횟수로 둔다.

  5. redirect count를 요청 전송 전 맵[request]에 추가한다.

  6. request의 클라이언트가 null이 아니면, related navigables를 request의 클라이언트로 관련 순회 가능 객체 가져오기를 수행한 결과로 둔다. 그렇지 않으면 related navigables를 빈 집합으로 둔다.

  7. response를 null로 둔다.

  8. response status를 "incomplete"로 둔다.

  9. 활성 BiDi 세션의 각 session에 대해:

    1. session, request 및 related navigables로 요청 헤더를 업데이트한다.

  10. "network.beforeRequestSent" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. params를 session, "network.beforeRequestSent", 그리고 request로 네트워크 이벤트 처리를 수행한 결과로 둔다.

    2. initiator를 request로 개시자 가져오기를 수행한 결과로 둔다.

    3. initiator가 비어 있지 않으면, params의 initiator 필드를 initiator로 설정한다.

    4. 단언: params는 network.BeforeRequestSentParameters 생성 규칙과 일치한다.

    5. body를 params 필드가 params로 설정된 network.BeforeRequestSent 생성 규칙과 일치하는 맵으로 둔다.

    6. session 및 body로 이벤트를 발생시킨다.

    7. params["isBlocked"]가 true이면:

      1. blocked requests를 session의 차단된 요청 맵으로 둔다.

      2. request id를 request의 요청 id로 둔다.

      3. blocked requests[request id]을 (request, "beforeRequestSent", null)로 설정한다.

      4. (response, status)를 «"continue request"» 및 request의 요청 id로 대기한 결과로 둔다.

      5. status가 "complete"이면 response status를 status로 설정한다.

      6. blocked requests[request id]을 제거한다.

      참고: 대기하는 동안에는 요청의 추가 처리가 이루어지지 않는다.

  11. emulated network conditions을 related navigables로 에뮬레이션된 네트워크 조건 가져오기를 수행한 결과로 둔다.

  12. emulated network conditions이 null이 아니고 emulated network conditions의 offline이 true이면, (네트워크 오류, "complete")를 반환한다.

  13. (response, response status)를 반환한다.

Fetch의 "HTTP-network-or-cache fetch" 알고리즘에서 반환 값을 반영한다.

7.5.6.3. network.fetchError 이벤트
이벤트 타입
network.FetchError = (
  method: "network.fetchError",
  params: network.FetchErrorParameters
 )

network.FetchErrorParameters = {
  network.BaseParameters,
  errorText: text,
}

이 이벤트는 네트워크 요청이 오류로 종료될 때 방출된다.

원격 끝 이벤트 트리거는 요청 request가 주어졌을 때의 WebDriver BiDi fetch error 단계이다:
  1. before request sent 맵[request]가 request의 리다이렉트 횟수를 포함하지 않으면, request로 WebDriver BiDi before request sent 단계를 실행한다.

    참고: 이는 호출자가 모든 오류 경로에서 WebDriver BiDi before request sent 단계를 명시적으로 호출할 필요 없이, network.fetchError 전에 network.beforeRequestSent가 항상 방출될 수 있도록 보장한다.

  2. request의 클라이언트가 null이 아니면, related navigables를 request의 클라이언트로 관련 navigable 가져오기를 수행한 결과로 둔다. 그렇지 않으면 related navigables를 빈 집합으로 둔다.

  3. request로 네트워크 응답 본문 수집 가능 시 중단을 수행한다.

  4. "network.fetchError" 및 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. params를 session, "network.fetchError", 및 request로 네트워크 이벤트 처리를 수행한 결과로 둔다.

    2. params의 errorText 필드를, 요청이 중단되게 한 오류를 설명하는 구현 정의 문자열로 설정한다.

    3. 단언: params는 network.FetchErrorParameters 생성규칙과 일치한다.

    4. body를 params 필드가 params로 설정된, network.FetchError 생성규칙과 일치하는 맵으로 둔다.

    5. session 및 body로 이벤트를 방출한다.

7.5.6.4. network.responseCompleted 이벤트
이벤트 타입
network.ResponseCompleted = (
  method: "network.responseCompleted",
  params: network.ResponseCompletedParameters
 )

network.ResponseCompletedParameters = {
  network.BaseParameters,
  response: network.ResponseData,
}

이 이벤트는 전체 응답 본문이 수신된 후 방출된다.

원격 끝 이벤트 트리거는 요청 request와 응답 response가 주어졌을 때의 WebDriver BiDi response completed 단계이다:
  1. redirect count를 request의 리다이렉트 횟수로 둔다.

  2. 단언: before request sent 맵[request]이 redirect count를 포함한다.

    참고: 이는 모든 호출자가 이 단계 전에 request로 WebDriver BiDi before request sent 단계를 호출하도록 보장해야 함을 의미한다.

  3. request의 클라이언트가 null이 아니면, related navigables를 request의 클라이언트로 관련 navigable 가져오기를 수행한 결과로 둔다. 그렇지 않으면 related navigables를 빈 집합으로 둔다.

  4. request 및 response로 네트워크 응답 본문 수집 가능 시 수집을 수행한다.

  5. sessions를 "network.responseCompleted" 및 related navigables가 주어졌을 때의 이벤트가 활성화된 세션 집합으로 둔다.

  6. sessions의 각 session에 대해:

    1. params를 session, "network.responseCompleted", 및 request로 네트워크 이벤트 처리를 수행한 결과로 둔다.

    2. 단언: params["isBlocked"]는 false이다.

    3. response data를 response로 응답 데이터 가져오기를 수행한 결과로 둔다.

    4. params의 response 필드를 response data로 설정한다.

    5. 단언: params는 network.ResponseCompletedParameters 생성규칙과 일치한다.

    6. body를 params 필드가 params로 설정된, network.ResponseCompleted 생성규칙과 일치하는 맵으로 둔다.

    7. session 및 body로 이벤트를 방출한다.

7.5.6.5. network.responseStarted 이벤트
이벤트 타입
network.ResponseStarted = (
  method: "network.responseStarted",
  params: network.ResponseStartedParameters
 )

network.ResponseStartedParameters = {
  network.BaseParameters,
  response: network.ResponseData,
}

이 이벤트는 응답 헤더가 수신된 후, 본문이 완료되기 전에 방출된다.

원격 끝 이벤트 트리거는 요청 request와 응답 response가 주어졌을 때의 WebDriver BiDi response started 단계이다:
  1. redirect count를 request의 리다이렉트 횟수로 둔다.

  2. 단언: before request sent 맵[request]은 redirect count와 같다.

    참고: 이는 모든 호출자가 이 단계 전에 request로 WebDriver BiDi before request sent 단계를 호출하도록 보장해야 함을 의미한다.

  3. request의 클라이언트가 null이 아니면, related navigables를 request의 클라이언트로 관련 navigable 가져오기를 수행한 결과로 둔다. 그렇지 않으면 related navigables를 빈 집합으로 둔다.

  4. response status를 "incomplete"로 둔다.

  5. sessions를 "network.responseStarted" 및 related navigables가 주어졌을 때의 이벤트가 활성화된 세션 집합으로 둔다.

  6. sessions의 각 session에 대해:

    1. params를 session, "network.responseStarted", 및 request로 네트워크 이벤트 처리를 수행한 결과로 둔다.

    2. response data를 response로 응답 데이터 가져오기를 수행한 결과로 둔다.

    3. params의 response 필드를 response data로 설정한다.

    4. 단언: params는 network.ResponseStartedParameters 생성규칙과 일치한다.

    5. body를 params 필드가 params로 설정된, network.ResponseStarted 생성규칙과 일치하는 맵으로 둔다.

    6. session 및 body로 이벤트를 방출한다.

    7. params["isBlocked"]가 true이면:

      1. blocked requests를 session의 차단된 요청 맵으로 둔다.

      2. request id를 request의 request id로 둔다.

      3. blocked requests[request id]를 (request, "beforeRequestSent", response)로 설정한다.

      4. (response, status)를 «"continue request"» 및 request id로 await한 결과로 둔다.

      5. status가 "complete"이면 response status를 status로 설정한다.

      6. blocked requests[request id]를 제거한다.

  7. (response, response status)를 반환한다.

7.6. script 모듈

script 모듈은 script realm 및 실행과 관련된 명령 및 이벤트를 포함한다.

7.6.1. 정의

Remote end definition

ScriptCommand = (
  script.AddPreloadScript //
  script.CallFunction //
  script.Disown //
  script.Evaluate //
  script.GetRealms //
  script.RemovePreloadScript
)

local end definition

ScriptResult = (
  script.AddPreloadScriptResult /
  script.CallFunctionResult /
  script.DisownResult /
  script.EvaluateResult /
  script.GetRealmsResult /
  script.RemovePreloadScriptResult
)

ScriptEvent = (
  script.Message //
  script.RealmCreated //
  script.RealmDestroyed
)

7.6.2. 프리로드 스크립트

프리로드 스크립트는 새 Window가 생성될 때, 작성자 정의 스크립트가 실행되기 전에 실행되는 것이다.

TODO: 이를 다른 종류의 렐름에 있는 스크립트로 확장한다.

BiDi 세션은 프리로드 스크립트 맵을 가지며, 이는 키가 UUID이고, 값이 문자열인 function declaration라는 이름의 항목, 리스트인 arguments라는 이름의 항목, 리스트 또는 null인 contexts라는 이름의 항목, 문자열 또는 null인 sandbox라는 이름의 항목, 그리고 집합인 user contexts라는 이름의 항목을 가진 구조체인 맵이다.

참고: 프리로드 스크립트 실행이 구문 오류 또는 런타임 예외로 인해 실패하면, 실행 중이던 렐름에 [ECMAScript] 예외가 보고되고, 다른 프리로드 스크립트는 정상적으로 실행된다.

environment settings가 주어졌을 때 WebDriver BiDi 프리로드 스크립트 실행을 수행하려면:
  1. document를 environment settings의 관련 전역 객체의 연관된 Document로 둔다.

  2. navigable을 document의 navigable로 둔다.

  3. user context를 navigable의 연관된 사용자 컨텍스트로 둔다.

  4. user context id를 user context의 사용자 컨텍스트 ID로 둔다.

  5. 활성 BiDi 세션 안의 각 session에 대해:

    1. session의 프리로드 스크립트 맵의 값 안의 각 preload script에 대해:

      1. preload script의 user contexts의 크기가 0이 아니면:

        1. preload script의 user contexts가 user context id를 포함하지 않으면, 계속한다.

      2. preload script의 contexts가 null이 아니면:

        1. navigable id를 navigable의 최상위 traversable의 id로 둔다.

        2. preload script의 contexts가 navigable id를 포함하지 않으면, 계속한다.

      3. preload script의 sandbox가 null이 아니면, realm을 preload script의 sandbox 및 navigable로 sandbox 렐름 가져오기 또는 생성을 수행한 결과로 둔다. 그렇지 않으면 realm을 environment settings의 렐름 실행 컨텍스트의 Realm 컴포넌트로 둔다.

      4. exception reporting global을 environment settings의 렐름 실행 컨텍스트의 Realm 컴포넌트의 전역 객체로 둔다.

      5. arguments를 preload script의 arguments로 둔다.

      6. deserialized arguments를 빈 리스트로 둔다.

      7. arguments 안의 각 argument에 대해:

        1. channel을 session, realm 및 argument로 채널 생성을 수행한 결과로 둔다.

        2. channel을 deserialized arguments에 추가한다.

      8. base URL을 environment settings의 API 기본 URL로 둔다.

      9. options를 기본 스크립트 fetch 옵션으로 둔다.

      10. function declaration을 preload script의 function declaration으로 둔다.

      11. function body evaluation status를 function declaration, environment settings, base URL, 및 options로 함수 본문 평가를 수행한 결과로 둔다.

      12. function body evaluation status가 갑작스러운 완료이면, exception reporting global에 대해 function body evaluation status.[[Value]]로 주어진 예외 보고를 수행한다.

      13. function object를 function body evaluation status.[[Value]]로 둔다.

      14. IsCallable(function object)이 false이면:

        1. error를 realm 안의 새 TypeError 객체로 둔다.

        2. exception reporting global에 대해 error로 예외 보고를 수행한다.

      15. environment settings로 스크립트 실행 준비를 수행한다.

      16. evaluation status를 Call(function object, null, deserialized arguments)로 설정한다.

      17. environment settings로 스크립트 실행 후 정리를 수행한다.

      18. evaluation status가 갑작스러운 완료이면, exception reporting global에 대해 evaluation status.[[Value]]로 주어진 예외 보고를 수행한다.

7.6.3. 타입

7.6.3.1. script.Channel 타입

원격 엔드 정의 및 로컬 엔드 정의

script.Channel = text;

script.Channel 타입은 원격 엔드에서 로컬 엔드로 사용자 지정 메시지를 보내는 데 사용되는 특정 채널의 id를 나타낸다.

7.6.3.2. script.ChannelValue 타입

원격 엔드 정의

script.ChannelValue = {
  type: "channel",
  value: script.ChannelProperties,
}

script.ChannelProperties = {
  channel: script.Channel,
  ? serializationOptions: script.SerializationOptions,
  ? ownership: script.ResultOwnership,
}

script.ChannelValue 타입은 원격 엔드에서 로컬 엔드로 메시지를 보내는 함수로 역직렬화될 수 있는 ArgumentValue를 나타낸다.

session, realm 및 protocol value가 주어졌을 때 채널을 생성하려면:

  1. channel properties를 protocol value["value"]로 둔다.

  2. steps를 인수 message가 주어졌을 때의 다음 단계로 둔다:

    1. current realm을 현재 Realm Record로 둔다.

    2. session, current realm, channel properties 및 message로 스크립트 메시지를 방출한다.

  3. CreateBuiltinFunction(steps, 1, "", « », realm)를 반환한다.

7.6.3.3. script.EvaluationResult 타입

원격 엔드 정의 및 로컬 엔드 정의

script.EvaluationResult = (
  script.EvaluationResultSuccess /
  script.EvaluationResultException
)

script.EvaluationResultSuccess = {
  type: "success",
  result: script.RemoteValue,
  realm: script.Realm
}

script.EvaluationResultException = {
  type: "exception",
  exceptionDetails: script.ExceptionDetails
  realm: script.Realm
}

script.EvaluationResult 타입은 명령의 반환값을 나타내며 해당 명령은 스크립트를 실행합니다. script.EvaluationResultSuccess 변형이 사용되는 것은 스크립트가 정상적으로 완료되는 경우이며, script.EvaluationResultException 변형이 사용되는 것은 스크립트가 예외를 던지며 완료되는 경우입니다.

7.6.3.4. script.ExceptionDetails 타입

원격 엔드 정의 및 로컬 엔드 정의

script.ExceptionDetails = {
  columnNumber: js-uint,
  exception: script.RemoteValue,
  lineNumber: js-uint,
  stackTrace: script.StackTrace,
  text: text,
}

script.ExceptionDetails 타입은 JavaScript 예외를 나타낸다.

realm, 완료 레코드 record, ownership type 및 session이 주어졌을 때 예외 세부 정보 가져오기:

  1. 단언: record.[[Type]]은 throw이다.

  2. text를 record가 나타내는 오류에 대한 구현 정의 텍스트 설명으로 둔다.

    TODO: 여기의 요구 사항을 더 엄격하게 한다. 사람들은 아마 이 데이터를 정규식이나 그와 비슷하게 좋지 않은 방법으로 구문 분석하려 할 것이다.

  3. serialization options를 필드가 기본값으로 설정된 script.SerializationOptions 생성 규칙과 일치하는 맵으로 둔다.

  4. exception을 record.[[Value]], serialization options, ownership type, 직렬화 내부 맵으로서 새로운 맵, realm 및 session으로 원격 값으로 직렬화한 결과로 둔다.

  5. stack trace를 record가 주어졌을 때 예외의 스택 추적으로 둔다.

  6. stack trace의 크기가 1 이상이면, line number를 stack trace[0]의 lineNumber 필드 값으로 두고, column number를 stack trace[0]의 columnNumber 필드 값으로 둔다. 그렇지 않으면 line number와 column number를 0으로 둔다.

  7. exception details를 text 필드는 text로, exception 필드는 exception으로, lineNumber 필드는 line number로, columnNumber 필드는 column number로, stackTrace 필드는 stack trace로 설정된 script.ExceptionDetails 생성 규칙과 일치하는 맵으로 둔다.

  8. exception details를 반환한다.

7.6.3.5. script.Handle 타입

원격 엔드 정의 및 로컬 엔드 정의

script.Handle = text;

script.Handle 타입은 ECMAScript 런타임이 소유한 객체에 대한 핸들을 나타낸다. 이 핸들은 특정 Realm에서만 유효하다.

각 ECMAScript Realm은 대응하는 핸들 객체 맵을 가진다. 이는 핸들 id에서 그에 대응하는 객체로 가는 강한 맵이다.

7.6.3.6. script.InternalId 타입

원격 엔드 정의 및 로컬 엔드 정의

script.InternalId = text;

script.InternalId 타입은 직렬화 중에 이전에 직렬화된 script.RemoteValue의 id를 나타낸다.

7.6.3.7. script.LocalValue 타입

원격 엔드 정의

script.LocalValue = (
  script.RemoteReference /
  script.PrimitiveProtocolValue /
  script.ChannelValue /
  script.ArrayLocalValue /
  { script.DateLocalValue } /
  script.MapLocalValue /
  script.ObjectLocalValue /
  { script.RegExpLocalValue } /
  script.SetLocalValue
)

script.ListLocalValue = [*script.LocalValue];

script.ArrayLocalValue = {
  type: "array",
  value: script.ListLocalValue,
}

script.DateLocalValue = (
  type: "date",
  value: text
)

script.MappingLocalValue = [*[(script.LocalValue / text), script.LocalValue]];

script.MapLocalValue = {
  type: "map",
  value: script.MappingLocalValue,
}

script.ObjectLocalValue = {
  type: "object",
  value: script.MappingLocalValue,
}

script.RegExpValue = {
  pattern: text,
  ? flags: text,
}

script.RegExpLocalValue = (
  type: "regexp",
  value: script.RegExpValue,
)

script.SetLocalValue = {
  type: "set",
  value: script.ListLocalValue,
}

script.LocalValue 타입은 ECMAScript로 역직렬화될 수 있는 값을 나타낸다. 여기에는 원시 값과 비원시 값뿐만 아니라 원격 참조 및 채널도 포함된다.

serialized key-value list, realm 및 session이 주어졌을 때 키-값 목록을 역직렬화하려면:

  1. deserialized key-value list를 새 목록으로 둡니다.

  2. serialized key-value list의 각 serialized key-value에 대해:

    1. serialized key-value의 크기가 2가 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

    2. serialized key를 serialized key-value[0]으로 둡니다.

    3. serialized key가 string이면, deserialized key를 serialized key로 둡니다.

    4. 그렇지 않으면 deserialized key를 serialized key, realm 및 session으로 시도하여 로컬 값을 역직렬화한 결과로 둡니다.

    5. serialized value를 serialized key-value[1]로 둡니다.

    6. deserialized value를 serialized value, realm 및 session이 주어졌을 때 시도하여 로컬 값을 역직렬화한 결과로 둡니다.

    7. CreateArrayFromList(«deserialized key, deserialized value»)를 deserialized key-value list에 추가합니다.

  3. 데이터 deserialized key-value list와 함께 성공을 반환합니다.

serialized value list, realm 및 session이 주어졌을 때 값 목록을 역직렬화하려면:

  1. deserialized values를 새 목록으로 둡니다.

  2. serialized value list의 각 serialized value에 대해:

    1. deserialized value를 serialized value, realm 및 session이 주어졌을 때 시도하여 로컬 값을 역직렬화한 결과로 둡니다.

    2. deserialized value를 deserialized values에 추가합니다;

  3. 데이터 deserialized values와 함께 성공을 반환합니다.

local protocol value, realm 및 session이 주어졌을 때 로컬 값을 역직렬화하려면:

  1. local protocol value가 script.RemoteReference 생성 규칙과 일치하면, 주어진 local protocol value, realm 및 session의 원격 참조를 역직렬화한 결과를 반환합니다.

  2. local protocol value가 script.PrimitiveProtocolValue 생성 규칙과 일치하면, local protocol value로 기본 프로토콜 값을 역직렬화한 결과를 반환합니다.

  3. local protocol value가 script.ChannelValue 생성 규칙과 일치하면, session, realm 및 local protocol value로 채널을 생성한 결과를 반환합니다.

  4. type을 local protocol value의 type 필드 값으로 두거나, 그러한 필드가 없으면 undefined로 둡니다.

  5. value를 local protocol value의 value 필드 값으로 두거나, 그러한 필드가 없으면 undefined로 둡니다.

  6. 다음 조건 및 관련 단계 목록에서 관련 조건이 true인 첫 번째 단계 집합을 실행합니다:

    type이 문자열 "array"인 경우
    1. deserialized value list를 value, realm 및 session이 주어졌을 때 시도하여 값 목록을 역직렬화한 결과로 둡니다.

    2. 데이터 CreateArrayFromList(deserialized value list)와 함께 성공을 반환합니다.

    type이 문자열 "date"인 경우
    1. value가 날짜 시간 문자열 형식과 일치하지 않으면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

    2. date result를 Construct(Date, value)로 둡니다.

    3. 단언: date result는 비정상 완료가 아닙니다.

    4. 데이터 date result와 함께 성공을 반환합니다.

    type이 문자열 "map"인 경우
    1. deserialized key-value list를 value, realm 및 session으로 시도하여 키-값 목록을 역직렬화한 결과로 둡니다.

    2. iterable을 CreateArrayFromList(deserialized key-value list)로 둡니다

    3. 데이터 Map(iterable)과 함께 성공을 반환합니다.

    type이 문자열 "object"인 경우
    1. deserialized key-value list를 value, realm 및 session으로 시도하여 키-값 목록을 역직렬화한 결과로 둡니다.

    2. iterable을 CreateArrayFromList(deserialized key-value list)로 둡니다

    3. 데이터 Object.fromEntries(iterable)와 함께 성공을 반환합니다.

    type이 문자열 "regexp"인 경우
    1. pattern을 local protocol value의 pattern 필드 값으로 둡니다.

    2. flags를 local protocol value의 flags 필드 값으로 두거나 그러한 필드가 없으면 undefined로 둡니다.

    3. regex_result를 Regexp(pattern, flags)로 둡니다. 이것이 예외를 던지면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

    4. 데이터 regex_result와 함께 성공을 반환합니다.

    type이 문자열 "set"인 경우
    1. deserialized value list를 value, realm 및 session이 주어졌을 때 시도하여 값 목록을 역직렬화한 결과로 둡니다.

    2. iterable을 CreateArrayFromList(deserialized key-value list)로 둡니다

    3. 데이터 Set 객체(iterable)와 함께 성공을 반환합니다.

    그렇지 않은 경우
    오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.
7.6.3.8. script.PreloadScript 타입

원격 엔드 정의 및 로컬 엔드 정의

script.PreloadScript = text;

script.PreloadScript 타입은 렐름 생성 시 실행될 스크립트에 대한 핸들을 나타낸다.

7.6.3.9. script.Realm 타입

원격 엔드 정의 및 로컬 엔드 정의

script.Realm = text;

각 Realm에는 연결된 Realm ID가 있으며, 이는 해당 Realm을 고유하게 식별하는 문자열입니다. 이는 Realm이 생성될 때 암시적으로 설정됩니다.

Realm의 Realm ID는 불투명하며 핸들 객체 맵에 있는 해당 전역 객체의 핸들 ID나, 관련되는 경우 어떠한 내비게이블의 내비게이블 ID에서도 도출할 수 없어야 합니다.

참고: 이는 사용자가 서로 다른 ID 사이의 구현별 관계에 의존하지 않도록 하기 위한 것입니다.

realm id가 주어졌을 때 Realm을 가져오려면:
  1. realm id가 null이면, 데이터 null과 함께 성공을 반환합니다.

  2. ID가 realm id인 Realm이 없으면 오류를 오류 코드 해당 프레임 없음과 함께 반환합니다.

  3. realm을 ID가 realm id인 Realm으로 둡니다.

  4. 데이터 realm과 함께 성공을 반환합니다

여기에는 잘못된 오류 코드가 사용되었습니다

7.6.3.10. script.PrimitiveProtocolValue 타입

원격 엔드 정의 및 로컬 엔드 정의

script.PrimitiveProtocolValue = (
  script.UndefinedValue /
  script.NullValue /
  script.StringValue /
  script.NumberValue /
  script.BooleanValue /
  script.BigIntValue
)

script.UndefinedValue = {
  type: "undefined",
}

script.NullValue = {
  type: "null",
}

script.StringValue = {
  type: "string",
  value: text,
}

script.SpecialNumber = "NaN" / "-0" / "Infinity" / "-Infinity";

script.NumberValue = {
  type: "number",
  value: number / script.SpecialNumber,
}

script.BooleanValue = {
  type: "boolean",
  value: bool,
}

script.BigIntValue = {
  type: "bigint",
  value: text,
}

script.PrimitiveProtocolValue는 참조로는 절대 표현될 수 없고, 값으로만 표현될 수 있는 값을 나타낸다.

value가 주어졌을 때 원시 프로토콜 값 직렬화:

  1. remote value를 undefined로 둔다.

  2. 다음 조건 및 관련 단계 목록에서, 관련 조건이 true인 첫 번째 단계 집합이 있으면 실행한다:

    Type(value)이 undefined인 경우
    remote value를 로컬 엔드 정의의 script.UndefinedValue 생성 규칙과 일치하는 맵으로 둔다.
    Type(value)이 Null인 경우
    remote value를 로컬 엔드 정의의 script.NullValue 생성 규칙과 일치하는 맵으로 둔다.
    Type(value)이 String인 경우
    remote value를 로컬 엔드 정의의 script.StringValue 생성 규칙과 일치하고, value 속성이 value로 설정된 맵으로 둔다.

    이는 단독 서로게이트를 처리하지 않는다

    Type(value)이 Number인 경우
    1. value의 값에 따라 분기한다:

      NaN
      serialized를 "NaN"으로 둔다
      -0
      serialized를 "-0"으로 둔다
      Infinity
      serialized를 "Infinity"로 둔다
      -Infinity
      serialized를 "-Infinity"로 둔다
      그렇지 않은 경우:
      serialized를 value로 둔다
    2. remote value를 로컬 엔드 정의의 script.NumberValue 생성 규칙과 일치하고, value 속성이 serialized로 설정된 맵으로 둔다.

    Type(value)이 Boolean인 경우
    remote value를 로컬 엔드 정의의 script.BooleanValue 생성 규칙과 일치하고, value 속성이 value로 설정된 맵으로 둔다.
    Type(value)이 BigInt인 경우
    remote value를 로컬 엔드 정의의 script.BigIntValue 생성 규칙과 일치하고, value 속성이 value에 ToString 연산을 실행한 결과로 설정된 맵으로 둔다.
  3. remote value를 반환한다

primitive protocol value가 주어졌을 때 원시 프로토콜 값 역직렬화:

  1. type을 primitive protocol value의 type 필드 값으로 둡니다.

  2. value를 undefined로 둡니다.

  3. primitive protocol value에 value 필드가 있는 경우:

    1. value를 primitive protocol value의 value 필드 값으로 둡니다.

  4. 다음 조건 및 관련 단계 목록에서 관련 조건이 true인 첫 번째 단계 집합을 실행합니다:

    type이 문자열 "undefined"인 경우
    데이터 undefined와 함께 성공을 반환합니다.
    type이 문자열 "null"인 경우
    데이터 null과 함께 성공을 반환합니다.
    type이 문자열 "string"인 경우
    데이터 value와 함께 성공을 반환합니다.
    type이 문자열 "number"인 경우
    1. Type(value)이 Number이면, 데이터 value와 함께 성공을 반환합니다.

    2. 단언: Type(value)은 String입니다.

    3. value가 문자열 "NaN"이면, 데이터 NaN과 함께 성공을 반환합니다.

    4. number_result를 StringToNumber(value)로 둡니다.

    5. number_result가 NaN이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다

    6. 데이터 number_result와 함께 성공을 반환합니다.

    type이 문자열 "boolean"인 경우
    데이터 value와 함께 성공을 반환합니다.
    type이 문자열 "bigint"인 경우
    1. bigint_result를 StringToBigInt(value)로 둡니다.

    2. bigint_result가 undefined이면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다

    3. 데이터 bigint_result와 함께 성공을 반환합니다.

  5. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다

7.6.3.11. script.RealmInfo 타입

로컬 엔드 정의

script.RealmInfo = (
  script.WindowRealmInfo /
  script.DedicatedWorkerRealmInfo /
  script.SharedWorkerRealmInfo /
  script.ServiceWorkerRealmInfo /
  script.WorkerRealmInfo /
  script.PaintWorkletRealmInfo /
  script.AudioWorkletRealmInfo /
  script.WorkletRealmInfo
)

script.BaseRealmInfo = (
  realm: script.Realm,
  origin: text
)

script.WindowRealmInfo = {
  script.BaseRealmInfo,
  type: "window",
  context: browsingContext.BrowsingContext,
  ? userContext: browser.UserContext,
  ? sandbox: text
}

script.DedicatedWorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "dedicated-worker",
  owners: [script.Realm]
}

script.SharedWorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "shared-worker"
}

script.ServiceWorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "service-worker"
}

script.WorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "worker"
}

script.PaintWorkletRealmInfo = {
  script.BaseRealmInfo,
  type: "paint-worklet"
}

script.AudioWorkletRealmInfo = {
  script.BaseRealmInfo,
  type: "audio-worklet"
}

script.WorkletRealmInfo = {
  script.BaseRealmInfo,
  type: "worklet"
}

참고: script.RealmInfo 변형과 script.RealmType 값 사이에는 1:1 관계가 있다.

script.RealmInfo 타입은 렐름의 속성을 나타낸다.

주어진 realm으로 순회 가능 객체 가져오기:
  1. global object를 realm의 전역 객체로 둔다.

  2. global object를 래핑 해제된 global object로 둔다.

  3. global object가 Window 객체가 아니면, null을 반환한다.

  4. document를 global object의 래핑된 Window의 연결된 Document로 둔다.

  5. document의 노드 순회 가능 객체를 반환한다.

주어진 global object으로 워커의 소유자 가져오기:
  1. 단언: global object는 WorkerGlobalScope 객체이다.

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

  3. global object의 연결된 소유자 집합의 각 owner에 대해:

    1. owner environment settings를 owner의 관련 설정 객체로 둔다.

    2. owner realm info를 주어진 owner environment settings으로 Realm 정보 가져오기를 수행한 결과로 둔다.

    3. owner realm info가 null이면, 계속한다.

    4. owner realm info["id"]를 owners에 추가한다.

  4. owners를 반환한다.

주어진 environment settings으로 Realm 정보 가져오기:
  1. realm을 environment settings의 Realm 실행 컨텍스트의 Realm 구성 요소로 둔다.

  2. realm id를 realm의 Realm id로 둔다.

  3. origin을 environment settings의 origin이 주어졌을 때 오리진 직렬화를 수행한 결과로 둔다.

  4. global object를 environment settings이 지정한 전역 객체로 둔다

  5. 처음으로 일치하는 조건에 해당하는 단계를 실행한다:

    global object가 Window 객체인 경우
    1. document를 environment settings의 관련 전역 객체의 연결된 Document로 둔다.

    2. navigable을 document의 노드 순회 가능 객체로 둔다.

    3. navigable이 null이면, null을 반환한다.

    4. navigable id를 navigable의 순회 가능 객체 id로 둔다.

    5. user context id를 navigable의 연결된 사용자 컨텍스트의 사용자 컨텍스트 id로 둔다

    6. realm info를 realm 필드는 realm id로, origin 필드는 origin으로, context 필드는 navigable id로, 그리고 userContext 필드는 user context id로 설정된 script.WindowRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 SandboxWindowProxy 객체인 경우
    TODO: 이것이 샌드박스를 처리하기에 올바른 구성인지 명확하지 않다.
    1. document를 global object의 래핑된 Window의 연결된 Document로 둔다.

    2. navigable을 document의 노드 순회 가능 객체로 둔다.

    3. navigable이 null이면, null을 반환한다.

    4. navigable id를 navigable의 순회 가능 객체 id로 둔다.

    5. user context id를 navigable의 연결된 사용자 컨텍스트의 사용자 컨텍스트 id로 둔다

    6. sandbox name을 주어진 realm으로 샌드박스 이름 가져오기를 수행한 결과로 둔다.

    7. 단언: sandbox name은 null이 아니다.

    8. realm info를 realm 필드는 realm id로, origin 필드는 origin으로, context 필드는 navigable id로, userContext 필드는 user context id로, 그리고 sandbox 필드는 sandbox name으로 설정된 script.WindowRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 DedicatedWorkerGlobalScope 객체인 경우
    1. owners를 주어진 global object으로 워커의 소유자 가져오기를 수행한 결과로 둔다.

    2. 단언: owners에는 정확히 하나의 항목이 있다.

    3. realm info를 realm 필드는 realm id로, origin 필드는 origin으로, 그리고 owners 필드는 owners로 설정된 script.DedicatedWorkerRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 SharedWorkerGlobalScope 객체인 경우
    1. realm info를 realm 필드는 realm id로, 그리고 origin 필드는 origin으로 설정된 script.SharedWorkerRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 ServiceWorkerGlobalScope 객체인 경우
    1. realm info를 realm 필드는 realm id로, 그리고 origin 필드는 origin으로 설정된 script.ServiceWorkerRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 WorkerGlobalScope 객체인 경우
    1. realm info를 realm 필드는 realm id로, 그리고 origin 필드는 origin으로 설정된 script.WorkerRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 PaintWorkletGlobalScope 객체인 경우
    1. realm info를 realm 필드는 realm id로, 그리고 origin 필드는 origin으로 설정된 script.PaintWorkletRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 AudioWorkletGlobalScope 객체인 경우
    1. realm info를 realm 필드는 realm id로, 그리고 origin 필드는 origin으로 설정된 script.AudioWorkletRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    global object가 WorkletGlobalScope 객체인 경우
    1. realm info를 realm 필드는 realm id로, 그리고 origin 필드는 origin으로 설정된 script.WorkletRealmInfo 생성 규칙과 일치하는 맵으로 둔다.

    그렇지 않은 경우:
    1. realm info를 null로 둔다.

  6. realm info를 반환한다

참고: 이 명세의 향후 버전에서도 "-"를 기준으로 분할한 유형 이름의 마지막 구성 요소가 WorkerGlobalScope를 구현하는 전역 객체의 경우 항상 "worker"이고, WorkletGlobalScope를 구현하는 전역 객체의 경우 "worklet"이라는 불변 조건을 유지한다.

7.6.3.12. script.RealmType 타입

원격 엔드 정의 및 로컬 엔드 정의

script.RealmType = "window" / "dedicated-worker" / "shared-worker" / "service-worker" /
                   "worker" / "paint-worklet" / "audio-worklet" / "worklet"

script.RealmType 타입은 Realm의 여러 타입을 나타낸다.

7.6.3.13. script.RemoteReference 타입

원격 엔드 정의

script.RemoteReference = (
  script.SharedReference /
  script.RemoteObjectReference
)

script.SharedReference = {
   sharedId: script.SharedId

   ? handle: script.Handle,
   Extensible
}

script.RemoteObjectReference = {
   handle: script.Handle,

   ? sharedId: script.SharedId
   Extensible
}

script.RemoteReference 타입은 주어진 Realm의 핸들 객체 맵 안에 있는 기존 ECMAScript 객체에 대한 원격 참조를 나타내는 script.RemoteObjectReference이거나, 노드에 대한 참조를 나타내는 script.SharedReference이다.

"stale object reference" 경우를 처리한다.

참고: 제공된 참조가 handle과 sharedId를 모두 가지면, 알고리즘은 handle을 무시하고 sharedId만 따른다.

remote reference, realm 및 session가 주어졌을 때 원격 참조 역직렬화를 수행하려면:
  1. 단언: remote reference는 script.RemoteReference 생성식과 일치한다.

  2. remote reference가 script.SharedReference 생성식과 일치하면, remote reference, realm 및 session로 공유 참조 역직렬화를 수행한 결과를 반환한다.

  3. remote reference 및 realm으로 원격 객체 참조 역직렬화를 수행한 결과를 반환한다.

remote object reference와 realm이 주어졌을 때 원격 객체 참조를 역직렬화하려면:
  1. handle id를 remote object reference의 handle 필드 값으로 둡니다.

  2. handle map을 realm의 핸들 객체 맵으로 둡니다

  3. handle map이 handle id를 포함하지 않으면, 오류를 오류 코드 해당 핸들 없음과 함께 반환합니다.

  4. 데이터 handle map[handle id]와 함께 성공을 반환합니다.

shared reference, realm 및 session이 주어졌을 때 공유 참조를 역직렬화하려면:
  1. shared reference가 script.SharedReference 생성 규칙과 일치한다고 단언합니다.

  2. navigable을 realm으로 내비게이블을 가져온 결과로 둡니다.

  3. navigable이 null이면, 오류를 오류 코드 해당 노드 없음과 함께 반환합니다.

    참고: 이는 Realm이 Window 전역이 아닐 때 발생합니다.

  4. shared id를 shared reference의 sharedId 필드 값으로 둡니다.

  5. node를 session, navigable 및 shared id로 시도하여 노드를 가져온 결과로 둡니다.

  6. node가 null이면, 오류를 오류 코드 해당 노드 없음과 함께 반환합니다.

  7. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둡니다.

  8. node의 노드 문서의 출처가 environment settings의 출처와 동일 출처 도메인이 아니면, 오류를 오류 코드 해당 노드 없음과 함께 반환합니다.

    참고: 이는 WebDriver-BiDi를 사용하여 원래 스크립트 접근을 허용하지 않는 Realm 사이에서 객체를 전달할 수 없도록 보장합니다.

  9. realm global object을 realm의 전역 객체로 둡니다.

  10. realm global object이 SandboxWindowProxy 객체이면, node를 realm에서 node를 래핑하는 SandboxProxy로 설정합니다.

  11. 데이터 node와 함께 성공을 반환합니다.

7.6.3.14. script.RemoteValue 타입

원격 엔드 정의 및 로컬 엔드 정의

script.RemoteValue = (
  script.PrimitiveProtocolValue /
  script.SymbolRemoteValue /
  script.ArrayRemoteValue /
  script.ObjectRemoteValue /
  script.FunctionRemoteValue /
  script.RegExpRemoteValue /
  script.DateRemoteValue /
  script.MapRemoteValue /
  script.SetRemoteValue /
  script.WeakMapRemoteValue /
  script.WeakSetRemoteValue /
  script.GeneratorRemoteValue /
  script.ErrorRemoteValue /
  script.ProxyRemoteValue /
  script.PromiseRemoteValue /
  script.TypedArrayRemoteValue /
  script.ArrayBufferRemoteValue /
  script.NodeListRemoteValue /
  script.HTMLCollectionRemoteValue /
  script.NodeRemoteValue /
  script.WindowProxyRemoteValue
)

script.ListRemoteValue = [*script.RemoteValue];

script.MappingRemoteValue = [*[(script.RemoteValue / text), script.RemoteValue]];

script.SymbolRemoteValue = {
  type: "symbol",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ArrayRemoteValue = {
  type: "array",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.ObjectRemoteValue = {
  type: "object",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.MappingRemoteValue,
}

script.FunctionRemoteValue = {
  type: "function",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.RegExpRemoteValue = {
  script.RegExpLocalValue,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.DateRemoteValue = {
  script.DateLocalValue,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.MapRemoteValue = {
  type: "map",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.MappingRemoteValue,
}

script.SetRemoteValue = {
  type: "set",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue
}

script.WeakMapRemoteValue = {
  type: "weakmap",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.WeakSetRemoteValue = {
  type: "weakset",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.GeneratorRemoteValue = {
  type: "generator",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ErrorRemoteValue = {
  type: "error",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ProxyRemoteValue = {
  type: "proxy",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.PromiseRemoteValue = {
  type: "promise",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.TypedArrayRemoteValue = {
  type: "typedarray",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ArrayBufferRemoteValue = {
  type: "arraybuffer",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.NodeListRemoteValue = {
  type: "nodelist",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.HTMLCollectionRemoteValue = {
  type: "htmlcollection",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.NodeRemoteValue = {
  type: "node",
  ? sharedId: script.SharedId,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.NodeProperties,
}

script.NodeProperties = {
  nodeType: js-uint,
  childNodeCount: js-uint,
  ? attributes: {*text => text},
  ? children: [*script.NodeRemoteValue],
  ? localName: text,
  ? mode: "open" / "closed",
  ? namespaceURI: text,
  ? nodeValue: text,
  ? shadowRoot: script.NodeRemoteValue / null,
}

script.WindowProxyRemoteValue = {
  type: "window",
  value: script.WindowProxyProperties,
  ? handle: script.Handle,
  ? internalId: script.InternalId
}

script.WindowProxyProperties = {
  context: browsingContext.BrowsingContext
}

WASM 타입 추가?

WindowProxy도 Node와 유사한 스타일로 속성을 가져야 하는가?

String / Number / 등 래퍼 객체를 특별히 처리할 것인가?

ECMAScript 런타임에서 접근 가능한 값은 script.RemoteValue로 지정되는 미러 객체로 표현된다. 값의 타입은 type 속성에 지정된다. JSON으로 표현 가능한 원시 값의 경우, 이는 값을 value 속성에 포함한다. JSON으로 표현할 수 없는 원시 값의 경우, value 속성은 값의 문자열 표현을 포함한다.

원시 객체가 아닌 객체의 경우, handle 속성이 존재하면 객체에 대한 고유한 문자열 핸들을 포함한다. 핸들은 각 직렬화마다 고유하다. 원격 끝은 대응하는 핸들이 있는 객체를, 해당 핸들로 script.disown이 호출되거나 realm 자체가 버려질 때까지 (예: 탐색으로 인해) 살아 있게 유지한다.

일부 비원시 타입의 경우, value 속성은 ECMAScript 객체 안의 데이터 표현을 포함한다. 컨테이너 타입의 경우 이는 추가적인 script.RemoteValue 인스턴스를 포함할 수 있다. 객체가 중복 객체인 경우, 즉 현재 script.RemoteValue 안에서 객체가 이미 직렬화되었거나, 아마도 순환의 일부로 직렬화되었거나, 또는 최대 직렬화 깊이에 도달한 경우에는 value 속성이 null이거나 생략될 수 있다.

동일한 script.RemoteValue 안에 중복 객체가 있는 경우, 값은 원격 값 중 하나에만 제공되며, 지정된 직렬화에서 중복 객체 모두에는 ECMAScript 객체마다 고유한 internalId가 제공된다.

노드도 script.RemoteValue 인스턴스로 표현된다. 이들은 value 속성에 노드의 부분 직렬화를 가진다.

미러 객체의 생명주기를 재고한다.

참고: 미러 객체는 원본 객체를 런타임에서 살아 있게 유지하지 않는다. 런타임에서 객체가 버려지면, 프로토콜을 통해 그 객체에 접근하려는 이후의 시도는 오류가 된다.

realm, ownership type 및 object가 주어졌을 때 객체에 대한 핸들을 얻으려면:
  1. ownership type이 "none"과 같으면, null을 반환한다.

  2. handle id를 object에 대한 새롭고 고유한 문자열 핸들로 둔다.

  3. handle map을 realm의 handle object map으로 둔다

  4. handle map[handle id]를 object로 설정한다.

  5. handle id를 결과로 반환한다.

node 및 session이 주어졌을 때 노드에 대한 shared id 가져오기:
  1. node를 unwrapped node로 둔다.

  2. node가 Node를 구현하지 않으면, null을 반환한다.

  3. navigable을 node의 node navigable로 둔다.

  4. navigable이 null이면, null을 반환한다.

  5. session, navigable 및 node로 노드 참조 가져오기 또는 생성을 반환한다.

serialization internal map, remote value 및 object가 주어졌을 때 필요한 경우 internal id 설정:
  1. serialization internal map이 object를 포함하지 않으면, serialization internal map[object]를 remote value로 설정한다.

  2. 그렇지 않으면, 다음 단계를 실행한다:

    1. previously serialized remote value를 serialization internal map[object]로 둔다.

    2. previously serialized remote value에 internalId 필드가 없으면, 다음 단계를 실행한다:

      1. internal id를 진정한 난수 또는 의사 난수를 기반으로 한 UUID의 문자열 표현으로 둔다.

      2. previously serialized remote value의 internalId 필드를 internal id로 설정한다.

    3. remote value의 internalId 필드를 previously serialized remote value 안의 internalId 필드로 설정한다.

value, serialization options, ownership type, serialization internal map, realm 및 session이 주어졌을 때 원격 값으로 직렬화를 수행하려면:

  1. remote value를 value가 주어졌을 때 원시 프로토콜 값 직렬화를 수행한 결과로 둔다.

  2. remote value가 undefined가 아니면, remote value를 반환한다.

  3. handle id를 realm, ownership type 및 value로 객체에 대한 핸들을 수행한 결과로 둔다.

  4. ownership type을 "none"으로 설정한다.

  5. value가 serialization internal map 안에 있으면 known object를 true로 두고, 그렇지 않으면 false로 둔다.

  6. 다음 조건 및 관련 단계 목록에서, 관련 조건이 true인 첫 번째 단계 집합을 실행한다:

    Type(value)이 Symbol인 경우
    remote value를 로컬 엔드 정의의 script.SymbolRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    IsArray(value)
    remote value를 session, script.ArrayRemoteValue, handle id, known object, value, serialization options, ownership type, serialization internal map, realm 및 session로 Array-like 직렬화를 수행한 결과로 둔다.
    IsRegExp(value)
    1. pattern을 ToString(Get(value, "source"))으로 둔다.

    2. flags를 ToString(Get(value, "flags"))로 둔다.

    3. serialized를 로컬 엔드 정의의 script.RegExpValue 생성식과 일치하는 맵으로 두고, pattern 속성을 pattern으로, flags 속성을 flags로 설정한다.

    4. remote value를 로컬 엔드 정의의 script.RegExpRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략하며, value 속성을 serialized로 설정한다.

    value가 [[DateValue]] 내부 슬롯을 가지는 경우.
    1. serialized를 Call(Date.prototype.toISOString, value)로 설정한다.

    2. 단언: serialized는 throw 완료가 아니다.

    3. remote value를 로컬 엔드 정의의 script.DateRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략하며, value를 serialized로 설정한다.

    value가 [[MapData]] 내부 슬롯을 가지는 경우
    1. remote value를 로컬 엔드 정의의 script.MapRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.

    2. serialization internal map, remote value 및 value로 필요하면 내부 ID 설정을 수행한다.

    3. serialized를 null로 둔다.

    4. known object가 false이고 serialization options["maxObjectDepth"]가 0이 아니면, 다음 단계를 실행한다:

      1. serialized를 CreateMapIterator(value, key+value), serialization options, ownership type, serialization internal map, realm 및 session로 매핑으로 직렬화를 수행한 결과로 둔다.

    5. serialized가 null이 아니면, remote value의 value 필드를 serialized로 설정한다.

    value가 [[SetData]] 내부 슬롯을 가지는 경우
    1. remote value를 로컬 엔드 정의의 script.SetRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.

    2. serialization internal map, remote value 및 value로 필요하면 내부 ID 설정을 수행한다.

    3. serialized를 null로 둔다.

    4. known object가 false이고 serialization options["maxObjectDepth"]가 0이 아니면, 다음 단계를 실행한다:

      1. serialized를 CreateSetIterator(value, value), serialization options, ownership type, serialization internal map, realm 및 session로 리스트로 직렬화를 수행한 결과로 둔다.

    5. serialized가 null이 아니면, remote value의 value 필드를 serialized로 설정한다.

    value가 [[WeakMapData]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.WeakMapRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 [[WeakSetData]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.WeakSetRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 [[GeneratorState]] 내부 슬롯 또는 [[AsyncGeneratorState]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.GeneratorRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 [[ErrorData]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.ErrorRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 [[ProxyHandler]] 내부 슬롯 및 [[ProxyTarget]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.ProxyRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    IsPromise(value)
    remote value를 로컬 엔드 정의의 script.PromiseRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 [[TypedArrayName]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.TypedArrayRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 [[ArrayBufferData]] 내부 슬롯을 가지는 경우
    remote value를 로컬 엔드 정의의 script.ArrayBufferRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    value가 NodeList를 구현하는 플랫폼 객체인 경우
    remote value를 script.NodeListRemoteValue,handle id, known object, value, serialization options, ownership type, serialization internal map, realm 및 session로 Array-like 직렬화를 수행한 결과로 둔다.
    value가 HTMLCollection을 구현하는 플랫폼 객체인 경우
    remote value를 script.HTMLCollectionRemoteValue, handle id, known object, value, serialization options, ownership type, known object, serialization internal map, realm 및 session로 Array-like 직렬화를 수행한 결과로 둔다.
    value가 Node를 구현하는 플랫폼 객체인 경우
    1. shared id를 value 및 session로 노드에 대한 공유 ID 가져오기를 수행한 결과로 둔다.

    2. remote value를 로컬 엔드 정의의 script.NodeRemoteValue 생성식과 일치하는 맵으로 두고, sharedId 속성을 shared id가 null이 아니면 shared id로 설정하고, 그렇지 않으면 생략하며, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.

    3. serialization internal map, remote value 및 value로 필요하면 내부 ID 설정을 수행한다.

    4. serialized를 null로 둔다.

    5. known object가 false이면, 다음 단계를 실행한다:

      1. serialized를 맵으로 둔다.

      2. serialized["nodeType"]를 Get(value, "nodeType")로 설정한다.

      3. node value를 Get(value, "nodeValue")로 설정한다.

      4. node value가 null이 아니면 serialized["nodeValue"]를 node value로 설정한다.

      5. value가 Element 또는 Attr를 구현하면:

        1. serialized["localName"]을 Get(value, "localName")으로 설정한다.

        2. serialized["namespaceURI"]를 Get(value, "namespaceURI")로 설정한다

      6. child node count를 value의 자식의 크기로 둔다.

      7. serialized["childNodeCount"]를 child node count로 설정한다.

      8. serialization options["maxDomDepth"]가 0과 같거나, value가 ShadowRoot를 구현하고 serialization options["includeShadowTree"]가 "none"이거나, serialization options["includeShadowTree"]가 "open"이고 value의 mode가 "closed"이면, children을 null로 둔다.

        그렇지 않으면, children을 빈 리스트로 두고, value의 자식 안의 각 노드 child에 대해:

        1. child serialization options를 serialization options의 복제본으로 둔다.

        2. child serialization options["maxDomDepth"]가 null이 아니면, child serialization options["maxDomDepth"]를 child serialization options["maxDomDepth"] - 1로 설정한다.

        3. serialized를 child, child serialization options, ownership type, serialization internal map, realm 및 session으로 원격 값으로 직렬화를 수행한 결과로 둔다.

        4. serialized를 children에 추가한다.

      9. children이 null이 아니면, serialized["children"]을 children으로 설정한다.

      10. value가 Element를 구현하면:

        1. attributes를 새 맵으로 둔다.

        2. value의 속성 리스트 안의 각 attribute에 대해:

          1. name을 attribute의 정규화된 이름으로 둔다

          2. value를 attribute의 값으로 둔다.

          3. attributes[name]을 value로 설정한다

        3. serialized["attributes"]를 attributes로 설정한다.

        4. shadow root를 value의 shadow root로 둔다.

        5. shadow root가 null이면, serialized shadow를 null로 둔다. 그렇지 않으면 다음 하위 단계를 실행한다:

          1. serialized shadow를 shadow root, serialization options, ownership type, serialization internal map, realm 및 session으로 원격 값으로 직렬화를 수행한 결과로 둔다.

        6. serialized["shadowRoot"]를 serialized shadow로 설정한다.

      11. value가 ShadowRoot를 구현하면, serialized["mode"]를 value의 mode로 설정한다.

    6. serialized가 null이 아니면, remote value의 value 필드를 serialized로 설정한다.

    value가 WindowProxy를 구현하는 플랫폼 객체인 경우
    1. window를 value의 [[WindowProxy]] 내부 슬롯 값으로 둔다.

    2. navigable을 window의 navigable로 둔다.

    3. navigable id를 navigable의 navigable id로 둔다.

    4. serialized를 로컬 엔드 정의의 script.WindowProxyProperties 생성식과 일치하는 맵으로 두고, context 속성을 navigable id로 설정한다.

    5. remote value를 로컬 엔드 정의의 script.WindowProxyRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략하며, value 속성을 serialized로 설정한다.

    value가 플랫폼 객체인 경우
    1. remote value를 로컬 엔드 정의의 script.ObjectRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    IsCallable(value)
    remote value를 로컬 엔드 정의의 script.FunctionRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.
    그 외의 경우:
    1. 단언: Type(value)은 Object이다

    2. remote value를 로컬 엔드 정의의 script.ObjectRemoteValue 생성식과 일치하는 맵으로 두고, handle 속성을 handle id가 null이 아니면 handle id로 설정하고, 그렇지 않으면 생략한다.

    3. serialization internal map, remote value 및 value로 필요하면 내부 ID 설정을 수행한다.

    4. serialized를 null로 둔다.

    5. known object가 false이고 serialization options["maxObjectDepth"]가 0이 아니면, 다음 단계를 실행한다:

      1. serialized를 EnumerableOwnPropertyNames(value, key+value), serialization options, ownership type, serialization internal map, realm 및 session로 매핑으로 직렬화를 수행한 결과로 둔다.

    6. serialized가 null이 아니면, remote value의 value 필드를 serialized로 설정한다.

  7. remote value를 반환한다

children과 자식 노드는 서로 다른 것이다. childNodeCount가 childNodes를 참조해야 하거나, childrenCount로 이름이 바뀌어야 한다.

production, handle id, known object, value, serialization options, ownership type, serialization internal map, realm, 및 session이 주어졌을 때 Array-like 직렬화:
  1. remote value를 production과 일치하는 맵으로 두며, handle 속성은 handle id가 null이 아니면 그것으로 설정하고, 그렇지 않으면 생략한다.

  2. serialization internal map, remote value 및 value로 필요한 경우 internal id 설정을 수행한다.

  3. known object가 false이고, serialization options["maxObjectDepth"]가 0이 아니면:

    1. serialized를 CreateArrayIterator(value, value), serialization options, ownership type, serialization internal map, realm, 및 session으로 list로 직렬화한 결과로 둔다.

    2. serialized가 null이 아니면, remote value의 value 필드를 serialized로 설정한다.

  4. remote value를 반환한다

iterable, serialization options, ownership type, serialization internal map, realm, 및 session이 주어졌을 때 list로 직렬화:
  1. serialization options["maxObjectDepth"]가 null이 아니면, 단언: serialization options["maxObjectDepth"]는 0보다 크다.

  2. serialized를 새 목록으로 둔다.

  3. GetIterator(iterable, sync)의 IteratorToList 안의 각 child value에 대해:

    1. child serialization options를 serialization options의 클론으로 둔다.

    2. child serialization options["maxObjectDepth"]가 null이 아니면, child serialization options["maxObjectDepth"]를 child serialization options["maxObjectDepth"] - 1로 설정한다.

    3. serialized child를 child value, child serialization options, ownership type, serialization internal map, realm, 및 session으로 remote value로 직렬화한 결과로 둔다.

    4. serialized child를 serialized에 추가한다.

  4. serialized를 반환한다

iterable, serialization options, ownership type, serialization internal map, realm, 및 session이 주어졌을 때 mapping으로 직렬화하려면:

  1. serialization options["maxObjectDepth"]가 null이 아니면, 단언: serialization options["maxObjectDepth"]는 0보다 크다.

  2. serialized를 새 목록으로 둔다.

  3. GetIterator(iterable, sync)의 IteratorToList 안의 item에 대해:

    1. 단언: IsArray(item)

    2. property를 CreateListFromArrayLike(item)로 둔다

    3. 단언: property는 크기 2의 목록이다

    4. key를 property[0]으로 두고, value를 property[1]로 둔다

    5. child serialization options를 serialization options의 클론으로 둔다.

    6. child serialization options["maxObjectDepth"]가 null이 아니면, child serialization options["maxObjectDepth"]를 child serialization options["maxObjectDepth"] - 1로 설정한다.

    7. Type(key)이 String이면, serialized key를 child key로 두고, 그렇지 않으면 serialized key를 child key, child serialization options, ownership type, serialization internal map, realm, 및 session으로 remote value로 직렬화한 결과로 둔다.

    8. serialized value를 value, child serialization options, ownership type, serialization internal map, realm, 및 session으로 remote value로 직렬화한 결과로 둔다.

    9. serialized child를 («serialized key, serialized value»)로 둔다.

    10. serialized child를 serialized에 추가한다.

  4. serialized를 반환한다

7.6.3.15. script.ResultOwnership 타입
script.ResultOwnership = "root" / "none"

script.ResultOwnership은 직렬화된 값의 소유권이 어떻게 처리될지를 지정한다.

7.6.3.16. script.SerializationOptions 타입

원격 엔드 정의

script.SerializationOptions = {
  ? maxDomDepth: (js-uint / null) .default 0,
  ? maxObjectDepth: (js-uint / null) .default null,
  ? includeShadowTree: ("none" / "open" / "all") .default "none",
}

script.SerializationOptions는 ECMAScript 객체가 어떻게 직렬화될지를 지정할 수 있게 한다.

7.6.3.17. script.SharedId 타입

원격 엔드 정의 및 로컬 엔드 정의

script.SharedId = text;

script.SharedId 타입은 어떤 렐름에서도 사용할 수 있는 DOM Node에 대한 참조를 나타낸다 (Sandbox Realms 포함).

7.6.3.18. script.StackFrame 타입

원격 엔드 정의 및 로컬 엔드 정의

script.StackFrame = {
  columnNumber: js-uint,
  functionName: text,
  lineNumber: js-uint,
  url: text,
}

스택 추적의 프레임은 StackFrame 객체로 표현된다. 이는 스크립트의 URL을 나타내는 url 속성, 실행 중인 함수의 이름을 나타내는 functionName 속성, 그리고 실행된 코드의 줄 번호와 열 번호를 나타내는 lineNumber 및 columnNumber 속성을 가진다.

7.6.3.19. script.StackTrace 타입

원격 엔드 정의 및 로컬 엔드 정의

script.StackTrace = {
  callFrames: [*script.StackFrame],
}

script.StackTrace 타입은 스크립트 실행 중 어느 시점의 JavaScript 스택을 나타낸다.

참고: 스택 프레임의 리스트를 얻는 방법과 그 리스트의 속성에 대한 세부 사항은 충분히 명세되지 않았으므로, 여기의 세부 사항은 구현 정의이다.

구현은 스택 프레임 리스트를 생성할 수 있다고 가정한다. 이는 JavaScript 호출 스택의 각 항목마다 하나의 엔트리를 가지는 리스트이며, 가장 최근의 것부터 시작한다. 각 엔트리는 스크립트 script 안의 문장 또는 표현식 실행에 대응하는 단일 스택 프레임이며, 다음 필드를 포함한다:

script url
script를 포함하는 리소스의 url
function
실행 중인 함수의 이름
line number
script를 포함하는 리소스의 맨 위를 기준으로 한, 실행된 코드의 0 기반 줄 번호.
column number
script를 포함하는 리소스의 해당 줄 시작을 기준으로 한, 실행된 코드의 0 기반 열 번호.

스택 프레임 리스트 stack으로 스택 추적 구성을 수행하려면:

  1. call frames를 새 리스트로 둔다.

  2. stack 안의 각 스택 프레임 frame에 대해, 가장 최근에 실행된 프레임부터 시작하여 다음 단계를 실행한다:

    1. url을 frame의 script url의 URL이 주어졌을 때 URL 직렬화기를 실행한 결과로 둔다.

    2. frame info를 script.StackFrame 생성식과 일치하는 새 맵으로 두고, url 필드는 url로, functionName 필드는 frame의 function으로, lineNumber 필드는 frame의 line number로, 그리고 columnNumber 필드는 frame의 column number로 설정한다.

  3. frame info를 call frames에 추가한다.

  4. stack trace를 script.StackTrace 생성식과 일치하는 새 맵으로 두고, callFrames 속성을 call frames로 설정한다.

  5. stack trace를 반환한다.

현재 스택 추적은 실행 중인 실행 컨텍스트의 호출 스택을 나타내는 스택 프레임 리스트가 주어졌을 때 스택 추적 구성을 수행한 결과이다.

예외 또는 throw 타입의 Completion Record인 exception으로 예외에 대한 스택 추적은 다음과 같이 주어진다:

  1. exception이 예외로 던져진 값이면, record를 exception을 던지기 위해 생성된 Completion Record로 둔다. 그렇지 않으면 record를 exception으로 둔다.

  2. stack을 record가 생성된 지점의 실행에 대응하는 스택 프레임 리스트로 둔다.

  3. stack이 주어졌을 때 스택 추적 구성을 수행한 결과를 반환한다.

7.6.3.20. script.Source 타입

로컬 엔드 정의

script.Source = {
  realm: script.Realm,
  ? context: browsingContext.BrowsingContext,
  ? userContext: browser.UserContext
}

script.Source 타입은 스크립트 관련 이벤트가 발생한 script.Realm과 선택적 browsingContext.BrowsingContext 및 관련 browser.UserContext를 나타낸다.

source realm이 주어졌을 때 소스 가져오기:
  1. realm을 source realm의 Realm id로 둔다.

  2. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 source realm인 환경 설정 객체로 둔다.

  3. environment settings에 연결된 Document가 있으면:

    1. document를 environment settings의 연결된 Document로 둔다.

    2. navigable을 document의 노드 순회 가능 객체로 둔다.

    3. navigable이 null이 아니면 navigable id를 navigable의 순회 가능 객체 id로 둔다.

    4. user context id를 navigable의 연결된 사용자 컨텍스트의 사용자 컨텍스트 id로 둔다.

    그렇지 않으면 navigable을 null로 둔다.

  4. source를 realm 필드는 realm로 설정하고, context 필드는 navigable이 null이 아니면 navigable id로 설정하고 그렇지 않으면 설정하지 않으며, userContext 필드는 |navigable이 null이 아니면 user context id로 설정하고 그렇지 않으면 설정하지 않은 script.Source 생성 규칙과 일치하는 맵으로 둔다.

  5. source를 반환한다.

7.6.3.21. script.Target 타입

원격 엔드 정의

script.RealmTarget = {
  realm: script.Realm
}

script.ContextTarget = {
  context: browsingContext.BrowsingContext,
  ? sandbox: text
}

script.Target = (
  script.ContextTarget /
  script.RealmTarget
)

script.Target 타입은 script.Realm 또는 browsingContext.BrowsingContext 중 하나인 값을 나타낸다. 이는 navigable 식별자가 navigable의 활성 문서와 연관된 렐름을 대신할 수 있는 경우에 유용하다.

navigable id와 sandbox가 주어졌을 때 내비게이블에서 Realm을 가져오려면:
  1. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

  2. sandbox가 null이거나 빈 문자열인 경우:

    1. document를 navigable의 활성 문서로 둡니다.

    2. environment settings를 환경 설정 객체 중 관련 전역 객체의 연결된 Document가 document인 것으로 둡니다.

    3. realm을 environment settings의 Realm 실행 컨텍스트의 Realm 구성 요소로 둡니다.

  3. 그렇지 않으면: realm을 sandbox와 navigable이 주어졌을 때 시도하여 샌드박스 Realm을 가져오거나 생성한 결과로 둡니다.

  4. 데이터 realm과 함께 성공을 반환합니다

여기에는 잘못된 오류 코드가 사용되었습니다

target이 주어졌을 때 대상에서 Realm을 가져오려면:
  1. target이 script.ContextTarget 생성 규칙과 일치하는 경우:

    1. sandbox를 null로 둡니다.

    2. target이 "sandbox"를 포함하면, sandbox를 target["sandbox"]로 설정합니다.

    3. realm을 target["context"]와 sandbox로 내비게이블에서 Realm을 가져온 결과로 둡니다.

  2. 그렇지 않으면:

    1. 단언: target은 script.RealmTarget 생성 규칙과 일치합니다.

    2. realm id를 target의 realm 필드 값으로 둡니다.

    3. realm을 realm id가 주어졌을 때 Realm을 가져온 결과로 둡니다.

  3. 데이터 realm과 함께 성공을 반환합니다

여기에는 잘못된 오류 코드가 사용되었습니다

7.6.4. 명령

7.6.4.1. script.addPreloadScript 명령

The script.addPreloadScript 명령은 프리로드 스크립트를 추가한다.

명령 타입
script.AddPreloadScript = (
  method: "script.addPreloadScript",
  params: script.AddPreloadScriptParameters
)

script.AddPreloadScriptParameters = {
  functionDeclaration: text,
  ? arguments: [*script.ChannelValue],
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
  ? sandbox: text
}
반환 타입
script.AddPreloadScriptResult = {
  script: script.PreloadScript
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. command parameters가 "userContexts"를 포함하고 command parameters가 "contexts"를 포함하면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

  2. function declaration을 command parameters의 functionDeclaration 필드로 둡니다.

  3. arguments를 command parameters의 arguments 필드가 존재하면 그 필드로, 그렇지 않으면 빈 목록으로 둡니다.

  4. user contexts를 집합으로 둡니다.

  5. navigables를 null로 둡니다.

  6. command parameters의 contexts 필드가 존재하는 경우:

    1. navigables를 빈 집합으로 설정합니다.

    2. command parameters["contexts"]의 각 navigable id에 대해

      1. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

      2. navigable이 최상위 순회 가능 항목이 아니면, 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다.

      3. navigable을 navigables에 추가합니다.

  7. 그렇지 않고, command parameters가 userContexts를 포함하는 경우:

    1. user contexts를 command parameters["userContexts"]로 집합을 생성한 결과로 설정합니다.

    2. user contexts의 각 user context id에 대해:

      1. user context를 user context id로 사용자 컨텍스트를 가져온 결과로 설정합니다.

      2. user context가 null이면, 오류를 오류 코드 해당 사용자 컨텍스트 없음과 함께 반환합니다.

  8. sandbox를 command parameters의 "sandbox" 필드가 존재하면 그 값으로, 그렇지 않으면 null로 둡니다.

  9. script를 UUID의 문자열 표현으로 둡니다.

  10. preload script map을 session의 사전 로드 스크립트 맵으로 둡니다.

  11. preload script map[script]을 function declaration function declaration, arguments arguments, contexts navigables, sandbox sandbox, 그리고 user contexts user contexts를 가진 구조체로 설정합니다.

  12. script 필드가 script로 설정된 script.AddPreloadScriptResult와 일치하는 새로운 맵을 반환합니다.

7.6.4.2. script.disown 명령

script.disown 명령은 주어진 핸들의 소유권을 해제한다. 이는 다른 핸들이나 강한 ECMAScript 참조가 있을 수 있으므로, 핸들이 가리키는 객체가 가비지 수집될 것임을 보장하지 않는다.

명령 타입
script.Disown = (
  method: "script.disown",
  params: script.DisownParameters
)

script.DisownParameters = {
  handles: [*script.Handle]
  target: script.Target;
}
반환 타입
script.DisownResult = EmptyResult
command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. realm을 command parameters의 target 필드 값이 주어졌을 때 시도하여 대상에서 Realm을 가져온 결과로 둡니다.

  2. handles를 command parameters의 handles 필드 값으로 둡니다.

  3. handles의 각 handle id에 대해:

    1. handle map을 realm의 핸들 객체 맵으로 둡니다

    2. handle map이 handle id를 포함하면, handle map에서 handle id를 제거합니다.

  4. 데이터 null과 함께 성공을 반환합니다.

7.6.4.3. script.callFunction 명령

script.callFunction 명령은 주어진 렐름에서 주어진 인수로 제공된 함수를 호출한다.

RealmInfo는 렐름 또는 navigable일 수 있다.

참고: functionDeclaration 안의 화살표 함수의 경우, this 인수는 함수의 this 바인딩에 영향을 주지 않는다.

명령 타입
script.CallFunction = (
  method: "script.callFunction",
  params: script.CallFunctionParameters
)

script.CallFunctionParameters = {
  functionDeclaration: text,
  awaitPromise: bool,
  target: script.Target,
  ? arguments: [*script.LocalValue],
  ? resultOwnership: script.ResultOwnership,
  ? serializationOptions: script.SerializationOptions,
  ? this: script.LocalValue,
  ? userActivation: bool .default false,
}
반환 타입
script.CallFunctionResult = script.EvaluationResult

TODO: script.evaluate에 설명된 대로 timeout 인수를 추가한다.

realm, serialized arguments list 및 session이 주어졌을 때 인수를 역직렬화하려면:

  1. deserialized arguments list를 빈 목록으로 둡니다.

  2. serialized arguments list의 각 serialized argument에 대해:

    1. deserialized argument를 serialized argument, realm 및 session이 주어졌을 때 시도하여 로컬 값을 역직렬화한 결과로 둡니다.

    2. deserialized argument를 deserialized arguments list에 추가합니다.

  3. 데이터 deserialized arguments list와 함께 성공을 반환합니다.

function declaration, environment settings, base URL 및 options가 주어졌을 때 함수 본문을 평가하려면:

참고: function declaration은 괄호로 둘러싸인 후 평가됩니다.

  1. bypassDisabledScripting을 true로 둡니다.

  2. parenthesized function declaration을 «"(", function declaration, ")"»를 연결한 결과로 둡니다

  3. function script를 parenthesized function declaration, environment settings, base URL, options 및 bypassDisabledScripting으로 클래식 스크립트를 생성한 결과로 둡니다.

  4. environment settings으로 스크립트 실행을 준비합니다.

  5. function body evaluation status를 ScriptEvaluation(function script의 레코드)로 둡니다.

  6. environment settings으로 스크립트 실행 후 정리합니다.

  7. function body evaluation status를 반환합니다.

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. realm을 command parameters의 target 필드 값이 주어졌을 때 시도하여 대상에서 Realm을 가져온 결과로 둡니다.

  2. realm id를 realm의 Realm ID로 둡니다.

  3. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둡니다.

  4. command arguments를 command parameters의 arguments 필드 값으로 둡니다.

  5. deserialized arguments를 빈 목록으로 둡니다.

  6. command arguments가 null이 아니면, deserialized arguments를 realm, command arguments 및 session이 주어졌을 때 시도하여 인수를 역직렬화한 결과로 설정합니다.

  7. this parameter를 command parameters의 this 필드 값으로 둡니다.

  8. this object를 null로 둡니다.

  9. this parameter가 null이 아니면, this object를 this parameter, realm 및 session이 주어졌을 때 시도하여 로컬 값을 역직렬화한 결과로 설정합니다.

  10. function declaration을 command parameters의 functionDeclaration 필드 값으로 둡니다.

  11. await promise를 command parameters의 awaitPromise 필드 값으로 둡니다.

  12. serialization options를 command parameters의 serializationOptions 필드가 존재하면 그 값으로, 그렇지 않으면 필드가 기본값으로 설정된 script.SerializationOptions 생성 규칙과 일치하는 맵으로 둡니다.

  13. result ownership을 command parameters의 resultOwnership 필드가 존재하면 그 값으로, 그렇지 않으면 none으로 둡니다.

  14. base URL을 environment settings의 API 기준 URL로 둡니다.

  15. options를 기본 스크립트 가져오기 옵션으로 둡니다.

  16. function body evaluation status를 function declaration, environment settings, base URL 및 options으로 함수 본문을 평가한 결과로 둡니다.

  17. function body evaluation status.[[Type]]이 throw인 경우:

    1. exception details를 realm, function body evaluation status, result ownership 및 session이 주어졌을 때 예외 세부 정보를 가져온 결과로 둡니다.

    2. exceptionDetails 필드가 exception details로 설정된 script.EvaluationResultException 생성 규칙과 일치하는 새로운 맵을 반환합니다.

  18. function object을 function body evaluation status.[[Value]]로 둡니다.

  19. IsCallable(function object)이 false인 경우:

    1. 오류를 오류 코드 유효하지 않은 인수와 함께 반환합니다

  20. command parameters["userActivation"]이 true이면, 활성화 알림 단계를 실행합니다.

  21. environment settings으로 스크립트 실행을 준비합니다.

  22. evaluation status를 Call(function object, this object, deserialized arguments)로 설정합니다.

  23. evaluation status.[[Type]]이 normal이고, await promise이 true이며, IsPromise(evaluation status.[[Value]])인 경우:

    1. evaluation status를 Await(evaluation status.[[Value]])로 설정합니다.

  24. environment settings으로 스크립트 실행 후 정리합니다.

  25. evaluation status.[[Type]]이 throw인 경우:

    1. exception details를 realm, evaluation status, result ownership 및 session이 주어졌을 때 예외 세부 정보를 가져온 결과로 둡니다.

    2. exceptionDetails 필드가 exception details로 설정된 script.EvaluationResultException 생성 규칙과 일치하는 새로운 맵을 반환합니다.

  26. 단언: evaluation status.[[Type]]은 normal입니다.

  27. result를 evaluation status.[[Value]], serialization options, result ownership, 직렬화 내부 맵으로 사용할 새로운 맵, realm 및 session으로 원격 값으로 직렬화한 결과로 둡니다.

  28. realm 필드가 realm id로 설정되고, result 필드가 result로 설정된 script.EvaluationResultSuccess 생성 규칙과 일치하는 새로운 맵을 반환합니다.

7.6.4.4. script.evaluate 명령

script.evaluate 명령은 지정된 realm에서 제공된 스크립트를 평가한다. 편의를 위해 realm 대신 navigable을 제공할 수 있으며, 이 경우 사용되는 realm은 브라우징 컨텍스트의 활성 문서의 realm이다.

이 메서드는 제공된 스크립트를 실행한 값을 반환한다. 단, promise를 반환하고 awaitPromise가 true인 경우에는 promise의 resolved value를 반환한다.

명령 타입
script.Evaluate = (
  method: "script.evaluate",
  params: script.EvaluateParameters
)

script.EvaluateParameters = {
  expression: text,
  target: script.Target,
  awaitPromise: bool,
  ? resultOwnership: script.ResultOwnership,
  ? serializationOptions: script.SerializationOptions,
  ? userActivation: bool .default false,
}
반환 타입
script.EvaluateResult = script.EvaluationResult

TODO: timeout 인수를 추가한다. 이것이 어떻게 동작해야 하는지는 완전히 명확하지 않다. Chrome에서는 timeout이 promise resolve 단계에는 적용되지 않는 것처럼 보이지만, 이는 클라이언트가 원하는 것은 아닐 가능성이 높다.

session 및 command parameters가 주어졌을 때 원격 엔드 단계는 다음과 같다:

  1. realm을 command parameters의 target 필드 값이 주어졌을 때 대상에서 Realm 가져오기를 시도한 결과로 둔다.

  2. realm id를 realm의 Realm id로 둔다.

  3. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둔다.

  4. source를 command parameters의 expression 필드 값으로 둔다.

  5. await promise을 command parameters의 awaitPromise 필드 값으로 둔다.

  6. serialization options을 command parameters의 serializationOptions 필드가 있으면 그 값으로, 그렇지 않으면 필드가 기본값으로 설정된 script.SerializationOptions 생성 규칙과 일치하는 맵으로 둔다.

  7. result ownership을 command parameters의 resultOwnership 필드 값이 있으면 그 값으로, 그렇지 않으면 none으로 둔다.

  8. options을 기본 스크립트 가져오기 옵션으로 둔다.

  9. base URL을 environment settings의 API 기준 URL로 둔다.

  10. bypassDisabledScripting을 true로 둔다.

  11. script를 source, environment settings, base URL, options 및 bypassDisabledScripting으로 클래식 스크립트 생성을 수행한 결과로 둔다.

  12. command parameters["userActivation"]이 true이면, 활성화 알림 단계를 실행한다.

  13. environment settings으로 스크립트 실행 준비를 수행한다.

  14. evaluation status를 ScriptEvaluation(script의 레코드)로 설정한다.

  15. evaluation status.[[Type]]이 normal이고, await promise이 true이며, IsPromise(evaluation status.[[Value]])이면:

    1. evaluation status를 Await(evaluation status.[[Value]])로 설정한다.

  16. environment settings으로 스크립트 실행 후 정리를 수행한다.

  17. evaluation status.[[Type]]이 throw이면:

    1. exception details을 realm, evaluation status, result ownership 및 session으로 예외 세부 정보 가져오기를 수행한 결과로 둔다.

    2. realm 필드가 realm id로, 그리고 exceptionDetails 필드가 exception details로 설정된 script.EvaluationResultException 생성 규칙과 일치하는 새 맵을 반환한다.

  18. 단언: evaluation status.[[Type]]은 normal이다.

  19. result를 evaluation status.[[Value]], serialization options, result ownership, 직렬화 내부 맵으로서 새 맵, realm 및 session으로 원격 값으로 직렬화한 결과로 둔다.

  20. realm 필드가 realm id로, 그리고 result 필드가 result로 설정된 script.EvaluationResultSuccess 생성 규칙과 일치하는 새 맵을 반환한다.

7.6.4.5. script.getRealms 명령

script.getRealms 명령은 모든 Realm의 목록을 반환하며, 선택적으로 특정 유형의 Realm 또는 내비게이블의 활성 문서와 연결된 Realm으로 필터링할 수 있습니다.

명령 유형
script.GetRealms = (
  method: "script.getRealms",
  params: script.GetRealmsParameters
)

script.GetRealmsParameters = {
  ? context: browsingContext.BrowsingContext,
  ? type: script.RealmType,
}
반환 유형
script.GetRealmsResult = {
  realms: [*script.RealmInfo]
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. environment settings를 환경 설정 객체 중 실행 준비 플래그가 설정된 모든 객체의 목록으로 둡니다.

  2. command parameters가 context를 포함하는 경우:

    1. navigable을 command parameters["context"]로 시도하여 내비게이블을 가져온 결과로 둡니다.

    2. document를 navigable의 활성 문서로 둡니다.

    3. navigable environment settings를 목록으로 둡니다.

    4. environment settings의 각 settings에 대해:

      1. 다음 조건 중 하나라도 충족되는 경우:

        settings를 navigable environment settings에 추가합니다.

    5. environment settings를 navigable environment settings로 설정합니다.

  3. realms를 목록으로 둡니다.

  4. environment settings의 각 settings에 대해:

    1. realm info를 settings가 주어졌을 때 Realm 정보를 가져온 결과로 둡니다.

    2. command parameters가 type을 포함하고 realm info["type"]이 command parameters["type"]과 같지 않으면 계속합니다.

    3. realm info가 null이 아니면, realm info를 realms에 추가합니다.

  5. body를 realms 필드가 realms로 설정된 script.GetRealmsResult 생성 규칙과 일치하는 맵으로 둡니다.

  6. 데이터 body와 함께 성공을 반환합니다.

중첩된 워커 등을 위해 Realm 부모도 허용하도록 이를 확장해야 합니까? 아니면 모든 상위 워커를 가져와야 합니까?

단순한 리터럴 일치보다 더 정교한 필터 시스템이 필요할 수도 있습니다.

7.6.4.6. script.removePreloadScript 명령

script.removePreloadScript 명령은 사전 로드 스크립트를 제거합니다.

명령 유형
script.RemovePreloadScript = (
  method: "script.removePreloadScript",
  params: script.RemovePreloadScriptParameters
)

script.RemovePreloadScriptParameters = {
  script: script.PreloadScript
}
반환 유형
script.RemovePreloadScriptResult = EmptyResult
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. script를 command parameters의 "script" 필드 값으로 둡니다.

  2. preload script map을 session의 사전 로드 스크립트 맵으로 둡니다.

  3. preload script map이 script를 포함하지 않으면, 오류를 오류 코드 해당 스크립트 없음과 함께 반환합니다.

  4. preload script map에서 script를 제거합니다.

  5. null을 반환합니다

7.6.5. 이벤트

7.6.5.1. script.message 이벤트
이벤트 타입
script.Message = (
  method: "script.message",
  params: script.MessageParameters
 )

script.MessageParameters = {
  channel: script.Channel,
  data: script.RemoteValue,
  source: script.Source,
}
원격 끝 이벤트 트리거는 session, realm, channel properties, 그리고 message가 주어졌을 때 스크립트 메시지 내보내기 단계입니다:
  1. environment settings를 Realm 실행 컨텍스트의 Realm 구성 요소가 realm인 환경 설정 객체로 둡니다.

  2. related navigables를 environment settings가 주어졌을 때 관련 내비게이블을 가져온 결과로 둡니다.

  3. session, "script.message" 및 related navigables이 주어졌을 때 이벤트가 활성화되어 있으면:

    1. channel properties가 "serializationOptions"를 포함하면, serialization options를 channel properties의 serializationOptions 필드 값으로 둡니다. 그렇지 않으면 serialization options를 필드가 기본값으로 설정된 script.SerializationOptions 생성 규칙과 일치하는 맵으로 둡니다.

    2. channel properties가 "ownership"을 포함하면, ownership type을 channel properties["ownership"]으로 둡니다. 그렇지 않으면 ownership type을 "none"으로 둡니다.

    3. data를 message, serialization options, ownership type, 직렬화 내부 맵으로 사용할 새로운 맵 및 realm이 주어졌을 때 원격 값으로 직렬화한 결과로 둡니다.

    4. source를 realm으로 소스를 가져온 결과로 둡니다.

    5. params를 channel 필드가 channel properties["channel"]로 설정되고, data 필드가 data로 설정되며, source 필드가 source로 설정된 script.MessageParameters 생성 규칙과 일치하는 맵으로 둡니다.

    6. body를 params 필드가 params로 설정된 script.Message 생성 규칙과 일치하는 맵으로 둡니다.

    7. session과 body로 이벤트를 내보냅니다.

7.6.5.2. script.realmCreated 이벤트
이벤트 타입
script.RealmCreated = (
 method: "script.realmCreated",
 params: script.RealmInfo
)
원격 엔드 이벤트 트리거는 다음과 같다:

창 환경 설정 객체 설정, 워커 환경 설정 객체 설정 또는 워크릿 환경 설정 객체 설정 알고리즘 중 하나가 호출되면, 설정 객체를 반환하기 직전에:

  1. environment settings를 새로 생성된 환경 설정 객체로 둔다.

  2. realm info를 environment settings이 주어졌을 때 Realm 정보 가져오기를 수행한 결과로 둔다.

  3. realm info가 null이면, 반환한다.

  4. related navigables를 environment settings이 주어졌을 때 관련 순회 가능 객체 가져오기를 수행한 결과로 둔다.

  5. body를 params 필드가 realm info로 설정된 script.RealmCreated 생성 규칙과 일치하는 맵으로 둔다.

  6. "script.realmCreated" 및 related navigables이 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. session 및 body로 이벤트를 발생시킨다.

session, navigables 및 include global이 주어졌을 때 구독 우선순위 2인 원격 엔드 구독 단계는 다음과 같다:

  1. environment settings를 실행 준비 플래그가 설정된 모든 환경 설정 객체의 목록으로 둔다.

  2. environment settings의 각 settings에 대해:

    1. related navigables를 새 집합으로 둔다.

    2. settings의 관련 전역 객체의 연결된 Document가 Document이면:

      1. navigable을 settings의 관련 전역 객체의 연결된 Document의 노드 순회 가능 객체로 둔다.

      2. navigable이 null이면, 계속한다.

      3. top-level traversible을 navigable의 최상위 순회 가능 객체로 둔다.

      4. top-level traversible이 navigables에 없으면, 계속한다.

      5. top-level traversible을 related navigables에 추가한다.

      그렇지 않고, include global이 false이면, 계속한다.

    3. realm info를 주어진 settings으로 Realm 정보 가져오기를 수행한 결과로 둔다.

    4. realm info가 null이면, 계속한다.

    5. body를 params 필드가 realm info로 설정된 script.RealmCreated 생성 규칙과 일치하는 맵으로 둔다.

    6. session, "script.realmCreated" 및 related navigables이 주어졌을 때 이벤트가 활성화됨이면:

      1. session 및 body로 이벤트를 발생시킨다.

여기의 순서를 더 명확하게 정의해야 하는가?

7.6.5.3. script.realmDestroyed 이벤트
이벤트 타입
script.RealmDestroyed = (
  method: "script.realmDestroyed",
  params: script.RealmDestroyedParameters
)

script.RealmDestroyedParameters = {
  realm: script.Realm
}

원격 엔드 이벤트 트리거는 다음과 같다:
document로 다음 문서 언로드 정리 단계를 정의한다:
  1. related navigables를 빈 집합으로 설정합니다.

  2. document의 탐색 가능 항목을 related navigables에 추가합니다.

  3. document의 worklet 전역 범위에 있는 각 worklet global scope에 대해:

    1. realm을 worklet global scope의 관련 Realm으로 설정합니다.

    2. realm id를 realm의 realm id로 설정합니다.

    3. params를 script.RealmDestroyedParameters 프로덕션과 일치하며 realm 필드가 realm id로 설정된 맵으로 설정합니다.

    4. body를 script.RealmDestroyed 프로덕션과 일치하며 params 필드가 params로 설정된 맵으로 설정합니다.

    5. "script.realmDestroyed"와 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

      1. session과 body를 사용하여 이벤트를 방출합니다.

  4. environment settings를, 그 관련 전역 객체의 연결된 Document가 document인 환경 설정 객체로 설정합니다.

  5. realm을 environment settings의 realm 실행 컨텍스트의 Realm 구성 요소로 설정합니다.

  6. realm id를 realm의 realm id로 설정합니다.

  7. params를 script.RealmDestroyedParameters 프로덕션과 일치하며 realm 필드가 realm id로 설정된 맵으로 설정합니다.

  8. body를 script.RealmDestroyed 프로덕션과 일치하며 params 필드가 params로 설정된 맵으로 설정합니다.

  9. "script.realmDestroyed"와 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. session과 body를 사용하여 이벤트를 방출합니다.

워커 이벤트 루프 event loop가 워커의 수명 주기가 끝나거나, 워커 종료 알고리즘을 통해 조기에 소멸될 때마다:

  1. environment settings를 event loop가 담당 이벤트 루프인 환경 설정 객체로 설정합니다.

  2. related navigables를 environment settings가 주어졌을 때 관련 탐색 가능 항목을 가져온 결과로 설정합니다.

  3. realm을 environment settings의 환경 설정 객체의 Realm으로 설정합니다.

  4. realm id를 realm의 realm id로 설정합니다.

  5. params를 script.RealmDestroyedParameters 프로덕션과 일치하며 realm 필드가 realm id로 설정된 맵으로 설정합니다.

  6. body를 script.RealmDestroyed 프로덕션과 일치하며 params 필드가 params로 설정된 맵으로 설정합니다.

  7. "script.realmDestroyed"와 related navigables가 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. session과 body를 사용하여 이벤트를 방출합니다.

7.7. storage 모듈

storage 모듈은 스토리지와 관련된 기능 및 이벤트를 포함한다.

스토리지 파티션은 사용자 에이전트가 쿠키 및 로컬 스토리지 같은 영속 데이터를 구성할 수 있는 네임스페이스이다.

스토리지 파티션 키는 맵이며, 스토리지 파티션을 고유하게 식별한다.

7.7.1. 정의

원격 엔드 정의

StorageCommand = (
  storage.DeleteCookies //
  storage.GetCookies //
  storage.SetCookie
)

로컬 엔드 정의

StorageResult = (
  storage.DeleteCookiesResult /
  storage.GetCookiesResult /
  storage.SetCookieResult
)

7.7.2. 타입

7.7.2.1. storage.PartitionKey 타입

로컬 엔드 정의

storage.PartitionKey = {
  ? userContext: text,
  ? sourceOrigin: text,
  Extensible,
}

storage.PartitionKey 타입은 스토리지 파티션 키를 나타낸다.

다음 표준 스토리지 파티션 키 속성 표는 잘 알려진 의미를 가지며 원격 엔드가 지원하도록 선택할 수 있는 속성을 열거한다. 구현은 추가 확장 스토리지 파티션 키 속성을 정의할 수 있다.

속성 정의
"userContext" 사용자 컨텍스트 ID
"sourceOrigin" 스토리지 파티션에 접근할 수 있는 리소스의 origin 직렬화

원격 끝은 임의의 수의 확장 스토리지 파티션 키 속성을 지원할 수 있습니다. 다른 구현과의 충돌을 방지하기 위해 이러한 속성은 공급업체 및 사용자 에이전트에 대한 고유 식별자로 시작하고 그 뒤에 U+003A (:)가 와야 합니다.

원격 끝에는 0개 이상의 항목을 포함하는 스토리지 파티션 키 속성의 기본값 맵이 있습니다. 각 키는 스토리지 파티션 키가 표준 스토리지 파티션에 해당하는 경우 표준 스토리지 파티션 키 속성 표의 멤버여야 하며, 그렇지 않은 경우 확장 스토리지 파티션 키 속성이어야 하고, 값은 사용자가 명시적인 값을 제공하지 않을 때 사용될 해당 파티션 키의 기본값을 나타냅니다. 정확한 항목은 구현 정의이며 구현이 채택한 스토리지 파티셔닝에 의해 결정됩니다.

원격 끝에는 0개 이상의 항목을 포함하는 필수 파티션 키 속성의 목록이 있습니다. 각 키는 스토리지 파티션 키가 표준 스토리지 파티션에 해당하는 경우 표준 스토리지 파티션 키 속성 표의 멤버여야 하며, 그렇지 않은 경우 확장 스토리지 파티션 키 속성이어야 합니다. 정확한 항목은 구현 정의이며 구현이 채택한 스토리지 파티셔닝에 의해 결정됩니다. 이 목록에는 기본값을 사용할 수 없는 파티션 키만 포함됩니다. 따라서 이 목록은 스토리지 파티션 키 속성의 기본값의 키와 어떠한 항목도 공유해서는 안 됩니다.

filter가 주어졌을 때 필터를 역직렬화하려면:
  1. deserialized filter를 빈 맵으로 둡니다.

  2. filter의 각 name → value에 대해:

    1. deserialized name을 쿠키 변환 표에서 JSON 키 name에 해당하는 필드 이름으로 둡니다.

    2. name이 "value"이면, deserialized value를 value로 프로토콜 바이트를 역직렬화한 결과로 설정하고, 그렇지 않으면 deserialized value를 value로 둡니다.

    3. deserialized filter[deserialized name]을 deserialized value로 설정합니다.

  3. deserialized filter를 반환합니다.

partition spec이 주어졌을 때 스토리지 파티션 명세를 확장하려면:
  1. partition spec이 null인 경우:

    1. partition spec을 빈 맵으로 설정합니다.

  2. 그렇지 않고, partition spec["type"]이 "context"인 경우:

    1. navigable을 partition spec["context"]가 주어졌을 때 시도하여 내비게이블을 가져온 결과로 둡니다.

    2. partition key를 navigable의 연결된 스토리지 파티션의 키로 둡니다.

    3. 데이터 partition key와 함께 성공을 반환합니다.

  3. partition key를 빈 맵으로 둡니다.

  4. 스토리지 파티션 키 속성의 기본값에 있는 각 name → default value에 대해:

    1. partition spec[name]이 존재하면 value를 그 값으로, 그렇지 않으면 default value로 둡니다.

    2. partition key[name]을 value로 설정합니다.

  5. 원격 끝의 필수 파티션 키 속성에 있는 각 name에 대해:

    1. partition spec[name]이 존재하는 경우:

      1. partition key][name]을 partition spec[name]로 설정합니다.

    2. 그렇지 않으면:

      1. 오류를 오류 코드 불충분하게 지정된 스토리지 파티션과 함께 반환합니다.

  6. 데이터 partition key와 함께 성공을 반환합니다.

storage partition key가 주어졌을 때 쿠키 저장소를 가져오려면:
  1. storage partition key가 현존하는 스토리지 파티션을 고유하게 식별하는 경우:

    1. store를 해당 스토리지 파티션의 쿠키 저장소로 둡니다.

    2. 데이터 store와 함께 성공을 반환합니다.

  2. 오류를 오류 코드 해당 스토리지 파티션 없음과 함께 반환합니다.

stored cookie와 filter가 주어졌을 때 쿠키를 일치시키려면:
  1. filter의 각 name → value에 대해:

    1. stored cookie[name]이 value와 같지 않은 경우:

      1. false를 반환합니다.

  2. true를 반환합니다.

cookie store와 filter가 주어졌을 때 일치하는 쿠키를 가져오려면:
  1. cookies를 새 목록으로 둡니다.

  2. deserialized filter를 filter로 필터를 역직렬화한 결과로 설정합니다.

  3. cookie store의 각 stored cookie에 대해:

    1. stored cookie와 deserialized filter로 쿠키를 일치시킨 결과가 true인 경우:

      1. stored cookie를 cookies에 추가합니다.

  4. cookies를 반환합니다.

7.7.3. 명령

7.7.3.1. storage.getCookies 명령

storage.getCookies 명령은 제공된 매개변수 집합과 일치하는 0개 이상의 쿠키를 검색한다.

명령 타입
storage.GetCookies = (
  method: "storage.getCookies",
  params: storage.GetCookiesParameters
)


storage.CookieFilter = {
  ? name: text,
  ? value: network.BytesValue,
  ? domain: text,
  ? path: text,
  ? size: js-uint,
  ? httpOnly: bool,
  ? secure: bool,
  ? sameSite: network.SameSite,
  ? expiry: js-uint,
  Extensible,
}

storage.BrowsingContextPartitionDescriptor = {
  type: "context",
  context: browsingContext.BrowsingContext
}

storage.StorageKeyPartitionDescriptor = {
  type: "storageKey",
  ? userContext: text,
  ? sourceOrigin: text,
  Extensible,
}

storage.PartitionDescriptor = (
  storage.BrowsingContextPartitionDescriptor /
  storage.StorageKeyPartitionDescriptor
)

storage.GetCookiesParameters = {
  ? filter: storage.CookieFilter,
  ? partition: storage.PartitionDescriptor,
}
반환 타입
storage.GetCookiesResult = {
  cookies: [*network.Cookie],
  partitionKey: storage.PartitionKey,
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. filter를 command parameters의 filter 필드가 존재하면 그 값으로, 존재하지 않으면 빈 맵으로 둡니다.

  2. partition spec을 command parameters의 partition 필드가 존재하면 그 값으로, 존재하지 않으면 null로 둡니다.

  3. partition key를 partition spec으로 시도하여 스토리지 파티션 명세를 확장한 결과로 둡니다.

  4. store를 partition key로 시도하여 쿠키 저장소를 가져온 결과로 둡니다.

  5. cookies를 store와 filter로 일치하는 쿠키를 가져온 결과로 둡니다.

  6. serialized cookies를 새 목록으로 둡니다.

  7. cookies의 각 cookie에 대해:

    1. serialized cookie를 cookie가 주어졌을 때 쿠키를 직렬화한 결과로 둡니다.

    2. serialized cookie를 serialized cookies에 추가합니다.

  8. body를 cookies 필드가 serialized cookies로 설정되고 partitionKey 필드가 partition key로 설정된 storage.GetCookiesResult 생성 규칙과 일치하는 맵으로 둡니다.

  9. 데이터 body와 함께 성공을 반환합니다.

7.7.3.2. storage.setCookie 명령

storage.setCookie 명령은 쿠키 저장소 안에 새 쿠키를 생성하며, [COOKIES]에 따라 일치하는 그 저장소 안의 모든 쿠키를 대체한다.

명령 타입
storage.SetCookie = (
  method: "storage.setCookie",
  params: storage.SetCookieParameters,
)


storage.PartialCookie = {
  name: text,
  value: network.BytesValue,
  domain: text,
  ? path: text,
  ? httpOnly: bool,
  ? secure: bool,
  ? sameSite: network.SameSite,
  ? expiry: js-uint,
  Extensible,
}

storage.SetCookieParameters = {
  cookie: storage.PartialCookie,
  ? partition: storage.PartitionDescriptor,
}
반환 타입
storage.SetCookieResult = {
  partitionKey: storage.PartitionKey
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. cookie spec을 command parameters의 cookie 필드 값으로 둡니다.

  2. partition spec을 command parameters의 partition 필드가 존재하면 그 값으로, 존재하지 않으면 null로 둡니다.

  3. partition key를 partition spec으로 시도하여 스토리지 파티션 명세를 확장한 결과로 둡니다.

  4. store를 partition key로 시도하여 쿠키 저장소를 가져온 결과로 둡니다.

  5. deserialized value를 cookie spec["value"]로 프로토콜 바이트를 역직렬화한 결과로 둡니다.

  6. store에 쿠키를 생성합니다. 이때 쿠키 이름은 cookie spec["name"], 쿠키 값은 deserialized value, 쿠키 도메인은 cookie spec["domain"]으로 하고, 쿠키 변환 표에 나열된 다음 쿠키 개념의 속성-값 목록을 사용합니다:

    쿠키 경로

    cookie spec["path"]가 존재하면 그 값으로, 그렇지 않으면 "/"로 합니다.

    쿠키 보안 전용

    cookie spec["secure"]가 존재하면 그 값으로, 그렇지 않으면 false로 합니다.

    쿠키 HTTP 전용

    cookie spec["httpOnly"]가 존재하면 그 값으로, 그렇지 않으면 false로 합니다.

    쿠키 만료 시간

    cookie spec["expiry"]가 존재하면 그 값으로, 그렇지 않으면 이것이 세션 쿠키임을 나타내기 위해 설정하지 않은 상태로 둡니다.

    참고: 쿠키의 만료 값은 쿠키 수명 제한에 따라 원격 끝에 의해 제한될 수 있습니다.

    쿠키 동일 사이트

    cookie spec["sameSite"]가 존재하면 그 값으로, 그렇지 않으면 동일 사이트 정책이 정의되지 않았음을 나타내기 위해 설정하지 않은 상태로 둡니다.

    이 단계가 쿠키 저장소에 쿠키를 삽입하지 못한 채 중단되면, 오류를 오류 코드 쿠키를 설정할 수 없음과 함께 반환합니다.

  7. body를 partitionKey 필드가 partition key로 설정된 storage.SetCookieResult 생성 규칙과 일치하는 맵으로 둡니다.

  8. 데이터 body와 함께 성공을 반환합니다.

7.7.3.3. storage.deleteCookies 명령

storage.deleteCookies 명령은 제공된 매개변수 집합과 일치하는 0개 이상의 쿠키를 제거한다.

명령 타입
storage.DeleteCookies = (
  method: "storage.deleteCookies",
  params: storage.DeleteCookiesParameters,
)

storage.DeleteCookiesParameters = {
  ? filter: storage.CookieFilter,
  ? partition: storage.PartitionDescriptor,
}
반환 타입
storage.DeleteCookiesResult = {
  partitionKey: storage.PartitionKey
}
session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. filter를 command parameters의 filter 필드가 존재하면 그 값으로, 존재하지 않으면 빈 맵으로 둡니다.

  2. partition spec을 command parameters의 partition 필드가 존재하면 그 값으로, 존재하지 않으면 null로 둡니다.

  3. partition key를 partition spec으로 시도하여 스토리지 파티션 명세를 확장한 결과로 둡니다.

  4. store를 partition key로 시도하여 쿠키 저장소를 가져온 결과로 둡니다.

  5. cookies를 store와 filter로 일치하는 쿠키를 가져온 결과로 둡니다.

  6. cookies의 각 cookie에 대해:

    1. store에서 cookie를 제거합니다.

  7. body를 partitionKey 필드가 partition key로 설정된 storage.DeleteCookiesResult 생성 규칙과 일치하는 맵으로 둡니다.

  8. 데이터 body와 함께 성공을 반환합니다.

7.8. log 모듈

log 모듈은 로깅과 관련된 기능 및 이벤트를 포함한다.

BiDi 세션은 로그 이벤트 버퍼를 가지며, 이는 맵으로, navigable id에서 그 컨텍스트의 아직 방출되지 않은 로그 이벤트 리스트로의 맵이다. 사용자 에이전트는 이 버퍼에 최대 크기를 부과할 수 있지만, 동일한 컨텍스트에서 이벤트 A와 B가 발생하고 A가 B보다 먼저 발생했으며 둘 다 버퍼에 추가된 경우, B의 엔트리는 A의 엔트리보다 먼저 제거되어서는 안 된다는 조건을 따른다.

session, navigables 및 event가 주어졌을 때 로그 이벤트 버퍼링을 수행하려면:

  1. buffer를 session의 로그 이벤트 버퍼로 둔다.

  2. navigable ids를 새 리스트로 둔다.

  3. navigables의 각 navigable에 대해:

    1. navigable의 navigable id를 navigable ids에 추가한다.

  4. navigable ids 안의 각 navigable id에 대해:

    1. other navigables를 빈 리스트로 둔다

    2. navigable ids 안의 각 other id에 대해:

    3. other id가 navigable id와 같지 않으면, other id를 other navigables에 추가한다.

    4. buffer가 navigable id를 포함하지 않으면, buffer[navigable id]를 새 리스트로 둔다.

    5. (event, other navigables)를 buffer[navigable id]에 추가한다.

참고: 각 이벤트가 한 번만 방출되도록 여기에서 다른 navigable들을 저장한다. 실제로 이는 여러 navigable과 연관될 수 있는 worker에 대해서만 의미가 있다.

이를 브라우징 컨텍스트를 기준으로 할 것인가, 아니면 최상위 traversable을 기준으로 할 것인가? 차이는 프레임에서 이벤트가 발생하고, 로컬 엔드가 최상위 navigable의 로그 이벤트를 구독하기 전에 그 프레임이 탐색되는 경우에 나타난다.

7.8.1. 정의

로컬 엔드 정의

LogEvent = (
  log.EntryAdded
)

7.8.2. 타입

7.8.2.1. log.LogEntry

로컬 엔드 정의

log.Level = "debug" / "info" / "warn" / "error"

log.Entry = (
  log.GenericLogEntry /
  log.ConsoleLogEntry /
  log.JavascriptLogEntry
)

log.BaseLogEntry = (
  level: log.Level,
  source: script.Source,
  text: text / null,
  timestamp: js-uint,
  ? stackTrace: script.StackTrace,
)

log.GenericLogEntry = {
  log.BaseLogEntry,
  type: text,
}

log.ConsoleLogEntry = {
  log.BaseLogEntry,
  type: "console",
  method: text,
  args: [*script.RemoteValue],
}

log.JavascriptLogEntry = {
  log.BaseLogEntry,
  type: "javascript",
}

각 로그 이벤트는 log.Entry 객체로 표현된다. 이는 추가된 로그 엔트리의 타입을 나타내는 type 속성, 심각도를 나타내는 level 속성, 로그 엔트리의 출처를 나타내는 source 속성, 로그 메시지 문자열 자체를 담는 text 속성, 그리고 로그 엔트리가 생성된 시간에 대응하는 timestamp 속성을 가진다. log.Entry의 특정 변형들은 서로 다른 출처의 로그를 나타내는 데 사용되며, 엔트리 타입별 추가 필드를 제공한다.

7.8.3. 이벤트

7.8.3.1. log.entryAdded 이벤트
이벤트 타입
log.EntryAdded = (
 method: "log.entryAdded",
 params: log.Entry,
)

원격 엔드 이벤트 트리거는 다음과 같다:

method, args 및 options으로 다음 콘솔 단계를 정의한다:

  1. 활성 BiDi 세션의 각 session에 대해:

    1. method가 "error" 또는 "assert"이면, level을 "error"로 둔다. method가 "debug" 또는 "trace"이면 level을 "debug"로 둔다. method가 "warn"이면, level을 "warn"로 둔다. 그렇지 않으면 level을 "info"로 둔다.

    2. timestamp를 UTC의 현재 날짜와 시간을 나타내는 시간 값으로 둔다.

    3. text를 빈 문자열로 둔다.

    4. Type(args[0])이 String이고, args[0]이 서식 지정자를 포함하면, formatted args를 Formatter(args)로 둔다. 그렇지 않으면 formatted args를 args로 둔다.

      참고: 포매터 연산은 콘솔 명세에서 충분히 정의되어 있지 않으므로, 서로 다른 구현 간에 서식 지정이 일관되지 않을 수 있다.

    5. formatted args의 각 arg에 대해:

      1. arg가 args의 첫 번째 항목이 아니면, U+0020 SPACE를 text에 추가한다.

      2. arg가 원시 ECMAScript 값이면, ToString(arg)을 text에 추가한다. 그렇지 않으면 구현 정의 문자열을 text에 추가한다.

    6. realm을 현재 Realm 레코드의 Realm id로 둔다.

    7. serialized args를 새 목록으로 둔다.

    8. serialization options를 필드가 기본값으로 설정된 script.SerializationOptions 생성 규칙과 일치하는 맵으로 둔다.

    9. args의 각 arg에 대해:

      1. serialized arg를 arg를 값으로, serialization options을, none을 소유권 유형으로, 새 맵을 직렬화 내부 맵으로, realm 및 session으로 원격 값으로 직렬화한 결과로 둔다.

      2. serialized arg를 serialized args에 추가한다.

    10. source를 현재 Realm 레코드가 주어졌을 때 소스 가져오기를 수행한 결과로 둔다.

    11. stack을 현재 스택 추적으로 둔다.

    12. entry를 level 필드는 level로, text 필드는 text로, timestamp 필드는 timestamp로, stackTrace 필드는 stack으로, method 필드는 method로, source 필드는 source로, 그리고 args 필드는 serialized args로 설정된 log.ConsoleLogEntry 생성 규칙과 일치하는 맵으로 둔다.

    13. body를 params 필드가 entry로 설정된 log.EntryAdded 생성 규칙과 일치하는 맵으로 둔다.

    14. settings를 현재 설정 객체로 둔다

    15. related navigables를 settings이 주어졌을 때 관련 순회 가능 객체 가져오기를 수행한 결과로 둔다.

    16. session, "log.entryAdded" 및 related navigables로 이벤트가 활성화됨이면, session 및 body로 이벤트를 발생시킨다.

      그렇지 않으면, session, related browsing contexts 및 body로 로그 이벤트를 버퍼링한다.

script, line number, column number, message 및 handled 인수로 다음 오류 보고 단계를 정의한다:

  1. handled가 true이면 반환한다.

  2. settings을 script의 설정 객체로 둔다.

  3. timestamp를 UTC의 현재 날짜와 시간을 나타내는 시간 값으로 둔다.

  4. stack을 보고 중인 오류에 대응하는 예외를 사용한 예외의 스택 추적으로 둔다.

  5. source를 현재 Realm 레코드가 주어졌을 때 소스 가져오기를 수행한 결과로 둔다.

  6. entry를 level은 "error"로, text는 message로, source는 source로, timestamp는 timestamp로, 그리고 stackTrace 필드는 stack으로 설정된 log.JavascriptLogEntry 생성 규칙과 일치하는 맵으로 둔다.

  7. body를 params 필드가 entry로 설정된 log.EntryAdded 생성 규칙과 일치하는 맵으로 둔다.

  8. related navigables를 settings이 주어졌을 때 관련 순회 가능 객체 가져오기를 수행한 결과로 둔다.

  9. 활성 BiDi 세션의 각 session에 대해:

    1. session, "log.entryAdded" 및 related navigables로 이벤트가 활성화됨이면, session 및 body로 이벤트를 발생시킨다.

      그렇지 않으면, session, related browsing contexts 및 body로 로그 이벤트를 버퍼링한다.

훨씬 더 많은 항목에 로깅이 필요하다. CDP에는 LogEntryAdded 유형으로 xml, javascript, network, storage, appcache, rendering, security, deprecation, worker, violation, intervention, recommendation, other가 있다. 이는 서로 다른 메서드로 표현되는 js 예외 및 콘솔 API 유형에 추가되는 것이다.

구현 정의 로그 유형을 허용한다

session, navigables 및 include global이 주어졌을 때 구독 우선순위 10인 원격 엔드 구독 단계는 다음과 같다:

  1. session의 로그 이벤트 버퍼에 있는 각 navigable id → events에 대해:

    1. maybe context를 navigable id가 주어졌을 때 순회 가능 객체 가져오기를 수행한 결과로 둔다.

    2. maybe context가 오류이면, navigable id를 로그 이벤트 버퍼에서 제거하고 계속한다.

    3. navigable을 maybe context의 데이터로 둔다

    4. top level navigable을 navigable의 최상위 순회 가능 객체로 둔다.

    5. include global이 true이고 top level navigable이 navigables에 없거나, include global이 false이고 top level navigable이 navigables에 있으면:

      1. events의 각 (event, other navigables)에 대해:

        1. session 및 event로 이벤트를 발생시킨다.

        2. other navigables의 각 other context id에 대해:

          1. 로그 이벤트 버퍼가 other context id를 포함하면, event를 로그 이벤트 버퍼[other context id]에서 제거한다.

7.9. input 모듈

input 모듈은 시뮬레이션된 사용자 입력을 위한 기능을 포함한다.

7.9.1. 정의

원격 엔드 정의

InputCommand = (
  input.PerformActions //
  input.ReleaseActions //
  input.SetFiles
)
InputResult = (
  input.PerformActionsResult /
  input.ReleaseActionsResult /
  input.SetFilesResult
)

로컬 엔드 정의

InputEvent = (
  input.FileDialogOpened
)

7.9.2. 타입

7.9.2.1. input.ElementOrigin

input.ElementOrigin 타입은 좌표 원점으로 사용될 Element를 나타낸다.

input.ElementOrigin = {
  type: "element",
  element: script.SharedReference
}
object가 주어졌을 때 input.ElementOrigin인지 단계는 다음과 같다:
  1. object가 input.ElementOrigin 생성식과 일치하는 맵이면, true를 반환한다.

  2. false를 반환한다.

session이 주어졌을 때 input.ElementOrigin에서 Element를 가져오는 단계:
  1. origin과 navigable이 주어졌을 때 다음 단계를 반환합니다:

    1. 단언: origin은 input.ElementOrigin과 일치합니다.

    2. document를 navigable의 활성 문서로 둡니다.

    3. reference를 origin["element"]로 둡니다

    4. environment settings를 관련 전역 객체의 연결된 Document가 document인 환경 설정 객체로 둡니다.

    5. realm을 environment settings의 Realm 실행 컨텍스트의 Realm 구성 요소로 둡니다.

    6. element를 reference, realm, 그리고 session으로 시도하여 원격 참조를 역직렬화한 결과로 둡니다.

    7. element가 Element를 구현하지 않으면 오류를 오류 코드 해당 요소 없음과 함께 반환합니다.

    8. 데이터 element와 함께 성공을 반환합니다.

7.9.3. 명령

7.9.3.1. input.performActions 명령

input.performActions 명령은 지정된 사용자 입력 동작 시퀀스를 수행한다.

참고: 이 명령의 동작에 대한 자세한 설명은 [WEBDRIVER]의 actions 섹션을 참조한다.

명령 타입
input.PerformActions = (
  method: "input.performActions",
  params: input.PerformActionsParameters
)

input.PerformActionsParameters = {
  context: browsingContext.BrowsingContext,
  actions: [*input.SourceActions]
}

input.SourceActions = (
  input.NoneSourceActions /
  input.KeySourceActions /
  input.PointerSourceActions /
  input.WheelSourceActions
)

input.NoneSourceActions = {
  type: "none",
  id: text,
  actions: [*input.NoneSourceAction]
}

input.NoneSourceAction = input.PauseAction

input.KeySourceActions = {
  type: "key",
  id: text,
  actions: [*input.KeySourceAction]
}

input.KeySourceAction = (
  input.PauseAction /
  input.KeyDownAction /
  input.KeyUpAction
)

input.PointerSourceActions = {
  type: "pointer",
  id: text,
  ? parameters: input.PointerParameters,
  actions: [*input.PointerSourceAction]
}

input.PointerType = "mouse" / "pen" / "touch"

input.PointerParameters = {
  ? pointerType: input.PointerType .default "mouse"
}

input.PointerSourceAction = (
  input.PauseAction /
  input.PointerDownAction /
  input.PointerUpAction /
  input.PointerMoveAction
)

input.WheelSourceActions = {
  type: "wheel",
  id: text,
  actions: [*input.WheelSourceAction]
}

input.WheelSourceAction = (
  input.PauseAction /
  input.WheelScrollAction
)

input.PauseAction = {
  type: "pause",
  ? duration: js-uint
}

input.KeyDownAction = {
  type: "keyDown",
  value: text
}

input.KeyUpAction = {
  type: "keyUp",
  value: text
}

input.PointerUpAction = {
  type: "pointerUp",
  button: js-uint,
}

input.PointerDownAction = {
  type: "pointerDown",
  button: js-uint,
  input.PointerCommonProperties
}

input.PointerMoveAction = {
  type: "pointerMove",
  x: float,
  y: float,
  ? duration: js-uint,
  ? origin: input.Origin,
  input.PointerCommonProperties
}

input.WheelScrollAction = {
  type: "scroll",
  x: js-int,
  y: js-int,
  deltaX: js-int,
  deltaY: js-int,
  ? duration: js-uint,
  ? origin: input.Origin .default "viewport",
}

input.PointerCommonProperties = (
  ? width: js-uint,
  ? height: js-uint,
  ? pressure: (0.0..1.0),
  ? tangentialPressure: (-1.0..1.0),
  ? twist: (0..359),
  ; 0 .. Math.PI / 2
  ? altitudeAngle: (0.0..1.5707963267948966),
  ; 0 .. 2 * Math.PI
  ? azimuthAngle: (0.0..6.283185307179586),
)

input.Origin = "viewport" / "pointer" / input.ElementOrigin
반환 타입
input.PerformActionsResult = EmptyResult

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. navigable id를 command parameters의 context 필드 값으로 둡니다.

  2. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

  3. input state를 session과 navigable의 최상위 순회 가능 항목으로 입력 상태를 가져온 결과로 둡니다.

  4. actions options를 요소 원점인지 여부 단계가 input.ElementOrigin인지 여부로 설정되고, 요소 원점 가져오기 단계가 session이 주어졌을 때 input.ElementOrigin에서 Element를 가져오는 단계의 결과로 설정된 새로운 액션 옵션으로 둡니다.

  5. actions by tick을 input state, command parameters, 그리고 actions options으로 액션 시퀀스를 추출한 결과로 둡니다.

  6. input state, actions by tick, navigable, 그리고 actions options으로 시도하여 액션을 디스패치합니다.

  7. 데이터 null과 함께 성공을 반환합니다.

7.9.3.2. input.releaseActions 명령

input.releaseActions 명령은 현재 세션과 연관된 입력 상태를 재설정한다.

명령 타입
input.ReleaseActions = (
  method: "input.releaseActions",
  params: input.ReleaseActionsParameters
)

input.ReleaseActionsParameters = {
  context: browsingContext.BrowsingContext,
}
반환 타입
input.ReleaseActionsResult = EmptyResult

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. navigable id를 command parameters의 context 필드 값으로 둡니다.

  2. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

  3. top-level traversable을 navigable의 최상위 순회 가능 항목으로 둡니다.

  4. input state를 session과 top-level traversable로 입력 상태를 가져온 결과로 둡니다.

  5. actions options를 요소 원점인지 여부 단계가 input.ElementOrigin인지 여부로 설정되고, 요소 원점 가져오기 단계가 session이 주어졌을 때 input.ElementOrigin에서 Element를 가져오는 단계로 설정된 새로운 액션 옵션으로 둡니다.

  6. undo actions를 input state의 입력 취소 목록을 역순으로 한 것으로 둡니다.

  7. undo actions, 0, navigable, 그리고 actions options으로 시도하여 틱 액션을 디스패치합니다.

  8. session과 top-level traversable로 입력 상태를 재설정합니다.

  9. 데이터 null과 함께 성공을 반환합니다.

7.9.3.3. input.setFiles 명령

input.setFiles 명령은 주어진 file 타입의 input 요소의 files 속성을 파일 경로 집합으로 설정한다.

명령 타입
input.SetFiles = (
  method: "input.setFiles",
  params: input.SetFilesParameters
)

input.SetFilesParameters = {
  context: browsingContext.BrowsingContext,
  element: script.SharedReference,
  files: [*text]
}
반환 타입
input.SetFilesResult = EmptyResult

session과 command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:

  1. navigable id를 command parameters["context"] 필드의 값으로 둡니다.

  2. navigable을 navigable id로 시도하여 내비게이블을 가져온 결과로 둡니다.

  3. document를 navigable의 활성 문서로 둡니다.

  4. environment settings를 관련 전역 객체의 연결된 Document가 document인 환경 설정 객체로 둡니다.

  5. realm을 environment settings의 Realm 실행 컨텍스트의 Realm 구성 요소로 둡니다.

  6. element를 command parameters["element"], realm, 그리고 session으로 시도하여 원격 참조를 역직렬화한 결과로 둡니다.

  7. element가 Element를 구현하지 않으면, 오류를 오류 코드 해당 요소 없음과 함께 반환합니다.

  8. element가 HTMLInputElement를 구현하지 않거나, element의 type이 파일 업로드 상태가 아니거나, element가 비활성화되어 있으면, 오류를 오류 코드 파일 입력을 설정할 수 없음과 함께 반환합니다.

  9. files의 크기가 1보다 크고 element의 multiple 속성이 설정되어 있지 않으면, 오류를 오류 코드 파일 입력을 설정할 수 없음과 함께 반환합니다.

  10. files를 command parameters["files"] 필드의 값으로 둡니다.

  11. selected files를 element의 선택된 파일로 둡니다.

  12. files와 selected files의 교집합의 크기가 selected files의 크기와 같고 files의 크기와도 같으면, element가 주어졌을 때 사용자 상호작용 태스크 소스에서 element에 cancel이라는 이름의 이벤트를 발생시키고, bubbles 속성을 true로 초기화하도록 요소 태스크를 큐에 추가합니다.

    참고: 브라우저에서 취소 여부는 일반적으로 파일 선택의 변경 여부에 따라 결정됩니다. 즉, 변경 사항이 없으면 "cancel" 이벤트가 전송됩니다.

  13. 그렇지 않으면, files를 사용자의 선택으로 하여 element의 파일 선택을 업데이트합니다.

  14. 어떤 이유로든 원격 끝이 element의 선택된 파일을 files에 지정된 경로의 파일로 설정할 수 없으면, 오류 코드 지원되지 않는 작업과 함께 오류를 반환합니다.

    참고: 예를 들어 원격 끝은 현재 파일 시스템에 존재하지 않는 파일을 선택된 파일로 설정하지 못할 수 있습니다.

  15. 데이터 null과 함께 성공을 반환합니다.

7.9.4. 이벤트

7.9.4.1. input.fileDialogOpened 이벤트
이벤트 타입
input.FileDialogOpened = (
   method: "input.fileDialogOpened",
   params: input.FileDialogInfo
)

input.FileDialogInfo = {
   context: browsingContext.BrowsingContext,
   ? userContext: browser.UserContext,
   ? element: script.SharedReference,
   multiple: bool,
}

WebDriver BiDi 파일 선택기 옵션은 구조체이며, boolean인 multiple이라는 이름의 항목을 가진다.

원격 끝 이벤트 트리거는 요소 element와 선택적으로 WebDriver BiDi 파일 선택기 옵션 file picker options(기본값: null)가 주어졌을 때 WebDriver BiDi 파일 대화상자 열림 단계입니다:

참고: 다른 사용자 프롬프트 처리기와 달리, 기본 동작은 파일 대화상자가 열리도록 허용하는 것입니다.

  1. navigable을 element의 노드 문서의 내비게이블로 둡니다.

  2. navigable id를 navigable의 내비게이블 ID로 둡니다.

  3. user context id를 navigable의 연결된 사용자 컨텍스트의 사용자 컨텍스트 ID로 둡니다.

  4. multiple을 false로 둡니다.

  5. element가 null이 아니고 element의 multiple 속성이 설정되어 있으면, multiple을 true로 설정합니다.

  6. file picker options가 null이 아니고 file picker options의 multiple이 true이면, multiple을 true로 설정합니다.

  7. related navigables를 navigable을 포함하는 집합으로 둡니다.

  8. "input.fileDialogOpened"와 related navigables이 주어졌을 때 이벤트가 활성화된 세션 집합의 각 session에 대해:

    1. params를 context 필드가 navigable id로 설정되고, userContext 필드가 user context id로 설정되며 multiple 필드가 multiple로 설정된 input.FileDialogInfo 생성 규칙과 일치하는 맵으로 둡니다.

    2. element가 null이 아닌 경우:

      1. shared id를 element와 session으로 노드의 공유 ID를 가져온 결과로 둡니다.

      2. params["element"]를 shared id로 설정합니다.

    3. body를 params 필드가 params로 설정된 input.fileDialogOpened 생성 규칙과 일치하는 맵으로 둡니다.

    4. session과 body로 이벤트를 내보냅니다.

  9. dismissed를 false로 둡니다.

  10. 활성 BiDi 세션의 각 session에 대해:

    1. user prompt handler를 session의 사용자 프롬프트 처리기로 둡니다.

    2. user prompt handler가 null이 아닌 경우:

    3. user prompt handler가 맵이라고 단언합니다.

    4. user prompt handler가 "file"을 포함하는 경우:

      1. user prompt handler["file"]이 "ignore"와 같지 않으면, dismissed를 true로 설정합니다.

    5. 그렇지 않고 user prompt handler가 "default"를 포함하고 user prompt handler["default"]가 "ignore"와 같지 않으면, dismissed를 true로 설정합니다.

  11. dismissed를 반환합니다.

7.10. webExtension 모듈

webExtension 모듈은 웹 확장을 관리하고 상호작용하기 위한 기능을 포함한다.

7.10.1. 정의

원격 엔드 정의

WebExtensionCommand = (
  webExtension.Install //
  webExtension.Uninstall
)

로컬 엔드 정의

WebExtensionResult = (
  webExtension.InstallResult /
  webExtension.UninstallResult
)

7.10.2. 타입

7.10.2.1. webExtension.Extension 타입
webExtension.Extension = text

webExtension.Extension 타입은 원격 엔드 내의 웹 확장 ID를 나타낸다.

7.10.3. 명령

7.10.3.1. webExtension.install 명령

webExtension.install 명령은 원격 끝에 웹 확장을 설치합니다.

명령 유형
webExtension.Install = (
   method: "webExtension.install",
   params: webExtension.InstallParameters
)

webExtension.InstallParameters = {
   extensionData: webExtension.ExtensionData,
}

webExtension.ExtensionData = (
   webExtension.ExtensionArchivePath /
   webExtension.ExtensionBase64Encoded /
   webExtension.ExtensionPath
)

webExtension.ExtensionPath = {
   type: "path",
   path: text,
}

webExtension.ExtensionArchivePath = {
   type: "archivePath",
   path: text,
}

webExtension.ExtensionBase64Encoded = {
   type: "base64",
   value: text,
}
반환 유형
webExtension.InstallResult = {
  extension: webExtension.Extension
}
bytes가 주어졌을 때 zip 아카이브를 추출하려면:
  1. zip 압축 알고리즘을 사용하여 bytes를 디코딩하는 구현 정의 단계를 수행합니다. TODO: zip 디코딩에 대한 더 나은 참조를 찾습니다.

  2. 이전 단계가 실패하면(예: bytes가 유효한 zip 압축 데이터를 나타내지 않았기 때문인 경우) 오류를 오류 코드 유효하지 않은 웹 확장과 함께 반환합니다. 그렇지 않으면 entry를 추출된 파일 시스템 항목을 포함하는 디렉터리 항목으로 둡니다.

  3. entry를 반환합니다.

extension data spec이 주어졌을 때 웹 확장 데이터 명세를 확장하려면:
  1. type을 extension data spec["type"]으로 둡니다.

  2. type을 사용한 웹 확장 설치가 지원되지 않으면 오류를 오류 코드 지원되지 않는 작업과 함께 반환합니다.

  3. 다음 조건 및 관련 단계 목록에서 관련 조건이 true인 첫 번째 단계 집합을 실행합니다:

    type이 문자열 "path"인 경우
    1. path를 extension data spec["path"]로 둡니다.

    2. locator를 경로 path와 파일 시스템의 루트에 해당하는 루트를 가진 디렉터리 로케이터로 둡니다.

    3. entry를 locator가 주어졌을 때 항목을 찾은 결과로 둡니다.

    type이 문자열 "archivePath"인 경우
    1. archive path를 extension data spec["path"]로 둡니다.

    2. locator를 경로 archive path와 파일 시스템의 루트에 해당하는 루트를 가진 파일 로케이터로 둡니다.

    3. archive entry를 locator가 주어졌을 때 항목을 찾은 결과로 둡니다.

    4. archive entry가 null이면, null을 반환합니다.

    5. bytes를 archive entry의 바이너리 데이터로 둡니다.

    6. entry를 bytes가 주어졌을 때 시도하여 zip 아카이브를 추출한 결과로 둡니다.

    type이 문자열 "base64"인 경우
    1. bytes를 extension data spec["value"]에 관대한 base64 디코딩을 적용한 결과로 둡니다.

    2. bytes가 실패이면, null을 반환합니다.

    3. entry를 bytes가 주어졌을 때 시도하여 zip 아카이브를 추출한 결과로 둡니다.

  4. entry를 반환합니다.

command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. 웹 확장 설치가 지원되지 않으면 오류를 오류 코드 지원되지 않는 작업과 함께 반환합니다.

  2. extension data spec을 command parameters["extensionData"]로 둡니다.

  3. extension directory entry를 extension data spec으로 시도하여 웹 확장 데이터 명세를 확장한 결과로 둡니다.

  4. extension directory entry가 null이면, 오류를 오류 코드 유효하지 않은 웹 확장과 함께 반환합니다.

  5. extension directory entry에서 웹 확장을 설치하는 구현 정의 단계를 수행합니다. 이것이 실패하면, 오류를 오류 코드 유효하지 않은 웹 확장과 함께 반환합니다. 그렇지 않으면 extension id를 새로 설치된 웹 확장의 고유 식별자로 둡니다.

  6. result를 extension 필드가 extension id로 설정된 webExtension.InstallResult 생성 규칙과 일치하는 맵으로 둡니다.

  7. 데이터 result와 함께 성공을 반환합니다.

참고: 브라우저는 기본적으로 웹 확장을 임시로만 설치할 수 있으므로, 다음 종료 시 자동으로 제거될 수 있다.

7.10.3.2. webExtension.uninstall 명령

webExtension.uninstall 명령은 원격 끝에서 웹 확장을 제거합니다.

명령 유형
webExtension.Uninstall = (
   method: "webExtension.uninstall",
   params: webExtension.UninstallParameters
)

webExtension.UninstallParameters = {
   extension: webExtension.Extension,
}
반환 유형
webExtension.UninstallResult = EmptyResult
command parameters가 주어졌을 때 원격 끝 단계는 다음과 같습니다:
  1. extension을 command parameters["extension"]으로 둡니다.

  2. 원격 끝에 ID가 extension과 같은 웹 확장이 없으면, 오류를 오류 코드 해당 웹 확장 없음과 함께 반환합니다.

  3. 원격 끝에서 웹 확장을 제거하기 위한 구현 정의 단계를 수행합니다. 이것이 실패하면, 오류를 오류 코드 알 수 없는 오류와 함께 반환합니다.

  4. 데이터 null과 함께 성공을 반환합니다.

8. 다른 명세에 대한 패치

이 명세는 필요한 통합 지점을 제공하기 위해 외부 명세에 대한 일부 변경을 요구한다. 이러한 패치는 표준화 과정의 일부로 다른 명세에 커밋될 것으로 가정한다.

8.1. HTML

오류 보고 알고리즘은 끝에 추가 단계가 있는 것으로 수정된다:

  1. 외부 명세에 정의된 모든 오류 보고 단계를 script, line, col, message, 그리고 오류가 처리된 경우 true, 그렇지 않은 경우 false와 함께 호출한다.

8.2. Console

다른 명세는 console steps를 정의할 수 있다.

  1. Printer 연산이 인자 name, printerArgs 및 options(인자가 제공되지 않으면 undefined)로 호출되는 시점에, 외부 명세에 정의된 모든 console steps를 인자 name, printerArgs, 그리고 options와 함께 호출한다.

8.3. CSS

8.3.1. device pixel ratio 결정

device pixel ratio 결정 알고리즘의 시작 부분에 다음 단계를 삽입한다:

  1. 기기 픽셀 비율 재정의가 window의 순회 가능 객체를 포함하면, 기기 픽셀 비율 재정의[window의 순회 가능 객체]를 반환한다.

8.3.2. 미디어 쿼리 평가

https://github.com/w3c/csswg-drafts/pull/13549가 병합된 후 제거한다.

[미디어 기능 평가 알고리즘은 WebDriver BiDi 재정의를 지원하도록 수정된다. "결과는 지정된 미디어 기능을 평가한 결과이다" 단계를 다음으로 대체한다:

주어진 Document document에서 미디어 기능 media feature을 평가한 결과를 얻으려면:
  1. media feature name을 media feature의 mf-name으로 둔다.

  2. emulated value를 document 및 media feature name에 대한 WebDriver BiDi 미디어 기능 값을 가져온 결과로 둔다.

  3. emulated value가 null이 아니면, emulated value를 반환한다.

  4. 그렇지 않으면, 지정된 media feature을 평가한 결과를 반환한다.

8.3.3. viewport 메타 요소

https://github.com/w3c/csswg-drafts/pull/13548가 병합된 후 제거한다.

[CSS-VIEWPORT-1] 명세의 'Viewport meta element' 절은 WebDriver BiDi viewport 메타 상태를 확인하도록 수정된다.

`viewport` 메타 요소의 노드 문서가 주어졌을 때 WebDriver BiDi viewport 메타 상태가 true이면, 사용자 에이전트는 `viewport` 메타 요소를 반드시 사용해야 한다.

그렇지 않으면, 사용자 에이전트는 `viewport` 메타 요소를 사용할 수 있다.

9. 부록

이 섹션은 비규범적이다.

9.1. 외부 명세

참고: 이 목록은 완전하지 않으며 최신이 아닐 수 있다.

다음 외부 명세는 추가 WebDriver BiDi 모듈을 정의한다:

  1. Digital Credentials API

  2. Permissions

  3. nav-speculation

  4. User-Agent Client Hints

  5. Web Bluetooth

색인

이 명세에서 정의하는 용어

참조로 정의된 용어

참고문헌

규범적 참고문헌

[ACCNAME-1.1]
Joanmarie Diggs; Bryan Garaventa; Michael Cooper. 접근 가능한 이름 및 설명 계산 1.1. URL: https://w3c.github.io/accname/
[CONSOLE]
Dominic Farolino; Robert Kowalski; Terin Stock. 콘솔 표준. 현행 표준. URL: https://console.spec.whatwg.org/
[COOKIES]
A. Barth. HTTP 상태 관리 메커니즘. 2011년 4월. 제안 표준. URL: https://httpwg.org/specs/rfc6265.html
[CORE-AAM-1.1]
Joanmarie Diggs; et al. 코어 접근성 API 매핑 1.1. URL: https://w3c.github.io/core-aam/
[CSS-COLOR-ADJUST-1]
Elika Etemad; et al. CSS 색상 조정 모듈 레벨 1. URL: https://drafts.csswg.org/css-color-adjust-1/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS 오버플로 모듈 레벨 3. URL: https://drafts.csswg.org/css-overflow-3/
[CSS-PAINT-API-1]
Ian Kilpatrick; Dean Jackson. CSS 페인팅 API 레벨 1. URL: https://drafts.css-houdini.org/css-paint-api-1/
[CSS-VIEWPORT-1]
Florian Rivoal; Emilio Cobos Álvarez. CSS 뷰포트 모듈 레벨 1. URL: https://drafts.csswg.org/css-viewport/
[CSS2]
Bert Bos; et al. 캐스케이딩 스타일 시트 레벨 2 개정 1 (CSS 2.1) 명세. URL: https://drafts.csswg.org/css2/
[CSSOM-VIEW-1]
Simon Fraser; Emilio Cobos Álvarez. CSSOM 뷰 모듈. URL: https://drafts.csswg.org/cssom-view/
[DOM]
Anne van Kesteren. DOM 표준. 현행 표준. URL: https://dom.spec.whatwg.org/
[ECMA-402]
ECMAScript 국제화 API 명세. URL: https://tc39.es/ecma402/
[ECMAScript]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. 인코딩 표준. 현행 표준. URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch 표준. 현행 표준. URL: https://fetch.spec.whatwg.org/
[FS]
Austin Sullivan. 파일 시스템 표준. 현행 표준. URL: https://fs.spec.whatwg.org/
[FULLSCREEN]
Philip Jägenstedt. Fullscreen API 표준. 현행 표준. URL: https://fullscreen.spec.whatwg.org/
[GEOLOCATION]
Marcos Caceres; Reilly Grant. Geolocation. URL: https://w3c.github.io/geolocation/
[GEOMETRY-1]
Sebastian Zartner; Yehonatan Daniv. 기하 인터페이스 모듈 레벨 1. URL: https://drafts.csswg.org/geometry/
[HR-TIME-3]
Yoav Weiss. 고해상도 시간. URL: https://w3c.github.io/hr-time/
[HTML]
Anne van Kesteren; et al. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[MEDIAQUERIES-5]
Tab Atkins Jr.; 외. 미디어 쿼리 레벨 5. URL: https://drafts.csswg.org/mediaqueries-5/
[MIMESNIFF]
Gordon P. Hemsley. MIME 스니핑 표준. 현행 표준. URL: https://mimesniff.spec.whatwg.org/
[RESOURCE-TIMING]
Yoav Weiss; Noam Rosenthal. 리소스 타이밍. URL: https://w3c.github.io/resource-timing/
[RFC4648]
S. Josefsson. Base16, Base32 및 Base64 데이터 인코딩. 2006년 10월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc4648/
[RFC5280]
D. Cooper; et al. 인터넷 X.509 공개 키 기반구조 인증서 및 인증서 폐기 목록(CRL) 프로파일. 2008년 5월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc5280/
[RFC6455]
I. Fette; A. Melnikov. WebSocket 프로토콜. 2011년 12월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc6455/
[RFC8610]
H. Birkholz; C. Vigano; C. Bormann. 간결한 데이터 정의 언어(CDDL): CBOR와 JSON 데이터 구조를 표현하기 위한 표기 규약. 2019년 6월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc8610/
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP 의미론. 2022년 6월. 인터넷 표준. URL: https://httpwg.org/specs/rfc9110.html
[RFC9562]
K. Davis; B. Peabody; P. Leach. 범용 고유 식별자(UUID). 2024년 5월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc9562/
[SCREEN-CAPTURE]
Jan-Ivar Bruaroey; Elad Alon. 화면 캡처. URL: https://w3c.github.io/mediacapture-screen-share/
[SCREEN-ORIENTATION]
Marcos Caceres; Léonie Watson. 화면 방향. URL: https://w3c.github.io/screen-orientation/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. 선택자 레벨 4. URL: https://drafts.csswg.org/selectors/
[SERVICE-WORKERS]
Monica CHINTALA; Yoshisato Yanagisawa. 서비스 워커 나이틀리. URL: https://w3c.github.io/ServiceWorker/
[UNICODE]
유니코드 표준. URL: https://www.unicode.org/versions/latest/
[URL]
Anne van Kesteren. URL 표준. 현행 표준. URL: https://url.spec.whatwg.org/
[WEBAUDIO-1.0]
Paul Adenot; Hongchan Choi. Web Audio API. URL: https://webaudio.github.io/web-audio-api/
[WEBDRIVER]
Simon Stewart; David Burns. WebDriver. URL: https://w3c.github.io/webdriver/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 표준. 현행 표준. URL: https://webidl.spec.whatwg.org/
[WEBSOCKETS]
Adam Rice. WebSockets 표준. 현행 표준. URL: https://websockets.spec.whatwg.org/
[WEBTRANSPORT]
Jan-Ivar Bruaroey; Victor Vasiliev; Nidhi Jaju. WebTransport. URL: https://w3c.github.io/webtransport/

정보성 참고문헌

[CSS-SIZE-ADJUST-1]
CSS 모바일 텍스트 크기 조정 모듈 레벨 1. 편집자 초안. URL: https://drafts.csswg.org/css-size-adjust-1/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. URL: https://drafts.csswg.org/css-values-3/
[HTTP11]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP/1.1. 2022년 6월. 인터넷 표준. URL: https://httpwg.org/specs/rfc9112.html
[JSON-RPC]
JSON-RPC Working Group. JSON-RPC 2.0 명세. 2013년 1월 4일. URL: https://www.jsonrpc.org/specification
[RFC6265BIS]
Cookies: HTTP 상태 관리 메커니즘. 편집자 초안. URL: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis
[TOUCH-EVENTS]
Doug Schepers; et al. Touch Events. URL: https://w3c.github.io/touch-events/
[URLPattern]
Ben Kelly; Jeremy Roman; 宍戸俊哉 (Shunya Shishido). URL Pattern 표준. Living Standard. URL: https://urlpattern.spec.whatwg.org/

CDDL 색인

원격 끝 정의

Command = {
  id: js-uint,
  CommandData,
  Extensible,
}

CommandData = (
  BrowserCommand //
  BrowsingContextCommand //
  EmulationCommand //
  InputCommand //
  NetworkCommand //
  ScriptCommand //
  SessionCommand //
  StorageCommand //
  WebExtensionCommand
)

EmptyParams = {
   Extensible
}

Extensible = (*text => any)

js-int = -9007199254740991..9007199254740991
js-uint = 0..9007199254740991

SessionCommand = (
  session.End //
  session.New //
  session.Status //
  session.Subscribe //
  session.Unsubscribe
)

session.CapabilitiesRequest = {
  ? alwaysMatch: session.CapabilityRequest,
  ? firstMatch: [*session.CapabilityRequest]
}

session.CapabilityRequest = {
  ? acceptInsecureCerts: bool,
  ? browserName: text,
  ? browserVersion: text,
  ? platformName: text,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler,
  Extensible
}

session.CapabilityResponse = {
  acceptInsecureCerts: bool,
  browserName: text,
  browserVersion: text,
  platformName: text,
  setWindowRect: bool,
  userAgent: text,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler,
  ? webSocketUrl: text,
  Extensible
}

session.ProxyConfiguration = {
   session.AutodetectProxyConfiguration //
   session.DirectProxyConfiguration //
   session.ManualProxyConfiguration //
   session.PacProxyConfiguration //
   session.SystemProxyConfiguration
}

session.AutodetectProxyConfiguration = (
   proxyType: "autodetect",
   Extensible
)

session.DirectProxyConfiguration = (
   proxyType: "direct",
   Extensible
)

session.ManualProxyConfiguration = (
   proxyType: "manual",
   ? httpProxy: text,
   ? sslProxy: text,
   ? session.SocksProxyConfiguration,
   ? noProxy: [*text],
   Extensible
)

session.SocksProxyConfiguration = (
   socksProxy: text,
   socksVersion: 0..255,
)

session.PacProxyConfiguration = (
   proxyType: "pac",
   proxyAutoconfigUrl: text,
   Extensible
)

session.SystemProxyConfiguration = (
   proxyType: "system",
   Extensible
)


session.UserPromptHandler = {
  ? alert: session.UserPromptHandlerType,
  ? beforeUnload: session.UserPromptHandlerType,
  ? confirm: session.UserPromptHandlerType,
  ? default: session.UserPromptHandlerType,
  ? file: session.UserPromptHandlerType,
  ? prompt: session.UserPromptHandlerType,
}

session.UserPromptHandlerType = "accept" / "dismiss" / "ignore";

session.Subscription = text

session.SubscribeParameters = {
  events: [+text],
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

session.UnsubscribeByIDRequest = {
  subscriptions: [+session.Subscription],
}

session.UnsubscribeByAttributesRequest = {
  events: [+text],
}

session.Status = (
  method: "session.status",
  params: EmptyParams,
)

session.New = (
  method: "session.new",
  params: session.NewParameters
)

session.NewParameters = {
  capabilities: session.CapabilitiesRequest
}

session.End = (
  method: "session.end",
  params: EmptyParams
)


session.Subscribe = (
  method: "session.subscribe",
  params: session.SubscribeParameters
)

session.Unsubscribe = (
  method: "session.unsubscribe",
  params: session.UnsubscribeParameters,
)

session.UnsubscribeParameters = session.UnsubscribeByAttributesRequest / session.UnsubscribeByIDRequest

BrowserCommand = (
  browser.Close //
  browser.CreateUserContext //
  browser.GetClientWindows //
  browser.GetUserContexts //
  browser.RemoveUserContext //
  browser.SetClientWindowState //
  browser.SetDownloadBehavior
)

browser.ClientWindow = text;

browser.ClientWindowInfo = {
  active: bool,
  clientWindow: browser.ClientWindow,
  height: js-uint,
  state: "fullscreen" / "maximized" / "minimized" / "normal",
  width: js-uint,
  x: js-int,
  y: js-int,
}

browser.UserContext = text;

browser.UserContextInfo = {
  userContext: browser.UserContext
}

browser.Close = (
  method: "browser.close",
  params: EmptyParams,
)

browser.CreateUserContext = (
  method: "browser.createUserContext",
  params: browser.CreateUserContextParameters,
)

browser.CreateUserContextParameters = {
  ? acceptInsecureCerts: bool,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler
}

browser.GetClientWindows = (
  method: "browser.getClientWindows",
  params: EmptyParams,
)

browser.GetUserContexts = (
  method: "browser.getUserContexts",
  params: EmptyParams,
)

browser.RemoveUserContext = (
  method: "browser.removeUserContext",
  params: browser.RemoveUserContextParameters
)

browser.RemoveUserContextParameters = {
  userContext: browser.UserContext
}

browser.SetClientWindowState = (
  method: "browser.setClientWindowState",
  params: browser.SetClientWindowStateParameters
)

browser.SetClientWindowStateParameters = {
  clientWindow: browser.ClientWindow,
  (browser.ClientWindowNamedState // browser.ClientWindowRectState)
}

browser.ClientWindowNamedState = (
  state: "fullscreen" / "maximized" / "minimized"
)

browser.ClientWindowRectState = (
  state: "normal",
  ? width: js-uint,
  ? height: js-uint,
  ? x: js-int,
  ? y: js-int,
)

browser.SetDownloadBehavior = (
  method: "browser.setDownloadBehavior",
  params: browser.SetDownloadBehaviorParameters
)

browser.SetDownloadBehaviorParameters = {
  downloadBehavior: browser.DownloadBehavior / null,
  ? userContexts: [+browser.UserContext]
}

browser.DownloadBehavior = {
  (
    browser.DownloadBehaviorAllowed //
    browser.DownloadBehaviorDenied
  )
}

browser.DownloadBehaviorAllowed = (
  type: "allowed",
  destinationFolder: text
)

browser.DownloadBehaviorDenied = (
  type: "denied"
)

BrowsingContextCommand = (
  browsingContext.Activate //
  browsingContext.CaptureScreenshot //
  browsingContext.Close //
  browsingContext.Create //
  browsingContext.GetTree //
  browsingContext.HandleUserPrompt //
  browsingContext.LocateNodes //
  browsingContext.Navigate //
  browsingContext.Print //
  browsingContext.Reload //
  browsingContext.SetBypassCSP //
  browsingContext.SetViewport //
  browsingContext.StartScreencast //
  browsingContext.StopScreencast //
  browsingContext.TraverseHistory
)

browsingContext.BrowsingContext = text;

browsingContext.Locator = (
   browsingContext.AccessibilityLocator /
   browsingContext.CssLocator /
   browsingContext.ContextLocator /
   browsingContext.InnerTextLocator /
   browsingContext.XPathLocator
)

browsingContext.AccessibilityLocator = {
   type: "accessibility",
   value: {
    ? name: text,
    ? role: text,
   }
}

browsingContext.CssLocator = {
   type: "css",
   value: text
}

browsingContext.ContextLocator = {
  type: "context",
  value: {
    context: browsingContext.BrowsingContext,
  }
}

browsingContext.InnerTextLocator = {
   type: "innerText",
   value: text,
   ? ignoreCase: bool
   ? matchType: "full" / "partial",
   ? maxDepth: js-uint,
}

browsingContext.XPathLocator = {
   type: "xpath",
   value: text
}

browsingContext.Navigation = text;

browsingContext.Download = text;

browsingContext.ReadinessState = "none" / "interactive" / "complete"

browsingContext.UserPromptType = "alert" / "beforeunload" / "confirm" / "prompt";

browsingContext.Activate = (
  method: "browsingContext.activate",
  params: browsingContext.ActivateParameters
)

browsingContext.ActivateParameters = {
  context: browsingContext.BrowsingContext
}

browsingContext.CaptureScreenshot = (
  method: "browsingContext.captureScreenshot",
  params: browsingContext.CaptureScreenshotParameters
)

browsingContext.CaptureScreenshotParameters = {
  context: browsingContext.BrowsingContext,
  ? origin: ("viewport" / "document") .default "viewport",
  ? format: browsingContext.ImageFormat,
  ? clip: browsingContext.ClipRectangle,
  ? imageSize: browsingContext.ImageSize,
}

browsingContext.ImageFormat = {
   type: text,
   ? quality: 0.0..1.0,
}

browsingContext.ImageSize = {
   ? maxWidth: (js-uint .ge 1),
   ? maxHeight: (js-uint .ge 1),
}

browsingContext.ClipRectangle = (
  browsingContext.BoxClipRectangle /
  browsingContext.ElementClipRectangle
)

browsingContext.ElementClipRectangle = {
  type: "element",
  element: script.SharedReference
}

browsingContext.BoxClipRectangle = {
   type: "box",
   x: float,
   y: float,
   width: float,
   height: float
}

browsingContext.Close = (
  method: "browsingContext.close",
  params: browsingContext.CloseParameters
)

browsingContext.CloseParameters = {
  context: browsingContext.BrowsingContext,
  ? promptUnload: bool .default false
}

browsingContext.Create = (
  method: "browsingContext.create",
  params: browsingContext.CreateParameters
)

browsingContext.CreateType = "tab" / "window"

browsingContext.CreateParameters = {
  type: browsingContext.CreateType,
  ? referenceContext: browsingContext.BrowsingContext,
  ? background: bool .default false,
  ? userContext: browser.UserContext
}

browsingContext.GetTree = (
  method: "browsingContext.getTree",
  params: browsingContext.GetTreeParameters
)

browsingContext.GetTreeParameters = {
  ? maxDepth: js-uint,
  ? root: browsingContext.BrowsingContext,
}

browsingContext.HandleUserPrompt = (
  method: "browsingContext.handleUserPrompt",
  params: browsingContext.HandleUserPromptParameters
)

browsingContext.HandleUserPromptParameters = {
  context: browsingContext.BrowsingContext,
  ? accept: bool,
  ? userText: text,
}

browsingContext.LocateNodes = (
  method: "browsingContext.locateNodes",
  params: browsingContext.LocateNodesParameters
)

browsingContext.LocateNodesParameters = {
   context: browsingContext.BrowsingContext,
   locator: browsingContext.Locator,
   ? maxNodeCount: (js-uint .ge 1),
   ? serializationOptions: script.SerializationOptions,
   ? startNodes: [ + script.SharedReference ]
}

browsingContext.Navigate = (
  method: "browsingContext.navigate",
  params: browsingContext.NavigateParameters
)

browsingContext.NavigateParameters = {
  context: browsingContext.BrowsingContext,
  url: text,
  ? wait: browsingContext.ReadinessState,
}

browsingContext.Print = (
  method: "browsingContext.print",
  params: browsingContext.PrintParameters
)

browsingContext.PrintParameters = {
  context: browsingContext.BrowsingContext,
  ? background: bool .default false,
  ? margin: browsingContext.PrintMarginParameters,
  ? orientation: ("portrait" / "landscape") .default "portrait",
  ? page: browsingContext.PrintPageParameters,
  ? pageRanges: [*(js-uint / text)],
  ? scale: (0.1..2.0) .default 1.0,
  ? shrinkToFit: bool .default true,
}

browsingContext.PrintMarginParameters = {
  ? bottom: (float .ge 0.0) .default 1.0,
  ? left: (float .ge 0.0) .default 1.0,
  ? right: (float .ge 0.0) .default 1.0,
  ? top: (float .ge 0.0) .default 1.0,
}

; Minimum size is 1pt x 1pt. Conversion follows from
; https://www.w3.org/TR/css3-values/#absolute-lengths
browsingContext.PrintPageParameters = {
  ? height: (float .ge 0.0352) .default 27.94,
  ? width: (float .ge 0.0352) .default 21.59,
}

browsingContext.Reload = (
  method: "browsingContext.reload",
  params: browsingContext.ReloadParameters
)

browsingContext.ReloadParameters = {
  context: browsingContext.BrowsingContext,
  ? ignoreCache: bool,
  ? wait: browsingContext.ReadinessState,
}

browsingContext.SetBypassCSP = (
  method: "browsingContext.setBypassCSP",
  params: browsingContext.SetBypassCSPParameters
)

browsingContext.SetBypassCSPParameters = {
  bypass: true / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

browsingContext.SetViewport = (
  method: "browsingContext.setViewport",
  params: browsingContext.SetViewportParameters
)

browsingContext.SetViewportParameters = {
  ? context: browsingContext.BrowsingContext,
  ? viewport: browsingContext.Viewport / null,
  ? devicePixelRatio: (float .gt 0.0) / null,
  ? userContexts: [+browser.UserContext],
}

browsingContext.Viewport = {
  width: js-uint,
  height: js-uint,
}

browsingContext.StartScreencast = (
  method: "browsingContext.startScreencast",
  params: browsingContext.StartScreencastParameters
)

browsingContext.StartScreencastParameters = {
  context: browsingContext.BrowsingContext,
  ? destinationFolder: text,
  ? mimeType: text,
  ? video: browsingContext.MediaTrackConstraints,
  ? audio: bool .default false,
}

browsingContext.MediaTrackConstraints = {
   ? width: js-uint,
   ? height: js-uint,
   ? frameRate: js-uint,
}


browsingContext.Screencast = text

browsingContext.StopScreencast = (
  method: "browsingContext.stopScreencast",
  params: browsingContext.StopScreencastParameters
)

browsingContext.StopScreencastParameters = {
  screencast: browsingContext.Screencast
}

browsingContext.TraverseHistory = (
  method: "browsingContext.traverseHistory",
  params: browsingContext.TraverseHistoryParameters
)

browsingContext.TraverseHistoryParameters = {
  context: browsingContext.BrowsingContext,
  delta: js-int,
}

EmulationCommand = (
  emulation.SetForcedColorsModeThemeOverride //
  emulation.SetGeolocationOverride //
  emulation.SetLocaleOverride //
  emulation.SetMediaFeaturesOverride //
  emulation.SetNetworkConditions //
  emulation.SetScreenOrientationOverride //
  emulation.SetScreenSettingsOverride //
  emulation.SetScriptingEnabled //
  emulation.SetScrollbarTypeOverride //
  emulation.SetTextLayoutModeOverride //
  emulation.SetTimezoneOverride //
  emulation.SetTouchOverride //
  emulation.SetUserAgentOverride //
  emulation.SetViewportMetaOverride
)


emulation.SetForcedColorsModeThemeOverride = (
  method: "emulation.setForcedColorsModeThemeOverride",
  params: emulation.SetForcedColorsModeThemeOverrideParameters
)

emulation.SetForcedColorsModeThemeOverrideParameters = {
  theme: emulation.ForcedColorsModeTheme / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.ForcedColorsModeTheme = "light" / "dark"

emulation.SetGeolocationOverride = (
  method: "emulation.setGeolocationOverride",
  params: emulation.SetGeolocationOverrideParameters
)

emulation.SetGeolocationOverrideParameters = {
  (
    (coordinates: emulation.GeolocationCoordinates / null) //
    (error: emulation.GeolocationPositionError)
  ),
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.GeolocationCoordinates = {
   latitude: -90.0..90.0,
   longitude: -180.0..180.0,
   ? accuracy: (float .ge 0.0) .default 1.0,
   ? altitude: float / null .default null,
   ? altitudeAccuracy: (float .ge 0.0) / null .default null,
   ? heading: (0.0...360.0) / null .default null,
   ? speed: (float .ge 0.0) / null .default null,
}

emulation.GeolocationPositionError = {
   type: "positionUnavailable"
}

emulation.SetLocaleOverride = (
  method: "emulation.setLocaleOverride",
  params: emulation.SetLocaleOverrideParameters
)

emulation.SetLocaleOverrideParameters = {
  locale: text / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetMediaFeaturesOverride = (
  method: "emulation.setMediaFeaturesOverride",
  params: emulation.SetMediaFeaturesOverrideParameters
)

emulation.SetMediaFeaturesOverrideParameters = {
  features: emulation.MediaFeatures / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.MediaFeatures = {
  ? "any-hover": "none" / "hover" / null,
  ? "any-pointer": "none" / "coarse" / "fine" / null,
  ? "color": js-uint / null,
  ? "color-gamut": "srgb" / "p3" / "rec2020" / null,
  ? "color-index": js-uint / null,
  ? "display-mode": "fullscreen" / "standalone" / "minimal-ui" / "browser" / "picture-in-picture" / null,
  ? "dynamic-range": "standard" / "high" / null,
  ? "environment-blending": "opaque" / "additive" / "subtractive" / null,
  ? "forced-colors": "none" / "active" / null,
  ? "grid": 0 / 1 / null,
  ? "horizontal-viewport-segments": js-uint / null,
  ? "hover": "none" / "hover" / null,
  ? "inverted-colors": "none" / "inverted" / null,
  ? "monochrome": js-uint / null,
  ? "nav-controls": "none" / "back" / null,
  ? "overflow-block": "none" / "scroll" / "optional-paged" / "paged" / null,
  ? "overflow-inline": "none" / "scroll" / null,
  ? "pointer": "none" / "coarse" / "fine" / null,
  ? "prefers-color-scheme": "light" / "dark" / null,
  ? "prefers-contrast": "no-preference" / "more" / "less" / "custom" / null,
  ? "prefers-reduced-data": "no-preference" / "reduce" / null,
  ? "prefers-reduced-motion": "no-preference" / "reduce" / null,
  ? "prefers-reduced-transparency": "no-preference" / "reduce" / null,
  ? "scan": "interlace" / "progressive" / null,
  ? "scripting": "none" / "initial-only" / "enabled" / null,
  ? "update": "none" / "slow" / "fast" / null,
  ? "vertical-viewport-segments": js-uint / null,
  ? "video-color-gamut": "srgb" / "p3" / "rec2020" / null,
  ? "video-dynamic-range": "standard" / "high" / null,
}


emulation.SetNetworkConditions = (
  method: "emulation.setNetworkConditions",
  params: emulation.SetNetworkConditionsParameters
)

emulation.SetNetworkConditionsParameters = {
  networkConditions: emulation.NetworkConditions / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.NetworkConditions = emulation.NetworkConditionsOffline

emulation.NetworkConditionsOffline = {
  type: "offline"
}

emulation.SetScreenSettingsOverride = (
  method: "emulation.setScreenSettingsOverride",
  params: emulation.SetScreenSettingsOverrideParameters
)

emulation.ScreenArea = {
  width: js-uint,
  height: js-uint
}

emulation.SetScreenSettingsOverrideParameters = {
  screenArea: emulation.ScreenArea / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetScreenOrientationOverride = (
  method: "emulation.setScreenOrientationOverride",
  params: emulation.SetScreenOrientationOverrideParameters
)

emulation.ScreenOrientationNatural = "portrait" / "landscape"
emulation.ScreenOrientationType = "portrait-primary" / "portrait-secondary" / "landscape-primary" / "landscape-secondary"

emulation.ScreenOrientation = {
  natural: emulation.ScreenOrientationNatural,
  type: emulation.ScreenOrientationType
}

emulation.SetScreenOrientationOverrideParameters = {
  screenOrientation: emulation.ScreenOrientation / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetUserAgentOverride = (
  method: "emulation.setUserAgentOverride",
  params: emulation.SetUserAgentOverrideParameters
)

emulation.SetUserAgentOverrideParameters = {
  userAgent: text / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetViewportMetaOverride = (
  method: "emulation.setViewportMetaOverride",
  params: emulation.SetViewportMetaOverrideParameters
)

emulation.SetViewportMetaOverrideParameters = {
  viewportMeta: true / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetScriptingEnabled = (
  method: "emulation.setScriptingEnabled",
  params: emulation.SetScriptingEnabledParameters
)

emulation.SetScriptingEnabledParameters = {
  enabled: false / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetScrollbarTypeOverride = (
  method: "emulation.setScrollbarTypeOverride",
  params: emulation.SetScrollbarTypeOverrideParameters
)

emulation.SetScrollbarTypeOverrideParameters = {
  scrollbarType: "classic" / "overlay" / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetTextLayoutModeOverride = (
  method: "emulation.setTextLayoutModeOverride",
  params: emulation.SetTextLayoutModeOverrideParameters
)

emulation.SetTextLayoutModeOverrideParameters = {
  textLayoutMode: emulation.TextLayoutMode / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.TextLayoutMode = "mobile"

emulation.SetTimezoneOverride = (
  method: "emulation.setTimezoneOverride",
  params: emulation.SetTimezoneOverrideParameters
)

emulation.SetTimezoneOverrideParameters = {
  timezone: text / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

emulation.SetTouchOverride = (
  method: "emulation.setTouchOverride",
  params: emulation.SetTouchOverrideParameters
)

emulation.SetTouchOverrideParameters = {
  maxTouchPoints: (js-uint .ge 1) / null,
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

NetworkCommand = (
  network.AddDataCollector //
  network.AddIntercept //
  network.ContinueRequest //
  network.ContinueResponse //
  network.ContinueWithAuth //
  network.DisownData //
  network.FailRequest //
  network.GetData //
  network.ProvideResponse //
  network.RemoveDataCollector //
  network.RemoveIntercept //
  network.SetCacheBehavior //
  network.SetExtraHeaders
)


network.AuthCredentials = {
  type: "password",
  username: text,
  password: text,
}

network.BytesValue = network.StringValue / network.Base64Value;

network.StringValue = {
  type: "string",
  value: text,
}

network.Base64Value = {
  type: "base64",
  value: text,
}

network.Collector = text

network.CollectorType = "blob"

network.SameSite = "strict" / "lax" / "none" / "default"


network.Cookie = {
    name: text,
    value: network.BytesValue,
    domain: text,
    path: text,
    size: js-uint,
    httpOnly: bool,
    secure: bool,
    sameSite: network.SameSite,
    ? expiry: js-uint,
    Extensible,
}

network.CookieHeader = {
    name: text,
    value: network.BytesValue,
}

network.DataType = "request" / "response"

network.Header = {
  name: text,
  value: network.BytesValue,
}

network.Intercept = text

network.Request = text;

network.SetCookieHeader = {
    name: text,
    value: network.BytesValue,
    ? domain: text,
    ? httpOnly: bool,
    ? expiry: text,
    ? maxAge: js-int,
    ? path: text,
    ? sameSite: network.SameSite,
    ? secure: bool,
}

network.UrlPattern = (
  network.UrlPatternPattern /
  network.UrlPatternString
)

network.UrlPatternPattern = {
    type: "pattern",
    ?protocol: text,
    ?hostname: text,
    ?port: text,
    ?pathname: text,
    ?search: text,
}


network.UrlPatternString = {
    type: "string",
    pattern: text,
}


network.AddDataCollector = (
  method: "network.addDataCollector",
  params: network.AddDataCollectorParameters
)

network.AddDataCollectorParameters = {
  dataTypes: [+network.DataType],
  maxEncodedDataSize: js-uint,
  ? collectorType: network.CollectorType .default "blob",
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
}

network.AddIntercept = (
  method: "network.addIntercept",
  params: network.AddInterceptParameters
)

network.AddInterceptParameters = {
  phases: [+network.InterceptPhase],
  ? contexts: [+browsingContext.BrowsingContext],
  ? urlPatterns: [*network.UrlPattern],
}

network.InterceptPhase = "beforeRequestSent" / "responseStarted" /
                         "authRequired"

network.ContinueRequest = (
  method: "network.continueRequest",
  params: network.ContinueRequestParameters
)

network.ContinueRequestParameters = {
  request: network.Request,
  ?body: network.BytesValue,
  ?cookies: [*network.CookieHeader],
  ?headers: [*network.Header],
  ?method: text,
  ?url: text,
}

network.ContinueResponse = (
  method: "network.continueResponse",
  params: network.ContinueResponseParameters
)

network.ContinueResponseParameters = {
  request: network.Request,
  ?cookies: [*network.SetCookieHeader]
  ?credentials: network.AuthCredentials,
  ?headers: [*network.Header],
  ?reasonPhrase: text,
  ?statusCode: js-uint,
}

network.ContinueWithAuth = (
  method: "network.continueWithAuth",
  params: network.ContinueWithAuthParameters
)

network.ContinueWithAuthParameters = {
  request: network.Request,
  (network.ContinueWithAuthCredentials // network.ContinueWithAuthNoCredentials)
}

network.ContinueWithAuthCredentials = (
  action: "provideCredentials", 
  credentials: network.AuthCredentials
)

network.ContinueWithAuthNoCredentials = (
  action: "default" / "cancel"
)

network.DisownData = (
  method: "network.disownData",
  params: network.DisownDataParameters
)

network.DisownDataParameters = {
  dataType: network.DataType,
  collector: network.Collector,
  request: network.Request,
}

network.FailRequest = (
  method: "network.failRequest",
  params: network.FailRequestParameters
)

network.FailRequestParameters = {
  request: network.Request,
}

network.GetData = (
  method: "network.getData",
  params: network.GetDataParameters
)

network.GetDataParameters = {
  dataType: network.DataType,
  ? collector: network.Collector,
  ? disown: bool .default false,
  request: network.Request,
}

network.ProvideResponse = (
  method: "network.provideResponse",
  params: network.ProvideResponseParameters
)

network.ProvideResponseParameters = {
  request: network.Request,
  ?body: network.BytesValue,
  ?cookies: [*network.SetCookieHeader],
  ?headers: [*network.Header],
  ?reasonPhrase: text,
  ?statusCode: js-uint,
}

network.RemoveDataCollector = (
  method: "network.removeDataCollector",
  params: network.RemoveDataCollectorParameters
)

network.RemoveDataCollectorParameters = {
  collector: network.Collector
}

network.RemoveIntercept = (
  method: "network.removeIntercept",
  params: network.RemoveInterceptParameters
)

network.RemoveInterceptParameters = {
  intercept: network.Intercept
}

network.SetCacheBehavior = (
  method: "network.setCacheBehavior",
  params: network.SetCacheBehaviorParameters
)

network.SetCacheBehaviorParameters = {
  cacheBehavior: "default" / "bypass",
  ? contexts: [+browsingContext.BrowsingContext]
}

network.SetExtraHeaders = (
  method: "network.setExtraHeaders",
  params: network.SetExtraHeadersParameters
)

network.SetExtraHeadersParameters = {
  headers: [*network.Header]
  ? contexts: [+browsingContext.BrowsingContext]
  ? userContexts: [+browser.UserContext]
}

ScriptCommand = (
  script.AddPreloadScript //
  script.CallFunction //
  script.Disown //
  script.Evaluate //
  script.GetRealms //
  script.RemovePreloadScript
)

script.Channel = text;

script.ChannelValue = {
  type: "channel",
  value: script.ChannelProperties,
}

script.ChannelProperties = {
  channel: script.Channel,
  ? serializationOptions: script.SerializationOptions,
  ? ownership: script.ResultOwnership,
}

script.EvaluationResult = (
  script.EvaluationResultSuccess /
  script.EvaluationResultException
)

script.EvaluationResultSuccess = {
  type: "success",
  result: script.RemoteValue,
  realm: script.Realm
}

script.EvaluationResultException = {
  type: "exception",
  exceptionDetails: script.ExceptionDetails
  realm: script.Realm
}

script.ExceptionDetails = {
  columnNumber: js-uint,
  exception: script.RemoteValue,
  lineNumber: js-uint,
  stackTrace: script.StackTrace,
  text: text,
}

script.Handle = text;

script.InternalId = text;

script.LocalValue = (
  script.RemoteReference /
  script.PrimitiveProtocolValue /
  script.ChannelValue /
  script.ArrayLocalValue /
  { script.DateLocalValue } /
  script.MapLocalValue /
  script.ObjectLocalValue /
  { script.RegExpLocalValue } /
  script.SetLocalValue
)

script.ListLocalValue = [*script.LocalValue];

script.ArrayLocalValue = {
  type: "array",
  value: script.ListLocalValue,
}

script.DateLocalValue = (
  type: "date",
  value: text
)

script.MappingLocalValue = [*[(script.LocalValue / text), script.LocalValue]];

script.MapLocalValue = {
  type: "map",
  value: script.MappingLocalValue,
}

script.ObjectLocalValue = {
  type: "object",
  value: script.MappingLocalValue,
}

script.RegExpValue = {
  pattern: text,
  ? flags: text,
}

script.RegExpLocalValue = (
  type: "regexp",
  value: script.RegExpValue,
)

script.SetLocalValue = {
  type: "set",
  value: script.ListLocalValue,
}

script.PreloadScript = text;

script.Realm = text;

script.PrimitiveProtocolValue = (
  script.UndefinedValue /
  script.NullValue /
  script.StringValue /
  script.NumberValue /
  script.BooleanValue /
  script.BigIntValue
)

script.UndefinedValue = {
  type: "undefined",
}

script.NullValue = {
  type: "null",
}

script.StringValue = {
  type: "string",
  value: text,
}

script.SpecialNumber = "NaN" / "-0" / "Infinity" / "-Infinity";

script.NumberValue = {
  type: "number",
  value: number / script.SpecialNumber,
}

script.BooleanValue = {
  type: "boolean",
  value: bool,
}

script.BigIntValue = {
  type: "bigint",
  value: text,
}

script.RealmType = "window" / "dedicated-worker" / "shared-worker" / "service-worker" /
                   "worker" / "paint-worklet" / "audio-worklet" / "worklet"

script.RemoteReference = (
  script.SharedReference /
  script.RemoteObjectReference
)

script.SharedReference = {
   sharedId: script.SharedId

   ? handle: script.Handle,
   Extensible
}

script.RemoteObjectReference = {
   handle: script.Handle,

   ? sharedId: script.SharedId
   Extensible
}

script.RemoteValue = (
  script.PrimitiveProtocolValue /
  script.SymbolRemoteValue /
  script.ArrayRemoteValue /
  script.ObjectRemoteValue /
  script.FunctionRemoteValue /
  script.RegExpRemoteValue /
  script.DateRemoteValue /
  script.MapRemoteValue /
  script.SetRemoteValue /
  script.WeakMapRemoteValue /
  script.WeakSetRemoteValue /
  script.GeneratorRemoteValue /
  script.ErrorRemoteValue /
  script.ProxyRemoteValue /
  script.PromiseRemoteValue /
  script.TypedArrayRemoteValue /
  script.ArrayBufferRemoteValue /
  script.NodeListRemoteValue /
  script.HTMLCollectionRemoteValue /
  script.NodeRemoteValue /
  script.WindowProxyRemoteValue
)

script.ListRemoteValue = [*script.RemoteValue];

script.MappingRemoteValue = [*[(script.RemoteValue / text), script.RemoteValue]];

script.SymbolRemoteValue = {
  type: "symbol",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ArrayRemoteValue = {
  type: "array",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.ObjectRemoteValue = {
  type: "object",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.MappingRemoteValue,
}

script.FunctionRemoteValue = {
  type: "function",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.RegExpRemoteValue = {
  script.RegExpLocalValue,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.DateRemoteValue = {
  script.DateLocalValue,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.MapRemoteValue = {
  type: "map",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.MappingRemoteValue,
}

script.SetRemoteValue = {
  type: "set",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue
}

script.WeakMapRemoteValue = {
  type: "weakmap",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.WeakSetRemoteValue = {
  type: "weakset",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.GeneratorRemoteValue = {
  type: "generator",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ErrorRemoteValue = {
  type: "error",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ProxyRemoteValue = {
  type: "proxy",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.PromiseRemoteValue = {
  type: "promise",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.TypedArrayRemoteValue = {
  type: "typedarray",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ArrayBufferRemoteValue = {
  type: "arraybuffer",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.NodeListRemoteValue = {
  type: "nodelist",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.HTMLCollectionRemoteValue = {
  type: "htmlcollection",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.NodeRemoteValue = {
  type: "node",
  ? sharedId: script.SharedId,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.NodeProperties,
}

script.NodeProperties = {
  nodeType: js-uint,
  childNodeCount: js-uint,
  ? attributes: {*text => text},
  ? children: [*script.NodeRemoteValue],
  ? localName: text,
  ? mode: "open" / "closed",
  ? namespaceURI: text,
  ? nodeValue: text,
  ? shadowRoot: script.NodeRemoteValue / null,
}

script.WindowProxyRemoteValue = {
  type: "window",
  value: script.WindowProxyProperties,
  ? handle: script.Handle,
  ? internalId: script.InternalId
}

script.WindowProxyProperties = {
  context: browsingContext.BrowsingContext
}

script.ResultOwnership = "root" / "none"

script.SerializationOptions = {
  ? maxDomDepth: (js-uint / null) .default 0,
  ? maxObjectDepth: (js-uint / null) .default null,
  ? includeShadowTree: ("none" / "open" / "all") .default "none",
}

script.SharedId = text;

script.StackFrame = {
  columnNumber: js-uint,
  functionName: text,
  lineNumber: js-uint,
  url: text,
}

script.StackTrace = {
  callFrames: [*script.StackFrame],
}

script.RealmTarget = {
  realm: script.Realm
}

script.ContextTarget = {
  context: browsingContext.BrowsingContext,
  ? sandbox: text
}

script.Target = (
  script.ContextTarget /
  script.RealmTarget
)

script.AddPreloadScript = (
  method: "script.addPreloadScript",
  params: script.AddPreloadScriptParameters
)

script.AddPreloadScriptParameters = {
  functionDeclaration: text,
  ? arguments: [*script.ChannelValue],
  ? contexts: [+browsingContext.BrowsingContext],
  ? userContexts: [+browser.UserContext],
  ? sandbox: text
}

script.Disown = (
  method: "script.disown",
  params: script.DisownParameters
)

script.DisownParameters = {
  handles: [*script.Handle]
  target: script.Target;
}

script.CallFunction = (
  method: "script.callFunction",
  params: script.CallFunctionParameters
)

script.CallFunctionParameters = {
  functionDeclaration: text,
  awaitPromise: bool,
  target: script.Target,
  ? arguments: [*script.LocalValue],
  ? resultOwnership: script.ResultOwnership,
  ? serializationOptions: script.SerializationOptions,
  ? this: script.LocalValue,
  ? userActivation: bool .default false,
}

script.Evaluate = (
  method: "script.evaluate",
  params: script.EvaluateParameters
)

script.EvaluateParameters = {
  expression: text,
  target: script.Target,
  awaitPromise: bool,
  ? resultOwnership: script.ResultOwnership,
  ? serializationOptions: script.SerializationOptions,
  ? userActivation: bool .default false,
}

script.GetRealms = (
  method: "script.getRealms",
  params: script.GetRealmsParameters
)

script.GetRealmsParameters = {
  ? context: browsingContext.BrowsingContext,
  ? type: script.RealmType,
}

script.RemovePreloadScript = (
  method: "script.removePreloadScript",
  params: script.RemovePreloadScriptParameters
)

script.RemovePreloadScriptParameters = {
  script: script.PreloadScript
}

StorageCommand = (
  storage.DeleteCookies //
  storage.GetCookies //
  storage.SetCookie
)

storage.PartitionKey = {
  ? userContext: text,
  ? sourceOrigin: text,
  Extensible,
}

storage.GetCookies = (
  method: "storage.getCookies",
  params: storage.GetCookiesParameters
)


storage.CookieFilter = {
  ? name: text,
  ? value: network.BytesValue,
  ? domain: text,
  ? path: text,
  ? size: js-uint,
  ? httpOnly: bool,
  ? secure: bool,
  ? sameSite: network.SameSite,
  ? expiry: js-uint,
  Extensible,
}

storage.BrowsingContextPartitionDescriptor = {
  type: "context",
  context: browsingContext.BrowsingContext
}

storage.StorageKeyPartitionDescriptor = {
  type: "storageKey",
  ? userContext: text,
  ? sourceOrigin: text,
  Extensible,
}

storage.PartitionDescriptor = (
  storage.BrowsingContextPartitionDescriptor /
  storage.StorageKeyPartitionDescriptor
)

storage.GetCookiesParameters = {
  ? filter: storage.CookieFilter,
  ? partition: storage.PartitionDescriptor,
}

storage.SetCookie = (
  method: "storage.setCookie",
  params: storage.SetCookieParameters,
)


storage.PartialCookie = {
  name: text,
  value: network.BytesValue,
  domain: text,
  ? path: text,
  ? httpOnly: bool,
  ? secure: bool,
  ? sameSite: network.SameSite,
  ? expiry: js-uint,
  Extensible,
}

storage.SetCookieParameters = {
  cookie: storage.PartialCookie,
  ? partition: storage.PartitionDescriptor,
}

storage.DeleteCookies = (
  method: "storage.deleteCookies",
  params: storage.DeleteCookiesParameters,
)

storage.DeleteCookiesParameters = {
  ? filter: storage.CookieFilter,
  ? partition: storage.PartitionDescriptor,
}

InputCommand = (
  input.PerformActions //
  input.ReleaseActions //
  input.SetFiles
)

input.ElementOrigin = {
  type: "element",
  element: script.SharedReference
}

input.PerformActions = (
  method: "input.performActions",
  params: input.PerformActionsParameters
)

input.PerformActionsParameters = {
  context: browsingContext.BrowsingContext,
  actions: [*input.SourceActions]
}

input.SourceActions = (
  input.NoneSourceActions /
  input.KeySourceActions /
  input.PointerSourceActions /
  input.WheelSourceActions
)

input.NoneSourceActions = {
  type: "none",
  id: text,
  actions: [*input.NoneSourceAction]
}

input.NoneSourceAction = input.PauseAction

input.KeySourceActions = {
  type: "key",
  id: text,
  actions: [*input.KeySourceAction]
}

input.KeySourceAction = (
  input.PauseAction /
  input.KeyDownAction /
  input.KeyUpAction
)

input.PointerSourceActions = {
  type: "pointer",
  id: text,
  ? parameters: input.PointerParameters,
  actions: [*input.PointerSourceAction]
}

input.PointerType = "mouse" / "pen" / "touch"

input.PointerParameters = {
  ? pointerType: input.PointerType .default "mouse"
}

input.PointerSourceAction = (
  input.PauseAction /
  input.PointerDownAction /
  input.PointerUpAction /
  input.PointerMoveAction
)

input.WheelSourceActions = {
  type: "wheel",
  id: text,
  actions: [*input.WheelSourceAction]
}

input.WheelSourceAction = (
  input.PauseAction /
  input.WheelScrollAction
)

input.PauseAction = {
  type: "pause",
  ? duration: js-uint
}

input.KeyDownAction = {
  type: "keyDown",
  value: text
}

input.KeyUpAction = {
  type: "keyUp",
  value: text
}

input.PointerUpAction = {
  type: "pointerUp",
  button: js-uint,
}

input.PointerDownAction = {
  type: "pointerDown",
  button: js-uint,
  input.PointerCommonProperties
}

input.PointerMoveAction = {
  type: "pointerMove",
  x: float,
  y: float,
  ? duration: js-uint,
  ? origin: input.Origin,
  input.PointerCommonProperties
}

input.WheelScrollAction = {
  type: "scroll",
  x: js-int,
  y: js-int,
  deltaX: js-int,
  deltaY: js-int,
  ? duration: js-uint,
  ? origin: input.Origin .default "viewport",
}

input.PointerCommonProperties = (
  ? width: js-uint,
  ? height: js-uint,
  ? pressure: (0.0..1.0),
  ? tangentialPressure: (-1.0..1.0),
  ? twist: (0..359),
  ; 0 .. Math.PI / 2
  ? altitudeAngle: (0.0..1.5707963267948966),
  ; 0 .. 2 * Math.PI
  ? azimuthAngle: (0.0..6.283185307179586),
)

input.Origin = "viewport" / "pointer" / input.ElementOrigin

input.ReleaseActions = (
  method: "input.releaseActions",
  params: input.ReleaseActionsParameters
)

input.ReleaseActionsParameters = {
  context: browsingContext.BrowsingContext,
}

input.SetFiles = (
  method: "input.setFiles",
  params: input.SetFilesParameters
)

input.SetFilesParameters = {
  context: browsingContext.BrowsingContext,
  element: script.SharedReference,
  files: [*text]
}

WebExtensionCommand = (
  webExtension.Install //
  webExtension.Uninstall
)

webExtension.Extension = text

webExtension.Install = (
   method: "webExtension.install",
   params: webExtension.InstallParameters
)

webExtension.InstallParameters = {
   extensionData: webExtension.ExtensionData,
}

webExtension.ExtensionData = (
   webExtension.ExtensionArchivePath /
   webExtension.ExtensionBase64Encoded /
   webExtension.ExtensionPath
)

webExtension.ExtensionPath = {
   type: "path",
   path: text,
}

webExtension.ExtensionArchivePath = {
   type: "archivePath",
   path: text,
}

webExtension.ExtensionBase64Encoded = {
   type: "base64",
   value: text,
}

webExtension.Uninstall = (
   method: "webExtension.uninstall",
   params: webExtension.UninstallParameters
)

webExtension.UninstallParameters = {
   extension: webExtension.Extension,
}

로컬 끝 정의

Message = (
  CommandResponse /
  ErrorResponse /
  Event
)

CommandResponse = {
  type: "success",
  id: js-uint,
  result: ResultData,
  Extensible
}

ErrorResponse = {
  type: "error",
  id: js-uint / null,
  error: ErrorCode,
  message: text,
  ? stacktrace: text,
  Extensible
}

ResultData = (
  BrowserResult /
  BrowsingContextResult /
  EmulationResult /
  InputResult /
  NetworkResult /
  ScriptResult /
  SessionResult /
  StorageResult /
  WebExtensionResult
)

EmptyResult = {
  Extensible
}

Event = {
  type: "event",
  EventData,
  Extensible
}

EventData = (
  BrowsingContextEvent //
  InputEvent //
  LogEvent //
  NetworkEvent //
  ScriptEvent
)

Extensible = (*text => any)

js-int = -9007199254740991..9007199254740991
js-uint = 0..9007199254740991

ErrorCode = "invalid argument" /
            "invalid selector" /
            "invalid session id" /
            "invalid web extension" /
            "move target out of bounds" /
            "no such alert" /
            "no such network collector" /
            "no such element" /
            "no such frame" /
            "no such handle" /
            "no such history entry" /
            "no such intercept" /
            "no such network data" /
            "no such node" /
            "no such request" /
            "no such screencast" /
            "no such script" /
            "no such storage partition" /
            "no such user context" /
            "no such web extension" /
            "session not created" /
            "unable to capture screen" /
            "unable to close browser" /
            "unable to set cookie" /
            "unable to set file input" /
            "unavailable network data" /
            "underspecified storage partition" /
            "unknown command" /
            "unknown error" /
            "unsupported operation"

SessionResult = (
  session.EndResult /
  session.NewResult /
  session.StatusResult /
  session.SubscribeResult /
  session.UnsubscribeResult
)

session.CapabilitiesRequest = {
  ? alwaysMatch: session.CapabilityRequest,
  ? firstMatch: [*session.CapabilityRequest]
}

session.CapabilityRequest = {
  ? acceptInsecureCerts: bool,
  ? browserName: text,
  ? browserVersion: text,
  ? platformName: text,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler,
  Extensible
}

session.CapabilityResponse = {
  acceptInsecureCerts: bool,
  browserName: text,
  browserVersion: text,
  platformName: text,
  setWindowRect: bool,
  userAgent: text,
  ? proxy: session.ProxyConfiguration,
  ? unhandledPromptBehavior: session.UserPromptHandler,
  ? webSocketUrl: text,
  Extensible
}

session.ProxyConfiguration = {
   session.AutodetectProxyConfiguration //
   session.DirectProxyConfiguration //
   session.ManualProxyConfiguration //
   session.PacProxyConfiguration //
   session.SystemProxyConfiguration
}

session.AutodetectProxyConfiguration = (
   proxyType: "autodetect",
   Extensible
)

session.DirectProxyConfiguration = (
   proxyType: "direct",
   Extensible
)

session.ManualProxyConfiguration = (
   proxyType: "manual",
   ? httpProxy: text,
   ? sslProxy: text,
   ? session.SocksProxyConfiguration,
   ? noProxy: [*text],
   Extensible
)

session.SocksProxyConfiguration = (
   socksProxy: text,
   socksVersion: 0..255,
)

session.PacProxyConfiguration = (
   proxyType: "pac",
   proxyAutoconfigUrl: text,
   Extensible
)

session.SystemProxyConfiguration = (
   proxyType: "system",
   Extensible
)


session.UserPromptHandler = {
  ? alert: session.UserPromptHandlerType,
  ? beforeUnload: session.UserPromptHandlerType,
  ? confirm: session.UserPromptHandlerType,
  ? default: session.UserPromptHandlerType,
  ? file: session.UserPromptHandlerType,
  ? prompt: session.UserPromptHandlerType,
}

session.UserPromptHandlerType = "accept" / "dismiss" / "ignore";

session.Subscription = text

session.StatusResult = {
  ready: bool,
  message: text,
}

session.NewResult = {
  sessionId: text,
  capabilities: session.CapabilityResponse
}

session.EndResult = EmptyResult

session.SubscribeResult = {
  subscription: session.Subscription,
}

session.UnsubscribeResult = EmptyResult

BrowserResult = (
  browser.CloseResult /
  browser.CreateUserContextResult /
  browser.GetClientWindowsResult /
  browser.GetUserContextsResult /
  browser.RemoveUserContextResult /
  browser.SetClientWindowStateResult /
  browser.SetDownloadBehaviorResult
)

browser.ClientWindow = text;

browser.ClientWindowInfo = {
  active: bool,
  clientWindow: browser.ClientWindow,
  height: js-uint,
  state: "fullscreen" / "maximized" / "minimized" / "normal",
  width: js-uint,
  x: js-int,
  y: js-int,
}

browser.UserContext = text;

browser.UserContextInfo = {
  userContext: browser.UserContext
}

browser.CloseResult = EmptyResult

browser.CreateUserContextResult = browser.UserContextInfo

browser.GetClientWindowsResult = {
  clientWindows: [ * browser.ClientWindowInfo]
}

browser.GetUserContextsResult = {
  userContexts: [ + browser.UserContextInfo]
}

browser.RemoveUserContextResult = EmptyResult

browser.SetClientWindowStateResult = browser.ClientWindowInfo

browser.SetDownloadBehaviorResult = EmptyResult

BrowsingContextResult = (
  browsingContext.ActivateResult /
  browsingContext.CaptureScreenshotResult /
  browsingContext.CloseResult /
  browsingContext.CreateResult /
  browsingContext.GetTreeResult /
  browsingContext.HandleUserPromptResult /
  browsingContext.LocateNodesResult /
  browsingContext.NavigateResult /
  browsingContext.PrintResult /
  browsingContext.ReloadResult /
  browsingContext.SetBypassCSPResult /
  browsingContext.SetViewportResult /
  browsingContext.StartScreencastResult /
  browsingContext.StopScreencastResult /
  browsingContext.TraverseHistoryResult
)

BrowsingContextEvent = (
  browsingContext.ContextCreated //
  browsingContext.ContextDestroyed //
  browsingContext.DomContentLoaded //
  browsingContext.DownloadEnd //
  browsingContext.DownloadWillBegin //
  browsingContext.FragmentNavigated //
  browsingContext.HistoryUpdated //
  browsingContext.Load //
  browsingContext.NavigationAborted //
  browsingContext.NavigationCommitted //
  browsingContext.NavigationFailed //
  browsingContext.NavigationStarted //
  browsingContext.UserPromptClosed //
  browsingContext.UserPromptOpened
)

browsingContext.BrowsingContext = text;

browsingContext.InfoList = [*browsingContext.Info]

browsingContext.BaseInfo = (
  children: browsingContext.InfoList / null,
  clientWindow: browser.ClientWindow,
  context: browsingContext.BrowsingContext,
  originalOpener: browsingContext.BrowsingContext / null,
  url: text,
  userContext: browser.UserContext,
  ? parent: browsingContext.BrowsingContext / null,
)

browsingContext.Info = {
  browsingContext.BaseInfo
}

browsingContext.Locator = (
   browsingContext.AccessibilityLocator /
   browsingContext.CssLocator /
   browsingContext.ContextLocator /
   browsingContext.InnerTextLocator /
   browsingContext.XPathLocator
)

browsingContext.AccessibilityLocator = {
   type: "accessibility",
   value: {
    ? name: text,
    ? role: text,
   }
}

browsingContext.CssLocator = {
   type: "css",
   value: text
}

browsingContext.ContextLocator = {
  type: "context",
  value: {
    context: browsingContext.BrowsingContext,
  }
}

browsingContext.InnerTextLocator = {
   type: "innerText",
   value: text,
   ? ignoreCase: bool
   ? matchType: "full" / "partial",
   ? maxDepth: js-uint,
}

browsingContext.XPathLocator = {
   type: "xpath",
   value: text
}

browsingContext.Navigation = text;

browsingContext.Download = text;

browsingContext.BaseNavigationInfo = (
  context: browsingContext.BrowsingContext,
  navigation: browsingContext.Navigation / null,
  timestamp: js-uint,
  url: text,
  ? userContext: browser.UserContext,
)

browsingContext.NavigationInfo = {
  browsingContext.BaseNavigationInfo
}

browsingContext.UserPromptType = "alert" / "beforeunload" / "confirm" / "prompt";

browsingContext.ActivateResult = EmptyResult

browsingContext.CaptureScreenshotResult = {
  data: text
}

browsingContext.CloseResult = EmptyResult

browsingContext.CreateResult = {
  context: browsingContext.BrowsingContext,
  ? userContext: browser.UserContext
}

browsingContext.GetTreeResult = {
  contexts: browsingContext.InfoList
}

browsingContext.HandleUserPromptResult = EmptyResult

browsingContext.LocateNodesResult = {
    nodes: [ * script.NodeRemoteValue ]
}

browsingContext.NavigateResult = {
  navigation: browsingContext.Navigation / null,
  url: text,
}

browsingContext.PrintResult = {
  data: text
}

browsingContext.ReloadResult = browsingContext.NavigateResult

browsingContext.SetBypassCSPResult = EmptyResult

browsingContext.SetViewportResult = EmptyResult

browsingContext.StartScreencastResult = {
   screencast: browsingContext.Screencast,
   path: text
}


browsingContext.Screencast = text

browsingContext.StopScreencastResult = {
   path: text,
   ? error: text
}

browsingContext.TraverseHistoryResult = EmptyResult

browsingContext.ContextCreated = (
 method: "browsingContext.contextCreated",
 params: browsingContext.ContextCreatedParameters
)

browsingContext.ContextCreatedParameters = {
 browsingContext.BaseInfo,
 hasPlannedNavigation: bool,
}

browsingContext.ContextDestroyed = (
 method: "browsingContext.contextDestroyed",
 params: browsingContext.Info
)

browsingContext.NavigationStarted = (
 method: "browsingContext.navigationStarted",
 params: browsingContext.NavigationInfo
)

browsingContext.FragmentNavigated = (
 method: "browsingContext.fragmentNavigated",
 params: browsingContext.NavigationInfo
)

browsingContext.HistoryUpdated = (
  method: "browsingContext.historyUpdated",
  params: browsingContext.HistoryUpdatedParameters
)

browsingContext.HistoryUpdatedParameters = {
  context: browsingContext.BrowsingContext,
  timestamp: js-uint,
  url: text,
  ? userContext: browser.UserContext
}

browsingContext.DomContentLoaded = (
 method: "browsingContext.domContentLoaded",
 params: browsingContext.NavigationInfo
)

browsingContext.Load = (
 method: "browsingContext.load",
 params: browsingContext.NavigationInfo
)

browsingContext.DownloadWillBegin = (
 method: "browsingContext.downloadWillBegin",
 params: browsingContext.DownloadWillBeginParams
)

browsingContext.DownloadWillBeginParams = {
  download: browsingContext.Download,
  suggestedFilename: text,
  browsingContext.BaseNavigationInfo
}

browsingContext.DownloadEnd = (
  method: "browsingContext.downloadEnd",
  params: browsingContext.DownloadEndParams
)

browsingContext.DownloadEndParams = {
  (
    browsingContext.DownloadCanceledParams //
    browsingContext.DownloadCompleteParams
  )
}

browsingContext.DownloadCanceledParams = (
  status: "canceled",
  download: browsingContext.Download,
  browsingContext.BaseNavigationInfo
)

browsingContext.DownloadCompleteParams = (
  status: "complete",
  download: browsingContext.Download,
  filepath: text / null,
  browsingContext.BaseNavigationInfo
)

browsingContext.NavigationAborted = (
 method: "browsingContext.navigationAborted",
 params: browsingContext.NavigationInfo
)

browsingContext.NavigationCommitted = (
 method: "browsingContext.navigationCommitted",
 params: browsingContext.NavigationInfo
)

browsingContext.NavigationFailed = (
 method: "browsingContext.navigationFailed",
 params: browsingContext.NavigationInfo
)

browsingContext.UserPromptClosed = (
  method: "browsingContext.userPromptClosed",
  params: browsingContext.UserPromptClosedParameters
)

browsingContext.UserPromptClosedParameters = {
  context: browsingContext.BrowsingContext,
  accepted: bool,
  type: browsingContext.UserPromptType,
  ? userContext: browser.UserContext,
  ? userText: text
}

browsingContext.UserPromptOpened = (
  method: "browsingContext.userPromptOpened",
  params: browsingContext.UserPromptOpenedParameters
)

browsingContext.UserPromptOpenedParameters = {
  context: browsingContext.BrowsingContext,
  handler: session.UserPromptHandlerType,
  message: text,
  type: browsingContext.UserPromptType,
  ? userContext: browser.UserContext,
  ? defaultValue: text
}

EmulationResult = (
  emulation.SetForcedColorsModeThemeOverrideResult /
  emulation.SetGeolocationOverrideResult /
  emulation.SetLocaleOverrideResult /
  emulation.SetMediaFeaturesOverrideResult /
  emulation.SetScreenOrientationOverrideResult /
  emulation.SetScriptingEnabledResult /
  emulation.SetScrollbarTypeOverrideResult /
  emulation.SetTextLayoutModeOverrideResult /
  emulation.SetTimezoneOverrideResult /
  emulation.SetTouchOverrideResult /
  emulation.SetUserAgentOverrideResult /
  emulation.SetViewportMetaOverrideResult
)

emulation.SetForcedColorsModeThemeOverrideResult = EmptyResult

emulation.SetGeolocationOverrideResult = EmptyResult

emulation.SetLocaleOverrideResult = EmptyResult

emulation.SetMediaFeaturesOverrideResult = EmptyResult

emulation.SetNetworkConditionsResult = EmptyResult

emulation.SetScreenSettingsOverrideResult = EmptyResult

emulation.SetScreenOrientationOverrideResult = EmptyResult

emulation.SetUserAgentOverrideResult = EmptyResult

emulation.SetViewportMetaOverrideResult = EmptyResult

emulation.SetScriptingEnabledResult = EmptyResult

emulation.SetScrollbarTypeOverrideResult = EmptyResult

emulation.SetTextLayoutModeOverrideResult = EmptyResult

emulation.SetTimezoneOverrideResult = EmptyResult

emulation.SetTouchOverrideResult = EmptyResult

NetworkResult = (
  network.AddDataCollectorResult /
  network.AddInterceptResult /
  network.ContinueRequestResult /
  network.ContinueResponseResult /
  network.ContinueWithAuthResult /
  network.DisownDataResult /
  network.FailRequestResult /
  network.GetDataResult /
  network.ProvideResponseResult /
  network.RemoveDataCollectorResult /
  network.RemoveInterceptResult /
  network.SetCacheBehaviorResult /
  network.SetExtraHeadersResult
)

NetworkEvent = (
    network.AuthRequired //
    network.BeforeRequestSent //
    network.FetchError //
    network.ResponseCompleted //
    network.ResponseStarted
)


network.AuthChallenge = {
  scheme: text,
  realm: text,
}

network.BaseParameters = (
    context: browsingContext.BrowsingContext / null,
    isBlocked: bool,
    navigation: browsingContext.Navigation / null,
    redirectCount: js-uint,
    request: network.RequestData,
    timestamp: js-uint,
    ? userContext: browser.UserContext / null,
    ? intercepts: [+network.Intercept]
)

network.BytesValue = network.StringValue / network.Base64Value;

network.StringValue = {
  type: "string",
  value: text,
}

network.Base64Value = {
  type: "base64",
  value: text,
}

network.Collector = text

network.CollectorType = "blob"

network.SameSite = "strict" / "lax" / "none" / "default"


network.Cookie = {
    name: text,
    value: network.BytesValue,
    domain: text,
    path: text,
    size: js-uint,
    httpOnly: bool,
    secure: bool,
    sameSite: network.SameSite,
    ? expiry: js-uint,
    Extensible,
}

network.DataType = "request" / "response"

network.FetchTimingInfo = {
    timeOrigin: float,
    requestTime: float,
    redirectStart: float,
    redirectEnd: float,
    fetchStart: float,
    dnsStart: float,
    dnsEnd: float,
    connectStart: float,
    connectEnd: float,
    tlsStart: float,

    requestStart: float,
    responseStart: float,

    responseEnd: float,
}

network.Header = {
  name: text,
  value: network.BytesValue,
}

network.Initiator = {
    ? columnNumber: js-uint,
    ? lineNumber: js-uint,
    ? request: network.Request,
    ? stackTrace: script.StackTrace,
    ? type: "parser" / "script" / "preflight" / "other"
}

network.Intercept = text

network.Request = text;

network.RequestData = {
    request: network.Request,
    url: text,
    method: text,
    headers: [*network.Header],
    cookies: [*network.Cookie],
    headersSize: js-uint,
    bodySize: js-uint / null,
    destination: text,
    initiatorType: text / null,
    timings: network.FetchTimingInfo,
}

network.ResponseContent = {
    size: js-uint
}

network.ResponseData = {
    url: text,
    protocol: text,
    status: js-uint,
    statusText: text,
    fromCache: bool,
    headers: [*network.Header],
    mimeType: text,
    bytesReceived: js-uint,
    headersSize: js-uint / null,
    bodySize: js-uint / null,
    content: network.ResponseContent,
    ?authChallenges: [*network.AuthChallenge],
}

network.AddDataCollectorResult = {
  collector: network.Collector
}

network.AddInterceptResult = {
  intercept: network.Intercept
}

network.ContinueRequestResult = EmptyResult

network.ContinueResponseResult = EmptyResult

network.ContinueWithAuthResult = EmptyResult

network.DisownDataResult = EmptyResult

network.FailRequestResult = EmptyResult

network.GetDataResult = {
  bytes: network.BytesValue,
}

network.ProvideResponseResult = EmptyResult

network.RemoveDataCollectorResult = EmptyResult

network.RemoveInterceptResult = EmptyResult

network.SetCacheBehaviorResult = EmptyResult

network.SetExtraHeadersResult = EmptyResult

network.AuthRequired = (
  method: "network.authRequired",
  params: network.AuthRequiredParameters
)

network.AuthRequiredParameters = {
  network.BaseParameters,
  response: network.ResponseData
}

network.BeforeRequestSent = (
  method: "network.beforeRequestSent",
  params: network.BeforeRequestSentParameters
 )

network.BeforeRequestSentParameters = {
  network.BaseParameters,
  ? initiator: network.Initiator,
}

network.FetchError = (
  method: "network.fetchError",
  params: network.FetchErrorParameters
 )

network.FetchErrorParameters = {
  network.BaseParameters,
  errorText: text,
}

network.ResponseCompleted = (
  method: "network.responseCompleted",
  params: network.ResponseCompletedParameters
 )

network.ResponseCompletedParameters = {
  network.BaseParameters,
  response: network.ResponseData,
}

network.ResponseStarted = (
  method: "network.responseStarted",
  params: network.ResponseStartedParameters
 )

network.ResponseStartedParameters = {
  network.BaseParameters,
  response: network.ResponseData,
}

ScriptResult = (
  script.AddPreloadScriptResult /
  script.CallFunctionResult /
  script.DisownResult /
  script.EvaluateResult /
  script.GetRealmsResult /
  script.RemovePreloadScriptResult
)

ScriptEvent = (
  script.Message //
  script.RealmCreated //
  script.RealmDestroyed
)

script.Channel = text;

script.ChannelValue = {
  type: "channel",
  value: script.ChannelProperties,
}

script.ChannelProperties = {
  channel: script.Channel,
  ? serializationOptions: script.SerializationOptions,
  ? ownership: script.ResultOwnership,
}

script.EvaluationResult = (
  script.EvaluationResultSuccess /
  script.EvaluationResultException
)

script.EvaluationResultSuccess = {
  type: "success",
  result: script.RemoteValue,
  realm: script.Realm
}

script.EvaluationResultException = {
  type: "exception",
  exceptionDetails: script.ExceptionDetails
  realm: script.Realm
}

script.ExceptionDetails = {
  columnNumber: js-uint,
  exception: script.RemoteValue,
  lineNumber: js-uint,
  stackTrace: script.StackTrace,
  text: text,
}

script.Handle = text;

script.InternalId = text;

script.LocalValue = (
  script.RemoteReference /
  script.PrimitiveProtocolValue /
  script.ChannelValue /
  script.ArrayLocalValue /
  { script.DateLocalValue } /
  script.MapLocalValue /
  script.ObjectLocalValue /
  { script.RegExpLocalValue } /
  script.SetLocalValue
)

script.ListLocalValue = [*script.LocalValue];

script.ArrayLocalValue = {
  type: "array",
  value: script.ListLocalValue,
}

script.DateLocalValue = (
  type: "date",
  value: text
)

script.MappingLocalValue = [*[(script.LocalValue / text), script.LocalValue]];

script.MapLocalValue = {
  type: "map",
  value: script.MappingLocalValue,
}

script.ObjectLocalValue = {
  type: "object",
  value: script.MappingLocalValue,
}

script.RegExpValue = {
  pattern: text,
  ? flags: text,
}

script.RegExpLocalValue = (
  type: "regexp",
  value: script.RegExpValue,
)

script.SetLocalValue = {
  type: "set",
  value: script.ListLocalValue,
}

script.PreloadScript = text;

script.Realm = text;

script.PrimitiveProtocolValue = (
  script.UndefinedValue /
  script.NullValue /
  script.StringValue /
  script.NumberValue /
  script.BooleanValue /
  script.BigIntValue
)

script.UndefinedValue = {
  type: "undefined",
}

script.NullValue = {
  type: "null",
}

script.StringValue = {
  type: "string",
  value: text,
}

script.SpecialNumber = "NaN" / "-0" / "Infinity" / "-Infinity";

script.NumberValue = {
  type: "number",
  value: number / script.SpecialNumber,
}

script.BooleanValue = {
  type: "boolean",
  value: bool,
}

script.BigIntValue = {
  type: "bigint",
  value: text,
}

script.RealmInfo = (
  script.WindowRealmInfo /
  script.DedicatedWorkerRealmInfo /
  script.SharedWorkerRealmInfo /
  script.ServiceWorkerRealmInfo /
  script.WorkerRealmInfo /
  script.PaintWorkletRealmInfo /
  script.AudioWorkletRealmInfo /
  script.WorkletRealmInfo
)

script.BaseRealmInfo = (
  realm: script.Realm,
  origin: text
)

script.WindowRealmInfo = {
  script.BaseRealmInfo,
  type: "window",
  context: browsingContext.BrowsingContext,
  ? userContext: browser.UserContext,
  ? sandbox: text
}

script.DedicatedWorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "dedicated-worker",
  owners: [script.Realm]
}

script.SharedWorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "shared-worker"
}

script.ServiceWorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "service-worker"
}

script.WorkerRealmInfo = {
  script.BaseRealmInfo,
  type: "worker"
}

script.PaintWorkletRealmInfo = {
  script.BaseRealmInfo,
  type: "paint-worklet"
}

script.AudioWorkletRealmInfo = {
  script.BaseRealmInfo,
  type: "audio-worklet"
}

script.WorkletRealmInfo = {
  script.BaseRealmInfo,
  type: "worklet"
}

script.RealmType = "window" / "dedicated-worker" / "shared-worker" / "service-worker" /
                   "worker" / "paint-worklet" / "audio-worklet" / "worklet"

script.RemoteReference = (
  script.SharedReference /
  script.RemoteObjectReference
)

script.SharedReference = {
   sharedId: script.SharedId

   ? handle: script.Handle,
   Extensible
}

script.RemoteObjectReference = {
   handle: script.Handle,

   ? sharedId: script.SharedId
   Extensible
}

script.RemoteValue = (
  script.PrimitiveProtocolValue /
  script.SymbolRemoteValue /
  script.ArrayRemoteValue /
  script.ObjectRemoteValue /
  script.FunctionRemoteValue /
  script.RegExpRemoteValue /
  script.DateRemoteValue /
  script.MapRemoteValue /
  script.SetRemoteValue /
  script.WeakMapRemoteValue /
  script.WeakSetRemoteValue /
  script.GeneratorRemoteValue /
  script.ErrorRemoteValue /
  script.ProxyRemoteValue /
  script.PromiseRemoteValue /
  script.TypedArrayRemoteValue /
  script.ArrayBufferRemoteValue /
  script.NodeListRemoteValue /
  script.HTMLCollectionRemoteValue /
  script.NodeRemoteValue /
  script.WindowProxyRemoteValue
)

script.ListRemoteValue = [*script.RemoteValue];

script.MappingRemoteValue = [*[(script.RemoteValue / text), script.RemoteValue]];

script.SymbolRemoteValue = {
  type: "symbol",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ArrayRemoteValue = {
  type: "array",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.ObjectRemoteValue = {
  type: "object",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.MappingRemoteValue,
}

script.FunctionRemoteValue = {
  type: "function",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.RegExpRemoteValue = {
  script.RegExpLocalValue,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.DateRemoteValue = {
  script.DateLocalValue,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.MapRemoteValue = {
  type: "map",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.MappingRemoteValue,
}

script.SetRemoteValue = {
  type: "set",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue
}

script.WeakMapRemoteValue = {
  type: "weakmap",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.WeakSetRemoteValue = {
  type: "weakset",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.GeneratorRemoteValue = {
  type: "generator",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ErrorRemoteValue = {
  type: "error",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ProxyRemoteValue = {
  type: "proxy",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.PromiseRemoteValue = {
  type: "promise",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.TypedArrayRemoteValue = {
  type: "typedarray",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.ArrayBufferRemoteValue = {
  type: "arraybuffer",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
}

script.NodeListRemoteValue = {
  type: "nodelist",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.HTMLCollectionRemoteValue = {
  type: "htmlcollection",
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.ListRemoteValue,
}

script.NodeRemoteValue = {
  type: "node",
  ? sharedId: script.SharedId,
  ? handle: script.Handle,
  ? internalId: script.InternalId,
  ? value: script.NodeProperties,
}

script.NodeProperties = {
  nodeType: js-uint,
  childNodeCount: js-uint,
  ? attributes: {*text => text},
  ? children: [*script.NodeRemoteValue],
  ? localName: text,
  ? mode: "open" / "closed",
  ? namespaceURI: text,
  ? nodeValue: text,
  ? shadowRoot: script.NodeRemoteValue / null,
}

script.WindowProxyRemoteValue = {
  type: "window",
  value: script.WindowProxyProperties,
  ? handle: script.Handle,
  ? internalId: script.InternalId
}

script.WindowProxyProperties = {
  context: browsingContext.BrowsingContext
}

script.ResultOwnership = "root" / "none"

script.SerializationOptions = {
  ? maxDomDepth: (js-uint / null) .default 0,
  ? maxObjectDepth: (js-uint / null) .default null,
  ? includeShadowTree: ("none" / "open" / "all") .default "none",
}

script.SharedId = text;

script.StackFrame = {
  columnNumber: js-uint,
  functionName: text,
  lineNumber: js-uint,
  url: text,
}

script.StackTrace = {
  callFrames: [*script.StackFrame],
}

script.Source = {
  realm: script.Realm,
  ? context: browsingContext.BrowsingContext,
  ? userContext: browser.UserContext
}

script.AddPreloadScriptResult = {
  script: script.PreloadScript
}

script.DisownResult = EmptyResult

script.CallFunctionResult = script.EvaluationResult

script.EvaluateResult = script.EvaluationResult

script.GetRealmsResult = {
  realms: [*script.RealmInfo]
}

script.RemovePreloadScriptResult = EmptyResult

script.Message = (
  method: "script.message",
  params: script.MessageParameters
 )

script.MessageParameters = {
  channel: script.Channel,
  data: script.RemoteValue,
  source: script.Source,
}

script.RealmCreated = (
 method: "script.realmCreated",
 params: script.RealmInfo
)

script.RealmDestroyed = (
  method: "script.realmDestroyed",
  params: script.RealmDestroyedParameters
)

script.RealmDestroyedParameters = {
  realm: script.Realm
}


StorageResult = (
  storage.DeleteCookiesResult /
  storage.GetCookiesResult /
  storage.SetCookieResult
)

storage.PartitionKey = {
  ? userContext: text,
  ? sourceOrigin: text,
  Extensible,
}

storage.GetCookiesResult = {
  cookies: [*network.Cookie],
  partitionKey: storage.PartitionKey,
}

storage.SetCookieResult = {
  partitionKey: storage.PartitionKey
}

storage.DeleteCookiesResult = {
  partitionKey: storage.PartitionKey
}

LogEvent = (
  log.EntryAdded
)

log.Level = "debug" / "info" / "warn" / "error"

log.Entry = (
  log.GenericLogEntry /
  log.ConsoleLogEntry /
  log.JavascriptLogEntry
)

log.BaseLogEntry = (
  level: log.Level,
  source: script.Source,
  text: text / null,
  timestamp: js-uint,
  ? stackTrace: script.StackTrace,
)

log.GenericLogEntry = {
  log.BaseLogEntry,
  type: text,
}

log.ConsoleLogEntry = {
  log.BaseLogEntry,
  type: "console",
  method: text,
  args: [*script.RemoteValue],
}

log.JavascriptLogEntry = {
  log.BaseLogEntry,
  type: "javascript",
}

log.EntryAdded = (
 method: "log.entryAdded",
 params: log.Entry,
)

InputResult = (
  input.PerformActionsResult /
  input.ReleaseActionsResult /
  input.SetFilesResult
)

InputEvent = (
  input.FileDialogOpened
)

input.PerformActionsResult = EmptyResult

input.ReleaseActionsResult = EmptyResult

input.SetFilesResult = EmptyResult

input.FileDialogOpened = (
   method: "input.fileDialogOpened",
   params: input.FileDialogInfo
)

input.FileDialogInfo = {
   context: browsingContext.BrowsingContext,
   ? userContext: browser.UserContext,
   ? element: script.SharedReference,
   multiple: bool,
}

WebExtensionResult = (
  webExtension.InstallResult /
  webExtension.UninstallResult
)

webExtension.Extension = text

webExtension.InstallResult = {
  extension: webExtension.Extension
}

webExtension.UninstallResult = EmptyResult

이슈 색인

분명 이 "이벤트 대기"를 수행하는 더 나은 메커니즘이 있을 것이다. ↵
이것이 이벤트 루프의 다른 모든 태스크보다 먼저 실행되도록 보장하기 위해 마이크로태스크와 같은 것이 있어야 하는가? ↵
이것은 부록이어야 하는가? ↵
단일 세션에 대해 1개를 초과하는 연결을 지원하는가? ↵
UTF-8 오류에 어떤 상태 코드 가 사용되는지 정의된 곳이 없는 것 같다. ↵
UA가 원할 경우 리스너를 닫을 수 있도록 세션 종료에 연결해야 한다. ↵
샌드박스 Realm의 생성을 정의한다. 이는 window을 래핑하는 SandboxWindowProxy를 반환하게 된다. ↵
SandboxProxy가 작동하는 방식을 자세히 정의한다. ↵
이것이 작동하는 방식을 정의한다. ↵
이것이 사용자 컨텍스트의 개념 또는 스토리지와의 상호 작용을 형식적으로 정의하는 최선의 방법인지는 불분명하다. ↵
null이 아닌 opener를 가진 최상위 순회 가능 객체가 opener와 동일한 연결된 사용자 컨텍스트를 갖도록 지정해야 하는가? 이것이 기존 구현에서 강제되는 사항인지 확인해야 한다. ↵
이것은 다소 부정확한 표현이지만, 의도는 연결의 종료를 시작하기 전에 명령에 대한 응답을 보낸다는 것이 명확하기를 바란다. ↵
이것은 Realm에서도 작동하도록 일반화해야 한다. ↵
이것은 Realm에서도 작동하도록 일반화해야 한다. ↵
ignore cache 플래그가 작동하는 방식을 올바르게 지정한다. 이때 리소스의 첫 번째 로드만 캐시를 우회하는지 (즉, 이것이 처음에 캐시를 지운 다음 정상적으로 진행하는 것과 같은지), 아니면 HTML 파서가 직접 로드하지 않은 리소스도 (예: 스크립트나 스타일시트가 시작한 로드) 캐시를 우회하는지를 고려해야 한다. ↵
여기서 오류가 발생했을 때 무엇이 실패했고 왜 실패했는지에 대한 정보를 충분히 노출하고 있는가? 어떤 오류 코드를 원하는가? 로컬 엔드가 실제로 무엇이 잘못되었는지 파악하기 위해 구현 정의 문자열을 파싱하는 문제가 생길 것인가? ↵
이것은 업데이트 렌더링 알고리즘에 좀 더 명시적인 방식으로 통합되어야 한다. [w3c/webdriver-bidi 이슈 #1131] ↵
마지막 최상위 순회 가능 객체를 닫을 때의 동작에 대해 공개 논의가 진행 중이다. 브라우저를 닫거나, 세션을 닫거나, 이를 구현에 맡길 수 있다. [w3c/webdriver-bidi 이슈 #170] ↵
이것은 업데이트 렌더링 알고리즘에 좀 더 명시적인 방식으로 통합되어야 한다. [w3c/webdriver-bidi 이슈 #1131] ↵
작성된 알고리즘에는 경쟁 조건이 있는데, 대상 세션 기록 엔트리로 이동하려고 할 때 해당 엔트리가 더 이상 존재하지 않을 수 있기 때문이다. 기록 내비게이션을 기다리는 기능을 지원하게 되면 이를 더 견고하게 처리할 수 있다. ↵
`browsingContext.pageShow` 이벤트를 노출하려는가? 그렇다면 bfcache 복원 시에만이 아니라 `pageshow`가 발생할 때마다 이것을 호출해야 하며, 데이터에 persisted 상태도 추가해야 한다. ↵
이 이벤트를 활성 문서가 있는 브라우징 컨텍스트에 대해서만 발생시켜야 하는지는 불분명하다. 내비게이션은 컨텍스트가 접근 불가능해지게 할 수도 있지만, bfcache 때문에 아직 폐기되지 않을 수 있다. ↵
이 알고리즘을 화면 방향 명세로 이동한다. ↵
이는 순회 가능 객체와 관련되지 않은 데이터가 수집되는 것을 방지한다. 수집기 구성을 기준으로 확인하려면 여전히 순회 가능 객체를 가져와야 하지만 여기서 null을 허용할 수도 있다. ↵
이것에는 인증을 취소하는 방법이 없다. ↵
Realm 이외의 매개변수도 포함해야 하는가? ↵
Fetch에서와 마찬가지로 여러 헤더, 파싱 문제 등을 처리하는 올바른 방법인지 불분명하다. ↵
컨텍스트에 더해 요청을 시작한 문서 노드의 `sharedId`를 포함하는 것을 고려한다. ↵
"request already sent" 오류를 고려한다. ↵
정확한 오류 종류를 설정할 수 있도록 한다. [이슈 #508] ↵
Fetch의 "HTTP-network-or-cache fetch" 알고리즘에서 반환 값을 준수한다. ↵
이것에는 잘못된 오류 코드가 있다. ↵
이것은 단독 서로게이트를 처리하지 않는다. ↵
"stale object reference" 경우를 처리한다. ↵
WASM 유형을 추가해야 하는가? ↵
WindowProxy도 Node와 유사한 방식으로 속성을 가져야 하는가? ↵
String / Number / 등의 래퍼 객체를 특별히 처리해야 하는가? ↵
미러 객체의 수명 주기를 재고한다. ↵
children와 자식 노드는 서로 다른 것이다. childNodeCount는 childNodes를 참조해야 하거나, childrenCount로 이름이 변경되어야 한다. ↵
이것에는 잘못된 오류 코드가 있다. ↵
이것에는 잘못된 오류 코드가 있다. ↵
TODO: script.evaluate에 설명된 대로 timeout 인수를 추가한다. ↵
중첩 워커 등에 대해 Realm 부모도 허용하도록 이것을 확장해야 하는가? 또는 모든 상위 워커를 가져와야 하는가? ↵
단순한 리터럴 일치보다 더 정교한 필터 시스템이 필요할 수 있다. ↵
여기의 순서를 더 명확하게 정의해야 하는가? ↵
이것을 브라우징 컨텍스트 또는 최상위 순회 가능 객체를 키로 해야 하는가? 차이는 프레임에서 이벤트가 발생하고 그 프레임이 로컬 엔드가 최상위 순회 가능 객체의 로그 이벤트를 구독하기 전에 내비게이션되는 경우에 나타난다. ↵
훨씬 더 많은 항목에 로깅이 필요하다. CDP에는 LogEntryAdded 유형으로 xml, javascript, network, storage, appcache, rendering, security, deprecation, worker, violation, intervention, recommendation, other가 있다. 이는 서로 다른 메서드로 표현되는 js 예외와 콘솔 API 유형에 추가되는 것이다. ↵
구현 정의 로그 유형을 허용한다. ↵
https://github.com/w3c/csswg-drafts/pull/13549가 병합된 후 제거한다. ↵
https://github.com/w3c/csswg-drafts/pull/13548가 병합된 후 제거한다. ↵