252 lines
9.1 KiB
C++
252 lines
9.1 KiB
C++
/*
|
|
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
|
|
* (C) 1999 Antti Koivisto (koivisto@kde.org)
|
|
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
* Portions are Copyright (C) 2002 Netscape Communications Corporation.
|
|
* Other contributors: David Baron <dbaron@fas.harvard.edu>
|
|
*
|
|
* This library 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 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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 library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Alternatively, the document type parsing portions of this file may be used
|
|
* under the terms of either the Mozilla Public License Version 1.1, found at
|
|
* http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
|
|
* License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
|
|
* (the "GPL"), in which case the provisions of the MPL or the GPL are
|
|
* applicable instead of those above. If you wish to allow use of your
|
|
* version of this file only under the terms of one of those two
|
|
* licenses (the MPL or the GPL) and not to allow others to use your
|
|
* version of this file under the LGPL, indicate your decision by
|
|
* deleting the provisions above and replace them with the notice and
|
|
* other provisions required by the MPL or the GPL, as the case may be.
|
|
* If you do not delete the provisions above, a recipient may use your
|
|
* version of this file under any of the LGPL, the MPL or the GPL.
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "HTMLDocument.h"
|
|
|
|
#include "CSSPropertyNames.h"
|
|
#include "CommonVM.h"
|
|
#include "CookieJar.h"
|
|
#include "DOMWindow.h"
|
|
#include "DocumentLoader.h"
|
|
#include "DocumentType.h"
|
|
#include "ElementChildIterator.h"
|
|
#include "FocusController.h"
|
|
#include "Frame.h"
|
|
#include "FrameLoader.h"
|
|
#include "FrameTree.h"
|
|
#include "FrameView.h"
|
|
#include "HTMLBodyElement.h"
|
|
#include "HTMLCollection.h"
|
|
#include "HTMLDocumentParser.h"
|
|
#include "HTMLElementFactory.h"
|
|
#include "HTMLFrameOwnerElement.h"
|
|
#include "HTMLFrameSetElement.h"
|
|
#include "HTMLHtmlElement.h"
|
|
#include "HTMLIFrameElement.h"
|
|
#include "HTMLNames.h"
|
|
#include "Quirks.h"
|
|
#include "ScriptController.h"
|
|
#include "StyleResolver.h"
|
|
#include <wtf/IsoMallocInlines.h>
|
|
#include <wtf/RobinHoodHashSet.h>
|
|
#include <wtf/text/CString.h>
|
|
|
|
namespace WebCore {
|
|
|
|
WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLDocument);
|
|
|
|
using namespace HTMLNames;
|
|
|
|
Ref<HTMLDocument> HTMLDocument::createSynthesizedDocument(Frame& frame, const URL& url)
|
|
{
|
|
return adoptRef(*new HTMLDocument(&frame, frame.settings(), url, HTMLDocumentClass, Synthesized));
|
|
}
|
|
|
|
HTMLDocument::HTMLDocument(Frame* frame, const Settings& settings, const URL& url, DocumentClassFlags documentClasses, unsigned constructionFlags)
|
|
: Document(frame, settings, url, documentClasses | HTMLDocumentClass, constructionFlags)
|
|
{
|
|
clearXMLVersion();
|
|
}
|
|
|
|
HTMLDocument::~HTMLDocument() = default;
|
|
|
|
int HTMLDocument::width()
|
|
{
|
|
updateLayoutIgnorePendingStylesheets();
|
|
RefPtr<FrameView> frameView = view();
|
|
return frameView ? frameView->contentsWidth() : 0;
|
|
}
|
|
|
|
int HTMLDocument::height()
|
|
{
|
|
updateLayoutIgnorePendingStylesheets();
|
|
RefPtr<FrameView> frameView = view();
|
|
return frameView ? frameView->contentsHeight() : 0;
|
|
}
|
|
|
|
Ref<DocumentParser> HTMLDocument::createParser()
|
|
{
|
|
return HTMLDocumentParser::create(*this);
|
|
}
|
|
|
|
// https://html.spec.whatwg.org/multipage/dom.html#dom-document-nameditem
|
|
std::optional<Variant<RefPtr<WindowProxy>, RefPtr<Element>, RefPtr<HTMLCollection>>> HTMLDocument::namedItem(const AtomString& name)
|
|
{
|
|
if (name.isNull() || !hasDocumentNamedItem(*name.impl()))
|
|
return std::nullopt;
|
|
|
|
if (UNLIKELY(documentNamedItemContainsMultipleElements(*name.impl()))) {
|
|
auto collection = documentNamedItems(name);
|
|
ASSERT(collection->length() > 1);
|
|
return Variant<RefPtr<WindowProxy>, RefPtr<Element>, RefPtr<HTMLCollection>> { RefPtr<HTMLCollection> { WTFMove(collection) } };
|
|
}
|
|
|
|
auto& element = *documentNamedItem(*name.impl());
|
|
if (UNLIKELY(is<HTMLIFrameElement>(element))) {
|
|
if (auto domWindow = makeRefPtr(downcast<HTMLIFrameElement>(element).contentWindow()))
|
|
return Variant<RefPtr<WindowProxy>, RefPtr<Element>, RefPtr<HTMLCollection>> { WTFMove(domWindow) };
|
|
}
|
|
|
|
return Variant<RefPtr<WindowProxy>, RefPtr<Element>, RefPtr<HTMLCollection>> { RefPtr<Element> { &element } };
|
|
}
|
|
|
|
Vector<AtomString> HTMLDocument::supportedPropertyNames() const
|
|
{
|
|
if (Quirks::shouldOmitHTMLDocumentSupportedPropertyNames())
|
|
return { };
|
|
|
|
auto properties = m_documentNamedItem.keys();
|
|
// The specification says these should be sorted in document order but this would be expensive
|
|
// and other browser engines do not comply with this part of the specification. For now, just
|
|
// do an alphabetical sort to get consistent results.
|
|
std::sort(properties.begin(), properties.end(), WTF::codePointCompareLessThan);
|
|
return properties;
|
|
}
|
|
|
|
void HTMLDocument::addDocumentNamedItem(const AtomStringImpl& name, Element& item)
|
|
{
|
|
m_documentNamedItem.add(name, item, *this);
|
|
addImpureProperty(AtomString(const_cast<AtomStringImpl*>(&name)));
|
|
}
|
|
|
|
void HTMLDocument::removeDocumentNamedItem(const AtomStringImpl& name, Element& item)
|
|
{
|
|
m_documentNamedItem.remove(name, item);
|
|
}
|
|
|
|
void HTMLDocument::addWindowNamedItem(const AtomStringImpl& name, Element& item)
|
|
{
|
|
m_windowNamedItem.add(name, item, *this);
|
|
}
|
|
|
|
void HTMLDocument::removeWindowNamedItem(const AtomStringImpl& name, Element& item)
|
|
{
|
|
m_windowNamedItem.remove(name, item);
|
|
}
|
|
|
|
bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName& attributeName)
|
|
{
|
|
static const auto caseInsensitiveAttributeSet = makeNeverDestroyed([] {
|
|
// This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
|
|
// Mozilla treats all other values as case-sensitive, thus so do we.
|
|
static const QualifiedName* const names[] = {
|
|
&accept_charsetAttr.get(),
|
|
&acceptAttr.get(),
|
|
&alignAttr.get(),
|
|
&alinkAttr.get(),
|
|
&axisAttr.get(),
|
|
&bgcolorAttr.get(),
|
|
&charsetAttr.get(),
|
|
&checkedAttr.get(),
|
|
&clearAttr.get(),
|
|
&codetypeAttr.get(),
|
|
&colorAttr.get(),
|
|
&compactAttr.get(),
|
|
&declareAttr.get(),
|
|
&deferAttr.get(),
|
|
&dirAttr.get(),
|
|
&disabledAttr.get(),
|
|
&enctypeAttr.get(),
|
|
&faceAttr.get(),
|
|
&frameAttr.get(),
|
|
&hreflangAttr.get(),
|
|
&http_equivAttr.get(),
|
|
&langAttr.get(),
|
|
&languageAttr.get(),
|
|
&linkAttr.get(),
|
|
&mediaAttr.get(),
|
|
&methodAttr.get(),
|
|
&multipleAttr.get(),
|
|
&nohrefAttr.get(),
|
|
&noresizeAttr.get(),
|
|
&noshadeAttr.get(),
|
|
&nowrapAttr.get(),
|
|
&readonlyAttr.get(),
|
|
&relAttr.get(),
|
|
&revAttr.get(),
|
|
&rulesAttr.get(),
|
|
&scopeAttr.get(),
|
|
&scrollingAttr.get(),
|
|
&selectedAttr.get(),
|
|
&shapeAttr.get(),
|
|
&targetAttr.get(),
|
|
&textAttr.get(),
|
|
&typeAttr.get(),
|
|
&valignAttr.get(),
|
|
&valuetypeAttr.get(),
|
|
&vlinkAttr.get(),
|
|
};
|
|
MemoryCompactLookupOnlyRobinHoodHashSet<AtomString> set;
|
|
for (auto* name : names)
|
|
set.add(name->localName());
|
|
return set;
|
|
}());
|
|
|
|
bool isPossibleHTMLAttr = !attributeName.hasPrefix() && attributeName.namespaceURI().isNull();
|
|
return !isPossibleHTMLAttr || !caseInsensitiveAttributeSet.get().contains(attributeName.localName());
|
|
}
|
|
|
|
bool HTMLDocument::isFrameSet() const
|
|
{
|
|
if (!documentElement())
|
|
return false;
|
|
return !!childrenOfType<HTMLFrameSetElement>(*documentElement()).first();
|
|
}
|
|
|
|
Ref<Document> HTMLDocument::cloneDocumentWithoutChildren() const
|
|
{
|
|
return create(nullptr, settings(), url());
|
|
}
|
|
|
|
}
|