Skip to content

Commit

Permalink
Merge pull request #55 from prebid/master
Browse files Browse the repository at this point in the history
[pull] master from prebid:master
  • Loading branch information
mefjush authored Jul 22, 2024
2 parents 2f72b57 + 115e7c6 commit c81016f
Show file tree
Hide file tree
Showing 238 changed files with 15,186 additions and 12,537 deletions.
36 changes: 31 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ module.exports = {
'no-useless-escape': 'off',
'no-console': 'error',
'jsdoc/check-types': 'off',
'jsdoc/no-defaults': 'off',
'jsdoc/newline-after-description': 'off',
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param': 'off',
Expand All @@ -83,27 +84,52 @@ module.exports = {
files: key + '/**/*.js',
rules: {
'prebid/validate-imports': ['error', allowedModules[key]],
'prebid/no-innerText': ['error', allowedModules[key]],
'no-restricted-globals': [
'error',
{
name: 'require',
message: 'use import instead'
}
],
'prebid/no-global': [
'error',
...['localStorage', 'sessionStorage'].map(name => ({name, message: 'use storageManager instead'})),
{
name: 'XMLHttpRequest',
message: 'use ajax.js instead'
},
],
'prebid/no-member': [
'error',
{
name: 'cookie',
target: 'document',
message: 'use storageManager instead'
},
{
name: 'sendBeacon',
target: 'navigator',
message: 'use ajax.js instead'
},
...['outerText', 'innerText'].map(name => ({
name,
message: 'use .textContent instead'
}))
]
}
})).concat([{
// code in other packages (such as plugins/eslint) is not "seen" by babel and its parser will complain.
files: 'plugins/*/**/*.js',
parser: 'esprima'
},
{
}, {
files: '**BidAdapter.js',
rules: {
'no-restricted-imports': [
'error', {
patterns: ["**/src/events.js",
"**/src/adloader.js"]
patterns: [
'**/src/events.js',
'**/src/adloader.js'
]
}
]
}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/jscpd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,15 @@ jobs:
const filteredReport = JSON.parse(fs.readFileSync('filtered-jscpd-report.json', 'utf8'));
let comment = "Whoa there, partner! 🌵🤠 We wrangled some duplicated code in your PR:\n\n";
function link(dup) {
return `https://github.com/${{ github.event.repository.full_name }}/blob/${{ github.event.pull_request.head.sha }}/${dup.name}#L${dup.start}-L${dup.end - 1}`
return `https://github.com/${{ github.event.repository.full_name }}/blob/${{ github.event.pull_request.head.sha }}/${dup.name}#L${dup.start + 1}-L${dup.end - 1}`
}
filteredReport.forEach(duplication => {
const firstFile = duplication.firstFile;
const secondFile = duplication.secondFile;
const lines = duplication.lines;
comment += `- [\`${firstFile.name}\`](${link(firstFile)}) has ${lines} duplicated lines with [\`${secondFile.name}\`](${link(secondFile)})\n`;
});
comment += "\nReducing code duplication by importing common functions from a library not only makes our code cleaner but also easier to maintain. Please move the common code from both files into a library and import it in each. Keep up the great work! 🚀";
comment += "\nReducing code duplication by importing common functions from a library not only makes our code cleaner but also easier to maintain. Please move the common code from both files into a library and import it in each. We hate that we have to mention this, however, commits designed to hide from this utility by renaming variables or reordering an object are poor conduct. We will not look upon them kindly! Keep up the great work! 🚀";
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
Expand Down
107 changes: 107 additions & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Check for linter warnings / exceptions

on:
pull_request_target:
branches:
- master

jobs:
check-linter:
runs-on: ubuntu-latest

steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.base.sha }}

- name: Fetch base and target branches
run: |
git fetch origin +refs/heads/${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }}
git fetch origin +refs/pull/${{ github.event.pull_request.number }}/merge:refs/remotes/pull/${{ github.event.pull_request.number }}/merge
- name: Install dependencies
run: npm ci

- name: Get the diff
run: git diff --name-only origin/${{ github.event.pull_request.base.ref }}...refs/remotes/pull/${{ github.event.pull_request.number }}/merge | grep '^\(modules\|src\|libraries\|creative\)/.*\.js$' > __changed_files.txt || true

- name: Run linter on base branch
run: npx eslint --no-inline-config --format json $(cat __changed_files.txt | xargs stat --printf '%n\n' 2> /dev/null) > __base.json || true

- name: Check out PR
run: git checkout ${{ github.event.pull_request.head.sha }}

- name: Run linter on PR
run: npx eslint --no-inline-config --format json $(cat __changed_files.txt | xargs stat --printf '%n\n' 2> /dev/null) > __pr.json || true

- name: Compare them and post comment if necessary
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const process = require('process');
function parse(fn) {
return JSON.parse(fs.readFileSync(fn)).reduce((memo, data) => {
const file = path.relative(process.cwd(), data.filePath);
if (!memo.hasOwnProperty(file)) { memo[file] = { errors: 0, warnings: 0} }
data.messages.forEach(({severity}) => {
memo[file][severity > 1 ? 'errors' : 'warnings']++;
});
return memo;
}, {})
}
function mkDiff(old, new_) {
const files = Object.fromEntries(
Object.entries(new_)
.map(([file, {errors, warnings}]) => {
const {errors: oldErrors, warnings: oldWarnings} = old[file] || {};
return [file, {errors: Math.max(0, errors - (oldErrors ?? 0)), warnings: Math.max(0, warnings - (oldWarnings ?? 0))}]
})
.filter(([_, {errors, warnings}]) => errors > 0 || warnings > 0)
)
return Object.values(files).reduce((memo, {warnings, errors}) => {
memo.errors += errors;
memo.warnings += warnings;
return memo;
}, {errors: 0, warnings: 0, files})
}
function mkComment({errors, warnings, files}) {
function pl(noun, number) {
return noun + (number === 1 ? '' : 's')
}
if (errors === 0 && warnings === 0) return;
const summary = [];
if (errors) summary.push(`**${errors}** linter ${pl('error', errors)}`)
if (warnings) summary.push(`**${warnings}** linter ${pl('warning', warnings)}`)
let cm = `Tread carefully! This PR adds ${summary.join(' and ')} (possibly disabled through directives):\n\n`;
Object.entries(files).forEach(([file, {errors, warnings}]) => {
const summary = [];
if (errors) summary.push(`+${errors} ${pl('error', errors)}`);
if (warnings) summary.push(`+${warnings} ${pl('warning', warnings)}`)
cm += ` * \`${file}\` (${summary.join(', ')})\n`
})
return cm;
}
const [base, pr] = ['__base.json', '__pr.json'].map(parse);
const comment = mkComment(mkDiff(base, pr));
if (comment) {
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}
3 changes: 2 additions & 1 deletion creative/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// eslint-disable-next-line prebid/validate-imports
import { AD_RENDER_FAILED_REASON, EVENTS, MESSAGES } from '../src/constants.js';
import {AD_RENDER_FAILED_REASON, EVENTS, MESSAGES} from '../src/constants.js';

export {PB_LOCATOR} from '../src/constants.js';
export const MESSAGE_REQUEST = MESSAGES.REQUEST;
export const MESSAGE_RESPONSE = MESSAGES.RESPONSE;
export const MESSAGE_EVENT = MESSAGES.EVENT;
Expand Down
23 changes: 19 additions & 4 deletions creative/crossDomain.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {
ERROR_EXCEPTION,
EVENT_AD_RENDER_FAILED, EVENT_AD_RENDER_SUCCEEDED,
EVENT_AD_RENDER_FAILED,
EVENT_AD_RENDER_SUCCEEDED,
MESSAGE_EVENT,
MESSAGE_REQUEST,
MESSAGE_RESPONSE
MESSAGE_RESPONSE,
PB_LOCATOR
} from './constants.js';

const mkFrame = (() => {
Expand All @@ -24,14 +26,27 @@ const mkFrame = (() => {
};
})();

function isPrebidWindow(win) {
return !!win.frames[PB_LOCATOR];
}

export function renderer(win) {
let target = win.parent;
try {
while (target !== win.top && !isPrebidWindow(target)) {
target = target.parent;
}
if (!isPrebidWindow(target)) target = win.parent;
} catch (e) {
}

return function ({adId, pubUrl, clickUrl}) {
const pubDomain = new URL(pubUrl, window.location).origin;

function sendMessage(type, payload, responseListener) {
const channel = new MessageChannel();
channel.port1.onmessage = guard(responseListener);
win.parent.postMessage(JSON.stringify(Object.assign({message: type, adId}, payload)), pubDomain, [channel.port2]);
target.postMessage(JSON.stringify(Object.assign({message: type, adId}, payload)), pubDomain, [channel.port2]);
}

function onError(e) {
Expand Down Expand Up @@ -77,7 +92,7 @@ export function renderer(win) {
W.Promise.resolve(W.render(data, {sendMessage, mkFrame}, win)).then(
() => sendMessage(MESSAGE_EVENT, {event: EVENT_AD_RENDER_SUCCEEDED}),
onError
)
);
});
win.document.body.appendChild(renderer);
}
Expand Down
2 changes: 1 addition & 1 deletion integrationExamples/gpt/x-domain/creative.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// creative will be rendered, e.g. GAM delivering a SafeFrame

// this code is autogenerated, also available in 'build/creative/creative.js'
<script>!function(){"use strict";const e="Prebid Event",n=(()=>{const e={frameBorder:0,scrolling:"no",marginHeight:0,marginWidth:0,topMargin:0,leftMargin:0,allowTransparency:"true"};return(n,t)=>{const r=n.createElement("iframe");return Object.entries(Object.assign({},t,e)).forEach((([e,n])=>r.setAttribute(e,n))),r}})();var t;window.pbRender=(t=window,function({adId:r,pubUrl:s,clickUrl:o}){const i=new URL(s,window.location).origin;function a(e,n,s){const o=new MessageChannel;o.port1.onmessage=d(s),t.parent.postMessage(JSON.stringify(Object.assign({message:e,adId:r},n)),i,[o.port2])}function c(n){a(e,{event:"adRenderFailed",info:{reason:n?.reason||"exception",message:n?.message}}),n?.stack&&console.error(n)}function d(e){return function(){try{return e.apply(this,arguments)}catch(e){c(e)}}}a("Prebid Request",{options:{clickUrl:o}},(function(s){let o;try{o=JSON.parse(s.data)}catch(e){return}if("Prebid Response"===o.message&&o.adId===r){const r=n(t.document,{width:0,height:0,style:"display: none",srcdoc:`<script>${o.renderer}<\/script>`});r.onload=d((function(){const s=r.contentWindow;s.Promise.resolve(s.render(o,{sendMessage:a,mkFrame:n},t)).then((()=>a(e,{event:"adRenderSucceeded"})),c)})),t.document.body.appendChild(r)}}))})}();</script>
<script>!function(){"use strict";const e="Prebid Event",n=(()=>{const e={frameBorder:0,scrolling:"no",marginHeight:0,marginWidth:0,topMargin:0,leftMargin:0,allowTransparency:"true"};return(n,t)=>{const r=n.createElement("iframe");return Object.entries(Object.assign({},t,e)).forEach((([e,n])=>r.setAttribute(e,n))),r}})();function t(e){return!!e.frames.__pb_locator__}window.pbRender=function(r){let o=r.parent;try{for(;o!==r.top&&!t(o);)o=o.parent;t(o)||(o=r.parent)}catch(e){}return function({adId:t,pubUrl:s,clickUrl:i}){const c=new URL(s,window.location).origin;function a(e,n,r){const s=new MessageChannel;s.port1.onmessage=u(r),o.postMessage(JSON.stringify(Object.assign({message:e,adId:t},n)),c,[s.port2])}function d(n){a(e,{event:"adRenderFailed",info:{reason:n?.reason||"exception",message:n?.message}}),n?.stack&&console.error(n)}function u(e){return function(){try{return e.apply(this,arguments)}catch(e){d(e)}}}a("Prebid Request",{options:{clickUrl:i}},(function(o){let s;try{s=JSON.parse(o.data)}catch(e){return}if("Prebid Response"===s.message&&s.adId===t){const t=n(r.document,{width:0,height:0,style:"display: none",srcdoc:`<script>${s.renderer}<\/script>`});t.onload=u((function(){const o=t.contentWindow;o.Promise.resolve(o.render(s,{sendMessage:a,mkFrame:n},r)).then((()=>a(e,{event:"adRenderSucceeded"})),d)})),r.document.body.appendChild(t)}}))}}(window)}();</script>

<script>
pbRender({
Expand Down
11 changes: 11 additions & 0 deletions libraries/adkernelUtils/adkernelUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function getBidFloor(bid, mediaType, sizes) {
var floor;
var size = sizes.length === 1 ? sizes[0] : '*';
if (typeof bid.getFloor === 'function') {
const floorInfo = bid.getFloor({currency: 'USD', mediaType, size});
if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) {
floor = parseFloat(floorInfo.floor);
}
}
return floor;
}
23 changes: 23 additions & 0 deletions libraries/currencyUtils/floor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as utils from '../../src/utils.js';

/**
* get BidFloor
* @param {*} bid
* @returns
*/
export function getBidFloor(bid) {
if (!utils.isFn(bid.getFloor)) {
return utils.deepAccess(bid, 'params.bidfloor', 0);
}

try {
const bidFloor = bid.getFloor({
currency: 'USD',
mediaType: '*',
size: '*',
});
return bidFloor.floor;
} catch (_) {
return 0;
}
}
7 changes: 7 additions & 0 deletions libraries/dfpUtils/dfpUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ export const DFP_ENDPOINT = {
host: 'securepubads.g.doubleclick.net',
pathname: '/gampad/ads'
}

export const setGdprConsent = (gdprConsent, queryParams) => {
if (!gdprConsent) { return; }
if (typeof gdprConsent.gdprApplies === 'boolean') { queryParams.gdpr = Number(gdprConsent.gdprApplies); }
if (gdprConsent.consentString) { queryParams.gdpr_consent = gdprConsent.consentString; }
if (gdprConsent.addtlConsent) { queryParams.addtl_consent = gdprConsent.addtlConsent; }
}
58 changes: 58 additions & 0 deletions libraries/fpdUtils/deviceInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as utils from '../../src/utils.js';

/**
* get device
* @return {boolean}
*/
export function getDevice() {
let check = false;
(function (a) {
let reg1 = new RegExp(
[
'(android|bbd+|meego)',
'.+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)',
'|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone',
'|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap',
'|windows ce|xda|xiino|android|ipad|playbook|silk',
].join(''),
'i'
);
let reg2 = new RegExp(
[
'1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)',
'|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )',
'|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell',
'|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)',
'|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene',
'|gf-5|g-mo|go(.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c',
'|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom',
'|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)',
'|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)',
'|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]',
'|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)',
'|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio',
'|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms',
'|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al',
'|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)',
'|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(.b|g1|si)|utst|',
'v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)',
'|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-',
'|your|zeto|zte-',
].join(''),
'i'
);
if (reg1.test(a) || reg2.test(a.substr(0, 4))) {
check = true;
}
})(navigator.userAgent || navigator.vendor || window.opera);
return check;
}

/**
* get screen size
*
* @returns {Array} eg: "['widthxheight']"
*/
export function getScreenSize() {
return utils.parseSizesInput([window.screen.width, window.screen.height]);
}
Loading

0 comments on commit c81016f

Please sign in to comment.