Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLEDGE API changes to accommodate <fencedframe> size attribute changes #312

Open
gtanzer opened this issue Jun 7, 2022 · 19 comments
Open

Comments

@gtanzer
Copy link
Contributor

gtanzer commented Jun 7, 2022

Currently, when a fenced frame used for rendering a FLEDGE ad is navigated to a urn:uuid, its content size is frozen based on the <fencedframe> element’s width and height attributes near that time.

We would like to consolidate fenced frame information flow as follows: when a fenced frame is navigated to a urn:uuid, instead of combining information from the urn:uuid mapping and the embedder’s <fencedframe> element attributes, we will get information only from the urn:uuid mapping. Therefore, instead of mapping to a URL, the urn:uuid now maps to a set of attributes which includes a src URL, width, height, etc.

In order to adjust FLEDGE to the fenced frame design changes, the following API changes would be necessary:

  • When declaring the FLEDGE auction config, the publisher must specify an ad size for the auction.
  • When submitting a container ad bid, the bidder must declare a size for its component ads. (details TBD)
@gtanzer
Copy link
Contributor Author

gtanzer commented Jun 7, 2022

A secondary point: if FLEDGE knows the size upfront, it is easier to support templating the size into the render URL, as requested in #311.

@michal-kalisz
Copy link

Hi,

Except #311 is there any other reason for introducing this change?

I was wondering how this change would impact related subjects:

Best regards,
Michal

@gtanzer
Copy link
Contributor Author

gtanzer commented Aug 1, 2022

Hi, sorry for the delay in responding. Thanks for the great questions.

We actually didn’t have #311 in mind when we came up with the changes, but it is a happy coincidence that they make it easier to support.

There are two main motivations for the proposal:

  • First, we feel that too many design decisions specific to FLEDGE are creeping into <fencedframe>, which is intended to serve multiple APIs with different requirements. By making the urn:uuid mappings more flexible, we give consumer APIs (like FLEDGE, SharedStorage, etc.) more control over how they individually use fenced frames, instead of making them use shared restrictions that may not be necessary for their particular use cases. But that requires that the APIs know the intended size when they generate urn:uuid mappings.
  • Second, related to your individual questions: we would like to relax or eliminate the allowed size list, i.e. the size of the ad is frozen to the size specified by the auction config. If the size flows into the k-anonymity check, then this becomes possible (otherwise, the embedder can split up k-sized groups using first-party information). In terms of component ads, we are still considering exactly what restrictions make sense, but our goal is to make them as flexible as possible without allowing the k-anonymity requirements to be circumvented. So, for example, it may make sense to say something like “All component ads in the same FF must be the same size, but that size is not restricted to a list. Each ad component is independently subject to a k-anonymity check.” This proposal makes it much easier to enforce properties like this across multiple (nested) fenced frames.

@michal-kalisz
Copy link

Thank you for detailed information, I would like to come back to this topic.

Hi, sorry for the delay in responding. Thanks for the great questions.

We actually didn’t have #311 in mind when we came up with the changes, but it is a happy coincidence that they make it easier to support.

There are two main motivations for the proposal:

  • First, we feel that too many design decisions specific to FLEDGE are creeping into <fencedframe>, which is intended to serve multiple APIs with different requirements. By making the urn:uuid mappings more flexible, we give consumer APIs (like FLEDGE, SharedStorage, etc.) more control over how they individually use fenced frames, instead of making them use shared restrictions that may not be necessary for their particular use cases. But that requires that the APIs know the intended size when they generate urn:uuid mappings.
  • Second, related to your individual questions: we would like to relax or eliminate the allowed size list, i.e. the size of the ad is frozen to the size specified by the auction config. If the size flows into the k-anonymity check, then this becomes possible (otherwise, the embedder can split up k-sized groups using first-party information).

We have recently observed - in our real-publisher experiment - that around 8% of ad slot sizes in the EU are outside of the current allowed size list. And vary between regions.
So, this looks promising, but let’s clarify one thing: when you think about “size flows into the k-anonymity check” do you mean exactly: single value “ad size” or tuple (url, ad size) that must pass k-anonymity?
We need to be careful with how exactly k-anonymity is applied to ads and adComponents. Applying it to a tuple of renderUrl and size will have a significant adverse effect on our ability to display effective ads, especially when it comes to product selection.

In the mentioned solution, size must be well defined. Have you considered where to put this information (maybe as a part of auctionConfig.auctionSignals?)

In terms of component ads, we are still considering exactly what restrictions make sense, but our goal is to make them as flexible as possible without allowing the k-anonymity requirements to be circumvented. So, for example, it may make sense to say something like “All component ads in the same FF must be the same size, but that size is not restricted to a list. Each ad component is independently subject to a k-anonymity check.” This proposal makes it much easier to enforce properties like this across multiple (nested) fenced frames.

I understand the need for a restriction on the size of ad components as a potential source of information transfer between FFs (ad and ad-component).
From our point of view, it is important that the basic visual effects on the banner are possible with the usage of ad components. Example of banner when single component is presented in small and large version.

I was wondering how this could be done without breaking the above assumptions: Maybe instead: “All component ads in the same FF must be the same size” it would be ok to accept two : “All component ads in the same FF can be displayed at most two sizes.”

@WICG WICG deleted a comment Nov 8, 2022
@gtanzer
Copy link
Contributor Author

gtanzer commented Nov 8, 2022

As a reminder, these changes are related to the proposed fenced frame changes here. In brief, we replace the urn:uuid string with a structured WebIDL object (with potentially opaque attributes), and more aspects of the fenced frame are specified by the WebIDL object than before (e.g. size) to consolidate information flow.

We now have a more concrete proposal for size-related API changes for FLEDGE (all of which would be opt-in for a transition period, and then eventually the old behavior would be removed). The API changes are designed so that FLEDGE has the information to prefetch the following modified k-anonymity checks (when the k-anonymity server eventually comes online):

  • The k-anonymity check on the container ad’s URL now also includes the container ad’s size.
  • The k-anonymity check on each component ad’s URL now also includes the component ad’s size.

**Note that size families (e.g., ads that are declared to scale with screen width in a particular aspect ratio) would be counted as a single size in k-anonymity checks.

This change improves the design along the following axes:

  • Privacy: In the old design, there was wiggle room for the publisher to cause observable differences inside the container ad (or for the container ad to cause them inside its component ads), splitting up k-sized groups based on first-party or third-party data. In the new design, we close this gap by running the k-anonymity check on the totality of information that flows from the embedder into the fenced frame.
  • Flexibility: Due to the privacy improvements above, we no longer need to stipulate a list of allowed ad sizes.
  • Performance: Due to the privacy improvements above (and FLEDGE knowing about ad sizes), we can now support slot size macro replacement in the render url, as requested here, saving a round trip for responsive ads.

The one potential downside is of course that given a fixed k-anonymity threshold, responsive ads displayed at multiple sizes that were collectively close to the threshold before the changes may now be below the threshold. But because the k-anonymity threshold hasn’t yet been decided, it doesn’t make sense to treat it as fixed: when it is determined, it will be taking all the privacy and utility factors at that time into account.

Here is a full list of the API changes, roughly in decreasing order of significance:

  • generateBid()
    • We update the render and adComponents fields to use dictionaries rather than urls, where each dictionary contains a url and a size. This size is the size that the ad creative will see inside its fenced frame once it is loaded (and in URL macro substitution, and in the k-anonymity check).
Current
generateBid(...) {
    ...
    return {...,
            'render': renderUrl,
            'adComponents': [adComponent1, adComponent2, ...]};
}
New
generateBid(...) {
    ...
    return {...,
            'render': {url: renderUrl, size: {width: renderWidth, height: renderHeight}},
            'adComponents': [{url: adComponent1, size: {width: componentWidth1, height: componentHeight1}},
                             {url: adComponent2, size: {width: componentWidth2, height: componentHeight2}}, ...]
};
  • joinAdInterestGroup()
    • We update the interest group declaration syntax to support declaring what sizes each ad (and components) could possibly take on. This is necessary to prefetch the k-anonymity checks.
Current
const myGroup = {
    ...
    'ads': [shoesAd1, shoesAd2, shoesAd3],
    'adComponents': [runningShoes1, runningShoes2, gymShoes, gymTrainers1, gymTrainers2],
};
const joinPromise = navigator.joinAdInterestGroup(myGroup, 30 * kSecsPerDay);

New

The interest group owner needs to declare the sizes available for each ad and for each component ad.

There are two types introduced here:

  • Sizes
  • Size groups

A size can be coerced as a size group with one element.

const myGroup = {
    ...
    'ads': [{url: shoesAd1, sizeGroup: 'size1'},
             {url: shoesAd2, sizeGroup: 'size2'},
             {url: shoesAd3, sizeGroup: 'group1'}],
    'adComponents': [{url: runningShoes1, sizeGroup: 'group2'},
                     {url: runningShoes2, sizeGroup: 'group2'},
                     {url: gymShoes, sizeGroup: 'group2'},
                     {url: gymTrainers1, sizeGroup: 'size4'},
                     {url: gymTrainers2, sizeGroup: 'size4'}],
    'adSizes': {'size1': {width: width1, height: height1},
                'size2': {width: width2, height: height2},
                'size3': {width: width3, height: height3},
                'size4': {width: width4, height: height4}},
    'sizeGroups': {'group1': ['size1', 'size2', 'size3'],
                   'group2': ['size3', 'size4']},
};

const joinPromise = navigator.joinAdInterestGroup(myGroup, 30 * kSecsPerDay);
  • URL macro replacement
    • We add the render url macros {%AD_WIDTH%} and {%AD_HEIGHT%} for both container and component ads, in order to avoid a round trip to report the loaded frame size from JS.
  • runAdAuction()
    • We add a new field requestedSize to the auction config object. This field is strictly optional, and is a convenience feature so that the fenced frame may automatically inherit its outer container size from the returned WebIDL config object. If the winning bid’s size doesn’t match the requested size, the winning size will visually scale to fit inside of the requested size, but the publisher will not be aware of the winning size (and the ad creative will not be aware of the requested size).
New
const myAuctionConfig = {
    ...
    'requestedSize': {width: 100, height: 200},
};

const auctionResultPromise = navigator.runAdAuction(myAuctionConfig);

  • scoreAd(), reportResult(), reportWin()
    • We add a new field renderSize to the browser signals object.

@gtanzer
Copy link
Contributor Author

gtanzer commented Nov 8, 2022

@michal-kalisz Please see the update to the proposal, which we just posted above.

Re the 8% of sizes not currently supported, we’re glad to hear that the increased flexibility here would be helpful.

Re the k-anonymity check, yes, we do mean the tuple (url, size). We’re very interested to hear more about the “significant adverse effect” you mentioned. Is there a particular limit/value of k that you’re thinking about? Is the effect different for top-level ads vs. components?

Re component ad sizes, the new version of the proposal is more flexible than previously described. (Each component in the same ad can have a different size.) The way you could implement that carousel ad would be something like:

adComponents: [('ad.com/component1', smallSize), ('ad.com/component1', largeSize), ('ad.com/component2', smallSize), ('http://ad.com/component2', largeSize), …]

We plan to discuss this proposal in the FLEDGE WICG meeting tomorrow.

@fhoering
Copy link
Contributor

@gtanzer Thanks for the proposal. It looks good from my point of view. It would reduce the exposure of full responsive ads because of the k-anonymity constraint, as 10 different creatives would reduce the number of exposed users by 10.
But in exchange it opens the way for static creatives like images and it also allows server side creative generation without the network round trip. So up to the bidder to distribute the ads in the right way. We will check if this meets the clients constraints for creatives on our side.

aarongable pushed a commit to chromium/chromium that referenced this issue Feb 6, 2023
This CL adds 2 new size-related fields to joinAdInterestGroup:
- adSizes: a dictionary that maps size names to a dictionary containing
a width and height string. The width and height are expected to be
in the format "##units". Acceptable values include "10px" and "200sw".
The values must be > 0. Disallowed values include "-20px" and "0sw".
- sizeGroups: a dictionary that maps group names to a list of size names

This adds database support for this fields as well as parsing the fields
and passing them over mojo. Right now, the field has no effect when
running auctions.

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Fuchsia-Binary-Size: Size increase is unavoidable due to new Mojo types.
Binary-Size: Size increase is unavoidable due to new Mojo types.
Change-Id: I32f1fbb11988793172e7dbbbc50fbd9f86827ab3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4167800
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Russ Hamilton <[email protected]>
Reviewed-by: Caleb Raitto <[email protected]>
Commit-Queue: Liam Brady <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1101466}
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 2, 2023
This CL is a first step to add size fields to the return value of
generateBid().

In https://crrev.com/c/4167800, blink::InterestGroup::Size is
introduced for adding sizes to joinAdInterestGroup(). It is declared
as a nested struct inside blink::InterestGroup.

When working on adding size fields to the return value of
generateBid(), we should reuse this Size struct, instead of
creating a new one, for BidderWorkletBid. The way it being declared
as a nested struct have a few drawbacks:
1. This struct seems to serve InterestGroup only at first glance,
   but it will be used to represent general size info for various
   FLEDGE APIs soon: runAdAuction(), scoreAd(), reportResult() and
   reportWin().
2. Clients that only need the size struct's declaration must include
   interest_group.h entirely.
3. Cannot be forward declared.

This CL decouples the nested blink::InterestGroup::Size, to a
standalone struct blink::AdSize.

Some minor notes:
1. Update Size's operator== to compare units as well.
2. Although the struct traits for Size was defined in the related
   CL, the type was not mapped because no mapping was specified
   the BUILD.gn. This CL added the type mapping. This will later
   be used in the follow-up CL on generateBid().
3. Added unit tests for Size.

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Bug: http://b/239866637

Related CL on adding sizes to joinAdInterestGroup():
https://crrev.com/c/4167800

Change-Id: I4a4dd47607102599bbeb33d05aa1ca5e6928ec5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4296777
Commit-Queue: Xiaochen Zhou <[email protected]>
Reviewed-by: Dominic Farolino <[email protected]>
Reviewed-by: Russ Hamilton <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1112228}
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 7, 2023
Adds optional size field to generateBid()'s render and adComponents
fields. The old behavior still works.

For example:
1. render: "example.test"
2. render: {url: "example.test"}
3. render: {url: "example.test",
            width: "100sw",
            height: "50px"}

1. adComponents: ["example.test/1", "example.test/2"]
2. adComponents: [{url: "example.test/1"},
                  {url: "example.test/2"}]
3. adComponents: [
                   {
                     url: "example.test/1",
                     width: "10sw",
                     height: "5px"
                   },
                   {
                     url: "example.test/2",
                     width: "10sw",
                     height: "5px"
                   },
                   "example.test/3"
                 ]

0. Currently these size fields have no effect on the result of
   generateBid() and runAdAuction(). All existing behaviors continue
   to work.

1. A new mojom type is introduced and type mapped to its blink
   representation: blink.mojom.AdDescriptor --> blink::AdDescriptor

2. BidderWorkletBid and content::InterestGroupAuction::Bid are
   updated to store the size info along with the ad url, using the
   structs above.

   See bidder_worklet.mojom and interest_group_auction.h.

3. As the type of 'render_url' and 'ad_components' changed from
   'GURL' to 'blink::AdDescriptor', many functions' signatures
   are updated.

4. The parsing codes in set_bid_binding.cc to parse the new formats
   of the return value of generateBid().

5. Added unit tests to bidder_worklet_unittest.cc.

6. We have not yet decided how to handle the size info at fenced
   frame config side, added TODO: crbug.com/1420638.

7. Marco substitutions, the logics of verifying sizes from interest
   group v.s sizes from bid, and more browser tests will be added in
   follow-up CLs.

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

http://b/239866637

Decouple nested blink::InterestGroup::Size:
https://crrev.com/c/4296777

Change-Id: I0b03f2ee70cf3c2b5ae20c89064767f5d9185060
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4301312
Reviewed-by: danakj <[email protected]>
Reviewed-by: Russ Hamilton <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Commit-Queue: Xiaochen Zhou <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1113941}
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 16, 2023
In https://crrev.com/c/4167800, these mappings are added:
1. size groups --> ad size names
2. ad size names --> blink::AdSize

This CL adds the mapping: ad --> size group

Note:
1. FindMatchingAd is updated. Two ads are considered matching if:
  a. They have the same url, and neither has any size specified.
  b. They have the same url, and both have the same size specified.

2. Updated IDL, serialize/deserialize implementations, copy from IDL
   functions and InterestGroupAd mojom/mojom traits.

3. Added the builder pattern setters for ad size and size groups.
4. Added unit tests and browser tests.
5. The next CL will implement the macro substitution of sizes into
   the mapped url in fenced frame mapping, when auction is completed.

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Bug: http://b/239866637

Related CL on adding sizes to joinAdInterestGroup():
https://crrev.com/c/4167800

Decouple nested blink::InterestGroup::Size:
https://crrev.com/c/4296777

Change-Id: I224c7285234e72ff5a7633b15c5ba256e43ef143
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4321037
Reviewed-by: Russ Hamilton <[email protected]>
Reviewed-by: Liam Brady <[email protected]>
Reviewed-by: Dominic Farolino <[email protected]>
Commit-Queue: Xiaochen Zhou <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1118329}
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 20, 2023
This CL implements the macro substitution for sizes. For example,
assume the interest group ad and the bid both specify the ad having
width of 100px and height of 50px:
Before substitution: https://ad&size={%AD_WIDTH%}x{%AD_HEIGHT%}
After substitution:  https://ad&size=100x50

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Change-Id: I92fb2f4f3edd55b4f2374e95ed8bafd5a98fe5a2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4327282
Commit-Queue: Xiaochen Zhou <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Russ Hamilton <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1119375}
aarongable pushed a commit to chromium/chromium that referenced this issue Apr 5, 2023
Now with FLEDGE auction able to be run with size specified for ad in
interest groups and bids, the winning ad may contain size info.

This CL propagates the size from the winning bid to the fenced frame
config. With this, fenced frame navigations using configs should render
an ad according to the size in the config object.

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Bug: 1347953
Change-Id: I436c9a989cd941ef3788fb7abe0c960945fc4abf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4356285
Reviewed-by: Nasko Oskov <[email protected]>
Commit-Queue: Xiaochen Zhou <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1126568}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Apr 27, 2023
size.

Currently, for generateBid() and joinAdInterestGroup(), the supported
ad size units are
* "px": pixel
* "sw": screen width

This CL adds the unit:
* "sh": screen height

The parser is also updated to support parsing pure numbers as pixels.
For example, "100" is parsed as 100 pixels.

A regular expression is used to match the input, and capture the
sub-patterns for value and unit.
^\s*((?:0|(?:[1-9][0-9]*))(?:\.[0-9]+)?)(px|sw|sh)?\s*$

It basically means we match
1. Zero or more leading spaces.
2. Numbers, with optionally decimal point and digits. No leading space, cannot begin with zero, non-negative. (Sub-pattern captured)
3. Immediately followed by an unit which can be one of "px", "sw" or "sh", or the unit can be ignored entirely.
entirely. (Sub-pattern captured)
4. Zero or more trailing spaces.

Bug: http://b/239866637

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Change-Id: I336055ff3dd635dcdfd78999d0cb5972569f5ac1
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Apr 28, 2023
size.

Currently, for generateBid() and joinAdInterestGroup(), the supported
ad size units are
* "px": pixel
* "sw": screen width

This CL adds the unit:
* "sh": screen height

The parser is also updated to support parsing pure numbers as pixels.
For example, "100" is parsed as 100 pixels.

A regular expression is used to match the input, and capture the
sub-patterns for value and unit.
^\s*((?:0|(?:[1-9][0-9]*))(?:\.[0-9]+)?)(px|sw|sh)?\s*$

It basically means we match
1. Zero or more leading spaces.
2. Numbers, with optionally decimal point and digits. No leading space, cannot begin with zero, non-negative. (Sub-pattern captured)
3. Immediately followed by an unit which can be one of "px", "sw" or "sh", or the unit can be ignored entirely.
entirely. (Sub-pattern captured)
4. Zero or more trailing spaces.

Bug: http://b/239866637

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Change-Id: I336055ff3dd635dcdfd78999d0cb5972569f5ac1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4402817
Commit-Queue: Xiaochen Zhou <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1137102}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Apr 28, 2023
size.

Currently, for generateBid() and joinAdInterestGroup(), the supported
ad size units are
* "px": pixel
* "sw": screen width

This CL adds the unit:
* "sh": screen height

The parser is also updated to support parsing pure numbers as pixels.
For example, "100" is parsed as 100 pixels.

A regular expression is used to match the input, and capture the
sub-patterns for value and unit.
^\s*((?:0|(?:[1-9][0-9]*))(?:\.[0-9]+)?)(px|sw|sh)?\s*$

It basically means we match
1. Zero or more leading spaces.
2. Numbers, with optionally decimal point and digits. No leading space, cannot begin with zero, non-negative. (Sub-pattern captured)
3. Immediately followed by an unit which can be one of "px", "sw" or "sh", or the unit can be ignored entirely.
entirely. (Sub-pattern captured)
4. Zero or more trailing spaces.

Bug: http://b/239866637

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Change-Id: I336055ff3dd635dcdfd78999d0cb5972569f5ac1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4402817
Commit-Queue: Xiaochen Zhou <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1137102}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue May 22, 2023
… pure numbers input for ad size., a=testonly

Automatic update from web-platform-tests
FLEDGE: Enable screen height as unit and pure numbers input for ad
size.

Currently, for generateBid() and joinAdInterestGroup(), the supported
ad size units are
* "px": pixel
* "sw": screen width

This CL adds the unit:
* "sh": screen height

The parser is also updated to support parsing pure numbers as pixels.
For example, "100" is parsed as 100 pixels.

A regular expression is used to match the input, and capture the
sub-patterns for value and unit.
^\s*((?:0|(?:[1-9][0-9]*))(?:\.[0-9]+)?)(px|sw|sh)?\s*$

It basically means we match
1. Zero or more leading spaces.
2. Numbers, with optionally decimal point and digits. No leading space, cannot begin with zero, non-negative. (Sub-pattern captured)
3. Immediately followed by an unit which can be one of "px", "sw" or "sh", or the unit can be ignored entirely.
entirely. (Sub-pattern captured)
4. Zero or more trailing spaces.

Bug: http://b/239866637

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Change-Id: I336055ff3dd635dcdfd78999d0cb5972569f5ac1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4402817
Commit-Queue: Xiaochen Zhou <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1137102}

--

wpt-commits: 673c0db073476e169caf04637dd900ea56ce08ce
wpt-pr: 39730
ErichDonGubler pushed a commit to ErichDonGubler/firefox that referenced this issue May 23, 2023
… pure numbers input for ad size., a=testonly

Automatic update from web-platform-tests
FLEDGE: Enable screen height as unit and pure numbers input for ad
size.

Currently, for generateBid() and joinAdInterestGroup(), the supported
ad size units are
* "px": pixel
* "sw": screen width

This CL adds the unit:
* "sh": screen height

The parser is also updated to support parsing pure numbers as pixels.
For example, "100" is parsed as 100 pixels.

A regular expression is used to match the input, and capture the
sub-patterns for value and unit.
^\s*((?:0|(?:[1-9][0-9]*))(?:\.[0-9]+)?)(px|sw|sh)?\s*$

It basically means we match
1. Zero or more leading spaces.
2. Numbers, with optionally decimal point and digits. No leading space, cannot begin with zero, non-negative. (Sub-pattern captured)
3. Immediately followed by an unit which can be one of "px", "sw" or "sh", or the unit can be ignored entirely.
entirely. (Sub-pattern captured)
4. Zero or more trailing spaces.

Bug: http://b/239866637

See Turtledove issue: WICG/turtledove#312
See Turtledove PR: WICG/turtledove#417

Change-Id: I336055ff3dd635dcdfd78999d0cb5972569f5ac1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4402817
Commit-Queue: Xiaochen Zhou <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1137102}

--

wpt-commits: 673c0db073476e169caf04637dd900ea56ce08ce
wpt-pr: 39730
@eroncastro
Copy link

Hi @gtanzer, thanks for all your previous clarifications.

We are running an auction with the following config

  const result = await navigator.runAdAuction({
    seller: "https://localhost:8443",
    decisionLogicUrl: "https://localhost:8443/td/seller.js",
    interestGroupBuyers: ["https://localhost:8444"],
    auctionSignals: {
      ad: {
        size: {
          width: 970,
          height: 250,
        },
      },
    },
    resolveToConfig: true,
    requestedSize: { width: 970, height: 250 },
  });

However, the FencedFrameConfig is always returned as FencedFrameConfig { width: null, height null }.
What config are we missing?

@dmdabbs
Copy link
Contributor

dmdabbs commented Feb 13, 2024

@eroncastro, was there a resolution to this?

@gtanzer
Copy link
Contributor Author

gtanzer commented Feb 13, 2024

Inspecting the width and height fields on the returned FencedFrameConfig is currently nonfunctional. (We added nonfunctional stubs at some point and forgot to remove them before launch...)

The config does have the container size and content size inside of it though. If you load the config inside of a fenced frame, it should automatically inherit the container size from inside the config.

@dmdabbs
Copy link
Contributor

dmdabbs commented Feb 14, 2024

Thank you Garrett.
I asked because I decided to fiddle with the required-no-earlier-than-2025 declaring size info with a bid, paired with both flavors of the the ad_width and ad_height macros. I tried both (conflicting) ways mentioned in the explainer, neither of which resulted in macro replacements:

return {'ad': adObject,
          'adCost': optionalAdCost,
          'bid': bidValue,
          'bidCurrency': 'USD',
          'render': {url: renderURL, width: renderWidth, height: renderHeight},

as well as

render: A dictionary describing the creative that should be rendered if this bid wins the auction. This includes:

url: The creative's URL.
size: A dictionary containing width and height fields, describing the creative's size (see the interest group declaration above).
When the ad is loaded in a fenced frame, the fenced frame's inner frame (i.e. the size visible to the ad creative) will be frozen to >this size, and it will be unable to see changes to the frame size made by the embedder.

@dmdabbs
Copy link
Contributor

dmdabbs commented Feb 21, 2024

Hello @gtanzer. In today's WICG call, the Chrome team suggested I connect with you here. To boil it down, how does one get Chrome to replace the AD_WIDTH & HEIGHT macros after having submitted size metadata with the winning bid when rendering in an iframe?

@gtanzer
Copy link
Contributor Author

gtanzer commented Feb 21, 2024

@dmdabbs These are our tests for ad size macroing, though they may be hard to read:
https://source.chromium.org/chromium/chromium/src/+/main:content/browser/interest_group/interest_group_browsertest.cc;l=8810;drc=35406c8d4b7301ede262aeedfc6a63e5e3cf555d
https://source.chromium.org/chromium/chromium/src/+/main:content/browser/interest_group/interest_group_browsertest.cc;l=8862;drc=35406c8d4b7301ede262aeedfc6a63e5e3cf555d

i.e.:

  • in the interest group declaration, you need to have the values {%AD_WIDTH%} or {%AD_HEIGHT%} or ${AD_WIDTH} or ${AD_HEIGHT} in the value of url parameters of the ad url
  • in the interest group declaration, you need to declare the ad size for that ad (in this case probably screen-relative sizes)
  • when returning the bid, you include the width and height fields (as in your example)

then the macroing should automatically happen.

Are you doing all of these steps? (in particular, maybe the size declarations in the interest group?) Are there any console logs? (not sure if we added these for the case where you return a size but it's not declared in the interest group declaration; that seems like something that would be useful for debugging)

@dmdabbs
Copy link
Contributor

dmdabbs commented Feb 21, 2024

Thank you @gtanzer

  • in the interest group declaration, you need to have the values {%AD_WIDTH%} or {%AD_HEIGHT%} or ${AD_WIDTH} or ${AD_HEIGHT} in the value of url parameters of the ad url
  • in the interest group declaration, you need to declare the ad size for that ad (in this case probably screen-relative sizes)
        "adSizes": {
            "300x250": {"width": "300", "height": "250"},
            "728x90": {"width": "728", "height": "90"}
        },
        "sizeGroups": {
            "mr_lb": ["300x250","728x90"]
        },
        "ads": [
            {
                "renderURL": "https://creative.example/r/t/previewer/be54ba10?w={%AD_WIDTH%}&h={%AD_HEIGHT%}&w1=${AD_WIDTH}&h1=${AD_HEIGHT}",
                "sizeGroup": "mr_lb"
            },

when returning the bid, you include the width and height fields (as in your example)

Metadata with the submitted bid...

        return {
            ad: {},            
            bid: winner.bidCPM,
            
            /*
                NB: also tried this (as found in a different explainer example)
                    'render': {'url': renderURL, 'width': renderWidth, 'height': renderHeight},
            */
            render: {'url': winner.renderURL, 'size':{'width': '300', 'height': '250'}},
            
            allowComponentAuction: true          
        };

@gtanzer
Copy link
Contributor Author

gtanzer commented Feb 21, 2024

@dmdabbs Everything looks right to me... when you load the config into a fenced frame, does it freeze to that size? (the window.innerWidth and window.innerHeight upon loading)

and 'render': {'url': renderURL, 'width': renderWidth, 'height': renderHeight} is the correct version.

Is the old version reflected somewhere in the explainer, or just in this issue?

@dmdabbs
Copy link
Contributor

dmdabbs commented Feb 22, 2024

@dmdabbs Everything looks right to me... when you load the config into a fenced frame, does it freeze to that size?

No, @gtanzer. When I switch from iframe to fencedframe (opaque-ads or not), the auction produces a winner and Chrome navigates, but macros still not replaced.

image

https://sp-ao.shortpixel.ai/client/to_webp,q_glossy,ret_img,w_300/https://blog.snappa.com/wp-content/uploads/2023/08/medium-ad-example-300x250.jpg?w={%AD_WIDTH%}&h={%AD_HEIGHT%}&w1=${AD_WIDTH}&h1=${AD_HEIGHT}

¯\(ツ)

Is the old version reflected somewhere in the explainer, or just in this issue?

Yes. This explanatory text describes a sub-dictionary named size:

render: A dictionary describing the creative that should be rendered if this bid wins the auction. This includes:

url: The creative's URL.
size: A dictionary containing width and height fields, describing the creative's size (see the interest group declaration above). When the ad is loaded in a fenced frame, the fenced frame's inner frame (i.e. the size visible to the ad creative) will be frozen to this size, and it will be unable to see changes to the frame size made by the embedder.

@gtanzer
Copy link
Contributor Author

gtanzer commented Feb 22, 2024

@dmdabbs Hmm... Do you have a website I could access that runs this code? I can step through with debug Chrome and see what's going wrong. This probably indicates there are failure cases where we need more console logs...

And thanks, will fix that outdated reference in the explainer.

@dmdabbs
Copy link
Contributor

dmdabbs commented Feb 22, 2024

(facepalm)
I thought that I had reverted the size dictionary style, but had not.
Amending to

            render: {'url': winner.render_url, 'width': '300', 'height': '250'},

fixed it. Both iframe and FFs ad size macro substitutions now work as advertised.

And thanks, will fix that outdated reference in the explainer.

YW. Clearer docs raise all boats.

@gtanzer
Copy link
Contributor Author

gtanzer commented Feb 22, 2024

@dmdabbs Glad the issue is resolved! We should probably log if you pass in unrecognized fields...

Created a PR for the explainer fix here: #1049

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants