I've been debugging the ReportingServices.js file using Firefox and Firebug. I've found that the reason SSRS (SQL Server Reporting Services) Report Manager (web front end for Reports) doesn't work in Firefox (v7.0.1) is that it's using javascript .lastChild to find elements. Unfortunately, Firefox also picks up on whitespace as TextNode elements causing the element selection to not work as expected.
This works in IE and hopefully someone knows a solution to this. I edited the javascript to get round one bug but then hit another more complicated one so probably a mine field to try to fix manually. Hopefully there is some update or patch available.
This is running SQL Server 2008 R2 Standard edition on a Windows 2008 R2 Datacenter server.
Apologies if you feel this is not the forum for such a question. In that case, please suggest where else I should ask the question if it's not appropriate. It is kindof a javascript problem but likely with a software update solution.
Updated:
After a few hours of fixing the browser compatibility bugs in the ReportingServices.js file I managed to get it to work on Firefox, Chrome, Opera and Safari as well as IE. Sorry that my answer below is in 2 parts; I posted the entire code of the updated ReportingServices.js for the solution.
After a few hours hacking around with the original ReportingServices.js file I managed to fix the javascript to work on Firefox, Chrome, Opera and Safari as well as IE.
Even though it's a bit big I've posted the whole edited ReportingServices.js below for others to use if needed. I've put "chris edit" comments showing the old lines above their edits so you can (if you care) follow what I've changed. I've also summarized these changes at the top of the code.
The SSRS report manager web interface is very useful and it would be a shame not to use it just because Microsoft didn't bother to test it on other browsers than IE. This is why I always prefer jQuery over plain javascript to avoid these kind of cross browser compatibility issues.
I had to post it in 2 parts. Hope this helps others!
/*
Author: Chris Snowden
Modified Date: 21st October 2011
ReportingServices.js file for SQL Server 2008 R2 Reporting Services
Updated to fix a bug whereby drop down context menus didn't work
for any other browser than IE.
1) I added functions to find firstChild and lastChild while skipping any
whitespace TextNode elements.
2) I updated the Clicked function to get at the table element value in a way
that works for firefox.
3) I updated the SplitContextMenuConfigString function to access the table
cells by first looping through each row and then the cells.
Drop downs now work on Firefox, Chrome, Opera and Safari as well as IE.
*/
var checkBoxCount;
var checkBoxId;
var checkBoxHead;
// Context menu
var _divContextMenu; // The container for the context menu
var _selectedIdHiddenField; // The id of the item that opened th context menu
var _timeOutLimit = 3000; // How long the context menu stays for after the cursor in no longer over it
var _timeOutTimer; // The timout for the context menu
var _itemSelected = false;
var _mouseOverContext = false; // If the mouse is over the context menu
var _contextMenusIds; // The array of the diffrent context menus
var _fadeTimeouts; // The array of timouts used for the fade effect
var _onLink = false; // If the user is over a name link
var _selectedItemId;
var _tabFocusedItem = '';
var _mouseOverItem = '';
var _unselectedItemStyle;
var _currentContextMenuId; // ID of currently displayed context menu
var _currentMenuItemId = null; // ID of currently selected context menu item
// Search bar
var _searchTextBoxID;
var _defaultSearchValue; // The value that the box defaults to.
// start chris edit
// new functions to find firstChild and lastChild but skipping whitespace elements
function firstChildNoWS(element) {
var child = element.firstChild;
while (child != null && child.isElementContentWhitespace) {
child = child.nextSibling;
}
return child;
}
function lastChildNoWS(element) {
var child = element.lastChild;
while (child != null && child.isElementContentWhitespace) {
child = child.previousSibling;
}
return child;
}
// end chris edit
function ToggleItem(itemId) {
var item = document.getElementById(itemId);
if (item.style.display == 'none')
item.style.display = 'inline';
else
item.style.display = 'none';
}
function ToggleButtonImage(image1ID, image2ID) {
var image1 = document.getElementById(image1ID);
var image2 = document.getElementById(image2ID);
if (image1.style.display == 'none') {
image1.style.display = 'inline-block';
image2.style.display = 'none';
}
else {
image1.style.display = 'none';
image2.style.display = 'inline-block';
}
}
function SetFocus(id) {
var obj = document.getElementById(id);
if (obj != null && !obj.disabled)
obj.focus();
}
// Validates that an extension has been selected
function ValidateDropDownSelection(source, args) {
var obj = document.getElementById(source.controltovalidate);
if (obj.options[0].selected && !obj.disabled)
args.IsValid = false;
else
args.IsValid = true;
}
/// selectAll
/// selects all the checkBoxes with the given id
function selectAll() {
var i;
var id;
var checked = checkBoxHead.checked;
for (i = 0; i < checkBoxCount; i++) {
id = checkBoxId + i;
document.getElementById(id).checked = checked;
}
}
/// onSglCheck
/// performs actions when a single checkBox is checked or unchecked
/// cb -> the checkBox generating the event
/// topId -> id of the "select all" checkBox
function onSglCheck() {
// uncheck the top checkBox
checkBoxHead.checked = false;
}
/// ToggleButton
/// Toggle a buttons enable state
function ToggleButton(id, disabled) {
if (document.getElementById(id) != null)
document.getElementById(id).disabled = disabled;
}
function ToggleValidator(id, enabled) {
document.getElementById(id).enabled = enabled;
}
function SetCbVars(cbid, count, cbh) {
checkBoxCount = count;
checkBoxId = cbid;
checkBoxHead = cbh;
}
/// Check to see if any check boxes should disable
/// a control
/// cbid -> id prefix of the checkBoxes
/// cbCount -> total checkBoxes to check
/// hidden -> input to look for
/// display -> control to disable
function CheckCheckBoxes(cbid, hidden, display) {
var i;
var id;
var disable;
disable = false;
for (i = 0; i < checkBoxCount; i++) {
id = cbid + i;
if (document.getElementById(id).checked) {
id = hidden + id;
if (document.getElementById(id) != null) {
disable = true;
break;
}
}
}
ToggleButton(display, disable);
}
function HiddenCheckClickHandler(hiddenID, promptID, promptStringID) {
var hiddenChk = document.getElementById(hiddenID);
var promptChk = document.getElementById(promptID);
// prompt should be in opposite state of hidden
promptChk.checked = !hiddenChk.checked;
}
function validateSaveRole(source, args) {
var i;
var id;
var c = 0;
for (i = 0; i < checkBoxCount; i++) {
id = checkBoxId + i;
if (document.getElementById(id).checked) c++;
}
if (0 == c)
args.IsValid = false;
else
args.IsValid = true;
}
/// Pad an integer less then 10 with a leading zero
function PadIntWithZero(val) {
var s = val.toString();
if (val < 10 && val >= 0) {
if (s.length == 1)
s = "0" + s;
else if (s.length > 2)
s = s.substring(s.length - 2, s.length);
}
return s;
}
/// Pad the contents of an input with leading zeros if necesarry
function PadInputInteger(id) {
document.getElementById(id).value = PadIntWithZero(document.getElementById(id).value);
}
/// text of confirmation popup when a single item is selected for deletion
/// e.g. "Are you sure you want to delete this item"
var confirmSingle;
/// text of confirmation popup when multiple items are selected for deletion
/// e.g. "Are you sure you want to delete these items"
var confirmMultiple;
function SetDeleteTxt(single, multiple) {
confirmSingle = single;
confirmMultiple = multiple;
}
/// doCmDel: DoConfirmDelete
/// Given a number of checked items, confirm their deletion
/// return true if OK was clicked; false otherwise
function doCmDel(checkedCount) {
var confirmTxt = confirmSingle;
if (checkedCount == 0)
return false;
if (checkedCount > 1)
confirmTxt = confirmMultiple;
return confirm(confirmTxt);
}
/// on non-Netscape browsers, confirm deletion of 0 or more items
function confirmDelete() {
return doCmDel(getChkCount());
}
/// confirm deletion of policies
function confirmDeletePlcies(alertString) {
var count = getChkCount();
if (count >= checkBoxCount) {
alert(alertString);
return false;
}
return doCmDel(count);
}
/// counts whether 0, 1, or more than 1 checkboxes are checked
/// returns 0, 1, or 2
function getChkCount() {
var checkedCount = 0;
for (i = 0; i < checkBoxCount && checkedCount < 2; i++) {
if (document.getElementById(checkBoxId + i).checked) {
checkedCount++;
}
}
return checkedCount;
}
function ToggleButtonBasedOnCheckBox(checkBoxId, toggleId, reverse) {
var chkb = document.getElementById(checkBoxId);
if (chkb != null) {
if (chkb.checked == true)
ToggleButton(toggleId, reverse); // enable if reverse == false
else
ToggleButton(toggleId, !reverse); // disable if reverse == false
}
}
function ToggleButtonBasedOnCheckBoxWithOverride(checkBoxId, toggleId, overrideToDisabled, reverse) {
if (overrideToDisabled == true)
ToggleButton(toggleId, true); // disable
else
ToggleButtonBasedOnCheckBox(checkBoxId, toggleId, reverse);
}
function ToggleButtonBasedOnCheckBoxes(checkBoxId, checkboxId2, toggleId) {
var chkb = document.getElementById(checkBoxId);
if (chkb != null) {
if (chkb.checked == true)
ToggleButtonBasedOnCheckBox(checkboxId2, toggleId, false);
else
ToggleButton(toggleId, true); // disable
}
}
function ToggleButtonBasedOnCheckBoxesWithOverride(checkBoxId, checkboxId2, toggleId, overrideToDisabled) {
if (overrideToDisabled == true)
ToggleButton(toggleId, true); // disable
else
ToggleButtonBasedOnCheckBoxes(checkBoxId, checkboxId2, toggleId);
}
function ToggleValidatorBasedOnCheckBoxWithOverride(checkBoxId, toggleId, overrideToDisabled, reverse) {
if (overrideToDisabled == true)
ToggleValidator(toggleId, false);
else {
var chkb = document.getElementById(checkBoxId);
if (chkb != null) {
ToggleValidator(toggleId, chkb.checked != reverse);
}
}
}
function ToggleValidatorBasedOnCheckBoxesWithOverride(checkBoxId, checkBoxId2, toggleId, overrideToDisabled, reverse) {
if (overrideToDisabled == true)
ToggleValidator(toggleId, false);
else {
var chkb = document.getElementById(checkBoxId);
if (chkb != null) {
if (chkb.checked == reverse)
ToggleValidator(toggleId, false);
else
ToggleValidatorBasedOnCheckBoxWithOverride(checkBoxId2, toggleId, overrideToDisabled, reverse);
}
}
}
function CheckButton(buttonID, shouldCheck) {
document.getElementById(buttonID).checked = shouldCheck;
}
function EnableMultiButtons(prefix) {
// If there are no multibuttons, there is no reason to iterate the
// list of checkboxes.
if (checkBoxCount == 0 || multiButtonList.length == 0)
return;
var enableMultiButtons = false;
var multipleCheckboxesSelected = false;
// If the top level check box is checked, we know the state of all
// of the checkboxes
var headerCheckBox = document.getElementById(prefix + "ch");
if (headerCheckBox != null && headerCheckBox.checked) {
enableMultiButtons = true;
multipleCheckboxesSelected = checkBoxCount > 1;
}
else {
// Look at each checkbox. If any one of them is checked,
// enable the multi buttons.
var foundOneChecked = false;
var i;
for (i = 0; i < checkBoxCount; i++) {
var checkBox = document.getElementById(prefix + 'cb' + i);
if (checkBox.checked) {
if (foundOneChecked) {
multipleCheckboxesSelected = true;
break;
}
else {
enableMultiButtons = true;
foundOneChecked = true;
}
}
}
}
// Enable/disable each of the multi buttons
var j;
for (j = 0; j < multiButtonList.length; j++) {
var button = document.getElementById(multiButtonList[j]);
if (button.allowMultiSelect)
button.disabled = !enableMultiButtons;
else
button.disabled = !enableMultiButtons || multipleCheckboxesSelected;
}
}
//function ShadowCopyPassword(suffix)
function MarkPasswordFieldChanged(suffix) {
if (event.propertyName == "value") {
var pwdField = document.getElementById("ui_txtStoredPwd" + suffix);
//var shadowField = document.getElementById("ui_shadowPassword" + suffix);
var shadowChanged = document.getElementById("ui_shadowPasswordChanged" + suffix);
// Don't shadow copy during initialization
if (pwdField.IsInit) {
//shadowField.value = pwdField.value;
//pwdField.UserEnteredPassword = "true";
shadowChanged.value = "true";
// Update validator state (there is no validator on the data driven subscription page)
var validator = document.getElementById("ui_validatorPassword" + suffix)
if (validator != null)
ValidatorValidate(validator);
}
}
}
function InitDataSourcePassword(suffix) {
var pwdField = document.getElementById("ui_txtStoredPwd" + suffix);
var shadowChanged = document.getElementById("ui_shadowPasswordChanged" + suffix);
// var shadowField = document.getElementById("ui_shadowPassword" + suffix);
var storedRadioButton = document.getElementById("ui_rdoStored" + suffix);
var pwdValidator = document.getElementById("ui_validatorPassword" + suffix);
pwdField.IsInit = false;
// Initialize the field to the shadow value (for when the user clicks back/forward)
// Or to a junk initial value.
if (pwdValidator != null && storedRadioButton.checked) {
/* if (shadowField.value.length > 0)
pwdField.value = shadowField.value;
else*/
pwdField.value = "********";
}
else
shadowChanged.value = "true"; // shadowChanged will be ignored if the page is submitted without storedRadioButton.checked
// Now that the initial value is set, track changes to the password field
pwdField.IsInit = true;
// There is no validator on the data driven subscription page (no stored radio button either)
if (pwdValidator != null)
ValidatorValidate(pwdValidator);
}
function SetNeedPassword(suffix) {
// Set a flag indicating that we need the password
var pwdField = document.getElementById("ui_txtStoredPwd" + suffix);
pwdField.NeedPassword = "true";
// Make the validator visible
ValidatorValidate(document.getElementById("ui_validatorPassword" + suffix));
}
function UpdateValidator(src, validatorID) {
if (src.checked) {
var validator = document.getElementById(validatorID);
ValidatorValidate(validator);
}
}
function ReEnterPasswordValidation(source, arguments) // source = validator
{
var validatorIdPrefix = "ui_validatorPassword"
var suffix = source.id.substr(validatorIdPrefix.length, source.id.length - validatorIdPrefix.length);
var storedRadioButton = document.getElementById("ui_rdoStored" + suffix);
var pwdField = document.getElementById("ui_txtStoredPwd" + suffix);
var shadowChanged = document.getElementById("ui_shadowPasswordChanged" + suffix);
var customDataSourceRadioButton = document.getElementById("ui_rdoCustomDataSource" + suffix);
var isCustomSelected = true;
if (customDataSourceRadioButton != null)
isCustomSelected = customDataSourceRadioButton.checked;
if (!isCustomSelected || // If the custom (vs shared) data source radio button exists and is not selected, we don't need the pwd.
storedRadioButton.checked == false || // If the data source is not using stored credentials, we don't need the password
pwdField.UserEnteredPassword == "true" || // If the password has changed, we don't need to get it from the user
pwdField.NeedPassword != "true" || // If no credentials have changed, we don't need the password
shadowChanged.value == "true") // If the user has typed a password
arguments.IsValid = true;
else
arguments.IsValid = false;
}
function ValidateDataSourceSelected(source, arguments) {
var validatorIdPrefix = "ui_sharedDSSelectedValidator"
var suffix = source.id.substr(validatorIdPrefix.length, source.id.length - validatorIdPrefix.length);
var sharedRadioButton = document.getElementById("ui_rdoSharedDataSource" + suffix);
var hiddenField = document.getElementById("ui_hiddenSharedDS" + suffix);
arguments.IsValid = (sharedRadioButton != null && !sharedRadioButton.checked) || hiddenField.value != "NotSelected";
}
/**************************************************************************/
// MultiValueParamClass
function MultiValueParamClass(thisID, visibleTextBoxID, floatingEditorID, floatingIFrameID, paramObject,
hasValidValues, allowBlank, doPostbackOnHide, postbackScript) {
this.m_thisID = thisID;
this.m_visibleTextBoxID = visibleTextBoxID;
this.m_floatingEditorID = floatingEditorID;
this.m_floatingIFrameID = floatingIFrameID;
this.m_paramObject = paramObject;
this.m_hasValidValues = hasValidValues;
this.m_allowBlank = allowBlank;
this.m_doPostbackOnHide = doPostbackOnHide;
this.m_postbackScript = postbackScript;
this.UpdateSummaryString();
}
function ToggleVisibility() {
var floatingEditor = GetControl(this.m_floatingEditorID);
if (floatingEditor.style.display != "inline")
this.Show();
else
this.Hide();
}
MultiValueParamClass.prototype.ToggleVisibility = ToggleVisibility;
function Show() {
var floatingEditor = GetControl(this.m_floatingEditorID);
if (floatingEditor.style.display == "inline")
return;
// Set the correct size of the floating editor - no more than
// 150 pixels high and no less than the width of the text box
var visibleTextBox = GetControl(this.m_visibleTextBoxID);
if (this.m_hasValidValues) {
if (floatingEditor.offsetHeight > 150)
floatingEditor.style.height = 150;
floatingEditor.style.width = visibleTextBox.offsetWidth;
}
var newEditorPosition = this.GetNewFloatingEditorPosition();
floatingEditor.style.left = newEditorPosition.Left;
floatingEditor.style.top = newEditorPosition.Top;
floatingEditor.style.display = "inline";
var floatingIFrame = GetControl(this.m_floatingIFrameID);
floatingIFrame.style.left = floatingEditor.style.left;
floatingIFrame.style.top = floatingEditor.style.top;
floatingIFrame.style.width = floatingEditor.offsetWidth;
floatingIFrame.style.height = floatingEditor.offsetHeight;
floatingIFrame.style.display = "inline";
// If another multi value is open, close it first
if (this.m_paramObject.ActiveMultValue != this && this.m_paramObject.ActiveMultiValue != null)
ControlClicked(this.m_paramObject.id);
this.m_paramObject.ActiveMultiValue = this;
if (floatingEditor.childNodes[0].focus) floatingEditor.childNodes[0].focus();
this.StartPolling();
}
MultiValueParamClass.prototype.Show = Show;
function Hide() {
var floatingEditor = GetControl(this.m_floatingEditorID);
var floatingIFrame = GetControl(this.m_floatingIFrameID);
// Hide the editor
floatingEditor.style.display = "none";
floatingIFrame.style.display = "none";
this.UpdateSummaryString();
if (this.m_doPostbackOnHide)
eval(this.m_postbackScript);
// Check that the reference is still us in case event ordering
// caused another multivalue to click open
if (this.m_paramObject.ActiveMultiValue == this)
this.m_paramObject.ActiveMultiValue = null;
}
MultiValueParamClass.prototype.Hide = Hide;
function GetNewFloatingEditorPosition() {
// Make the editor visible
var visibleTextBox = GetControl(this.m_visibleTextBoxID);
var textBoxPosition = GetObjectPosition(visibleTextBox);
return { Left: textBoxPosition.Left, Top: textBoxPosition.Top + visibleTextBox.offsetHeight };
}
MultiValueParamClass.prototype.GetNewFloatingEditorPosition = GetNewFloatingEditorPosition;
function UpdateSummaryString() {
var summaryString;
if (this.m_hasValidValues)
summaryString = GetValueStringFromValidValueList(this.m_floatingEditorID);
else
summaryString = GetValueStringFromTextEditor(this.m_floatingEditorID, false, this.m_allowBlank);
var visibleTextBox = GetControl(this.m_visibleTextBoxID);
visibleTextBox.value = summaryString;
}
MultiValueParamClass.prototype.UpdateSummaryString = UpdateSummaryString;
function StartPolling() {
setTimeout(this.m_thisID + ".PollingCallback();", 100);
}
MultiValueParamClass.prototype.StartPolling = StartPolling;
function PollingCallback() {
// If the editor isn't visible, no more events.
var floatingEditor = GetControl(this.m_floatingEditorID);
if (floatingEditor.style.display != "inline")
return;
// If the text box moved, something on the page resized, so close the editor
var expectedEditorPos = this.GetNewFloatingEditorPosition();
if (floatingEditor.style.left != expectedEditorPos.Left + "px" ||
floatingEditor.style.top != expectedEditorPos.Top + "px") {
this.Hide();
}
else {
this.StartPolling();
}
}
MultiValueParamClass.prototype.PollingCallback = PollingCallback;
/*****************************************************************************/
function GetObjectPosition(obj) {
var totalTop = 0;
var totalLeft = 0;
while (obj != document.body) {
// Add up the position
totalTop += obj.offsetTop;
totalLeft += obj.offsetLeft;
// Prepare for next iteration
obj = obj.offsetParent;
}
totalTop += obj.offsetTop;
totalLeft += obj.offsetLeft;
return { Left: totalLeft, Top: totalTop };
}
function GetValueStringFromTextEditor(floatingEditorID, asRaw, allowBlank) {
var span = GetControl(floatingEditorID);
var editor = span.childNodes[0];
var valueString = editor.value;
// Remove the blanks
if (!allowBlank) {
// Break down the text box string to the individual lines
var valueArray = valueString.split("\r\n");
var delimiter;
if (asRaw)
delimiter = "\r\n";
else
delimiter = ", ";
var finalValue = "";
for (var i = 0; i < valueArray.length; i++) {
// If the string is non-blank, add it
if (valueArray[i].length > 0) {
if (finalValue.length > 0)
finalValue += delimiter;
finalValue += valueArray[i];
}
}
return finalValue;
}
else {
if (asRaw)
return valueString;
else
return valueString.replace(/\r\n/g, ", ");
}
}
function GetValueStringFromValidValueList(editorID) {
var valueString = "";
// Get the table
var div = GetControl(editorID);
var table = div.childNodes[0];
if (table.nodeName != "TABLE") // Skip whitespace if needed
table = div.childNodes[1];
// If there is only one element, it is a real value, not the select all option
var startIndex = 0;
if (table.rows.length > 1)
startIndex = 1;
for (var i = startIndex; i < table.rows.length; i++)
{
// Get the first cell of the row
var firstCell = table.rows[i].cells[0];
var span = firstCell.childNodes[0];
var checkBox = span.childNodes[0];
var label = span.childNodes[1];
if (checkBox.checked) {
if (valueString.length > 0)
valueString += ", ";
// chris edit - valueString += label.firstChild.nodeValue;
valueString += firstChildNoWS(label).nodeValue;
}
}
return valueString;
}
function MultiValidValuesSelectAll(src, editorID)
{
// Get the table
var div = GetControl(editorID);
var table = div.childNodes[0];
if (table.nodeName != "TABLE")
table = div.childNodes[1];
for (var i = 1; i < table.rows.length; i++)
{
// Get the first cell of the row
var firstCell = table.rows[i].cells[0];
var span = firstCell.childNodes[0];
var checkBox = span.childNodes[0];
checkBox.checked = src.checked;
}
}
function ValidateMultiValidValue(editorID, errMsg)
{
var summaryString = GetValueStringFromValidValueList(editorID);
var isValid = summaryString.length > 0;
if (!isValid)
alert(errMsg)
return isValid;
}
function ValidateMultiEditValue(editorID, errMsg) {
// Need to check for a value specified. This code only runs if not allow blank.
// GetValueStringFromTextEditor filters out blank strings. So if it was all blank,
// the final string will be length 0
var summaryString = GetValueStringFromTextEditor(editorID, true, false)
var isValid = false;
if (summaryString.length > 0)
isValid = true;
if (!isValid)
alert(errMsg);
return isValid;
}
function GetControl(controlID) {
var control = document.getElementById(controlID);
if (control == null)
alert("Unable to locate control: " + controlID);
return control;
}
function ControlClicked(formID) {
var form = GetControl(formID);
if (form.ActiveMultiValue != null)
form.ActiveMultiValue.Hide();
}
Part 2 of updated ReportingServices.js from my answer:
// --- Context Menu ---
// This function is called in the onload event of the body.
// It hooks the context menus up to the Javascript code.
// divContextMenuId, is the id of the div that contains the context menus
// selectedIdHiddenFieldId, is the id of the field used to post back the name of the item clicked
// contextMenusIds, is an array of the ids of the context menus
// searchTextBox ID, is the id of the search box
// defaultSearchValue. the value the search box has by default
function InitContextMenu(divContextMenuId, selectedIdHiddenFieldId, contextMenusIds, searchTextBoxID, defaultSearchValue ) {
ResetSearchBar( searchTextBoxID, defaultSearchValue );
_divContextMenu = document.getElementById(divContextMenuId);
_selectedIdHiddenField = document.getElementById(selectedIdHiddenFieldId);
_contextMenusIds = contextMenusIds;
_divContextMenu.onmouseover = function() { _mouseOverContext = true; };
_divContextMenu.onmouseout = function() {
if (_mouseOverContext == true) {
_mouseOverContext = false;
if (_timeOutTimer == null) {
_timeOutTimer = setTimeout(TimeOutAction, _timeOutLimit);
}
}
};
document.body.onmousedown = ContextMouseDown;
AddKeyDownListener();
}
// This handler stops bubling when arrow keys Up or Down pressed to prevent scrolling window
function KeyDownHandler(e)
{
// Cancel window scrolling only when menu is opened
if(_currentContextMenuId == null)
{
return true;
}
if(!e)
{
e = window.event;
}
var key = e.keyCode;
if(key == 38 || key == 40)
{
return false;
}
else
{
return true;
}
}
function AddKeyDownListener()
{
if(document.addEventListener)
{
document.addEventListener('keydown', KeyDownHandler, false);
}
else
{
document.onkeydown = KeyDownHandler;
}
}
// This function starts the context menu timeout process
function TimeOutAction() {
if (_mouseOverContext == false) {
UnSelectedMenuItem()
}
_timeOutTimer = null;
}
// This function is called when a name tag is clicked, it displays the contextmenu for a given item.
function Clicked(event, contextMenuId) {
if (!_onLink) {
ClearTimeouts();
SelectContextMenuFromColletion(contextMenuId);
_itemSelected = true;
// **Cross browser compatibility code**
// Some browsers will not pass the event so we need to get it from the window instead.
if (event == null)
event = window.event;
var selectedElement = event.target != null ? event.target : event.srcElement;
var outerTableElement = GetOuterElementOfType(selectedElement, 'table');
var elementPosition = GetElementPosition(outerTableElement);
_selectedItemId = outerTableElement.id;
// chris edit - _selectedIdHiddenField.value = outerTableElement.value;
_selectedIdHiddenField.value = outerTableElement.attributes["value"].value;
outerTableElement.className = "msrs-SelectedItem";
ResetContextMenu();
var contextMenuHeight = _divContextMenu.offsetHeight;
var contextMenuWidth = _divContextMenu.offsetWidth;
var boxHeight = outerTableElement.offsetHeight;
var boxWidth = outerTableElement.offsetWidth;
var boxXcoordinate = elementPosition.left;
var boxYcooridnate = elementPosition.top;
var pageWidth = 0, pageHeight = 0;
// **Cross browser compatibility code**
if (typeof (window.innerWidth) == 'number') {
//Non-IE
pageWidth = window.innerWidth;
pageHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
pageWidth = document.documentElement.clientWidth;
pageHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
pageWidth = document.body.clientWidth;
pageHeight = document.body.clientHeight;
}
// **Cross browser compatibility code**
var iebody = (document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body
var pageXOffSet = document.all ? iebody.scrollLeft : pageXOffset
var pageYOffSet = document.all ? iebody.scrollTop : pageYOffset
_divContextMenu.style.left = SetContextMenuHorizonatalPosition(pageWidth, pageXOffSet, boxXcoordinate, contextMenuWidth, boxWidth) + 'px';
_divContextMenu.style.top = SetContextMenuVerticalPosition(pageHeight, pageYOffSet, boxYcooridnate, contextMenuHeight, boxHeight) + 'px';
ChangeOpacityForElement(100, _divContextMenu.id);
// chris edit - document.getElementById(_currentContextMenuId).firstChild.focus();
firstChildNoWS(document.getElementById(_currentContextMenuId)).focus();
}
}
// ***********************************
// Context menu keyboard navigation
// ***********************************
// Opens context menu via keyboard. Context menu
// is opened by selecting an item and pressing
// Alt + Down.
function OpenMenuKeyPress(e, contextMenuId)
{
// Alt key was pressed
if (e.altKey)
{
var keyCode;
if (window.event)
keyCode = e.keyCode;
else
keyCode = e.which;
// Down key was pressed
if (keyCode == 40)
{
// Open context menu.
Clicked(event, contextMenuId);
// Highlight the first selectable item
// in the context menu.
HighlightContextMenuItem(true);
}
}
}
// Performs keyboard navigation within
// opened context menu.
function NavigateMenuKeyPress(e)
{
var keyCode;
if (window.event)
keyCode = e.keyCode;
else
keyCode = e.which;
// Down key moves down to the next context menu item
if (keyCode == 40)
{
HighlightContextMenuItem(true);
}
// Up key moves up to the previous context menu item
else if (keyCode == 38)
{
HighlightContextMenuItem(false);
}
// Escape key closes context menu
else if (keyCode == 27)
{
// Close context menu
UnSelectedMenuItem();
// Make sure focus is given to the catalog item
// in the folder view.
document.getElementById(_selectedItemId).focus();
}
}
// Highlights context menu item.
// Parameter: highlightNext
// - If true, highlights menu item below current menu item.
// If current menu item is the last item, wraps around and
// highlights first menu item.
// - If false, highlights menu item above current menu item.
// If current menu item is the first item, wraps around and
// highlights last menu item.
function HighlightContextMenuItem(highlightNext)
{
var contextMenu = document.getElementById(_currentContextMenuId);
// chris edit - var table = contextMenu.lastChild;
var table = lastChildNoWS(contextMenu);
var currentMenuItemIndex = -1;
if (_currentMenuItemId != null)
currentMenuItemIndex = document.getElementById(_currentMenuItemId).parentNode.rowIndex;
var index = currentMenuItemIndex;
while (true)
{
if (highlightNext)
{
index++;
// If the index is out of range,
// reset it to the beginning
if (index < 0 || index >= table.cells.length)
index = 0;
}
else
{
index--;
// If the index is out of range,
// reset it to the end
if (index < 0 || index >= table.cells.length)
index = table.cells.length - 1;
}
// Each context menu item has an associated
// group ID. Make sure the table cell has a valid
// group ID, otherwise it is not a menu item (e.g.
// an underline separator).
if (table.cells[index].group >= 0)
{
FocusContextMenuItem(table.cells[index].id, 'msrs-MenuUIItemTableHover', 'msrs-MenuUIItemTableCell');
break;
}
// If we reach the orignal index, that means we looped
// through all table cells and did not find a valid context
// menu item. In that case, stop searching.
if (index == currentMenuItemIndex)
break;
}
}
// *** End keyboard navigation ***
// This function resets the context menus shape and size.
function ResetContextMenu() {
_divContextMenu.style.height = 'auto';
_divContextMenu.style.width = 'auto';
_divContextMenu.style.overflowY = 'visible';
_divContextMenu.style.overflowX = 'visible';
_divContextMenu.style.overflow = 'visible';
_divContextMenu.style.display = 'block';
}
// This function sets the horizontal position of the context menu.
// It also sets is the context menu has vertical scroll bars.
function SetContextMenuHorizonatalPosition(pageWidth, pageXOffSet, boxXcoordinate, contextMenuWidth, boxWidth) {
var menuXCoordinate = boxXcoordinate + boxWidth - contextMenuWidth;
var spaceRightBox = (pageWidth + pageXOffSet) - menuXCoordinate;
var spaceLeftBox = menuXCoordinate - pageXOffSet;
var returnValue;
if ((contextMenuWidth < spaceRightBox) && (pageXOffSet < menuXCoordinate)) {
returnValue = menuXCoordinate;
}
else if ((contextMenuWidth < spaceRightBox)) {
returnValue = pageXOffSet;
}
else if (contextMenuWidth < spaceLeftBox) {
returnValue = menuXCoordinate - (contextMenuWidth - (pageWidth + pageXOffSet - menuXCoordinate));
}
else {
_divContextMenu.style.overflowX = "scroll";
if (spaceLeftBox < spaceRightBox) {
_divContextMenu.style.width = spaceRightBox;
returnValue = pageXOffSet;
}
else {
_divContextMenu.style.width = spaceLeftBox;
returnValue = menuXCoordinate - (spaceLeftBox - (pageWidth + pageXOffSet - menuXCoordinate));
}
}
return returnValue;
}
// This function sets the vertical position of the context menu.
// It also sets is the context menu has horizontal scroll bars.
function SetContextMenuVerticalPosition(pageHeight, pageYOffSet, boxYcooridnate, contextMenuHeight, boxHeight) {
var spaceBelowBox = (pageHeight + pageYOffSet) - (boxYcooridnate + boxHeight);
var spaceAboveBox = boxYcooridnate - pageYOffSet;
var returnValue;
if (contextMenuHeight < spaceBelowBox) {
returnValue = (boxYcooridnate + boxHeight);
}
else if (contextMenuHeight < spaceAboveBox) {
returnValue = (boxYcooridnate - contextMenuHeight);
}
else if (spaceBelowBox > spaceAboveBox) {
_divContextMenu.style.height = spaceBelowBox;
_divContextMenu.style.overflowY = "scroll";
returnValue = (boxYcooridnate + boxHeight);
}
else {
_divContextMenu.style.height = spaceAboveBox;
_divContextMenu.style.overflowY = "scroll";
returnValue = (boxYcooridnate - spaceAboveBox);
}
return returnValue;
}
// This function displays a context menu given its id and then hides the others
function SelectContextMenuFromColletion(contextMenuConfigString) {
var contextMenuId = SplitContextMenuConfigString(contextMenuConfigString);
for (i = 0; i < _contextMenusIds.length; i++) {
var cm = document.getElementById(_contextMenusIds[i]);
if (cm.id == contextMenuId) {
cm.style.visibility = 'visible';
cm.style.display = 'block';
_currentContextMenuId = contextMenuId;
}
else {
cm.style.visibility = 'hidden';
cm.style.display = 'none';
}
}
}
function SplitContextMenuConfigString(contextMenuConfigString) {
var contextMenuEnd = contextMenuConfigString.indexOf(":");
var contextMenuId = contextMenuConfigString;
var contextMenuHiddenItems;
if (contextMenuEnd != -1)
{
contextMenuId = contextMenuConfigString.substr(0, contextMenuEnd);
}
var cm = document.getElementById(contextMenuId);
// chris edit - var table = cm.firstChild;
var table = firstChildNoWS(cm);
var groupItemCount = []; // The items in each group
var groupUnderlineId = []; // The Id's of the underlines.
// Enable all menu items counting the number of groups,
// number of items in the groups and underlines for the groups as we go.
// start chris edit
/* for (i = 0; i < table.cells.length; i++)
{
table.cells[i].style.visibility = 'visible';
table.cells[i].style.display = 'block'
if ((groupItemCount.length - 1) < table.cells[i].group) {
groupItemCount.push(1);
groupUnderlineId.push(table.cells[i].underline);
}
else {
groupItemCount[table.cells[i].group]++;
}
AlterVisibilityOfAssociatedUnderline(table.cells[i], true)
}*/
if (table != null && table.rows != null)
{
for (r = 0; r < table.rows.length; r++) {
for (i = 0; i < table.rows[r].cells.length; i++)
{
table.rows[r].cells[i].style.visibility = 'visible';
table.rows[r].cells[i].style.display = 'block'
if ((groupItemCount.length - 1) < table.rows[r].cells[i].group) {
groupItemCount.push(1);
groupUnderlineId.push(table.rows[r].cells[i].underline);
}
else {
groupItemCount[table.rows[r].cells[i].group]++;
}
AlterVisibilityOfAssociatedUnderline(table.rows[r].cells[i], true)
}
}
}
// end chris edit
// If hidden items are listed, remove them from the context menu
if (contextMenuEnd != -1)
{
contextMenuHiddenItems = contextMenuConfigString.substr((contextMenuEnd + 1), (contextMenuConfigString.length - 1)).split("-");
var groupsToHide = groupItemCount;
// Hide the hidden items
for (i = 0; i < contextMenuHiddenItems.length; i++)
{
var item = document.getElementById(contextMenuHiddenItems[i]);
item.style.visibility = 'hidden';
item.style.display = 'none'
groupsToHide[item.group]--;
}
var allHidden = true;
// Work back through the groups hiding the underlines as required.
for (i = (groupsToHide.length - 1); i > -1; i--) {
if (groupsToHide[i] == 0) {
AlterVisibilityOfAssociatedUnderline(groupUnderlineId[i], false);
}
else if (allHidden && i == (groupsToHide.length - 1)) {
allHidden = false;
}
// If all the items have been hidden so far hide the last underline too.
else if (allHidden) {
allHidden = false;
AlterVisibilityOfAssociatedUnderline(groupUnderlineId[i], false);
}
}
}
return contextMenuId;
}
function AlterVisibilityOfAssociatedUnderline(underLineId, visibility) {
if (underLineId != null && underLineId != "") {
var underlineElement = document.getElementById(underLineId);
if (underlineElement != null) {
if (visibility) {
underlineElement.style.visibility = 'visible';
underlineElement.style.display = 'block'
}
else {
underlineElement.style.visibility = 'hidden';
underlineElement.style.display = 'none'
}
}
}
}
function ClearTimeouts() {
if (_fadeTimeouts != null) {
for (i = 0; i < _fadeTimeouts.length; i++) {
clearTimeout(_fadeTimeouts[i]);
}
}
_fadeTimeouts = [];
}
// This function chnages an elements opacity given its id.
function FadeOutElement(id, opacStart, opacEnd, millisec) {
ClearTimeouts();
//speed for each frame
var speed = Math.round(millisec / 100);
var timer = 0;
for (i = opacStart; i >= opacEnd; i--) {
_fadeTimeouts.push(setTimeout("ChangeOpacityForElement(" + i + ",'" + id + "')", (timer * speed)));
timer++;
}
}
// This function changes the opacity of an elemnent given it's id.
// Works across browsers for different browsers
function ChangeOpacityForElement(opacity, id) {
var object = document.getElementById(id).style;
if (opacity != 0) {
// **Cross browser compatibility code**
object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";
}
else {
object.display = 'none';
}
}
// This function is the click for the body of the document
function ContextMouseDown() {
if (_mouseOverContext) {
return;
}
else {
HideMenu()
}
}
// This function fades out the context menu and then unselects the associated name control
function UnSelectedMenuItem() {
if (_itemSelected) {
FadeOutElement(_divContextMenu.id, 100, 0, 300);
UnselectCurrentMenuItem();
}
}
// Hides context menu without fading effect
function HideMenu()
{
if (_itemSelected)
{
ChangeOpacityForElement(0, _divContextMenu.id);
UnselectCurrentMenuItem();
}
}
function UnselectCurrentMenuItem()
{
_itemSelected = false;
_currentContextMenuId = null;
SwapStyle(_currentMenuItemId, 'msrs-MenuUIItemTableCell');
_currentMenuItemId = null;
ChangeReportItemStyle(_selectedItemId, "msrs-UnSelectedItem");
}
// This function walks back up the DOM tree until it finds the first occurrence
// of a given element. It then returns this element
function GetOuterElementOfType(element, type) {
while (element.tagName.toLowerCase() != type) {
element = element.parentNode;
}
return element;
}
// This function gets the corrdinates of the top left corner of a given element
function GetElementPosition(element) {
element = GetOuterElementOfType(element, 'table');
var left, top;
left = top = 0;
if (element.offsetParent) {
do {
left += element.offsetLeft;
top += element.offsetTop;
} while (element = element.offsetParent);
}
return { left: left, top: top };
}
function FocusContextMenuItem(menuItemId, focusStyle, blurStyle)
{
SwapStyle(_currentMenuItemId, blurStyle);
SwapStyle(menuItemId, focusStyle);
// chrid edit - document.getElementById(menuItemId).firstChild.focus();
firstChildNoWS(document.getElementById(menuItemId)).focus();
_currentMenuItemId = menuItemId;
}
// This function swaps the style using the id of a given element
function SwapStyle(id, style) {
if (document.getElementById) {
var selectedElement = document.getElementById(id);
if (selectedElement != null)
{
selectedElement.className = style;
}
}
}
// This function changes the style using the id of a given element
// and should only be called for catalog items in the tile or details view
function ChangeReportItemStyle(id, style)
{
if (!_itemSelected)
{
if (document.getElementById)
{
var selectedElement = document.getElementById(id);
selectedElement.className = style;
// Change the style on the end cell by drilling into the table.
if (selectedElement.tagName.toLowerCase() == "table")
{
// chris edit - var tbody = selectedElement.lastChild;
var tbody = lastChildNoWS(selectedElement);
if (tbody != null)
{
// chris edit - var tr = tbody.lastChild;
var tr = lastChildNoWS(tbody);
if (tr != null)
{
// chris edit - tr.lastChild.className = style + 'End';
trLastChild = lastChildNoWS(tr);
if (trLastChild != null)
{
trLastChild.className = style + 'End';
}
}
}
}
}
}
}
function ChangeReportItemStyleOnFocus(id, currentStyle, unselectedStyle)
{
_unselectedItemStyle = unselectedStyle;
_tabFocusedItem = id;
// We should unselect selected by mouse over item if there is one
if(_mouseOverItem != '')
{
ChangeReportItemStyle(_mouseOverItem, _unselectedItemStyle);
_mouseOverItem = '';
}
ChangeReportItemStyle(id, currentStyle);
}
function ChangeReportItemStyleOnBlur(id, style)
{
ChangeReportItemStyle(id, style);
_tabFocusedItem = '';
}
function ChangeReportItemStyleOnMouseOver(id, currentStyle, unselectedStyle)
{
_unselectedItemStyle = unselectedStyle;
_mouseOverItem = id;
// We should unselect tabbed item if there is one
if(_tabFocusedItem != '')
{
ChangeReportItemStyle(_tabFocusedItem, _unselectedItemStyle);
_tabFocusedItem = '';
}
ChangeReportItemStyle(id, currentStyle);
}
function ChangeReportItemStyleOnMouseOut(id, style)
{
ChangeReportItemStyle(id, style);
_mouseOverItem = '';
}
// This function is used to set the style of the search bar on the onclick event.
function SearchBarClicked(id, defaultText, style) {
var selectedElement = document.getElementById(id);
if (selectedElement.value == defaultText) {
selectedElement.value = "";
selectedElement.className = style;
}
}
// This function is used to set the style of the search bar on the onblur event.
function SearchBarBlured(id, defaultText, style) {
var selectedElement = document.getElementById(id);
if (selectedElement.value == "") {
selectedElement.value = defaultText;
selectedElement.className = style;
}
}
function ResetSearchBar(searchTextBoxID,defaultSearchValue) {
var selectedElement = document.getElementById(searchTextBoxID);
if (selectedElement != null) {
if (selectedElement.value == defaultSearchValue) {
selectedElement.className = 'msrs-searchDefaultFont';
}
else {
selectedElement.className = 'msrs-searchBarNoBorder';
}
}
}
function OnLink()
{
_onLink = true;
}
function OffLink()
{
_onLink = false;
}
function ShouldDelete(confirmMessage) {
if (_selectedIdHiddenField.value != null || _selectedIdHiddenField.value != "") {
var message = confirmMessage.replace("{0}", _selectedIdHiddenField.value);
var result = confirm(message);
if (result == true) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
function UpdateValidationButtonState(promptCredsRdoBtnId, typesDropDownId, forbiddenTypesConfigString, validateButtonId)
{
var dropdown = document.getElementById(typesDropDownId);
if(dropdown == null)
{
return;
}
var selectedValue = dropdown.options[dropdown.selectedIndex].value;
var forbiddenTypes = forbiddenTypesConfigString.split(":");
var chosenForbiddenType = false;
for (i = 0; i < forbiddenTypes.length; i++)
{
if(forbiddenTypes[i] == selectedValue)
{
chosenForbiddenType = true;
}
}
var isDisabled = chosenForbiddenType || IsRadioButtonChecked(promptCredsRdoBtnId);
ChangeDisabledButtonState(validateButtonId, isDisabled);
}
function ChangeDisabledButtonState(buttonId, isDisabled)
{
var button = document.getElementById(buttonId);
if(button != null)
{
button.disabled = isDisabled;
}
}
function IsRadioButtonChecked(radioButtonId)
{
var rbtn = document.getElementById(radioButtonId);
if(rbtn != null && rbtn.checked)
{
return true;
}
return false;
}
I have a 'jargon buster' on my site that uses an xml file to load an A-Z of words which when clicked display a brief short explanation of each word. This works fine in all browsers bar the latest ie's which i get an 'undefined' error with. The jscript im using is below
Jargon = {
xmlfile: 'http://www.mysite.com/jargon.xml',
xml: null,
wordHolder: 'words',
defHolder: 'definition',
idprefix: 'jargon_',
selected: null,
init: function () {
var con = Jargon.xhcon();
Jargon.wordHolder = $(Jargon.wordHolder);
Jargon.defHolder = $(Jargon.defHolder);
if (!con || !Jargon.wordHolder || !Jargon.defHolder) {
return;
}
function conComplete(oXML) {
Jargon.xml = oXML.responseXML;
//Jargon.showWords('a');
}
con.connect(Jargon.xmlfile, 'GET', Math.random(), conComplete);
},
showWords: function (c) {
if (Jargon.selected) {
Jargon.selected.className = '';
}
var words = Jargon.getWords(c);
while (Jargon.wordHolder.childNodes.length > 0) {
Jargon.wordHolder.removeChild(Jargon.wordHolder.childNodes[0]);
}
while (Jargon.defHolder.childNodes.length > 0) {
Jargon.defHolder.removeChild(Jargon.defHolder.childNodes[0]);
}
for (var i = 0; i < words.length; i++) {
var o = document.createElement('a');
o.href = 'javascript:Jargon.showDef(\'' + words[i].id + '\');';
o.id = Jargon.idprefix + words[i].id;
//o.onclick = Jargon.showDef;
o.appendChild($t(words[i].name));
Jargon.wordHolder.appendChild(o);
Jargon.wordHolder.appendChild(document.createElement('br'));
}
if (!words.length) {
var o = document.createElement('p');
var s = 'There are no words for the letter ' + c.toUpperCase();
Jargon.wordHolder.appendChild(o.appendChild($t(s)));
}
},
showDef: function (id) {
var o = $(Jargon.idprefix + id);
if (Jargon.selected) {
Jargon.selected.className = '';
}
if (o) {
o.className = 'selected';
Jargon.selected = o;
}
var defobjs = Jargon.getDef(id);
while (Jargon.defHolder.childNodes.length > 0) {
Jargon.defHolder.removeChild(Jargon.defHolder.childNodes[0]);
}
var heading = document.createElement('span');
heading.className = "jargtitle";
heading.appendChild(document.createTextNode(defobjs[1][0].textContent));
Jargon.defHolder.appendChild(heading);
var definition = document.createElement('span');
definition.className = "jargdefinition";
definition.appendChild(document.createTextNode(defobjs[0][0].textContent));
Jargon.defHolder.appendChild(definition);
},
getWords: function(c) {
var x = Jargon.xml;
var letters = x.getElementsByTagName('letter');
var oLetter = null;
for (var i = 0; i < letters.length; i++) {
if (letters[i].getAttribute('id') == c) {
oLetter = letters[i];
break;
}
}
if (!oLetter) {
return [];
}
var words = [];
for (i = 0; i < oLetter.childNodes.length; i++) {
var oJargon = oLetter.childNodes[i];
if (oJargon.nodeName == 'jargon') {
var s = Jargon.getName(oJargon);
words[words.length] = {
id: oLetter.childNodes[i].getAttribute('id'),
name: s
};
}
}
return words;
},
getDef: function (id) {
var x = Jargon.xml;
var j = null;
var temp = new Array(2);
var jargons = x.getElementsByTagName('jargon');
for (var i = 0; i < jargons.length; i++) {
if (jargons[i].getAttribute('id') == id) {
j = jargons[i];
break;
}
}
if (!j) {
return [];
}
//return [];
for (i = 0; i < j.childNodes.length; i++) {
if (j.childNodes[i].nodeName == 'name') {
temp[1] = j.childNodes[i].childNodes;
}
}
for (i = 0; i < j.childNodes.length; i++) {
if (j.childNodes[i].nodeName == 'desc') {
temp[0] = j.childNodes[i].childNodes;
}
}
//return [];
return temp;
},
cloneNode: function (oldNode, deep) {
deep = (deep) ? true : false;
// a replacement to the normal dom clone node
// this will copy xml nodes to html nodes
// which can then be inserted into the document
// scope in all browsers
// See for for the bug http://www.quirksmode.org/blog/archives/2005/12/xmlhttp_notes_c.html
var newNode = null;
if (oldNode.nodeType == '3') {
// textnode
newNode = $t(oldNode.nodeValue);
}
else if (oldNode.nodeType == '1') {
// element node
newNode = document.createElement(oldNode.nodeName);
if (deep) {
for (var i = 0; i < oldNode.childNodes.length; i++) {
newNode.appendChild(Jargon.cloneNode(oldNode.childNodes[i], true));
}
}
}
return newNode;
},
getName: function (oJargon) {
for (var i = 0; i < oJargon.childNodes.length; i++) {
if (oJargon.childNodes[i].nodeName == 'name') {
var oName = oJargon.childNodes[i];
var s = '';
for (var j = 0; j < oName.childNodes.length; j++) {
if (oName.childNodes[j].nodeType == 3) {
// text node
s += oName.childNodes[j].nodeValue;
}
}
return s;
}
}
return '';
},
xhcon: function () {
var xmlhttp, bComplete = false;
try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) { try { xmlhttp = new XMLHttpRequest(); }
catch (e) { xmlhttp = false; }}}
if (!xmlhttp) {
return null;
}
this.connect = function(sURL, sMethod, sVars, fnDone) {
if (!xmlhttp) {
return false;
}
bComplete = false;
sMethod = sMethod.toUpperCase();
try {
if (sMethod == "GET") {
xmlhttp.open(sMethod, sURL+"?"+sVars, true);
sVars = "";
}
else {
xmlhttp.open(sMethod, sURL, true);
xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && !bComplete) {
bComplete = true;
fnDone(xmlhttp);
}
};
xmlhttp.send(sVars);
}
catch(z) { return false; }
return true;
};
return this;
}
}
In terms of how im calling the jscript im using <li>a</li>
which loads a list of all items that begin with f then when i click one of items from that list say "Fiduciary" it triggers javascript:Jargon.showDef('f1'); which in turns loads the and into a definition div
however in ie9 it displays "undefined" . It works in all other browers
Example of the XML below:
<letter id="f"> -<jargon id="f1"> <name>Fiduciary</name> <desc>in a position of trust. This includes people such as trustees looking after trust assets for the beneficiaries and company directors running a company for the shareholders' benefit.</desc> </jargon> -<jargon id="f2"> <name>Forfeiture</name> <desc>the loss of possession of a property because the tenancy conditions have not been met by the tenant.</desc> </jargon> -<jargon id="f3"> <name>Freehold</name> <desc>describing land that only the owner has any rights over.</desc> </jargon> -<jargon id="f4"> <name>Free of encumbrances</name> <desc>no one else having any rights over something. When property is owned by someone and nobody else has any rights over it, it is owned free of encumbrances.</desc> </jargon> </letter>
I have a javascript file for history management. It is not supported by chrome when i am trying to navigate to back page with back button in the browser.I can see the url change but it doesnt go to preceeding page.
BrowserHistoryUtils = {
addEvent: function(elm, evType, fn, useCapture) {
useCapture = useCapture || false;
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
}
else if (elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;
}
else {
elm['on' + evType] = fn;
}
}
}
BrowserHistory = (function() {
// type of browser
var browser = {
ie: false,
firefox: false,
safari: false,
opera: false,
version: -1
};
// if setDefaultURL has been called, our first clue
// that the SWF is ready and listening
//var swfReady = false;
// the URL we'll send to the SWF once it is ready
//var pendingURL = '';
// Default app state URL to use when no fragment ID present
var defaultHash = '';
// Last-known app state URL
var currentHref = document.location.href;
// Initial URL (used only by IE)
var initialHref = document.location.href;
// Initial URL (used only by IE)
var initialHash = document.location.hash;
// History frame source URL prefix (used only by IE)
var historyFrameSourcePrefix = 'history/historyFrame.html?';
// History maintenance (used only by Safari)
var currentHistoryLength = -1;
var historyHash = [];
var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);
var backStack = [];
var forwardStack = [];
var currentObjectId = null;
//UserAgent detection
var useragent = navigator.userAgent.toLowerCase();
if (useragent.indexOf("opera") != -1) {
browser.opera = true;
} else if (useragent.indexOf("msie") != -1) {
browser.ie = true;
browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
} else if (useragent.indexOf("safari") != -1) {
browser.safari = true;
browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
} else if (useragent.indexOf("gecko") != -1) {
browser.firefox = true;
}
if (browser.ie == true && browser.version == 7) {
window["_ie_firstload"] = false;
}
// Accessor functions for obtaining specific elements of the page.
function getHistoryFrame()
{
return document.getElementById('ie_historyFrame');
}
function getAnchorElement()
{
return document.getElementById('firefox_anchorDiv');
}
function getFormElement()
{
return document.getElementById('safari_formDiv');
}
function getRememberElement()
{
return document.getElementById("safari_remember_field");
}
// Get the Flash player object for performing ExternalInterface callbacks.
// Updated for changes to SWFObject2.
function getPlayer(id) {
if (id && document.getElementById(id)) {
var r = document.getElementById(id);
if (typeof r.SetVariable != "undefined") {
return r;
}
else {
var o = r.getElementsByTagName("object");
var e = r.getElementsByTagName("embed");
if (o.length > 0 && typeof o[0].SetVariable != "undefined") {
return o[0];
}
else if (e.length > 0 && typeof e[0].SetVariable != "undefined") {
return e[0];
}
}
}
else {
var o = document.getElementsByTagName("object");
var e = document.getElementsByTagName("embed");
if (e.length > 0 && typeof e[0].SetVariable != "undefined") {
return e[0];
}
else if (o.length > 0 && typeof o[0].SetVariable != "undefined") {
return o[0];
}
else if (o.length > 1 && typeof o[1].SetVariable != "undefined") {
return o[1];
}
}
return undefined;
}
function getPlayers() {
var players = [];
if (players.length == 0) {
var tmp = document.getElementsByTagName('object');
players = tmp;
}
if (players.length == 0 || players[0].object == null) {
var tmp = document.getElementsByTagName('embed');
players = tmp;
}
return players;
}
function getIframeHash() {
var doc = getHistoryFrame().contentWindow.document;
var hash = String(doc.location.search);
if (hash.length == 1 && hash.charAt(0) == "?") {
hash = "";
}
else if (hash.length >= 2 && hash.charAt(0) == "?") {
hash = hash.substring(1);
}
return hash;
}
/* Get the current location hash excluding the '#' symbol. */
function getHash() {
// It would be nice if we could use document.location.hash here,
// but it's faulty sometimes.
var idx = document.location.href.indexOf('#');
return (idx >= 0) ? document.location.href.substr(idx+1) : '';
}
/* Get the current location hash excluding the '#' symbol. */
function setHash(hash) {
// It would be nice if we could use document.location.hash here,
// but it's faulty sometimes.
if (hash == '') hash = '#'
document.location.hash = hash;
}
function createState(baseUrl, newUrl, flexAppUrl) {
return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
}
/* Add a history entry to the browser.
* baseUrl: the portion of the location prior to the '#'
* newUrl: the entire new URL, including '#' and following fragment
* flexAppUrl: the portion of the location following the '#' only
*/
function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
//delete all the history entries
forwardStack = [];
if (browser.ie) {
//Check to see if we are being asked to do a navigate for the first
//history entry, and if so ignore, because it's coming from the creation
//of the history iframe
if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
currentHref = initialHref;
return;
}
if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
newUrl = baseUrl + '#' + defaultHash;
flexAppUrl = defaultHash;
} else {
// for IE, tell the history frame to go somewhere without a '#'
// in order to get this entry into the browser history.
getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
}
setHash(flexAppUrl);
} else {
//ADR
if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
initialState = createState(baseUrl, newUrl, flexAppUrl);
} else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
}
if (browser.safari) {
// for Safari, submit a form whose action points to the desired URL
if (browser.version <= 419.3) {
var file = window.location.pathname.toString();
file = file.substring(file.lastIndexOf("/")+1);
getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
//get the current elements and add them to the form
var qs = window.location.search.substring(1);
var qs_arr = qs.split("&");
for (var i = 0; i < qs_arr.length; i++) {
var tmp = qs_arr[i].split("=");
var elem = document.createElement("input");
elem.type = "hidden";
elem.name = tmp[0];
elem.value = tmp[1];
document.forms.historyForm.appendChild(elem);
}
document.forms.historyForm.submit();
} else {
top.location.hash = flexAppUrl;
}
// We also have to maintain the history by hand for Safari
historyHash[history.length] = flexAppUrl;
_storeStates();
} else {
// Otherwise, write an anchor into the page and tell the browser to go there
addAnchor(flexAppUrl);
setHash(flexAppUrl);
}
}
backStack.push(createState(baseUrl, newUrl, flexAppUrl));
}
function _storeStates() {
if (browser.safari) {
getRememberElement().value = historyHash.join(",");
}
}
function handleBackButton() {
//The "current" page is always at the top of the history stack.
var current = backStack.pop();
if (!current) { return; }
var last = backStack[backStack.length - 1];
if (!last && backStack.length == 0){
last = initialState;
}
forwardStack.push(current);
}
function handleForwardButton() {
//summary: private method. Do not call this directly.
var last = forwardStack.pop();
if (!last) { return; }
backStack.push(last);
}
function handleArbitraryUrl() {
//delete all the history entries
forwardStack = [];
}
/* Called periodically to poll to see if we need to detect navigation that has occurred */
function checkForUrlChange() {
if (browser.ie) {
if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
//This occurs when the user has navigated to a specific URL
//within the app, and didn't use browser back/forward
//IE seems to have a bug where it stops updating the URL it
//shows the end-user at this point, but programatically it
//appears to be correct. Do a full app reload to get around
//this issue.
if (browser.version < 7) {
currentHref = document.location.href;
document.location.reload();
} else {
if (getHash() != getIframeHash()) {
// this.iframe.src = this.blankURL + hash;
var sourceToSet = historyFrameSourcePrefix + getHash();
getHistoryFrame().src = sourceToSet;
}
}
}
}
if (browser.safari) {
// For Safari, we have to check to see if history.length changed.
if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
//alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
// If it did change, then we have to look the old state up
// in our hand-maintained array since document.location.hash
// won't have changed, then call back into BrowserManager.
currentHistoryLength = history.length;
var flexAppUrl = historyHash[currentHistoryLength];
if (flexAppUrl == '') {
//flexAppUrl = defaultHash;
}
//ADR: to fix multiple
if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
var pl = getPlayers();
for (var i = 0; i < pl.length; i++) {
pl[i].browserURLChange(flexAppUrl);
}
} else {
getPlayer().browserURLChange(flexAppUrl);
}
_storeStates();
}
}
if (browser.firefox) {
if (currentHref != document.location.href) {
var bsl = backStack.length;
var urlActions = {
back: false,
forward: false,
set: false
}
if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
urlActions.back = true;
// FIXME: could this ever be a forward button?
// we can't clear it because we still need to check for forwards. Ugg.
// clearInterval(this.locationTimer);
handleBackButton();
}
// first check to see if we could have gone forward. We always halt on
// a no-hash item.
if (forwardStack.length > 0) {
if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
urlActions.forward = true;
handleForwardButton();
}
}
// ok, that didn't work, try someplace back in the history stack
if ((bsl >= 2) && (backStack[bsl - 2])) {
if (backStack[bsl - 2].flexAppUrl == getHash()) {
urlActions.back = true;
handleBackButton();
}
}
if (!urlActions.back && !urlActions.forward) {
var foundInStacks = {
back: -1,
forward: -1
}
for (var i = 0; i < backStack.length; i++) {
if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
arbitraryUrl = true;
foundInStacks.back = i;
}
}
for (var i = 0; i < forwardStack.length; i++) {
if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
arbitraryUrl = true;
foundInStacks.forward = i;
}
}
handleArbitraryUrl();
}
// Firefox changed; do a callback into BrowserManager to tell it.
currentHref = document.location.href;
var flexAppUrl = getHash();
if (flexAppUrl == '') {
//flexAppUrl = defaultHash;
}
//ADR: to fix multiple
if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
var pl = getPlayers();
for (var i = 0; i < pl.length; i++) {
pl[i].browserURLChange(flexAppUrl);
}
} else {
getPlayer().browserURLChange(flexAppUrl);
}
}
}
//setTimeout(checkForUrlChange, 50);
}
/* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
function addAnchor(flexAppUrl)
{
if (document.getElementsByName(flexAppUrl).length == 0) {
getAnchorElement().innerHTML += "<a name='" + flexAppUrl + "'>" + flexAppUrl + "</a>";
}
}
var _initialize = function () {
if (browser.ie)
{
var scripts = document.getElementsByTagName('script');
for (var i = 0, s; s = scripts[i]; i++) {
if (s.src.indexOf("history.js") > -1) {
var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
}
}
historyFrameSourcePrefix = iframe_location + "?";
var src = historyFrameSourcePrefix;
var iframe = document.createElement("iframe");
iframe.id = 'ie_historyFrame';
iframe.name = 'ie_historyFrame';
//iframe.src = historyFrameSourcePrefix;
try {
document.body.appendChild(iframe);
} catch(e) {
setTimeout(function() {
document.body.appendChild(iframe);
}, 0);
}
}
if (browser.safari)
{
var rememberDiv = document.createElement("div");
rememberDiv.id = 'safari_rememberDiv';
document.body.appendChild(rememberDiv);
rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';
var formDiv = document.createElement("div");
formDiv.id = 'safari_formDiv';
document.body.appendChild(formDiv);
var reloader_content = document.createElement('div');
reloader_content.id = 'safarireloader';
var scripts = document.getElementsByTagName('script');
for (var i = 0, s; s = scripts[i]; i++) {
if (s.src.indexOf("history.js") > -1) {
html = (new String(s.src)).replace(".js", ".html");
}
}
reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
document.body.appendChild(reloader_content);
reloader_content.style.position = 'absolute';
reloader_content.style.left = reloader_content.style.top = '-9999px';
iframe = reloader_content.getElementsByTagName('iframe')[0];
if (document.getElementById("safari_remember_field").value != "" ) {
historyHash = document.getElementById("safari_remember_field").value.split(",");
}
}
if (browser.firefox)
{
var anchorDiv = document.createElement("div");
anchorDiv.id = 'firefox_anchorDiv';
document.body.appendChild(anchorDiv);
}
//setTimeout(checkForUrlChange, 50);
}
return {
historyHash: historyHash,
backStack: function() { return backStack; },
forwardStack: function() { return forwardStack },
getPlayer: getPlayer,
initialize: function(src) {
_initialize(src);
},
setURL: function(url) {
document.location.href = url;
},
getURL: function() {
return document.location.href;
},
getTitle: function() {
return document.title;
},
setTitle: function(title) {
try {
backStack[backStack.length - 1].title = title;
} catch(e) { }
//if on safari, set the title to be the empty string.
if (browser.safari) {
if (title == "") {
try {
var tmp = window.location.href.toString();
title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
} catch(e) {
title = "";
}
}
}
document.title = title;
},
setDefaultURL: function(def)
{
defaultHash = def;
def = getHash();
//trailing ? is important else an extra frame gets added to the history
//when navigating back to the first page. Alternatively could check
//in history frame navigation to compare # and ?.
if (browser.ie)
{
window['_ie_firstload'] = true;
var sourceToSet = historyFrameSourcePrefix + def;
var func = function() {
getHistoryFrame().src = sourceToSet;
window.location.replace("#" + def);
setInterval(checkForUrlChange, 50);
}
try {
func();
} catch(e) {
window.setTimeout(function() { func(); }, 0);
}
}
if (browser.safari)
{
currentHistoryLength = history.length;
if (historyHash.length == 0) {
historyHash[currentHistoryLength] = def;
var newloc = "#" + def;
window.location.replace(newloc);
} else {
//alert(historyHash[historyHash.length-1]);
}
//setHash(def);
setInterval(checkForUrlChange, 50);
}
if (browser.firefox || browser.opera)
{
var reg = new RegExp("#" + def + "$");
if (window.location.toString().match(reg)) {
} else {
var newloc ="#" + def;
window.location.replace(newloc);
}
setInterval(checkForUrlChange, 50);
//setHash(def);
}
},
/* Set the current browser URL; called from inside BrowserManager to propagate
* the application state out to the container.
*/
setBrowserURL: function(flexAppUrl, objectId) {
if (browser.ie && typeof objectId != "undefined") {
currentObjectId = objectId;
}
//fromIframe = fromIframe || false;
//fromFlex = fromFlex || false;
//alert("setBrowserURL: " + flexAppUrl);
//flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
var pos = document.location.href.indexOf('#');
var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
var newUrl = baseUrl + '#' + flexAppUrl;
if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
currentHref = newUrl;
addHistoryEntry(baseUrl, newUrl, flexAppUrl);
currentHistoryLength = history.length;
}
return false;
},
browserURLChange: function(flexAppUrl) {
var objectId = null;
if (browser.ie && currentObjectId != null) {
objectId = currentObjectId;
}
pendingURL = '';
if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
var pl = getPlayers();
for (var i = 0; i < pl.length; i++) {
try {
pl[i].browserURLChange(flexAppUrl);
} catch(e) { }
}
} else {
try {
getPlayer(objectId).browserURLChange(flexAppUrl);
} catch(e) { }
}
currentObjectId = null;
}
}
})();
// Initialization
// Automated unit testing and other diagnostics
function setURL(url)
{
document.location.href = url;
}
function backButton()
{
history.back();
}
function forwardButton()
{
history.forward();
}
function goForwardOrBackInHistory(step)
{
history.go(step);
}
//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
(function(i) {
var u =navigator.userAgent;var e=/*#cc_on!#*/false;
var st = setTimeout;
if(/webkit/i.test(u)){
st(function(){
var dr=document.readyState;
if(dr=="loaded"||dr=="complete"){i()}
else{st(arguments.callee,10);}},10);
} else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
document.addEventListener("DOMContentLoaded",i,false);
} else if(e){
(function(){
var t=document.createElement('doc:rdy');
try{t.doScroll('left');
i();t=null;
}catch(e){st(arguments.callee,0);}})();
} else{
window.onload=i;
}
})( function() {BrowserHistory.initialize();} );
The script doesn't support chrome. Read through it in most of the functions like checkForUrlChange() it looks at the name of the browser to decide what to do.
Because chrome and safari are both based on webkit, you can try to change the line useragent.indexOf("safari") != -1 to useragent.indexOf("safari") != -1 || useragent.indexOf("chrome") != -1 to see if that works.
If not, try using unfocus history keeper. It supports Chrome.
(http://www.unfocus.com/projects/historykeeper/)
Why oh why oh why... I can't figure out why I keep getting this error. I think I might cry.
/*** common functions */
function GE(id) { return document.getElementById(id); }
function changePage(newLoc) {
nextPage = newLoc.options[newLoc.selectedIndex].value
if (nextPage != "")
{
document.location.href = nextPage
}
}
function isHorizO(){
if (navigator.userAgent.indexOf('iPod')>-1)
return (window.orientation == 90 || window.orientation==-90)? 1 : 0;
else return 1;
}
function ShowHideE(el, act){
if (GE(el)) GE(el).style.display = act;
}
function KeepTop(){
window.scrollTo(0, 1);
}
/* end of common function */
var f = window.onload;
if (typeof f == 'function'){
window.onload = function() {
f();
init();
}
}else window.onload = init;
function init(){
if (GE('frontpage')) init_FP();
else {
if (GE('image')) init_Image();
setTimeout('window.scrollTo(0, 1)', 100);
}
AddExtLink();
}
function AddExtLink(){
var z = GE('extLink');
if (z){
z = z.getElementsByTagName('a');
if (z.length>0){
z = z[0];
var e_name = z.innerHTML;
var e_link = z.href;
var newOption, oSe;
if (GE('PSel')) oSe = new Array(GE('PSel'));
else
oSe = getObjectsByClassName('PSel', 'select')
for(i=0; i<oSe.length; i++){
newOption = new Option(e_name, e_link);
oSe[i].options[oSe[i].options.length] = newOption;
}
}
}
}
/* fp */
function FP_OrientChanged() {
init_FP();
}
function init_FP() {
// GE('orientMsg').style.visibility = (!isHorizO())? 'visible' : 'hidden';
}
/* gallery */
function GAL_OrientChanged(link){
if (!isHorizO()){
ShowHideE('vertCover', 'block');
GoG(link);
}
setTimeout('window.scrollTo(0, 1)', 500);
}
function init_Portfolio() {
// if (!isHorizO())
// ShowHideE('vertCover', 'block');
}
function ShowPortfolios(){
if (isHorizO()) ShowHideE('vertCover', 'none');
}
var CurPos_G = 1
function MoveG(dir) {
MoveItem('G',CurPos_G, dir);
}
/* image */
function init_Image(){
// check for alone vertical images
PlaceAloneVertImages();
}
function Img_OrtChanged(){
//CompareOrientation(arImgOrt[CurPos_I]);
//setTimeout('window.scrollTo(0, 1)', 500);
}
var CurPos_I = 1
function MoveI(dir) {
CompareOrientation(arImgOrt[CurPos_I+dir]);
MoveItem('I',CurPos_I, dir);
}
var arImgOrt = new Array(); // orientation: 1-horizontal, 0-vertical
var aModeName = new Array('Horizontal' , 'Vertical');
var arHs = new Array();
function getDims(obj, ind){
var arT = new Array(2);
arT[0] = obj.height;
arT[1] = obj.width;
//arWs[ind-1] = arT;
arHs[ind] = arT[0];
//**** (arT[0] > arT[1]) = (vertical image=0)
arImgOrt[ind] = (arT[0] > arT[1])? 0 : 1;
// todor debug
if(DebugMode) {
//alert("["+obj.width+","+obj.height+"] mode="+((arT[0] > arT[1])? 'verical' : 'hoziontal'))
writeLog("["+obj.width+","+obj.height+"] mode="+((arT[0] > arT[1])? 'verical' : 'hoziontal')+' src='+obj.src)
}
if (arImgOrt[ind]) {
GE('mi'+ind).className = 'mImageH';
}
}
function CompareOrientation(imgOrt){
var iPhoneOrt = aModeName[isHorizO()];
GE('omode').innerHTML = iPhoneOrt;
//alert(imgOrt == isHorizO())
var sSH = (imgOrt == isHorizO())? 'none' : 'block';
ShowHideE('vertCover', sSH);
var sL = imgOrt? 'H' : 'V';
if (GE('navig')) GE('navig').className = 'navig'+ sL ;
if (GE('mainimage')) GE('mainimage').className = 'mainimage'+sL;
var sPfL = imgOrt? 'Port-<br>folios' : 'Portfolios' ;
if (GE('PortLnk')) GE('PortLnk').innerHTML = sPfL;
}
function SetGetDim( iMInd){
var dv = GE('IImg'+iMInd);
if (dv) {
var arI = dv.getElementsByTagName('img');
if (arI.length>0){
var oImg = arI[0];
oImg.id = 'Img'+iMInd;
oImg.className = 'imageStyle';
//YAHOO.util.Event.removeListener('Img'+iMInd,'load');
YAHOO.util.Event.on('Img'+iMInd, 'load', function(){GetDims(oImg,iMInd);}, true, true);
//oImg.addEventListener('load',GetDims(oImg,iMInd),true);
}
}
}
var occ = new Array();
function PlaceAloneVertImages(){
var iBLim, iELim;
iBLim = 0;
iELim = arImgOrt.length;
occ[0] = true;
//occ[iELim]=true;
for (i=1; i<iELim; i++){
if ( arImgOrt[i]){//horizontal image
occ[i]=true;
continue;
}else { // current is vertical
if (!occ[i-1]){//previous is free-alone. this happens only the first time width i=1
occ[i] = true;
continue;
}else {
if (i+1 == iELim){//this is the last image, it is alone and vertical
GE('mi'+i).className = 'mImageV_a'; //***** expand the image container
}else {
if ( arImgOrt[i+1] ){
GE('mi'+i).className = 'mImageV_a';//*****expland image container
occ[i] = true;
occ[i+1] = true;
i++;
continue;
}else { // second vertical image
occ[i] = true;
occ[i+1] = true;
if (arHs[i]>arHs[i+1]) GE('mi'+(i+1)).style.height = arHs[i]+'px';
i++;
continue;
}
}
}
}
}
//arImgOrt
}
function AdjustWebSiteTitle(){
//if (GE('wstitle')) if (GE('wstitle').offsetWidth > GE('wsholder').offsetWidth) {
if (GE('wstitle')) if (GE('wstitle').offsetWidth > 325) {
ShowHideE('dots1','block');
ShowHideE('dots2','block');
}
}
function getObjectsByClassName(className, eLTag, parent){
var oParent;
var arr = new Array();
if (parent) oParent = GE(parent); else oParent=document;
var elems = oParent.getElementsByTagName(eLTag);
for(var i = 0; i < elems.length; i++)
{
var elem = elems[i];
var cls = elem.className
if(cls == className){
arr[arr.length] = elem;
}
}
return arr;
}
////////////////////////////////
///
// todor debug
var DebugMode = (getQueryVariable("debug")=="1")
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
var sRet = ""
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
sRet = pair[1];
}
}
return sRet
//alert('Query Variable ' + variable + ' not found');
}
var oLogDiv=''
function writeLog(sMes){
if(!oLogDiv) oLogDiv=document.getElementById('oLogDiv')
if(!oLogDiv) {
oLogDiv = document.createElement("div");
oLogDiv.style.border="1px solid red"
var o = document.getElementsByTagName("body")
if(o.length>0) {
o[0].appendChild(oLogDiv)
}
}
if(oLogDiv) {
oLogDiv.innerHTML = sMes+"<br>"+oLogDiv.innerHTML
}
}
First, Firebug is your friend, get used to it. Second, if you paste each function and some supporting lines, one by one, you will eventually get to the following.
var DebugMode = (getQueryVariable("debug")=="1")
function getQueryVariable(variable)
You can't execute getQueryVariable before it is defined, you can create a handle to a future reference though, there is a difference.
There are several other potential issues in your code, but putting the var DebugMode line after the close of the getQueryVariable method should work fine.
It would help if you gave more context. For example, is
Failed to load source for:
http://localhost/js/m.js
the literal text of an error message? Where and when do you see it?
Also, does that code represent the contents of http://localhost/js/m.js? It seems that way, but it's hard to tell.
In any case, the JavaScript that you've shown has quite a few statements that are missing their semicolons. There may be other syntax errors as well. If you can't find them on your own, you might find tools such as jslint to be helpful.
make sure the type attribute in tag is "text/javascript" not "script/javascript".
I know it is more than a year since this question was asked, but I faced this today. I had a
<script type="text/javascript" src="/test/test-script.js"/>
and I was getting the 'Failed to load source for: http://localhost/test/test-script.js' error in Firebug. Even chrome was no loading this script. Then I modified the above line as
<script type="text/javascript" src="/test/test-script.js"></script>
and it started working both in Firefox and chrome. Documenting this here hoping that this will help someone. Btw, I dont know why the later works where as the previous one didn't.