Skip to content

Instantly share code, notes, and snippets.

@HaQadosch
Last active April 11, 2016 17:28
Show Gist options
  • Save HaQadosch/f867f50acecd47bc3bb3 to your computer and use it in GitHub Desktop.
Save HaQadosch/f867f50acecd47bc3bb3 to your computer and use it in GitHub Desktop.
JLibrary

Optimost functions used in live tests.

044 - Homepage - Trending Products

(Setup)

window.optimost.XB_JLibrary

1_remove

window.$optg_XB.f.rmStyleById window.$optg_XB.f.addStyle window.$optt.s016t044_HomePageTrendingProducts

043 - Product page - Rich Media

(Setup)

1_hide

window.$optg_XB.f.rmStyleByID window.$optg_XB.f.addStyle window.$optg_XB.f.log

customer help file

augmentLoadList

utils.log window.optimost.Q.q

onAssetsLoaded

utils.log window.optimost.SC window.optimost.Q.action window.$optg_XB.f.fireJSCounter window.optimost.removeCookie window.$optg_XB.runJavaScriptCounter window.$optg_XB.akira window.$optg_XB.fireBinaryCounter trial.fireBinaryCounter trial.Attribs window.optimost.jQueryReadyCallbacks

Primitives and prototypes

Array.map Array.filter Array.reduce String.trim Object.keys

/* eslint-disable comma-style */
'use strict'
/**
* Object passed to cbk should be:
* 'error': ... // Try/catch execution error.
* 'noEntry': ... // Args passed in do not match the requirements.
* 'fail': ... // When function did not complete successfully the taks.
*/
String.optrim = String.optrim || window.optimost && window.optimost.jQuery && window.optimost.jQuery.optrim
Object.opassign = Object.opassign || window.optimost && window.optimost.jQuery && window.optimost.jQuery.extend
Object.opkeys = Object.opkeys || function keys (obj) {
if (obj !== Object(obj))
throw new TypeError('Object.keys called on a non-object')
const k = []
for (let member in obj) if (Object.prototype.hasOwnProperty.call(obj, member)) k.push(member)
return k
}
const saitama = () => {
const debug = true || /opdebug=true/i.test(window.location.href) || /opdebug=true/i.test(window.document.cookie) || window.$optg && window.$optg.debug || window.optimost && window.optimost.debug
const log = (...mess) => {
try {
if (window.console && debug) window.console.log('[Optimost]:', ...mess)
} catch (err) {
if (window.console) {
window.console.log('! Optimost XLibrary log error: ', err)
window.console.log(...mess)
}
}
}
/**
* Example addStyle('div.buttonRight:last-child {filter:opacity(50%)};', 'opInactive', cbkLog).
* @param {String} style - CSS Rules '<css selector> {style details}'.
* @param {string} tagID - Stylesheet id.
* @param {function} cbk - callbak function is case of bad return.
*/
const addStyle = (style, tagID, cbk) => {
try {
if (style && tagID
&& typeof style === 'string' && typeof tagID === 'string'
&& window.document.getElementById(tagID) === null) {
let doc = window.document
let styleTag = doc.createElement('style')
styleTag.setAttribute('type', 'text/css')
styleTag.setAttribute('id', tagID)
const txt = doc.createTextNode(style)
styleTag.appendChild(txt)
let head = doc.getElementsByTagName('head')
if (head.length) head[0].appendChild(styleTag)
} else {
if (!style || !tagID) log('! XLibrary addStyle is missing arguments.')
else if (typeof style !== 'string' || typeof tagID !== 'string') log('! XLibrary addStyle works with strings only. addStyle called with ', style, tagID)
else if (window.document.getElementById(tagID) !== null) log('! XLibrary addStyle, looks like an element called ', tagID, 'already exists. ', window.document.getElementById(tagID))
}
} catch (err) {
let logAlso = true
if (cbk) logAlso = cbk({'error' : err})
if (!cbk || logAlso) log('! Saitama addStyle error: ', err)
}
}
const rmStyleById = (tagID, cbk) => {
try {
if (tagID && typeof tagID === 'string') {
const elt = window.document.getElementById(tagID)
if (elt) {
elt.parentNode.removeChild(elt)
} else {
let logAlso = true
if (cbk) logAlso = cbk({'fail' : tagID})
if (!cbk || logAlso) log('! Saitama rmStyleById, elt ', tagID, 'not found. getElementById Returns ', elt)
}
} else {
let logAlso = true
if (cbk) logAlso = cbk({'nonEntry' : tagID})
if (!cbk || logAlso) {
if (!tagID) log('! Saitama rmStyleById is missing an argument.')
else if (typeof tagID !== 'string') log('! Saitama rmStyleById works with string. rmStyleById called with ', tagID)
}
}
} catch (err) {
let logAlso = true
if (cbk) logAlso = cbk({'error' : err})
if (!cbk || logAlso) log(' ! Saitama rmStyleById error: ', err)
}
}
const nalog = (foo) => log(`! ${foo}() not available`)
let setCookie = () => nalog('setCookie')
let getCookie = () => nalog('getCookie')
let removeCookie = () => nalog('removeCookie')
let hasCookie = () => nalog('hasCookie')
let keysCookie = () => nalog('keysCookie')
if (window.dmh && window.dmh.tracker && window.dmh.tracker.cookie) {
setCookie = window.dmh.tracker.cookie.setItem
getCookie = window.dmh.tracker.cookie.getItem
removeCookie = window.dmh.tracker.cookie.removeItem
hasCookie = window.dmh.tracker.cookie.hasItem
keysCookie = window.dmh.tracker.cookie.keys
}
/*
* XLibrary.runJavaScriptCounter('http://by.marketinghub.hp.com/counter/1684/-/11/event.js')
* Builds a script to call a js 'pixel'.
* Contains:
* All cookies starting with 'op'.
* All QSP parameters.
* All variables in 'window.opcounter'.
* Re-initialise window.optimost.Q with the URL query parameters.
* Re-initialise window.optimost.C with the document cookies.
*/
const runJavaScriptCounter = function runJavaScriptCounter (counterBaseURL, cbk) {
try {
const wdl = window.document.location
const timeStamp = new Date
const details = [
`D_ts=${Math.round(timeStamp.getTime() / 1000)}`
, `D_tzo=${timeStamp.getTimezoneOffset()}`
, `D_loc=${wdl.protocol}//${wdl.hostname}${wdl.pathname}`
, `D_ckl=${window.document.cookie.length}`
, `D_ref=${window.document.referrer}`
]
const qParams = wdl.search.split(/&|\?/g)
const opCookies = window.document.cookie
.split(';')
.map(ckPair => ckPair.optrim())
.filter(ckPair => /^op/i.test(ckPair))
const opCounters = Object.opkeys(window.opcounter)
.filter(opVar => /^op/i.test(opVar))
.map(opVar => `${opVar}=${window.encodeURIComponent(window.opcounter[opVar])}`)
const qsp = [].concat(
details
, qParams
, opCookies
, opCounters
)
const pixelSrc = `${counterBaseURL}?${qsp.join('&')}`
if (document.getElementsByTagName('head')[0]) {
const opScript = document.createElement('script')
opScript.src = pixelSrc
document.getElementsByTagName('head')[0].appendChild(opScript)
}
} catch (runJavaScriptCounterErr) {
let logAlso = true
if (cbk) logAlso = cbk({'error' : runJavaScriptCounterErr})
if (!cbk || logAlso) log(' ! Saitama runJavaScriptCounter error: ', runJavaScriptCounterErr)
}
}
/**
* Loops maxIter times every ms millisecond until cond is true.
* Calls action if cond is true or maxOut if maxIter reaches 0, whichever happens first.
*/
const loop = (...args) => {
const defaults = {
'maxIter' : 10
, 'ms' : 200
, 'cond' : true
, 'action' : (() => { log('Saitama loop: Missing function, nothing to do.') })
, 'maxOut' : (() => { log('Saitama loop: Max Iteration reached.') })
, 'cbk': false
}
let {maxIter, ms, cond, action, maxOut, cbk} = Object.opassign({}, defaults, ...args)
try {
if (0 < maxIter) {
if (Boolean(typeof cond === 'function' ? cond() : cond)) action()
else window.setTimeout(loop({'maxIter': --maxIter, ms, cond, action, maxOut, cbk}), ms)
} else {
maxOut()
}
} catch (loopErr) {
let logAlso = true
if (cbk) logAlso = cbk({'error' : loopErr})
if (!cbk || logAlso) log(' ! Saitama loop Error: ', loopErr)
} finally {
return maxIter
}
}
/**
* timer waits ms millisecond before firing action if cond is true or else wait again
* until maxIter is reached or passed 5 min, whichever comes first.
*/
const timer = (...args) => {
log('Saitama Timer called with ', ...args)
let intervalID = 0
const defaults = {
'action': (() => { log('Saitama timer: Missing function, nothing to do.') })
, 'ms': 500
, 'timestamp': new Date().getTime() + 5*60000
, 'maxIter': Infinity
, 'cond': true
, 'cbk': false
}
const {action, ms, timestamp, maxIter, cond, cbk} = Object.opassign({}, defaults, ...args)
try {
let accu = 0
const fireCond = () => accu < maxIter && Boolean(typeof cond === 'function' ? cond() : cond) && Date.now() < timestamp
const useCBK = typeof cbk === 'function'
if (useCBK) cbk('Saitama Timer parameters set up: ', {accu, maxIter, ms, timestamp, fireCond: fireCond(), intervalID, 'TTL': new Date(timestamp - Date.now())})
if (!fireCond()) intervalID = window.setInterval(() => {
if (useCBK) cbk(`Saitama Timer condition for action not met; waiting ${ms}ms: `, {accu, fireCond: fireCond(), intervalID, 'TTL': new Date(timestamp - Date.now())})
if (!fireCond()) {
if (useCBK) cbk(`Saitama Timer ${ms}ms elapsed, cond still not met.`, {accu, fireCond: fireCond(), intervalID, 'TTL': new Date(timestamp - Date.now())})
accu++
} else {
action()
if (useCBK) cbk('Saitama Timer condition met, action fired, interval cleared', {accu, fireCond: fireCond(), intervalID, 'TTL': new Date(timestamp - Date.now())})
window.clearInterval(intervalID)
}
}, ms)
else if (useCBK) cbk('Saitama Timer initial cond check met, nothing to do.')
} catch (timerErr) {
let logAlso = true
if (cbk) logAlso = cbk({'error' : loopErr})
if (!cbk || logAlso) log(' ! Saitama timer Error: ', loopErr)
} finally {
return intervalID
}
}
/**
* XB. 08/03/2016
* Akira adds viewport mediaMatch feature with IE9 polyfill, as well as detcting html elts in viewport.
* We want to segment based on CSS min-width feature rather than screen width.
*/
const akira = (function akira () {
let xports = {}
, win = typeof window !== 'undefined' && window
, doc = typeof document !== 'undefined' && document
, docElem = doc && doc.documentElement
, matchMedia = win['matchMedia']
|| win['msMatchMedia']
|| win['webkitMatchMedia']
|| win['mozMatchMedia']
|| win['oMatchMedia']
|| function matchMedia () {
'use strict';
var t = window.styleMedia || window.media;
return t || !function () {
var e = document.createElement('style'),
n = document.getElementsByTagName('script') [0],
i = null;
e.type = 'text/css',
e.id = 'matchmediajs-test',
n.parentNode.insertBefore(e, n),
i = window.getComputedStyle && window.getComputedStyle(e, null) || e.currentStyle,
t = {
matchMedium: function (t) {
var n = '@media ' + t + '{ #matchmediajs-test { width: 1px; } }';
return e.styleSheet ? e.styleSheet.cssText = n : e.textContent = n,
'1px' === i.width
}
}
}(),
function (e) {
return {
matches: t.matchMedium(e || 'all'),
media: e || 'all'
}
}
}()
, mq = matchMedia ? function mq (q) {
return !!matchMedia.call(win, q).matches
} : function () {
return false
}
, viewportW = xports['viewportW'] = function viewportW () {
const a = docElem['clientWidth']
const b = win['innerWidth']
return a < b ? b : a
}
, viewportH = xports['viewportH'] = function viewportH () {
const a = docElem['clientHeight']
const b = win['innerHeight']
return a < b ? b : a
}
/**
* Test if a media query is active. Like Modernizr.mq
* @since 1.6.0
* @return {boolean}
*/
xports['mq'] = mq
/**
* Normalized matchMedia
* @since 1.6.0
* @return {MediaQueryList|Object}
*/
xports['matchMedia'] = matchMedia ? function matchMedia () {
// matchMedia must be binded to window
return matchMedia.apply(win, arguments)
} : function matchMediaDegraded () {
// Gracefully degrade to plain object
return {}
}
/**
* @since 1.8.0
* @return {{width:number, height:number}}
*/
function viewport () {
return {'width': viewportW(), 'height': viewportH()}
}
xports['viewport'] = viewport
/**
* Cross-browser window.scrollX
* @since 1.0.0
* @return {number}
*/
xports['scrollX'] = function scrollX () {
return win.pageXOffset || docElem.scrollLeft
}
/**
* Cross-browser window.scrollY
* @since 1.0.0
* @return {number}
*/
xports['scrollY'] = function scrollY () {
return win.pageYOffset || docElem.scrollTop
}
/**
* @param {{top:number, right:number, bottom:number, left:number}} coords
* @param {number=} cushion adjustment
* @return {Object}
*/
function calibrate (coords, cushion) {
const o = {}
cushion = +cushion || 0
o['width'] = (o['right'] = coords['right'] + cushion) - (o['left'] = coords['left'] - cushion)
o['height'] = (o['bottom'] = coords['bottom'] + cushion) - (o['top'] = coords['top'] - cushion)
return o
}
/**
* Cross-browser element.getBoundingClientRect plus optional cushion.
* Coords are relative to the top-left corner of the viewport.
* @since 1.0.0
* @param {Element|Object} el element or stack (uses first item)
* @param {number=} cushion +/- pixel adjustment amount
* @return {Object|boolean}
*/
function rectangle (el, cushion) {
el = el && !el.nodeType ? el[0] : el
return !el || el.nodeType !== 1 && calibrate(el.getBoundingClientRect(), cushion)
}
xports['rectangle'] = rectangle
/**
* Get the viewport aspect ratio (or the aspect ratio of an object or element)
* @since 1.7.0
* @param {(Element|Object)=} o optional object with width/height props or methods
* @return {number}
* @link http://w3.org/TR/css3-mediaqueries/#orientation
*/
function aspect (o) {
o = o === null ? viewport() : o.nodeType === 1 ? rectangle(o) : o
let h = o['height']
let w = o['width']
h = typeof h === 'function' ? h.call(o) : h
w = typeof w === 'function' ? w.call(o) : w
return w / h
}
xports['aspect'] = aspect
/**
* Test if an element is in the same x-axis section as the viewport.
* @since 1.0.0
* @param {Element|Object} el
* @param {number=} cushion
* @return {boolean}
*/
xports['inX'] = function inX (el, cushion) {
const r = rectangle(el, cushion)
return !!r && r.right >= 0 && r.left <= viewportW()
}
/**
* Test if an element is in the same y-axis section as the viewport.
* @since 1.0.0
* @param {Element|Object} el
* @param {number=} cushion
* @return {boolean}
*/
xports['inY'] = function inY (el, cushion) {
const r = rectangle(el, cushion)
return !!r && r.bottom >= 0 && r.top <= viewportH()
}
/**
* Test if an element is in the viewport.
* @since 1.0.0
* @param {Element|Object} el
* @param {number=} cushion
* @return {boolean}
*/
xports['inViewport'] = function inViewport (el, cushion) {
// Equiv to `inX(el, cushion) && inY(el, cushion)` but just manually do both
// to avoid calling rectangle() twice. It gzips just as small like this.
const r = rectangle(el, cushion)
return !!r && r.bottom >= 0 && r.right >= 0 && r.top <= viewportH() && r.left <= viewportW()
}
return xports
}())
return {
log
, addStyle
, rmStyleById
, setCookie
, getCookie
, removeCookie
, hasCookie
, keysCookie
, runJavaScriptCounter
, loop
, timer
, akira
}
}
window.optimost.saitama = saitama()
// ------------------------------------------------------------------------------------
/*
*
* :: cookies.js ::
*
* A complete cookies reader/writer framework with full unicode support.
*
* https://developer.mozilla.org/en-US/docs/DOM/document.cookie
*
* This framework is released under the GNU Public License, version 3 or later.
* http://www.gnu.org/licenses/gpl-3.0-standalone.html
*
* Syntaxes:
*
* * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
* * docCookies.getItem(name)
* * docCookies.removeItem(name[, path], domain)
* * docCookies.hasItem(name)
* * docCookies.keys()
*
*/
/*
cookie = {
getItem: function (sKey) {
return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null;
},
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
return false;
}
var sExpires = '';
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity ? '; expires=Fri, 31 Dec 9999 23:59:59 GMT' : '; max-age=' + vEnd;
break;
case String:
sExpires = '; expires=' + vEnd;
break;
case Date:
sExpires = '; expires=' + vEnd.toUTCString();
break;
}
}
document.cookie = encodeURIComponent(sKey) + '=' + encodeURIComponent(sValue) + sExpires + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '') + (bSecure ? '; secure' : '');
return true;
},
removeItem: function (sKey, sPath, sDomain) {
if (!sKey || !this.hasItem(sKey)) {
return false;
}
document.cookie = encodeURIComponent(sKey) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '');
return true;
},
hasItem: function (sKey) {
return (new RegExp('(?:^|;\\s*)' + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=')).test(document.cookie);
},
keys: /* optional method: you can safely remove it! /
function () {
var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, '').split(/\s*(?:\=[^;]*)?;\s/);
for (var nIdx = 0; nIdx < aKeys.length; nIdx++) {
aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]);
}
return aKeys;
}
};
*/
// <script>
;(
/**
* XB. 15/03/2016.
* @param {Object} optgf - The $optg.f object holding libraries and functions for css styling.
* @param {Object} trial - The trial object, mainly for console output.
* @param {Object} most - The optimost object, mainly for jQuery waiting loop.
* @returns {boolean} The conditions to execute the styling.
*/
function op_1_styling (trial, most, saitama, undefined) {
'use strict'
if (trial && most && saitama && saitama.rmStyleById && saitama.addStyle && most.jQuery) {
try {
const jQ = most.jQuery
const cbkLog = (fooName, alsoLog, resp) => {
saitama.log
? (resp) => {saitama.log(`! Travel Money Card Funnel 1_styling ${fooName} returns: `, resp ); return alsoLog}
: () => alsoLog
}
/**
* Modifications applied to all Steps:
*/
;(function stylingAllSteps () {
try {
const alsoLog = true
const cbkLogAllSteps = cbkLog('All Steps', alsoLog)
// Hides left panel (done in setup module) & centers the main layer.
const rightPanelSelector = 'div#Category-layer-main'
const centerCSS = '{float: none !important; margin: auto !important;}'
saitama.rmStyleById('optimost_css_centerRightPanel', () => false)
saitama.addStyle(`${rightPanelSelector} ${centerCSS}`, 'optimost_css_centerRightPanel', resp => {saitama.log('Center right panel'); return true})
// FAQ in Footer.
const leftPanel = jQ('div#Category-layer-left')
const faq = leftPanel.find('li').filter((index, elt) => /FAQ|Frequently\ asked\ questions/i.test(elt.textContent || ''))
const footerLinks = jQ('div#Footer ul')
footerLinks.append(faq.clone().addClass('header'))
/**
* All continue buttons are slightly opaque until all mandatory fields are filled in.
* IE css rules are slightly different:
* styleIE="-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=50); filter: alpha(opacity=50);"
*/
const cssSelector = 'div.submitButtonsBar div.buttonBar div.buttonRight'
const opOpacityCSS = '{filter:opacity(50%); -webkit-filter: opacity(0.5); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";}'
saitama.rmStyleById('opInactive', cbkLogAllSteps)
saitama.addStyle(`${cssSelector} ${opOpacityCSS}`, 'opInactive', cbkLogAllSteps)
saitama.rmStyleById('optimost_css_HideButtons', cbkLogAllSteps) // Style has been added via the setup module.
// Tooltips as title (show on hover).
const tooltipContainers = jQ('div.tooltipContainer')
if (tooltipContainers.length)
tooltipContainers.map((ind, b) => b.title = jQ(b).find('div.toolTipContent').text())
// Activates button when one mandatory field is left, or after 5 min.
let cond = () => {
const formFields = jQ('div#mainContainer').find('input, textarea, select')
const mandatoryFields = jQ(formFields.filter((index, elt) => { // Filters out all non mandatory fields.
const cousins = elt.parentElement.previousElementSibling && elt.parentElement.previousElementSibling.firstElementChild || ''
return cousins && /mandatory/i.test(cousins && cousins.className || '')
}))
return mandatoryFields.filter((index, elt) => !elt.value).length < 1
}
saitama.timer({
'action': () => saitama.rmStyleById('opInactive')
, cond
, 'cbk': saitama.log
})
// After 5 min, we activate the button, just in case.
window.setTimeout(() => saitama.rmStyleById('opInactive'), 5*60000)
} catch (stylingAllStepsErr) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingAllSteps error: `, stylingAllStepsErr)
}
}())
/**
* Modifications for Step 1.
*/
const stylingStep1 = function stylingStep1 () {
try {
const alsoLog = true
const cbkLogStep1 = cbkLog('Step 1_Quote', alsoLog)
// Money input with a more meaningful placeholder, the tooltip.
const form = jQ('div#mainContainer')
const moneySpan = form.find('div.pair:last')
const tooltip = moneySpan.find('div.toolTipContent').text()
const input = moneySpan.find('input:first')
.attr('value', '')
.attr('placeholder', '50.00')
.attr('title', tooltip)
.on('click', evt => evt.currentTarget.placeholder = '')
saitama.rmStyleById('optimost_css_HideFormInputs', cbkLogStep1) // Style has been added via the setup module.
// if amount after calculation shows during page load, activate the button right away.
if (jQ('span[id="website.cardApplication.output.debitAmount"]').length) {
saitama.rmStyleById('opInactive')
}
} catch (stylingStep1Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep1 error: `, stylingStep1Err)
}
}
/**
* Modifications for Step 2:
*/
const stylingStep2 = function stylingStep2 () {
try {
const alsoLog = true
const cbkLogStep2 = cbkLog('Step 2_PersonalDetails', alsoLog)
// Money input with a more meaningful placeholder, the tooltip.
const moneySpan = jQ('div.pair:last')
const tooltip = moneySpan.find('div.toolTipContent').text()
const input = moneySpan.find('input:first')
.attr('value', '')
.attr('placeholder', '50.00')
.attr('title', tooltip)
.on('click', evt => evt.currentTarget.placeholder = '')
saitama.rmStyleById('optimost_css_HideFormInputs', cbkLogStep2) // Style has been added via the setup module.
} catch (stylingStep2Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep2 error: `, stylingStep2Err)
}
}
;(function selectStylingStep (TMCBookingStep) {
if (TMCBookingStep) {
try {
if (/1_Quote/i.test(TMCBookingStep)) stylingStep1(2)
else if (/2_PersonalDetails/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 2')
else if (/3_IdentityDetails/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 3')
else if (/4_SecurityDetails/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 4')
else if (/5_Agreement/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 5')
else if (/6_Summary/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 6')
else if (/7_PaymentDetails/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 7')
else if (/8_Confirmation/i.test(TMCBookingStep)) saitama.log('Travel Money Card Funnel 1_styling selectStylingStep : Step 8')
else saitama.log('Travel Money Card Funnel 1_styling selectStylingStep, step is out of the booking journey. window.optrial.TMCBookingStep returns ', TMCBookingStep)
} catch (selectStylingStepErr) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling selectStylingStep error: `, selectStylingStepErr)
}
} else {
if (saitama.log) saitama.log(`Travel Money Card Funnel 1_styling selectStylingStep non Entry, window.optrial.TMCBookingStep returns `, TMCBookingStep)
}
}(window.optrial? window.optrial.TMCBookingStep : 0))
} catch (err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling Error: `, err)
}
} else {
if (saitama.log) {
saitama.log('! Travel Money Card Funnel 1_styling condition not met for execution: ', {
trial
, most
, 'rmStyleById': saitama.rmStyleById
, 'addStyle': saitama.addStyle
, 'jQuery': most.jQuery
})
}
}
return trial && most && saitama && saitama.rmStyleById && saitama.addStyle && most.jQuery
}(window.$optt ? window.$optt.s030t073_TravelMoneyCardFunnel : 0, window.optimost, window.optimost ? window.optimost.saitama : 0)
)
// </script>
/* eslint-disable comma-style */
// (0, _some2.default) -> Array.some
// (0, _filter2.default) -> Array.filter
// � -> £
// <script>
;(
/**
* XB. 11/04/2016.
* @param {Object} optgf - The $optg.f object holding libraries and functions for css styling.
* @param {Object} trial - The trial object, mainly for console output.
* @param {Object} most - The optimost object, mainly for jQuery waiting loop.
* @returns {boolean} The conditions to execute the styling.
*/
function op_1_styling (trial, most, saitama, undefined) {
'use strict'
if (trial && most && saitama && saitama.rmStyleById && saitama.addStyle && most.jQuery) {
try {
const jQ = most.jQuery
const cbkLog = (fooName, alsoLog, resp) => {
saitama.log
? (resp) => { saitama.log(`! Travel Money Card Funnel 1_styling ${fooName} returns: `, resp); return alsoLog }
: () => alsoLog
}
const opOpacityCSS = '{filter:opacity(50%); -webkit-filter: opacity(0.5); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; opacity: 0.5;}'
/**
********************************************************
* Modifications applied to all Steps:
********************************************************
*/
;(function stylingAllSteps () {
try {
const alsoLog = false
const cbkLogAllSteps = cbkLog('All Steps', alsoLog)
// Hides left panel (done in setup module) & centers the main layer.
const rightPanelSelector = 'div#Category-layer-main'
const centerCSS = '{float: none !important; margin: auto !important;}'
saitama.rmStyleById('optimost_css_centerRightPanel', () => false)
saitama.addStyle(`${rightPanelSelector} ${centerCSS}`, 'optimost_css_centerRightPanel', () => false)
// FAQ in Footer.
const leftPanel = jQ('div#Category-layer-left')
const faq = leftPanel.find('li').filter((index, elt) => /FAQ|Frequently\ asked\ questions/i.test(elt.textContent || ''))
const footerLinks = jQ('div#Footer ul')
footerLinks.append(faq.clone().addClass('header'))
// Tooltips as title (show on hover).
const tooltipContainers = jQ('div.tooltipContainer')
if (tooltipContainers.length) {
tooltipContainers.map((ind, b) => b.title = jQ(b).find('div.toolTipContent').text())
}
// Removes the buttonBar and includes the continue button at the bottom of the form.
const buttonbar = jQ('div.submitButtonsBar.clearBoth')
jQ('div#mainContainer').append(buttonbar.find('div.buttonBar').remove()).attr('style', 'padding-bottom: 0px; margin-bottom: 30px;')
buttonbar.remove()
/**
* All continue buttons are slightly opaque until all mandatory fields are filled in.
* IE css rules are slightly different:
* styleIE="-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=50); filter: alpha(opacity=50); opacity: 0.5;"
*/
const cssContinueSelector = 'div#mainContainer > div.buttonBar:last-child div.buttonRight'
saitama.rmStyleById('opContinueInactive', () => false)
saitama.addStyle(`${cssContinueSelector} ${opOpacityCSS}`, 'opContinueInactive', () => false)
saitama.rmStyleById('optimost_css_HideButtons', () => false) // Style has been added via the setup module.
// Activates button when one mandatory field is left, or after 5 min.
let cond = () => {
const formFields = jQ('div#mainContainer').find('input, textarea, select')
const mandatoryFields = jQ(formFields.filter((index, elt) => { // Filters out all non mandatory fields.
const cousins = elt.parentElement.previousElementSibling && elt.parentElement.previousElementSibling.firstElementChild || ''
return cousins && /mandatory/i.test(cousins && cousins.className || '')
}))
return mandatoryFields.filter((index, elt) => !elt.value).length < 1
}
// The page might reload if one entry is wrong.
// If all fields are filled in, we activate continue button.
if (cond()) {
saitama.rmStyleById('opContinueInactive')
} else {
const timerID = saitama.timer({
'timeInAction': () => saitama.rmStyleById('opContinueInactive', () => false)
, 'timeOutAction': () => saitama.rmStyleById('opContinueInactive', () => false)
, cond
, 'cbk': false
})
// After 5 min, we activate the button and clear the timer, just in case.
const in5min = 5 * 60000
window.setTimeout(
() => { saitama.rmStyleById('opContinueInactive', () => false); window.clearInterval(timerID) }
, in5min)
}
// Buttons are clickable only in the inner input element, sides are not clickable.
// Redirects the click on the whole button into the input elt to simulate a whole clickable button.
jQ('div.buttonRight').on('click', elt => jQ('elt').find('input').click())
} catch (stylingAllStepsErr) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingAllSteps error: `, stylingAllStepsErr)
}
}())
/**
********************************************************
* Modifications for Step 1: Quote
********************************************************
*/
const stylingStep1 = function stylingStep1 () {
try {
const alsoLog = false
const cbkLogStep1 = cbkLog('Step 1_Quote', alsoLog)
// Money input with a more meaningful placeholder, the tooltip.
const form = jQ('div#mainContainer')
const moneySpan = form.find('div.pair:last')
const tooltip = moneySpan.find('div.toolTipContent').text()
const input = moneySpan.find('input:first')
.attr('value', '')
.attr('placeholder', '')
.attr('title', tooltip)
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
// Step 1 has a manadatory "calculate" step. The calculate button should be more obvious.
// We place it before the tooltip.
// style: width: 120px; margin-top: -2px;
const tooltipDiv = moneySpan.find('div.tooltipContainer')
tooltipDiv.remove()
moneySpan.append(tooltipDiv)
jQ('div#cardApplicationQuoteCalculateButtonBar').attr('style', 'width: 120px; margin-top: -2px; padding: 0 0;')
// Inactivate the Calc button until there is an entry in the money field.
const cssCalcSelector = 'div#cardApplicationQuoteCalculateButtonBar.buttonBar div.buttonRight'
saitama.rmStyleById('opCalcInactive', () => false)
saitama.addStyle(`${cssCalcSelector} ${opOpacityCSS}`, 'opCalcInactive', () => false)
if (window.$optg.ieVer() < 100) {
window.jQuery('input.money').live('focus, change, blur, input', () => saitama.rmStyleById('opCalcInactive', () => false))
} else {
jQ('input.money').on('focus, change, blur, input', () => saitama.rmStyleById('opCalcInactive', () => false))
}
// Continue button follows a different rule for this page as the CTA should be activated as a result of the payment calculation.
const cssContinueBisSelector = 'div#mainContainer > div.buttonBar:last-child div.buttonRight'
saitama.rmStyleById('opContinueBisInactive', () => false)
saitama.addStyle(`${cssContinueBisSelector} ${opOpacityCSS}`, 'opContinueBisInactive', () => false)
// if amount after calculation shows during page load, activate the button right away.
if (jQ('span[id="website.cardApplication.output.debitAmount"]').length) {
saitama.rmStyleById('opContinueBisInactive', () => false)
saitama.rmStyleById('opContinueInactive', () => false)
saitama.rmStyleById('opCalcInactive', () => false)
}
} catch (stylingStep1Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep1 error: `, stylingStep1Err)
}
}
/**
********************************************************
* Modifications for Step 2: PersonalDetails
********************************************************
*/
const stylingStep2 = function stylingStep2 () {
try {
const alsoLog = false
const cbkLogStep2 = cbkLog('Step 2_PersonalDetails', alsoLog)
// Inactivate the PostCode button until there is an entry in the money field.
// If the field is already filled in, leave the button active.
if (jQ('input[id="website.cardApplication.label.addressLookupPostcode"]').val() === '') {
const cssPostcodeSelector = 'div.registerCardLookupPostCodeButton div.buttonRight'
saitama.rmStyleById('opPostCodeInactive', () => false)
saitama.addStyle(`${cssPostcodeSelector} ${opOpacityCSS}`, 'opPostCodeInactive', () => false)
jQ('input[id="website.cardApplication.label.addressLookupPostcode"]').on('focus, change, blur, input', () => saitama.rmStyleById('opPostCodeInactive', () => false))
}
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep2Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep2 error: `, stylingStep2Err)
}
}
/**
********************************************************
* Modifications for Step 3: IdentityDetails
********************************************************
*/
const stylingStep3 = function stylingStep3 () {
try {
const alsoLog = false
const cbkLogStep3 = cbkLog('Step 3_IdentityDetails', alsoLog)
const cssContinueSelector = 'div#mainContainer > div.buttonBar:last-child div.buttonRight'
saitama.addStyle(`${cssContinueSelector} ${opOpacityCSS}`, 'opContinueInactive')
// Step 3 has no mandatory field but at least one must be filled in to continue.
// Making the choice more obvious by adding OR between the 2 text inputs.
const additionalOrElt = '<p style="margin-bottom: 0px; margin-top: 5px; margin-right: 14px;">OR</p>'
jQ('span.additionaldataOr').append(additionalOrElt)
// Activates button right away as this forms is optional.
if (window.$optg.ieVer() < 100) {
window.jQuery('input[id="additionalDetailsReference.label.KYC110.FRT_PASSPORTNO"], input[id="additionalDetailsReference.label.KYC220.FRT_UKDVL"]').live('focus, change, blur, input', () => saitama.rmStyleById('opContinueInactive', () => false))
} else {
jQ('input[id="additionalDetailsReference.label.KYC110.FRT_PASSPORTNO"], input[id="additionalDetailsReference.label.KYC220.FRT_UKDVL"]').on('focus, change, blur, input', () => saitama.rmStyleById('opContinueInactive', () => false))
}
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep3Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep3 error: `, stylingStep3Err)
}
}
/**
********************************************************
* Modifications for Step 4: SecurityDetails
********************************************************
*/
const stylingStep4 = function stylingStep4 () {
try {
const alsoLog = false
const cbkLogStep4 = cbkLog('Step 4_SecurityDetails', alsoLog)
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep4Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep4 error: `, stylingStep4Err)
}
}
/**
********************************************************
* Modifications for Step 5: Agreement
********************************************************
*/
const stylingStep5 = function stylingStep5 () {
try {
const alsoLog = false
const cbkLogStep5 = cbkLog('Step 5_Agreement', alsoLog)
const cssContinueSelector = 'div#mainContainer > div.buttonBar:last-child div.buttonRight'
const termsAndConditionChecked = () => jQ('input[id="website.cardApplication.label.termsAndConditions"]:checked').length
if (termsAndConditionChecked()) {
saitama.rmStyleById('opContinueInactive', () => false)
} else {
saitama.addStyle(`${cssContinueSelector} ${opOpacityCSS}`, 'opContinueInactive')
}
// In case of error, div.pair becomes div.boxed
const checkBoxCSS = jQ('div#mainContainer > div.boxed:last').length ? 'div#mainContainer > div.boxed:last' : 'div#mainContainer > div.pair:last'
const toggleCSS = () => {
if (termsAndConditionChecked()) saitama.rmStyleById('opContinueInactive', () => false)
else saitama.addStyle(`${cssContinueSelector} ${opOpacityCSS}`, 'opContinueInactive')
}
if (window.$optg.ieVer() < 100) window.jQuery(checkBoxCSS).live('click', toggleCSS)
else jQ(checkBoxCSS).on('click', toggleCSS)
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep5Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep5 error: `, stylingStep5Err)
}
}
/**
********************************************************
* Modifications for Step 6: Summary
********************************************************
*/
const stylingStep6 = function stylingStep6 (isFirstLoad) {
try {
const alsoLog = false
const cbkLogStep6 = cbkLog('Step 6_Summary', alsoLog)
// Continue button has a little brother, we need to be more specific when targetting the button.
saitama.rmStyleById('opContinueInactive', () => false)
const cssContinueSelector = 'div#mainContainer > div.buttonBar:last-child div.buttonRight:first-child'
saitama.addStyle(`${cssContinueSelector} ${opOpacityCSS}`, 'opContinueInactive')
// Hides the currency line.
const currencyLine = jQ('label[for="website.cardApplication.label.currency"]').parent()
currencyLine.hide()
if (isFirstLoad) {
// Transforms the forms input, checkbox and select in plain text as this is a summary.
jQ('div.tooltipContainer').hide()
jQ('div.pair').each(
(index, elt) => {
if (index !== 26 && index !== 27) { // We do nothing in the Captcha.
const jQelt = jQ(elt)
const jQspanData = jQelt.find('.data')
if (/21|22|23|24/.test(index)) { // Series of checkbox.
const data = jQspanData.find('input').val() && '*' || 'o'
jQspanData.append(`<span class="info" style="font-size: 100%;">${data}</span>`)
jQspanData.find('input').hide()
} else if (index === 17 || index === 19) { // Passport and driving licence.
const data = jQelt.find('span.pair input').val()
jQelt.append(`<span class="info" style="float: left; font-size: 100%;">${data}</span>`)
jQelt.find('span.pair').hide()
} else {
let data = jQspanData.find('input').val() || jQspanData.find('select option:selected').text() || ''
if (index === 16) {
data = data.replace(/(\d\d)(\d\d)(\d\d\d\d)/, '$1/$2/$3')
}
jQelt.append(`<span class="info" style="float: left; font-size: 100%;">${data}</span>`)
jQspanData.hide()
}
}
}
)
} else {
saitama.rmStyleById('opContinueInactive', () => false)
}
// Clones the Edit button on top of the form.
const editInput = jQ('input#website_general_button_edit')
const editButton = editInput.parent().parent()
jQ('div.formHeaderContainer')
.append(editButton
.clone()
.attr('style', 'float: right; margin-top: -3px;')
.addClass('buttonClone')
)
// Redirects the clicks to the original button.
jQ('div.buttonClone').on('click', () => editInput.click())
if (jQ('input[id="website.cardApplication.label.captchaText"]').val()) saitama.rmStyleById('opContinueInactive', () => false)
else jQ('input[id="website.cardApplication.label.captchaText"]').on('focus, change, blur, input', () => saitama.rmStyleById('opCalcInactive', () => false))
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep6Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep6 error: `, stylingStep6Err)
}
}
/**
********************************************************
* Modifications for Step 7: PaymentDetails
********************************************************
*/
const stylingStep7 = function stylingStep7 () {
try {
const alsoLog = false
const cbkLogStep7 = cbkLog('Step 7_PaymentDetails', alsoLog)
// Renames the availableToLoad extra line.
jQ('span[id="website.cardApplication.label.availableToLoad"]').text('Maximum you can load, on your card').removeClass('bold')
// Adding Max load in the apropriate tooltip.
jQ('div.tooltipContainer[title="Minimum load is £50."] div.tooltipContentContainer')
.append('<div class="toolTipContent" style="margin-top: 2px;">Maximum load is £5000.</span>')
// Places the Calculate button between the Money input and the tooltip '?'.
const form = jQ('div#mainContainer')
const moneySpan = jQ('div#cardApplicationUnAuthCalculateButtonBar').parent()
const tooltipDiv = moneySpan.find('div.tooltipContainer')
tooltipDiv.remove()
moneySpan.append(tooltipDiv)
jQ('div#cardApplicationUnAuthCalculateButtonBar').attr('style', 'width: 120px; margin-top: -2px; padding: 0 0;')
// Moves the cancel top up button on the left side and makes it look like a link rather than a button.
const cancelTopUpInput = jQ('input[id="website.cardApplication.label.cancelTopUp"]')
const cancelTopUpBtn = cancelTopUpInput.parent().parent()
const cancelTopUpSpans = cancelTopUpBtn.find('span')
cancelTopUpSpans.hide()
cancelTopUpBtn
.removeClass('buttonRight')
.addClass('buttonLeft')
.attr('style', 'margin-left: 10px;')
.append(cancelTopUpInput.attr('style', 'text-decoration-line: underline; color: black;'))
// All fields below the calculate button are "deactivated" unless the amount loaded is being displayed.
if (!jQ('span[id="website.cardApplication.label.amountToBeLoaded"]').length) {
form.find('div.pair:gt(3)').attr('style', 'filter:opacity(50%); -webkit-filter: opacity(0.5); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; opacity: 0.5;')
// Removes the value 50.00 from the 'Calculate' input box as well.
jQ('input[id="website.cardApplication.label.topUpAmount"]').attr('value', '')
}
// Makes buy button bigger.
jQ('input[id="website.general.button.buy"]').attr('style', 'font-size: 110%; padding-bottom: 0px; margin-bottom: 0px; padding-top: 4px;')
// Removes Start Date and Issue Number fields.
// Only reveals these fields if required from Maestro card selected.
const startDateline = jQ('fieldset[id="website.cardApplication.legend.startDate"]').parent()
const issueNumberline = jQ('label[for="website.cardApplication.label.issueNumber"]').parent()
startDateline.hide()
issueNumberline.hide()
const selectCard = jQ('select[id="website.cardApplication.label.cardType"]')
selectCard.on('change', evt => {
const cardType = selectCard.find('option:selected').text() || ''
if (/Maestro/i.test(cardType)) {
startDateline.show()
issueNumberline.show()
} else {
startDateline.hide()
issueNumberline.hide()
}
})
// Continue button has a little brother, we need to be more specific when targetting the button.
saitama.rmStyleById('opContinueInactive', () => false)
const cssContinueSelector = 'div#mainContainer > div.buttonBar:last-child div.buttonRight:first-child'
saitama.addStyle(`${cssContinueSelector} ${opOpacityCSS}`, 'opContinueInactive')
// The page might reload if one entry is wrong.
// If all fields are filled in, we activate continue button.
let cond = () => {
const formFields = jQ('div#mainContainer').find('input, textarea, select')
const mandatoryFields = jQ(formFields.filter((index, elt) => { // Filters out all non mandatory fields.
const cousins = elt.parentElement.previousElementSibling && elt.parentElement.previousElementSibling.firstElementChild || ''
return cousins && /mandatory/i.test(cousins && cousins.className || '')
}))
return mandatoryFields.filter((index, elt) => !elt.value).length < 1
}
if (cond()) saitama.rmStyleById('opContinueInactive', () => false)
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep7Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep7 error: `, stylingStep7Err)
}
}
/**
********************************************************
* Modifications for Step 8: Confirmation
********************************************************
*/
const stylingStep8 = function stylingStep8 () {
try {
const alsoLog = false
const cbkLogStep8 = cbkLog('Step 8_Confimration', alsoLog)
// Changes header title.
jQ('h2[id="website.cardApplication.label.header1"]').text('Thank you.')
// hides the required field annotation.
jQ('p[id="website.general.requiredFields"]').hide()
// Removes the buttonBar and includes the continue button at the bottom of the form.
const buttonbar = jQ('div.submitButtonsBar')
jQ('div#mainContainer').append(buttonbar.find('div.buttonBar').remove()).attr('style', 'padding-bottom: 0px; margin-bottom: 30px;')
buttonbar.remove()
// Moves the cancel top up button on the left side and makes it look like a link rather than a button.
const backToLoginInput = jQ('input[id="website_cardApplication_button_backToLogin"]')
const backToLoginBtn = backToLoginInput.parent().parent()
const backToLoginSpans = backToLoginBtn.find('span')
backToLoginSpans.hide()
backToLoginBtn
.removeClass('buttonRight')
.addClass('buttonLeft')
.attr('style', 'margin-left: 10px;')
.append(backToLoginInput.attr('style', 'text-decoration-line: underline; color: black;').attr('value', 'Back to PostOffice'))
jQ('div#cardApplicationButtonBackToLogin').show()
// Reactivates the form submit but redirects to Post Office HP instead of the TMC Login page.
jQ('form#cardApplicationUnAuth').attr('action', 'http://www.postoffice.co.uk/')
saitama.rmStyleById('optimost_css_HideFormInputs', () => false) // Style has been added via the setup module.
} catch (stylingStep8Err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling stylingStep8 error: `, stylingStep8Err)
}
}
const selectStylingStep = function selectStylingStep (TMCBookingStep) {
if (TMCBookingStep) {
try {
if (/1_Quote/i.test(TMCBookingStep))/* */ stylingStep1()
else if (/2_PersonalDetails/i.test(TMCBookingStep))/**/ stylingStep2()
else if (/3_IdentityDetails/i.test(TMCBookingStep))/**/ stylingStep3()
else if (/4_SecurityDetails/i.test(TMCBookingStep))/**/ stylingStep4()
else if (/5_Agreement/i.test(TMCBookingStep))/* */ stylingStep5()
else if (/6_Summary/i.test(TMCBookingStep))/* */ stylingStep6(true)
else if (/7_PaymentDetails/i.test(TMCBookingStep))/* */ stylingStep7()
else if (/8_Confirmation/i.test(TMCBookingStep))/* */ stylingStep8()
else saitama.log('Travel Money Card Funnel 1_styling selectStylingStep, step is out of the booking journey. window.optrial.TMCBookingStep returns ', TMCBookingStep)
} catch (selectStylingStepErr) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling selectStylingStep error: `, selectStylingStepErr)
}
} else if (/actionExitCardApplication/i.test(window.document && window.document.URL)) {
stylingStep8()
} else {
if (saitama.log) saitama.log(`Travel Money Card Funnel 1_styling selectStylingStep non Entry, window.optrial.TMCBookingStep returns `, TMCBookingStep)
}
}
selectStylingStep(window.optrial ? window.optrial.TMCBookingStep : 0) // On first page load.
if (window.jQuery(document) && window.jQuery(document).ajaxComplete) {
window.jQuery(document).ajaxComplete((event, xhr, settings) => {
const updateForm = function updateForm () {
// Tooltips as title (show on hover).
const tooltipContainers = jQ('div.tooltipContainer')
if (tooltipContainers.length) {
tooltipContainers.map((ind, b) => b.title = jQ(b).find('div.toolTipContent').text())
}
// Removes the buttonBar and includes the continue button at the bottom of the form.
const buttonbar = jQ('div.submitButtonsBar.clearBoth')
jQ('div#mainContainer').append(buttonbar.find('div.buttonBar').remove()).attr('style', 'padding-bottom: 0px; margin-bottom: 30px;')
buttonbar.remove()
}
if (xhr && xhr.status === '200' || xhr.statusText === 'OK') {
updateForm()
if (xhr.responseURL) {
saitama.log('Travel Money Card Funnel 1_styling ajaxComplete event fired, responseURL is ', xhr.responseURL)
xhr.responseURL.replace(/.+_cardApplicationUnAuth_WAR_Website_action([^=]*)=.+/i, (match, p1, offset, string) => {
saitama.log('Travel Money Card Funnel 1_styling ajaxComplete event fired, replace called with p1: ', p1)
if (/Calculate/i.test(p1)) {
if (/1_Quote/.test(window.optrial && window.optrial.TMCBookingStep || '')) {
stylingStep1()
} else if (/7_PaymentDetails/.test(window.optrial && window.optrial.TMCBookingStep || '')) {
stylingStep7()
} else {
saitama.log('Travel Money Card Funnel 1_styling ajaxComplete replace, Calculate test for an unknown steps. Doing nothing, gives up..')
// This is not supposed to happen!, do nothing.
}
} else if (/LookupPostCode/i.test(p1)) {
stylingStep2()
} else if (/SelectTimeAtAddress/i.test(p1)) {
stylingStep2()
} else if (/CardApplicationApplicantDetailsCaptchaRefresh/i.test(p1)) {
stylingStep6(true)
} else if (/EditDetails/i.test(p1)) {
stylingStep6(false)
} else if (/actionExitCardApplication/i.test(window.document && window.document.URL)) {
stylingStep8();
} else {
saitama.log('Travel Money Card Funnel 1_styling ajaxComplete replace, unknown test for an unknown steps. Doing nothing, gives up..')
// This is not supposed to happen!, do nothing.
}
})
} else {
const funnelStep = window.parseInt(jQ('span.progressBarTextLive').text() || 0)
if (funnelStep === 1) {
stylingStep1()
} else if (funnelStep === 2) {
stylingStep2()
} else if (funnelStep === 3) {
stylingStep3()
} else if (funnelStep === 4) {
stylingStep4()
} else if (funnelStep === 5) {
stylingStep5()
} else if (funnelStep === 6) {
stylingStep6()
} else if (funnelStep === 7) {
stylingStep7()
} else if (/actionExitCardApplication/i.test(window.document && window.document.URL)) {
stylingStep8()
} else {
saitama.log('Travel Money Card Funnel 1_styling parseInt step, unknown test for an unknown steps. Doing nothing, gives up..')
}
}
}
})
} else {
saitama.log('Travel Money Card Funnel 1_styling ajaxComplete event not attached. window.jQuery(document).ajaxComplete returns ', window.jQuery(document) && window.jQuery(document).ajaxComplete)
}
} catch (err) {
if (saitama.log) saitama.log(`! Travel Money Card Funnel 1_styling Error: `, err)
}
} else {
if (saitama.log) {
saitama.log('! Travel Money Card Funnel 1_styling condition not met for execution: ', {
trial
, most
, 'rmStyleById': saitama.rmStyleById
, 'addStyle': saitama.addStyle
, 'jQuery': most.jQuery
})
}
}
return trial && most && saitama && saitama.rmStyleById && saitama.addStyle && most.jQuery
}(window.$optt ? window.$optt.s030t073_TravelMoneyCardFunnel : 0, window.optimost, window.optimost ? window.optimost.saitama : 0)
)
// </script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment