Created
April 9, 2012 23:04
-
-
Save xiata/2347239 to your computer and use it in GitHub Desktop.
Refactor of GetSatisfaction Feedback widget embed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var GSFN = { | |
gId: function(id) { | |
return (typeof id == "string" ? document.getElementById(id) : id); | |
}, | |
hasClassName: function(element, className) { | |
return new RegExp("\\s*" + className + "\\b").test(element.className || ""); | |
}, | |
addClassName: function(element, className) { | |
if (!GSFN.hasClassName(element, className)) element.className += (element.className ? ' ' : '') + className; | |
return element; | |
}, | |
removeClassName: function(element, className) { | |
element.className = GSFN.strip(element.className.replace(new RegExp("\\s*" + className + "\\b"), '')); | |
return element; | |
}, | |
strip: function(string) { | |
return string.replace(/(^\s+)|(\s+$)/g, ''); | |
}, | |
add_css: function(css_content) { | |
var style = document.createElement('style'); | |
style.type = 'text/css'; | |
if (style.styleSheet) { | |
style.styleSheet.cssText = css_content; | |
} else { | |
style.appendChild(document.createTextNode(css_content)); | |
} | |
(document.getElementsByTagName('head')[0] || document.body).appendChild(style); | |
}, | |
feedback_widget: function(options) { | |
this.options = options || {}; | |
this.options.display = this.options.display || "overlay"; | |
this.options.placement = this.options.placement || 'left'; | |
this.options.color = this.options.color || '#222'; | |
this.widget_disabled = false; | |
this.feedback_base_url = location.protocol + local_base_url; | |
this.asset_base_url = (this.options.local_assets ? this.feedback_base_url : location.protocol + s3_base_url); | |
var initialURL = ''; | |
if (this.options.display == 'overlay') { | |
this.options.width = this.options.width || "658px"; | |
this.options.height = this.options.height || "100%"; | |
} else { | |
initialURL = this._feedbackURL(); | |
this.options.width = this.options.width || "100%"; | |
this.options.height = this.options.height || "500px"; | |
} | |
var self = this; | |
if (this.options.display == 'overlay') { | |
GSFN.add_css(templates.css(this.asset_base_url)); | |
var tabHTML = templates.tab(this.options.color, this.options.placement); | |
var overlayHTML = templates.overlay(this.widget_disabled, initialURL, this.options.width, this.options.height); | |
appendHTML(this.options.container, tabHTML + overlayHTML, function() { | |
self._refElements(); | |
addEvent('fdbk_tab', 'click', self.show, self); | |
addEvent('fdbk_close', 'click', self.hide, self); | |
self._iframe.removeAttribute("src"); | |
}); | |
} else { | |
var iframeHTML = templates.iframe(this.widget_disabled, initialURL, this.options.width, this.options.height); | |
appendHTML(this.options.container, iframeHTML, function() { self._refElements(); }); | |
} | |
} | |
}; | |
GSFN.feedback_widget.prototype = { | |
VERSION: 2, | |
asset_url: function(asset) { | |
return this.asset_base_url + asset; | |
}, | |
set_position: function() { | |
this.scroll_top = document.documentElement.scrollTop || document.body.scrollTop; | |
this.scroll_height = document.documentElement.scrollHeight; | |
this.client_height = window.innerHeight || document.documentElement.clientHeight; | |
this._screen.style.height = this.scroll_height+"px"; | |
this._container.style.top = this.scroll_top+(this.client_height*0.1)+"px"; | |
}, | |
show: function() { | |
this._iframe.setAttribute("src", this._feedbackURL()); | |
addOnceEvent(this._iframe, "load", this.loaded, this); | |
addOnceEvent(this._iframe, "error", this.notloaded, this); | |
this.set_position(); | |
GSFN.addClassName(this._html, 'feedback_tab_on'); | |
this._overlay.style.display = "block"; | |
return false; | |
}, | |
hide: function() { | |
this._overlay.style.display = "none"; | |
this._iframe.removeAttribute("src"); | |
GSFN.removeClassName(this._iframe, "loading"); | |
GSFN.removeClassName(this._html, 'feedback_tab_on'); | |
return false; | |
}, | |
loaded: function() { | |
GSFN.addClassName(this._iframe, "loaded"); | |
}, | |
notLoaded: function() { | |
GSFN.removeClassName(this._iframe, "loaded"); | |
}, | |
get_fastpass_url: function(options) { | |
if (options.fastpass) { | |
return options.fastpass; | |
} | |
var script_tags = document.getElementsByTagName('script'); | |
for (var i = 0; i < script_tags.length; i++) { | |
var tag = script_tags[i]; | |
if (tag.src.match(/\/fastpass/ && tag.src.match(/oauth/))) { | |
return tag.src; | |
} | |
} | |
}, | |
// Generate the feedback URL. | |
_feedbackURL: function() { | |
var o = this.options, fields = feedback_fields, tagged = feedback_tagged, queries = []; | |
for (var i = 0; i < fields.length; ++i) { | |
if (o[fields[i]] != null) queries.push(fields[i] + "=" + o[fields[i]]); | |
} | |
var fastpass = this.get_fastpass_url(o); | |
if (fastpass) queries.push('fastpass=' + fastpass); | |
if (o.auto_tag != false) { | |
for (var i = 0; i < tagged.length; ++i) { | |
if (o[tagged[i]] != null) queries.push(tagged[i] + "=" + escFunc(o[tagged[i]])); | |
} | |
} | |
return this.feedback_base_url + "/" + this.options.company + "/feedback/topics/new?" + queries.join('&'); | |
}, | |
_refElements: function() { | |
this._screen = GSFN.gId('fdbk_screen'); | |
this._container = GSFN.gId('fdbk_container'); | |
this._iframe = GSFN.gId('fdbk_iframe'); | |
this._overlay = GSFN.gId('fdbk_overlay'); | |
this._html = document.getElementsByTagName('html')[0]; | |
} | |
}; | |
// Export GSFN feedback widget by merging. | |
if (!window.GSFN) window.GSFN = {}; | |
for (var k in GSFN) { | |
if (GSFN.hasOwnProperty(k)) window.GSFN[k] = GSFN[k]; | |
} | |
// == Private data ================================ | |
var local_base_url = "//getsatisfaction.com"; | |
var s3_base_url = "//d1xklv3tn7qmp2.cloudfront.net"; //s3_base_url = "//d3rdqalhjaisuu.cloudfront.net"; | |
var escFunc = encodeURIComponent || escape; | |
var feedback_fields = ['display', 'style', 'popular_topics', 'limit', 'problem', 'powered_by', 'custom_css', 'custom_ie_css', 'custom_js', 'auto_tag', 'interstitial', 'community_base_url', 'document_domain']; | |
var feedback_tagged = ['product', 'tag', 'user_defined_code']; | |
// Don't use DOM 1 event listeners when you can avoid it. | |
var addEvent = (function() { | |
if (window.addEventListener) { | |
return function(obj, type, callback, scope) { // Most everyone | |
obj = GSFN.gId(obj); | |
if (scope) return obj.addEventListener(type, function() { return callback.apply(scope, arguments); }, false); | |
else return GSFN.gId(obj).addEventListener(type, callback, false); | |
} | |
} | |
return function(obj, type, callback, scope) { // IE 6 - 8 | |
obj = GSFN.gId(obj); | |
if (scope) return obj.attachEvent("on" + type, function() { return callback.apply(scope, arguments); }); | |
else return obj.attachEvent("on" + type, callback); | |
} | |
})(); | |
var addOnceEvent = (function(obj, type, callback, scope) { | |
obj = GSFN.gId(obj); | |
var func = function() { | |
if (window.removeEventListener) obj.removeEventListener(type, callback, false); | |
else obj.detachEvent("on" + type, callback); | |
callback.apply(scope || this, arguments); | |
} | |
addEvent(obj, type, func); | |
}); | |
// Avoid document.write(). Widget will render either in container or body if not found. | |
// Note: this does nothing if the page is already loaded and the item can't be found. | |
var appendHTML = function(container, html, callback) { | |
var container_el = GSFN.gId(container); | |
callback = callback || function() {}; | |
if (container_el) { | |
container_el.innerHTML += html; | |
callback(container_el); | |
} | |
else { | |
function later() { | |
if (!later.loaded) { | |
later.loaded = true; | |
var container_el = (GSFN.gId(container) || document.body); | |
container_el.innerHTML += html; | |
callback(container_el); | |
} | |
} | |
addEvent(window, "DOMContentLoaded", later); | |
addEvent(window, "load", later); | |
} | |
} | |
// Honestly this should be generated by HAMLJS. | |
var templates = { | |
tab: function(color, placement) { | |
return '<a href="#" id="fdbk_tab" class="fdbk_tab_'+placement+'" style="background-color:'+color+'">FEEDBACK</a>'; | |
}, | |
overlay: function(enabled, url, width, height) { | |
return '<div id="fdbk_overlay" style="display:none"><div id="fdbk_container"><a href="#" id="fdbk_close"></a>' + templates.iframe(enabled, url, width, height) + '</div><div id="fdbk_screen"></div></div>'; | |
}, | |
iframe: function(disabled, url, width, height) { | |
if (disabled) { | |
return '<div id="fdbk_iframe" style="position:relative; top: 20px; margin:20px;background:orange;color:purple;font-size:72px; padding: 20px;">WIDGETS ARE UNAVAILABLE LOL</div>'; | |
} else { | |
url = url ? (' src="' + url + '"') : '' | |
return '<iframe id="fdbk_iframe" allowTransparency="true" scrolling="no" frameborder="0" class="loading" width="'+width+'" height="'+height+'" style="width: '+width+'; height: '+height+';"' + url + '></iframe>'; | |
} | |
}, | |
css: function(url) { | |
return "#fdbk_overlay {\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n z-index: 1000000;\n position: absolute; }\n\n#fdbk_screen {\n top: 0;\n left: 0;\n z-index: 1;\n width: 100%;\n position: absolute;\n background-color: black;\n opacity: 0.45;\n -moz-opacity: 0.45;\n filter: alpha(opacity=45); }\n\n#fdbk_container {\n width: 680px;\n height: 640px;\n margin: 0 auto;\n z-index: 2;\n position: relative; }\n #fdbk_container iframe {\n width: 658px;\n height: 100%;\n margin: 20px;\n background: transparent; }\n #fdbk_container iframe.loading {\n background: transparent url("+url+"/_cb/8e27877/assets/fb_loading.png) no-repeat; }\n\na#fdbk_tab {\n top: 25%;\n left: 0;\n width: 42px;\n height: 102px;\n color: white;\n cursor: pointer;\n text-indent: -100000px;\n overflow: hidden;\n position: fixed;\n z-index: 100000;\n margin-left: -7px;\n background-image: url("+url+"/_cb/8e27877/assets/feedback_trans_tab.png);\n _position: absolute;\n _background-image: url("+url+"/_cb/8e27877/assets/feedback_tab_ie6.png); }\n a#fdbk_tab:hover {\n margin-left: -4px; }\n\na.fdbk_tab_right {\n right: 0 !important;\n left: auto !important;\n margin-right: 0 !important;\n margin-left: auto !important;\n width: 35px !important; }\n a.fdbk_tab_right:hover {\n width: 38px !important;\n margin-right: 0 !important;\n margin-left: auto !important; }\n\na.fdbk_tab_bottom {\n top: auto !important;\n bottom: 0 !important;\n left: 20% !important;\n height: 38px !important;\n width: 102px !important;\n background-position: 0 -102px !important;\n margin-bottom: -7px !important;\n margin-left: auto !important; }\n a.fdbk_tab_bottom:hover {\n margin-bottom: -4px !important;\n margin-left: auto !important; }\n\na.fdbk_tab_hidden {\n display: none !important; }\n\na#fdbk_close {\n position: absolute;\n cursor: pointer;\n outline: none;\n top: 0;\n left: 0;\n z-index: 4;\n width: 42px;\n height: 42px;\n overflow: hidden;\n background-image: url("+url+"/_cb/8e27877/assets/feedback-close.png);\n _background: none;\n _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\""+url+"/_cb/8e27877/assets/feedback-close.png\", sizingMethod='crop'); }\n a#fdbk_close:hover {\n background-position: -42px 0; }\n\n.feedback_tab_on embed, .feedback_tab_on select, .feedback_tab_on object {\n visibility: hidden; }\n"; | |
} | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment