static bool transform3dMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { UseCounter::count(mediaValues.document(), UseCounter::PrefixedTransform3dMediaFeature); bool returnValueIfNoParameter; int have3dRendering; bool threeDEnabled = mediaValues.threeDEnabled(); returnValueIfNoParameter = threeDEnabled; have3dRendering = threeDEnabled ? 1 : 0; if (value.isValid()) { float number; return numberValue(value, number) && compareValue(have3dRendering, static_cast<int>(number), op); } return returnValueIfNoParameter; }
static bool colorMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { float number; int bitsPerComponent = mediaValues.colorBitsPerComponent(); if (value.isValid()) return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op); return bitsPerComponent != 0; }
static bool deviceWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { if (value.isValid()) return computeLengthAndCompare(value, op, mediaValues, mediaValues.deviceWidth()); // ({,min-,max-}device-width) // assume if we have a device, assume non-zero return true; }
static bool heightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { int height = mediaValues.viewportHeight(); if (value.isValid()) { int length; return computeLength(value, mediaValues, length) && compareValue(height, length, op); } return height; }
static bool widthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { int width = mediaValues.viewportWidth(); if (value.isValid()) { int length; return computeLength(value, mediaValues, length) && compareValue(width, length, op); } return width; }
static bool monochromeMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { if (!mediaValues.monochromeBitsPerComponent()) { if (value.isValid()) { float number; return numberValue(value, number) && compareValue(0, static_cast<int>(number), op); } return false; } return colorMediaFeatureEval(value, op, mediaValues); }
static bool pointerMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { PointerType pointer = mediaValues.primaryPointerType(); if (!value.isValid()) return pointer != PointerTypeNone; if (!value.isID) return false; return (pointer == PointerTypeNone && value.id == CSSValueNone) || (pointer == PointerTypeCoarse && value.id == CSSValueCoarse) || (pointer == PointerTypeFine && value.id == CSSValueFine); }
static bool hoverMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { HoverType hover = mediaValues.primaryHoverType(); if (!value.isValid()) return hover != HoverTypeNone; if (!value.isID) return false; return (hover == HoverTypeNone && value.id == CSSValueNone) || (hover == HoverTypeOnDemand && value.id == CSSValueOnDemand) || (hover == HoverTypeHover && value.id == CSSValueHover); }
static bool scanMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { if (!mediaValues.scanMediaType()) return false; if (!value.isValid()) return true; if (!value.isID) return false; // If a platform interface supplies progressive/interlace info for TVs in the // future, it needs to be handled here. For now, assume a modern TV with // progressive display. return (value.id == CSSValueProgressive); }
static bool displayModeMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { if (!value.isID) return false; WebDisplayMode mode = mediaValues.displayMode(); switch (value.id) { case CSSValueFullscreen: return mode == WebDisplayModeFullscreen; case CSSValueStandalone: return mode == WebDisplayModeStandalone; case CSSValueMinimalUi: return mode == WebDisplayModeMinimalUi; case CSSValueBrowser: return mode == WebDisplayModeBrowser; default: ASSERT_NOT_REACHED(); return false; } }
static bool pointerMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { MediaValues::PointerDeviceType pointer = mediaValues.pointer(); // If we're on a port that hasn't explicitly opted into providing pointer device information // (or otherwise can't be confident in the pointer hardware available), then behave exactly // as if this feature feature isn't supported. if (pointer == MediaValues::UnknownPointer) return false; if (!value.isValid()) return pointer != MediaValues::NoPointer; if (!value.isID) return false; return (pointer == MediaValues::NoPointer && value.id == CSSValueNone) || (pointer == MediaValues::TouchPointer && value.id == CSSValueCoarse) || (pointer == MediaValues::MousePointer && value.id == CSSValueFine); }
static bool hoverMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { MediaValues::PointerDeviceType pointer = mediaValues.pointer(); // If we're on a port that hasn't explicitly opted into providing pointer device information // (or otherwise can't be confident in the pointer hardware available), then behave exactly // as if this feature feature isn't supported. if (pointer == MediaValues::UnknownPointer) return false; float number = 1; if (value.isValid()) { if (!numberValue(value, number)) return false; } return (pointer == MediaValues::NoPointer && !number) || (pointer == MediaValues::TouchPointer && !number) || (pointer == MediaValues::MousePointer && number == 1); }
static bool anyHoverMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { int availableHoverTypes = mediaValues.availableHoverTypes(); if (!value.isValid()) return availableHoverTypes & ~HoverTypeNone; if (!value.isID) return false; switch (value.id) { case CSSValueNone: return availableHoverTypes & HoverTypeNone; case CSSValueOnDemand: return availableHoverTypes & HoverTypeOnDemand; case CSSValueHover: return availableHoverTypes & HoverTypeHover; default: ASSERT_NOT_REACHED(); return false; } }
static bool anyPointerMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { int availablePointers = mediaValues.availablePointerTypes(); if (!value.isValid()) return availablePointers & ~PointerTypeNone; if (!value.isID) return false; switch (value.id) { case CSSValueCoarse: return availablePointers & PointerTypeCoarse; case CSSValueFine: return availablePointers & PointerTypeFine; case CSSValueNone: return availablePointers & PointerTypeNone; default: ASSERT_NOT_REACHED(); return false; } }
MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, const MediaValues& mediaValues) : m_mediaType(acceptedMediaType) , m_expectedResult(false) // Doesn't matter when we have mediaValues. , m_mediaValues(mediaValues.copy()) { }
static bool maxDevicePixelRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues) { UseCounter::count(mediaValues.document(), UseCounter::PrefixedMaxDevicePixelRatioMediaFeature); return devicePixelRatioMediaFeatureEval(value, MaxPrefix, mediaValues); }
static Resource* preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& href, Document& document, const String& as, const String& mimeType, const String& media, CrossOriginAttributeValue crossOrigin, LinkCaller caller, bool& errorOccurred, ViewportDescription* viewportDescription, ReferrerPolicy referrerPolicy) { if (!document.loader() || !relAttribute.isLinkPreload()) return nullptr; UseCounter::count(document, UseCounter::LinkRelPreload); if (!href.isValid() || href.isEmpty()) { document.addConsoleMessage(ConsoleMessage::create( OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an invalid `href` value"))); return nullptr; } if (!media.isEmpty()) { MediaValues* mediaValues = MediaValues::createDynamicIfFrameExists(document.frame()); if (viewportDescription) { mediaValues->overrideViewportDimensions( viewportDescription->maxWidth.getFloatValue(), viewportDescription->maxHeight.getFloatValue()); } // Preload only if media matches MediaQuerySet* mediaQueries = MediaQuerySet::create(media); MediaQueryEvaluator evaluator(*mediaValues); if (!evaluator.eval(mediaQueries)) return nullptr; } if (caller == LinkCalledFromHeader) UseCounter::count(document, UseCounter::LinkHeaderPreload); Resource::Type resourceType; if (!LinkLoader::getResourceTypeFromAsAttribute(as, resourceType)) { document.addConsoleMessage(ConsoleMessage::create( OtherMessageSource, WarningMessageLevel, String("<link rel=preload> must have a valid `as` value"))); errorOccurred = true; return nullptr; } if (!isSupportedType(resourceType, mimeType)) { document.addConsoleMessage(ConsoleMessage::create( OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an unsupported `type` value"))); return nullptr; } ResourceRequest resourceRequest(document.completeURL(href)); ResourceFetcher::determineRequestContext(resourceRequest, resourceType, false); if (referrerPolicy != ReferrerPolicyDefault) { resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( referrerPolicy, href, document.outgoingReferrer())); } FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link, document.encodingName()); if (crossOrigin != CrossOriginAttributeNotSet) { linkRequest.setCrossOriginAccessControl(document.getSecurityOrigin(), crossOrigin); } Settings* settings = document.settings(); if (settings && settings->logPreload()) { document.addConsoleMessage(ConsoleMessage::create( OtherMessageSource, DebugMessageLevel, String("Preload triggered for " + href.host() + href.path()))); } linkRequest.setForPreload(true, monotonicallyIncreasingTime()); linkRequest.setLinkPreload(true); return document.loader()->startPreload(resourceType, linkRequest); }
static bool deviceWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { if (value.isValid()) { int length; return computeLength(value, mediaValues, length) && compareValue(static_cast<int>(mediaValues.deviceWidth()), length, op); } // ({,min-,max-}device-width) // assume if we have a device, assume non-zero return true; }
static bool devicePixelRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { UseCounter::count(mediaValues.document(), UseCounter::PrefixedDevicePixelRatioMediaFeature); return (!value.isValid() || value.unit == CSSPrimitiveValue::CSS_NUMBER) && evalResolution(value, op, mediaValues); }
MediaQueryEvaluator::MediaQueryEvaluator(const MediaValues& mediaValues) : m_expectedResult(false) // Doesn't matter when we have mediaValues. , m_mediaValues(mediaValues.copy()) { }