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

PUC update to include Native Phase 2 spec: #106

Merged
merged 16 commits into from
Jan 13, 2021

Conversation

mmoschovas
Copy link
Contributor

  1. Added renderNativeAd function to nativeTrackerManager.js
  2. renderNativeAd checks for existence of adId and performs the following:
    • Checks for rendererUrl and preloads if exists
    • Uses prexisting loadAssets function with new callback
    • Fires Impression tracker and loads click tracker
  3. LoadAssets update:
    • Checks for existence of assetsToReplace and adds each asset to placeholder
    • If no placeholders exist, checks for requestAllAssets flag to fire new requestAllAssets function
  4. requestAllAssets will postmessage Prebid using the action allAssetRequest instead of assetRequest
  5. Replace assets will now use added logic:
    • If rendererUrl existence. If exists in adServer (preloaded) then check for renderAd availability on the window. If none exists, set load event on the script tag using the id 'pb-native-renderer'. If url sent as asset from Prebid, append script to window and attach load event. When script loaded and renderAd available, fire function to retrieve HTML. This inserted into innerHtml
    • Else if adTemplate exists, replace assets and insert into innerHtml
    • Else run existing replace method
  6. replace function updated to include check for new native to replace keys which are in the format of ##KEY##

nativeAssetManager_spec and nativeTrackerManager_spec both updated to include additional tests

nativeTracker.js updated to include renderNativeAd function definition on window object

1) Added renderNativeAd function to nativeTrackerManager.js
2) renderNativeAd checks for existence of adId and performs the following:
   - Checks for rendererUrl and preloads if exists
   - Uses prexisting loadAssets function with new callback
   - Fires Impression tracker and loads click tracker
3) LoadAssets update:
   - Checks for existence of assetsToReplace and adds each asset to placeholder
   - If no placeholders exist, checks for requestAllAssets flag to fire new requestAllAssets function
4) requestAllAssets will postmessage Prebid using the action allAssetRequest instead of assetRequest
5) Replace assets will now use added logic:
   - If rendererUrl existence. If exists in adServer (preloaded) then check for renderAd availability on the window. If none exists, set load event on the script tag using the id 'pb-native-renderer'. If url sent as asset from Prebid, append script to window and attach load event. When script loaded and renderAd available, fire function to retrieve HTML. This inserted into innerHtml
   - Else if adTemplate exists, replace assets and insert into innerHtml
   - Else run existing replace method
6) replace function updated to include check for new native to replace keys which are in the format of ##KEY##

nativeAssetManager_spec and nativeTrackerManager_spec both updated to include additional tests

nativeTracker.js updated to include renderNativeAd function definition on window object
return {
startTrackers
startTrackers,
renderNativeAd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest move renderNativeAd to a new class instead of add into newNativeTrackerManager. In long run, newNativeTrackerManager.startTrackers will get deprecated. If we separate code renderNativeAd from newNativeTrackerManager now, it will be much easier when that happens.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renderAd code separated into new nativeRenderManager


function fireNativeCallback(){
let parsedUrl = parseUrl(window.pbNativeData.pubUrl);
publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We suppose set publisherDomain value inside renderNativeAd once, instead of set it before each tracker call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected the above to one definition in renderNativeAd as opposed to the tracker definitions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good.

@wqi1972
Copy link
Contributor

wqi1972 commented Jun 24, 2020

I don't see code inside renderNativeAd take care of request for Mobile App as startTrackers does. I don't have experience on native ad for Mobile App, need someone has that experience double check it.

@wqi1972
Copy link
Contributor

wqi1972 commented Jun 24, 2020

We need logic to take care <img class="pb-icon"> and <img class="pb-image"> as https://github.com/prebid/prebid-universal-creative/pull/60/files does.
This way will avoid 400 error message for icon and hero image.

…nderManager. Removed repetitive publisherDomain definitions
Comment on lines 181 to 183
}else if(flag && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) {
callback = cb;
requestAllAssets(adId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we suppose check requestAllAssets first. If it is true, then requestAllAssets. Only when requestAllAssets is not true, then requestAssets for placeholders.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe the use case for this? I would think that if placeholders are detected/defined, then requesting all assets should not be a requirement as the needed assets would be known.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 reasons:

  1. for Use Case 1 - “Render Replacements”, and Use Case 2 - “Ad Template as String”, these 2 use cases both have placementholder token inside html. pbNativeTagData.requestAllAssets = true; will be useless if the code check placementholders exist first;
  2. for Use Case 1 - “Render Replacements”, for html <img class="pb-icon" alt="icon" height="10" width="10">, there suppose have some code which get asset of ##hb_native_icon##, and set src of the image be the value of ##hb_native_icon##. But inside html, there is no placeholder for ##hb_native_icon##, so the asset won't get pulled in existing logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it easier, I will create a PR against your branch, so you will understand what I mean.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately my account can't push commit into git@github.com:mmoschovas/prebid-universal-creative.git repo, even inside the my own branch.
Here is the code change I made, I change function fireNativeCallback() to:

  function fireNativeCallback(){
    const adElements = findAdElements(AD_ANCHOR_CLASS_NAME);
    for (let i = 0; i < adElements.length; i++) {
      adElements[i].addEventListener('click', function(event) {
        loadClickTrackers(event, window.pbNativeData.adId);
      }, true);
    }
    const imgElements = win.document.getElementsByTagName("img");
    for (let i = 0; i < imgElements.length; i++) {
      if (imgElements[i].dataset && imgElements[i].dataset.src) {
        imgElements[i].src = imgElements[i].dataset.src;
      }
    }
  }

with this change, then it will support tag with following format

<img data-src="##hb_native_image##" alt="" />
<img data-src="##hb_native_icon##" alt="logo" />

This will avoid 400 error if we directly set img.src inside html template.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notice, this is a different solution than using <img class="pb-icon">, I think it is better and easier.
And with this solution, it doesn't need pbNativeTagData.requestAllAssets = true; for Use Case 1 - “Render Replacements” anymore, since all asset placementholder exists in GAM template html.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more notice, you need to adjust renderingMocks inside nativeRenderManager_spec.js to

const renderingMocks = {
  getWindowObject: function() {
    return {
      document: {
        getElementsByTagName: function() {
          return [];
        }
      },
      parent: {
        postMessage: sinon.spy()
      }
    }
  }
};

@robertrmartinez
Copy link
Contributor

Hey all, I am setting up some GAM line items today to help make testing local PUC changes easier.

I'll share example test pages once I am done today / tomorrow.

I would like to finalize the native stuff and merge both these for next weeks release!

Thanks again.

@wqi1972
Copy link
Contributor

wqi1972 commented Jul 14, 2020

I've tested on my local with following test cases:

  1. New PBJS + PUC code with existing configure and templates, (using native key/value). Confirmed it is backward compatible;
  2. New PBJS + PUC code + sendTargetingKeys: false + template with macro ##native_##. Confirmed Use Case 1 - “Render Replacements” is working. The only issue the tag temporarily raises 400 error. And with my suggestion provided above, that 400 error will get solved.

Copy link
Contributor

@robertrmartinez robertrmartinez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple minor things.

Want to get the Xander team to do a more in depth review of the rendererUrl use case.

@@ -0,0 +1,16 @@
<!DOCTYPE html>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should not be checked in correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with the .DS_Store binary.

callback && callback();
win.removeEventListener('message', replaceAssets);
if((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) {
if(win.renderAd){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some lint issues (we do not have automatic linter on puc code yet)

Maybe run the entire code on your local with your eslint plugin and do the fixes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

callback && callback();
win.removeEventListener('message', replaceAssets);
if((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) {
if(win.renderAd){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaiminpanchal27 When the rendererUrl is loaded, is the expected output that a renderAd function is placed on the win.

If you could review this use case a little more in depth I would appreciate it since it was spec'd by you.

nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback);
fireNativeCallback();
fireNativeImpTracker(nativeTag.adId);
}else{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some more lint issues

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have a space after closing bracket befor else and after

} else {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just run enable eslint in your editor and see what else there is?

@@ -10,6 +10,7 @@ const AD_DATA_ADID_ATTRIBUTE = 'pbAdId';
export function newNativeTrackerManager(win) {
let publisherDomain;


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra new line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this. I believe I originally added logic that I later removed.

@@ -89,6 +95,58 @@ describe('nativeTrackerManager', function () {
expect(trimPort(postMessageTargetDomain)).to.equal(tagData.pubUrl);
});

/*it('should verify the postMessage for impression trackers was executed', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reasoning behind this being commented out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to remove this test. Originally the new rendering code lived within trackerManager code but it was requested to live in a new class. This was mirrored in the nativeRenderManager_spec test.

@robertrmartinez
Copy link
Contributor

Ok changes look good to me.

Would like @jaiminpanchal27 to do a review before we merge this.

Specifically making sure the Xander proposal of rendererUrl looks good. since they spec'd that part out.

More than happy to set some time or keep an open dialogue if you want @jaiminpanchal27

Thanks all!

@robertrmartinez
Copy link
Contributor

The associated Prebid.js change has been approved and is ready for merge once this has been approved and merged as well:

prebid/Prebid.js#5411

Copy link
Contributor

@robertrmartinez robertrmartinez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

Copy link
Collaborator

@jsnellbaker jsnellbaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mmoschovas
I think the code here looks okay. Can you please remove the .DS_Store file and the package-lock.json updates from the PR though?

@mmoschovas
Copy link
Contributor Author

Removed both updates

Copy link
Contributor

@robertrmartinez robertrmartinez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple minor things

@@ -227,12 +271,45 @@ export function newNativeAssetManager(win) {
}

if (data.message === 'assetResponse') {
const body = win.document.body.innerHTML;
const newHtml = replace(body, data);
const body = win.document.body.innerHTML,flag = (typeof win.pbNativeData !== 'undefined');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you split this flag out to a new declaration please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

win.document.body.innerHTML = newHtml;
callback && callback();
win.removeEventListener('message', replaceAssets);
if (flag && data.adId != win.pbNativeData.adId) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason to use != vs !===?

Do we expect adId to be the same data type in both? Or is is possible one is string and one is number?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope good catch. Updated

nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback);
fireNativeCallback();
fireNativeImpTracker(nativeTag.adId);
}else{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have a space after closing bracket befor else and after

} else {

}

return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could just do

return win.document.body.innerHTML.indexOf(str) !== -1

Not sure this function is even being used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont remember this function but cant find a use for it so removing


if (placeholders.length > 0) {
callback = cb;
requestAssets(adId, placeholders);
}else if (flag && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after closing brackets

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed these. Not sure how they didnt update last time around

nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback);
fireNativeCallback();
fireNativeImpTracker(nativeTag.adId);
}else{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just run enable eslint in your editor and see what else there is?

@bretg
Copy link
Contributor

bretg commented Nov 6, 2020

Docs PR prebid/prebid.github.io#2479

@bretg bretg added LGTM and removed Needs: Docs labels Dec 10, 2020
@jsnellbaker
Copy link
Collaborator

@mmoschovas Can you please take a look at the code conflict in the gulpfile.js? I'm not sure if it's a recent thing, but it needs to be addressed.

Thanks.

@mmoschovas
Copy link
Contributor Author

@jsnellbaker committed merge

@jsnellbaker
Copy link
Collaborator

@mmoschovas Thanks for the updates and for the overall effort behind this PR. Based on side conversations, we are good to merge this PR (finally).

@jsnellbaker jsnellbaker merged commit 647c7d5 into prebid:master Jan 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants