웹 인쇄 API

비공식 제안 초안,

이 버전:
https://github.com/bylica-at-google/web-printing-api
이슈 추적:
GitHub
편집자:
Dominik Bylica (Google)

초록

이 문서는 앱 개발자가 격리된 컨텍스트에서 프린터에 직접 접근할 수 있게 하여 훌륭한 프린터 관련 기능을 구축할 수 있도록 하는 새로운 Web Printing API를 정의합니다.

이 문서의 상태

이 명세는 Web Platform Incubator Community Group에서 발행했습니다. 이는 W3C 표준도 아니며 W3C 표준화 절차에 있는 것도 아닙니다. 다음 사항에 유의하십시오. W3C Community Contributor License Agreement (CLA) 에 따라 제한적인 옵트아웃 및 기타 조건이 적용됩니다. 자세한 내용은 W3C Community and Business Groups를 참조하십시오.

1. 소개

Web Printing API는 격리된 컨텍스트에서 인쇄 기능을 구현하는 데 전례 없는 유연성을 제공합니다. 이 API는 일반 웹 컨텍스트에는 노출되지 않습니다.

1.1. 기존 대안

존재하는 window.print() 메서드가 있지만, 기본적으로 인쇄 대화 상자를 열고 나머지는 사용자가 하도록 요청합니다. Web Printing API는 앱 개발자가 격리된 컨텍스트의 웹 애플리케이션에서 운영체제에서 로컬로 사용할 수 있는 프린터에 직접 접근할 수 있게 해 주며, 사용자 지정 인쇄 속성(용지 크기, 색상 설정, 품질 등)으로 인쇄 작업을 제출할 수 있게 합니다.

1.2. Web Printing API 기능

Web Printing API를 사용하면 다음을 할 수 있습니다.

Web Printing API는 Internet Printing Protocol을 모델로 합니다. 이는 프린터 기능과 인쇄 속성, 그 이름, 가능한 값, 유효한 값이 모두 Internet Printing Protocol(RFC8011)을 정의하는 표준 문서의 정의에서 온다는 뜻입니다.

RFC8011의 섹션 5는 더 자세히 알아보는 데 특히 유용합니다 (https://datatracker.ietf.org/doc/html/rfc8011#section-5).

2. 예제

2.1. 프린터 및 기본 속성 나열

try {
  const printers = await printing.getPrinters();
  for (const printer of printers) {
    const attributes = printer.cachedAttributes();
    console.log(
      ${attributes.printerName} has the following (basic) attributes: ${attributes});
  }
} catch (err) {
  console.warn("Printing operation failed: " + err);
}

2.2. 프린터 및 자세한 속성 나열

try {
  const printers = await printing.getPrinters();
  const promises = printers.map(printer => printer.fetchAttributes());
    Promise.all(promises).then((values) => {
      for (const attributes of values) {
        console.log(
          ${attributes.printerName} has the following (detailed) attributes: ${attributes});
      }
    });
} catch (err) {
  console.warn("Printing operation failed: " + err);
}

2.3. 프린터 상태 쿼리

try {
  const printers = await printing.getPrinters();
  const printer = printers.find(
      printer => printer.cachedAttributes().printerName === 'Brother QL-820NWB');
  const attributes = await printer.fetchAttributes();
  console.log(
    ${attributes.printerName}'s new state is ${attributes.printerState}!);
} catch (err) {
  console.warn("Printing operation failed: " + err);
}

2.4. 인쇄 작업 제출

try {
  const printers = await printing.getPrinters();
  const printer = printers.find(
    printer => printer.cachedAttributes().printerName === 'Brother QL-820NWB');

  const printJob = await printer.submitPrintJob("Sample Print Job",
    new Blob(...), {
      copies: 2,
      media: 'iso_a4_210x297mm',
      multipleDocumentHandling: 'separate-documents-collated-copies',
      printerResolution: {
        crossFeedDirectionResolution: 300,
        feedDirectionResolution: 400,
        units: 'dots-per-inch'
      },
      sides: 'one-sided',
      printQuality: 'high',
      pageRanges: [{from: 1, to: 5}, {from: 7, to: 10}],
    });

  const printJobComplete = new Promise((resolve, reject) => {
    printJob.onjobstatechange = () => {
      const jobState = printJob.attributes().jobState;
      if (IsErrorStatus(jobState)) {
        console.warn(Job errored: ${jobState});
        reject(/**/);
        return;
      }
      if (jobState === "completed") {
        console.log("Job complete!");
        resolve(/**/);
        return;
      }
      console.log(Job state changed to ${jobState});
    };
  });
  await printJobComplete;
} catch (err) {
  console.warn("Printing operation failed: " + err);
}

2.5. 인쇄 작업 취소

try {
  const printers = await printing.getPrinters();
  const printer = printers.find(
    printer => printer.cachedAttributes().printerName === 'Brother QL-820NWB');

  const printJob = await printer.submitPrintJob(...);

  // This might take no effect if the job has already finished.
  printJob.cancel();

} catch (err) {
  console.warn("Printing operation failed: " + err);
}

3. Window 인터페이스에 대한 확장

[Exposed=Window, SecureContext, IsolatedContext]
partial interface Window {
  [SameObject] readonly attribute WebPrintingManager printing;
};

각 Window 객체는 고유한 WebPrintingManager 객체 인스턴스와 연결되며, 이는 Window 객체가 생성될 때 할당됩니다.

4. WebPrintingManager

[Exposed=Window, SecureContext, IsolatedContext]
interface WebPrintingManager {
  Promise<sequence<WebPrinter>> getPrinters();
};

이 인터페이스의 메서드는 일부 단계를 병렬로 실행하며, web printing task source를 통해 메인 스레드에 작업을 다시 큐에 넣습니다.

getPrinters() 메서드 단계는 다음과 같습니다.
  1. this의 관련 전역 객체의 연결된 Document가 "web-printing"이라는 정책 제어 기능을 사용하도록 허용되지 않은 경우, "NotAllowedError" DOMException을 throw합니다.

  2. promise를 새 promise로 둡니다.

  3. global을 this의 관련 전역 객체로 둡니다.

  4. 다음 단계를 병렬로 실행합니다.

    1. local_printers를 운영체제에서 로컬로 사용할 수 있는 모든 프린터로 둡니다.

    2. attributes_list를 WebPrinterAttributes 딕셔너리의 빈 목록으로 둡니다.

    3. local_printers의 각 printer에 대해 반복합니다.

      1. web_printer_attributes를 새 WebPrinterAttributes 딕셔너리로 둡니다.

      2. web_printer_attributes의 printerName을 printer의 이름으로 설정합니다.

      3. web_printer_attributes의 printerId를 printer의 id로 설정합니다. 이 id는 자기 자신의 SHA256 해시를 16진수 문자열 표현으로 반환하여 난독화되어야 합니다.

      4. web_printer_attributes를 attributes_list에 추가합니다.

    4. global에서 전역 작업을 큐에 넣어 web printing task source를 사용해 다음 단계를 실행합니다.

      1. web_printers를 WebPrinter 객체의 빈 목록으로 둡니다.

      2. attributes_list의 각 attributes에 대해 반복합니다.

        1. web_printer를 attributes가 attributes로 설정된 새 WebPrinter로 둡니다.

        2. web_printer를 web_printers에 추가합니다.

      3. promise를 web_printers로 resolve합니다.

  5. promise를 반환합니다.

5. WebPrinter

[Exposed=Window, SecureContext, IsolatedContext]
interface WebPrinter {
  WebPrinterAttributes cachedAttributes();
  Promise<WebPrinterAttributes> fetchAttributes();
  Promise<WebPrintJob> submitPrintJob(
    USVString job_name,
    Blob document_data,
    optional WebPrintJobTemplateAttributes template_attributes = {});
};

각 WebPrinter에는 attributes가 있으며, 이는 WebPrinterAttributes의 인스턴스입니다. 처음에는 printerName 및 printerId만 포함하며, 더 많은 정보를 얻으려면 fetchAttributes()를 사용해야 합니다.

cachedAttributes() 메서드는 attributes를 반환합니다.

fetchAttributes() 메서드 단계는 다음과 같습니다.
  1. promise를 새 promise로 둡니다.

  2. 다음 단계를 병렬로 실행합니다.

    1. 프린터와 통신하는 동안 문제가 있는 경우, promise를 새 NetworkError DOMException으로 reject하고 이 단계를 중단합니다.

    2. new_web_printer_attributes를 WebPrinterAttributes의 새 인스턴스로 둡니다.

    3. 프린터에 프린터 기능을 쿼리합니다. 반환된 기능의 목록을 printer_capabilities로 둡니다.

    4. printer_capabilities의 각 printer_capability에 대해 반복합니다.

    5. Internet Printing Protocol(RFC 8011)에 따라 printer_capability가 WebPrinterAttributes 딕셔너리에 부합하도록 필요한 매핑을 수행합니다.

    6. 매핑된 printer_capability로 new_web_printer_attributes의 해당 필드를 설정합니다(예: media source와 관련된 printer_capability는 mediaSourceDefault 및 mediaSourceSupported의 유효한 값으로 매핑되어야 합니다).

    7. 프린터에 프린터 상태를 쿼리합니다. new_web_printer_attributes의 printerState를 반환된 프린터 상태 값으로 설정합니다.

    8. attributes를 new_web_printer_attributes로 설정합니다.

    9. promise를 new_web_printer_attributes로 resolve합니다.

  3. promise를 반환합니다.

submitPrintJob() 메서드 단계는 다음과 같습니다.
  1. promise를 새 promise로 둡니다.

  2. 다음 단계를 병렬로 실행합니다.

    1. 프린터와 통신하는 동안 문제가 있는 경우, promise를 새 NetworkError DOMException으로 reject하고 이 단계를 중단합니다.

    2. fetchAttributes()의 알고리즘을 사용하여 attributes를 업데이트합니다.

    3. printer를 submitPrintJob()가 실행되는 WebPrinter 인스턴스로 둡니다.

    4. template_attributes의 각 template_attribute에 대해 반복합니다.

    5. template_attribute가 해당 printer의 attributes에 대해 확인한 지원 값(예: mediaSource를 mediaSourceSupported에 대해 확인한 값)을 포함하지 않는 경우, promise를 새 DataError DOMException으로 reject하고 이 단계를 중단합니다.

    6. pdf_data가 PDF 문서 데이터를 보유하도록 합니다. document_data Blob을 PDF 문서로 변환하고 그 값을 pdf_data로 설정합니다. document_data가 잘못된 형식, 즉 유효한 PDF 문서가 아닌 경우, promise를 새 DataError DOMException으로 reject하고 이 단계를 중단합니다.

    7. pdf_data를 WebPrintJobTemplateAttributes와 함께 보내고 프린터에 인쇄 작업으로 제출합니다.

    8. print_job를 WebPrintJob 인터페이스의 인스턴스로 둡니다. print_job을 방금 프린터에 제출한 인쇄 작업과 연결합니다.

  3. promise를 print_job으로 resolve합니다.

  4. promise를 반환합니다.

signal은 AbortSignal 타입이며, 인쇄 작업을 cancel()하는 데에도 사용할 수 있습니다.

6. WebPrintJob

[Exposed=Window, SecureContext, IsolatedContext]
interface WebPrintJob : EventTarget {
  WebPrintJobAttributes attributes();
  undefined cancel();

  attribute EventHandler onjobstatechange;
};

각 WebPrintJob에는 attributes가 있으며, 이는 WebPrintJobAttributes의 인스턴스이고, 처음에는 비어 있습니다.

attributes() 메서드는 인쇄 작업이 어떤 상태에 있는지(예: 완료된 페이지 수)를 보여 주는 attributes를 반환합니다.

cancel() 메서드는 인쇄 작업을 즉시 중단합니다.

취소는 signal 매개변수로 전달된 AbortSignal 타입을 사용해 수행할 수 있으며, 이는 submitPrintJob() 메서드를 호출할 때 WebPrintJobTemplateAttributes의 일부로 전달됩니다.

onjobstatechange는 onjobstatechange 이벤트 타입에 대한 이벤트 핸들러 IDL 속성입니다. 사용자 에이전트는 인쇄 작업의 WebPrintJobState 또는 jobPagesCompleted가 변경될 때마다 onjobstatechange 이벤트를 반드시 발생시켜야 합니다.

7. 데이터 모델

WebPrinterAttributes - attributes를 나타내는 딕셔너리입니다.

WebPrintJobTemplateAttributes - 인쇄 작업 속성을 나타내는 딕셔너리입니다.

dictionary WebPrinterAttributes {
  USVString printerName;
  USVString printerId;

  unsigned long copiesDefault;
  WebPrintingRange copiesSupported;

  WebPrintingMediaCollection mediaColDefault;
  sequence<WebPrintingMediaCollection> mediaColDatabase;

  USVString mediaSourceDefault;
  sequence<USVString> mediaSourceSupported;

  WebPrintingMimeMediaType documentFormatDefault;
  sequence<WebPrintingMimeMediaType> documentFormatSupported;

  WebPrintingMultipleDocumentHandling multipleDocumentHandlingDefault;
  sequence<WebPrintingMultipleDocumentHandling> multipleDocumentHandlingSupported;

  WebPrintingOrientationRequested orientationRequestedDefault;
  sequence<WebPrintingOrientationRequested> orientationRequestedSupported;

  WebPrintingResolution printerResolutionDefault;
  sequence<WebPrintingResolution> printerResolutionSupported;

  WebPrintColorMode printColorModeDefault;
  sequence<WebPrintColorMode> printColorModeSupported;

  WebPrinterState printerState;
  USVString printerStateMessage;
  sequence<WebPrinterStateReason> printerStateReasons;

  WebPrintQuality printQualityDefault;
  sequence<WebPrintQuality> printQualitySupported;

  WebPrintingSides sidesDefault;
  sequence<WebPrintingSides> sidesSupported;
};

dictionary WebPrintJobTemplateAttributes {
  unsigned long copies;

  WebPrintingMediaCollectionRequested mediaCol;
  USVString mediaSource;
  WebPrintingMultipleDocumentHandling multipleDocumentHandling;
  WebPrintingOrientationRequested orientationRequested;
  WebPrintingResolution printerResolution;
  WebPrintColorMode printColorMode;
  WebPrintQuality printQuality;
  WebPrintingSides sides;

  AbortSignal signal;
};

dictionary WebPrintingRange {
  unsigned long from;
  unsigned long to;
};

dictionary WebPrintingResolution {
  unsigned long crossFeedDirectionResolution;
  unsigned long feedDirectionResolution;
  WebPrintingResolutionUnits units;
};

typedef (WebPrintingRange or unsigned long) WebPrintingMediaSizeDimension;

dictionary WebPrintingMediaSize {
  WebPrintingMediaSizeDimension yDimension;
  WebPrintingMediaSizeDimension xDimension;
};

dictionary WebPrintingMediaCollection {
  USVString mediaSizeName;
  WebPrintingMediaSize mediaSize;
};

dictionary WebPrintingMediaSizeRequested {
  required unsigned long yDimension;
  required unsigned long xDimension;
};

dictionary WebPrintingMediaCollectionRequested {
  required WebPrintingMediaSizeRequested mediaSize;
};

dictionary WebPrintJobAttributes {
  USVString jobName;
  unsigned long jobPages;
  unsigned long jobPagesCompleted;
  WebPrintJobState jobState;
};

enum WebPrintingMimeMediaType {
  "application/pdf",
};

enum WebPrintingMultipleDocumentHandling {
  "separate-documents-collated-copies",
  "separate-documents-uncollated-copies",
};

enum WebPrintingOrientationRequested {
  "portrait",
  "landscape",
};

enum WebPrintingResolutionUnits {
  "dots-per-inch",
  "dots-per-centimeter",
};

enum WebPrintingSides {
  "one-sided",
  "two-sided-long-edge",
  "two-sided-short-edge",
};

enum WebPrintQuality {
  "draft",
  "normal",
  "high",
};

enum WebPrintColorMode {
  "color",
  "monochrome",
};

enum WebPrinterState {
  "idle",
  "processing",
  "stopped",
};

enum WebPrinterStateReason {
  "none",
  "other",
  "connecting-to-device",
  "cover-open",
  "developer-empty",
  "developer-low",
  "door-open",
  "fuser-over-temp",
  "fuser-under-temp",
  "input-tray-missing",
  "interlock-open",
  "interpreter-resource-unavailable",
  "marker-supply-empty",
  "marker-supply-low",
  "marker-waste-almost-full",
  "marker-waste-full",
  "media-empty",
  "media-jam",
  "media-low",
  "media-needed",
  "moving-to-paused",
  "opc-life-over",
  "opc-near-eol",
  "output-area-almost-full",
  "output-area-full",
  "output-tray-missing",
  "paused",
  "shutdown",
  "spool-area-full",
  "stopped-partly",
  "stopping",
  "timed-out",
  "toner-empty",
  "toner-low",
  "cups-pki-expired",
};

enum WebPrintJobState {
  "preliminary",
  "pending",
  "processing",
  "completed",
  "canceled",
  "aborted"
};

8. 개인정보 보호 및 보안 고려 사항

8.1. 잠재적 문제

8.1.1. 핑거프린팅

WebPrinter 객체는 핑거프린팅에 사용될 수 있는 printerName 및 printerId attributes를 노출합니다.

8.1.2. 인쇄 작업 위조

악성 코드 주입은 다음으로 이어질 수 있습니다.

이는 격리된 컨텍스트에서는 절대 발생해서는 안 됩니다.

8.1.3. 감시

애플리케이션은 프린터가 언제 사용 중인지 잠재적으로 관찰할 수 있습니다.

8.2. 완화 요소

IDL은 이 API가 격리된 컨텍스트에서만 노출되도록 요구합니다.

8.2.1. Permissions Policy

이 명세는 문자열 "web-printing"으로 식별되는 정책 제어 기능을 정의합니다. 그 기본 허용 목록은 "self"입니다.

document의 permissions policy는 해당 문서의 모든 콘텐츠가 getPrinters()를 사용할 수 있는지 여부를 결정합니다. 어떤 문서에서든 비활성화된 경우, 해당 문서의 어떤 콘텐츠도 getPrinters()를 사용하도록 허용되지 않습니다.

프린터에 대한 접근은 강력한 기능입니다. 사용자 에이전트는 명시적 권한 없이 웹 애플리케이션이 WebPrinter 객체에 접근할 수 있도록 허용해서는 안 됩니다.

사용자 동의는 특정 origin에 대해 얻어야 합니다. 동의 요청은 getPrinters() 메서드 호출에 의해 트리거되어야 합니다. 사용자 에이전트는 어떤 origin이 접근을 요청하는지 명확히 나타내고 사용자가 충분한 정보를 바탕으로 결정을 내릴 수 있도록 충분한 정보를 제공하는 권한 프롬프트를 표시해야 합니다.

사용자 에이전트는 임시 (예: "이 세션에서만") 권한과 영구 권한 모두에 대한 옵션을 제공해야 합니다. 사용자가 영구 접근을 허용했다는 사실을 잊어버릴 위험을 완화하기 위해, 임시 권한이 기본값이자 더 눈에 띄는 옵션이어야 합니다.

사용자에게는 이 API에 대해 이전에 부여한 모든 권한을 보고 철회할 수 있는 메커니즘이 제공되어야 합니다.

적합성

문서 규약

적합성 요구 사항은 서술적 주장과 RFC 2119 용어의 조합으로 표현됩니다. 이 문서의 규범적 부분에서 핵심 단어 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”은 RFC 2119에 설명된 대로 해석됩니다. 다만 가독성을 위해 이 명세에서는 이러한 단어가 모두 대문자로 표시되지는 않습니다.

이 명세의 모든 텍스트는 규범적입니다. 단, 명시적으로 비규범으로 표시된 섹션, 예제 및 참고는 예외입니다. [RFC2119]

이 명세의 예제는 “예를 들어”라는 말로 도입되거나 class="example"을 사용하여 규범적 텍스트와 구분됩니다. 다음과 같습니다.

이것은 정보 제공용 예제의 예입니다.

정보 제공용 참고는 “참고”라는 말로 시작하며 class="note"를 사용하여 규범적 텍스트와 구분됩니다. 다음과 같습니다.

참고, 이것은 정보 제공용 참고입니다.

색인

이 명세에서 정의한 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FileAPI]
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[ISOLATED-CONTEXTS]
Isolated Contexts. Draft Community Group Report. URL: https://wicg.github.io/isolated-web-apps/isolated-contexts.html
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. URL: https://w3c.github.io/permissions/
[PERMISSIONS-POLICY-1]
Ian Clelland. Permissions Policy. URL: https://w3c.github.io/webappsec-permissions-policy/
[RFC2119]
S. Bradner. RFC에서 요구 수준을 나타내기 위한 핵심 단어. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL 색인

[Exposed=Window, SecureContext, IsolatedContext]
partial interface Window {
  [SameObject] readonly attribute WebPrintingManager printing;
};

[Exposed=Window, SecureContext, IsolatedContext]
interface WebPrintingManager {
  Promise<sequence<WebPrinter>> getPrinters();
};

[Exposed=Window, SecureContext, IsolatedContext]
interface WebPrinter {
  WebPrinterAttributes cachedAttributes();
  Promise<WebPrinterAttributes> fetchAttributes();
  Promise<WebPrintJob> submitPrintJob(
    USVString job_name,
    Blob document_data,
    optional WebPrintJobTemplateAttributes template_attributes = {});
};

[Exposed=Window, SecureContext, IsolatedContext]
interface WebPrintJob : EventTarget {
  WebPrintJobAttributes attributes();
  undefined cancel();

  attribute EventHandler onjobstatechange;
};

dictionary WebPrinterAttributes {
  USVString printerName;
  USVString printerId;

  unsigned long copiesDefault;
  WebPrintingRange copiesSupported;

  WebPrintingMediaCollection mediaColDefault;
  sequence<WebPrintingMediaCollection> mediaColDatabase;

  USVString mediaSourceDefault;
  sequence<USVString> mediaSourceSupported;

  WebPrintingMimeMediaType documentFormatDefault;
  sequence<WebPrintingMimeMediaType> documentFormatSupported;

  WebPrintingMultipleDocumentHandling multipleDocumentHandlingDefault;
  sequence<WebPrintingMultipleDocumentHandling> multipleDocumentHandlingSupported;

  WebPrintingOrientationRequested orientationRequestedDefault;
  sequence<WebPrintingOrientationRequested> orientationRequestedSupported;

  WebPrintingResolution printerResolutionDefault;
  sequence<WebPrintingResolution> printerResolutionSupported;

  WebPrintColorMode printColorModeDefault;
  sequence<WebPrintColorMode> printColorModeSupported;

  WebPrinterState printerState;
  USVString printerStateMessage;
  sequence<WebPrinterStateReason> printerStateReasons;

  WebPrintQuality printQualityDefault;
  sequence<WebPrintQuality> printQualitySupported;

  WebPrintingSides sidesDefault;
  sequence<WebPrintingSides> sidesSupported;
};

dictionary WebPrintJobTemplateAttributes {
  unsigned long copies;

  WebPrintingMediaCollectionRequested mediaCol;
  USVString mediaSource;
  WebPrintingMultipleDocumentHandling multipleDocumentHandling;
  WebPrintingOrientationRequested orientationRequested;
  WebPrintingResolution printerResolution;
  WebPrintColorMode printColorMode;
  WebPrintQuality printQuality;
  WebPrintingSides sides;

  AbortSignal signal;
};

dictionary WebPrintingRange {
  unsigned long from;
  unsigned long to;
};

dictionary WebPrintingResolution {
  unsigned long crossFeedDirectionResolution;
  unsigned long feedDirectionResolution;
  WebPrintingResolutionUnits units;
};

typedef (WebPrintingRange or unsigned long) WebPrintingMediaSizeDimension;

dictionary WebPrintingMediaSize {
  WebPrintingMediaSizeDimension yDimension;
  WebPrintingMediaSizeDimension xDimension;
};

dictionary WebPrintingMediaCollection {
  USVString mediaSizeName;
  WebPrintingMediaSize mediaSize;
};

dictionary WebPrintingMediaSizeRequested {
  required unsigned long yDimension;
  required unsigned long xDimension;
};

dictionary WebPrintingMediaCollectionRequested {
  required WebPrintingMediaSizeRequested mediaSize;
};

dictionary WebPrintJobAttributes {
  USVString jobName;
  unsigned long jobPages;
  unsigned long jobPagesCompleted;
  WebPrintJobState jobState;
};

enum WebPrintingMimeMediaType {
  "application/pdf",
};

enum WebPrintingMultipleDocumentHandling {
  "separate-documents-collated-copies",
  "separate-documents-uncollated-copies",
};

enum WebPrintingOrientationRequested {
  "portrait",
  "landscape",
};

enum WebPrintingResolutionUnits {
  "dots-per-inch",
  "dots-per-centimeter",
};

enum WebPrintingSides {
  "one-sided",
  "two-sided-long-edge",
  "two-sided-short-edge",
};

enum WebPrintQuality {
  "draft",
  "normal",
  "high",
};

enum WebPrintColorMode {
  "color",
  "monochrome",
};

enum WebPrinterState {
  "idle",
  "processing",
  "stopped",
};

enum WebPrinterStateReason {
  "none",
  "other",
  "connecting-to-device",
  "cover-open",
  "developer-empty",
  "developer-low",
  "door-open",
  "fuser-over-temp",
  "fuser-under-temp",
  "input-tray-missing",
  "interlock-open",
  "interpreter-resource-unavailable",
  "marker-supply-empty",
  "marker-supply-low",
  "marker-waste-almost-full",
  "marker-waste-full",
  "media-empty",
  "media-jam",
  "media-low",
  "media-needed",
  "moving-to-paused",
  "opc-life-over",
  "opc-near-eol",
  "output-area-almost-full",
  "output-area-full",
  "output-tray-missing",
  "paused",
  "shutdown",
  "spool-area-full",
  "stopped-partly",
  "stopping",
  "timed-out",
  "toner-empty",
  "toner-low",
  "cups-pki-expired",
};

enum WebPrintJobState {
  "preliminary",
  "pending",
  "processing",
  "completed",
  "canceled",
  "aborted"
};