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

Publisher Ads support for initial test sites #6

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
34 changes: 34 additions & 0 deletions Greaselion.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,36 @@
[
{
"urls": [
"https://*.washingtonpost.com/*"
],
"scripts": [
"publisher-ads/washingtonpost.bundle.js"
]
},
{
"urls": [
"https://*.marketwatch.com/*"
],
"scripts": [
"publisher-ads/marketwatch.bundle.js"
]
},
{
"urls": [
"https://*.wsj.com/*",
"https://*.barrons.com/*"
],
"scripts": [
"publisher-ads/wsjgroup.bundle.js"
]
},
{
"urls": [
"https://venturebeat.com/*",
"*://www.mlssoccer.com/*"
],
"scripts": [
"publisher-ads/gpt-site.bundle.js"
]
}
]
22 changes: 22 additions & 0 deletions common/contentScript/inject-to-document.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

export default function injectToDocument (isolatedFn: Function | string, ...codeVars: any[]) {
// Convert function to single-scope and stringify
const codeToEval = `(
${isolatedFn.toString()}
)(${codeVars.map(prop => JSON.stringify(prop)).join(', ')})`

function inject () {
const scriptEl = document.createElement('script')
scriptEl.async = true
scriptEl.textContent = codeToEval
;(document.body || document.documentElement).appendChild(scriptEl)
requestAnimationFrame(() => {
scriptEl.remove()
})
}
inject()
}
10 changes: 10 additions & 0 deletions common/contentScript/sendMessageToBrave.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function (
message: any,
responseCallback?: ((response: any) => void) | undefined
) {
chrome.runtime.sendMessage(
'mnojpmjdmbbfmejpflffifhffcmidifd',
message,
responseCallback
)
}
16 changes: 16 additions & 0 deletions common/debounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

export default function debounce<T>(fn: (data: T) => void, bufferInterval: number, ...args: Array<any>) {
let timeout: any
return (...args2: any[]) => {
clearTimeout(timeout)
let a: Array<string> = args || []
if (args2 && args2.constructor === Array) {
a = a.concat(args2)
}
timeout = setTimeout(fn.apply.bind(fn, this, a), bufferInterval)
}
}
8 changes: 8 additions & 0 deletions common/generate-random-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

export default function getRandomId(): string {
return Math.random().toString(36).substr(2, 9)
}
18 changes: 18 additions & 0 deletions common/pageLifecycle/run-on-first-visible.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

export default function runOnFirstVisible(fn: Function) {
if (document.visibilityState === 'visible') {
fn()
} else {
function onVisible() {
if (document.visibilityState === 'visible') {
document.removeEventListener('visibilitychange', onVisible)
fn()
}
}
document.addEventListener('visibilitychange', onVisible)
}
}
12 changes: 12 additions & 0 deletions common/pageLifecycle/run-on-loaded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

export default function runOnPageLoaded (fn: Function) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', (e) => fn())
} else {
fn()
}
}
36 changes: 36 additions & 0 deletions common/pageLifecycle/run-on-url-change.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

import injectToDocument from '../contentScript/inject-to-document'
import runOnPageLoaded from './run-on-loaded'

const customEventName = 'brave-url-changed'

export default function runOnUrlChange(fn: Function) {
// content script observes
window.addEventListener(customEventName, (e) => fn())
// document script fires
function fnPageInjectionCode ($customEventName: string) {
console.log('replacing events and sending name', $customEventName)

const prevPushState = window.history.pushState
const prevReplaceState = window.history.replaceState

window.history.pushState = function (...args) {
console.log('pushState was called')
requestAnimationFrame(() => window.dispatchEvent(new CustomEvent($customEventName)))
return prevPushState.call(this, ...args)
}

window.history.replaceState = function (...args) {
console.log('replaceState was called')
requestAnimationFrame(() => window.dispatchEvent(new CustomEvent($customEventName)))
return prevReplaceState.call(this, ...args)
}
}
runOnPageLoaded(() =>
injectToDocument(fnPageInjectionCode, customEventName)
)
}
58 changes: 58 additions & 0 deletions common/pageLifecycle/wait-for-window-var.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

import injectToDocument from '../contentScript/inject-to-document'
import runOnPageLoaded from './run-on-loaded'

type OnValueFunction = (varValue: any) => void
type VarValueCustomEvent = CustomEvent<{ varValue: any}>

// Intercepts the setting of a global variable on the page
// and returns it to a callback function when it is set.
export default function waitForWindowVar(varName: string, onValue: OnValueFunction) {

const customEventName = `brave-value-found-${varName}`

function onCustomEvent (e: VarValueCustomEvent) {
const { varValue } = e.detail
if (varValue) {
window.removeEventListener(customEventName, onCustomEvent)
onValue(varValue)
}
}

window.addEventListener(customEventName, onCustomEvent)

function fnPageInjectionCode ($varName: string, $customEventName: string) {
function valueFound (varValue: any) {
window.dispatchEvent(new CustomEvent($customEventName, {
detail: {
varValue
},
bubbles: true
}))
}

if (window[$varName]) {
valueFound(window[$varName])
return
}

let _value: any
Object.defineProperty(window, $varName, {
configurable: true,
set: function (value) {
_value = value
valueFound(_value)
},
get: function () {
return _value
}
})
}
runOnPageLoaded(() =>
injectToDocument(fnPageInjectionCode, varName, customEventName)
)
}
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"webpack-cli": "^3.3.11"
},
"dependencies": {
"@types/chrome": "0.0.100"
"@types/chrome": "0.0.100",
"@types/doubleclick-gpt": "^2019041801.0.2"
}
}
21 changes: 21 additions & 0 deletions publisher-ads/adSelecting/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

import { PublisherAd, stringToAdSize } from '../'

export default function SelectBiggestAd (ads: PublisherAd[]): PublisherAd {
if (!ads.length) {
throw new Error('SelectBiggestAd: ads should not be empty!')
}
if (ads.length === 1) {
return ads[0]
}
return ads.sort(function (a, b) {
const sizeA = stringToAdSize(a.size)
const sizeB = stringToAdSize(b.size)
if (!sizeA || !sizeB) return 0
return (sizeB[0] * sizeB[1]) - (sizeA[0] * sizeA[1])
})[0]
}
Loading