Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 명세는 웹 콘텐츠가 프레젠테이션 디스플레이에 접근하고 이를 웹 콘텐츠를 표시하는 데 사용할 수 있도록 하는 API를 정의합니다.
이 절에서는 이 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 https://www.w3.org/TR/에 있는 W3C 기술 보고서 색인에서 확인할 수 있습니다.
이 문서는 Second Screen 워킹 그룹이 권고안 트랙을 사용하여 후보 권고안 초안으로 발행했습니다.
2017년 6월
1일 후보 권고안으로 발행된 이후, 워킹 그룹은 지원되지 않는
스킴을 사용하는 URL을 무시하도록 PresentationRequest를 구성하는 단계를
업데이트하고, 수신 브라우징 컨텍스트가
자체적으로 탐색할 수 있는 방식에 추가 제한을 두었으며, HTML
명세에 정의된 것을 사용하기 위해 BinaryType 열거형의 정의를
삭제했습니다. 이 문서에 정의된 다른 인터페이스는 WebIDL 업데이트에
맞게 조정된 것을 제외하면 변경되지 않았습니다. 여러 명확화와
편집상의 업데이트도 이루어졌습니다. 자세한 내용은 변경 사항 목록을
참조하십시오.
위험 요소로 식별된 기능은 없습니다.
Second Screen 워킹 그룹은 후보 권고안 기간 동안 Presentation API의 테스트 스위트를 개선하고 예비 구현 보고서를 업데이트할 예정입니다. 이 명세가 제안 권고안으로 진행되려면 후보 권고안 종료 기준 절에 자세히 설명된 대로 각 기능에 대해 독립적이고 상호 운용 가능한 구현 두 개가 입증되어야 합니다.
후보 권고안으로 발행되었다고 해서 W3C와 그 회원이 이를 승인한다는 의미는 아닙니다. 후보 권고안 초안에는 워킹 그룹이 이후 후보 권고안 스냅샷에 포함하려는 이전 후보 권고안의 변경 사항이 통합되어 있습니다.
이 문서는 초안이며 언제든지 다른 문서에 의해 업데이트되거나 대체되거나 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않습니다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성했습니다. W3C는 해당 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허를 공개하는 방법에 대한 지침도 포함되어 있습니다. 자신이 알고 있는 특허에 필수 청구항이 포함되어 있다고 판단하는 개인은 W3C 특허 정책의 제6절에 따라 해당 정보를 공개해야 합니다.
이 문서에는 2023년 11월 3일 W3C 프로세스 문서가 적용됩니다.
이 절은 비규범적입니다.
Presentation API는 프로젝터, 연결된 모니터, 네트워크에 연결된 TV와 같은 프레젠테이션 디스플레이를 웹에서 사용할 수 있도록 하는 것을 목표로 합니다. 유선 (HDMI, DVI 또는 이와 유사한 기술) 및 무선 기술(Miracast, Chromecast, DLNA, AirPlay 또는 이와 유사한 기술)을 사용하여 연결된 디스플레이를 고려합니다.
화면 크기가 제한된 장치는 웹 콘텐츠를 더 많은 사람에게 보여 줄 수 있는 기능이 부족합니다. 예를 들어 회의실의 동료 그룹이나 집의 친구와 가족이 이에 해당합니다. 더 큰 프레젠테이션 디스플레이에 표시되는 웹 콘텐츠는 지각되는 품질, 가독성, 그리고 영향력이 더 높습니다.
핵심적으로 Presentation API는 컨트롤러 페이지가 프레젠테이션 페이지를 프레젠테이션 디스플레이에 표시하고 해당 페이지와 메시지를 교환할 수 있게 합니다. 프레젠테이션 페이지를 디스플레이로 전송하는 방법과 해당 페이지와 컨트롤러 페이지 사이에서 메시지를 교환하는 방법은 구현에 맡깁니다. 이를 통해 매우 다양한 디스플레이 기술을 사용할 수 있습니다.
예를 들어 프레젠테이션 디스플레이가 오디오와 비디오 전송만 허용하는 HDMI 또는 Miracast로 연결된 경우, 컨트롤러를 호스팅하는 사용자 에이전트(UA)도 프레젠테이션을 렌더링합니다. 그런 다음 운영 체제를 사용하여 그 결과 생성된 그래픽 및 오디오 출력을 프레젠테이션 디스플레이로 전송합니다. 이 상황을 Presentation API의 1-UA 모드 구현이라고 합니다. 유일한 요구 사항은 사용자 에이전트가 프레젠테이션을 렌더링한 그래픽과 오디오를 프레젠테이션 디스플레이로 전송하고, 컨트롤러 페이지와 프레젠테이션 페이지 사이에서 내부적으로 메시지를 교환할 수 있어야 한다는 것입니다.
프레젠테이션 디스플레이가 HTML을 기본적으로 렌더링하고 네트워크를 통해 컨트롤러와 통신할 수 있는 경우, 컨트롤러를 호스팅하는 사용자 에이전트는 프레젠테이션을 렌더링할 필요가 없습니다. 대신 사용자 에이전트는 프레젠테이션 디스플레이에 프레젠테이션 페이지 자체를 로드하고 렌더링하도록 요청하는 프록시 역할을 합니다. 메시지 교환은 사용자 에이전트와 프레젠테이션 디스플레이 간의 네트워크 연결을 통해 이루어집니다. 이 상황을 Presentation API의 2-UA 모드 구현이라고 합니다.
Presentation API는 1-UA 모드, 2-UA 모드 및 위에 나열되지 않은 다른 가능한 수단으로 프레젠테이션 디스플레이에 연결하는 사용자 에이전트와 함께 사용하기 위한 것입니다. 사용자 에이전트와 프레젠테이션 디스플레이 간의 상호 운용성을 개선하기 위해 브라우저와 디스플레이 사이의 네트워크 통신 표준화가 Second Screen Community Group에서 검토되고 있습니다.
이 절은 비규범적입니다.
사용 사례 및 요구 사항은 별도의 Presentation API 사용 사례 및 요구 사항 문서에 정리되어 있습니다.
비규범적이라고 표시된 절뿐만 아니라 이 명세의 모든 작성 지침, 다이어그램, 예제 및 참고 사항도 비규범적입니다. 이 명세의 그 밖의 모든 내용은 규범적입니다.
이 문서의 핵심 단어 MAY, MUST, MUST NOT, OPTIONAL, SHOULD, 및 SHOULD NOT은 여기에서처럼 모두 대문자로 나타나는 경우에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석해야 합니다.
알고리즘의 일부로 명령형으로 표현된 요구 사항(예: "앞쪽의 모든 공백 문자를 제거한다" 또는 "false를 반환하고 이 단계를 종료한다")은 해당 알고리즘을 소개할 때 사용된 핵심 단어 ("MUST", "SHOULD", "MAY" 등)의 의미로 해석해야 합니다.
알고리즘이나 특정 단계로 표현된 적합성 요구 사항은 결과가 동등한 한 어떤 방식으로든 구현할 수 있습니다. (특히 이 명세에 정의된 알고리즘은 이해하기 쉽도록 작성된 것이며, 성능을 목적으로 한 것이 아닙니다.)
이 명세는 두 클래스의 사용자 에이전트에 대한 적합성 기준을 설명합니다.
제어 사용자 에이전트의 명세를 준수하는
웹 브라우저는 이 명세에 설명된 대로 제어 브라우징
컨텍스트를 제공하여 프레젠테이션을 시작하고
제어할 수 있어야 합니다. 이 컨텍스트는
Presentation,
PresentationAvailability,
PresentationConnection,
PresentationConnectionAvailableEvent,
PresentationConnectionCloseEvent,
그리고
PresentationRequest 인터페이스를 구현합니다.
수신
사용자 에이전트의 명세를 준수하는 웹 브라우저는 이
명세에 설명된 대로 수신 브라우징 컨텍스트를 제공하여
프레젠테이션을 렌더링할 수 있어야 합니다. 이 컨텍스트는
Presentation,
PresentationConnection,
PresentationConnectionAvailableEvent,
PresentationConnectionCloseEvent,
PresentationConnectionList,
그리고
PresentationReceiver 인터페이스를 구현합니다.
하나의 사용자 에이전트가 제어 사용자 에이전트와 수신 사용자 에이전트 역할을 모두 할 수 있습니다. 두 브라우징 컨텍스트를 모두 제공하고 필요한 모든 인터페이스를 구현하는 경우에 해당합니다. 이는 같은 사용자 에이전트가 API의 1-UA 모드 구현에서처럼 하나의 프레젠테이션에 대해 제어 브라우징 컨텍스트와 수신 브라우징 컨텍스트를 모두 호스팅할 수 있을 때 발생할 수 있습니다.
사용자 에이전트에 대해 표현된 적합성 요구 사항은 문맥에 따라 제어 사용자 에이전트, 수신 사용자 에이전트 또는 두 클래스 모두에 적용됩니다.
JavaScript
realm 및 current
realm이라는 용어는 [ECMASCRIPT]에 정의된 대로 사용됩니다.
Promise 객체의 문맥에서
resolved 및 rejected라는 용어는
[ECMASCRIPT]에 정의된 대로 사용됩니다.
Accept-Language 및 HTTP 인증이라는 용어는 [RFC9110]에 정의된 대로 사용됩니다.
쿠키 저장소라는 용어는 [RFC6265]에 정의된 대로 사용됩니다.
UUID라는 용어는 [RFC4122]에 정의된 대로 사용됩니다.
DIAL이라는 용어는 [DIAL]에 정의된 대로 사용됩니다.
문서를 다시
로드한다는 용어는 [HTML]에서
reload() 메서드가 호출될 때
실행되는 단계를 의미합니다.
로컬 저장소 영역이라는 용어는
[HTML]의
localStorage
속성이 노출하는 저장소 영역을 의미하며,
세션 저장소 영역이라는 용어는
sessionStorage
속성이 노출하는 저장소 영역을 의미합니다.
이 명세는 다른 명세에서 내보낸 용어를 참조합니다. B.2 참조로 정의된 용어를 참조하십시오. 또한 다른 명세의 다음 내부 개념을 참조합니다.
이 절은 비규범적입니다.
이 절에서는 Presentation API의 주요 기능 사용법을 보여 주는
예제 코드를 제공합니다. 이 예제에서
controller.html은 컨트롤러를 구현하고
presentation.html은 프레젠테이션을 구현합니다. 두 페이지 모두
https://example.org 도메인에서 제공됩니다.
(https://example.org/controller.html 및
https://example.org/presentation.html). 이 예제에서는
제어 페이지가 한 번에 하나의 프레젠테이션을 관리한다고
가정합니다. 자세한 내용은 코드 예제의 주석을
참조하십시오.
이 코드는 https://example.com/presentation.html 또는
https://example.net/alternate.html을 표시할 수 있는
호환 가능한 프레젠테이션 디스플레이가 하나 이상 있을 때
표시되는 버튼을 렌더링합니다.
디스플레이 가용성 모니터링은 먼저 표시하려는 URL로
PresentationRequest를 생성한 다음,
getAvailability를 호출하여
프레젠테이션 가용성 상태가 변경될 때
change
이벤트가 발생하는 PresentationAvailability 객체를
얻는 방식으로 수행됩니다.
<!-- controller.html -->
<button id="presentBtn" style="display: none;">표시</button>
<script>
// 사용 가능한 프레젠테이션 디스플레이가 하나 이상 있으면 표시 버튼이 보입니다
var presentBtn = document.getElementById("presentBtn");
// 상대 프레젠테이션 URL(예: "presentation.html")을 사용할 수도 있습니다
var presUrls = ["https://example.com/presentation.html",
"https://example.net/alternate.html"];
// 디스플레이 가용성에 따라 표시 버튼을 표시하거나 숨깁니다
var handleAvailabilityChange = function(available) {
presentBtn.style.display = available ? "inline" : "none";
};
// 프레젠테이션 디스플레이의 가용성을 알게 되는 즉시 Promise가 이행됩니다
// .
var request = new PresentationRequest(presUrls);
request.getAvailability().then(function(availability) {
// 가용성 객체가 살아 있는 동안 제어 UA가 availability.value를 최신 상태로
// 유지할 수 있습니다. 웹 개발자는 이 객체가 더 이상 필요하지 않게 되는 즉시
// 폐기하는 것이 좋습니다.
handleAvailabilityChange(availability.value);
availability.onchange = function() { handleAvailabilityChange(this.value); };
}).catch(function() {
// 플랫폼에서 가용성 모니터링을 지원하지 않으므로
// 프레젠테이션 디스플레이 검색은 request.start()가 호출된 후에만 수행됩니다.
// 단순화를 위해 장치를 사용할 수 있다고 가정합니다. 또는 버튼에
// 세 번째 상태를 구현할 수도 있습니다.
handleAvailabilityChange(true);
});
</script>
사용자가 presentBtn을 클릭하면 이 코드는
PresentationRequest의 URL 중 하나를
표시하도록 요청합니다.
start가 호출되면
브라우저는 일반적으로 사용자가 사용 가능한 호환 디스플레이 중 하나를
선택할 수 있는 대화 상자를 표시합니다.
선택한 디스플레이와 호환되는
PresentationRequest의 첫 번째 URL이
해당 디스플레이에 표시됩니다.
start 메서드는
프레젠테이션 상태를 추적하고 디스플레이에 로드된 후
프레젠테이션 페이지와 메시지를 교환하는 데 사용되는
PresentationConnection 객체로
이행됩니다.
<!-- controller.html -->
<script>
presentBtn.onclick = function () {
// 새 프레젠테이션을 시작합니다.
request.start()
// 성공하면 프레젠테이션 연결이 setConnection에
// 전달됩니다.
.then(setConnection);
// 그렇지 않으면 사용자가 선택 대화 상자를 취소했거나 화면을
// 찾지 못한 것입니다.
};
</script>
프레젠테이션을 시작한 원래 페이지가
PresentationConnection을 닫거나,
탐색하거나, 페이지 자체가 닫힌 후에도 프레젠테이션은 계속 실행됩니다.
다른 페이지는 PresentationConnection의
id를 사용하여
기존 프레젠테이션에 다시 연결하고 제어를 재개할 수 있습니다.
이는 프레젠테이션을 시작한 동일한 브라우저에서만 작동한다고
보장됩니다.
<!-- controller.html -->
<button id="reconnectBtn" style="display: none;">다시 연결</button>
<script>
var reconnect = function () {
// 존재하는 경우 localStorage에서 presId를 읽습니다
var presId = localStorage["presId"];
// 프레젠테이션에 다시 연결할 때 presId는 필수입니다.
if (!!presId) {
request.reconnect(presId)
// 성공하면 프레젠테이션에 대한 새 연결이
// setConnection에 전달됩니다.
.then(setConnection);
// presUrl과 presId에 해당하는 연결을 찾지 못했거나 오류가 발생했습니다.
}
};
// 컨트롤러가 탐색되면 자동으로 다시 연결합니다.
document.addEventListener("DOMContentLoaded", reconnect);
// 또는 수동으로 다시 연결할 수 있게 합니다.
const reconnectBtn = document.querySelector("#reconnectBtn");
reconnectBtn.onclick = reconnect;
</script>
일부 브라우저는 사용자가 제어 페이지와 직접
상호 작용하지 않고도 프레젠테이션을 시작할 수 있는 방법을 제공합니다. 제어 페이지는
navigator.presentation의 defaultRequest
속성을 설정하고, 이러한 방식으로 프레젠테이션이 시작될 때 발생하는
connectionavailable 이벤트를
수신하여 이 동작을 선택할 수 있습니다. 이벤트와 함께 전달되는
PresentationConnection은
페이지가 start를 호출한 경우와 동일하게 동작합니다.
<!-- controller.html -->
<!-- presentation.defaultRequest를 설정하면 제어 UA가
프레젠테이션을 시작할 때 사용할 PresentationRequest를 페이지가
지정할 수 있습니다. -->
<script>
navigator.presentation.defaultRequest = new PresentationRequest(presUrls);
navigator.presentation.defaultRequest.onconnectionavailable = function(evt) {
setConnection(evt.connection);
};
</script>
프레젠테이션이 시작되면 반환된
PresentationConnection을 사용하여
상태를 모니터링하고 메시지를 교환합니다. 일반적으로 사용자에게
제어 페이지에서 프레젠테이션의 연결을 끊거나 종료할 수 있는
선택권이 제공됩니다.
제어 페이지는 수명 동안 여러 프레젠테이션에 연결하거나 연결을 끊을 수 있으므로
현재 PresentationConnection과 그 상태를
추적하는 것이 유용합니다.
메시지는 connected 상태인
연결에서만 송수신할 수 있습니다.
<!-- controller.html -->
<button id="disconnectBtn" style="display: none;">연결 끊기</button>
<button id="stopBtn" style="display: none;">중지</button>
<script>
let connection;
// 연결된 프레젠테이션이 있으면 연결 끊기 및 중지 버튼이 보입니다
const stopBtn = document.querySelector("#stopBtn");
const disconnectBtn = document.querySelector("#disconnectBtn");
stopBtn.onclick = _ => {
connection && connection.terminate();
};
disconnectBtn.onclick = _ => {
connection && connection.close();
};
function setConnection(newConnection) {
// 다시 연결하려는 경우가 아니라면 기존 프레젠테이션과의 연결을 끊습니다
if (connection && connection != newConnection && connection.state != 'closed') {
connection.onclose = undefined;
connection.close();
}
// 새 연결을 설정하고 프레젠테이션 ID를 저장합니다
connection = newConnection;
localStorage["presId"] = connection.id;
function showConnectedUI() {
// 사용자가 프레젠테이션의 연결을 끊거나 종료할 수 있게 합니다
stopBtn.style.display = "inline";
disconnectBtn.style.display = "inline";
reconnectBtn.style.display = "none";
}
function showDisconnectedUI() {
disconnectBtn.style.display = "none";
stopBtn.style.display = "none";
reconnectBtn.style.display = localStorage["presId"] ? "inline" : "none";
}
// 연결 상태를 모니터링합니다
connection.onconnect = _ => {
showConnectedUI();
// 메시지 핸들러를 등록합니다
connection.onmessage = message => {
console.log(`수신한 메시지: ${message.data}`);
};
// 프레젠테이션 페이지에 초기 메시지를 보냅니다
connection.send("안녕하세요");
};
connection.onclose = _ => {
connection = null;
showDisconnectedUI();
};
connection.onterminate = _ => {
// 존재하는 경우 localStorage에서 presId를 제거합니다
delete localStorage["presId"];
connection = null;
showDisconnectedUI();
};
};
</script>
이 코드는 표시되는 페이지
(https://example.org/presentation.html)에서 실행됩니다. 프레젠테이션은
여러 제어 페이지에서 연결될 수 있으므로 표시되는 페이지가
connectionList
객체에서 들어오는 연결을 수신 대기하는 것이 중요합니다.
<!-- presentation.html -->
<script>
var addConnection = function(connection) {
connection.onmessage = function (message) {
if (message.data == "안녕하세요")
connection.send("안녕하세요");
};
};
navigator.presentation.receiver.connectionList.then(function (list) {
list.connections.map(function (connection) {
addConnection(connection);
});
list.onconnectionavailable = function (evt) {
addConnection(evt.connection);
};
});
</script>
<!-- controller.html -->
<script>
connection.send('{"string": "你好,世界!", "lang": "zh-CN"}');
connection.send('{"string": "こんにちは、世界!", "lang": "ja"}');
connection.send('{"string": "안녕하세요, 세계!", "lang": "ko"}');
connection.send('{"string": "Hello, world!", "lang": "en-US"}');
</script>
<!-- presentation.html -->
<script>
connection.onmessage = function (message) {
var messageObj = JSON.parse(message.data);
var spanElt = document.createElement("SPAN");
spanElt.lang = messageObj.lang;
spanElt.textContent = messageObj.string;
document.body.appendChild(spanElt);
};
</script>
하나의 제어 페이지가 서로 다른 두 프레젠테이션 디스플레이에서 독립적인 프레젠테이션 두 개를 시작하고 제어할 수 있습니다. 이 코드는 위 예제의 첫 번째 프레젠테이션에 두 번째 프레젠테이션을 추가하는 방법을 보여 줍니다.
<!-- controller.html -->
<!-- 동일한 제어 페이지는 start()를 여러 번 호출하여
여러 프레젠테이션을 생성하고 관리할 수 있습니다. -->
<button id="secondPresentBtn" style="display: none;">다시 표시</button>
<script>
var secondPresentBtn = document.getElementById("secondPresentBtn");
var secondPresUrl = "https://example.com/second-presentation.html";
var secondRequest = new PresentationRequest(secondPresUrl);
// 단순화를 위해 secondRequest의 화면 가용성을 처리하는 로직과
// secondPresentBtn의 상태를 업데이트하는 로직은 생략합니다.
secondPresentBtn.onclick = function () {
// 원래 화면과 다른 화면일 가능성이 높은 곳에서 새 프레젠테이션을 시작합니다
// .
secondRequest.start().then(setSecondConnection);
};
function setSecondConnection(newConnection) {
// second-presentation.html과 주고받는 메시지를 처리하는 로직입니다.
};
</script>
프레젠테이션 디스플레이란 구현별 연결 기술을 통해 사용자 에이전트가 사용할 수 있는 그래픽 및/또는 오디오 출력 장치를 의미합니다.
프레젠테이션 연결은 제어 브라우징 컨텍스트를 해당 수신 브라우징 컨텍스트와 연결하고 둘 사이에서 양방향 메시징을 가능하게 하는 객체입니다. 각 프레젠테이션 연결에는 프레젠테이션 연결 상태, 다른 프레젠테이션과 구별하기 위한 고유한 프레젠테이션 식별자, 그리고 프레젠테이션을 생성하거나 다시 연결하는 데 사용하는 URL인 프레젠테이션 URL이 있습니다. 유효한 프레젠테이션 식별자는 영숫자 ASCII 문자로만 구성되며 길이가 최소 16자입니다.
일부 프레젠테이션 디스플레이는 기능, 보안 또는 하드웨어 제한으로 인해 웹 콘텐츠의 일부만 표시할 수 있습니다. 예를 들어 셋톱박스, 스마트 TV 또는 오디오만 렌더링할 수 있는 네트워크 스피커가 있습니다. 제어 사용자 에이전트가 해당 디스플레이에서 URL의 프레젠테이션이 성공할 것이라고 합리적으로 보장할 수 있는 경우, 이러한 디스플레이를 프레젠테이션 URL에 대한 사용 가능한 프레젠테이션 디스플레이라고 합니다.
제어 브라우징 컨텍스트(줄여서 컨트롤러)는
브라우징 컨텍스트로서,
start 또는 reconnect를 호출하여
프레젠테이션에
연결했거나,
connectionavailable 이벤트를 통해 프레젠테이션
연결을 받은 컨텍스트입니다. PresentationRequest 알고리즘에서 제어 브라우징
컨텍스트는 PresentationRequest를
구성하는 데 사용된 JavaScript
realm을 가진 브라우징 컨텍스트입니다.
수신 브라우징 컨텍스트(줄여서 프레젠테이션)는 프레젠테이션 디스플레이에 렌더링하는 브라우징 컨텍스트입니다. 수신 브라우징 컨텍스트는 제어 브라우징 컨텍스트와 동일한 사용자 에이전트에 있거나 다른 사용자 에이전트에 있을 수 있습니다. 수신 브라우징 컨텍스트는 수신 브라우징 컨텍스트를 생성하는 단계에 따라 생성됩니다.
절차에서 대상 브라우징 컨텍스트는 절차가 제어 브라우징 컨텍스트에서 시작된 경우 수신 브라우징 컨텍스트이고, 수신 브라우징 컨텍스트에서 시작된 경우 제어 브라우징 컨텍스트입니다.
처음에는 비어 있는 제어되는 프레젠테이션 집합에는
제어 사용자
에이전트(또는 해당 사용자 에이전트 내의 특정 사용자 프로필)를 위해
제어 브라우징 컨텍스트가 생성한
프레젠테이션 연결이 포함됩니다.
제어되는 프레젠테이션 집합은
기반 프레젠테이션 연결을 나타내는
PresentationConnection 객체의 목록으로
표현됩니다. 이 집합에서는 여러
PresentationConnection 객체가 동일한
프레젠테이션 URL과 프레젠테이션
식별자를 공유할 수 있지만,
주어진 제어 브라우징 컨텍스트에는
특정 프레젠테이션 URL과 프레젠테이션
식별자를 가진 PresentationConnection 객체가 하나만
있을 수 있습니다.
처음에는 비어 있는 프레젠테이션 컨트롤러 집합에는
수신 사용자
에이전트를 위해 수신 브라우징 컨텍스트가 생성한
프레젠테이션 연결이 포함됩니다.
프레젠테이션
컨트롤러 집합은 기반
프레젠테이션 연결을 나타내는 PresentationConnection 객체의 목록으로
표현됩니다. 이 집합의 모든 프레젠테이션
연결은 동일한 프레젠테이션 URL과
프레젠테이션 식별자를 공유합니다.
수신 브라우징 컨텍스트에서 처음에는 null로 설정되는 프레젠테이션
컨트롤러 모니터는 현재 프레젠테이션
컨트롤러 집합을 수신 애플리케이션에
노출합니다. 프레젠테이션 컨트롤러
모니터는
PresentationConnectionList로 표현됩니다.
수신 브라우징 컨텍스트에서 처음에는
null로 설정되는 프레젠테이션
컨트롤러 프로미스는 초기 프레젠테이션 연결이
설정되면 프레젠테이션 컨트롤러
모니터를 제공합니다.
프레젠테이션 컨트롤러
프로미스는
프레젠테이션
컨트롤러 모니터로 이행되는 Promise로 표현됩니다.
제어 브라우징 컨텍스트에서 처음에는
null로 설정되는 기본
프레젠테이션 요청은 사용자가 브라우저 크롬에서
프레젠테이션 연결을 시작하려 할 때 사용할 요청을 나타냅니다.
이 명세에서 언급하는 작업의 작업 소스는 프레젠테이션 작업 소스입니다.
알고리즘이 Presentation API 작업을 큐에 넣을 때 T, 사용자 에이전트는 현재 realm의 전역 객체를 사용하여 프레젠테이션 작업 소스에 T를 전역 작업으로 큐에 넣어야 합니다.
달리 명시되지 않는 한, 알고리즘 단계에서 생성되는 스크립트 객체의 JavaScript realm은 현재 realm입니다.
WebIDL
[SecureContext, Exposed=Window]
interface Presentation {
};
presentation 속성은
Presentation 인터페이스의 인스턴스를 가져오는 데
사용됩니다. 이 속성은
Presentation 인스턴스를
반환해야 합니다.
제어 사용자 에이전트는 다음 부분 인터페이스를 구현해야 합니다.
WebIDLpartial interface Presentation {
attribute PresentationRequest? defaultRequest;
};
defaultRequest 속성은 존재하는 경우 기본 프레젠테이션 요청을,
그렇지 않으면 null을 반환해야 합니다. 설정할 때는 기본
프레젠테이션 요청을 새 값으로 설정해야 합니다.
제어 사용자 에이전트는 사용자가 예를 들어 브라우저 크롬의 버튼을 클릭하는 등의 사용자 제스처를 통해 그렇게 하려는 의사를 표현한 경우에만 기본 프레젠테이션 요청을 사용하여 프레젠테이션을 시작하는 것이 좋습니다.
기본 프레젠테이션 요청을 사용하여 프레젠테이션을 시작하려면 제어 사용자 에이전트는 기본 프레젠테이션 요청에서 프레젠테이션을 시작하는 단계를 따라야 합니다.
기본 프레젠테이션 요청을 사용하여 프레젠테이션을 시작하는 기능의 지원은 선택 사항입니다.
defaultRequest에 설정된 값을 무시하는
것이 좋습니다.
수신 사용자 에이전트는 다음 부분 인터페이스를 구현해야 합니다.
WebIDLpartial interface Presentation {
readonly attribute PresentationReceiver? receiver;
};
receiver
속성은 수신 브라우징
컨텍스트와 연결되어 있으며, 수신 브라우징
컨텍스트가 생성될 때
수신 사용자 에이전트가 생성한 PresentationReceiver 인스턴스를 반환해야 합니다.
그 밖의 모든 브라우징 컨텍스트(수신 브라우징
컨텍스트의 자식 navigable 포함)에서는 null을 반환해야 합니다.
웹 개발자는 navigator.presentation.receiver를 사용하여 문서가 프레젠테이션으로 로드되었는지 감지할 수 있습니다.
WebIDL[SecureContext, Exposed=Window]
interface PresentationRequest : EventTarget {
constructor(USVString url);
constructor(sequence<USVString> urls);
Promise<PresentationConnection> start();
Promise<PresentationConnection> reconnect(USVString presentationId);
Promise<PresentationAvailability> getAvailability();
};
PresentationRequest 객체는
제어
브라우징 컨텍스트가 만든 프레젠테이션 시작 또는 재연결 요청과 연결됩니다.
PresentationRequest
객체는 제어 사용자 에이전트가 제공하는
제어 브라우징 컨텍스트에
구현되어야 합니다.
PresentationRequest가 생성되면, 주어진
urls는 PresentationRequest 인스턴스에서 각각 가능한
프레젠테이션 URL인 프레젠테이션 요청
URL 목록으로
사용해야 합니다.
PresentationRequest 구성
PresentationRequest 생성자가
호출되면 제어 사용자 에이전트는
다음 단계를 실행해야 합니다.
PresentationRequest 객체
SecurityError를 발생시키고
이 단계를 중단합니다.
NotSupportedError를
발생시키고 남은 모든
단계를 중단합니다.
SyntaxError
예외를 발생시키고 남은 모든
단계를 중단합니다.
NotSupportedError를
발생시키고 남은 모든 단계를 중단합니다.
SecurityError를
발생시키고 이 단계를 중단합니다.
PresentationRequest 객체를
생성하고 반환합니다.
start
메서드가 호출되면
사용자
에이전트는 프레젠테이션
디스플레이를 선택하기 위해 다음
단계를 실행해야 합니다.
start
호출을 받은 PresentationRequest
객체
Promise
InvalidAccessError
예외로 거부된 Promise를 반환하고 이 단계를 중단합니다.
start 호출에서 아직 미정인
Promise가 이미 있다면,
OperationError 예외로
거부된 새 Promise를 반환하고
남은 모든 단계를 중단합니다.
Promise로 둡니다.
NotFoundError
예외로 거부하도록
Presentation API 작업을 큐에 넣습니다.
NotAllowedError
예외로 거부하도록 Presentation API 작업을 큐에 넣고,
남은 모든 단계를 중단합니다.
사용자가 브라우저 크롬(전용 버튼, 사용자 제스처 또는 기타 신호를 통해)을 사용하여 프레젠테이션 디스플레이에서 문서의 프레젠테이션을 시작하려는 의사를 표현하면, 해당 사용자 에이전트는 기본 프레젠테이션 요청에서 프레젠테이션을 시작하기 위해 다음 단계를 실행해야 합니다. 문서에 기본 프레젠테이션 요청이 설정되지 않은 경우 이 단계들을 실행해서는 안 됩니다.
null이 아닌 값
사용자 에이전트가 프레젠테이션 연결을 시작하려면 다음 단계를 실행해야 합니다.
PresentationRequest
Promise
PresentationConnection
S를 생성합니다.
connecting으로
설정합니다.
connectionavailable이라는 이름의 이벤트를
발생시키도록
Presentation API 작업을 큐에 넣습니다.
이 이벤트는 PresentationConnectionAvailableEvent
인터페이스를 사용하고, connection
속성은 S로 초기화됩니다.
이벤트는 버블링되지 않아야 하며 취소할 수 없어야 합니다.
error,
closeMessage으로 실패를 설명하는 사람이 읽을 수 있는 메시지를 사용해 닫습니다.
http
또는 https 스킴을 사용하는 presentationUrl의 동작을 정의하며,
다른 스킴에 대한 동작은 이 명세에서 정의하지 않습니다.
reconnect
메서드가 호출되면 사용자 에이전트는 프레젠테이션에 다시 연결하기 위해
다음 단계를 실행해야 합니다.
reconnect가
호출된 PresentationRequest
객체
Promise
Promise로 둡니다.
PresentationConnection을
검색합니다.
terminated가
아닙니다.
PresentationConnection이 존재하면
다음 단계를 실행합니다.
PresentationConnection으로
둡니다.
connecting
또는
connected이면
남은 모든 단계를 중단합니다.
connecting으로
설정합니다.
PresentationConnection을
검색합니다.
terminated가
아닙니다.
PresentationConnection이 존재하면
다음 단계를 실행합니다.
PresentationConnection으로
둡니다.
PresentationConnection
newConnection을 생성합니다.
connecting으로
설정합니다.
connectionavailable이라는 이름의
이벤트를 발생시키도록
Presentation API 작업을 큐에 넣습니다.
이 이벤트는 PresentationConnectionAvailableEvent
인터페이스를 사용하고
connection
속성은 newConnection으로 초기화됩니다.
이벤트는 버블링되지 않아야 하며 취소할 수 없어야 합니다.
NotFoundError 예외로
거부하도록
Presentation API 작업을 큐에 넣습니다.
다음은 PresentationRequest
인터페이스를 구현하는 객체가 이벤트 핸들러 IDL 속성으로 지원해야 하는
이벤트 핸들러와 해당 이벤트 핸들러 이벤트 유형입니다.
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 유형 |
|---|---|
onconnectionavailable
|
connectionavailable
|
각 프레젠테이션 연결은
PresentationConnection 객체로 표현됩니다.
제어 사용자
에이전트와 수신 사용자 에이전트 모두
PresentationConnection을 구현해야 합니다.
WebIDLenum PresentationConnectionState { "connecting", "connected", "closed", "terminated" };
[SecureContext, Exposed=Window]
interface PresentationConnection : EventTarget {
readonly attribute USVString id;
readonly attribute USVString url;
readonly attribute PresentationConnectionState state;
undefined close();
undefined terminate();
attribute EventHandler onconnect;
attribute EventHandler onclose;
attribute EventHandler onterminate;
// 통신
attribute BinaryType binaryType;
attribute EventHandler onmessage;
undefined send (DOMString message);
undefined send (Blob data);
undefined send (ArrayBuffer data);
undefined send (ArrayBufferView data);
};
id 속성은
프레젠테이션 연결의 프레젠테이션 식별자를 지정합니다.
url 속성은
프레젠테이션 연결의 프레젠테이션 URL을
지정합니다.
state 속성은
프레젠테이션 연결의 현재 상태를 나타냅니다.
연결 상태에 따라
PresentationConnectionState의 값 중 하나를
가질 수 있습니다.
connecting은 사용자 에이전트가
대상 브라우징 컨텍스트와
프레젠테이션
연결을 설정하려고 시도 중임을 의미합니다. 이는
PresentationConnection 객체가
생성될 때의 초기 상태입니다.
connected는
프레젠테이션
연결이 설정되었고 통신이 가능함을 의미합니다.
closed는
프레젠테이션 연결이
닫혔거나 열 수 없었음을 의미합니다.
reconnect 호출을 통해 다시
열 수 있습니다. 통신은
불가능합니다.
terminated는
수신 브라우징
컨텍스트가 종료되었음을 의미합니다. 해당
프레젠테이션에 대한 모든
프레젠테이션
연결도 종료되며 다시 열 수 없습니다. 통신은 불가능합니다.
connected
상태라고 해서 메시지 송수신이 성공한다는 의미는 아닙니다.
이러한 상황을 가능한 한 빨리 감지하려는 애플리케이션은
자체 keep-alive 메커니즘을 구현하는 것이 좋습니다.
PresentationConnection
S에서
close 메서드가 호출되면
사용자 에이전트는
closeReason으로 closed를,
closeMessage으로 빈 메시지를 사용하여
S의 프레젠테이션
연결 닫기를 시작해야 합니다.
제어
브라우징 컨텍스트의
PresentationConnection
S에서
terminate 메서드가 호출되면,
사용자 에이전트는 S를 사용하여
제어 브라우징
컨텍스트에서 프레젠테이션을 종료하는 알고리즘을 실행해야 합니다.
수신 브라우징 컨텍스트의
PresentationConnection
S에서
terminate
메서드가 호출되면 사용자 에이전트는 S를 사용하여
수신
브라우징 컨텍스트에서 프레젠테이션을 종료하는 알고리즘을 실행해야 합니다.
binaryType 속성은
BinaryType의 값 중 하나를 가질 수 있습니다.
PresentationConnection 객체가
생성되면 해당 binaryType 속성을
문자열 "arraybuffer"로 설정해야 합니다. 가져올 때는
마지막으로 설정된 값을 반환해야 합니다. 설정할 때는 사용자 에이전트가
속성을 새 값으로 설정해야 합니다.
binaryType
속성을 사용하면 작성자가 바이너리 데이터가 스크립트에 노출되는 방식을
제어할 수 있습니다. 속성을 "blob"으로 설정하면 바이너리
데이터가 Blob 형태로 반환되고,
"arraybuffer"로 설정하면 ArrayBuffer 형태로 반환됩니다.
이 속성의 기본값은 "arraybuffer"입니다. 이 속성은
문자열 형태로 전송되는 데이터에는 영향을 주지 않습니다.
PresentationConnection
S에서
send 메서드가 호출되면
사용자 에이전트는
S를 통해 메시지를 전송하는 알고리즘을 실행해야 합니다.
PresentationConnection 객체
S의 프레젠테이션 연결
상태가 connecting 또는
connected인 동안
S가 폐기되면(이를 소유한 문서가 탐색 중이거나 닫혔기 때문),
사용자 에이전트는
closeReason으로 wentaway를,
closeMessage으로 빈 값을 사용하여 S의
프레젠테이션
연결 닫기를 시작해야 합니다.
사용자 에이전트가
대상
브라우징 컨텍스트로부터 PresentationConnection
S를 닫아야 한다는 신호를 받으면,
closeReason으로 closed 또는 wentaway를,
closeMessage으로 빈 값을 사용하여 S의 프레젠테이션
연결을 닫아야 합니다.
사용자 에이전트가 프레젠테이션 연결을 사용하여 프레젠테이션 연결을 설정하려면 다음 단계를 실행해야 합니다.
PresentationConnection 객체
connecting이 아니면
남은 모든 단계를 중단합니다.
connected로
설정합니다.
connect라는 이름의 이벤트를
발생시킵니다.
error로,
closeMessage은 실패를 설명하는 사람이 읽을 수 있는 메시지로 설정합니다.
DOMString 및 바이너리 페이로드를 신뢰할 수 있고
순서대로 전달할 수 있는 양방향 메시징 추상화를 제공해야 합니다.
PresentationConnection을 통해 메시지
전송
send를 여러 번 호출하는 경우
메시지가 상대측에 신뢰성 있게 순서대로 전달되도록 보장해야 합니다.
전송은 신뢰성 모드의 RTCDataChannel과
동등하게 동작해야 합니다.
프레젠테이션 메시지 데이터를 두 브라우징 컨텍스트 사이에서
전송할 페이로드 데이터라고 합니다. 프레젠테이션
메시지 유형을 해당 데이터의 유형으로 하며,
text 또는 binary 중 하나입니다.
사용자 에이전트가 프레젠테이션 연결을 통해 메시지를 전송하려면 다음 단계를 실행해야 합니다.
state 속성이
connected가 아니면
InvalidStateError
예외를 발생시킵니다.
ArrayBuffer,
ArrayBufferView 또는
Blob이면
프레젠테이션 메시지 유형
messageType을 binary로 둡니다.
messageOrData의 유형이 DOMString이면
messageType을 text로 둡니다.
error로,
closeMessage은 발생한 오류를 설명하는 값으로 설정합니다.
애플리케이션이 프레젠테이션 연결을 통해 메시지를 전송할 때 발생한 오류에서 복구할 수 있도록 사용자 에이전트는 closeMessage에 실패 이유를 설명하는 사람이 읽을 수 있는 문자열과 함께 어떤 시도가 실패했는지에 대한 세부 정보를 포함하는 것이 좋습니다. closeMessage의 예시는 다음과 같습니다.
Unable to send text message (network_error):
"hello"는 DOMString 메시지의 경우이며,
"hello"는 실패한 메시지의 처음 256자입니다.
Unable to send binary message (invalid_message)는
ArrayBuffer,
ArrayBufferView 및
Blob 메시지의 경우입니다.
PresentationConnection을 통해 메시지
수신
사용자 에이전트가 원격 측에서
프레젠테이션 메시지 데이터와
프레젠테이션 메시지 유형으로 구성된 전송을 받으면,
PresentationConnection을 통해
메시지를 수신하기 위해
다음 단계를 실행해야 합니다.
state 속성이
connected가 아니면
이 단계를 중단합니다.
message를 사용하여
MessageEvent 인터페이스로
이벤트를 생성한 결과로 둡니다.
이 이벤트는 버블링되지 않으며 취소할 수 없습니다.
text이면
event의 data 속성을
DOMString 유형의 messageData로 초기화합니다.
binary이고
binaryType
속성이 "blob"으로 설정되어 있으면,
event의 data 속성을
messageData를 원시 데이터로 갖는 새
Blob 객체로 초기화합니다.
binary이고
binaryType
속성이 "arraybuffer"로 설정되어 있으면,
event의 data 속성을
내용이 messageData인 새 ArrayBuffer 객체로
초기화합니다.
사용자 에이전트가
presentationConnection을 통해 메시지를 수신하는 동안
복구할 수 없는 오류를 만나면, closeReason으로
error를 사용하여
presentationConnection의 프레젠테이션 연결을
즉시 닫아야 합니다. closeMessage으로는 발생한 오류에 대한
사람이 읽을 수 있는 설명을 사용하는 것이 좋습니다.
WebIDLenum PresentationConnectionCloseReason { "error", "closed", "wentaway" };
[SecureContext, Exposed=Window]
interface PresentationConnectionCloseEvent : Event {
constructor(DOMString type, PresentationConnectionCloseEventInit eventInitDict);
readonly attribute PresentationConnectionCloseReason reason;
readonly attribute DOMString message;
};
dictionary PresentationConnectionCloseEventInit : EventInit {
required PresentationConnectionCloseReason reason;
DOMString message = "";
};
프레젠테이션 연결이
closed 상태가 되면
PresentationConnectionCloseEvent가
발생합니다. reason
속성은 연결이 닫힌 이유를 제공합니다. 이 속성은
PresentationConnectionCloseReason의 값 중 하나를
가질 수 있습니다.
error는
프레젠테이션에 연결하거나 통신하는 메커니즘에서
복구할 수 없는 오류가 발생했음을 의미합니다.
closed는
PresentationConnection으로 연결된
제어 브라우징
컨텍스트 또는 수신 브라우징
컨텍스트 중 하나가
close()를 호출했음을 의미합니다.
wentaway는 브라우저가 연결을
닫았음을 의미합니다. 예를 들어 연결을 소유한 브라우징 컨텍스트가
탐색되었거나 폐기된 경우입니다.
reason 속성이
error일 때,
사용자 에이전트는 message 속성을
통신 채널에서 오류가 어떻게 발생했는지를 설명하는 사람이 읽을 수 있는 설명으로
설정하는 것이 좋습니다.
PresentationConnectionCloseEvent
생성자가 호출되면 사용자 에이전트는 새
PresentationConnectionCloseEvent
객체를 생성해야 합니다. 해당
reason
속성은 생성자에 전달된 PresentationConnectionCloseEventInit
객체의 reason 구성원으로 설정하고,
message 속성은
이 PresentationConnectionCloseEventInit
객체의 message 구성원이
설정되어 있으면 해당 구성원으로, 그렇지 않으면 빈 문자열로 설정합니다.
PresentationConnection 닫기
사용자 에이전트가 프레젠테이션 연결 닫기를 시작하려면 다음을 수행해야 합니다.
PresentationConnectionCloseReason
connecting 또는
connected가 아니면
남은 단계를 중단합니다.
closed로 설정합니다.
PresentationConnection을
닫으려는 의도를 알리는 신호를 보내기 시작하고,
closeReason을 해당 컨텍스트에 전달합니다.
사용자 에이전트는 다음 단계로 진행하기 전에 해당
PresentationConnection이
실제로 닫혔다는 확인을 기다릴 필요가 없습니다.
wentaway가
아니면,
presentationConnection, closeReason,
closeMessage을 사용하여 로컬에서
프레젠테이션
연결을 닫는 단계를 실행합니다.
사용자 에이전트가 프레젠테이션 연결을 닫으려면 다음을 수행해야 합니다.
PresentationConnectionCloseReason
connecting,
connected,
또는 closed 중 하나가
아니면
남은 단계를 중단합니다.
closed가 아니면
closed로
설정합니다.
close라는 이름의 이벤트를 발생시킵니다.
이 이벤트는 PresentationConnectionCloseEvent
인터페이스를 사용하며,
reason
속성은 closeReason으로,
message
속성은 closeMessage으로 초기화됩니다.
이벤트는 버블링되지 않아야 하며 취소할 수 없어야 합니다.
제어 사용자 에이전트가 connection을 사용하여 제어 브라우징 컨텍스트에서 프레젠테이션을 종료하려면 다음 단계를 실행해야 합니다.
connected 또는
connecting이 아니면
이 단계를 중단합니다.
connected
또는 connecting이면,
known connection의 관련
전역 객체를 사용하여 프레젠테이션 작업
소스에 다음 단계를 실행하는 전역 작업을 큐에 넣습니다.
terminated로
설정합니다.
terminate라는 이름의 이벤트를
발생시킵니다.
다음 중 하나가 발생하면 수신 사용자 에이전트는 수신 브라우징 컨텍스트에서 프레젠테이션을 종료해야 합니다.
이는 명시적인 사용자 동작이나 사용자 에이전트 정책에 의해 발생할 수 있습니다.
예를 들어 수신 사용자
에이전트는 모든
PresentationConnection
객체가 30분 동안 닫혀 있는 프레젠테이션을 종료하도록 구성할 수 있습니다.
수신 사용자 에이전트가 수신 브라우징 컨텍스트에서 프레젠테이션을 종료하려면 다음 단계를 실행해야 합니다.
connected이면
connection을 connectedControllers에 추가합니다.
terminated로
설정합니다.
각 제어 사용자 에이전트에는 종료 확인을 하나만 전송하면 됩니다.
수신 사용자 에이전트가 프레젠테이션 P에 대한 종료 확인을 전송하고 그 확인을 제어 사용자 에이전트가 받으면, 제어 사용자 에이전트는 다음 단계를 실행해야 합니다.
connected
또는 connecting이
아니면
다음 단계를 중단합니다.
terminated로
설정합니다.
terminate라는 이름의 이벤트를
발생시킵니다.
다음은 PresentationConnection 인터페이스를 구현하는
객체가 이벤트 핸들러 IDL 속성으로 지원해야 하는 이벤트 핸들러와 해당 이벤트
핸들러 이벤트 유형입니다.
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 유형 |
|---|---|
onmessage
|
message
|
onconnect
|
connect
|
onclose
|
close
|
onterminate
|
terminate
|
WebIDL[SecureContext, Exposed=Window]
interface PresentationReceiver {
readonly attribute Promise<PresentationConnectionList> connectionList;
};
PresentationReceiver 인터페이스는
수신
브라우징 컨텍스트가 제어 브라우징
컨텍스트에 접근하고
통신할 수 있게 합니다. PresentationReceiver 인터페이스는
수신 사용자 에이전트가 제공하는
수신 브라우징 컨텍스트에
구현되어야 합니다.
가져올 때 connectionList 속성은
다음 단계를 실행한 결과를 반환해야 합니다.
null이 아니면
프레젠테이션
컨트롤러 프로미스를 반환하고 남은 모든 단계를 중단합니다.
PresentationReceiver 객체의
JavaScript realm에서 생성된 새
Promise로 둡니다.
null이 아니면, 프레젠테이션 컨트롤러
프로미스를 프레젠테이션
컨트롤러 모니터로 이행합니다.
사용자 에이전트가 수신 브라우징 컨텍스트를 생성하려면 다음 단계를 실행해야 합니다.
"denied"로 설정합니다.
Cache 객체의 새 빈 집합을 생성합니다.
표시된 문서가 생성한 모든 자식 navigable, 즉 수신 브라우징 컨텍스트를 해당 최상위 브라우징 컨텍스트로 갖는 모든 자식 navigable에도 위의 제한 2-4가 적용되어야 합니다. 또한 이들은 사용자 활성화 없는 최상위 탐색 샌드박스 브라우징 컨텍스트 플래그가 설정되어 있어야 합니다. 이 모든 브라우징 컨텍스트는 위에 나열된 기능 5-10에 대해 동일한 브라우징 상태(저장소)도 공유해야 합니다.
최상위 브라우징 컨텍스트가 새 리소스로 탐색하려고 하면서 탐색 단계를 실행할 때, 탐색이 허용되는지 판단하기 위해 1단계를 따라야 합니다. 또한 프래그먼트 식별자로 탐색하거나 문서를 다시 로드하는 경우를 제외하고 자기 자신을 새 리소스로 탐색하도록 허용해서는 안 됩니다.
이를 통해 사용자는 프레젠테이션 디스플레이를 선택할 때 표시되는 프레젠테이션 URL의 출처를 기준으로 권한을 부여할 수 있습니다.
최상위 브라우징 컨텍스트가 탐색할 수 있도록 허용되지 않았다면, 새 최상위 브라우징 컨텍스트에서 리소스를 열도록 제안하지 않는 것이 좋습니다. 그렇지 않은 경우에는 탐색 단계와 일관되게 동작하는 것이 좋습니다.
수신 브라우징 컨텍스트와 그 하위 navigable에 연결된 Window 클라이언트와 worker 클라이언트는 서로 연결된 서비스 워커에 노출되어서는 안 됩니다.
수신 브라우징 컨텍스트가 종료되면,
해당 컨텍스트 및 그 하위 navigable의
브라우징
컨텍스트와 연결된 모든 서비스 워커는
등록 해제되고 종료되어야 합니다. 수신 브라우징 컨텍스트와 그
하위 navigable의
브라우징 컨텍스트와 관련된 모든 브라우징 상태,
즉 세션
기록, 쿠키 저장소,
모든 HTTP
인증 상태, 모든 데이터베이스,
세션
저장소 영역, 로컬 저장소 영역,
등록된 서비스 워커 등록 목록 및
Cache
객체는 폐기되어야 하며 다른 어떤 브라우징
컨텍스트에서도 사용해서는 안 됩니다.
이 알고리즘은 1-UA 및 2-UA 프레젠테이션이 상호 운용 가능한 동작을 할 수 있도록 잘 정의된 환경을 생성하고, 2-UA 프레젠테이션에 사용되는 프레젠테이션 디스플레이에 남는 상태의 양을 최소화하기 위한 것입니다.
수신 사용자 에이전트는 제어 사용자 에이전트의 언어 기본 설정을 반영하는 HTTP Accept-Language 헤더를 사용하여 수신 브라우징 컨텍스트의 리소스를 가져오는 것이 좋습니다. 즉, 제어 사용자 에이전트가 보냈을 것과 동일한 Accept-Language를 사용합니다. 이는 수신 사용자 에이전트가 사용자의 기본 설정을 반영하는 글꼴과 로케일별 속성을 사용하여 프레젠테이션을 렌더링하는 데 도움이 됩니다.
프레젠테이션 디스플레이의 작동 환경을 고려하면 일부 Web API는 설계상 동작하지 않거나 (예: 사용자 입력을 요구함) 더 이상 적절하지 않을 수 있습니다 (예: 창 관리를 시도함). 수신 사용자 에이전트는 이를 고려해야 합니다. 또한 모든 모달 사용자 인터페이스는 주의해서 처리해야 합니다. 이러한 작업 대부분을 방지하기 위해 샌드박스된 모달 플래그가 수신 브라우징 컨텍스트에 설정됩니다.
적합성에서 언급했듯이, 제어 사용자 에이전트이면서 수신 사용자 에이전트이기도 한 사용자 에이전트는 수신 브라우징 컨텍스트가 추가 프레젠테이션을 생성하도록 허용할 수 있습니다. 그러면 해당 컨텍스트는 제어 브라우징 컨텍스트도 됩니다. 웹 개발자는 navigator.presentation.receiver를 사용하여 문서가 수신 브라우징 컨텍스트로 로드되었는지 감지할 수 있습니다.
WebIDL[SecureContext, Exposed=Window]
interface PresentationConnectionList : EventTarget {
readonly attribute FrozenArray<PresentationConnection> connections;
};
connections
속성은 프레젠테이션
컨트롤러 집합에 있는 종료되지 않은 프레젠테이션
연결 집합을 반환해야 합니다.
수신 사용자 에이전트가 수신 브라우징 컨텍스트에서 제어 브라우징 컨텍스트로부터의 들어오는 프레젠테이션 연결 모니터링을 시작하려면, 구현별 메커니즘을 사용하여 제어 브라우징 컨텍스트에서 오는 연결 요청을 수신하고 수락해야 합니다. 제어 브라우징 컨텍스트에서 새 연결 요청을 받으면 수신 사용자 에이전트는 다음 단계를 실행해야 합니다.
PresentationConnection
S를 생성합니다.
connected로 설정합니다.
그렇지 않으면 S의 프레젠테이션
연결 상태를
closed로 설정하고
남은 모든 단계를 중단합니다.
null이면 다음 단계를 병렬로 실행합니다.
PresentationReceiver
객체의 JavaScript realm에서 생성된 새
PresentationConnectionList로
둡니다.
null이 아니면,
프레젠테이션 컨트롤러
프로미스를 프레젠테이션
컨트롤러
모니터로
이행하도록 Presentation
API 작업을 큐에 넣습니다.
connectionavailable이라는 이름의
이벤트를 발생시키도록
Presentation API 작업을 큐에 넣습니다.
이 이벤트는 PresentationConnectionAvailableEvent
인터페이스를 사용하며,
connection
속성은 S로 초기화됩니다. 이벤트는 버블링되지 않아야 하며
취소할 수 없어야 합니다.
다음은 PresentationConnectionList
인터페이스를 구현하는 객체가 이벤트 핸들러 IDL 속성으로 지원해야 하는
이벤트 핸들러와 해당 이벤트 핸들러 이벤트 유형입니다.
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 유형 |
|---|---|
onconnectionavailable
|
connectionavailable
|
이 절은 비규범적입니다.
PresentationAvailability
객체에서 발생하는 change 이벤트는 흔히
브라우저의 로컬 영역 네트워크를 통해 검색되는
프레젠테이션 디스플레이의 존재 여부에 관한
1비트의 정보를 노출합니다. 이는 다른 정보와 함께 사용되어
사용자의 핑거프린팅에 이용될 수 있습니다. 그러나 이
정보는 사용자의 로컬 네트워크 환경에도 의존하므로
위험은 최소화됩니다.
이 API는 사용 가능한 프레젠테이션 디스플레이 목록 모니터링을 지원합니다. 사용자 에이전트가 주어진 URL에 대한 프레젠테이션 디스플레이의 호환성과 가용성을 결정하는 방법은 구현 세부 사항입니다. 제어 사용자 에이전트가 프레젠테이션 요청 URL을 DIAL 애플리케이션과 일치시켜 가용성을 판단하는 경우, 이 기능을 사용하여 사용자의 동의 없이 프레젠테이션 디스플레이에 사용자가 설치한 DIAL 애플리케이션에 관한 정보를 탐색할 수 있습니다.
프레젠테이션은 출처 간에 접근할 수 있습니다. 프레젠테이션을 생성하는 데 사용된 프레젠테이션 URL과 프레젠테이션 식별자만 있으면 제어 사용자 에이전트의 어느 출처에서든 프레젠테이션에 다시 연결할 수 있습니다. 즉, 프레젠테이션은 특정한 최초 출처에 종속되지 않습니다.
이 설계는 서로 다른 출처의 제어 컨텍스트가 공유 프레젠테이션 리소스에 연결할 수 있게 합니다. 프레젠테이션 식별자의 보안은 임의의 출처가 기존 프레젠테이션에 연결하는 것을 방지합니다.
이 명세는 또한 수신 사용자 에이전트가
자신의 제어되는
프레젠테이션 집합에 관한 정보를 공개하고,
제어 사용자 에이전트가 다른 장치에서
시작된 프레젠테이션에 다시 연결할 수 있도록 허용합니다. 이는
제어
브라우징 컨텍스트가 실행 중인 프레젠테이션의
프레젠테이션 URL과
프레젠테이션 식별자를
사용자, 로컬 저장소 또는 서버에서 가져온 다음
reconnect를 통해
프레젠테이션에 연결할 때 가능합니다.
이 명세는 프레젠테이션에 연결하는 어느 당사자의 신원도
보장하지 않습니다. 연결된 후 프레젠테이션은
애플리케이션별 수단을 통해 연결한 당사자의 신원을 추가로
검증할 수 있습니다. 예를 들어 프레젠테이션은 컨트롤러에
send를 통해 토큰을 제공하도록
요구하고, 이를 사용하여 신원과 권한 부여를 검증할 수 있습니다.
프레젠테이션 디스플레이를 선택하는 단계에서 사용자가 프레젠테이션 디스플레이 사용 권한을 요청받을 때, 제어 사용자 에이전트는 어떤 출처가 프레젠테이션을 요청하는지와 그리고 어떤 출처가 표시될지를 명확하게 알려야 합니다.
프레젠테이션을 요청하는 출처를 표시하면 사용자가 어떤 콘텐츠가 요청을 하는지 이해하는 데 도움이 됩니다. 특히 요청이 자식 navigable에서 시작되는 경우에 유용합니다. 예를 들어 임베디드 콘텐츠가 사용자를 설득하여 클릭하게 하고, 원치 않는 프레젠테이션을 시작하는 요청을 발생시키려 할 수 있습니다.
프레젠테이션의 수명 동안 최상위 출처가 동일하게 유지되도록 하기 위해 사용자 활성화 없는 샌드박스된 최상위 탐색 브라우징 컨텍스트 플래그가 수신 브라우징 컨텍스트에 설정됩니다.
사용자가 프레젠테이션을 시작하면 처음에는 사용자가 프레젠테이션을 독점적으로 제어합니다. 그러나 Presentation API는 추가 장치(서로 다른 사용자의 장치일 가능성이 높음)가 연결하여 프레젠테이션을 함께 제어할 수 있도록 허용합니다. 두 번째 장치가 프레젠테이션에 연결되면 연결된 모든 제어 사용자 에이전트가 브라우저 크롬을 통해 사용자에게 원래 사용자가 독점 접근 권한을 잃었으며 이제 프레젠테이션에 여러 컨트롤러가 존재함을 알리는 것이 권장됩니다.
또한 수신 사용자 에이전트가 프레젠테이션 디스플레이 역할뿐만 아니라 사용자 입력도 받을 수 있는 경우가 있습니다. 이 경우 수신 사용자 에이전트는 수신 브라우징 컨텍스트가 원격 당사자의 제어를 받고 있을 때(즉, 하나 이상의 컨트롤러가 연결되어 있을 때) 브라우저 크롬을 통해 사용자에게 알려야 합니다.
Presentation API는 디스플레이에서 "로컬"이 무엇을 의미하는지를 추상화하여, 네트워크로 접근 가능한 디스플레이를 사용자의 장치에 직접 연결된 것처럼 노출합니다. Presentation API는 다른 사람이 볼 수 있는 디스플레이에 원치 않는 콘텐츠를 표시하는 것과 같은 문제가 발생할 가능성을 줄이기 위해 페이지가 어떤 디스플레이에든 접근하려면 사용자 권한을 요구합니다.
프레젠테이션 URL과 프레젠테이션 식별자를 사용하면 다른 브라우징 컨텍스트에서 프레젠테이션에 연결할 수 있습니다. 공격자가 제어 페이지에 콘텐츠를 삽입할 수 있다면 이를 가로챌 수 있습니다.
프레젠테이션에 표시되는 콘텐츠는 컨트롤러와 서로 다릅니다. 특히 사용자가 두 컨텍스트 모두에 로그인한 상태에서 제어 브라우징 컨텍스트에서 로그아웃하더라도 수신 브라우징 컨텍스트에서는 자동으로 로그아웃되지 않습니다. 인증을 사용하는 애플리케이션은 장치 간 통신 시 각별히 주의해야 합니다.
사용자 에이전트가 알고 있는 프레젠테이션 집합은 사용자가 "브라우징 데이터 삭제"를 요청할 때 지워야 합니다.
비공개 브라우징 모드("시크릿 모드")에서는 해당 브라우징 세션의 초기 제어되는 프레젠테이션 집합이 비어 있어야 합니다. 여기에 추가되는 모든 프레젠테이션 연결은 세션이 종료될 때 폐기해야 합니다.
이 명세는 제어 브라우징 컨텍스트와 수신 브라우징 컨텍스트 간 통신 프로토콜을 의무화하지 않지만, 서로 대응하는 프레젠테이션 연결 간 메시지의 기밀성과 진정성에 관한 일정한 보장을 설정해야 합니다.
WebIDLpartial interface Navigator {
[SecureContext, SameObject] readonly attribute Presentation presentation;
};
[SecureContext, Exposed=Window]
interface Presentation {
};
partial interface Presentation {
attribute PresentationRequest? defaultRequest;
};
partial interface Presentation {
readonly attribute PresentationReceiver? receiver;
};
[SecureContext, Exposed=Window]
interface PresentationRequest : EventTarget {
constructor(USVString url);
constructor(sequence<USVString> urls);
Promise<PresentationConnection> start();
Promise<PresentationConnection> reconnect(USVString presentationId);
Promise<PresentationAvailability> getAvailability();
attribute EventHandler onconnectionavailable;
};
[SecureContext, Exposed=Window]
interface PresentationAvailability : EventTarget {
readonly attribute boolean value;
attribute EventHandler onchange;
};
[SecureContext, Exposed=Window]
interface PresentationConnectionAvailableEvent : Event {
constructor(DOMString type, PresentationConnectionAvailableEventInit eventInitDict);
[SameObject] readonly attribute PresentationConnection connection;
};
dictionary PresentationConnectionAvailableEventInit : EventInit {
required PresentationConnection connection;
};
enum PresentationConnectionState { "connecting", "connected", "closed", "terminated" };
[SecureContext, Exposed=Window]
interface PresentationConnection : EventTarget {
readonly attribute USVString id;
readonly attribute USVString url;
readonly attribute PresentationConnectionState state;
undefined close();
undefined terminate();
attribute EventHandler onconnect;
attribute EventHandler onclose;
attribute EventHandler onterminate;
// 통신
attribute BinaryType binaryType;
attribute EventHandler onmessage;
undefined send (DOMString message);
undefined send (Blob data);
undefined send (ArrayBuffer data);
undefined send (ArrayBufferView data);
};
enum PresentationConnectionCloseReason { "error", "closed", "wentaway" };
[SecureContext, Exposed=Window]
interface PresentationConnectionCloseEvent : Event {
constructor(DOMString type, PresentationConnectionCloseEventInit eventInitDict);
readonly attribute PresentationConnectionCloseReason reason;
readonly attribute DOMString message;
};
dictionary PresentationConnectionCloseEventInit : EventInit {
required PresentationConnectionCloseReason reason;
DOMString message = "";
};
[SecureContext, Exposed=Window]
interface PresentationReceiver {
readonly attribute Promise<PresentationConnectionList> connectionList;
};
[SecureContext, Exposed=Window]
interface PresentationConnectionList : EventTarget {
readonly attribute FrozenArray<PresentationConnection> connections;
attribute EventHandler onconnectionavailable;
};
binaryType
PresentationConnection의 속성
§6.5
close
PresentationConnection의 메서드
§6.5
"connected"
PresentationConnectionState의 열거형 값
§6.5
"connecting"
PresentationConnectionState의
열거형 값
§6.5
connectionList
PresentationReceiver의
속성
§6.6
connections
PresentationConnectionList의
속성
§6.7
defaultRequest
Presentation의 속성
§6.2.1
"error"
PresentationConnectionCloseReason의 열거형 값
§6.5.4
getAvailability
PresentationRequest의
메서드
§6.4.3
id
PresentationConnection의
속성
§6.5
onchange
PresentationAvailability의 속성
§6.4
onclose
PresentationConnection의
속성
§6.5.9
onconnect
PresentationConnection의 속성
§6.5.9
PresentationRequest의
속성
§6.3.6
PresentationConnectionList의
속성
§6.7.2
onmessage
PresentationConnection의 속성
§6.5.9
onterminate
PresentationConnection의 속성
§6.5.9
presentation
Navigator의
속성
§6.2
Presentation 인터페이스
§6.2
PresentationAvailability
인터페이스
§6.4
PresentationConnection
인터페이스
§6.5
PresentationConnectionAvailableEvent
인터페이스
§6.4.5
PresentationConnectionAvailableEventInit
딕셔너리
§6.4.5
PresentationConnectionCloseEvent
인터페이스
§6.5.4
PresentationConnectionCloseEventInit
딕셔너리
§6.5.4
PresentationConnectionCloseReason
열거형
§6.5.4
PresentationConnectionList 인터페이스
§6.7
PresentationConnectionState 열거형
§6.5
PresentationReceiver
인터페이스
§6.6
PresentationRequest 인터페이스
§6.3
receiver
Presentation의
속성
§6.2.2
reconnect
PresentationRequest의
메서드
§6.3.5
send
PresentationConnection의
메서드
§6.5
start
PresentationRequest의
메서드
§6.3.2
state
PresentationConnection의
속성
§6.5
terminate
PresentationConnection의
메서드
§6.5
"terminated"
PresentationConnectionState의
열거형 값
§6.5
url
PresentationConnection의
속성
§6.5
value
PresentationAvailability의
속성
§6.4
"wentaway"
PresentationConnectionCloseReason의
열거형 값
§6.5.4
Event
인터페이스
EventInit
EventTarget 인터페이스
Blob
인터페이스
Document용)
EventHandler
localStorage
속성(WindowLocalStorage용)
MessageEvent 인터페이스
reload()(Location용)
sessionStorage
속성(WindowSessionStorage용)
Cache
인터페이스
ArrayBuffer 인터페이스
ArrayBufferView
boolean
유형
DOMString 인터페이스
[Exposed] 확장 속성
FrozenArray 인터페이스
InvalidAccessError 예외
InvalidStateError 예외
NotAllowedError 예외
NotFoundError 예외
NotSupportedError 예외
OperationError 예외
Promise 인터페이스
[SameObject] 확장 속성
[SecureContext] 확장 속성
SecurityError 예외
SyntaxError 예외
exception용)
undefined 유형
USVString 인터페이스
RTCDataChannel 인터페이스
BinaryType 열거형
이 초안의 편집, 검토 및 피드백에 도움을 주신 Addison Phillips, Anne Van Kesteren, Anssi Kostiainen, Anton Vayvod, Chris Needham, Christine Runnegar, Daniel Davis, Domenic Denicola, Erik Wilde, François Daoust, 闵洪波 (Hongbo Min), Hongki CHA, Hubert Sablonnière, Hyojin Song, Hyun June Kim, Jean-Claude Dufourd, Joanmarie Diggs, Jonas Sicking, Louay Bassbouss, Mark Watson, Martin Dürst, Matt Hammond, Mike West, Mounir Lamouri, Nick Doty, Oleg Beletski, Philip Jägenstedt, Richard Ishida, Shih-Chiang Chien, Takeshi Kanai, Tobie Langel, Tomoyuki Shimizu, Travis Leithead 및 Wayne Carr께 감사드립니다.
AirPlay, HDMI, Chromecast, DLNA 및 Miracast는 각각 Apple Inc., HDMI Licensing LLC., Google Inc., Digital Living Network Alliance 및 Wi-Fi Alliance의 등록 상표입니다. 이들은 배경 정보로만 인용되며 이 명세를 구현하기 위해 사용할 필요는 없습니다.
이 명세가 제안 권고안으로 진행되려면 이 명세에서 정의하는 각 적합성 클래스(제어 사용자 에이전트 및 수신 사용자 에이전트)마다 각 기능에 대해 독립적이고 상호 운용 가능한 구현이 최소 두 개 있어야 합니다. 각 기능은 서로 다른 제품 집합으로 구현될 수 있으며, 하나의 제품이 모든 기능을 구현해야 한다는 요구 사항은 없습니다. 또한 제어 사용자 에이전트 적합성 클래스의 구현에는 최소 하나의 1-UA 모드 구현과 하나의 2-UA 모드 구현이 포함되어야 합니다. 2-UA 모드 구현은 http/https가 아닌 프레젠테이션 URL만 지원할 수도 있습니다. 수신 사용자 에이전트 적합성 클래스의 구현에는 2-UA 모드 구현이 포함되지 않을 수도 있습니다.
이 API는 최근 보안 컨텍스트로 제한되었습니다. 초기 구현에서 비보안 컨텍스트의 API를 사용 중단하는 데에는 시간이 걸립니다. 향후 이러한 구현을 제한할 일정이 존재한다면, 그룹은 여전히 비보안 컨텍스트에서 API를 노출하는 구현으로도 제안 권고안으로의 전환을 요청할 수 있습니다.
이 기준의 목적상 다음 용어를 정의합니다.
이 절은 비규범적입니다.
이 절에서는 명세가 2016년 7월 후보 권고안으로 처음 발행된 이후 변경된 사항을 그룹의 이슈 추적기에서 관련 이슈로 연결되는 링크와 함께 나열합니다.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: