File indexing completed on 2024-04-21 04:34:27

0001 /***************************************************************************
0002  *   This file is part of KDevelop                                         *
0003  *   Copyright 2010 Niko Sams <niko.sams@gmail.com>                        *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU Library General Public License as       *
0007  *   published by the Free Software Foundation; either version 2 of the    *
0008  *   License, or (at your option) any later version.                       *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU Library General Public     *
0016  *   License along with this program; if not, write to the                 *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0019  ***************************************************************************/
0020 
0021 #include "htmlparser.h"
0022 
0023 #include "debug.h"
0024 
0025 #include <QXmlStreamReader>
0026 #include <QRegExp>
0027 #include <QBuffer>
0028 
0029 namespace Css {
0030 
0031 HtmlParser::HtmlParser()
0032 {
0033 }
0034 
0035 void HtmlParser::setContents(const QString& contents)
0036 {
0037     m_contents = contents;
0038 }
0039 
0040 QList<HtmlParser::Part> HtmlParser::parse()
0041 {
0042     QList<HtmlParser::Part> ret;
0043     QXmlStreamReader reader(m_contents);
0044     while (!reader.atEnd()) {
0045         if (reader.isStartElement() && reader.name() == "style") {
0046             Part p;
0047             p.kind = Part::StyleElement;
0048             KTextEditor::Cursor start(reader.lineNumber()-1, reader.columnNumber());
0049             KTextEditor::Cursor end;
0050             while (!reader.isEndElement() && !reader.atEnd()) {
0051                 p.contents += reader.text();
0052                 end = KTextEditor::Cursor(reader.lineNumber()-1, reader.columnNumber()-1);
0053                 reader.readNext();
0054             }
0055             p.range = {start, end};
0056             ret << p;
0057         }
0058         if (reader.attributes().hasAttribute("style")) {
0059             Part p;
0060             p.kind = Part::InlineStyle;
0061             QString c = m_contents.left(reader.characterOffset());
0062             static QRegExp rx("<[^<>]+\\sstyle=[\"'](([^<>]*)[\"'][^<>]*>)$");
0063             if (rx.indexIn(c) != -1) {
0064                 qCDebug(KDEV_CSS) << rx.cap(0);
0065                 p.contents = rx.cap(2); //don't use reader.attributes() as it doesn't contain newlines correctly
0066                 KTextEditor::Cursor start;
0067                 start.setLine(reader.lineNumber()-1-rx.cap(1).count('\n'));
0068                 if (!rx.cap(1).contains('\n')) {
0069                     start.setColumn(reader.columnNumber()-rx.cap(1).length());
0070                 } else {
0071                     start.setColumn(rx.cap(1).midRef(rx.cap(1).indexOf('\n')).length());
0072                 }
0073                 KTextEditor::Cursor end;
0074                 end.setLine(start.line() + p.contents.count('\n'));
0075                 if (!p.contents.contains('\n')) {
0076                     end.setColumn(start.column()+p.contents.length());
0077                 } else {
0078                     end.setColumn(p.contents.midRef(p.contents.lastIndexOf('\n')+1).length());
0079                 }
0080                 p.range = {start, end};
0081                 p.tag = reader.name().toString();
0082                 ret << p;
0083             } else {
0084                 qCWarning(KDEV_CSS) << "failed parsing style attribute" << c;
0085             }
0086         }
0087         reader.readNext();
0088     }
0089     return ret;
0090 }
0091 
0092 }