﻿/*
name         : ClassBehaviours, the javascript framework based on class-name parsing
update         : 9.3.17
author         : Maurice van Creij
dependencies   : jquery.classbehaviours.js
info         : http://www.classbehaviours.com/

This file is part of jQuery.classBehaviours.

ClassBehaviours is a javascript framework based on class-name parsing.
Copyright (C) 2008  Maurice van Creij

ClassBehaviours is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

ClassBehaviours is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ClassBehaviours. If not, see http://www.gnu.org/licenses/gpl.html.
*/

// create the jQuery object if it doesn't already exist
if (typeof (jQuery) == 'undefined') jQuery = function() { };

// create the root classbehaviours object if it doesn't already exist
if (typeof (jQuery.classBehaviours) == 'undefined') jQuery.classBehaviours = function() { };

// create the handlers child object if it doesn't already exist
if (typeof (jQuery.classBehaviours.handlers) == 'undefined') jQuery.classBehaviours.handlers = function() { }

// Replace a link to external content with the actual content
jQuery.classBehaviours.handlers.reloadFromUrl = {
    // properties
    name: 'reloadFromUrl',
    focus: '',
    index: 0,
    // methods
    start: function(node) {
        // if the node is marked to load automatically start loading else set an onclick event
        automatic = jQuery.classBehaviours.utilities.getClassParameter(node, 'auto', 'no');
        if (node.nodeName == 'IFRAME' || automatic == 'yes') this.clicked(node)
        //  Addde for .NET
        else if (node.nodeName == 'A' && node.href.indexOf('javascript:__doPostBack') > -1) {   //  ADDED BY MARC
            node.href = '';
            node.onclick = this.clicked;
        }
        else if (node.nodeName == 'FORM') node.onsubmit = this.clicked
        else if (node.nodeName == 'BUTTON') node.onclick = this.clicked
        else if (node.nodeName == 'INPUT' && (node.type == 'button' || node.type == 'submit')) node.onclick = this.clicked
        else if (node.nodeName == 'INPUT' && (node.type == 'radio' || node.type == 'checkbox')) node.onclick = this.changed
        else if (node.nodeName == 'INPUT') node.onchange = this.changed
        else if (node.nodeName == 'SELECT') node.onchange = this.changed
        else if (node.nodeName == 'TEXTAREA') node.onchange = this.changed
        else if (node.nodeName == 'FIELDSET') null
        else node.onclick = this.clicked;
    },
    wait: function(importProgress, referedNode, importError) {
        // get the target for the indicator
        targetId = jQuery.classBehaviours.utilities.getClassParameter(referedNode, 'target', null);
        if (targetId != null) targetNode = document.getElementById(targetId)
        else targetNode = referedNode;
        // animate the progress indicator
        jQuery.classBehaviours.utilities.setClassParameter(targetNode, 'progress', importProgress);
        jQuery.classBehaviours.utilities.setClassParameter(targetNode, 'error', importError);
    },
    insert: function(importedObj, referedNode, importedText) {
        var rfu = jQuery.classBehaviours.handlers.reloadFromUrl;
        // get the optional parameters from the refered node
        targetId = jQuery.classBehaviours.utilities.getClassParameter(referedNode, 'target', null);
        sourceId = jQuery.classBehaviours.utilities.getClassParameter(referedNode, 'source', null);
        noformId = jQuery.classBehaviours.utilities.getClassParameter(referedNode, 'noform', null); // NEW 
        nonIntrusive = (jQuery.classBehaviours.utilities.getClassParameter(referedNode, 'gently', '0') == '1');
        // get the content from the imported node
        importedNode = (sourceId != null) ?
            jQuery.classBehaviours.utilities.getXmlElementById(sourceId, importedObj, true) :
            importedObj;
        // forcefully insert the content into the target node
        if (!nonIntrusive) {
            // get the source HTML from the imported document
            importedHTML = jQuery.classBehaviours.ajax.serialize(importedNode, true);
            // strip any left over body tags from the content
            if (importedHTML.indexOf('<body') > -1) {
                importedHTML = importedHTML.split('<body')[1].split('</body>')[0];
                importedHTML = importedHTML.substr(importedHTML.indexOf('>') + 1, importedHTML.length);
            }
            // if no id was given for the target node
            if (targetId == null) {
                // replace the refered node
                newDiv = document.createElement('div');
                newDiv.id = rfu.name + rfu.index++;
                referedNode.parentNode.replaceChild(newDiv, referedNode);
                targetNode = document.getElementById(newDiv.id);
            }
            // else
            else {
                // use the target id to find the node
                targetNode = document.getElementById(targetId);
            }
            //  If a full page is loaded (possible redirect!!)
            if (noformId == '1' && new String(importedHTML).toLowerCase().indexOf('<form') > -1) { // FULLY NEW MARC
                url = new String(importedHTML).toLowerCase();
                index = url.indexOf('action') + 8;
                url = url.substr(index, url.length - index);
                //  IE removed the " from the action="".
                index = url.indexOf('"') > url.indexOf('>') ? url.indexOf('>') : url.indexOf('"');
                url = url.substr(0, index);
                location.href = url;
                return;
            }
            // insert the imported HTML
            if (targetNode != null)
                targetNode.innerHTML = importedHTML;
            if (document.getElementById(jQuery.classBehaviours.handlers.reloadFromUrl.focus) != null) // ADDED
                document.getElementById(jQuery.classBehaviours.handlers.reloadFromUrl.focus).focus();
        }
        // or gently compare classnames and text
        else {
            // for all imported nodes
            importedChildNodes = importedNode.getElementsByTagName('*');
            for (var a = importedChildNodes.length - 1; a >= 0; a--) {
                // get the target ID
                exportedChildNodeId = importedChildNodes[a].getAttribute('id');
                // if it's a node with an existing ID
                if (exportedChildNodeId != null && exportedChildNodeId != '') {
                    // get the target node
                    exportedChildNode = document.getElementById(exportedChildNodeId);
                    // does this node actually exist?
                    if (exportedChildNode != null) {
                        // sync the classname
                        exportedChildNode.className = (importedChildNodes[a].className != null) ? importedChildNodes[a].className : importedChildNodes[a].getAttribute('class');
                        // sync the select options
                        if (importedChildNodes[a].nodeName == 'SELECT') {
                            // every node in this select
                            importedSelectOptions = importedChildNodes[a].getElementsByTagName('OPTION');
                            exportedSelectOptions = exportedChildNode.getElementsByTagName('OPTION');
                            // choose the longest list
                            selectOptionsLength = (importedSelectOptions.length > exportedSelectOptions.length) ? importedSelectOptions.length : exportedSelectOptions.length;
                            // for every item in the list
                            for (var b = selectOptionsLength - 1; b >= 0; b--) {
                                // if there is no exported option
                                if (b >= exportedSelectOptions.length) {
                                    // make a new option node
                                    newOptionElement = document.createElement('OPTION');
                                    newOptionText = document.createTextNode(importedSelectOptions[b].firstChild.nodeValue);
                                    newOptionElement.appendChild(newOptionText);
                                    newOptionElement.setAttribute('value', importedSelectOptions[b].value);
                                    exportedChildNode.appendChild(newOptionElement);
                                }
                                // if there is no imported option
                                else if (b >= importedSelectOptions.length) {
                                    // remove an option node
                                    exportedSelectOptions[b].parentNode.removeChild(exportedSelectOptions[b]);
                                }
                                // else
                                else {
                                    // transfer the imported to the exported node
                                    exportedSelectOptions[b].firstChild.nodeValue = importedSelectOptions[b].firstChild.nodeValue;
                                    exportedSelectOptions[b].value = importedSelectOptions[b].value;
                                }
                            }
                        }
                        // sync the text
                        importedHTML = jQuery.classBehaviours.ajax.serialize(importedChildNodes[a]);
                        importedHTML = importedHTML.substring(importedHTML.indexOf('>') + 1, importedHTML.lastIndexOf('<'));
                        isInlineMarkup = (
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<DIV') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<SECTION') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<ARTICLE') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<HEADER') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<FOOTER') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<NAV') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<FIELDSET') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<SELECT') < 0 &&
                        exportedChildNode.nodeName != 'SELECT' &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<OPTION') < 0 &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<TEXTAREA') < 0 &&
                        exportedChildNode.nodeName != 'TEXTAREA' &&
                        exportedChildNode.innerHTML.toUpperCase().indexOf('<INPUT') < 0 &&
                        exportedChildNode.nodeName != 'INPUT'
                     );
                        if (isInlineMarkup) exportedChildNode.innerHTML = importedHTML;
                    }
                }
            }
        }
        // reset the progress indicator
        jQuery.classBehaviours.utilities.setClassParameter(targetNode, 'progress', 4);
        jQuery.classBehaviours.utilities.setClassParameter(targetNode, 'error', 200);
        // activate any classbehaviours in there
        jQuery.classBehaviours.parser.parseNode(targetNode);
        // OPTIONAL: replace the title
        replaceTitleId = jQuery.classBehaviours.utilities.getClassParameter(referedNode, 'title', null);
        if (replaceTitleId != null) document.getElementById(replaceTitleId).innerHTML = referedNode.title;
    },
    // events
    clicked: function(that) {
        var objNode = (typeof (this.nodeName) == 'undefined') ? that : this;
        jQuery.classBehaviours.handlers.reloadFromUrl.focus = objNode.id; // ADDED BY MARC
        var rfu = jQuery.classBehaviours.handlers.reloadFromUrl;
        // try to get a URL from somewhere
        targetHref = objNode.getAttribute('href');
        targetSrc = objNode.getAttribute('src');
        targetLongdesc = objNode.getAttribute('longdesc');
        rootForm = jQuery.classBehaviours.utilities.rootNode(objNode, 'FORM', null);
        targetAction = rootForm.getAttribute('action');
        hrefTarget = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'id', ''); // ADDED BY MARC
        // decide which URL has priority
        targetUrl = (targetHref != null && targetHref != '') ? targetHref :
            (hrefTarget != null && hrefTarget != '') ? document.getElementById(hrefTarget).href : // ADDED BY MARC
            (targetAction != null && targetAction != '') ? targetAction :
            (targetLongdesc != null && targetLongdesc != '') ? targetLongdesc :
            (targetSrc != null && targetSrc != '') ? targetSrc :
            document.location.href;
        // get the post values
        postValues = jQuery.classBehaviours.ajax.getPostValues(objNode);
        // get the post method
        postPrefix = (targetUrl.indexOf('?') < 0) ? '?' : '&';
        // place the AJAX request and cancel the click
        (new String(rootForm.getAttribute('method')).toLowerCase() == 'post') ?  //  ALTERED BY MARC
            jQuery.classBehaviours.ajax.addRequest(targetUrl, rfu.insert, rfu.wait, postValues, objNode) :
            jQuery.classBehaviours.ajax.addRequest(targetUrl + postPrefix + postValues, rfu.insert, rfu.wait, null, objNode);
        return false;

    },
    changed: function(that) {
        var objNode = (typeof (this.nodeName) == 'undefined') ? that : this;
        var rfu = jQuery.classBehaviours.handlers.reloadFromUrl;
        // find the fieldset that belongs to this part of the form
        submitNode = jQuery.classBehaviours.utilities.rootNode(objNode, 'FIELDSET', null);
        // use the entire form if no fieldset was found
        if (submitNode.nodeName == 'BODY') {
            submitNode = jQuery.classBehaviours.utilities.rootNode(objNode, 'FORM', null);
        }
        // find any buttons in this fieldset
        buttonNodes = submitNode.getElementsByTagName('BUTTON');
        if (buttonNodes.length > 0) {
            submitNode = buttonNodes[0];
        }
        // or find any submit inputs in this fieldset instead
        else {
            inputNodes = submitNode.getElementsByTagName('INPUT');
            for (var a = 0; a < inputNodes.length; a++) if (inputNodes[a].type == 'submit' || inputNodes[a].type == 'button') submitNode = inputNodes[a];
        }
        // post it
        void (rfu.clicked(submitNode));
        return true;
    }
}

// add this addon to the jQuery object
if (typeof (jQuery.fn) != 'undefined') {
    // extend jQuery with this method
    jQuery.fn.reloadFromUrl = function() {
        return this.each(
            function() {
                jQuery.classBehaviours.handlers.reloadFromUrl.start(this);
            }
         );
    };
    // set the event handler for this jQuery method
    $(document).ready(
         function() {
             $(".reloadFromUrl").reloadFromUrl();
         }
      );
}