Skip to content

Commit

Permalink
feat: Add transferableUrlParameters option to the embed API
Browse files Browse the repository at this point in the history
  • Loading branch information
supertinou committed Jul 29, 2020
1 parent 87b7824 commit 5531870
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 10 deletions.
8 changes: 5 additions & 3 deletions demo/popup-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,17 @@
window.addEventListener('DOMContentLoaded', function () {
document.getElementById('btn-popup').onclick = function(e) {
e.preventDefault()
makeMockPopup({mode: 'popup'}).open()
makeMockPopup({mode: 'popup', transferableUrlParameters: ['utm_source']}).open()
}

document.getElementById('btn-drawer_left').onclick = function(e) {
e.preventDefault()
makeMockPopup({mode: 'drawer_left'}).open()
makeMockPopup({mode: 'drawer_left', transferableUrlParameters: ['utm_source']}).open()
}

document.getElementById('btn-drawer_right').onclick = function(e) {
e.preventDefault()
makeMockPopup({mode: 'drawer_right', width: 300}).open()
makeMockPopup({mode: 'drawer_right', width: 300, transferableUrlParameters: ['utm_source']}).open()
}

let popoverPopup
Expand All @@ -164,6 +164,7 @@
mode: 'popover',
width: 400,
height: 400,
transferableUrlParameters: ['utm_source'],
onReady: popoverReadyCallback
})
popoverButton.innerHTML = '...'
Expand Down Expand Up @@ -202,6 +203,7 @@
mode: 'side_panel',
width: 400,
height: 400,
transferableUrlParameters: ['utm_source'],
container: sidePanelContainerElement,
onReady: sidePanelReadyCallback
})
Expand Down
5 changes: 5 additions & 0 deletions demo/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
href="./form/mock.html#foobar=hello"
data-mode="popup"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
target="_blank"
>
Launch me as a popup!
Expand All @@ -107,6 +108,7 @@
href="./form/mock.html?foobar=hello"
data-mode="drawer_left"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
target="_blank"
>
Launch me as a drawer!
Expand All @@ -119,6 +121,7 @@
data-mode="drawer_right"
data-width="400"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
target="_blank"
>
Launch me as a right drawer!
Expand All @@ -134,6 +137,7 @@
data-width="500"
data-height="600"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
target="_blank"
>
<span class="icon">
Expand All @@ -155,6 +159,7 @@
data-width="360"
data-height="560"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
target="_blank"
>
<span class="icon">
Expand Down
1 change: 1 addition & 0 deletions demo/widget-legacy.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<div
class="typeform-widget"
data-url="./form/mock.html?foobar=hello"
data-transferable-url-parameters="utm_source"
style="width:100%; height:500px;"
></div>

Expand Down
1 change: 1 addition & 0 deletions demo/widget.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<div
class="typeform-widget"
data-url="./form/mock.html#foobar=hello"
data-transferable-url-parameters="utm_source"
style="width:100%; height:500px;"
></div>

Expand Down
8 changes: 6 additions & 2 deletions e2e/spec/functional/popup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const popupModes = {
}

const pages = {
'/popup.html': 'embed code',
'/popup-api.html': 'API'
'/popup.html?utm_source=facebook ': 'embed code',
'/popup-api.html?utm_source=facebook': 'API'
}

Object.keys(popupModes).forEach(popupMode => {
Expand All @@ -35,6 +35,10 @@ Object.keys(popupModes).forEach(popupMode => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /foobar=hello/)
})

it('Passes Browser URL parameters', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /utm_source=facebook/)
})

it('Closes Embed Popup clicking on the close button', () => {
if (popupMode === 'popover' || popupMode === 'side_panel') {
closePopupViaButton(`#btn-${popupMode}`) // no close button, popup closes via the button that opened it
Expand Down
24 changes: 20 additions & 4 deletions e2e/spec/functional/widget.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('Embed Widget in div with position:absolute on mobile', () => {
describe('Basic Embed Widget', () => {
describe('On Desktop', () => {
before(() => {
open('/widget.html')
open('/widget.html?utm_source=facebook')
})

it('Loads correctly the basic embed widget', () => {
Expand All @@ -20,11 +20,15 @@ describe('Basic Embed Widget', () => {
it('Passes hidden field parameter', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /foobar=hello/)
})

it('Passes Browser URL parameters', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /utm_source=facebook/)
})
})

describe('On Mobile', () => {
before(() => {
openOnMobile('/widget.html')
openOnMobile('/widget.html?utm_source=facebook')
})

it('Loads correctly the basic embed widget', () => {
Expand All @@ -34,13 +38,17 @@ describe('Basic Embed Widget', () => {
it('Passes hidden field parameter', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /foobar=hello/)
})

it('Passes Browser URL parameters', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /utm_source=facebook/)
})
})
})

describe('Basic Embed Widget with Legacy Hidden Fields', () => {
describe('On Desktop', () => {
before(() => {
open('/widget-legacy.html')
open('/widget-legacy.html?utm_source=facebook')
})

it('Loads correctly the basic embed widget', () => {
Expand All @@ -50,11 +58,15 @@ describe('Basic Embed Widget with Legacy Hidden Fields', () => {
it('Passes hidden field parameter', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /foobar=hello/)
})

it('Passes Browser URL parameters', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /utm_source=facebook/)
})
})

describe('On Mobile', () => {
before(() => {
openOnMobile('/widget-legacy.html')
openOnMobile('/widget-legacy.html?utm_source=facebook')
})

it('Loads correctly the basic embed widget', () => {
Expand All @@ -64,6 +76,10 @@ describe('Basic Embed Widget with Legacy Hidden Fields', () => {
it('Passes hidden field parameter', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /foobar=hello/)
})

it('Passes Browser URL parameters', () => {
cy.get(IFRAME_SELECTOR).should('have.attr', 'src').and('match', /utm_source=facebook/)
})
})
})

Expand Down
9 changes: 8 additions & 1 deletion src/core/make-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
ensureMetaViewport,
noop
} from './utils'
import {
transferUrlParametersToQueryStrings
} from './utils/url-parameters-transfer'
import randomString from './utils/random-string'
import {
isMobile,
Expand Down Expand Up @@ -45,6 +48,7 @@ const buildOptions = (embedId, options) => {
hideHeaders: false,
hideScrollbars: false,
disableTracking: false,
transferableUrlParameters: options.transferableUrlParameters || [],
onSubmit: noop,
open: null,
openValue: null,
Expand Down Expand Up @@ -72,9 +76,12 @@ const renderComponent = (params, options) => {
onSubmit
} = options

let queryStrings = replaceExistingKeys(options, queryStringKeys)
queryStrings = transferUrlParametersToQueryStrings(options.transferableUrlParameters, queryStrings)

const urlWithQueryString = appendParamsToUrl(
url,
replaceExistingKeys(options, queryStringKeys)
queryStrings
)

if (!isMobile(navigator.userAgent) && isScreenBig()) {
Expand Down
5 changes: 5 additions & 0 deletions src/core/make-widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
noop,
omit
} from './utils'
import {
transferUrlParametersToQueryStrings
} from './utils/url-parameters-transfer'
import {
isMobile
} from './utils/mobile-detection'
Expand All @@ -19,6 +22,7 @@ const defaultOptions = {
hideHeaders: false,
hideScrollbars: false,
disableTracking: false,
transferableUrlParameters: [],
onSubmit: noop
}

Expand All @@ -38,6 +42,7 @@ export default function makeWidget (element, url, options) {
const enabledFullscreen = isMobile(navigator.userAgent)

let queryStrings = replaceExistingKeys(options, queryStringKeys)
queryStrings = transferUrlParametersToQueryStrings(options.transferableUrlParameters, queryStrings)

if (enabledFullscreen) {
queryStrings = {
Expand Down
23 changes: 23 additions & 0 deletions src/core/utils/url-parameters-transfer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const urlSearchToParams = (search) => {
var params = {}
if (search !== '' && search !== null) {
var vars = search.split('&')
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=')
params[pair[0]] = decodeURIComponent(pair[1])
}
}
return params
}

export const transferUrlParametersToQueryStrings = (transferableUrlParameters, queryStrings) => {
const urlSearchString = window.location.search.substr(1)
const urlSearchParams = urlSearchToParams(urlSearchString)
const queryStringsWithTransferedParams = { ...queryStrings }
transferableUrlParameters.forEach(transferableParam => {
if (!(transferableParam in queryStrings)) {
queryStringsWithTransferedParams[transferableParam] = urlSearchParams[transferableParam]
}
})
return queryStringsWithTransferedParams
}
32 changes: 32 additions & 0 deletions src/core/utils/url-parameters-transfer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { transferUrlParametersToQueryStrings } from './url-parameters-transfer'

describe('transferUrlParametersToQueryStrings', () => {
const { location } = window

beforeAll(() => {
delete window.location
window.location = { search: '?foo=jason&bar=rachel&utm_medium=cpc&utm_campaign=camp2008&utm_source=instagram&embed-hide-footer=false' }
})

afterAll(() => {
window.location = location
})

it('should return ?foo=jason&bar=rachel&utm_medium=cpc&utm_campaign=camp2008&utm_source=instagram&embed-hide-footer=false', () => {
expect(window.location.search).toEqual('?foo=jason&bar=rachel&utm_medium=cpc&utm_campaign=camp2008&utm_source=instagram&embed-hide-footer=false')
})

it('transfer the parameters of the URL in the query strings', () => {
const urlParameters = ['foo', 'bar']
const queryStrings = {}
const queryStringWithTransferedUrlParameters = transferUrlParametersToQueryStrings(urlParameters, queryStrings)
expect(queryStringWithTransferedUrlParameters).toEqual({ foo: 'jason', bar: 'rachel' })
})

it('does not override existing queryString for embed configuration', () => {
const urlParameters = ['foo', 'bar', 'embed-hide-footer']
const queryStrings = { 'embed-hide-footer': true }
const queryStringWithTransferedUrlParameters = transferUrlParametersToQueryStrings(urlParameters, queryStrings)
expect(queryStringWithTransferedUrlParameters).toEqual({ foo: 'jason', bar: 'rachel', 'embed-hide-footer': true })
})
})

0 comments on commit 5531870

Please sign in to comment.