var initialized = window.initialized || []; var vfWidgetHandler = (function() { 'use strict'; var apiUrl = "https://api.vouchedfor.co.uk/v0/public/widget"; var mainUrl = "https://www.vouchedfor.co.uk"; var profUrl; return { init: init, getRatings: getRatings, closePopups: closePopups }; /** * Init method. * * @param win * @param fn */ function init(win, fn) { contentLoaded(win, fn); injectCss(); addEscapeListener(); } /** * Get professional ratings. * * @param professionalHash * @param elementName */ function getRatings(professionalHash, elementName) { var professionalId = atob(professionalHash); var callbackName = 'c' + Math.round(100000 * Math.random()); var url = apiUrl + '/customer-rating/professional?callback=' + callbackName + '&prof_id=' + professionalHash; var version = ""; if (version) { url = url + '&version=' + version; } jsonp(url, { timeout: 30, callbackName: callbackName, onSuccess: function(data) { var elements = document.getElementsByClassName(elementName) || getElementsById(elementName); if (elements) { var processedElement = 1; for (var i = 0; i < elements.length; i++) { if (elements[i].outerHTML.indexOf(professionalHash) >= 0) { // ++processedElement; elements[i].innerHTML = data.html || ''; // elements[i].className += ' vf-content-processed'; var linkElement = elements[i].getElementsByClassName('vf-read-reviews')[0]; profUrl = linkElement ? linkElement.href : mainUrl; initPopup(profUrl, professionalId); attachParentListener(professionalId, professionalHash, elementName, profUrl); } } } }, onTimeout: function() { console.info('timeout'); } }); } /** * Content loaded method. * * @param win * @param fn */ function contentLoaded(win, fn) { var done = false; var top = true; var doc = win.document; var root = doc.documentElement; var add = doc.addEventListener ? 'addEventListener' : 'attachEvent'; var rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent'; var pre = doc.addEventListener ? '' : 'on'; var init = function (e) { if (e.type === 'readystatechange' && doc.readyState !== 'complete') return; (e.type === 'load' ? win : doc)[rem](pre + e.type, init, false); if (!done && (done = true)) fn.call(win, e.type || e); }; var poll = function () { try { root.doScroll('left'); } catch (e) { setTimeout(poll, 50); return; } init('poll'); }; if (doc.readyState === 'complete') { fn.call(win, 'lazy'); } else { if (doc.createEventObject && root.doScroll) { try { top = !win.frameElement; } catch (e) { // do nothing } if (top) { poll(); } } doc[add](pre + 'DOMContentLoaded', init, false); doc[add](pre + 'readystatechange', init, false); win[add](pre + 'load', init, false); } } /** * Inject the widget css. */ function injectCss() { // Add the css link only if it was not added. if (initialized.indexOf('css') === -1) { initialized.push('css'); var link = document.createElement("link"); link.rel = "stylesheet"; link.href = 'https://s3-eu-west-1.amazonaws.com/assets.vouchedfor.co.uk/widgets/ratings-and-reviews/legacy-version/css/widget2.css'; document.getElementsByTagName('head')[0].appendChild(link); } } /** * Escape key press event listener. */ function addEscapeListener() { // Add listener only once. if (initialized.indexOf('escapeListener') === -1) { initialized.push('escapeListener'); // Add listener on escape key press to close all popups (if any). window.addEventListener('keydown', function(evt) { if (evt.keyCode === 27) { vfWidget.closePopups(); } }); } } /** * Helper method to attach a listener on the reviews widget wrapper. * * @param professionalId * @param professionalHash * @param elementName */ function attachParentListener(professionalId, professionalHash, elementName, profUrl) { var elements = document.getElementsByClassName(elementName); if (elements) { for (var i = 0; i < elements.length; i++) { addListener(elements[i].parentElement, professionalId, profUrl); } } } /** * Add custom event listener on rating badge click event. * * @param element * @param professionalId */ function addListener(element, professionalId, url) { // Add the event listener only if it was not added. if (initialized.indexOf(professionalId) === -1) { initialized.push(professionalId); element.addEventListener('click', function(evt) { evt.preventDefault(); if (!document.getElementById('vf-frame-professional-' + professionalId)) { var childDiv = document.createElement('div'); childDiv.setAttribute('id', 'vf-frame-professional-' + professionalId); childDiv.setAttribute('style', 'height: 100%'); childDiv.innerHTML = ''; document.getElementById('vf-frame-outer-professional-' + professionalId).appendChild( childDiv ) } togglePopup(professionalId, url); }); } } /** * Initialize the popup for the professional. * * @param url * @param professionalId */ function initPopup(url, professionalId) { var vfFrameClass = 'vf-frame-' + professionalId; var vfFrameCloseClass = 'vf-close-' + professionalId; var vfFrame = document.createElement('div'); vfFrame.setAttribute('class', 'vf-frame ' + vfFrameClass); vfFrame.style.display = 'none'; vfFrame.innerHTML = '
' + '' + '
'; document.body.appendChild(vfFrame); // Add click listener on main wrapper. vfFrame = document.getElementsByClassName(vfFrameClass); if (vfFrame) { vfFrame[0].addEventListener('click', function(evt) { evt.preventDefault(); togglePopup(professionalId, url); }); } // Add click listener on close button. var vfClose = document.getElementsByClassName('vf-close'); if(vfClose) { vfClose[0].addEventListener('click', function(evt) { evt.preventDefault(); evt.stopPropagation(); closePopups(); }); } } function openIframe(vfFrame, vfIframe, url) { vfFrame.style.display = 'block'; vfIframe.src = url+'?utm_source=widget' } function closeIframe(vfFrame, vfIframe) { vfFrame.style.display = 'none'; vfIframe.src = 'about:blank' } /** * Toggle popup visibility. * * @param professionalId */ function togglePopup(professionalId, url) { var vfFrame = document.getElementsByClassName('vf-frame-' + professionalId)[0]; //find vf-iframe element inside vfFrame wrapper var vfIframe = vfFrame.getElementsByClassName('vf-iframe')[0]; if( vfFrame.style.display === 'none' ) { openIframe(vfFrame, vfIframe, url) } else { closeIframe(vfFrame, vfIframe) } } /** * Helper method to close all popus. */ function closePopups() { for (let vfFrame of document.getElementsByClassName('vf-frame')) { closeIframe(vfFrame, vfFrame.getElementsByClassName('vf-iframe')[0]) } } /** * @param src * @param options */ function jsonp(src, options) { var callback_name = options.callbackName || 'callback'; var on_success = options.onSuccess || function(){}; var on_timeout = options.onTimeout || function(){}; var timeout = options.timeout || 10; // sec var timeout_trigger = window.setTimeout(function(){ window[callback_name] = function(){}; on_timeout(); }, timeout * 1000); window[callback_name] = function(data){ window.clearTimeout(timeout_trigger); on_success(data); }; var script = document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.src = src; document.getElementsByTagName('head')[0].appendChild(script); } /** * Helper method to get multiple elements with the same ID. * * @param elementID */ function getElementsById(elementID){ var elementCollection = []; var allElements = document.getElementsByTagName("*"); for(var i = 0; i < allElements.length; i++){ if(allElements[i].id === elementID) elementCollection.push(allElements[i]); } return elementCollection; } })(); /** * In case we have both customer review widget and firm review widget * on the same page, we need to create separate widget handler for * each of them to ensure that the right widget is being built. */ if ('/customer-rating/professional' == '/customer-rating/professional') { var vfCustomerWidget = window.vfCustomerWidget || vfWidgetHandler; } else if ('/customer-rating/professional' == '/firm-rating/professional') { var vfFirmWidget = window.vfFirmWidget || vfWidgetHandler; } else { var vfWidget = window.vfWidget || vfWidgetHandler; } /** * Gets the proper rating widget handler. */ function getVfWidget() { if ('/customer-rating/professional' == '/customer-rating/professional') { return vfCustomerWidget; } else if ('/customer-rating/professional' == '/firm-rating/professional') { return vfFirmWidget; } else { return vfWidget; } } function contentLoaded(win, fn) { var vfWidget = getVfWidget(); vfWidget.init(win, fn); } function vf_get_ratings(id, el) { if (el.indexOf('vf-firm') === 0) { vfFirmWidget.getRatings(id.trim(), el); } else if (el.indexOf('vf-prof') === 0) { vfCustomerWidget.getRatings(id.trim(), el); } else { vfWidget.getRatings(id.trim(), el); } } function vf_gr(id) { var vfWidget = getVfWidget(); vfWidget.getRatings(id.trim(), 'vf-ifa'); }