/*
 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "CSSParserContext.h"

#include "CSSImageValue.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "Page.h"
#include "RuntimeEnabledFeatures.h"
#include "Settings.h"
#include <wtf/NeverDestroyed.h>

namespace WebCore {

const CSSParserContext& strictCSSParserContext()
{
    static MainThreadNeverDestroyed<CSSParserContext> strictContext(HTMLStandardMode);
    return strictContext;
}

CSSParserContext::CSSParserContext(CSSParserMode mode, const URL& baseURL)
    : baseURL(baseURL)
    , mode(mode)
{
    // FIXME: We should turn all of the features on from their WebCore Settings defaults.
    if (mode == UASheetMode) {
        individualTransformPropertiesEnabled = true;
        focusVisibleEnabled = true;
        inputSecurityEnabled = true;
        containmentEnabled = true;
#if ENABLE(CSS_TRANSFORM_STYLE_OPTIMIZED_3D)
        transformStyleOptimized3DEnabled = true;
#endif
    }
}

#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
static bool shouldEnableLegacyOverflowScrollingTouch(const Document& document)
{
    // The legacy -webkit-overflow-scrolling: touch behavior may have been disabled through the website policy,
    // in that case we want to disable the legacy behavior regardless of what the setting says.
    if (auto* loader = document.loader()) {
        if (loader->legacyOverflowScrollingTouchPolicy() == LegacyOverflowScrollingTouchPolicy::Disable)
            return false;
    }
    return document.settings().legacyOverflowScrollingTouchEnabled();
}
#endif

CSSParserContext::CSSParserContext(const Document& document, const URL& sheetBaseURL, const String& charset)
    : baseURL { sheetBaseURL.isNull() ? document.baseURL() : sheetBaseURL }
    , charset { charset }
    , mode { document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode }
    , isHTMLDocument { document.isHTMLDocument() }
    , hasDocumentSecurityOrigin { sheetBaseURL.isNull() || document.securityOrigin().canRequest(baseURL) }
    , useSystemAppearance { document.page() ? document.page()->useSystemAppearance() : false }
    , accentColorEnabled { document.settings().accentColorEnabled() }
    , aspectRatioEnabled { document.settings().aspectRatioEnabled() }
    , colorContrastEnabled { document.settings().cssColorContrastEnabled() }
    , colorFilterEnabled { document.settings().colorFilterEnabled() }
    , colorMixEnabled { document.settings().cssColorMixEnabled() }
    , constantPropertiesEnabled { document.settings().constantPropertiesEnabled() }
    , containmentEnabled { document.settings().cssContainmentEnabled() }
    , counterStyleAtRulesEnabled { document.settings().cssCounterStyleAtRulesEnabled() }
    , counterStyleAtRuleImageSymbolsEnabled { document.settings().cssCounterStyleAtRuleImageSymbolsEnabled() }
    , cssColor4 { document.settings().cssColor4() }
    , individualTransformPropertiesEnabled { document.settings().cssIndividualTransformPropertiesEnabled() }
#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
    , legacyOverflowScrollingTouchEnabled { shouldEnableLegacyOverflowScrollingTouch(document) }
#endif
    , overscrollBehaviorEnabled { document.settings().overscrollBehaviorEnabled() }
    , relativeColorSyntaxEnabled { document.settings().cssRelativeColorSyntaxEnabled() }
    , scrollBehaviorEnabled { document.settings().CSSOMViewSmoothScrollingEnabled() }
    , springTimingFunctionEnabled { document.settings().springTimingFunctionEnabled() }
#if ENABLE(TEXT_AUTOSIZING)
    , textAutosizingEnabled { document.settings().textAutosizingEnabled() }
#endif
#if ENABLE(CSS_TRANSFORM_STYLE_OPTIMIZED_3D)
    , transformStyleOptimized3DEnabled { document.settings().cssTransformStyleOptimized3DEnabled() }
#endif
    , useLegacyBackgroundSizeShorthandBehavior { document.settings().useLegacyBackgroundSizeShorthandBehavior() }
    , focusVisibleEnabled { document.settings().focusVisibleEnabled() }
    , hasPseudoClassEnabled { document.settings().hasPseudoClassEnabled() }
    , cascadeLayersEnabled { document.settings().cssCascadeLayersEnabled() }
    , containerQueriesEnabled { document.settings().cssContainerQueriesEnabled() }
    , overflowClipEnabled { document.settings().overflowClipEnabled() }
    , gradientPremultipliedAlphaInterpolationEnabled { document.settings().cssGradientPremultipliedAlphaInterpolationEnabled() }
    , gradientInterpolationColorSpacesEnabled { document.settings().cssGradientInterpolationColorSpacesEnabled() }
    , inputSecurityEnabled { document.settings().cssInputSecurityEnabled() }
    , subgridEnabled { document.settings().subgridEnabled() }
    , containIntrinsicSizeEnabled { document.settings().cssContainIntrinsicSizeEnabled() }
    , motionPathEnabled { document.settings().cssMotionPathEnabled() }
    , cssTextAlignLastEnabled { document.settings().cssTextAlignLastEnabled() }
    , cssTextJustifyEnabled { document.settings().cssTextJustifyEnabled() }
#if ENABLE(ATTACHMENT_ELEMENT)
    , attachmentEnabled { RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() }
#endif
{
}

bool operator==(const CSSParserContext& a, const CSSParserContext& b)
{
    return a.baseURL == b.baseURL
        && a.charset == b.charset
        && a.mode == b.mode
        && a.enclosingRuleType == b.enclosingRuleType
        && a.isHTMLDocument == b.isHTMLDocument
        && a.hasDocumentSecurityOrigin == b.hasDocumentSecurityOrigin
        && a.isContentOpaque == b.isContentOpaque
        && a.useSystemAppearance == b.useSystemAppearance
        && a.accentColorEnabled == b.accentColorEnabled
        && a.aspectRatioEnabled == b.aspectRatioEnabled
        && a.colorContrastEnabled == b.colorContrastEnabled
        && a.colorFilterEnabled == b.colorFilterEnabled
        && a.colorMixEnabled == b.colorMixEnabled
        && a.constantPropertiesEnabled == b.constantPropertiesEnabled
        && a.containmentEnabled == b.containmentEnabled
        && a.counterStyleAtRulesEnabled == b.counterStyleAtRulesEnabled
        && a.counterStyleAtRuleImageSymbolsEnabled == b.counterStyleAtRuleImageSymbolsEnabled
        && a.cssColor4 == b.cssColor4
        && a.individualTransformPropertiesEnabled == b.individualTransformPropertiesEnabled
#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
        && a.legacyOverflowScrollingTouchEnabled == b.legacyOverflowScrollingTouchEnabled
#endif
        && a.overscrollBehaviorEnabled == b.overscrollBehaviorEnabled
        && a.relativeColorSyntaxEnabled == b.relativeColorSyntaxEnabled
        && a.scrollBehaviorEnabled == b.scrollBehaviorEnabled
        && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled
#if ENABLE(TEXT_AUTOSIZING)
        && a.textAutosizingEnabled == b.textAutosizingEnabled
#endif
#if ENABLE(CSS_TRANSFORM_STYLE_OPTIMIZED_3D)
        && a.transformStyleOptimized3DEnabled == b.transformStyleOptimized3DEnabled
#endif
        && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior
        && a.focusVisibleEnabled == b.focusVisibleEnabled
        && a.hasPseudoClassEnabled == b.hasPseudoClassEnabled
        && a.cascadeLayersEnabled == b.cascadeLayersEnabled
        && a.containerQueriesEnabled == b.containerQueriesEnabled
        && a.overflowClipEnabled == b.overflowClipEnabled
        && a.gradientPremultipliedAlphaInterpolationEnabled == b.gradientPremultipliedAlphaInterpolationEnabled
        && a.gradientInterpolationColorSpacesEnabled == b.gradientInterpolationColorSpacesEnabled
        && a.inputSecurityEnabled == b.inputSecurityEnabled
#if ENABLE(ATTACHMENT_ELEMENT)
        && a.attachmentEnabled == b.attachmentEnabled
#endif
        && a.subgridEnabled == b.subgridEnabled
        && a.containIntrinsicSizeEnabled == b.containIntrinsicSizeEnabled
        && a.motionPathEnabled == b.motionPathEnabled
        && a.cssTextAlignLastEnabled == b.cssTextAlignLastEnabled
        && a.cssTextJustifyEnabled == b.cssTextJustifyEnabled
    ;
}

void add(Hasher& hasher, const CSSParserContext& context)
{
    uint64_t bits = context.isHTMLDocument                  << 0
        | context.hasDocumentSecurityOrigin                 << 1
        | context.isContentOpaque                           << 2
        | context.useSystemAppearance                       << 3
        | context.aspectRatioEnabled                        << 4
        | context.colorContrastEnabled                      << 5
        | context.colorFilterEnabled                        << 6
        | context.colorMixEnabled                           << 7
        | context.constantPropertiesEnabled                 << 8
        | context.containmentEnabled                        << 9
        | context.cssColor4                                 << 10
        | context.individualTransformPropertiesEnabled      << 11
#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
        | context.legacyOverflowScrollingTouchEnabled       << 12
#endif
        | context.overscrollBehaviorEnabled                 << 13
        | context.relativeColorSyntaxEnabled                << 14
        | context.scrollBehaviorEnabled                     << 15
        | context.springTimingFunctionEnabled               << 16
#if ENABLE(TEXT_AUTOSIZING)
        | context.textAutosizingEnabled                     << 17
#endif
#if ENABLE(CSS_TRANSFORM_STYLE_OPTIMIZED_3D)
        | context.transformStyleOptimized3DEnabled          << 18
#endif
        | context.useLegacyBackgroundSizeShorthandBehavior  << 19
        | context.focusVisibleEnabled                       << 20
        | context.hasPseudoClassEnabled                     << 21
        | context.cascadeLayersEnabled                      << 22
        | context.containerQueriesEnabled                   << 23
        | context.overflowClipEnabled                       << 24
        | context.gradientPremultipliedAlphaInterpolationEnabled << 25
        | context.gradientInterpolationColorSpacesEnabled   << 27
#if ENABLE(ATTACHMENT_ELEMENT)
        | context.attachmentEnabled                         << 28
#endif
        | context.accentColorEnabled                        << 29
        | context.inputSecurityEnabled                      << 30
        | context.subgridEnabled                            << 31
        | (uint64_t)context.containIntrinsicSizeEnabled     << 32
        | (uint64_t)context.motionPathEnabled               << 33
        | (uint64_t)context.cssTextAlignLastEnabled         << 34
        | (uint64_t)context.cssTextJustifyEnabled           << 35
        | (uint64_t)context.mode                            << 36; // This is multiple bits, so keep it last.

    add(hasher, context.baseURL, context.charset, bits);
}

bool CSSParserContext::isPropertyRuntimeDisabled(CSSPropertyID property) const
{
    switch (property) {
    case CSSPropertyAdditiveSymbols:
    case CSSPropertyFallback:
    case CSSPropertyPad:
    case CSSPropertySymbols:
    case CSSPropertyNegative:
    case CSSPropertyPrefix:
    case CSSPropertyRange:
    case CSSPropertySuffix:
    case CSSPropertySystem:
        return !counterStyleAtRulesEnabled;
    case CSSPropertyAccentColor:
        return !accentColorEnabled;
    case CSSPropertyAspectRatio:
        return !aspectRatioEnabled;
    case CSSPropertyContain:
        return !containmentEnabled;
    case CSSPropertyAppleColorFilter:
        return !colorFilterEnabled;
    case CSSPropertyInputSecurity:
        return !inputSecurityEnabled;
    case CSSPropertyTranslate:
    case CSSPropertyRotate:
    case CSSPropertyScale:
        return !individualTransformPropertiesEnabled;
    case CSSPropertyOverscrollBehavior:
    case CSSPropertyOverscrollBehaviorBlock:
    case CSSPropertyOverscrollBehaviorInline:
    case CSSPropertyOverscrollBehaviorX:
    case CSSPropertyOverscrollBehaviorY:
        return !overscrollBehaviorEnabled;
    case CSSPropertyScrollBehavior:
        return !scrollBehaviorEnabled;
#if ENABLE(TEXT_AUTOSIZING) && !PLATFORM(IOS_FAMILY)
    case CSSPropertyWebkitTextSizeAdjust:
        return !textAutosizingEnabled;
#endif
#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
    case CSSPropertyWebkitOverflowScrolling:
        return !legacyOverflowScrollingTouchEnabled;
#endif
    case CSSPropertyContainIntrinsicSize:
    case CSSPropertyContainIntrinsicHeight:
    case CSSPropertyContainIntrinsicWidth:
    case CSSPropertyContainIntrinsicBlockSize:
    case CSSPropertyContainIntrinsicInlineSize:
        return !containIntrinsicSizeEnabled;
    case CSSPropertyOffset:
    case CSSPropertyOffsetPath:
    case CSSPropertyOffsetDistance:
    case CSSPropertyOffsetPosition:
    case CSSPropertyOffsetAnchor:
    case CSSPropertyOffsetRotate:
        return !motionPathEnabled;
    case CSSPropertyTextAlignLast:
        return !cssTextAlignLastEnabled;
    case CSSPropertyTextJustify:
        return !cssTextJustifyEnabled;
    default:
        return false;
    }
}

ResolvedURL CSSParserContext::completeURL(const String& string) const
{
    auto result = [&] () -> ResolvedURL {
        // See also Document::completeURL(const String&)
        if (string.isNull())
            return { };

        if (CSSValue::isCSSLocalURL(string))
            return { string, URL { string } };

        if (charset.isEmpty())
            return { string, { baseURL, string } };
        auto encodingForURLParsing = PAL::TextEncoding { charset }.encodingForFormSubmissionOrURLParsing();
        return { string, { baseURL, string, encodingForURLParsing == PAL::UTF8Encoding() ? nullptr : &encodingForURLParsing } };
    }();

    if (mode == WebVTTMode && !result.resolvedURL.protocolIsData())
        return { };

    return result;
}

}
