webengine/osswebengine/WebCore/dom/ProcessingInstruction.cpp
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /**
       
     2  * This file is part of the DOM implementation for KDE.
       
     3  *
       
     4  * Copyright (C) 2000 Peter Kelly (pmk@post.com)
       
     5  * Copyright (C) 2006 Apple Computer, Inc.
       
     6  *
       
     7  * This library is free software; you can redistribute it and/or
       
     8  * modify it under the terms of the GNU Library General Public
       
     9  * License as published by the Free Software Foundation; either
       
    10  * version 2 of the License, or (at your option) any later version.
       
    11  *
       
    12  * This library is distributed in the hope that it will be useful,
       
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    15  * Library General Public License for more details.
       
    16  *
       
    17  * You should have received a copy of the GNU Library General Public License
       
    18  * along with this library; see the file COPYING.LIB.  If not, write to
       
    19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    20  * Boston, MA 02110-1301, USA.
       
    21  */
       
    22 #include "config.h"
       
    23 #include "ProcessingInstruction.h"
       
    24 
       
    25 #include "CSSStyleSheet.h"
       
    26 #include "CachedCSSStyleSheet.h"
       
    27 #include "CachedXSLStyleSheet.h"
       
    28 #include "Document.h"
       
    29 #include "DocLoader.h"
       
    30 #include "ExceptionCode.h"
       
    31 #include "Frame.h"
       
    32 #include "FrameLoader.h"
       
    33 #include "XSLStyleSheet.h"
       
    34 #include "XMLTokenizer.h" // for parseAttributes()
       
    35 
       
    36 namespace WebCore {
       
    37 
       
    38 ProcessingInstruction::ProcessingInstruction(Document* doc)
       
    39     : ContainerNode(doc)
       
    40     , m_cachedSheet(0)
       
    41     , m_loading(false)
       
    42 #if ENABLE(XSLT)
       
    43     , m_isXSL(false)
       
    44 #endif
       
    45 {
       
    46 }
       
    47 
       
    48 ProcessingInstruction::ProcessingInstruction(Document* doc, const String& target, const String& data)
       
    49     : ContainerNode(doc)
       
    50     , m_target(target)
       
    51     , m_data(data)
       
    52     , m_cachedSheet(0)
       
    53     , m_loading(false)
       
    54 #if ENABLE(XSLT)
       
    55     , m_isXSL(false)
       
    56 #endif
       
    57 {
       
    58 }
       
    59 
       
    60 ProcessingInstruction::~ProcessingInstruction()
       
    61 {
       
    62     if (m_cachedSheet)
       
    63         m_cachedSheet->deref(this);
       
    64 }
       
    65 
       
    66 void ProcessingInstruction::setData(const String& data, ExceptionCode& ec)
       
    67 {
       
    68     // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
       
    69     if (isReadOnlyNode()) {
       
    70         ec = NO_MODIFICATION_ALLOWED_ERR;
       
    71         return;
       
    72     }
       
    73     m_data = data;
       
    74 }
       
    75 
       
    76 String ProcessingInstruction::nodeName() const
       
    77 {
       
    78     return m_target;
       
    79 }
       
    80 
       
    81 Node::NodeType ProcessingInstruction::nodeType() const
       
    82 {
       
    83     return PROCESSING_INSTRUCTION_NODE;
       
    84 }
       
    85 
       
    86 String ProcessingInstruction::nodeValue() const
       
    87 {
       
    88     return m_data;
       
    89 }
       
    90 
       
    91 void ProcessingInstruction::setNodeValue(const String& nodeValue, ExceptionCode& ec)
       
    92 {
       
    93     // NO_MODIFICATION_ALLOWED_ERR: taken care of by setData()
       
    94     setData(nodeValue, ec);
       
    95 }
       
    96 
       
    97 PassRefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
       
    98 {
       
    99     // ### copy m_localHref
       
   100     return new ProcessingInstruction(document(), m_target, m_data);
       
   101 }
       
   102 
       
   103 // DOM Section 1.1.1
       
   104 bool ProcessingInstruction::childTypeAllowed(NodeType)
       
   105 {
       
   106     return false;
       
   107 }
       
   108 
       
   109 bool ProcessingInstruction::checkStyleSheet()
       
   110 {
       
   111     if (m_target == "xml-stylesheet") {
       
   112         // see http://www.w3.org/TR/xml-stylesheet/
       
   113         // ### support stylesheet included in a fragment of this (or another) document
       
   114         // ### make sure this gets called when adding from javascript
       
   115         bool attrsOk;
       
   116         const HashMap<String, String> attrs = parseAttributes(m_data, attrsOk);
       
   117         if (!attrsOk)
       
   118             return true;
       
   119         HashMap<String, String>::const_iterator i = attrs.find("type");
       
   120         String type;
       
   121         if (i != attrs.end())
       
   122             type = i->second;
       
   123 
       
   124         bool isCSS = type.isEmpty() || type == "text/css";
       
   125 #if ENABLE(XSLT)
       
   126         m_isXSL = (type == "text/xml" || type == "text/xsl" || type == "application/xml" ||
       
   127                    type == "application/xhtml+xml" || type == "application/rss+xml" || type == "application/atom=xml");
       
   128         if (!isCSS && !m_isXSL)
       
   129 #else
       
   130         if (!isCSS)
       
   131 #endif
       
   132             return true;
       
   133 
       
   134         String href = attrs.get("href");
       
   135 
       
   136         if (href.length() > 1) {
       
   137             if (href[0] == '#') {
       
   138                 m_localHref = href.substring(1);
       
   139 #if ENABLE(XSLT)
       
   140                 // We need to make a synthetic XSLStyleSheet that is embedded.  It needs to be able
       
   141                 // to kick off import/include loads that can hang off some parent sheet.
       
   142                 if (m_isXSL) {
       
   143                     m_sheet = new XSLStyleSheet(this, m_localHref, true);
       
   144                     m_loading = false;
       
   145                 }
       
   146                 return !m_isXSL;
       
   147 #endif
       
   148             }
       
   149             else
       
   150             {
       
   151                 // FIXME: some validation on the URL?
       
   152                 if (document()->frame()) {
       
   153                     m_loading = true;
       
   154                     document()->addPendingSheet();
       
   155                     if (m_cachedSheet)
       
   156                         m_cachedSheet->deref(this);
       
   157 #if ENABLE(XSLT)
       
   158                     if (m_isXSL)
       
   159                         m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(document()->completeURL(href));
       
   160                     else
       
   161 #endif
       
   162                     {
       
   163                         String charset = attrs.get("charset");
       
   164                         if (charset.isEmpty())
       
   165                             charset = document()->frame()->loader()->encoding();
       
   166 
       
   167                         m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(document()->completeURL(href), charset);
       
   168                     }
       
   169                     if (m_cachedSheet)
       
   170                         m_cachedSheet->ref(this);
       
   171 #if ENABLE(XSLT)
       
   172                     return !m_isXSL;
       
   173 #endif
       
   174                 }
       
   175             }
       
   176         }
       
   177     }
       
   178     
       
   179     return true;
       
   180 }
       
   181 
       
   182 bool ProcessingInstruction::isLoading() const
       
   183 {
       
   184     if (m_loading)
       
   185         return true;
       
   186     if (!m_sheet)
       
   187         return false;
       
   188     return m_sheet->isLoading();
       
   189 }
       
   190 
       
   191 bool ProcessingInstruction::sheetLoaded()
       
   192 {
       
   193     if (!isLoading()) {
       
   194         document()->removePendingSheet();
       
   195         return true;
       
   196     }
       
   197     return false;
       
   198 }
       
   199 
       
   200 void ProcessingInstruction::setCSSStyleSheet(const String& url, const String& charset, const String& sheet)
       
   201 {
       
   202 #if ENABLE(XSLT)
       
   203     ASSERT(!m_isXSL);
       
   204 #endif
       
   205     m_sheet = new CSSStyleSheet(this, url, charset);
       
   206     parseStyleSheet(sheet);
       
   207 }
       
   208 
       
   209 #if ENABLE(XSLT)
       
   210 void ProcessingInstruction::setXSLStyleSheet(const String& url, const String& sheet)
       
   211 {
       
   212     ASSERT(m_isXSL);
       
   213     m_sheet = new XSLStyleSheet(this, url);
       
   214     parseStyleSheet(sheet);
       
   215 }
       
   216 #endif
       
   217 
       
   218 void ProcessingInstruction::parseStyleSheet(const String& sheet)
       
   219 {
       
   220     m_sheet->parseString(sheet, true);
       
   221     if (m_cachedSheet)
       
   222         m_cachedSheet->deref(this);
       
   223     m_cachedSheet = 0;
       
   224 
       
   225     m_loading = false;
       
   226     m_sheet->checkLoaded();
       
   227 }
       
   228 
       
   229 String ProcessingInstruction::toString() const
       
   230 {
       
   231     String result = "<?";
       
   232     result += m_target;
       
   233     result += " ";
       
   234     result += m_data;
       
   235     result += "?>";
       
   236     return result;
       
   237 }
       
   238 
       
   239 void ProcessingInstruction::setCSSStyleSheet(CSSStyleSheet* sheet)
       
   240 {
       
   241     ASSERT(!m_cachedSheet);
       
   242     ASSERT(!m_loading);
       
   243     m_sheet = sheet;
       
   244 }
       
   245 
       
   246 bool ProcessingInstruction::offsetInCharacters() const
       
   247 {
       
   248     return true;
       
   249 }
       
   250 
       
   251 } // namespace