Package org.itsnat.impl.core.resp.shared.html

Source Code of org.itsnat.impl.core.resp.shared.html.ResponseDelegateHTMLLoadDocMSIEOldImpl

/*
  ItsNat Java Web Application Framework
  Copyright (C) 2007-2011 Jose Maria Arranz Santamaria, Spanish citizen

  This software is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 3 of
  the License, or (at your option) any later version.
  This software 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
  Lesser General Public License for more details. You should have received
  a copy of the GNU Lesser General Public License along with this program.
  If not, see <http://www.gnu.org/licenses/>.
*/

package org.itsnat.impl.core.resp.shared.html;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.itsnat.impl.core.browser.BrowserMSIEOld;
import org.itsnat.impl.core.doc.ItsNatHTMLDocumentImpl;
import org.itsnat.impl.core.domutil.DOMUtilHTML;
import org.itsnat.impl.core.domutil.NamespaceUtil;
import org.itsnat.impl.core.resp.ResponseLoadStfulDocumentValid;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.html.HTMLBodyElement;
import org.w3c.dom.html.HTMLDocument;
import org.w3c.dom.html.HTMLHeadElement;

/**
*
* @author jmarranz
*/
public class ResponseDelegateHTMLLoadDocMSIEOldImpl extends ResponseDelegateHTMLLoadDocImpl
{
    public ResponseDelegateHTMLLoadDocMSIEOldImpl(ResponseLoadStfulDocumentValid response)
    {
        super(response);
    }

    public static ResponseDelegateHTMLLoadDocMSIEOldImpl createResponseDelegateHTMLLoadDocMSIEOld(BrowserMSIEOld browser,ResponseLoadStfulDocumentValid responseParent)
    {
        return new ResponseDelegateHTMLLoadDocMSIEOldImpl(responseParent);       
    }

    protected LinkedList<Element> fixOtherNSElementsInHTMLFindRootElems()
    {
        return null; // Nada que hacer, s�lo W3C
    }

    protected LinkedList<Attr> fixOtherNSElementsInHTMLSaveValidNames(LinkedList<Element> otherNSRootElemsInHTML)
    {
        return null; // Nada que hacer, s�lo W3C
    }

    protected void fixOtherNSElementsInHTMLCleanAuxAttribs(LinkedList<Attr> attribs)
    {
        // Nada que hacer, s�lo W3C
    }

    protected void fixOtherNSElementsInHTMLGenCode(LinkedList<Element> otherNSElemsInHTML)
    {
        // Nada que hacer, s�lo W3C
    }
    public String getJavaScriptDocumentName()
    {
        return "MSIEOldHTMLDocument";
    }
   
    @Override
    public String serializeDocument()
    {
        ItsNatHTMLDocumentImpl itsNatDoc = getItsNatHTMLDocument();
        HTMLDocument doc = itsNatDoc.getHTMLDocument();
        Map<String,Attr> attrNamespaces = processTreeNamespaces(doc);

        String docMarkup = super.serializeDocument();

        restoreHTMLElemAttrNamespaces(doc,attrNamespaces);

        // Al serializar siempre se genera un finalizador </embed> para los <embed>
        // En MSIE 6,7,8 </embed> es convertido en un elemento desconocido.
        // http://msdn.microsoft.com/en-us/library/ms535245%28VS.85%29.aspx#

        // docMarkup = docMarkup.replaceAll("></embed>","/>");

        return docMarkup;
    }

    protected Map<String,Attr> processTreeNamespaces(HTMLDocument doc)
    {
        // MSIE 6 y 7 tienen un soporte muy pobre de namespaces pero algo hay
        // En tiempo de carga para que el namespace de un elemento como <svg:svg>...</svg:svg>
        // sea reconocido, el prefijo "svg" debe estar declarado como namespace en <html> y s�lo en este
        // elemento.
        // Lo que hacemos es recorrer todos los elementos del documento
        // que tengan declaraciones tipo xmlns:prefijo="..." y compiar dicha
        // declaraci�n a <html>, de esta manera conseguimos que plugins como el Adobe SVG Viewer en su modo "SVG inline"
        // o en general "Behaviors" asociados namespaces puedan funcionar con elementos tipo <svg:svg> ....</svg:svg>
        // devolviendo en la propiedad tagUrn el namespace y en scopeName el prefijo.
        // Esto no funcionar� obviamente en casos peculiares de namespaces anidados
        // o de uso del mismo prefijo para diferentes URIs en diferentes lugares, pero los casos habituales funcionar�n.
        // No nos preocupan los namespaces de los nodos cacheados pues estos
        // no son activos en el servidor.

        Map<String,Attr> attrNamespaces = null;

        // Copiamos en la colecci�n attrNamespaces las declaraciones que ya existan
        // de namespaces tipo xmlns:prefijo para restaurar como estaba al final.
        Element html = doc.getDocumentElement();
        if (html.hasAttributes())
        {
            NamedNodeMap attribs = html.getAttributes();
            for(int i = 0; i < attribs.getLength(); i++)
            {
                Attr attr = (Attr)attribs.item(i);
                String prefix = attr.getPrefix();
                if ((prefix != null) && prefix.equals("xmlns"))
                {
                    if (attrNamespaces == null) attrNamespaces = new HashMap<String,Attr>();
                    attrNamespaces.put(attr.getName(),attr);
                }
            }
        }
        HTMLHeadElement head = DOMUtilHTML.getHTMLHead(doc);
        processTreeNamespaces(head); // head puede ser null
        HTMLBodyElement body = (HTMLBodyElement)doc.getBody();
        processTreeNamespaces(body);
        return attrNamespaces;
    }

    protected void processTreeNamespaces(Node node)
    {
        if (node == null) return;
        if (node.getNodeType() != Node.ELEMENT_NODE) return;

        Element elem = (Element)node;
        processNamespacesOfElement(elem);

        if (elem.hasChildNodes())
        {
            Node child = elem.getFirstChild();
            while(child != null)
            {
                processTreeNamespaces(child);

                child = child.getNextSibling();
            }
        }
    }

    protected void processNamespacesOfElement(Element elem)
    {
        if (elem.hasAttributes())
        {
            NamedNodeMap attribs = elem.getAttributes();
            for(int i = 0; i < attribs.getLength(); i++)
            {
                Attr attr = (Attr)attribs.item(i);
                String prefix = attr.getPrefix();
                if ((prefix != null) && prefix.equals("xmlns"))
                {
                    // No consideramos el caso de xmlns:itsnat="itsnat namespace"
                    // porque nunca enviaremos elementos al cliente tal y como
                    // <itsnat:nombre>... pues estos se procesan y se substituyen en el servidor.
                    // Evitando este caso, evitamos poner en <html> la declaraci�n xmlns:itsnat que no
                    // ha hecho el programador y que puede confundirle.
                    if (NamespaceUtil.isItsNatNamespace(attr.getValue()))
                        continue;
                    Element html = elem.getOwnerDocument().getDocumentElement();
                    html.setAttributeNS(NamespaceUtil.XMLNS_NAMESPACE,attr.getName(),attr.getValue());
                }
            }
        }
    }

    protected static void restoreHTMLElemAttrNamespaces(Document doc,Map<String,Attr> attrNamespaces)
    {
        // Restauramos el estado original del DOM
        // attrNamespaces puede ser null
        Element html = doc.getDocumentElement();

        if (attrNamespaces != null)
        {
            for(Map.Entry<String,Attr> entry : attrNamespaces.entrySet())
            {
                String name = entry.getKey(); // xmlns:algo
                Attr value = entry.getValue();
                html.setAttributeNS(NamespaceUtil.XMLNS_NAMESPACE,name,value.getValue());
            }
        }

        // Ahora eliminamos aquellos atributos que no est�n en attrNamespaces
        if (html.hasAttributes())
        {
            NamedNodeMap attribs = html.getAttributes();
            // ���Cuidado la longitud de la colecci�n cambia !!!
            for(int i = 0; i < attribs.getLength(); )
            {
                Attr attr = (Attr)attribs.item(i);
                String prefix = attr.getPrefix();
                if ((prefix != null) && prefix.equals("xmlns"))
                {
                    // Si attrNamespaces es nulo es que obviamente este atributo no estaba en el elemento original
                    if ((attrNamespaces == null) || !attrNamespaces.containsKey(attr.getName()))
                        html.removeAttributeNode(attr);
                    else i++;
                }
                else i++;
            }
        }

    }
}
TOP

Related Classes of org.itsnat.impl.core.resp.shared.html.ResponseDelegateHTMLLoadDocMSIEOldImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.