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);
}
Beispiel #17
0
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())
{
}