⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cocoon-ajax.js

📁 Hippo CMS是一个以信息为中心的开源内容管理系统。Hippo CMS目标是供中,大型企业来管理其发布在互连网
💻 JS
字号:
/*
 * Copyright 1999-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

if (typeof cocoon == "undefined") cocoon = {};

cocoon.ajax = {};

/**
 * Create an XHR if the browser supports it.
 */
cocoon.ajax.newXMLHttpRequest = function () {
    if (window.XMLHttpRequest)
        return new XMLHttpRequest;
    else if (window.ActiveXObject)
        return new ActiveXObject("Microsoft.XMLHTTP");
}

//-------------------------------------------------------------------------------------------------

cocoon.ajax.DOMUtils = {
    // Stupid IE doesn't have these constants
    ELEMENT_NODE : 1,
    ATTRIBUTE_NODE : 2,
    TEXT_NODE : 3,
    CDATA_SECTION_NODE : 4,
    ENTITY_REFERENCE_NODE : 5,
    ENTITY_NODE : 6,
    PROCESSING_INSTRUCTION_NODE : 7,
    COMMENT_NODE : 8,
    DOCUMENT_NODE : 9,
    DOCUMENT_TYPE_NODE : 10,
    DOCUMENT_FRAGMENT_NODE : 11
}

/**
 * Get the first child element of an element, ignoring text nodes
 */
cocoon.ajax.DOMUtils.firstChildElement = function(element) {
    var nodes = element.childNodes;
    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        if (node.nodeType == this.ELEMENT_NODE) {
            return node;
        }
    }
}
cocoon.ajax.DOMUtils.ScriptRegexp = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
/**
 * Imports an element into a document, taking care of using the correct implementation
 * so that the browser interprets it as displayable XML.
 * Any <script> in the imported node are collected and evaluated after the import
 */
cocoon.ajax.DOMUtils.importNode = function(node, targetDoc) {
    var result;
    if(node.xml) {
        // IE
        var div = targetDoc.createElement("DIV");
        var text = node.xml;
        
        // Extract scripts
        var match    = new RegExp(cocoon.ajax.DOMUtils.ScriptRegexp, 'img');
        
        // Update screen
        div.innerHTML = text.replace(match, '');

        // And evaluate scripts with a small delay (looks like IE doesn't
        // immediately update the DOM after setting innerHTML?)
        var scripts  = text.match(match);
        if (scripts) {
	        setTimeout(function() {
	            var match = new RegExp(cocoon.ajax.DOMUtils.ScriptRegexp, 'im');
	            for (var i = 0; i < scripts.length; i++) {
	                eval(scripts[i].match(match)[1]);
	            }
	        }, 10);
	    }
        
        result = this.firstChildElement(div);
        
    } else {
        var scripts = new Array();
        result = this._importNode(node, targetDoc, scripts);
        for (var i = 0; i < scripts.length; i++) {
              eval(scripts[i]);
        }
    }
    return result;
}

/**
 * DOM implementation of importNode, recursively creating nodes.
 * Scripts are collected in the "scripts" parameter
 */
cocoon.ajax.DOMUtils._importNode = function(node, targetDoc, scripts) {
    switch(node.nodeType) {
        case this.ELEMENT_NODE:
            if (node.nodeName.toLowerCase() == "script") {
                // Collect scripts
                scripts.push(node.firstChild && node.firstChild.nodeValue);
                return;
            }
            var element = targetDoc.createElement(node.nodeName);
            //var element = targetDoc.createElementNS(node.namespaceURI, node.nodeName);
            var attrs = node.attributes;
            for (var i = 0; i < attrs.length; i++) {
                var attr = attrs[i];
                element.setAttribute(attr.nodeName, attr.nodeValue);
                //element.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.nodeValue);
            }
            var children = node.childNodes;
            for (var j = 0; j < children.length; j++) {
                var imported = this.importNode(children[j], targetDoc);
                if (imported) element.appendChild(imported);
            }
            return element;
        break;
        
        case this.TEXT_NODE:
            return targetDoc.createTextNode(node.nodeValue);
        break;
        
        case this.CDATA_SECTION_NODE:
            return targetDoc.createTextNode(node.nodeValue);
        break;
    }
}

//-------------------------------------------------------------------------------------------------
// General purpose AJAX infrastructure to handle a BU ("browser update") response
//
// To implement a new system-wide instruction, add the corresponding function as a property of
// BrowserUpdate.handlers.
// To add a new handler for a given request, create a new BrowserUpdater and update its
// handlers property.
//-------------------------------------------------------------------------------------------------

cocoon.ajax.BrowserUpdater = function() {
    this.handlers = {};
};

cocoon.ajax.BrowserUpdater.highlight = null;

cocoon.ajax.BrowserUpdater.prototype.processResponse = function(doc, request) {
    var nodes = doc.documentElement.childNodes;
    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        if (node.nodeType == cocoon.ajax.DOMUtils.ELEMENT_NODE) {
            var handler;
            if (node.localName) {
                handler = node.localName;
            } else {
                // No DOM2 support (IE6)
                handler = node.nodeName.replace(/.*:/, "");
            }
            var handlerFunc = this.handlers[handler] || cocoon.ajax.BrowserUpdater.handlers[handler];
            if (handlerFunc) {
                handlerFunc(node);
            } else {
                cocoon.ajax.BrowserUpdater.handleError("No handler found for element " + handler, request);
            }
        }
    }
}

/**
 * System-wide handlers
 */
cocoon.ajax.BrowserUpdater.handlers = {
    replace :  function(element) {
        var id = element.getAttribute("id");
        if (!id) {
           alert("no id found on update element");
           return;
        }    
        // Get the first child element (the first child may be some text!)
        var firstChild = cocoon.ajax.DOMUtils.firstChildElement(element);
    
        var oldElement = document.getElementById(id);
        
        if (!oldElement) {
            alert("no element '" + id + "' in source document");
            return;
        }
    
        var newElement = cocoon.ajax.DOMUtils.importNode(firstChild, document);
        
        // Warn: it's replace(new, old)!!
        oldElement.parentNode.replaceChild(newElement, oldElement);
        // Ensure the new node has the correct id
        newElement.setAttribute("id", id);
        
        if (cocoon.ajax.BrowserUpdater.highlight) {
           cocoon.ajax.BrowserUpdater.highlight(newElement);
        }
    }
}

cocoon.ajax.BrowserUpdater.handleError = function(message, request) {
    if (confirm(message + "\nShow server response?")) {
        var w = window.open(undefined, "Cocoon Error", "location=no");
        if (w == undefined) {
            alert("You must allow popups from this server to display the response.");
        } else {
	        var doc = w.document;
	        doc.open();
	        doc.write(request.responseText);
	        doc.close();
	    }
    }
}

//-------------------------------------------------------------------------------------------------
// Fader used to highlight page areas that have been updated
// WARNING: don't rely too much on these effects, as they're very likely to be replaced
//          by some third party library in the near future
//-------------------------------------------------------------------------------------------------

/**
 * Create a fader that will progressively change an element's background color from
 * a given color back to its original color.
 *
 * @param elt the element to fade
 * @param color the starting color (default blue)
 * @param duration the fade duration in msecs (default 1000)
 * @param fps the animation frames per seconds (default 25)
 */
cocoon.ajax.Fader = function(elt, color, duration, fps) {
   // Set default values
   if (!color) color = "#d6d7f7"; // blue
   if (!duration) duration = 1000; // 1 sec
   if (!fps) fps = 25; // 25 frames/sec
   
   this.element = elt;
   this.fromColor = cocoon.ajax.Fader.colorToRgb(color);
   this.toColor = cocoon.ajax.Fader.colorToRgb(cocoon.ajax.Fader.getBgColor(this.element));
   
   this.maxFrames = Math.round(fps * duration / 1000.0);
   this.delay = duration / this.maxFrames;
}

/**
 * Creates a default fader for a given element. This function can be used to set BrowserUpdate.highlight
 */
cocoon.ajax.Fader.fade = function(elt) {
   new cocoon.ajax.Fader(elt).start();
}

cocoon.ajax.Fader.prototype.start = function() {
   this.frame = 0;
   this._changeColor();
}

cocoon.ajax.Fader.prototype._changeColor = function() {
    if (this.frame < this.maxFrames) {
        // Schedule the next iteration right now to keep a more accurate timing
        var fader = this;
        setTimeout(function() {fader._changeColor();}, this.delay);
    }
    var newColor = new Array(3);
    for (var channel = 0; channel < 3; channel++) {
        newColor[channel] = Math.floor(
            this.fromColor[channel] * ((this.maxFrames - this.frame) / this.maxFrames) +
            this.toColor[channel] * (this.frame/this.maxFrames)
        );
    }

    this.frame++;
    var color = cocoon.ajax.Fader.rgbToColor(newColor[0], newColor[1], newColor[2]);
    this.element.style.backgroundColor = color;
}

/** Converts a "#RRGGBB" color as an array of 3 ints */
cocoon.ajax.Fader.colorToRgb = function(hex) {
    return [
        parseInt(hex.substr(1,2),16),
        parseInt(hex.substr(3,2),16),
        parseInt(hex.substr(5,2),16) ];
}

/** Converts rgb values to a "#RRGGBB" color */
cocoon.ajax.Fader.rgbToColor = function(r, g, b) {
    r = r.toString(16); if (r.length == 1) r = '0' + r;
    g = g.toString(16); if (g.length == 1) g = '0' + g;
    b = b.toString(16); if (b.length == 1) b = '0' + b;
    return "#" + r + g + b;
}

/** Get the background color of an element */
cocoon.ajax.Fader.getBgColor = function(elt) {
    while(elt) {
        var c;
        if (window.getComputedStyle) c = window.getComputedStyle(elt,null).getPropertyValue("background-color");
        if (elt.currentStyle) c = elt.currentStyle.backgroundColor;
        if ((c != "" && c != "transparent") || elt.tagName == "BODY") { break; }
        elt = elt.parentNode;
    }
    if (c == undefined || c == "" || c == "transparent" || c == "white") c = "#FFFFFF";

    var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
    if (rgb) return this.rgbToColor(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3]));
    return c;
}

//-------------------------------------------------------------------------------------------------
// Blinker used to highlight page areas that have been updated
//-------------------------------------------------------------------------------------------------

cocoon.ajax.Blinker = function(elt, color, hltDelay, normalDelay, blinks) {
    this.element = elt;
    if (!color) color = "#FFFF80"; // yellow
    if (!hltDelay) hltDelay = 100;
    if (!normalDelay) normalDelay = 100;
    if (!blinks) blinks = 2;
    
    this.hltColor = color;
    this.hltDelay = hltDelay;
    this.normalDelay = normalDelay;
    this.normalColor = cocoon.ajax.Fader.getBgColor(elt);
    this.maxBlinks = blinks * 2;
    this.blink = 0;
}

cocoon.ajax.Blinker.prototype.start = function() {
   this.blink = 0;
   this._doBlink();
}

cocoon.ajax.Blinker.blink = function(elt) {
   new cocoon.ajax.Blinker(elt).start();
}

cocoon.ajax.Blinker.prototype._doBlink = function() {
   var hlt = (this.blink % 2 == 0);
   this.element.style.backgroundColor = hlt ? this.hltColor : this.normalColor;;
   if (this.blink <= this.maxBlinks) {
      var blinker = this;
      setTimeout(function() {blinker._doBlink();}, hlt ? this.hltDelay : this.normalDelay);
   }
   this.blink++;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -