/** * To use, log in to your Google Voice account. Go to Settings, then Call Widgets. * In the text box, there is some HTML code to embed in your web page. There should * be a PARAM element that contains the attribute name="FlashVars". Copy the contents * of the value attribute. Include this script in the HEAD portion of your document. * At the end of the BODY, place the following code: * * * * Be sure to substitute (or define) the phoneNumber variable with your Google Voice number. * Be sure to substitute (or define) the flashVars variable with the value you copied. * * This will install the click-to-call widget on mouseover for every matching * "tel:" link in your document. */ (function() { var backdrop, widgetURI = 'https://clients4.google.com/voice/embed/webCallButton', widgetWidth = 230, widgetHeight = 85; /** * Takes a phone number, matches all 'tel:' links * in the current document and installs the * Google Voice click-to-call widget as a mouseover * on those links. The 'maxwait' argument is to specify * how long to wait for the Flash widget to load. */ this.installClick2Call = // export function function installClick2Call(number, flashvars, maxwait) { var widget = createWidget(flashvars); maxwait = maxwait || 20000; // 20 second default wait pollUntilFlashIsLoaded(maxwait, widget, function() { if (document.activeElement && document.activeElement == widget) document.body.setActive(); widget.style.visibility = 'hidden'; installOnTelLinks(number, widget); }); } /** * Installs the already loaded widget on all matching * 'tel:' links. */ function installOnTelLinks(number, widget) { var links = document.getElementsByTagName('a'); var href = "tel:" + number; for (var i=0; i' + // 'visibility:hidden">' + '' + // for IE '' + '' + ''; return appendHTML(document.body, html); } /** * Show a semi-transparent backdrop that will cover the entire document * and hide itself (and call callback) when clicked. */ function showBackdrop(callback) { var d = document; // make sure the backdrop is initialized if (!backdrop) { backdrop = d.createElement('div'); backdrop.style.position = 'absolute'; backdrop.style.top = '0px'; backdrop.style.left = '0px'; backdrop.style.zIndex = 10000; backdrop.style.backgroundColor = 'black'; backdrop.style.opacity = 0.80; backdrop.style.filter = // idiotic 'filter' style needed for IE 'progid:DXImageTransform.Microsoft.Alpha(opacity=80)'; backdrop.style.visibility = 'hidden'; d.body.appendChild(backdrop); } // stretch the backdrop to cover the document, then show it backdrop.style.width = Math.max(d.documentElement.scrollWidth,d.body.scrollWidth) + 'px'; backdrop.style.height = Math.max(d.documentElement.scrollHeight,d.body.scrollHeight) + 'px'; backdrop.style.visibility = 'visible'; // create a function that will hide the backdrop and fire 'callback' on click var finished = function() { if (backdrop.removeEventListener) { backdrop.removeEventListener('click', finished, false); } else if (backdrop.detachEvent) { backdrop.detachEvent('onclick', finished); finished = null; } backdrop.style.visibility = 'hidden'; callback(); }; if (backdrop.addEventListener) { backdrop.addEventListener('click', finished, false); } else if (backdrop.attachEvent) { backdrop.attachEvent('onclick', finished); } } /** * Poll up to 3 times a second to check if the flash widget * is fully loaded. Once loaded, invoke the callback. */ function pollUntilFlashIsLoaded(maxwait, widget, callback) { if ( flashIsLoaded(widget) ) { callback(); } else if (maxwait > 0) { setTimeout(function() { pollUntilFlashIsLoaded(maxwait-300, widget, callback); }, 300); } } /** * Returns true if the flash widget is fully loaded, * false otherwise. */ function flashIsLoaded(widget) { return (typeof widget.PercentLoaded != 'undefined' && widget.PercentLoaded() == 100); } /** * Box 'class'. A box has a coordinate set, width and height. */ function Box(x, y, width, height) { this.x = x; this.y = y; this.width = width; this.height = height; } /** * Create a Box from the given element. * The box's coordinates wil be relative to the current document. * http://www.quirksmode.org/js/findpos.html */ Box.fromElement = function(el) { var posx = posy = 0; var parent = el; do { posx += parent.offsetLeft; posy += parent.offsetTop; } while (parent = parent.offsetParent); return new Box(posx, posy, el.offsetWidth, el.offsetHeight); } Box.prototype = { /** * Returns true if the given point is inside the box. */ contains: function(point) { return ( (point.x >= this.x && point.x <= (this.x + this.width) ) && (point.y >= this.y && point.y <= (this.y + this.height) ) ); } }; /** * Find the mouse position relative to the current document. * http://www.quirksmode.org/js/events_properties.html */ function eventPoint(e) { var posx = posy = 0; if (!e) var e = window.event; if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } return { x: posx, y: posy }; } /** * Appends the given HTML to end of the * given element and returns a reference to * the new node. This will only work reliably * if all HTML is wrapped in a single parent * element. */ function appendHTML(el, html) { if (el.insertAdjacentHTML) { el.insertAdjacentHTML('beforeEnd', html); return el.lastChild; } else { var tmp = el.ownerDocument.createElement('div'); tmp.innerHTML = html; return el.appendChild(tmp.firstChild); } } })();