/* $Id: Utilities.js 7354 2009-06-24 13:30:59Z dgorsline $ */ ////// // New suite of common utilities ////// RegisterNamespace('Client.Utilities'); ////// // Register the passed namespace ////// function RegisterNamespace(namespacePath) { var rootObject = window; var namespaceParts = namespacePath.split('.'); for ( var i = 0; i < namespaceParts.length; i++) { var currentPart = namespaceParts[i]; if (!rootObject[currentPart]) { rootObject[currentPart] = new Object(); } rootObject = rootObject[currentPart]; } } ////// // Post a message, via AJAX, to be written to the application log. // // Usage notes: Use the wrapper functions postFatalMessage(), postErrorMessage(), // postWarnMessage(), postInfoMessage(), and postDebugMessage() // // Arguments: // // msg (required, but may be an empty string): free text to identify the // problem or to provide debugging info // location (required): free text to identify line number, function name, source file // as appropriate // more info (optional): the caught exception would be good to pass in this argument // ////// Client.Utilities.postFatalMessage = function (msg, location, moreInfo) { Client.Utilities.postLogMessage(msg, location, 'FATAL', moreInfo); }; Client.Utilities.postErrorMessage = function (msg, location, moreInfo) { if (msg.length == 0) { msg = 'General JavaScript error'; } Client.Utilities.postLogMessage(msg, location, 'ERROR', moreInfo); }; Client.Utilities.postWarnMessage = function (msg, location, moreInfo) { Client.Utilities.postLogMessage(msg, location, 'WARN', moreInfo); }; Client.Utilities.postInfoMessage = function (msg, location, moreInfo) { Client.Utilities.postLogMessage(msg, location, 'INFO', moreInfo); }; Client.Utilities.postDebugMessage = function (msg, location, moreInfo) { Client.Utilities.postLogMessage(msg, location, 'DEBUG', moreInfo); }; Client.Utilities.postLogMessage = function (msg, location, level, moreInfo) { //assemble message parameters var request = null; var parms = ''; parms += 'msg=' + encodeURIComponent(msg) + '&location=' + encodeURIComponent(location) + '&level=' + encodeURIComponent(level); if (moreInfo) { //does this act like an Error object? if (moreInfo.name) { var errorInfo = 'Error type: ' + moreInfo.name; //ECMAScript std member if (moreInfo.message) { errorInfo += '; message: ' + moreInfo.message; //ECMAScript std member } if (moreInfo.fileName) { errorInfo += '; fileName: ' + moreInfo.fileName; //optional } if (moreInfo.lineNumber) { errorInfo += '; lineNumber: ' + moreInfo.lineNumber; //optional } if (moreInfo.stack) { errorInfo += '; stack: ' + moreInfo.stack; //optional } parms += '&moreInfo=' + encodeURIComponent(errorInfo); } else { //treat it like any old string parms += '&moreInfo=' + encodeURIComponent(moreInfo); } } parms += '&browser=' + encodeURIComponent(navigator.appCodeName + ' [' + navigator.appName + ' ' + navigator.appVersion + ']'); var url = '/new_cms/jsp/shared/LogMessage.jsp' //construct the appropriate object if (window.XMLHttpRequest) { // code for IE7, Firefox, Mozilla, etc. request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // code for IE5, IE6 request = new ActiveXObject('Microsoft.XMLHTTP'); } if (request === null) { return; //no way to post } //do an async call so we don't have to wait request.open('POST', url, true); //set headers request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); request.setRequestHeader('Content-length', parms.length); request.setRequestHeader('Connection', 'close'); //set a handler that does nothing request.onreadystatechange = function() { if (request.readyState == 4 && request.status == 200) { //debug alert(http.responseText); } } //post the request request.send(parms); }; ////// // Open a popup window of help for the passed topic. // // Arguments: // // topic(required, but may be an empty string) // ////// Client.Utilities.popupHelp = function (topic) { try { var url = 'https://wiki.client.org/index.php/' + topic; var parms = 'width=400,resizable=yes,toolbars=no,menubar=no,status=no,scrollbars=yes'; var win = window.open(url, 'helpWindow', parms); return false; } catch (e) { Client.Utilities.postWarnMessage('', 'Utilities.js popupHelp()', e); return false; } }; ////// // Apply to the current selection within the control ( or ) // specified by id. If there is no current selection, insert the tag sequence at the insertion point. // If selfClosing is specified (as true), insert . If attributes is specified, insert // this string as . // // Arguments: // // tag (required) // id (required) // selfClosing (boolean, required) // attributes (string, optional) // // Notes: // // For the Internet Explorer case, this code uses some hacks suggested by // http://parentnode.org/javascript/working-with-the-cursor-position/ and // http://the-stickman.com/web-development/javascript/finding-selection-cursor-position-in-a-textarea-in-internet-explorer/ // to determine where the insertion point is. This code fails in certain edge cases--for // instance, where the selection spans text inside and outside the control. This code also // appears to behave differently, depending on the series of events that cause it to fire. // ////// Client.Utilities.applyTagToSelection = function (tag, id, selfClosing, attributes) { try { var start; //position of the var end; //selected text var added; //string length of the added tag and attributes var scroll; //current scrolling position var newlines; //adjustment to poition of new insertion point (Internet Explorer only) var elt = document.getElementById(id); if (elt) { //remember current scrolling position scroll = elt.scrollTop; //compute start and end positions of the selected text if (elt.selectionStart != undefined && elt.selectionEnd != undefined) { //Firefox, Opera, Safari, Chrome start = elt.selectionStart; end = elt.selectionEnd; } else if (document.selection) { //Internet Explorer elt.focus(); var range = document.selection.createRange(); var dummy = range.duplicate(); dummy.moveToElementText(elt); dummy.setEndPoint('EndToEnd', range); start = dummy.text.length - range.text.length; end = start + range.text.length; //count newlines up to the new insertion point var matches = elt.value.substring(0, end).match(/[\n\r]/g); newlines = (matches ? matches.length / 2 : 0); } else { Client.Utilities.postWarnMessage('Unsupported browser/cannot determine selection', 'Utilities.js applyTagToSelection()', ''); return; } //apply the tag and attributes var newValue = ''; if (selfClosing) { newValue += elt.value.substring(0, start) + '<' + tag; if (attributes) { newValue += ' ' + attributes; } newValue += ' />' + elt.value.substring(end, elt.value.length); } else { var selectedText = elt.value.substring(start, end); newValue += elt.value.substring(0, start) + '<' + tag; if (attributes) { newValue += ' ' + attributes; } newValue += '>' + selectedText + '' + elt.value.substring(end, elt.value.length); } added = newValue.length - elt.value.length; //compute new insertion point elt.value = newValue; //establish new insertion point after the newly-inserted closing tag if (elt.selectionStart != undefined && elt.selectionEnd != undefined) { //Firefox, Opera, Safari, Chrome elt.setSelectionRange(end + added, end + added); elt.focus(); } else { //Internet Explorer var newRange = elt.createTextRange(); newRange.move('character', ((end + added) - newlines)); newRange.select(); } //restore scrolling position if (scroll) { elt.scrollTop = scroll; } } } catch (e) { Client.Utilities.postWarnMessage('', 'Utilities.js applyTagToSelection()', e); } }; ///// // Prompt for the URL part of an tag, then apply the tag // to the current selection. // // Arguments: // // id (required) // ///// Client.Utilities.promptAndApplyAnchorTagToSelection = function (id) { try { var url = prompt('Enter URL', 'http://'); if (!url || url.length == 0) { return; } Client.Utilities.applyTagToSelection('a', id, false, 'href="' + url + '"'); } catch (e) { Client.Utilities.postWarnMessage('', 'Utilities.js promptAndApplyAnchorTagToSelection()', e); } }; ///// // // Display, via alert() boxes, all the properties of the passed object. // // Arguments: // // obj (required) // ///// Client.Utilities.debugShowAllProperties = function (obj) { try { for (var prop in obj) { alert('property name: ' + prop + '; property value: ' + obj[prop]); } } catch (e) { Client.Utilities.postWarnMessage('', 'Utilities.js debugShowAllProperties()', e); } };