<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HtmlSanitizer\Reference;

/**
 * Stores reference data from the W3C Sanitizer API standard.
 *
 * @see https://wicg.github.io/sanitizer-api/#default-configuration
 *
 * @author Titouan Galopin <galopintitouan@gmail.com>
 *
 * @internal
 */
final class W3CReference
{
    /**
     * Sanitizer supported contexts.
     *
     * A parent element name can be passed as an argument to {@see HtmlSanitizer::sanitizeFor()}.
     * When doing so, depending on the given context, different elements will be allowed.
     */
    public const CONTEXT_HEAD = 'head';
    public const CONTEXT_BODY = 'body';
    public const CONTEXT_TEXT = 'text';

    // Which context to apply depending on the passed parent element name
    public const CONTEXTS_MAP = [
        'head' => self::CONTEXT_HEAD,
        'textarea' => self::CONTEXT_TEXT,
        'title' => self::CONTEXT_TEXT,
    ];

    /**
     * Elements allowed by the Sanitizer standard in <head> as keys, including whether
     * they are safe or not as values (safe meaning no global display/audio/video impact).
     */
    public const HEAD_ELEMENTS = [
        'head' => true,
        'link' => true,
        'meta' => true,
        'style' => false,
        'title' => true,
    ];

    /**
     * Elements allowed by the Sanitizer standard in <body> as keys, including whether
     * they are safe or not as values (safe meaning no global display/audio/video impact).
     */
    public const BODY_ELEMENTS = [
        'a' => true,
        'abbr' => true,
        'acronym' => true,
        'address' => true,
        'area' => true,
        'article' => true,
        'aside' => true,
        'audio' => true,
        'b' => true,
        'basefont' => true,
        'bdi' => true,
        'bdo' => true,
        'bgsound' => false,
        'big' => true,
        'blockquote' => true,
        'body' => true,
        'br' => true,
        'button' => true,
        'canvas' => true,
        'caption' => true,
        'center' => true,
        'cite' => true,
        'code' => true,
        'col' => true,
        'colgroup' => true,
        'command' => true,
        'data' => true,
        'datalist' => true,
        'dd' => true,
        'del' => true,
        'details' => true,
        'dfn' => true,
        'dialog' => true,
        'dir' => true,
        'div' => true,
        'dl' => true,
        'dt' => true,
        'em' => true,
        'fieldset' => true,
        'figcaption' => true,
        'figure' => true,
        'font' => true,
        'footer' => true,
        'form' => false,
        'h1' => true,
        'h2' => true,
        'h3' => true,
        'h4' => true,
        'h5' => true,
        'h6' => true,
        'header' => true,
        'hgroup' => true,
        'hr' => true,
        'html' => true,
        'i' => true,
        'image' => true,
        'img' => true,
        'input' => false,
        'ins' => true,
        'kbd' => true,
        'keygen' => true,
        'label' => true,
        'layer' => true,
        'legend' => true,
        'li' => true,
        'listing' => true,
        'main' => true,
        'map' => true,
        'mark' => true,
        'marquee' => true,
        'menu' => true,
        'meter' => true,
        'nav' => true,
        'nobr' => true,
        'ol' => true,
        'optgroup' => true,
        'option' => true,
        'output' => true,
        'p' => true,
        'picture' => true,
        'plaintext' => true,
        'popup' => true,
        'portal' => true,
        'pre' => true,
        'progress' => true,
        'q' => true,
        'rb' => true,
        'rp' => true,
        'rt' => true,
        'rtc' => true,
        'ruby' => true,
        's' => true,
        'samp' => true,
        'section' => true,
        'select' => false,
        'selectmenu' => false,
        'slot' => true,
        'small' => true,
        'source' => true,
        'span' => true,
        'strike' => true,
        'strong' => true,
        'sub' => true,
        'summary' => true,
        'sup' => true,
        'table' => true,
        'tbody' => true,
        'td' => true,
        'template' => true,
        'textarea' => false,
        'tfoot' => true,
        'th' => true,
        'thead' => true,
        'time' => true,
        'tr' => true,
        'track' => true,
        'tt' => true,
        'u' => true,
        'ul' => true,
        'var' => true,
        'video' => true,
        'wbr' => true,
        'xmp' => true,
    ];

    /**
     * Attributes allowed by the standard.
     */
    public const ATTRIBUTES = [
        'abbr' => true,
        'accept' => true,
        'accept-charset' => true,
        'accesskey' => true,
        'action' => true,
        'align' => true,
        'alink' => true,
        'allow' => true,
        'allowfullscreen' => true,
        'allowpaymentrequest' => false,
        'alt' => true,
        'anchor' => true,
        'archive' => true,
        'as' => true,
        'async' => false,
        'autocapitalize' => false,
        'autocomplete' => false,
        'autocorrect' => false,
        'autofocus' => false,
        'autopictureinpicture' => false,
        'autoplay' => false,
        'axis' => true,
        'background' => false,
        'behavior' => true,
        'bgcolor' => false,
        'border' => false,
        'bordercolor' => false,
        'capture' => true,
        'cellpadding' => true,
        'cellspacing' => true,
        'challenge' => true,
        'char' => true,
        'charoff' => true,
        'charset' => true,
        'checked' => false,
        'cite' => true,
        'class' => false,
        'classid' => false,
        'clear' => true,
        'code' => true,
        'codebase' => true,
        'codetype' => true,
        'color' => false,
        'cols' => true,
        'colspan' => true,
        'compact' => true,
        'content' => true,
        'contenteditable' => false,
        'controls' => true,
        'controlslist' => true,
        'conversiondestination' => true,
        'coords' => true,
        'crossorigin' => true,
        'csp' => true,
        'data' => true,
        'datetime' => true,
        'declare' => true,
        'decoding' => true,
        'default' => true,
        'defer' => true,
        'dir' => true,
        'direction' => true,
        'dirname' => true,
        'disabled' => true,
        'disablepictureinpicture' => true,
        'disableremoteplayback' => true,
        'disallowdocumentaccess' => true,
        'download' => true,
        'draggable' => true,
        'elementtiming' => true,
        'enctype' => true,
        'end' => true,
        'enterkeyhint' => true,
        'event' => true,
        'exportparts' => true,
        'face' => true,
        'for' => true,
        'form' => false,
        'formaction' => false,
        'formenctype' => false,
        'formmethod' => false,
        'formnovalidate' => false,
        'formtarget' => false,
        'frame' => false,
        'frameborder' => false,
        'headers' => true,
        'height' => true,
        'hidden' => false,
        'high' => true,
        'href' => true,
        'hreflang' => true,
        'hreftranslate' => true,
        'hspace' => true,
        'http-equiv' => false,
        'id' => true,
        'imagesizes' => true,
        'imagesrcset' => true,
        'importance' => true,
        'impressiondata' => true,
        'impressionexpiry' => true,
        'incremental' => true,
        'inert' => true,
        'inputmode' => true,
        'integrity' => true,
        'invisible' => true,
        'is' => true,
        'ismap' => true,
        'keytype' => true,
        'kind' => true,
        'label' => true,
        'lang' => true,
        'language' => true,
        'latencyhint' => true,
        'leftmargin' => true,
        'link' => true,
        'list' => true,
        'loading' => true,
        'longdesc' => true,
        'loop' => true,
        'low' => true,
        'lowsrc' => true,
        'manifest' => true,
        'marginheight' => true,
        'marginwidth' => true,
        'max' => true,
        'maxlength' => true,
        'mayscript' => true,
        'media' => true,
        'method' => true,
        'min' => true,
        'minlength' => true,
        'multiple' => true,
        'muted' => true,
        'name' => true,
        'nohref' => true,
        'nomodule' => true,
        'nonce' => true,
        'noresize' => true,
        'noshade' => true,
        'novalidate' => true,
        'nowrap' => true,
        'object' => true,
        'open' => true,
        'optimum' => true,
        'part' => true,
        'pattern' => true,
        'ping' => false,
        'placeholder' => true,
        'playsinline' => true,
        'policy' => true,
        'poster' => true,
        'preload' => true,
        'pseudo' => true,
        'readonly' => true,
        'referrerpolicy' => true,
        'rel' => true,
        'reportingorigin' => true,
        'required' => true,
        'resources' => true,
        'rev' => true,
        'reversed' => true,
        'role' => true,
        'rows' => true,
        'rowspan' => true,
        'rules' => true,
        'sandbox' => true,
        'scheme' => true,
        'scope' => true,
        'scopes' => true,
        'scrollamount' => true,
        'scrolldelay' => true,
        'scrolling' => true,
        'select' => false,
        'selected' => false,
        'shadowroot' => true,
        'shadowrootdelegatesfocus' => true,
        'shape' => true,
        'size' => true,
        'sizes' => true,
        'slot' => true,
        'span' => true,
        'spellcheck' => true,
        'src' => true,
        // 'srcdoc' => false, // XSS vector if not properly sandboxed, should be enabled explicitly with ->allowAttribute('srcdoc', 'iframe')->forceAttribute('iframe', 'sandbox', '')
        'srclang' => true,
        'srcset' => true,
        'standby' => true,
        'start' => true,
        'step' => true,
        'style' => false,
        'summary' => true,
        'tabindex' => true,
        'target' => true,
        'text' => true,
        'title' => true,
        'topmargin' => true,
        'translate' => true,
        'truespeed' => true,
        'trusttoken' => true,
        'type' => true,
        'usemap' => true,
        'valign' => true,
        'value' => false,
        'valuetype' => true,
        'version' => true,
        'virtualkeyboardpolicy' => true,
        'vlink' => false,
        'vspace' => true,
        'webkitdirectory' => true,
        'width' => true,
        'wrap' => true,
    ];
}
