All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wings.js.wings.wings.js Maven / Gradle / Ivy

The newest version!
/***************************************************************************************************
 * WINGS.NAMESPACE  --  contains: global namespace object and related functions
 **************************************************************************************************/

/**
 * Create global namespace object
 */
if (typeof wingS == "undefined") {
    var wingS = {};
}

/**
 * Returns the namespace specified and creates it if it doesn't exist. For example both,
 * 'wingS.namespace("property.package");' and 'wingS.namespace("wingS.property.package");'
 * would create wingS.property, then wingS.property.package --> (@see YAHOO.namespace()).
 * @param {String} arguments - 1 to n namespaces to create (separated with '.')
 * @return {Object} reference to the last namespace object created
 */
wingS.namespace = function() {
    var a=arguments, o=null, i, j, d;
    for (i=0; i 0) {
        // Only if something is going on
        wingS.global.asyncHeaderCount--;
        wingS.global.dequeueNextHeader();
    }
};

/**
 * Enqueues the given header download if another one is still in action.
 * @param {Function} load - the function to load the header with
 * @param {Array} args - the arguments needed by the load function
 * @return {boolean} true, if header was enqueued, false otherwise
 */
wingS.global.enqueueThisHeader = function(load, args) {
    if (wingS.global.asyncHeaderCount > 0) { // Load one header after another
        // This is because header 2 might require header 1 to be fully loaded
        wingS.global.asyncHeaderQueue.push( {"load" : load, "args" : args} );
        return true;
    }
    return false;
};

/**
 * Grabs the next available header download from the queue and starts it.
 */
wingS.global.dequeueNextHeader = function() {
    if (wingS.global.asyncHeaderQueue.length > 0) {
        // Remove and start first enqueued header download
        var header = wingS.global.asyncHeaderQueue.shift();
        var args = header.args;
        header.load(args[0], args[1], args[2], args[3]);
    } else {
        // Invoke all callback methods which have registered interest
        for (var i = 0; i < wingS.global.asyncHeaderCalls.length; i++) {
            wingS.global.asyncHeaderCalls[i]();
        }
        // Clear all callbacks upon each new request
        wingS.global.asyncHeaderCalls = new Array();

        // Reset activity indicators and active flag
        wingS.ajax.setActivityIndicatorsVisible(false);
        wingS.ajax.requestIsActive = false;

        // Send the next enqueued request
        wingS.ajax.dequeueNextRequest();
    }
};

/**
 * Enables debugging at a certain level
 */
wingS.global.enableDebugging = function(loglevel) {
   if (loglevel === undefined || loglevel === null || loglevel === "") {
       loglevel = "off";
   }
   
   wingS.util.setCookie("DEBUG", "javascript|loglevel=" + loglevel, 365, "/");
  
   window.location.reload();
};

/**
 * Enables the YUI console for wingS
 */
wingS.global.enableYuiConsole = function() {
    wingS.global.onHeadersLoaded(function() {
        if (!wingS.global.yuiConsole) {
            wingS.global.yuiConsole = new YAHOO.widget.LogReader("compact", {verboseOutput:false, fontSize:"12px"});
            wingS.global.yuiConsole.setTitle("YUI Console for wingS");
        }
        wingS.global.yuiConsole.show();
        wingS.global.yuiConsole.resume();
    });
};

/**
 * Disables the YUI console for wingS
 */
wingS.global.disableYuiConsole = function() {
    if (wingS.global.yuiConsole) {
        wingS.global.yuiConsole.pause();
        wingS.global.yuiConsole.hide();
    }
};


//**************************************************************************************************


/**
 * Enables Firebug API support for Safari
 */
if (YAHOO.env.ua.webkit) {
    var wc = window.console;
    if (wc) {
        wc.debug = wc.log;
        wc.info = wc.log
        wc.warn = wc.log;
        wc.error = wc.log;
    }
}

/**
 * Moves the execution context of the function used upon to the given object. Useful when using
 * setTimeout or event handling, e.g.: setTimeout(func1.bind(someObject), 1); The function func1
 * will be called within the context of someObject. NB: Function object is extended by bind()!
 *
 * @param {Object} obj new execution context
 */
Function.prototype.bind = function(obj) {
    var method = this;
    temp = function() {
        return method.apply(obj, arguments);
    };

    return temp;
};

/***************************************************************************************************
 * WINGS.EVENT  --  contains: functions used to do event handling
 **************************************************************************************************/

// Create module namespace
wingS.namespace("event");


wingS.event.getEvent = function(event) {
    if (window.event)
        return window.event;
    else
        return event;
};

wingS.event.getTarget = function(event) {
    var target;
    if (event.srcElement)
        // according to IE
        target = event.srcElement;
    else if (event.target)
        // according to W3C
        target = event.target;
    if (target.nodeType == 3)
        // defeat Safari bug
        target = target.parentNode;
    return target;
};

/**
 * Cross-browser method to register an event listener on the passed object. Only Mozilla will
 * support captive mode of event handling. The 'eventType' is without the 'on'-prefix.
 * Example: wingS.event.registerEvent(document,'focus',storeFocus,false);
 *
 * Deprecated! Use YAHOO.util.Event.addListener() instead of this function.
 */
wingS.event.registerEvent = function(obj, eventType, func, useCaption) {
    if (obj.addEventListener) {
        obj.addEventListener(eventType, func, useCaption);
        return true;
    } else if (obj.attachEvent) {
        var retVal = object.attachEvent("on" + eventType, func);
        return retVal;
    } else {
        return false;
    }
};

/***************************************************************************************************
 * WINGS.UTIL  --  contains: functions used to do common tasks
 **************************************************************************************************/

// Create module namespace
wingS.namespace("util");


wingS.util.getReloadResource = function() {
    return wingS.global.eventEpoch + "-" + wingS.global.reloadResource;
};

wingS.util.getUpdateResource = function() {
    return wingS.global.eventEpoch + "-" + wingS.global.updateResource;
};

wingS.util.invokeScriptCodeArray = function(scriptCodeArray) {
    if (scriptCodeArray) {
        for (var i = 0; i < scriptCodeArray.length; i++) {
            invokeNext = scriptCodeArray[i]();
            if (invokeNext == false) return false;
        }
    }
    return true;
};

/**
 * Returns an array of elements with the specified properties.
 * @param {Object} parent - the element whose children will be processed
 * @param {String} tagName - the tag name of the elements to look in (use * for all)
 * @param {String} attributeName - the name of the attribute to look for
 * @param {String} attributeValue - the value of the attribute to look for (optional)
 */
wingS.util.getElementsByAttribute = function(parent, tagName, attributeName, attributeValue) {
    var elements = (tagName == "*" && parent.all) ?
                   parent.all : parent.getElementsByTagName(tagName);
    var value = (typeof attributeValue != "undefined") ?
                new RegExp("(^|\\s)" + attributeValue + "(\\s|$)") : null;
    var element;
    var attribute;
    var result = new Array();
    for (var i = 0; i < elements.length; i++) {
        element = elements[i];
        attribute = element.getAttribute && element.getAttribute(attributeName);
        if (typeof attribute == "string" && attribute.length > 0) {
            if (typeof attributeValue == "undefined" || (value && value.test(attribute))) {
                result.push(element);
            }
        }
    }
    return result;
};

wingS.util.getParentByAttribute = function(element, attributeName) {
    var attribute;
    while (element != null) {
        attribute = element.getAttribute && element.getAttribute(attributeName);
        if (typeof attribute == "string" && attribute.length > 0) {
            return element;
        }
        element = element.parentNode;
    }
    return null;
};

wingS.util.getParentByAttributeAndValue = function(element, attributeName, attributeValue) {
    var attribute;
    while (element != null) {
        attribute = element.getAttribute && element.getAttribute(attributeName);
        if (attribute == attributeValue) {
            return element;
        }
        element = element.parentNode;
    }
    return null;
};


wingS.util.getParentByTagName = function(element, tag) {
    while (element != null) {
        if (tag == element.tagName)
            return element;
        element = element.parentNode;
    }
    return null;
};

wingS.util.openLink = function(target, url, scriptCodeArray) {
  if (wingS.util.invokeScriptCodeArray(scriptCodeArray)) {
      // if the target exists => change URL, else => open URL in new window
      if (target == null) {
          wingS.request.sendRedirect(url);
      } else {
          for (var i = 0; i < parent.frames.length; i++) {
              if (parent.frames[i].name == target) {
                  parent.frames[target].location.href = url;
                  return;
              }
          }
          window.open(url, target);
      }
  }
};

// TODO document + event.stopPropagation()
wingS.util.preventDefault = function(event) {
    if (event.preventDefault)
        event.preventDefault();
    if (event.returnValue)
        event.returnValue = false;
    event.cancelBubble = true;
};

/**
 * Can be used to prevent a form submit. By calling 'return wingS.util.preventSubmit()' on the
 * input event 'onkeypress', false will be returned when the return key was hit and by that
 * avoiding a form submit.
 */
wingS.util.preventSubmit = function() {
  return !(window.event && window.event.keyCode == 13);
};

/**
 * All normal requests (except form submits) in a wingS application are done through this method.
 * @param {Object} element - the element on which text selection should be enabled or disabled
 * @param {boolean} prevent - true, if text selection should be prevented - false otherwise
 */
wingS.util.preventTextSelection = function(element, prevent) {
    element.onmousedown = function () { return prevent; }   // Mozilla
    element.onselectstart = function () { return prevent; } // IE
};

/**
 * Inserts a node into the childNodes array after the specified child node refChild. Note:
 * Because there is no function insertAfter, it is done by raping insertBefore.
 * @param {Object} newChild node to insert
 * @param {Object} refChild node to insert after
 */
wingS.util.insertAfter = function(newChild, refChild) {
    refChild.parentNode.insertBefore(newChild, refChild.nextSibling);
};

wingS.util.appendHTML = function(element, html) {
    if (element.insertAdjacentHTML) {
        element.insertAdjacentHTML("BeforeEnd", html);
    } else if (document.createRange) {
        var range = document.createRange();
        if (!range.selectNodeContents || !range.createContextualFragment) {
            return false;
        }
        range.selectNodeContents(element);
        var fragment = range.createContextualFragment(html);
        element.appendChild(fragment);
    } else {
        return false;
    }
    return true;
};

/**
 * Search and return the first HTML element with the given tag name inside the HTML code generated
 * by wings for the passed component id. This function is i.e. helpful if you want to modify i.e.
 * the INPUT element of a STextField which is probably wrapped into TABLE elements wearing the
 * component ID generated by wingS for layouting purposes.
 */
wingS.util.findElement = function(id, tagname) {
    var div = document.getElementById(id);
    if (div) {
        var elements = div.getElementsByTagName(tagname);
        if (elements && elements.length > 0)
            return elements[0];
    }
};

/**
 * Highlights the element with the given ID for a certain time span.
 * @param {String} id - the ID of the element to highlight
 * @param {String} color - the color to highlight with
 * @param {int} duration - the highlight duration in ms
 */
wingS.util.highlightElement = function(id, color, duration) {
    var initialColor = document.getElementById(id).style.backgroundColor;
    document.getElementById(id).style.backgroundColor = color;
    var resetColor = "document.getElementById('" + id + "').style." +
                     "backgroundColor = '" + initialColor + "';";
    setTimeout(resetColor, duration);
};

/**
 * Remove focus from a component and respect additonal custom script listeners attached by user.
 */
wingS.util.blurComponent = function(component, scriptCodeArray) {
    if (wingS.util.invokeScriptCodeArray(scriptCodeArray)) {
        component.blur();
    }
    return true;
};

/**
 * Set focus to a component and respect additonal custom script listeners attached by user.
 */
wingS.util.focusComponent = function(component, scriptCodeArray) {
    if (wingS.util.invokeScriptCodeArray(scriptCodeArray)) {
        component.focus();
    }
    return true;
};

/**
 * Set the focus to a component identified by a wingS id. Also do some heuristic trace-down to the
 * actual HTML element, i.e. a STextField renders as 
but you want * the focus to be the input element and not the table element. */ wingS.util.requestFocus = function(id) { window.focus(); var parent = document.getElementById(id); if (parent != null) { if (!parent.getAttribute("foc")) { parent.setAttribute("foc", id); } if (parent.getAttribute("foc") == id) { if (parent.style.display != "none" && !parent.disabled) { // Workaround for IE6! Without timeout IE6 hangs the complete // GUI in case 'parent' is a combobox and the newly selected // index is smaller than before. Unbelieveable, but true!!! // Also, IE complains sometimes whe the focus is set on non focusable elements // That's why we're wrapping the focus request call inside a try / catch block window.setTimeout(function() { try { wingS.util.focus(parent); } catch (er) {}}, 100); } return; } var tags = new Array("INPUT", "A", "SELECT", "TEXTAREA"); for (var i = 0; i < tags.length; i++) { var elements = parent.getElementsByTagName(tags[i]); for (var j = 0; j < elements.length; j++) { var element = elements[j]; if (element.getAttribute("foc") == id && element.style.display != "none" && !element.disabled) { window.setTimeout(function() { wingS.util.focus(element); }, 100); return; } } } } }; wingS.util.focus = function(component){ component.focus(); if (component.tagName == "INPUT") component.select(); } wingS.util.storeFocus = function(event) { var target = wingS.event.getTarget(event); var eidProvider = wingS.util.getParentByAttribute(target, "eid"); var body = wingS.util.getParentByTagName(target, "BODY"); // Avoid rembering FORM as focus component as this automatically // gains focus on pressing Enter in MSIE. if (eidProvider && body && eidProvider.tagName != "FORM") { wingS.util.setCookie(body.id + "_focus", eidProvider.id, 1); } }; wingS.util.getCookie = function(name) { var c = new Object(); var i = 0; var clen = document.cookie.length; while (i < clen) { var endstr = document.cookie.indexOf(";", i); if (endstr == -1) endstr = document.cookie.length; var v = unescape(document.cookie.substring(i, endstr)); var key = v.substring(0, v.indexOf("=", 0)); var val = v.substring(v.indexOf("=") + 1); c[key] = val; i = endstr + 2; // skip whitespace after ; } if (name) return c[name]; return c; }; wingS.util.setCookie = function(name, value, days, path) { if (!days) days = -1; var expire = new Date(); expire.setTime(expire.getTime() + 86400000 * days); document.cookie = name + "=" + escape(value) + "; expires=" + expire.toGMTString() + ";" + (path ? 'path=' + path : ''); }; wingS.util.handleBodyClick = function(event) { if (window.wpm_handleBodyClicks != undefined) { wpm_handleBodyClicks(event); } }; /** * Returns the size of the browser window. */ wingS.util.windowSize = function() { var size = []; if (self.innerHeight) { // all except Explorer size[0] = self.innerWidth; size[1] = self.innerHeight; } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode size[0] = document.documentElement.clientWidth; size[1] = document.documentElement.clientHeight; } else if (document.body) { // other Explorers size[0] = document.body.clientWidth; size[1] = document.body.clientHeight; } return size; } /** * Calculates the absolute position of the element to the left. */ wingS.util.absLeft = function(el) { return (el.offsetParent) ? el.offsetLeft + wingS.util.absLeft(el.offsetParent) : el.offsetLeft; }; /** * Calculates the absolute position of the element to the top. */ wingS.util.absTop = function(el) { return (el.offsetParent) ? el.offsetTop + wingS.util.absTop(el.offsetParent) : el.offsetTop; }; /** * Alerts all fields/elements of a given object. NB: you will also get object methods (which are * function valued properties). helper function to debug * @param {Object} obj */ wingS.util.printAllFields = function(obj) { for(var i in obj) { logDebug(obj[i], obj); } }; /*************************************************************************************************** * WINGS.REQUEST -- contains: functions used to send new request **************************************************************************************************/ // Create module namespace wingS.namespace("request"); /** * Redirects the browser to the specified url. * @param {String} url - the url to redirect to */ wingS.request.sendRedirect = function(url) { window.location.href = url; }; /** * Sends a request to the ReloadResource attached to this frame thereby forcing a complete reload. * @param {String} parameters - the parameter string that is encoded into the URL (optional) */ wingS.request.reloadFrame = function(parameters) { var reloadRequestUrl = wingS.util.getReloadResource(); if (parameters != null) { if (parameters.charAt(0) != "?") { reloadRequestUrl += "?"; } reloadRequestUrl += parameters; } window.location.href = reloadRequestUrl; }; /** * This method prepares any requests and dispatches them to the appropriate send method. * @param {Object} event - an object that provides information about the occured event * @param {boolean} submit - true, if this request entails a form submit * @param {boolean} async - true, if this request is sent asynchronously * @param {String} eventName - the name of the event or component respectively * @param {String} eventValue - the value of the event or component respectively * @param {Array} scriptCodeArray - the scripts to invoke before sending the request */ wingS.request.sendEvent = function(event, submit, async, eventName, eventValue, scriptCodeArray) { if (wingS.global.isInitialized) { event = wingS.event.getEvent(event); var target; if (event != null) target = wingS.event.getTarget(event); else target = document.forms[0]; // Prepare the appropriate method call var sendMethod; if (submit && target != null) { sendMethod = wingS.request.submitForm; } else { sendMethod = wingS.request.followLink; } var sendMethodArgs = new Array(target, async, eventName, eventValue, scriptCodeArray); // Enqueue asynchronous requests in case another one hasn't been processed yet if (async && wingS.ajax.enqueueThisRequest(sendMethod, sendMethodArgs)) return; // Otherwise instantly send the request by calling the appropriate send method sendMethod(target, async, eventName, eventValue, scriptCodeArray); } }; /** * Each and every form submit within a wingS application is done through this method. * @param {Object} target - the element in the DOM which initiated the form submit * @param {boolean} async - true, if the form should be submitted asynchronously * @param {String} eventName - the name of the event or component respectively * @param {String} eventValue - the value of the event or component respectively * @param {Array} scriptCodeArray - the scripts to invoke before submitting the form */ wingS.request.submitForm = function(target, async, eventName, eventValue, scriptCodeArray) { var form; // The form that we want to submit // Try to get the desired form from an according provider (i.e. this is // used by menues which reside out of any forms but want to submit one) var formProvider = wingS.util.getParentByAttribute(target, "form"); if (formProvider != null) { // Use the form suggested by the provider form = document.getElementById(formProvider.getAttribute("form")); } else { // By default we walk up until we find the first form form = wingS.util.getParentByTagName(target, "FORM"); if(form == null || form.id == undefined || form.id == "") { // this workarounds if a component created forms with no id - it searched the first form with id // maybe look for other things too? class=SForm? var forms = document.getElementsByTagName("form"); if(forms != undefined && forms != null) { for(var i=0; i-1) ? "&" : "?"); uri += "_xhrID=" + new Date().getTime(); } var callbackProxy = { success : function(request) { responded = true; wingS.ajax.callbackObject.success(request); }, failure : function(request) { responded = true; wingS.ajax.callbackObject.failure(request); }, upload : function(request) { responded = true; wingS.ajax.callbackObject.upload(request); } } wingS.ajax.connectionObject = YAHOO.util.Connect.asyncRequest(method, uri, callbackProxy, postData); }; /** * Aborts the currently active request, in case there is any. * @return {boolean} true if successfully aborted, false otherwise */ wingS.ajax.abortRequest = function() { if (YAHOO.util.Connect.isCallInProgress(wingS.ajax.connectionObject)) { return YAHOO.util.Connect.abort(wingS.ajax.connectionObject, wingS.ajax.callbackObject); } return false; }; /** * Callback method which processes any request failures. * @param {Object} request - the request to process */ wingS.ajax.processRequestFailure = function(request) { if (wingS.global.useAjaxDebugView) wingS.ajax.updateDebugView(request); if ("console" in window && window.console) console.error("Error occured while processing request %o", request); // Reset activity indicators and active flag wingS.ajax.setActivityIndicatorsVisible(false); wingS.ajax.requestIsActive = false; // Clear enqueued request wingS.ajax.requestQueue = new Array(); if (request.status == -1) { // Transaction has been aborted --> OK! } else if (request.status == 0) { // Happens in case of a communication // failure, i.e if the server has mean- // while been shut down --> do reload! wingS.request.reloadFrame(); } }; /** * Callback method which processes any successful request. * @param {Object} request - the request to process */ wingS.ajax.processRequestSuccess = function(request) { if (wingS.global.useAjaxDebugView) wingS.ajax.updateDebugView(request); // Get the received XML response var xmlDoc = request.responseXML; if (xmlDoc == null) { // In case we don't get any XML there is nothing more // what we can do here; the only thing --> do reload! wingS.request.reloadFrame(); // Better?: wingS.ajax.processRequestFailure(request); return; } // Get the document's root element var xmlRoot = xmlDoc.getElementsByTagName("updates")[0]; if (xmlRoot == null) { // Workaround to prevent IE from showing JS errors // if session has meanwhile timed out --> do reload! wingS.request.reloadFrame(); // Better?: wingS.ajax.processRequestFailure(request); return; } var exception = null; // Process each incremental update var updates = xmlRoot.getElementsByTagName("update"); if (updates.length > 0) { for (var i = 0; i < updates.length; i++) { // WebKIt browser parses under some circumstances the response from // the server into multiple CDATASections var cdatasections = new Array(); for (var child = 0; child < updates[i].childNodes.length; child++ ) { cdatasections.push(updates[i].childNodes[child].data); } try { // Dispatch update to the corresponding // handler function simply by evaluation window.eval(cdatasections.join()); } catch (e) { if (exception == null) exception = {message: e.message, detail: updates[i].firstChild.data}; } } } // Show exception. if (exception != null) { wingS.dialog.showExceptionDialog(exception); } // So far we applied all updates. If there are // no headers downloaded asynchronously at this // stage, we are finished with this request and // ready to process the next one from the queue. // Otherwise there will be a callback when all // header downloads and header callbacks ended. if (wingS.global.asyncHeaderQueue.length == 0) { // Reset activity indicators and active flag wingS.ajax.setActivityIndicatorsVisible(false); wingS.ajax.requestIsActive = false; // Send the next enqueued request wingS.ajax.dequeueNextRequest(); } }; /** * Enqueues the given request if another one is still in action. * @param {Function} send - the function to send the request with * @param {Array} args - the arguments needed by the send function * @return {boolean} true, if request was enqueued, false otherwise */ wingS.ajax.enqueueThisRequest = function(send, args) { if (wingS.ajax.requestIsActive) { wingS.ajax.requestQueue.push( {"send" : send, "args" : args} ); return true; } return false; }; /** * Grabs the next available request from the queue and invokes it. */ wingS.ajax.dequeueNextRequest = function() { if (wingS.ajax.requestQueue.length > 0) { var request = wingS.ajax.requestQueue.shift(); var args = request.args; request.send(args[0], args[1], args[2], args[3], args[4]); } //else { //wingS.ajax.connectionObject = //YAHOO.util.Connect.asyncRequest('GET', wingS.comet.cometPath, wingS.comet.callbackObject); //} else if (wingS.comet.newHangingGetAllowed) { wingS.comet.newHangingGetAllowed = false; wingS.comet.sendHangingGetRequest(); } }; /** * Makes the activity indicators either visible or invisible. * @param {boolean} visible - true to set indicators visible */ wingS.ajax.setActivityIndicatorsVisible = function(visible) { if (wingS.global.updateCursor.enabled) { wingS.cursor.setAjaxActivityIndicatorVisible(visible); // An alternative to the cursor might be something like // if (visible) document.body.style.cursor = "progress"; // else document.body.style.cursor = "default"; } /* var indicator = document.getElementById("ajaxActivityIndicator"); if (indicator != null) { if (visible) indicator.style.visibility = "visible"; else indicator.style.visibility = "hidden"; }*/ }; /** * Initializes the appearance of the activity cursor. *//* wingS.ajax.ActivityCursor = function() { this.dx = wingS.global.updateCursor.dx; this.dy = wingS.global.updateCursor.dy; this.div = document.createElement("div"); this.div.style.position = "absolute"; this.div.style.zIndex = "9999"; this.div.style.display = "none"; this.div.innerHTML = ""; document.body.insertBefore(this.div, document.body.firstChild); document.onmousemove = this.followMouse.bind(this); };*/ /** * Calculates the new position of the activity cursor. * @param {Object} event - the event object *//* wingS.ajax.ActivityCursor.prototype.followMouse = function(event) { event = wingS.event.getEvent(event); var target = wingS.event.getTarget(event); var posX = 0; var posY = 0; if (event.pageX || event.pageY) { posX = event.pageX; posY = event.pageY; } else if (event.clientX || event.clientY) { posX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; } if (target.nodeName == "OPTION" && !YAHOO.env.ua.ie) { posX += wingS.util.absLeft(target); posY += wingS.util.absTop(target.parentNode) + 18; } var newX = posX + this.dx; if (newX > 0 && newX < (YAHOO.util.Dom.getDocumentWidth() - wingS.global.updateCursor.width - 2)) { this.div.style.left = newX + "px"; } var newY = posY + this.dy; if (newY > 0 && newY < (YAHOO.util.Dom.getDocumentHeight() - wingS.global.updateCursor.height - 2)) { this.div.style.top = newY + "px"; } };*/ /** * Sets the activity cursor either visible or invisible. * @param {boolean} visible - true to set cursor visible *//* wingS.ajax.ActivityCursor.prototype.setVisible = function(visible) { if (visible) this.div.style.display = "block"; else this.div.style.display = "none"; };*/ /** * Prints some debug information about the given AJAX request. * @param {Object} request - the request object to debug */ wingS.ajax.updateDebugView = function(request) { var debugArea = document.getElementById("ajaxDebugView"); if (debugArea == null) { var debugHtmlCode = '
AJAX DEBUG VIEW: ' + 'HIDE
\n' + '\n'; debugArea = document.createElement("div"); debugArea.id = "ajaxDebugView"; debugArea.style.display = "none"; debugArea.innerHTML = debugHtmlCode; document.body.appendChild(debugArea); } var output = ""; if (request != null) { output += "Status: " + request.statusText + " ("; output += request.status + ") | TID: " + request.tId + "\n"; var response = ""; if (request.status > 0) { output += "\n" + request.getAllResponseHeaders + "\n"; response = request.responseText; if (response == null) { response = (new XMLSerializer()).serializeToString(request.responseXML); } output += response; } output += "\n\nPayload: " + response.length + " chars"; } else { output += "Currently there is no XML response available..." + "\nProbably no asynchronous request has been sent."; } debugArea.getElementsByTagName("TEXTAREA")[0].value = output; }; /** * Returns the current visibility state of the debug view. * @return {boolean} true if view is visible, false otherwise */ wingS.ajax.isDebugViewVisible = function() { var debugArea = document.getElementById("ajaxDebugView"); if (debugArea != null && debugArea.style.display != "none") { return true; } return false; }; /** * Makes the debug view either visible or invisible. Furthermore * the wingS.global.useAjaxDebugView flag ist set accordingly. * @param {boolean} visible - true to set debug view visible */ wingS.ajax.setDebugViewVisible = function(visible) { var debugArea = document.getElementById("ajaxDebugView"); if (debugArea != null) { if (visible) { wingS.global.useAjaxDebugView = true; debugArea.style.display = "block"; } else { wingS.global.useAjaxDebugView = false; debugArea.style.display = "none"; } } else { wingS.ajax.updateDebugView(); wingS.ajax.setDebugViewVisible(true); } }; /** * Toggles the visibility of the debug view. */ wingS.ajax.toggleDebugView = function() { if (wingS.ajax.isDebugViewVisible()) wingS.ajax.setDebugViewVisible(false); else wingS.ajax.setDebugViewVisible(true); }; /** * Toggles the visibility of the debug console. */ wingS.ajax.toggleDebugConsole = function() { if (wingS.ajax.isDebugViewVisible()) { var debugArea = document.getElementById("ajaxDebugView"); var debugToggle = debugArea.getElementsByTagName("A")[0]; var debugConsole = debugArea.getElementsByTagName("TEXTAREA")[0]; if (debugConsole.style.display != "none") { debugConsole.style.display = "none"; debugToggle.firstChild.data = "SHOW"; } else { debugConsole.style.display = "block"; debugToggle.firstChild.data = "HIDE"; } } }; /*************************************************************************************************** * WINGS.UPDATE -- contains: functions to process incremental updates **************************************************************************************************/ // Create module namespace wingS.namespace("update"); /** * Adds or removes a script header with the given parameters. * @param {Boolean} add - true, if the header should be added * @param {String} src - the source of the script header * @param {String} type - the type of the script header * @param {int} index - the desired position of the header */ wingS.update.headerScript = function(add, src, type, index) { var loadMethod = wingS.update.headerScript; var loadMethodArgs = new Array(add, src, type, index); // Enqueue header download in case another one isn't finished yet. if (wingS.global.enqueueThisHeader(loadMethod, loadMethodArgs)) return; if (src == null || type == null) return; var head = document.getElementsByTagName("HEAD")[0]; if (add) { wingS.global.startLoadingHeader(); var script = document.createElement("script"); script.src = src; script.type = type; if (index == null || index < 0 || index > head.childNodes.length) { head.appendChild(script); } else { head.insertBefore(script, wingS.update.headerNext(index)); } } else { var scripts = head.getElementsByTagName("SCRIPT"); for (var i = 0; i < scripts.length; i++) { if (scripts[i].getAttribute("src") == src && scripts[i].getAttribute("type") == type) { head.removeChild(scripts[i]); } } } }; /** * Adds or removes a link header with the given parameters. * @param {Boolean} add - true, if the header should be added * @param {String} href - the source of the link header * @param {String} type - the type of the link header * @param {String} rel - the relationship of the link header * @param {String} rev - the reverse relationship of the link * @param {String} target - the target of the link header * @param {int} index - the desired position of the header */ wingS.update.headerLink = function(add, href, type, rel, rev, target, index) { if (href == null || type == null) return; var head = document.getElementsByTagName("HEAD")[0]; if (add) { var link = document.createElement("link"); link.href = href; link.type = type; if (rel != null) link.rel = rel; if (rev != null) link.rev = rev; if (target != null) link.target = target; if (index == null || index < 0 || index > head.childNodes.length) { head.appendChild(link); } else { head.insertBefore(link, wingS.update.headerNext(index)); } } else { var links = head.getElementsByTagName("LINK"); for (var i = 0; i < links.length; i++) { if (links[i].getAttribute("href") == href && links[i].getAttribute("type") == type) { head.removeChild(links[i]); } } } }; /** * Returns the header next to the one with the given index. * @param {int} index - the desired position of the header */ wingS.update.headerNext = function(index) { var head = document.getElementsByTagName("HEAD")[0]; var position = 0; var header = null; for (var i = 0; i < head.childNodes.length; i++) { // We have to filter everything (eg. whitespace // or title nodes) except for element nodes with // a tag name of either script, link or meta. header = head.childNodes[i]; if (header.nodeType == 1 && ( header.nodeName == "SCRIPT" || header.nodeName == "LINK" || header.nodeName == "META")) { if (index == position) break; position++; } } // It's ok if "header" is still "null" // since head.insertBefore(XXX, null) // is equal to head.appendChild(XXX). return header; }; /** * Updates the current event epoch of this frame. * @param {String} epoch - the current event epoch */ wingS.update.epoch = function(epoch) { wingS.global.eventEpoch = epoch; }; /** * Gives the focus to the component with the given ID. * @param {String} id - the ID of the component to focus */ wingS.update.focus = function(id) { wingS.util.requestFocus(id); }; /** * Enables or disabled incremental updates for this frame. * @param {boolean} enabled - true, if updates are allowed */ wingS.update.updateEnabled = function(enabled) { wingS.global.updateEnabled = enabled; }; /** * Replaces the HTML code of the component with the given ID. * @param {String} componentId - the ID of the component * @param {String} html - the new HTML code of the component * @param {String} exception - the server exception (optional) */ wingS.update.component = function(componentId, html, exception) { // Exception handling if (exception != null) { var update = "ComponentUpdate for '" + componentId + "'"; wingS.update.alertException(exception, update); return; } // Search DOM for according component var component = document.getElementById(componentId); if (component == null) { throw {message: "Could not find component with id '" + componentId + "'"}; } // Handle layout workaround for IE (if necessary) var wrapping = component.getAttribute("wrapping"); if (wrapping != null && !isNaN(wrapping)) { for (var i = 0; i < parseInt(wrapping); i++) { component = component.parentNode; } } // Replace the actual JavaScript element wingS.update.element(component, html); wingS.sdnd.elementUpdated(componentId); }; /** * Replaces the HTML code of the given JavaScript element. * @param {String} element - the JavaScript element to replace * @param {String} html - the new HTML code of the component */ wingS.update.element = function(element, html) { if (typeof element.outerHTML != "undefined") { // Use outerHTML if available element.outerHTML = html; } else { var parent = element.parentNode; if (parent == null) return; var nrOfChildElements = 0; for (var i = 0; i < parent.childNodes.length; i++) { // We have to filter everything except element nodes // since browsers treat whitespace nodes differently if (parent.childNodes[i].nodeType == 1) { nrOfChildElements++; } } if (nrOfChildElements == 1) { // If there is only one child it must be our element parent.innerHTML = html; } else { var range; // If there is no other way we have to use proprietary methods if (document.createRange && (range = document.createRange()) && range.createContextualFragment) { range.selectNode(element); var newElement = range.createContextualFragment(html); parent.replaceChild(newElement, element); } } } }; /** * Adds or replaces the HTML code of the menu with the given ID. * @param {String} menuId - the ID of the menu to add or replace * @param {String} html - the new HTML code of the menu * @param {String} exception - the server exception (optional) */ wingS.update.componentMenu = function(menuId, html, exception) { // Exception handling if (exception != null) { var update = "ComponentUpdate for '" + menuId + "'"; wingS.update.alertException(exception, update); return; } if (document.getElementById(menuId) == null) { var menues = document.getElementById("wings_menues"); wingS.util.appendHTML(menues, html); } else { wingS.update.component(menuId, html); } }; /** * Updates the value of the component with the given ID. * @param {String} componentId - the ID of the component * @param {String} value - the new value of the component * @param {String} exception - the server exception (optional) */ wingS.update.value = function(componentId, value, exception) { // Exception handling if (exception != null) { var update = "TextUpdate for '" + componentId + "'"; wingS.update.alertException(exception, update); return; } var component = document.getElementById(componentId); if (component.nodeName == "NOBR") component.innerHTML = value; else component.value = value; }; /** * Updates the text of the component with the given ID. * @param {String} componentId - the ID of the component * @param {String} text - the new text of the component * @param {String} exception - the server exception (optional) */ wingS.update.text = function(componentId, text, exception) { // Exception handling if (exception != null) { var update = "TextUpdate for '" + componentId + "'"; wingS.update.alertException(exception, update); return; } var component = document.getElementById(componentId); var textNode = component.getElementsByTagName("SPAN")[0]; textNode.parentNode.innerHTML = text; }; /** * Updates the icon of the component with the given ID. * @param {String} componentId - the ID of the component * @param {String} icon - the new icon of the component * @param {String} exception - the server exception (optional) */ wingS.update.icon = function(componentId, icon, exception) { // Exception handling if (exception != null) { var update = "IconUpdate for '" + componentId + "'"; wingS.update.alertException(exception, update); return; } var component = document.getElementById(componentId); var iconNode = component.getElementsByTagName("IMG")[0]; iconNode.parentNode.innerHTML = icon; }; /** * Updates the encoding of the form with the given ID. * @param {String} formId - the ID of the form to update * @param {int} encoding - the encoding to be set */ wingS.update.encoding = function(formId, encoding) { var form = document.getElementById(formId); form.enctype = encoding; }; /** * Updates the method of the form with the given ID. * @param {String} formId - the ID of the form to update * @param {int} method - the method to be set */ wingS.update.method = function(formId, method) { var form = document.getElementById(formId); form.method = method; }; /** * Updates the class of the component with the given ID. * @param {String} componentId - the ID of the component * @param {String} value - the new class of the component * @param {String} exception - the server exception (optional) */ wingS.update.className = function(componentId, className, exception) { // Exception handling if (exception != null) { var update = "ClassNameUpdate for '" + componentId + "'"; wingS.update.alertException(exception, update); return; } var component = document.getElementById(componentId); if (component.nodeName == "NOBR") component.innerHTML = className; else component.className = className; }; /** * Adds a window to the window stack of a SRootContainer. * @param {String} componentId - the ID of the window stack * @param {String} html - the new HTML code of the window */ wingS.update.addWindow = function(componentId, skeleton) { // Search DOM for according component var component = document.getElementById(componentId); if (component == null) { throw {message: "Could not find component with id '" + componentId + "'"}; } // Create wrapping tr and td for container table. var tr = component.tBodies[0].insertRow(-1); var td = document.createElement("td"); tr.appendChild(td); wingS.util.appendHTML(td, skeleton); }; /** * Removes a window of the window stack. * @param {String} componentId - the ID of the window */ wingS.update.removeWindow = function(componentId) { // Search DOM for according component var component = document.getElementById(componentId); if (component == null) { throw {message: "Could not find component with id '" + componentId + "'"}; } var tr = component.parentNode.parentNode.parentNode; var table = tr.parentNode; // Hide dialog mask if available. var dialog = window["dialog_" + componentId]; if (dialog != null) { dialog.hideMask(); dialog.destroy(); window["dialog_" + componentId] = null; // clear global variable } table.removeChild(tr); }; /** * This update scrolls the table with the given ID. * @param {String} tableId - the ID of the table to scroll * @param {int} oldmin - the old minimum index * @param {int} min - the new minumum index * @param {int} max - the new maximum index * @param {Array} tabledata - the new data to show */ wingS.update.tableScroll = function(tableId, oldmin, min, max, tabledata) { var table = document.getElementById(tableId); for (rownumber in tabledata) { var rowindex = rownumber - oldmin; var row = table.rows[rowindex]; if (row == null || row == undefined) { row = table.insertRow(rowindex); } var rowdata = tabledata[rownumber]; if (rowdata == null) { table.deleteRow(rowindex); } else { // creating a dom node for our new cell var celldiv = document.createElement("div"); for (cellnumber in rowdata) { var cell = row.cells[cellnumber]; // convert data into dom node and replace old child celldiv.innerHTML = rowdata[cellnumber]; var cellnode = celldiv.firstChild(); row.replaceChild(cell, cellnode); var cell = row.cells[cellnumber]; } } } }; /** * An update which replaces the whole data of the table with the given ID. * @param {String} tableId - the ID of the table which has to be updated * @param {Array} data - the new cell data to show */ wingS.update.tableData = function(tableId, rowOffset, columnOffset, data, exception) { var table = document.getElementById(tableId); var rows = table.rows; var i=0; for (var r = rowOffset; r < rows.length; r++) { var tr = rows[r]; var cells = tr.cells; for (var c = columnOffset; c < cells.length; c++) { cells[c].innerHTML = data[i++]; } } }; /** * An update which replaces the cell content of the table with the given ID. * @param {String} tableId - the ID of the table which has to be updated * @param {int} r - the row index of the cell to be replaced * @param {int} c - the column index of the cell to be replaced * @param {String} editing - the editing attribute for the cell * @param {String} html - the html code for the cell */ wingS.update.tableCell = function(tableId, r, c, editing, html) { var table = document.getElementById(tableId); var row = table.rows[r]; var col = row.cells[c]; col.innerHTML = html; col.setAttribute("editing", editing); if (editing) col.className = "cell"; else col.className = "cell clickable"; }; /** * Updates the selection of the combobox with the given ID. * @param {String} comboBoxId - the ID of the combobox to update * @param {int} selectedIndex - the index of the entry to select */ wingS.update.selectionComboBox = function(comboBoxId, selectedIndex) { var comboBox = document.getElementById(comboBoxId); comboBox.selectedIndex = selectedIndex; }; /** * Updates the selection of the list with the given ID. * @param {String} listId - the ID of the list to update * @param {Array} deselectedIndices - the indices to deselect * @param {Array} selectedIndices - the indices to select */ wingS.update.selectionList = function(listId, deselectedIndices, selectedIndices) { var list = document.getElementById(listId); if (list.options) { for (var i = 0; i < deselectedIndices.length; i++) { list.options[deselectedIndices[i]].selected = false; } for (var i = 0; i < selectedIndices.length; i++) { list.options[selectedIndices[i]].selected = true; } } else { var listItems = list.getElementsByTagName("LI"); for (var i = 0; i < deselectedIndices.length; i++) { YAHOO.util.Dom.removeClass(listItems[deselectedIndices[i]], "selected"); } for (var i = 0; i < selectedIndices.length; i++) { YAHOO.util.Dom.addClass(listItems[selectedIndices[i]], "selected"); } } }; /** * Updates the selection of the tree with the given ID. * @param {String} treeId - the ID of the tree to update * @param {Array} deselectedRows - the rows to deselect * @param {Array} selectedRows - the rows to select */ wingS.update.selectionTree = function(treeId, deselectedRows, selectedRows) { var tree = document.getElementById(treeId); var rows = wingS.util.getElementsByAttribute(tree, "td", "row"); for (var i = 0; i < deselectedRows.length; i++) { YAHOO.util.Dom.replaceClass(rows[deselectedRows[i]], "selected", "norm"); } for (var i = 0; i < selectedRows.length; i++) { YAHOO.util.Dom.replaceClass(rows[selectedRows[i]], "norm", "selected"); } }; /** * Updates the selection of the table with the given ID. * @param {String} tableId - the ID of the table to update * @param {int} indexOffset - the index offset for each row * @param {Array} deselectedIndices - the rows to deselect * @param {Array} selectedIndices - the rows to select * @param {Array} deselectedBodies - the deselected cell bodies * @param {Array} selectedBodies - the selected cell bodies * @param {String} exception - the server exception (optional) */ wingS.update.selectionTable = function(tableId, indexOffset, deselectedIndices, selectedIndices, deselectedBodies, selectedBodies, exception) { // Exception handling if (exception != null) { var update = "SelectionUpdate for '" + tableId + "'"; wingS.update.alertException(exception, update); return; } var table = document.getElementById(tableId); if (table.tagName == "FIELDSET") { // Workaround for tables with titled border: Necessary table = table.childNodes[1]; // as long as the fieldset id is equal to the table id. } var rows = table.rows; for (var i = 0; i < deselectedIndices.length; i++) { var tr = rows[deselectedIndices[i] + indexOffset]; YAHOO.util.Dom.removeClass(tr, "selected"); if (deselectedBodies != null) { tr.cells[0].innerHTML = deselectedBodies[i]; } } for (var i = 0; i < selectedIndices.length; i++) { var tr = rows[selectedIndices[i] + indexOffset]; YAHOO.util.Dom.addClass(tr, "selected"); if (selectedBodies != null) { tr.cells[0].innerHTML = selectedBodies[i]; } } }; /** * Alerts an error message containing the exception name. * @param {String} exception - the exception name to alert * @param {String} details - details about the failed update */ wingS.update.alertException = function(exception, details) { var e = { message: "Couldn't apply update due to an exception on server side!", detail: "Exception: " + exception + "\n" + "Failed Update: " + details + "\n\n" + "Please examine your server's log file for further details..." } wingS.dialog.showExceptionDialog(e); }; /** * Updates a component's visibility * @param componentId (HTML)-id of the component * @param display New Setting of the element.style.display parameter * @param visibility New Setting of the element.style.visibility parameter */ wingS.update.visibility = function(componentId, display, visibility) { var elt = document.getElementById(componentId); elt.style.display = display; elt.style.visibility = visibility; }; /** * Runs the script in the given parameter. * @param scriptToEval Script to run */ wingS.update.runScript = function(scriptToEval) { eval(scriptToEval); }; wingS.update.comet = function(task) { if (task == "connect") { wingS.comet.connect(); } else if (task == "disconnect") { wingS.comet.disconnect(); } else if (task == "switchToHanging") { wingS.comet.switchToHanging(); } }; /** * Updates the current default button name of this frame. * @param {String} defaultButtonName - the current default button name */ wingS.update.defaultButtonName = function(defaultButtonName) { wingS.global.defaultButtonName = defaultButtonName; }; /*************************************************************************************************** * WINGS.LAYOUT -- contains: functions used to layout components **************************************************************************************************/ // Create module namespace wingS.namespace("layout"); wingS.layout.fill = function(tableId) { var table = document.getElementById(tableId); if (table == null || table.style.height == table.getAttribute("layoutHeight")) return; var consumedHeight = 0; var rows = table.rows; if (rows != undefined) { for (var i = 0; i < rows.length; i++) { var row = rows[i]; var yweight = row.getAttribute("yweight"); if (!yweight) consumedHeight += row.offsetHeight; } } else { return; // there may be a need for component specific code here } table.style.height = table.getAttribute("layoutHeight"); var diff = table.clientHeight - consumedHeight; if (diff > 0) { if(rows != undefined) { for (var i = 0; i < rows.length; i++) { var row = rows[i]; var yweight = row.getAttribute("yweight"); if (yweight) { var oversize = row.getAttribute("oversize"); if (oversize == null) oversize = 0; row.height = Math.max(Math.floor((diff * yweight) / 100) - oversize, oversize); } } } else { // there may be a need for component specific code here } } }; wingS.layout.fix = function(tableId) { var table = document.getElementById(tableId); if (table == null) return; var consumedHeight = 0; var rows = table.rows; for (var i = 0; i < rows.length; i++) { var row = rows[i]; consumedHeight += row.offsetHeight; } table.style.height = consumedHeight + "px"; }; wingS.layout.scrollPane = function(tableId) { var table = document.getElementById(tableId); if (table == null) return; var div = table.getElementsByTagName("DIV")[0]; if (document.defaultView) { div.style.height = document.defaultView.getComputedStyle(table, null).getPropertyValue("height"); div.style.display = "block"; } else { var td = wingS.util.getParentByTagName(div, "TD"); div.style.height = td.clientHeight + "px"; div.style.width = td.clientWidth + "px"; div.style.position = "absolute"; div.style.display = "block"; //div.style.overflow = "auto"; } // The following two lines are a hack needed to make IE work properly. The browser displays // scrollpanes in dialogs only after the mouse hovers the dialog. By playing with the display CSS attribute // we can work around this problem. div.style.display = 'none'; setTimeout('wingS.layout.updateScrollPaneDiv("' + tableId + '")', 1); }; // This meethod implements a hack needed to make IE work properly. The browser displays // scrollpanes in dialogs only after the mouse hovers the dialog. By playing with the display CSS attribute // we can work around this problem. wingS.layout.updateScrollPaneDiv = function(tableId) { var table = document.getElementById(tableId); var div = table.getElementsByTagName("DIV")[0]; div.style.display = "block"; }; /*************************************************************************************************** * WINGS.KEYBOARD -- contains: keyboard handling functionality **************************************************************************************************/ // Create module namespace wingS.namespace("keyboard"); wingS.keyboard.keyStrokes = null; wingS.keyboard.handler = function(event) { var element; if (window.event) { event = window.event; element = event.srcElement; } else element = event.target; if (wingS.keyboard.handler.match(event, element)) { if (window.event && !event.shiftKey && !event.ctrlKey) event.keyCode = 16; return false; } return true; }; wingS.keyboard.uphandler = function(event) { if (window.event) { event = window.event; } var shiftKey = event.shiftKey; var ctrlKey = event.ctrlKey; if(wingS.sdnd.isDragging()) { // don't process keyboard operations while dragging - forward them to sdnd.js wingS.sdnd.keyChange(ctrlKey, shiftKey); return false; } return false; } wingS.keyboard.handler.match = function(event, element) { var keyCode = event.keyCode; var shiftKey = event.shiftKey; var ctrlKey = event.ctrlKey; var altKey = event.altKey; var keyStrokes = wingS.keyboard.keyStrokes; if(wingS.sdnd.isDragging()) { // don't process keyboard operations while dragging - forward them to sdnd.js wingS.sdnd.keyChange(ctrlKey, shiftKey); return false; } if (!keyStrokes) return false; var wu = wingS.util; for (var index = 0, len = keyStrokes.length; index < len; ++index) { var keyStroke = keyStrokes[index]; if (keyStroke.keyCode == keyCode && keyStroke.shiftKey == shiftKey && keyStroke.ctrlKey == ctrlKey && keyStroke.altKey == altKey) { if (!keyStroke.focussed || wu.getParentByAttributeAndValue(element, "id", keyStroke.component) != null) { wingS.request.sendEvent(event, true, true, keyStroke.component + '_keystroke', keyStroke.command); if ("console" in window && window.console) window.console.log("match true"); return true; } } } return false; } /** * @param {String} component - will receive the event * @param {Boolean} focussed - check wether event has been fired in focus of component * @param {String} command - the value of the event * @param {Integer} keyCode - the keyCode of the key stroke * @param {Boolean} shiftKey - the shift modifier of the key stroke * @param {Boolean} ctrlKey - the ctrl modifier of the key stroke * @param {Boolean} altKey - the alt modifier of the key stroke */ wingS.keyboard.KeyStroke = function(component, focussed, command, keyCode, shiftKey, ctrlKey, altKey) { this.component = component; this.focussed = focussed; this.command = command; this.keyCode = keyCode; this.shiftKey = shiftKey; this.ctrlKey = ctrlKey; this.altKey = altKey; } document.onkeydown = wingS.keyboard.handler; document.onkeyup = wingS.keyboard.uphandler; /*************************************************************************************************** * WINGS.DND -- contains: drag 'n' drop functionality **************************************************************************************************/ // Create module namespace wingS.namespace("dnd"); /** * @class a YAHOO.util.DDFramed implementation. During the drag over event, the * dragged element is inserted before the dragged-over element. * * @extends YAHOO.util.DDProxy * @constructor * @param {String} id the id of the linked element * @param {String} sGroup the group of related DragDrop objects */ wingS.dnd.DD = function(id, sGroup, config) { this.wingSInit(id, sGroup, config); }; YAHOO.extend(wingS.dnd.DD, YAHOO.util.DDProxy); wingS.dnd.DD.prototype.wingSInit = function(id, sGroup, config) { if (!id) { return; } this.init(id, sGroup, config); this.initFrame(); this.setInitPosition(); }; wingS.dnd.DD.TYPE = "wingS.DD"; wingS.dnd.DD.prototype.onDrag = function(e) { }; wingS.dnd.DD.prototype.onDragOver = function(e) { }; wingS.dnd.DD.prototype.onDragDrop = function(event, id) { // get the drag and drop object that was targeted var target; if ("string" == typeof id) { target = YAHOO.util.DDM.getDDById(id); } else { target = YAHOO.util.DDM.getBestMatch(id); } this.resetConstraints(); target.resetConstraints(); wingS.request.sendEvent(event, true, true, wingS.dnd.manager, this.id + ':' + id); }; wingS.dnd.DD.prototype.endDrag = function(e) { }; /*************************************************************************************************** * WINGS.SDND -- contains: functions related to new drag-and-drop support **************************************************************************************************/ (function() { var wingS = window.wingS; // Create module namespace wingS.namespace("sdnd"); var lib = wingS.sdnd; /** * Helper variables */ var dragSources = { }; var dropTargets = { }; var manager = null; var dragCodeRegistry = { }; var dropCodeRegistry = { }; // From DnDConstants, need to be changed if the java constants change var ACTION_NONE = 0; var ACTION_COPY = 1; var ACTION_MOVE = 2; var ACTION_LINK = 0x40000000; // draggedElement == null when no (possible) dragging operation is in progress, if != null, // it contains the currently dragged element and gets filled right after the mouosedown on a draggable element var draggedElementId = null // isDragging is true after the dragging gesture was detected and while the dragging is in progress, false after drop var isDragging = false; var lastTarget = null; var pixelDelta = 0; /** * Helper functions - called within this context but aren't exported outside of it */ lib.error = function(errorText) { alert(errorText); } function error(text) { lib.error(text); } /** * Wrapper for YAHOO.util.Event.addListener * @param element * @param event * @param func */ lib.addEvent = function(element, event, func) { if(!YAHOO.util.Event.addListener(element, event, func)) error("addListener for " + element + " event: " + event + " failed."); } function addEvent(element, event, func) { lib.addEvent(element, event, func); } /** * Wrapper for YAHOO.util.Event.removeListener * @param element * @param event * @param func */ lib.removeEvent = function(element, event, func) { YAHOO.util.Event.removeListener(element, event); // sometimes removing events bugs // if(!YAHOO.util.Event.removeListener(element, event, func)) // error("removeListener for " + element + " event: " + event + " failed."); } function removeEvent(element, event, func) { lib.removeEvent(element, event, func); } /** * Gets the first parent of element that has a handler called handler and is in between element and parent */ lib.getFirstParentWithHandlerBeforeParent = function(element, handler, parent) { if(element == undefined || element == null || element == parent) return null; if(typeof(element[handler]) == "function" || typeof(element[handler]) == "string") return element; if(element.parentNode && element.parentNode != null) return lib.getFirstParentWithHandlerBeforeParent(element.parentNode, handler, parent); return null; } function getTarget(event) { return wingS.event.getTarget(event); } function log(text) { if("console" in window && console.log) { console.log(text); } } function getEvent(event) { // make sure we use event if possible and use window.event only if event isn't available if(event != undefined && event != null) return event; return wingS.event.getEvent(event); } function addDragPrepareEvents() { addEvent(document.body, 'mousemove', lib.drag); addEvent(document.body, 'mouseup', lib.drop); } function removeDragPrepareEvents() { removeEvent(document.body, 'mouseup', lib.drop); removeEvent(document.body, 'mousemove', lib.drag); } function addDragStartEvents() { for(var elementId in dropTargets) { var elt = document.getElementById(elementId); if(elt == null) // if the element isn't on the page at the moment continue; if(typeof(dropTargets[elementId].dropCode.install) == "function") { dropTargets[elementId].dropCode.install(elt); } else { dropCodeRegistry['default'].install(elt); } } } var checkIfStayedOnElementTimer = null; var StayOnElement = null; function checkIfStayedOnElement() { if(StayOnElement == lastTarget) { var element = getFirstParentWithHandler(StayOnElement, dropTargets) if(typeof(dropTargets[element.id].dropCode.stayedOnElement) == "function") { var fakeEvent = { }; fakeEvent.ctrlKey = oldCtrlKeyStatus; // set the new keystatus in the 'old' status fakeEvent.shiftKey = oldShiftKeyStatus; fakeEvent.target = StayOnElement; dropTargets[element.id].dropCode.stayedOnElement(fakeEvent); var options = dropTargets[element.id].options; if(options != undefined && options != null) { if(typeof(options.stayOnElementTimeoutInterval) == "number") setTimeout(checkIfStayedOnElement, options.stayOnElementTimeoutInterval); } } } } function removeDragStartEvents() { for(var elementId in dropTargets) { var elt = document.getElementById(elementId); if(elt == null) return; if(typeof(dropTargets[elementId].dropCode.uninstall) == "function") { dropTargets[elementId].dropCode.uninstall(elt); } else { dropCodeRegistry['default'].uninstall(elt); } } } var isHoveringDropTarget = false; var hoverParent = null; var checkIfLeftParent = false; /** * Called in drag-operations, when a element is entered - will automatically check if it was a subelement * @param event */ lib.dragOverEnter = function(event) { if(!isDragging) return; event = getEvent(event); lastTarget = getTarget(event); var element = getFirstParentWithHandler(lastTarget, dropTargets); if(element == null || element.id == null || typeof(dropTargets[element.id]) != "object") return; isHoveringDropTarget = true; if(checkIfStayedOnElementTimer != null) clearTimeout(checkIfStayedOnElementTimer) var options = dropTargets[element.id].options; if(options != undefined && options != null) { if(typeof(options.stayOnElementTimeout) == "number") checkIfStayedOnElementTimer = setTimeout(checkIfStayedOnElement, options.stayOnElementTimeout); } StayOnElement = lastTarget; if(typeof(dropTargets[element.id].dropCode.enter) == "function") { // if a custom dragenter function exists if(dropTargets[element.id].dropCode.enter(event)) { // call it, and send event if it returns true lib.sendDragEvent(event, "de"); } return; } if(element != hoverParent) { hoverParent = element; lib.sendDragEvent(event, "de"); } } /** * Called in drag-operations, when a element is left - will automatically check if it was a subelement * @param event */ lib.dragOverLeave = function(event) { if(!isDragging) return; event = getEvent(event); var target = getTarget(event); clearTimeout(checkIfStayedOnElementTimer); var element = getFirstParentWithHandler(target, dropTargets); if(element == null || element.id == null || typeof(dropTargets[element.id]) != "object") return; isHoveringDropTarget = false; if(typeof(dropTargets[element.id].dropCode.leave) == "function") { // if a custom dragenter function exists if(dropTargets[element.id].dropCode.leave(event)) { // call it, and send event if it returns true lib.sendDragEvent(event, "dl"); } return; } checkIfLeftParent = true; } function checkIfSendLeaveEvent(currentEvent) { var element = getFirstParentWithHandler(getTarget(currentEvent), dropTargets); if(checkIfLeftParent && element != hoverParent) { var fakeEvent = { }; fakeEvent.ctrlKey = oldCtrlKeyStatus; // set the new keystatus in the 'old' status fakeEvent.shiftKey = oldShiftKeyStatus; fakeEvent.target = lastTarget; lib.sendDragEvent(fakeEvent, "dl"); hoverParent = null; } checkIfLeftParent = false; } /** * Returns the first parent-element that has a entry in handler * @param element * @param handler */ function getFirstParentWithHandlerRecursively(element, handler) { if(element.id != undefined && typeof(handler[element.id]) == "object") return element; else if(element.parentNode != null) { return getFirstParentWithHandlerRecursively(element.parentNode, handler); } else { return null; } } lib.getFirstParentWithHandler = function(element, handler) { return getFirstParentWithHandlerRecursively(element, handler); } function getFirstParentWithHandler(element, handler) { return lib.getFirstParentWithHandler(element, handler); } var backupHandler = null; /** * Disables all selection in Internet Explorer */ function disableSelection() { if(navigator.userAgent.indexOf("MSIE") == -1) return; backupHandler = document.onselectstart; document.onselectstart = function() { return false; } } /** * Reenables selections in Internet Explorer */ function enableSelection() { if(navigator.userAgent.indexOf("MSIE") == -1) return; document.onselectstart = backupHandler; } var backupStartEvent = null; /** * Called upon any drag-operation (mousedown, mousemove) * @param event */ lib.drag = function(event) { event = getEvent(event); var target = getTarget(event); if(navigator.userAgent.indexOf("MSIE") != -1) { // only permit the left mouse button if(event.button != 1) // ie return; } else { if(event.button != 0) { // firefox/w3c return; } } if(draggedElementId == null) { var element = getFirstParentWithHandler(target, dragSources); draggedElementId = element.id; backupStartEvent = { }; // backup the event at the time of the first click (because one pixel further away // the element under the mouse could be a different one) for(var prop in event) { if(typeof(event[prop]) != "function") { backupStartEvent[prop] = event[prop]; } } lastTarget = target; hoverParent = element; if(typeof(dragSources[element.id].dragCode.dragPrepare) == "function") { if(dragSources[element.id].dragCode.dragPrepare(event)) { addDragPrepareEvents(); } else { // don't start drag and drop draggedElementId = null; } } else { if(dragCodeRegistry['default'].dragPrepare(event)) { addDragPrepareEvents(); } else { // don't start drag and drop draggedElementId = null; } } isDragging = false; } else { if(!isDragging) { if(pixelDelta < 5) { if(pixelDelta == 0) { // disable selection (in internet explorer) when a drag may start disableSelection(); } pixelDelta++; YAHOO.util.Event.stopEvent(event); return false; } pixelDelta = 0; isDragging = true; // don't start the drag operation, if the requested action isn't allowed by the source element if(isActionAllowedBySource(event) && dragSources[draggedElementId].dragCode.dragStart(backupStartEvent, event)) { addDragStartEvents(); } else { // abort drag operation removeDragPrepareEvents(); isDragging = false; draggedElementId = null; } } else { if(typeof(dragSources[draggedElementId].dragCode.whileDragging) == "function") { dragSources[draggedElementId].dragCode.whileDragging(event); } checkIfSendLeaveEvent(event); } } } /** * Called upon a drop - determines if a drop is possible, on which element it was, calls further drop handlers inside the dropcode or aborts the transfer * @param event */ lib.drop = function(event) { hoverParent = null; clearTimeout(checkIfStayedOnElementTimer); event = getEvent(event); var element = getTarget(event); element = getFirstParentWithHandler(element, dropTargets); enableSelection(); if(!isDragging) { // drop called before dragging started if(typeof(dragSources[draggedElementId].dragCode.abort) == "function") { if(dragSources[draggedElementId].dragCode.abort(document.getElementById(draggedElementId), event)) { removeDragPrepareEvents(); draggedElementId = null; isDragging = false; } } else { if(dragCodeRegistry['default'].abort(document.getElementById(draggedElementId), event)) { removeDragPrepareEvents(); draggedElementId = null; isDragging = false; } } return; } isDragging = false; if(element == null || dropTargets[element.id] == undefined) { lib.sendDragEvent(event, "ab", null); removeDragPrepareEvents(); removeDragStartEvents(); draggedElementId = null; return; } if(dropTargets[element.id].dropCode.drop(event)) { removeDragPrepareEvents(); removeDragStartEvents(); } draggedElementId = null; } /** * Gets the requested action from the given keys in event * @param event */ function getActionFromEvent(event) { if(event.shiftKey == false && event.ctrlKey == false) { if((dragSources[draggedElementId].sourceActions & ACTION_MOVE) == ACTION_MOVE) return ACTION_MOVE; if((dragSources[draggedElementId].sourceActions & ACTION_COPY) == ACTION_COPY) return ACTION_COPY; if((dragSources[draggedElementId].sourceActions & ACTION_LINK) == ACTION_LINK) return ACTION_COPY; return ACTION_NONE; } if(event.shiftKey == true && event.ctrlKey == false) return ACTION_MOVE; if(event.shiftKey == false && event.ctrlKey == true) return ACTION_COPY; if(event.shiftKey == true && event.ctrlKey == true) return ACTION_LINK; return ACTION_NONE; } /** * Determines if the requested action by the keys in event is allowed by the drag source * @param event */ function isActionAllowedBySource(event) { var action = getActionFromEvent(event); return (dragSources[draggedElementId].sourceActions & action) == action; } /** * called in the case, that keypresses occured - needs to check if the new (requested) action is allowed * @param ctrlKey * @param shiftKey */ function ReviewDraggingOperation(ctrlKey, shiftKey) { if(!isHoveringDropTarget) // we don't need to do anything if we aren't on a droptarget return; if(ctrlKey == undefined || shiftKey == undefined) error("ReviewDraggingOperation - undefined keys"); var fakeEvent = { }; // build a fake-event (we can't change the last event object 'cause the attributes are sometimes get-only) fakeEvent.ctrlKey = ctrlKey; // set the new keystatus in the 'old' status fakeEvent.shiftKey = shiftKey; fakeEvent.target = lastTarget; // simulate dragenter event (will send target + requested action, will answer if action is allowed or not) hoverParent = null; lib.dragOverEnter(fakeEvent) } /** * Public (exported) functions, to be used with wingS.sdnd.functionname */ /** * Adds element as a drag source, dragCode is either null, or a customized drag-and-drop Handler * @param element Element to be registered as a drag source * @param sourceActions Source (Drag) Actions supported by the drag source * @param dragCode Either a string, pointing to the dragcode-handler in the dragcoderegistry or a dragcode-handler */ lib.addDragSource = function(elementId, sourceActions, dragCode) { if(typeof(elementId) == 'string') { var element = document.getElementById(elementId); } dragSources[elementId] = { }; if(typeof(dragCode) == 'string') { if(typeof(dragCodeRegistry[dragCode]) != "object") { error("no dragcode registered for '" + dragCode +"'"); return; } dragSources[elementId].dragCode = dragCodeRegistry[dragCode]; } else if(typeof(dragCode) == 'object') { dragSources[elementId].dragCode = dragCode; } else { error("invalid dragCode"); return; } if(typeof(sourceActions) == 'number') { dragSources[elementId].sourceActions = sourceActions; } else { error("no actions for addDragSource given"); return; } if(element == null) // element isn't on page (at the moment) return; if(typeof(dragSources[element.id].dragCode.install) == "function") { dragSources[elementId].dragCode.install(element); } else { dragCodeRegistry['default'].install(element); } }; /** * Removes element as a drag source * @param element */ lib.removeDragSource = function(element) { if(typeof(element) == "string") element = document.getElementById(element); if(typeof(dragSources[element.id].dragCode.uninstall) == "function") { dragSources[element.id].dragCode.uninstall(element); dragSources[element.id] = null; } else { dragCodeRegistry['default'].uninstall(element); } }; /** * Adds element as a drop target * @param element Element to be registered * @param dropCode Dropcode to use * @param options Array of options for the element */ lib.addDropTarget = function(elementId, dropCode, options) { if(typeof(elementId) == 'string') { var element = document.getElementById(elementId); } dropTargets[elementId] = { }; if(typeof(dropCode) == 'string') { dropTargets[elementId].dropCode = dropCodeRegistry[dropCode]; dropTargets[elementId].options = options; } else if(typeof(dragCode) == 'object') { dropTargets[elementId].dropCode = dropCode; dropTargets[elementId].options = options; } else { error("invalid dropCode"); } }; /** * Removes a drop target * @param element */ lib.removeDropTarget = function(element) { if(typeof(element) == "string") { dropTargets[element] = null; } else { // assume it's a object dropTargets[element.id] = null; } }; /** * Sets the SDnD Manager isntance * @param newDnDManager */ lib.setManager = function(newDnDManager) { manager = newDnDManager; }; /** * Returns the Classname of the Drag-and-Drop Manager, to be used for ajax requests */ lib.getManager = function() { return manager; }; /** * Returns if a drag operation is in progress */ lib.isDragging = function() { return isDragging; }; var oldShiftKeyStatus = false; var oldCtrlKeyStatus = false; /** * Method to receive keypresses while dragging * @param ctrlKey * @param shiftKey */ lib.keyChange = function(ctrlKey, shiftKey) { if(oldCtrlKeyStatus != ctrlKey || oldShiftKeyStatus != shiftKey ) { // TODO: maybe wait a little to check if another key was pressed/released to prevent server hammering ReviewDraggingOperation(ctrlKey, shiftKey); } oldCtrlKeyStatus = ctrlKey; oldShiftKeyStatus = shiftKey; }; /** * Sends a drag event to the SDragAndDropManager * @param event * @param dragEvent * @param additionalInformation */ lib.sendDragEvent = function(event, dragEvent, additionalInformation) { // format: :sourceid:destinationid:eventdata:requestedaction:additional (depends on type of element/component) // eventdescriptor: ds = dragstart, de = dragenter, dl = dragleave, dr = drop // on ds source and destination will be equal var target = getTarget(event); if(dragEvent == "ds") { target = getFirstParentWithHandler(target, dragSources); } else if(dragEvent == "de") { target = getFirstParentWithHandler(target, dropTargets); } else if(dragEvent == "dl") { target = getFirstParentWithHandler(target, dropTargets); } else if(dragEvent == "dr") { target = getFirstParentWithHandler(target, dropTargets); } else if(dragEvent == "st") { target = getFirstParentWithHandler(target, dropTargets); } if(additionalInformation == undefined || additionalInformation == null) { additionalInformation = ""; } else { additionalInformation = ";" + additionalInformation; } var targetstr = "" if(target != null) { targetstr = target.id; } var str = dragEvent + ";" + draggedElementId + ";" + targetstr + ";" + getActionFromEvent(event) + additionalInformation; wingS.request.sendEvent(event, true, true, lib.getManager(), str); }; /** * Registers Code with type codetype with key and code * To delete code, use null as code-argument * @param codetype Either 'drag' or 'drop' * @param key Key * @param code */ lib.registerCode = function(codetype, key, code) { if(codetype == "drag") { dragCodeRegistry[key] = code; } else if(codetype == "drop") { dropCodeRegistry[key] = code; } }; /** * Returns Code from the registry specified with codetype the code associated with key * @param codetype either 'drag' or 'drop' * @param key Key */ lib.getCode = function(codetype, key) { if(codetype == "drag") { return dragCodeRegistry[key]; } else if(codetype == "drop") { return dropCodeRegistry[key]; } } /** * Returns a array of droptargets - the eleemntid is the key */ lib.getDropTargets = function() { return dropTargets; }; /** * Returns a array of dragsources, the elementid is the key */ lib.getDragSources = function() { return dragSources; }; /** * Reapplys all Drag and Drop handlers recursively to element and all of it's childs * @param element */ function reapplyDragAndDropOperationsRecursively(element) { if(element != null && typeof(element) == "object" && element.id != null && typeof(element.id) == "string" && dragSources[element.id] != null && typeof(dragSources[element.id]) == "object") { if(typeof(dragSources[element.id].dragCode.install) == "function") { dragSources[element.id].dragCode.install(element); } else { dragCodeRegistry['default'].install(element); } } if(element != null && typeof(element) == "object" && element.id != null && typeof(element.id) == "string" && dropTargets[element.id] != null && typeof(dropTargets[element.id]) == "object") { if(typeof(dropTargets[element.id].dropCode.install) == "function") { dropTargets[element.id].dropCode.install(element); } else { dropCodeRegistry['default'].install(element); } } if(element == null || element.childNodes == null || typeof(element.childNodes) == 'undefined') return; for(var i=0; i tag lengthOfRange += 1; } }*/ // append dragged content return target.value.length; } // IE-Handling code if(target.tagName == "INPUT") { if(!target.createTextRange) { // if there is no .rangeOffset available, but the browser isn't ie (most likely a click into the scrollfield, decide on server what position to use) return -1; } var range = target.createTextRange(); range.moveToPoint(event.clientX, event.clientY); var pos = Math.abs(range.moveStart('character', -1)); // buggy in ie - god knows why return pos; } else if(target.tagName == "TEXTAREA") { if(!target.createTextRange) { // if there is no .rangeOffset available, but the browser isn't ie (most likely a click into the scrollfield, decide on server what position to use) return -1; } var range = target.createTextRange(); range.moveToPoint(event.x, event.y); var pos = Math.abs(range.moveEnd('character', -1000000)); return pos; } return -1; } function isSelectionEvent(event) { var target = getTarget(event); // returns true if you want to drag 1 selected char (not fixable!) if(target.tagName == "INPUT" || target.tagName == "TEXTAREA") { if(document.selection) // don't decide for internet explorer, it'll decide itself return false; var rangeOffset = getClickedPosition(event, target); var selectionStart = getSelectionStart(event, target); var selectionEnd = getSelectionEnd(event, target); if(selectionStart > selectionEnd) { var temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } if(selectionStart == selectionEnd) return true; if((rangeOffset <= selectionStart || rangeOffset >= selectionEnd)) return true; } return false; }; var textDragCode = { install : function(element) { if(isMSIE()) { // internet explorer // use the ondragstart event on textelements in the internet explorer // as it is impossible to determine if a user wanted to start // a new selection or drag the text with onmousedown etc. // because it is impossible to determine the position of the cursor // in the text, when a selection is active in the onmousedown event addEvent(element.id, 'dragstart', lib.dragStartTextComponentsMSIE); } else { addEvent(element.id, 'mousedown', lib.drag); } }, uninstall : function(element) { if(isMSIE()) { removeEvent(element.id, 'dragstart', lib.dragStartTextComponentsMSIE); } else { removeEvent(element.id, 'mousedown', lib.drag); } }, abort : function(element, event) { if(event.rangeOffset) { // put the caret at the position where clicked - removes selection, works in ff element.selectionStart = event.rangeOffset; element.selectionEnd = event.rangeOffset; } /*else { /* ie handles the textfield dragging differently, therefore no need for this, maybe in opera? if(document.selection) { var range = document.selection.createRange(); range.moveToPoint(event.clientX, event.clientY); } } */ return true; }, dragPrepare : function(event) { // decides if a drag operation is possible after the initial click if(isSelectionEvent(event)) return false; stopEvent(event); return true; }, dragStart : function(event, realEvent) { // is called when the drag operation should start (first mousemove while clicking) // - decides, if the whiledragging events should be registered (mouseenter/leave) var target = getTarget(event); var additionalParams = null; if(target.tagName == "INPUT" || target.tagName == "TEXTAREA") { additionalParams = getSelectionStart(event, target) + "-" + getSelectionEnd(event, target); } lib.sendDragEvent(event, "ds", additionalParams); stopEvent(realEvent); return true; } } var textDropCode = { drop : function(event) { // called when the mouse button is released on a droptarget // - decides if the events should be deregistered // return false only if you're using your own events var target = getTarget(event); var additionalParams = null; if(target.tagName == "INPUT" || target.tagName == "TEXTAREA") { additionalParams = getClickedPosition(event, target); } lib.sendDragEvent(event, "dr", additionalParams); stopEvent(event); return true; } } var selectionAndPosition = new Array(); function saveCaretPositionAndSelection(event) { event = wingS.event.getEvent(event); var target = wingS.event.getTarget(event); var pos = getClickedPosition(event, target); var selStart = getSelectionStart(event, target); var selEnd = getSelectionEnd(event, target); var posString = ""; if(pos == -1) { posString = selStart + "-" + selEnd; } else { posString = ""+pos; } selectionAndPosition[target.id] = posString; //wingS.request.sendEvent(event, false, true, destinationElementId, posString, null); } lib.getSelectionAndPosition = function(textElementId) { return selectionAndPosition[textElementId]; } lib.installTextPositionHandler = function(elementId) { lib.addEvent(elementId, "select", saveCaretPositionAndSelection); lib.addEvent(elementId, "mousedown", saveCaretPositionAndSelection); lib.addEvent(elementId, "keyup", saveCaretPositionAndSelection); } lib.removeTextPositionHandler = function(elementId) { lib.removeEvent(elementId, "select"); lib.removeEvent(elementId, "mousedown"); lib.removeEvent(elementId, "keyup"); } lib.registerCode('drag', 'text', textDragCode); lib.registerCode('drop', 'text', textDropCode); })(); /** * List Drag and Drop Code */ (function(){ function isSelectionEvent(event) { var target = getTarget(event); if(target.tagName == "OPTION") { // lists in firefox if(target.selected == false) {// if it isn't selected yet, it is a selection event return true; } return false; } else if(target.tagName == "SELECT") { // TODO: implement this for ie (if possible) log("determinating if this was a selection event isn't possible in internet explorer"); /* if(event.button == 2) { return false; } else return true; */ } return false; } function getRowIndex(event) { var target = getTarget(event); var parentElement = null; if(target.tagName == "OPTION") { // in firefox we can attach mouselisteners to the option elements, therefore just count at which element-position we are parentElement = getFirstParentWithTagName(target, "SELECT") } else if(target.tagName == "SELECT") { // ie unfortunately doesn't give us the OPTION-element on mouseover-events, therefore no way to get the index parentElement = null; } else { target = getFirstParentWithTagName(target, "LI") parentElement = getFirstParentWithTagName(target, "UL", "OL") } var childrenNumber = -1; if(parentElement != null) { if(parentElement.childNodes) { childrenNumber = 0; for(var i=0; i 0 && newX < (YAHOO.util.Dom.getDocumentWidth() - cursor.offsetWidth - 2)) { cursor.style.left = newX + "px"; } newX -= xOffset; newX += ajaxActivityIndicatorElement.dx; if(newX > 0 && newX < (YAHOO.util.Dom.getDocumentWidth() - wingS.global.updateCursor.width - 2)) { ajaxActivityIndicatorElement.style.left = newX + "px"; } var newY = posY + yOffset; if (newY > 0 && newY < (YAHOO.util.Dom.getDocumentHeight() - cursor.offsetHeight - 2)) { cursor.style.top = newY + "px"; } newY -= yOffset; newY += ajaxActivityIndicatorElement.dy; if(newY > 0 && newY < (YAHOO.util.Dom.getDocumentHeight() - wingS.global.updateCursor.height - 2)) { ajaxActivityIndicatorElement.style.top = newY + "px"; } } lib.setCursorElement = function(cursorElementId) { cursor = document.getElementById(cursorElementId); startFollow(); } var ajaxActivityIndicatorElement = null; function createAjaxActivityIndicatorElement() { ajaxActivityIndicatorElement = document.createElement("div"); ajaxActivityIndicatorElement.style.position = "absolute"; ajaxActivityIndicatorElement.style.top = "0px"; ajaxActivityIndicatorElement.style.left = "0px"; ajaxActivityIndicatorElement.style.zIndex = "9999"; ajaxActivityIndicatorElement.style.display = "none"; ajaxActivityIndicatorElement.style.visibility = "hidden"; ajaxActivityIndicatorElement.dx = wingS.global.updateCursor.dx; ajaxActivityIndicatorElement.dy = wingS.global.updateCursor.dy; ajaxActivityIndicatorElement.innerHTML = ""; document.body.insertBefore(ajaxActivityIndicatorElement, document.body.firstChild); return true; } lib.setAjaxActivityIndicatorVisible = function(enable) { if(wingS.global == undefined || wingS.global == null || wingS.global.updateCursor == undefined) return; if(ajaxActivityIndicatorElement == null) createAjaxActivityIndicatorElement(); if(enable) { ajaxActivityIndicatorElement.style.display = "block"; ajaxActivityIndicatorElement.style.visibility = "visible"; } else { ajaxActivityIndicatorElement.style.display = "none"; ajaxActivityIndicatorElement.style.visibility = "hidden"; } } })();/*************************************************************************************************** * WINGS.TOOLTIP -- contains: tooltip related functions **************************************************************************************************/ // Create module namespace wingS.namespace("tooltip"); wingS.tooltip.init = function(delay, duration, followMouse) { if (config && config.Delay && config.Duration && config.FollowMouse) { config.Delay = delay; config.Duration = duration; config.FollowMouse = followMouse; } }; /*************************************************************************************************** * WINGS.SCROLLBAR -- contains: scrollbar related functions **************************************************************************************************/ // Create module namespace wingS.namespace("scrollbar"); wingS.scrollbar.layout_vertical = function(id) { var table = document.getElementById(id); var outer = table.getElementsByTagName("DIV")[0]; var inner = outer.getElementsByTagName("DIV")[0]; var td = outer.parentNode; if (document.defaultView) { var heightpx = document.defaultView.getComputedStyle(td, null).getPropertyValue("height"); outer.style.height = heightpx; inner.style.height = heightpx; } else { var height = td.offsetHeight; outer.style.height = height + "px"; inner.style.height = height + "px"; } table.callbackObject = { _tOutId : 0, _adjust : function (target) { table.focus(); wingS.scrollbar.scroll_vertical(target); table.callbackObject._tOutId = 0; }, adjust : function (event) { if (table.callbackObject._tOutId == 0) { var cb = table.callbackObject; var target = wingS.event.getTarget(event); table.callbackObject._tOutId = setTimeout(function() { cb._adjust(target); }, wingS.global.autoAdjustLayout.delay); } } }; YAHOO.util.Event.addListener(outer, 'scroll', table.callbackObject.adjust); }; wingS.scrollbar.handleMouseWheel = function(event, scrollbar) { var delta = 0; if (event.wheelDelta) { delta = event.wheelDelta/120; if (window.opera) delta = -delta; } else if (event.detail) { delta = -event.detail/3; } var table = document.getElementById(scrollbar); if(table == null) return; var outer = table.getElementsByTagName("DIV")[0]; var inner = outer.getElementsByTagName("DIV")[0]; var scrollTop = outer.scrollTop; var innerHeight = inner.clientHeight; var size = parseInt(outer.getAttribute("size")); var position = scrollTop * size / innerHeight; if (delta > 0) { outer.scrollTop = innerHeight * ( position-1 ) / size; } if (delta < 0) { outer.scrollTop = innerHeight * ( position+1 ) / size; } } wingS.scrollbar.set_vertical = function(id, position, extent, size) { var table = document.getElementById(id); var outer = table.getElementsByTagName("DIV")[0]; var inner = outer.getElementsByTagName("DIV")[0]; outer.setAttribute("position", position); outer.setAttribute("size", size); var outerHeight = outer.offsetHeight; var innerHeight = outerHeight * size / extent; inner.style.height = innerHeight + "px"; outer.scrollTop = innerHeight * position / size; }; wingS.scrollbar.scroll_vertical = function(outer) { var inner = outer.getElementsByTagName("DIV")[0]; var table = wingS.util.getParentByTagName(outer, "TABLE"); var innerHeight = inner.offsetHeight; var scrollTop = outer.scrollTop; var size = outer.getAttribute("size"); var position = Math.round(scrollTop / innerHeight * size); if (outer.getAttribute("position") != position) { outer.setAttribute("position", position); wingS.request.sendEvent(null, true, true, table.id, position); } }; wingS.scrollbar.layout_horizontal = function(id) { var table = document.getElementById(id); var outer = table.getElementsByTagName("DIV")[0]; var inner = outer.getElementsByTagName("DIV")[0]; var td = outer.parentNode; if (document.defaultView) { var widthpx = document.defaultView.getComputedStyle(td, null).getPropertyValue("width"); outer.style.width = widthpx; inner.style.width = widthpx; } else { var width = td.offsetWidth; outer.style.width = width + "px"; inner.style.width = width + "px"; } table.callbackObject = { _tOutId : 0, _adjust : function (target) { table.focus(); wingS.scrollbar.scroll_horizontal(target); table.callbackObject._tOutId = 0; }, adjust : function (event) { if (table.callbackObject._tOutId == 0) { var cb = table.callbackObject; var target = wingS.event.getTarget(event); table.callbackObject._tOutId = setTimeout(function() { cb._adjust(target); }, wingS.global.autoAdjustLayout.delay); } } }; YAHOO.util.Event.addListener(outer, 'scroll', table.callbackObject.adjust); }; wingS.scrollbar.set_horizontal = function(id, position, extent, size) { var table = document.getElementById(id); var outer = table.getElementsByTagName("DIV")[0]; var inner = outer.getElementsByTagName("DIV")[0]; outer.setAttribute("position", position); outer.setAttribute("size", size); var outerWidth = outer.offsetWidth; var innerWidth = outerWidth * size / extent; inner.style.width = innerWidth + "px"; outer.scrollLeft = innerWidth * position / size; }; wingS.scrollbar.scroll_horizontal = function(outer) { var inner = outer.getElementsByTagName("DIV")[0]; var table = wingS.util.getParentByTagName(outer, "TABLE"); var innerWidth = inner.offsetWidth; var scrollLeft = outer.scrollLeft; var size = outer.getAttribute("size"); var position = Math.round(scrollLeft / innerWidth * size); if (outer.getAttribute("position") != position) { outer.setAttribute("position", position); wingS.request.sendEvent(null, true, true, table.id, position); } }; /*************************************************************************************************** * WINGS.TABLE -- contains: functions for tables **************************************************************************************************/ // Create module namespace wingS.namespace("table"); wingS.table.cellClick = function(event, cell, submit, async, eventName, eventValue) { event = wingS.event.getEvent(event); var editing = cell.getAttribute("editing"); if (!editing || editing == "false") { wingS.request.sendEvent(event, submit, async, eventName, eventValue); return false; } else return true; } /*************************************************************************************************** * WINGS.SPLITPANE -- contains: spitpane related functions **************************************************************************************************/ // Create module namespace wingS.namespace("splitpane"); wingS.splitpane.resized = function(sb, size) { wingS.request.sendEvent(null, true, true, sb.el.id, size); } /*************************************************************************************************** * WINGS.DIALOG -- contains: functions used for dialogs **************************************************************************************************/ // Create module namespace wingS.namespace("dialog"); /** * SDialog behaves like an OS dialog, with a draggable * header and an optional close icon at the top right. * @param {String} el - the element (ID) representing the SDialog * @param {Object} userConfig - the configuration object literal */ wingS.dialog.SDialog = function(el, userConfig) { wingS.dialog.SDialog.superclass.constructor.call(this, el, userConfig); wingS.global.overlayManager.register(this); }; /** * Constant representing the default CSS class used for a SDialog */ wingS.dialog.SDialog.CSS_DIALOG = "SDialog"; /** * Constant representing the SDialog's configuration properties */ wingS.dialog.SDialog._DEFAULT_CONFIG = { "VIEWPORTELEMENT": { key: "viewportelement", validator: YAHOO.lang.isString }, "PROPAGATE_MOVE_EVENT": { key: "propagateMoveEvent", value:true, validator: YAHOO.lang.isBoolean } }; YAHOO.extend(wingS.dialog.SDialog, YAHOO.widget.Dialog, { x: -1, y: -1, shadowWidth: 0, init: function(el, userConfig) { wingS.dialog.SDialog.superclass.init.call(this, el, userConfig); YAHOO.util.Dom.addClass(this.element, wingS.dialog.SDialog.CSS_DIALOG); // Set fixed width for dialogs. This fixes several problems: // - Corrupt sizing issues in IE when dragging the dialog. // - The dialog body has the "overflow" property set to "auto" // which prevents invisible cursors in textfields on FF 2.x // in case the dialog is shown in front of a DIV element // with "overflow:auto" (see Firefox bug report #167801). // However, this leads to sizing problems in probably all // browsers. The only solution is to set a fixed width here. this.beforeShowEvent.subscribe(this.setFixedWidth, this, true); // Handle close events. this.cancelEvent.subscribe(this.destroy, this, true); if (this.cfg.getProperty("underlay") == "shadow") { // Actually the default shadow width is 3px, // however, this doesn't seem to be enough. this.shadowWidth = 5; }; }, initDefaultConfig : function() { wingS.dialog.SDialog.superclass.initDefaultConfig.call(this); // Add SDialog config properties // var DEFAULT_CONFIG = wingS.dialog.SDialog._DEFAULT_CONFIG; // The element that get the dialog as responsible actor this.cfg.addProperty(DEFAULT_CONFIG.VIEWPORTELEMENT.key, { handler: this.configContext, validator: DEFAULT_CONFIG.VIEWPORTELEMENT.validator }); this.cfg.addProperty(DEFAULT_CONFIG.PROPAGATE_MOVE_EVENT.key, { handler: this.configMoveHandler, value: DEFAULT_CONFIG.PROPAGATE_MOVE_EVENT.value, validator: DEFAULT_CONFIG.PROPAGATE_MOVE_EVENT.validator }); }, configMoveHandler: function(type, args, obj) { // Register the dialog for move events if args[0] == true. if (args[0]) { this.moveEvent.subscribe(this.moveHandler, this, true); } }, /** * Handle move events. Send a request back to server containing the * x-position and y-position of this dialog. That permits a consitent * component state between server and client. * * @param {Object} type * @param {Object} args * @param {Object} obj */ moveHandler: function(type, args, obj) { var xy = args[0]; // Send events if position has been changed. if (xy[0] != this.x || xy[1] != this.y) { this.x = xy[0]; this.y = xy[1]; wingS.request.sendEvent(null, false, true, this.id + "_xy", args[0]); } }, doSubmit: function() { // do nothing }, submit: function() { // do nothing }, /** * Sends a destroy event to the server and destroys this dialog afterwards. */ destroy: function(type, args, obj) { wingS.request.sendEvent(null, false, true, this.id + "_dispose", 1); }, /** * Calculates the width of the dialog's content and sets this width as the * width of the dialog's most outer div. */ setFixedWidth: function(type, args, obj) { var formContentTable = YAHOO.util.Dom.getRegion(this.id + '_table'); var innerWidth = formContentTable.right - formContentTable.left; this.cfg.setProperty("width", innerWidth + "px"); }, /** * Centers this dialog within the window or within a viewport element if * specified at instanciation time. */ center: function() { var viewportelementId = this.cfg.getProperty("viewportelement"); if (typeof viewportelementId == 'undefined') { wingS.dialog.SDialog.superclass.center.call(this); return; } var viewportelement = document.getElementById(viewportelementId); var viewportX = YAHOO.util.Dom.getX(viewportelement); var viewportY = YAHOO.util.Dom.getY(viewportelement); var viewportW = viewportelement.offsetWidth; var viewportH = viewportelement.offsetHeight; var viewportO = YAHOO.widget.Overlay.VIEWPORT_OFFSET; var dialogW = this.element.offsetWidth + (2 * this.shadowWidth); var dialogH = this.element.offsetHeight + (1 * this.shadowWidth); var centeredX; var centeredY; if (dialogW < viewportW) { centeredX = viewportX + (viewportW / 2) - (dialogW / 2); } else { centeredX = viewportX + viewportOffset; } if (dialogH < viewportH) { centeredY = viewportY + (viewportH / 2) - (dialogH / 2); } else { centeredY = viewportY + viewportOffset; } this.cfg.setProperty("xy", [parseInt(centeredX, 10), parseInt(centeredY, 10)]); this.cfg.refireEvent("iframe"); }, getConstrainedXY: function(x, y) { var viewportelementId = this.cfg.getProperty("viewportelement"); if (typeof viewportelementId == 'undefined') { return wingS.dialog.SDialog.superclass.getConstrainedXY.call(this, x, y); } var viewportelement = document.getElementById(viewportelementId); var viewportX = YAHOO.util.Dom.getX(viewportelement); var viewportY = YAHOO.util.Dom.getY(viewportelement); var viewportW = viewportelement.offsetWidth; var viewportH = viewportelement.offsetHeight; var viewportO = YAHOO.widget.Overlay.VIEWPORT_OFFSET; var dialogW = this.element.offsetWidth + (2 * this.shadowWidth); var dialogH = this.element.offsetHeight + (1 * this.shadowWidth); var constrainedX = x; var constrainedY = y; if (dialogW + viewportO < viewportW) { var leftConstraint = viewportX + viewportO; var rightConstraint = viewportX + viewportW - dialogW - viewportO; if (x < leftConstraint) { constrainedX = leftConstraint; } else if (x > rightConstraint) { constrainedX = rightConstraint; } } else { constrainedX = viewportO + viewportX; } if (dialogH + viewportO < viewportH) { var topConstraint = viewportY + viewportO; var bottomConstraint = viewportY + viewportH - dialogH - viewportO; if (y < topConstraint) { constrainedY = topConstraint; } else if (y > bottomConstraint) { constrainedY = bottomConstraint; } } else { constrainedY = viewportO + viewportY; } return [constrainedX, constrainedY]; }, configModal: function(type, args, obj) { var modal = args[0]; if (modal) { if (!this._hasModalityEventListeners) { this.buildMask(); this.bringToTop(); this.showMask(); this.sizeMask(); } } else { if (this._hasModalityEventListeners) { if (this.cfg.getProperty("visible")) { this.hideMask(); this.removeMask(); } this.unsubscribe("beforeShow", this.buildMask); this.unsubscribe("beforeShow", this.bringToTop); this.unsubscribe("beforeShow", this.showMask); this.unsubscribe("hide", this.hideMask); Overlay.windowResizeEvent.unsubscribe(this.sizeMask, this); this._hasModalityEventListeners = false; } } }, registerDragDrop: function () { var viewportelementId = this.cfg.getProperty("viewportelement"); if (typeof viewportelementId == 'undefined') { wingS.dialog.SDialog.superclass.registerDragDrop.call(this); return; } var me = this; if (this.header) { if (!YAHOO.util.DD) { YAHOO.log("DD dependency not met.", "error"); return; } this.dd = new YAHOO.util.DD(this.element.id, this.id); if (!this.header.id) { this.header.id = this.id + "_h"; } this.dd.startDrag = function () { var offsetHeight, offsetWidth, viewPortWidth, viewPortHeight, scrollX, scrollY, topConstraint, leftConstraint, bottomConstraint, rightConstraint; if (YAHOO.env.ua.ie == 6) { YAHOO.util.Dom.addClass(me.element, "drag"); } if (me.cfg.getProperty("constraintoviewport")) { var viewportelement = document.getElementById(viewportelementId); var viewportX = YAHOO.util.Dom.getX(viewportelement); var viewportY = YAHOO.util.Dom.getY(viewportelement); var viewportW = viewportelement.offsetWidth; var viewportH = viewportelement.offsetHeight; var viewportO = YAHOO.widget.Overlay.VIEWPORT_OFFSET; var dialogW = me.element.offsetWidth + (2 * me.shadowWidth); var dialogH = me.element.offsetHeight + (1 * me.shadowWidth); var topConstraint = viewportY + viewportO; var leftConstraint = viewportX + viewportO; var bottomConstraint = viewportY + viewportH - dialogH - viewportO; var rightConstraint = viewportX + viewportW - dialogW - viewportO; this.minX = leftConstraint; this.maxX = rightConstraint; this.constrainX = true; this.minY = topConstraint; this.maxY = bottomConstraint; this.constrainY = true; } else { this.constrainX = false; this.constrainY = false; } me.dragEvent.fire("startDrag", arguments); }; this.dd.onDrag = function () { me.syncPosition(); me.cfg.refireEvent("iframe"); if (this.platform == "mac" && YAHOO.env.ua.gecko) { this.showMacGeckoScrollbars(); } me.dragEvent.fire("onDrag", arguments); }; this.dd.endDrag = function () { if (YAHOO.env.ua.ie == 6) { YAHOO.util.Dom.removeClass(me.element, "drag"); } me.dragEvent.fire("endDrag", arguments); me.moveEvent.fire(me.cfg.getProperty("xy")); }; this.dd.setHandleElId(this.header.id); this.dd.addInvalidHandleType("INPUT"); this.dd.addInvalidHandleType("SELECT"); this.dd.addInvalidHandleType("TEXTAREA"); } }, buildMask: function () { var oMask = this.mask; if (!oMask) { oMask = document.createElement("div"); oMask.className = "mask"; oMask.innerHTML = " "; oMask.id = this.id + "_mask"; YAHOO.util.Dom.insertAfter(oMask, this.element); this.mask = oMask; // Stack mask based on the element zindex this.stackMask(); } }, hideMask: function () { if (this.cfg.getProperty("modal") && this.mask) { this.mask.style.display = "none"; this.hideMaskEvent.fire(); } }, showMask: function () { if (this.cfg.getProperty("modal") && this.mask) { this.sizeMask(); this.mask.style.display = "block"; this.showMaskEvent.fire(); } }, sizeMask: function () { var viewportelementId = this.cfg.getProperty("viewportelement"); if (typeof viewportelementId == 'undefined') { wingS.dialog.SDialog.superclass.sizeMask.call(this); return; } var viewportelement = document.getElementById(viewportelementId); if (this.mask) { var zIndex = "2"; var top = YAHOO.util.Dom.getY(viewportelement) + "px"; var left = YAHOO.util.Dom.getX(viewportelement) + "px"; var height = viewportelement.offsetHeight + "px"; var width = viewportelement.offsetWidth + "px"; if (YAHOO.env.ua.ie == 7) { top = (YAHOO.util.Dom.getY(viewportelement) - 2) + "px"; left = (YAHOO.util.Dom.getX(viewportelement) - 2) + "px"; } this.element.style.zIndex = zIndex; this.mask.style.top = top; this.mask.style.left = left; this.mask.style.height = height; this.mask.style.width = width; } }, toString: function() { return "wingS.dialog.SDialog " + this.id; } }); /** * Creates the markup for a dialog with the given container id and returns * the container element. * @param {Object} containerId The id that will be set for the container. */ wingS.dialog.createDialogMarkup = function(containerId, cfg){ var container = document.createElement("div"); container.id = containerId; var hd = wingS.dialog.createConfiguredElement("hd", cfg); var bd = wingS.dialog.createConfiguredElement("bd", cfg); var ft = wingS.dialog.createConfiguredElement("ft", cfg); container.appendChild(hd); container.appendChild(bd); container.appendChild(ft); return container; } wingS.dialog.createConfiguredElement = function(className, cfg) { var el = document.createElement("div"); el.className = className; if (cfg == null || cfg == 'undefined') { return el; } el.className = el.className + (cfg.className != 'undefined' ? " " + cfg.className : ""); return el; } wingS.dialog.showExceptionDialog = function(exception){ // Initialize exception dialog count if not already done. if (!wingS.dialog.exceptionDialogCount) { wingS.dialog.exceptionDialogCount = 0; } // Count of currently available exception dialogs. var count = wingS.dialog.exceptionDialogCount; // Ids for exception message and exception detail container. var exceptionMessageId = "exceptionMessage" + count; var exceptionDetailId = "exceptionDetail" + count; // Create exception dialog markup containing exception message // container and exception detail container. var exceptionMarkup = wingS.dialog.createExceptionDialogMarkup(exceptionMessageId, exceptionDetailId) document.body.appendChild(exceptionMarkup); // Define various event handlers for Dialog var handleClose = function(){ this.removeMask(); this.destroy(); wingS.request.reloadFrame(); }; var toggleDetails = function(){ var visible = detail.cfg.getProperty("visible"); detail.cfg.setProperty("visible", !visible); }; // Instantiate the Dialog var dialog = new YAHOO.widget.SimpleDialog(exceptionMessageId, { width: "400px", fixedcenter: true, visible: false, draggable: true, modal: true, close: true, icon: YAHOO.widget.SimpleDialog.ICON_BLOCK, constraintoviewport: true, buttons: [{ text: "Close", handler: handleClose, isDefault: true }, { text: "Details", handler: toggleDetails }] }); // Instantiate the Module var detail = new YAHOO.widget.Module(exceptionDetailId, { width: "400px", visible: false }); dialog.setHeader("Error message"); dialog.setBody(exception.message); dialog.render(); // Prepares the message. var detailedMessage = wingS.dialog.prepareDetailedMessage(exception.message + "\n" + exception.detail); detail.setHeader("Detailed Message:"); detail.setBody(detailedMessage); detail.render(); dialog.show(); }; /** * Creates the markup for the exception dialog. * * @param {Object} exceptionMessageId The id for the exception message container. * @param {Object} exceptionDetailId The id for the exception detail container. */ wingS.dialog.createExceptionDialogMarkup = function(exceptionMessageId, exceptionDetailId){ var exceptionMessage = wingS.dialog.createDialogMarkup(exceptionMessageId); var exceptionDetail = document.createElement("div"); exceptionDetail.id = exceptionDetailId; exceptionMessage.appendChild(exceptionDetail); return exceptionMessage; } /** * Uses a message and converts each '\n' into a '
' element and wraps the rest * of the message into text nodes. * @param {Object} msg The message to be prepared. * @return {HTMLElement} The prepared message wrapped into a '
' element.
 */
wingS.dialog.prepareDetailedMessage = function(msg) {
    var parts = msg.split("\\n");

    var detailedMessage = document.createElement("textarea");
/*
    for (var i = 0; i < parts.length; i++) {
        var textNode = document.createTextNode(parts[i]);
        detailedMessage.appendChild(textNode);

        if ((i + 1) < parts.length) {
            var br = document.createElement("br");
            detailedMessage.appendChild(br);
        }
    }
*/
    detailedMessage.value = msg;

//	detailedMessage.style.overflow = "auto";
    detailedMessage.style.width = "100%";
    detailedMessage.style.height = "120px";
    detailedMessage.style.border = "1px solid black";
    detailedMessage.readOnly = true;
//	detailedMessage.style.backgroundColor = "white";

    return detailedMessage;
}/***************************************************************************************************
 * WINGS.COMET  --  contains: functions used to process ajax comet requests
 **************************************************************************************************/

// Create module namespace
wingS.namespace("comet");

// Set the Comet Path
//wingS.comet.cometPath = "http://localhost:8080/comet_chat/Chat/blub";
wingS.comet.cometPath = "hanging";

wingS.comet.newHangingGetAllowed = false;

wingS.comet.requestUpdates = function() {
    wingS.request.sendEvent(null, false, true, "comet", "1");
};

wingS.comet.requestUpdates_polling = function() {
    wingS.request.sendEvent(null, false, true, "polling", "1");
};

wingS.comet.connect = function() {
    //wingS.comet.newHangingGetAllowed = true;
    //if (wingS.global.asyncHeaderQueue.length == 0) {
        //wingS.ajax.dequeueNextRequest();
    //}
    wingS.comet.sendHangingGetRequest();
};

wingS.comet.disconnect = function() {
    clearInterval(wingS.comet.intervalID);
    wingS.comet.newHangingGetAllowed = false;
};

wingS.comet.periodicPolling = function(interval) {
    wingS.comet.intervalID = setInterval("wingS.comet.requestUpdates_polling()", interval);
};

wingS.comet.switchToHanging = function() {
    clearInterval(wingS.comet.intervalID);
    wingS.comet.connect();
};

wingS.comet.init = function() {

    // Send first Hanging GET request
    wingS.comet.connect();

    //wingS.comet.periodicPolling(2000);
    //wingS.comet.streamTriggers();
};

wingS.comet.handleSuccess = function(request) {
    if (wingS.global.debugMode)
        wingS.ajax.updateDebugView(request);

    // Get the received XML response
    var xmlDoc = request.responseXML;
    if (xmlDoc == null) {
        // In case we don't get any XML there is nothing more
        // what we can do here; the only thing --> do reload!
        wingS.request.reloadFrame();
        // Better?: wingS.ajax.processRequestFailure(request);
        return;
    }

    // Get the document's root element
    var xmlRoot = xmlDoc.getElementsByTagName("updates")[0];
    if (xmlRoot == null) {
        // Workaround to prevent IE from showing JS errors
        // if session has meanwhile timed out --> do reload!
        wingS.request.reloadFrame();
        // Better?: wingS.ajax.processRequestFailure(request);
        return;
    }

    // Process each incremental update
    var updates = xmlRoot.getElementsByTagName("update");
    if (updates.length > 0) {
        for (var i = 0; i < updates.length; i++) {
            try {
                // Dispatch update to the corresponding
                // handler function simply by evaluation
                window.eval(updates[i].firstChild.data);
            } catch(e) {
                var errorMsg = "Failure while processing the reponse of an AJAX Comet request!\n" +
                               "**********************************************\n\n" +
                               "Error Message: " + e.message + "!\n\n" +
                               "The error occurred while evaluating the following JS code:\n" +
                               updates[i].firstChild.data;
                alert(errorMsg);
            }
        }
    }
};

wingS.comet.handleFailure = function(request) {

    /*
    if (request.status == -1) {
        alert("transaction aborted");
    } else if (request.status == 0) {
        alert("communication failure");
    }
    */

    // Pull updates & send new Hanging GET request
    wingS.comet.requestUpdates();
};

wingS.comet.callbackObject = {
    success : function(request) { wingS.comet.handleSuccess(request); },
    failure : function(request) { wingS.comet.handleFailure(request); }
};

wingS.comet.sendHangingGetRequest = function() {
	uri = wingS.comet.cometPath 
		+ "-" + wingS.global.updateResource  
		+ "?_xhrID=" + new Date().getTime();
    wingS.comet.connectionObject = 
        YAHOO.util.Connect.asyncRequest("GET", uri, wingS.comet.callbackObject);
};

wingS.comet.streamTriggers = function() {

    var streamreq = new XMLHttpRequest();
    var byteoffset = 0;
    var buffer;
    var newdata;
    var url = "blub";
    var now = new Date();
    var t = now.getTime();
    url += "?nocache=" + t;

    streamreq.open("GET", url, true);

    streamreq.onreadystatechange = function() {

        if (streamreq.readyState == 3) {

            buffer = streamreq.responseText;
            newdata = buffer.substring(byteoffset);
            byteoffset = buffer.length;

            while (1) {
                var x = newdata.indexOf("");
                if (x != -1) {
                    var y = newdata.indexOf("");
                    if (y != -1) {
                        window.eval(newdata.substring((x+8),y));
                        newdata = newdata.substring(y+9);
                    } else {
                        // Last message is corrupt or incomplete. Ignore it and it will be fetched again.
                        break;
                    }
               } else {
               // No more messages.
               break;
               }
            }

            byteoffset = buffer.length - newdata.length;
        }
    }

    streamreq.send(null);
};

/*
wingS.comet.getCookie = function( name ) {
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ';', len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}

wingS.comet.setCookie = function( name, value, expires, path, domain, secure ) {
	var today = new Date();
	today.setTime( today.getTime() );
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+'='+escape( value ) +
		( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) +
		( ( path ) ? ';path=' + path : '' ) +
		( ( domain ) ? ';domain=' + domain : '' ) +
		( ( secure ) ? ';secure' : '' );
}

wingS.comet.deleteCookie = function( name, path, domain ) {
	if ( getCookie( name ) ) document.cookie = name + '=' +
			( ( path ) ? ';path=' + path : '') +
			( ( domain ) ? ';domain=' + domain : '' ) +
			';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}
*/




© 2015 - 2024 Weber Informatics LLC | Privacy Policy