Skip to content

Instantly share code, notes, and snippets.

@Strongground
Last active May 5, 2023 07:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Strongground/e5788398e7ffb96f1a555a19ab78ba22 to your computer and use it in GitHub Desktop.
Save Strongground/e5788398e7ffb96f1a555a19ab78ba22 to your computer and use it in GitHub Desktop.
ScanBlue A/B Test Snippet, adding inline all necessary code to display two buttons according to CC-16566
const version = '1.1.2';
/**
* Returns the HTML for the modal, which is used for both AR and 3D.
* @param {String} id The ID of the type of modal, can only be "ar" or "3d". Is used for class names and data attributes.
* @returns {String} The HTML for the modal
*/
function getModal(id) {
return `<div class="modal fade modal-scanblue modal-scanblue-${id}" data-scanblue-type="${id}" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content modal-bg-white">
<div class="modal-header">
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<iframe></iframe>
</div>
</div>
</div>
</div>`;
}
let loading_spinner = `<div class="spinner-scanblue hidden">
<div class="spinner-scanblue-inner">
<div></div>
</div>
</div>`;
/**
* Method to toggle the modal and dynamically add or remove the AR URL from the iframe inside the modal to prevent a autoload-bug.
* @param {String} id The ID of the type of modal, can only be "ar" or "3d"
* @param {String | null} url The src URL for the iframe inside the modal or null. If null, any src URL is stripped from the modal iframe.
* This is to prevent a bug where the AR mode will launch as soon as the modal with iframe with AR src-URL is added to the sites html code.
*/
function toggleModal(id, url) {
document.querySelector('html').classList.toggle('modal-open');
let modal = document.querySelector(`.modal-scanblue-${id}`);
let modal_iframe = modal.querySelector('iframe');
modal.querySelector('.modal-backdrop.scanblue').classList.toggle('show');
modal.classList.toggle('show');
// If url is null, remove the src attribute from the iframe
if (url === null) {
modal_iframe.removeAttribute('src');
} else if (url === 'keep') {
// Do nothing
} else {
modal_iframe.setAttribute('src', url)
}
}
ready(function () {
console.log(`ScanBlue AB Test Script loaded - v${version}`)
let compareResult = isTargetPage(window.location.pathname);
console.log(`ScanBlue AB Test Script - isTarget: ${JSON.stringify(compareResult)}`);
if (compareResult.isTarget) {
// Inject loading spinner for later use
document.body.insertAdjacentHTML('beforeend', loading_spinner);
// inject ScanBlue script
let script = document.createElement('script');
script.src = 'https://ar.scanblue.cloud/assets/scanblue.3.js';
script.async = true;
document.head.appendChild(script);
// Inject inline CSS
let css = document.createElement('style');
css.innerHTML = `
a.btn-scanblue {
display: inline-block;
background-color: #fff;
border: 2px solid #EE1C25;
border-radius: 3px;
font-family: 'Futura Bold', sans-serif;
font-style: normal;
font-weight: 700;
font-size: 14px;
line-height: 140%;
text-transform: uppercase;
color: #EE1C25;
position: relative;
z-index: 99;
padding: 8px 16px 8px 18px;
margin-right: 16px;
cursor: pointer;
text-align: center;
}
a.btn-scanblue:not([href]):not([tabindex]), a.btn-scanblue:not([href]):not([tabindex]):focus {
color: #EE1C25;
}
a.btn-scanblue:last-child {
margin-right: 0;
}
a.btn-scanblue:hover,
a.btn-scanblue:not([href]):not([tabindex]):hover {
border-color: #D40009;
color: #D40009;
}
a.btn-scanblue svg.icon {
margin-right: 10px;
height: 20px;
width: 20px;
}
a.btn-scanblue svg.icon * {
fill: currentColor;
}
.scanblue-buttons {
position: absolute;
left: 0;
margin: 10px;
}
.modal-backdrop.scanblue {
position: relative;
left: -9999px;
}
.modal-backdrop.scanblue.show {
left: 0;
position: fixed;
}
.modal.modal-scanblue.show {
display: block;
}
.modal-scanblue iframe {
border: none;
width: 100%;
height: 466px;
}
.modal-scanblue .modal-dialog {
z-index: 1050;
}
.modal-scanblue .hidden {
display: none;
}
/* Modal sizes */
.modal-scanblue.modal-scanblue-ar .modal-dialog {
max-width: 50vw;
width: 50vw;
}
.modal-scanblue.modal-scanblue-ar iframe {
height: 70vh;
}
.modal-scanblue.modal-scanblue-3d .modal-dialog {
max-width: 90vw;
width: 90vw;
}
.modal-scanblue.modal-scanblue-3d iframe {
height: 75vh;
}
/* Desktop */
@media (min-width: 1210px) {
.scanblue-buttons {
bottom: 140px;
}
}
/* Between 1024 and 0 */
@media (min-width: 1023px) {
.modal-scanblue.modal-scanblue-ar .modal-dialog {
max-width: 70vw;
width: 70vw;
}
}
/* Between 1024 and 1210 */
@media (min-width: 1024px) and (max-width: 1210px) {
.scanblue-buttons {
bottom: 90px;
}
}
/* Between 530 and 1024 */
@media (min-width: 530px) and (max-width: 1023px) {
.scanblue-buttons {
width: 100%;
bottom: auto;
position: relative;
margin: 0;
}
}
/* Mobile between 425 and 530 */
@media (min-width: 425px) and (max-width: 529px) {
.scanblue-buttons {
width: 100%;
bottom: auto;
position: relative;
margin: 0;
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
}
a.btn-scanblue {
flex-grow: 1;
margin-bottom: 0;
margin-right: 0;
padding: 8px 13px;
}
}
/* Mobile Below 424 */
@media (max-width: 424px) {
.scanblue-buttons {
width: 100%;
bottom: auto;
position: relative;
margin: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 16px;
}
a.btn-scanblue {
margin: 0;
}
}
/* Loading spinner */
@keyframes spinner-scanblue-inner {
0% { transform: translate(-50%,-50%) rotate(0deg); }
100% { transform: translate(-50%,-50%) rotate(360deg); }
}
.spinner-scanblue-inner div {
position: absolute;
width: 55px;
height: 55px;
border: 6px solid #ee1c25;
border-top-color: transparent;
border-radius: 50%;
}
.spinner-scanblue-inner div {
animation: spinner-scanblue-inner 1s linear infinite;
top: 50%;
left: 50%;
}
.spinner-scanblue {
z-index: 9999;
width: 110px;
height: 110px;
display: inline-block;
overflow: hidden;
background: white;
position: fixed;
top: 50%;
left: 35%;
border-radius: 10px;
opacity: 1;
box-shadow: rgba(0,0,0,.15) 0px 5px 15px;
transition: opacity .3s ease;
}
.spinner-scanblue.hidden {
display: none;
opacity: 0;
}
.spinner-scanblue-inner {
width: 100%;
height: 100%;
position: relative;
transform: translateZ(0) scale(1);
backface-visibility: hidden;
transform-origin: 0 0;
}
.spinner-scanblue-inner div {
box-sizing: content-box;
}
`;
document.head.appendChild(css);
let modal_backdrop = `<div class="modal-backdrop scanblue fade"></div>`;
let modal_ar = getModal('ar', compareResult.urls['augmented']);
let modal_3d = getModal('3d', compareResult.urls['threesixty']);
document.querySelector('.sfra-modals').insertAdjacentHTML('beforeend', modal_ar);
document.querySelector('.sfra-modals').insertAdjacentHTML('beforeend', modal_3d);
document.querySelectorAll('.modal.modal-scanblue').forEach((modal) => {
modal.insertAdjacentHTML('beforeend', modal_backdrop);
});
// Define buttons to inject
let btn_ar = document.createElement('a');
btn_ar.classList.add('btn-scanblue', 'btn-scanblue-ar');
btn_ar.innerHTML = `
<svg class="icon icon-ar" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 2C0 0.895431 0.89543 0 2 0H6C6.55228 0 7 0.447715 7 1C7 1.55228 6.55228 2 6 2H2V6C2 6.55228 1.55228 7 1 7C0.447715 7 0 6.55228 0 6V2Z" fill="black"/>
<path d="M20 18C20 19.1046 19.1046 20 18 20H14C13.4477 20 13 19.5523 13 19C13 18.4477 13.4477 18 14 18H18V14C18 13.4477 18.4477 13 19 13C19.5523 13 20 13.4477 20 14V18Z" fill="black"/>
<path d="M20 6V2C20 0.895431 19.1046 0 18 0H14C13.4477 0 13 0.447715 13 1C13 1.55228 13.4477 2 14 2L18 2V6C18 6.55228 18.4477 7 19 7C19.5523 7 20 6.55228 20 6Z" fill="black"/>
<path d="M0 18V14C0 13.4477 0.447716 13 1 13C1.55229 13 2 13.4477 2 14L2 18H6C6.55228 18 7 18.4477 7 19C7 19.5523 6.55228 20 6 20H2C0.89543 20 0 19.1046 0 18Z" fill="black"/>
<path d="M9.03179 3.54223C9.63009 3.14471 10.4127 3.15275 11.0036 3.56634L15.0036 6.36634C15.4714 6.69382 15.75 7.22895 15.75 7.8V12.7587C15.75 13.3297 15.4714 13.8649 15.0036 14.1923L11.0036 16.9923C10.4127 17.4059 9.6301 17.414 9.03179 17.0165L4.99644 14.1923C4.52862 13.8649 4.25 13.3297 4.25 12.7587V7.8C4.25 7.22895 4.52862 6.69382 4.99644 6.36634L9.03179 3.54223ZM10.1434 4.79519C10.0573 4.73494 9.94271 4.73494 9.85663 4.79519L6.28115 7.2994L9.91603 9.72265L13.6379 7.24138L10.1434 4.79519ZM5.75 12.7587C5.75 12.8318 5.782 12.9009 5.8368 12.9481L9.16603 15.2798V11.0254L5.75 8.74808V12.7587ZM14.1434 12.9635C14.2102 12.9167 14.25 12.8403 14.25 12.7587V8.63611L10.666 11.0254V15.3976L14.1434 12.9635Z" fill="black"/>
</svg>
<span>Im Raum ansehen</span>
`;
btn_ar.addEventListener('click', function() {
if (window.matchMedia('(max-width: 1023px)').matches) {
let url = compareResult.urls['augmented']
let spinner = document.querySelector('.spinner-scanblue');
spinner.classList.remove('hidden');
window.open(url, '_self');
// Set delay of 1 second after which the spinner is hidden again
setTimeout(function() {
spinner.classList.add('hidden');
}, 1000);
} else {
toggleModal('ar', compareResult.urls['augmented']);
}
});
let btn_3d = document.createElement('a');
btn_3d.classList.add('btn-scanblue', 'btn-scanblue-3d');
btn_3d.innerHTML = `
<svg class="icon icon-360" width="20" height="15" viewBox="0 0 20 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.6794 1.50932C16.8142 1.57971 16.9624 1.61491 17.1241 1.61491C17.2858 1.61491 17.4318 1.57971 17.562 1.50932C17.6968 1.43478 17.8024 1.33747 17.8787 1.21739C17.9596 1.09317 18 0.956522 18 0.807453C18 0.662526 17.9596 0.52795 17.8787 0.403727C17.8024 0.279503 17.6968 0.182194 17.562 0.111801C17.4273 0.0372671 17.2813 0 17.1241 0C16.9669 0 16.8209 0.0372671 16.6861 0.111801C16.5514 0.182194 16.4436 0.279503 16.3627 0.403727C16.2864 0.52795 16.2482 0.662526 16.2482 0.807453C16.2482 0.956522 16.2864 1.09317 16.3627 1.21739C16.4436 1.33747 16.5491 1.43478 16.6794 1.50932ZM17.4071 1.07453C17.3307 1.14493 17.2364 1.18012 17.1241 1.18012C17.0118 1.18012 16.9152 1.14493 16.8344 1.07453C16.758 1 16.7198 0.910973 16.7198 0.807453C16.7198 0.703934 16.758 0.616977 16.8344 0.546584C16.9152 0.47619 17.0118 0.440994 17.1241 0.440994C17.2364 0.440994 17.3307 0.47619 17.4071 0.546584C17.4879 0.616977 17.5284 0.703934 17.5284 0.807453C17.5284 0.910973 17.4879 1 17.4071 1.07453Z" fill="black"/>
<path d="M4.77484 4.84472C5.02189 4.94824 5.30937 5 5.63727 5C6.00111 5 6.3133 4.94617 6.57382 4.83851C6.83884 4.73085 7.04097 4.57764 7.18022 4.37888C7.31947 4.18012 7.38909 3.94824 7.38909 3.68323C7.38909 3.48861 7.35091 3.31263 7.27455 3.15528C7.20268 2.99793 7.09712 2.86749 6.95787 2.76397C6.81863 2.65631 6.65468 2.58385 6.46602 2.54658C6.62772 2.52174 6.76922 2.46377 6.8905 2.37267C7.01178 2.28157 7.1061 2.1677 7.17348 2.03106C7.24086 1.89441 7.27455 1.74327 7.27455 1.57764C7.27455 1.33747 7.21166 1.13043 7.08589 0.956522C6.96461 0.778468 6.78943 0.641822 6.56035 0.546584C6.33126 0.447205 6.06175 0.397515 5.75182 0.397515C5.26221 0.397515 4.8804 0.498965 4.6064 0.701863C4.33689 0.904762 4.1909 1.19462 4.16844 1.57143H5.08478C5.10724 1.42236 5.17012 1.30849 5.27344 1.22981C5.38124 1.15114 5.52947 1.1118 5.71813 1.1118C5.8978 1.1118 6.04154 1.16149 6.14934 1.26087C6.25715 1.35611 6.31105 1.4824 6.31105 1.63975C6.31105 1.82195 6.25041 1.96066 6.12913 2.0559C6.01234 2.15114 5.83492 2.19876 5.59685 2.19876L5.48231 2.19255V2.96894L5.61032 2.96273C5.87534 2.96273 6.07523 3.01863 6.20998 3.13043C6.34923 3.24224 6.41885 3.4058 6.41885 3.62112C6.41885 3.82402 6.35148 3.98137 6.21672 4.09317C6.08646 4.20497 5.90005 4.26087 5.65749 4.26087C5.51824 4.26087 5.39472 4.23809 5.28691 4.19255C5.17911 4.147 5.09601 4.08282 5.03761 4C4.97922 3.91718 4.95002 3.82402 4.95002 3.7205V3.70807H4V3.74534C4 3.98965 4.06738 4.20704 4.20213 4.39752C4.33689 4.58799 4.52779 4.73706 4.77484 4.84472Z" fill="black"/>
<path d="M8.93393 4.80745C9.18098 4.93582 9.46846 5 9.79636 5C10.1422 5 10.4454 4.93789 10.706 4.81366C10.971 4.6853 11.1754 4.50725 11.3191 4.2795C11.4628 4.04762 11.5347 3.78054 11.5347 3.47826C11.5347 3.21325 11.4741 2.97723 11.3528 2.77019C11.236 2.56315 11.0698 2.40166 10.8542 2.28571C10.6431 2.16563 10.4028 2.10559 10.1333 2.10559C10.012 2.10559 9.90192 2.11387 9.8031 2.13043C9.70877 2.147 9.6122 2.18012 9.51338 2.22981L10.8879 0.484472H9.73572L8.97436 1.55901C8.70485 1.93996 8.50271 2.28778 8.36796 2.60248C8.2377 2.91304 8.17256 3.2029 8.17256 3.47205C8.17256 3.77433 8.2377 4.04141 8.36796 4.27329C8.50271 4.50103 8.69137 4.67909 8.93393 4.80745ZM10.2276 4.13043C10.1198 4.18841 9.994 4.21739 9.85027 4.21739C9.62567 4.21739 9.446 4.15528 9.31124 4.03106C9.17649 3.90683 9.10911 3.73499 9.10911 3.51553C9.10911 3.37888 9.13831 3.25673 9.1967 3.14907C9.25959 3.03727 9.34493 2.95238 9.45274 2.89441C9.56054 2.8323 9.68407 2.80124 9.82331 2.80124C10.0614 2.80124 10.2455 2.86542 10.3758 2.99379C10.5106 3.12215 10.5779 3.29607 10.5779 3.51553C10.5779 3.65217 10.5465 3.77433 10.4836 3.88199C10.4252 3.98965 10.3399 4.07246 10.2276 4.13043Z" fill="black"/>
<path d="M13.9824 5C14.3462 5 14.6607 4.91097 14.9257 4.73292C15.1952 4.55072 15.4018 4.28778 15.5456 3.9441C15.6893 3.59627 15.7612 3.18012 15.7612 2.69565C15.7612 2.20704 15.6893 1.79089 15.5456 1.4472C15.4063 1.10352 15.2019 0.84265 14.9324 0.664596C14.6674 0.486542 14.3507 0.397515 13.9824 0.397515C13.6141 0.397515 13.2952 0.488613 13.0256 0.670807C12.7606 0.853002 12.5562 1.11594 12.4125 1.45963C12.2733 1.80331 12.2036 2.21532 12.2036 2.69565C12.2036 3.18012 12.2733 3.59627 12.4125 3.9441C12.5562 4.28778 12.7606 4.55072 13.0256 4.73292C13.2952 4.91097 13.6141 5 13.9824 5ZM13.9757 4.18012C13.7241 4.18012 13.531 4.05383 13.3962 3.80124C13.266 3.54451 13.2008 3.17805 13.2008 2.70186C13.2008 2.21739 13.2682 1.84886 13.403 1.59627C13.5377 1.33954 13.7309 1.21118 13.9824 1.21118C14.2339 1.21118 14.4248 1.33747 14.5551 1.59006C14.6899 1.83851 14.7572 2.20497 14.7572 2.68944C14.7572 3.17805 14.6899 3.54865 14.5551 3.80124C14.4248 4.05383 14.2317 4.18012 13.9757 4.18012Z" fill="black"/>
<path d="M0 6.99999C0 5.78941 0.861883 4.67886 2.29537 3.8135C2.61212 3.62228 3 3.86236 3 4.23235V5.46927C3 5.63349 2.91798 5.78573 2.7882 5.88636C2.27277 6.286 2 6.68247 2 6.99999C2 7.82999 3.85 9.16999 7 9.72999V8.2071C7 7.76164 7.53857 7.53856 7.85355 7.85354L11 11L7.85355 14.1464C7.53857 14.4614 7 14.2383 7 13.7929V11.77C2.94 11.13 0 9.23999 0 6.99999Z" fill="black"/>
<path d="M18 6.99999C18 6.68247 17.7272 6.286 17.2118 5.88636C17.082 5.78573 17 5.63349 17 5.46927V4.23235C17 3.86236 17.3879 3.62228 17.7046 3.8135C19.1381 4.67886 20 5.78941 20 6.99999C20 8.80477 18.0856 10.3848 15.2188 11.2624C14.5999 11.4519 14 10.9678 14 10.3205C14 9.85572 14.318 9.45481 14.7607 9.31331C16.8293 8.65216 18 7.65367 18 6.99999Z" fill="black"/>
</svg>
<span>360° Ansicht</span>
`;
btn_3d.addEventListener('click', () => {
toggleModal('3d', compareResult.urls['threesixty']);
});
// Event listener for modal close button and the modal backdrop elements
document.querySelectorAll('.modal-scanblue .close, .modal-backdrop.scanblue').forEach(function (el) {
el.addEventListener('click', function () {
toggleModal(el.closest('.modal-scanblue').getAttribute('data-scanblue-type'), null);
});
});
// Inject buttons
let btn_target = document.querySelector('.product-image-container');
let btn_container = document.createElement('div');
btn_container.classList.add('scanblue-buttons');
btn_target.appendChild(btn_container);
btn_container.appendChild(btn_ar);
btn_container.appendChild(btn_3d);
// Additionally mark the product image container
btn_target.classList.add('scanblue');
}
});
// Compare pathname with a given list of SKUS. If one SKU is contained
// in the pathname, return corresponding data object.
function isTargetPage(pathname) {
let skus = [
{
sku: "54532-007-0",
id: "scanblue-bDccRxC",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre031709bzd2d47s1dldxu",
augmented: "https://ar.scanblue.com/eRaSBv",
}
},
{
sku: "35621-004-0",
id: "scanblue-4lQ7Ssn",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre03174uyenxvg6j4c03vs",
augmented: "https://ar.scanblue.com/CzBXCv",
}
},{
sku: "40509-356-0",
id: "scanblue-eikU9Pz",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317c3z79vhqh1yw0q25",
augmented: "https://ar.scanblue.com/mn2P2V",
}
},{
sku: "40500-241-0",
id: "scanblue-g8ZUJU7",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317b2any79vofpy97ml",
augmented: "https://ar.scanblue.com/lx9I8l",
}
},{
sku: "40502-294-0",
id: "scanblue-4x8sAeo",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317u5s2vcb508cto5gj",
augmented: "https://ar.scanblue.com/wQylim",
}
},{
sku: "40509-835-0",
id: "scanblue-PNQK793",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317ui2huny9oi6zpne5",
augmented: "https://ar.scanblue.com/cWKQvt",
}
},{
sku: "40511-296-0",
id: "scanblue-qhZsYuG",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317b2any79vofpy97ml",
augmented: "https://ar.scanblue.com/SzaqV1",
}
},{
sku: "40510-283-0",
id: "scanblue-y1FvNZs",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre03177zzstymnbytudixo",
augmented: "https://ar.scanblue.com/r6pGDJ",
}
},{
sku: "40500-246-0",
id: "scanblue-EE9jCrl",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317rc5r0827zo6aebsp",
augmented: "https://ar.scanblue.com/yp0OoR",
}
},{
sku: "40509-357-0",
id: "scanblue-mFrjzyc",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317bfoqpcyd0smc0b8h",
augmented: "https://ar.scanblue.com/7F9oL5",
}
},{
sku: "40508-654-0",
id: "scanblue-UpL2L5K",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre03173h6yj4k9jtd1eu3h",
augmented: "https://ar.scanblue.com/HEN09n",
}
},{
sku: "40505-364-0",
id: "scanblue-uSILVsw",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre03175ngp1lhytii6e2my",
augmented: "https://ar.scanblue.com/kQtBWo",
}
},{
sku: "40501-412-0",
id: "scanblue-03jXRWw",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317c63xc1e06fbalis6",
augmented: "https://ar.scanblue.com/Br2oL9",
}
},{
sku: "36450-280-0",
id: "scanblue-ZhNS1t5",
urls: {
threesixty: "https://vr.scanblue.cloud/nk5the7z6tre0317usf3olmfcvsnoayz",
augmented: "https://ar.scanblue.com/uZbANx",
}
}
]
let result = {'isTarget': false, 'sku': null, 'urls': null, 'id': null};
for (let skuIndex in skus) {
skuObject = skus[skuIndex]
if (pathname.includes(skuObject.sku)) {
result.isTarget = true;
result.sku = skuObject.sku;
result.urls = skuObject.urls;
result.id = skuObject.id;
break;
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment