Skip to content

Instantly share code, notes, and snippets.

@seanemmel-ba
Last active February 14, 2018 20:50
Show Gist options
  • Save seanemmel-ba/0c2679ea3dcebfe7e560 to your computer and use it in GitHub Desktop.
Save seanemmel-ba/0c2679ea3dcebfe7e560 to your computer and use it in GitHub Desktop.
A bookmarklet that enables you to retrieve information about active Optimizely experiments, variations, segments, cookies, and more, all in a GUI modal.
javascript:(function() {
/**
* @package N/A
* @version 1.0
* @author Blue Acorn <[email protected]>, Sean Emmel <[email protected]>
* @copyright Copyright © 2015 Blue Acorn.
*/
function Modal() {
this.el = document.createElement('div');
this.el.id = 'opt-modal-overlay';
this.styles = '#opt-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 10000000000; background-color: rgba(44, 44, 44, 0.6); overflow-y: auto; } #opt-modal-container { position: relative; margin: 10% auto; width: 500px; padding: 20px; z-index: 100000000000; background-color: #fff; border-radius: 2px; box-shadow: 1px 1px 5px 2px #444; font-family: \'Arial\', sans-serif; text-align: left; font-size: 16px; } #opt-modal-close-x { position: absolute; top: -30px; right: -25px; width: 30px; height: 30px; background-image: url(\'//cdn.optimizely.com/img/543470256/b2d11caa90f5463e9d8cbae950656144.png\'); background-repeat: no-repeat; background-size: 30px 30px; } #opt-modal-close-x:hover { cursor: pointer; } #opt-header { margin-bottom: 20px; padding: 10px 0; color: #222; background-color: #eee; font-weight: bold; font-size: 22px; text-align: center; } #opt-options h3 { display: block; margin: 20px 0 12px 0; color: #000; font-weight: bold; font-size: 20px; font-family: \'Arial\', sans-serif; letter-spacing: 0; } #opt-options label { display: inline-block; width: 100%; margin-bottom: 10px; color: #1b6dbc; font-size: 18px; font-weight: bold; letter-spacing: 0; transition: all 0.1s ease-in-out; } #opt-options label:hover { cursor: pointer; color: #5d9fd5; text-shadow: 1px 1px 5px #eee; } #opt-options input[type=\"checkbox\"] { display:none; } #opt-options input[type=\"checkbox\"] + label span { display:inline-block; width:19px; height:19px; margin:-1px 4px 0 0; vertical-align:middle; background-image: url(\'//cdn.optimizely.com/img/404692387/9fd5ca6857104cbebb2502b34a49bc66.png\'); background-position: left top; background-repeat: no-repeat; cursor:pointer; } #opt-options input[type=\"checkbox\"]:checked + label span { background-image: url(\'//cdn.optimizely.com/img/404692387/9fd5ca6857104cbebb2502b34a49bc66.png\'); background-position: -19px top; background-repeat: no-repeat; } #opt-modal-container .center-me { text-align: center; } #check-cookies { width: 180px; height: 50px; margin: 10px auto 0 auto; border: 2px solid #9AC33D; border-radius: 10px; background-color: #9AC33D; color: #fff; letter-spacing: 3px; font-size: 20px; transition: all 0.2s ease-in-out; } #check-cookies:hover { cursor: pointer; background-color: #709a46; border-color: #709a46; } #cookie-results { display: none; max-height: 350px; margin-top: 20px; padding: 10px; border: 2px solid #ba0000; border-radius: 4px; overflow-y: auto; } #cookie-results .cookie-title { margin-bottom: 5px; color: #000; font-weight: bold; letter-spacing: 0; } #cookie-results .cookie-value { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee; color: #000; word-wrap: break-word; letter-spacing: 0; } #cookie-help { display: none; margin-top: 5px; padding: 0 5px; letter-spacing: 0; } #cookie-help::after { content: \'\'; display: block; width: 100%; clear: both; } #cookie-help a:first-child { color: #0DA6DD; text-decoration: none; float: left; letter-spacing: 0; } #cookie-help a:last-child { color: #0DA6DD; text-decoration: none; float: right; letter-spacing: 0; } #cookie-help a:hover { text-decoration: underline; } #opt-close-modal { display: none; width: 180px; height: 50px; margin: 10px auto 0 auto; border: 2px solid #ba0000; border-radius: 10px; background-color: #ba0000; color: #fff; letter-spacing: 3px; font-size: 20px; transition: all 0.2s ease-in-out; } #opt-close-modal:hover { cursor: pointer; transform: scale(1.2); }';
}
Modal.prototype = {
createAndAddStylesheet: function(styles) {
var css = document.createElement('style');
css.type = 'text/css';
css.id = "opt-debugger-styles";
if (css.styleSheet) {
css.styleSheet.cssText = styles;
} else {
css.appendChild(document.createTextNode(styles));
}
document.getElementsByTagName('head')[0].appendChild(css);
},
readCookie: function(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1, c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length, c.length);
}
}
return null;
},
buildModal: function() {
var html = "";
html += " <div id=\"opt-modal-container\">";
html += " <div id=\"opt-modal-close-x\"></div>";
html += " <div id=\"opt-header\">Optimizely: Debugger & Cookies</div>";
html += " <div id=\"opt-options\">";
html += " <h3>Experiments & Variations Mapping<\/h3>";
html += " <input type=\"checkbox\" id=\"opt-active-experiments\" \/>";
html += " <label for=\"opt-active-experiments\"><span><\/span>Active Experiments<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-variations-name-map\" \/>";
html += " <label for=\"opt-variations-name-map\"><span><\/span>Variations Mapping By Name<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-variations-index-map\" \/>";
html += " <label for=\"opt-variations-index-map\"><span><\/span>Variations Mapping By Index (0 is Original)<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-variations-id-map\" />";
html += " <label for=\"opt-variations-id-map\"><span></span>Variations Mapping By ID</label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-account-id\" \/>";
html += " <label for=\"opt-account-id\"><span><\/span>Account ID<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-project-id\" \/>";
html += " <label for=\"opt-project-id\"><span><\/span>Project ID<\/label>";
html += " <br \/>";
html += " <h3>Cookies<\/h3>";
html += " <input type=\"checkbox\" id=\"opt-end-user-id\" \/>";
html += " <label for=\"opt-end-user-id\"><span><\/span>optimizelyEndUserId<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-buckets\" \/>";
html += " <label for=\"opt-buckets\"><span><\/span>optimizelyBuckets<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-segments\" \/>";
html += " <label for=\"opt-segments\"><span><\/span>optimizelySegments<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-redirect\" \/>";
html += " <label for=\"opt-redirect\"><span><\/span>optimizelyRedirect<\/label>";
html += " <br \/>";
html += " <input type=\"checkbox\" id=\"opt-pending-log-events\" \/>";
html += " <label for=\"opt-pending-log-events\"><span><\/span>optimizelyPendingLogEvents<\/label>";
html += " <br \/>";
html += " <\/div>";
html += " <div class=\"center-me\"><button id=\"check-cookies\">Go!<\/button><\/div>";
html += " <div id=\"cookie-results\"><\/div>";
html += " <div id=\"cookie-help\">";
html += " <a id=\"modal-destroy\" href=\"#\">Start Over</a>";
html += " <a href=\"//help.optimizely.com/hc/en-us/articles/200040335-How-Optimizely-Works-Snippet-order-of-execution-JavaScript-evaluation-timing-and-cookies#first_party\" target=\"_blank\">What do these cookies mean?</a>";
html += " </div>";
html += " <div class=\"center-me\"><button id=\"opt-close-modal\">CLOSE</button></div>";
html += " <\/div>";
html += "";
this.el.innerHTML = html;
document.body.appendChild(this.el);
},
buildBasicInfoRow: function(name, optly_api_call) {
var cookie_wrap_div = document.createElement('div'),
cookie_title_div = document.createElement('div'),
cookie_value_div = document.createElement('div');
cookie_title_div.innerHTML = '<div class="cookie-title">' + name + '</div>';
cookie_value_div.innerHTML = '<div class="cookie-value">' + optly_api_call + '</div>';
cookie_wrap_div.appendChild(cookie_title_div);
cookie_wrap_div.appendChild(cookie_value_div);
return cookie_wrap_div;
},
decodeCookieValue: function(name) {
var self = this,
cookie_wrap_div = document.createElement('div'),
cookie_title_div = document.createElement('div'),
cookie_value_div = document.createElement('div');
cookie_title_div.innerHTML = '<div class="cookie-title">' + name + '</div>';
cookie_value_div.innerHTML = '<div class="cookie-value">' + decodeURIComponent(self.readCookie(name)) + '</div>';
cookie_wrap_div.appendChild(cookie_title_div);
cookie_wrap_div.appendChild(cookie_value_div);
return cookie_wrap_div;
},
destroy: function() {
this.el.remove();
var stylesheet = document.getElementById('opt-debugger-styles');
if (stylesheet) stylesheet.remove();
},
setListeners: function() {
var self = this,
opt_options = document.getElementById('opt-options'),
go_btn = document.getElementById('check-cookies'),
close_btn = document.getElementById('opt-close-modal'),
x_btn = document.getElementById('opt-modal-close-x'),
results = document.getElementById('cookie-results'),
start_over = document.getElementById('modal-destroy'),
help_link = document.getElementById('cookie-help');
go_btn.addEventListener('click', function() {
if (document.getElementById('opt-active-experiments').checked) {
results.appendChild(self.buildBasicInfoRow('Active Experiments', optimizely.activeExperiments.join(', ')));
}
if (document.getElementById('opt-variations-name-map').checked) {
var d = document.createElement('div'),
map = optimizely.variationNamesMap,
html = '<div class="cookie-title">Variations Mapping By Name</div><div class="cookie-value">';
for (var experiment in map) {
html += '<b>Experiment ID </b>' + experiment + ' : <b>Variation Name </b>' + map[experiment] + '<br />';
}
html += '</div>';
d.innerHTML = html;
results.appendChild(d);
}
if (document.getElementById('opt-variations-index-map').checked) {
var d = document.createElement('div'),
map = optimizely.variationMap,
html = '<div class="cookie-title">Variations Mapping By Index (0 is Original)</div><div class="cookie-value">';
for (var experiment in map) {
html += '<b>Experiment ID </b>' + experiment + ' : <b>Variation Index </b>' + map[experiment] + '<br />';
}
html += '</div>';
d.innerHTML = html;
results.appendChild(d);
}
if (document.getElementById('opt-variations-id-map').checked) {
var d = document.createElement('div'),
map = optimizely.variationIdsMap,
html = '<div class="cookie-title">Variations Mapping By ID</div><div class="cookie-value">';
for (var experiment in map) {
html += '<b>Experiment ID </b>' + experiment + ' : <b>Variation ID </b>' + map[experiment] + '<br />';
}
html += '</div>';
d.innerHTML = html;
results.appendChild(d);
}
if (document.getElementById('opt-account-id').checked) {
results.appendChild(self.buildBasicInfoRow('Account ID', optimizely.getAccountId()));
}
if (document.getElementById('opt-project-id').checked) {
results.appendChild(self.buildBasicInfoRow('Project ID', optimizely.getProjectId()));
}
if (document.getElementById('opt-end-user-id').checked) {
results.appendChild(self.decodeCookieValue('optimizelyEndUserId'));
}
if (document.getElementById('opt-buckets').checked) {
results.appendChild(self.decodeCookieValue('optimizelyBuckets'));
}
if (document.getElementById('opt-segments').checked) {
results.appendChild(self.decodeCookieValue('optimizelySegments'));
}
if (document.getElementById('opt-redirect').checked) {
results.appendChild(self.decodeCookieValue('optimizelyRedirect'));
}
if (document.getElementById('opt-pending-log-events').checked) {
results.appendChild(self.decodeCookieValue('optimizelyPendingLogEvents'));
}
opt_options.style.display = "none";
this.style.display = "none";
results.style.display = "block";
help_link.style.display = "block";
close_btn.style.display = "block";
});
close_btn.addEventListener('click', function() {
self.destroy();
});
x_btn.addEventListener('click', function() {
self.destroy();
});
start_over.addEventListener('click', function(e) {
e.preventDefault();
self.destroy();
self.init();
});
},
init: function() {
if (!window.optimizely) {
alert('Optimizely not loaded on page!');
return;
}
var self = this;
this.createAndAddStylesheet(self.styles);
this.buildModal();
this.setListeners();
}
};
var modal = new Modal();
modal.init();
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment