summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/ImageDocument.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/html/ImageDocument.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/html/ImageDocument.cpp')
-rw-r--r--Source/WebCore/html/ImageDocument.cpp399
1 files changed, 194 insertions, 205 deletions
diff --git a/Source/WebCore/html/ImageDocument.cpp b/Source/WebCore/html/ImageDocument.cpp
index fd4de6490..f1a26d2e4 100644
--- a/Source/WebCore/html/ImageDocument.cpp
+++ b/Source/WebCore/html/ImageDocument.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2010, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -26,79 +26,73 @@
#include "ImageDocument.h"
#include "CachedImage.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
#include "DocumentLoader.h"
#include "EventListener.h"
#include "EventNames.h"
-#include "ExceptionCodePlaceholder.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameView.h"
+#include "HTMLBodyElement.h"
+#include "HTMLHeadElement.h"
#include "HTMLHtmlElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "LocalizedStrings.h"
+#include "MIMETypeRegistry.h"
#include "MainFrame.h"
#include "MouseEvent.h"
-#include "NotImplemented.h"
#include "Page.h"
#include "RawDataDocumentParser.h"
#include "RenderElement.h"
-#include "ResourceBuffer.h"
#include "Settings.h"
namespace WebCore {
using namespace HTMLNames;
-class ImageEventListener : public EventListener {
+#if !PLATFORM(IOS)
+class ImageEventListener final : public EventListener {
public:
- static PassRefPtr<ImageEventListener> create(ImageDocument* document) { return adoptRef(new ImageEventListener(document)); }
- static const ImageEventListener* cast(const EventListener* listener)
- {
- return listener->type() == ImageEventListenerType
- ? static_cast<const ImageEventListener*>(listener)
- : 0;
- }
-
- virtual bool operator==(const EventListener& other) override;
+ static Ref<ImageEventListener> create(ImageDocument& document) { return adoptRef(*new ImageEventListener(document)); }
private:
- ImageEventListener(ImageDocument* document)
+ ImageEventListener(ImageDocument& document)
: EventListener(ImageEventListenerType)
- , m_doc(document)
+ , m_document(document)
{
}
- virtual void handleEvent(ScriptExecutionContext*, Event*) override;
+ bool operator==(const EventListener&) const override;
+ void handleEvent(ScriptExecutionContext*, Event*) override;
- ImageDocument* m_doc;
+ ImageDocument& m_document;
};
-
+#endif
+
class ImageDocumentParser final : public RawDataDocumentParser {
public:
- static PassRefPtr<ImageDocumentParser> create(ImageDocument& document)
+ static Ref<ImageDocumentParser> create(ImageDocument& document)
{
- return adoptRef(new ImageDocumentParser(document));
+ return adoptRef(*new ImageDocumentParser(document));
}
- ImageDocument* document() const
- {
- return toImageDocument(RawDataDocumentParser::document());
- }
-
private:
ImageDocumentParser(ImageDocument& document)
: RawDataDocumentParser(document)
{
}
- virtual void appendBytes(DocumentWriter&, const char*, size_t) override;
- virtual void finish() override;
+ ImageDocument& document() const;
+
+ void appendBytes(DocumentWriter&, const char*, size_t) override;
+ void finish() override;
};
class ImageDocumentElement final : public HTMLImageElement {
public:
- static PassRefPtr<ImageDocumentElement> create(ImageDocument&);
+ static Ref<ImageDocumentElement> create(ImageDocument&);
private:
ImageDocumentElement(ImageDocument& document)
@@ -108,249 +102,247 @@ private:
}
virtual ~ImageDocumentElement();
- virtual void didMoveToNewDocument(Document* oldDocument) override;
+ void didMoveToNewDocument(Document& oldDocument) override;
ImageDocument* m_imageDocument;
};
-inline PassRefPtr<ImageDocumentElement> ImageDocumentElement::create(ImageDocument& document)
+inline Ref<ImageDocumentElement> ImageDocumentElement::create(ImageDocument& document)
{
- return adoptRef(new ImageDocumentElement(document));
+ return adoptRef(*new ImageDocumentElement(document));
}
// --------
-static float pageZoomFactor(const Document* document)
+HTMLImageElement* ImageDocument::imageElement() const
{
- Frame* frame = document->frame();
- return frame ? frame->pageZoomFactor() : 1;
+ return m_imageElement;
}
-void ImageDocumentParser::appendBytes(DocumentWriter&, const char*, size_t)
+LayoutSize ImageDocument::imageSize()
+{
+ ASSERT(m_imageElement);
+ updateStyleIfNeeded();
+ return m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), frame() ? frame()->pageZoomFactor() : 1);
+}
+
+void ImageDocument::updateDuringParsing()
{
- Frame* frame = document()->frame();
- if (!frame->loader().client().allowImage(frame->settings().areImagesEnabled(), document()->url()))
+ if (!settings().areImagesEnabled())
return;
- CachedImage* cachedImage = document()->cachedImage();
- RefPtr<ResourceBuffer> resourceData = frame->loader().documentLoader()->mainResourceData();
- cachedImage->addDataBuffer(resourceData.get());
+ if (!m_imageElement)
+ createDocumentStructure();
+
+ if (RefPtr<SharedBuffer> buffer = loader()->mainResourceData())
+ m_imageElement->cachedImage()->addDataBuffer(*buffer);
- document()->imageUpdated();
+ imageUpdated();
}
-void ImageDocumentParser::finish()
+void ImageDocument::finishedParsing()
{
- if (!isStopped() && document()->imageElement()) {
- CachedImage* cachedImage = document()->cachedImage();
- RefPtr<ResourceBuffer> data = document()->frame()->loader().documentLoader()->mainResourceData();
+ if (!parser()->isStopped() && m_imageElement) {
+ CachedImage& cachedImage = *m_imageElement->cachedImage();
+ RefPtr<SharedBuffer> data = loader()->mainResourceData();
// If this is a multipart image, make a copy of the current part, since the resource data
// will be overwritten by the next part.
- if (document()->frame()->loader().documentLoader()->isLoadingMultipartContent())
+ if (data && loader()->isLoadingMultipartContent())
data = data->copy();
- cachedImage->finishLoading(data.get());
- cachedImage->finish();
-
- cachedImage->setResponse(document()->frame()->loader().documentLoader()->response());
+ cachedImage.finishLoading(data.get());
+ cachedImage.finish();
// Report the natural image size in the page title, regardless of zoom level.
// At a zoom level of 1 the image is guaranteed to have an integer size.
- IntSize size = flooredIntSize(cachedImage->imageSizeForRenderer(document()->imageElement()->renderer(), 1.0f));
+ updateStyleIfNeeded();
+ IntSize size = flooredIntSize(cachedImage.imageSizeForRenderer(m_imageElement->renderer(), 1));
if (size.width()) {
- // Compute the title, we use the decoded filename of the resource, falling
- // back on the (decoded) hostname if there is no path.
- String fileName = decodeURLEscapeSequences(document()->url().lastPathComponent());
- if (fileName.isEmpty())
- fileName = document()->url().host();
- document()->setTitle(imageTitle(fileName, size));
+ // Compute the title. We use the decoded filename of the resource, falling
+ // back on the hostname if there is no path.
+ String name = decodeURLEscapeSequences(url().lastPathComponent());
+ if (name.isEmpty())
+ name = url().host();
+ setTitle(imageTitle(name, size));
}
- document()->imageUpdated();
+ imageUpdated();
}
- document()->finishedParsing();
+ HTMLDocument::finishedParsing();
}
-// --------
+inline ImageDocument& ImageDocumentParser::document() const
+{
+ // Only used during parsing, so document is guaranteed to be non-null.
+ ASSERT(RawDataDocumentParser::document());
+ return downcast<ImageDocument>(*RawDataDocumentParser::document());
+}
-ImageDocument::ImageDocument(Frame* frame, const URL& url)
- : HTMLDocument(frame, url, ImageDocumentClass)
- , m_imageElement(0)
+void ImageDocumentParser::appendBytes(DocumentWriter&, const char*, size_t)
+{
+ document().updateDuringParsing();
+}
+
+void ImageDocumentParser::finish()
+{
+ document().finishedParsing();
+}
+
+ImageDocument::ImageDocument(Frame& frame, const URL& url)
+ : HTMLDocument(&frame, url, ImageDocumentClass)
+ , m_imageElement(nullptr)
, m_imageSizeIsKnown(false)
+#if !PLATFORM(IOS)
, m_didShrinkImage(false)
- , m_shouldShrinkImage(shouldShrinkToFit())
+#endif
+ , m_shouldShrinkImage(frame.settings().shrinksStandaloneImagesToFit() && frame.isMainFrame())
{
- setCompatibilityMode(QuirksMode);
+ setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> ImageDocument::createParser()
+Ref<DocumentParser> ImageDocument::createParser()
{
return ImageDocumentParser::create(*this);
}
void ImageDocument::createDocumentStructure()
{
- RefPtr<Element> rootElement = Document::createElement(htmlTag, false);
- appendChild(rootElement, IGNORE_EXCEPTION);
- toHTMLHtmlElement(rootElement.get())->insertedByParser();
+ auto rootElement = HTMLHtmlElement::create(*this);
+ appendChild(rootElement);
+ rootElement->insertedByParser();
- if (frame())
- frame()->injectUserScripts(InjectAtDocumentStart);
+ frame()->injectUserScripts(InjectAtDocumentStart);
- RefPtr<Element> body = Document::createElement(bodyTag, false);
- body->setAttribute(styleAttr, "margin: 0px;");
-
- rootElement->appendChild(body, IGNORE_EXCEPTION);
-
- RefPtr<ImageDocumentElement> imageElement = ImageDocumentElement::create(*this);
+ // We need a <head> so that the call to setTitle() later on actually has an <head> to append to <title> to.
+ auto head = HTMLHeadElement::create(*this);
+ rootElement->appendChild(head);
+
+ auto body = HTMLBodyElement::create(*this);
+ body->setAttribute(styleAttr, "margin: 0px");
+ if (MIMETypeRegistry::isPDFMIMEType(document().loader()->responseMIMEType()))
+ body->setInlineStyleProperty(CSSPropertyBackgroundColor, "white", CSSPrimitiveValue::CSS_IDENT);
+ rootElement->appendChild(body);
- imageElement->setAttribute(styleAttr, "-webkit-user-select: none");
+ auto imageElement = ImageDocumentElement::create(*this);
+ if (m_shouldShrinkImage)
+ imageElement->setAttribute(styleAttr, "-webkit-user-select:none; display:block; margin:auto;");
+ else
+ imageElement->setAttribute(styleAttr, "-webkit-user-select:none;");
imageElement->setLoadManually(true);
imageElement->setSrc(url().string());
+ imageElement->cachedImage()->setResponse(loader()->response());
+ body->appendChild(imageElement);
- body->appendChild(imageElement, IGNORE_EXCEPTION);
-
- if (shouldShrinkToFit()) {
- // Add event listeners
- RefPtr<EventListener> listener = ImageEventListener::create(this);
- if (DOMWindow* domWindow = this->domWindow())
- domWindow->addEventListener("resize", listener, false);
- imageElement->addEventListener("click", listener.release(), false);
+ if (m_shouldShrinkImage) {
#if PLATFORM(IOS)
// Set the viewport to be in device pixels (rather than the default of 980).
processViewport(ASCIILiteral("width=device-width"), ViewportArguments::ImageDocument);
+#else
+ auto listener = ImageEventListener::create(*this);
+ if (DOMWindow* window = this->domWindow())
+ window->addEventListener("resize", listener.copyRef(), false);
+ imageElement->addEventListener("click", WTFMove(listener), false);
#endif
}
- m_imageElement = imageElement.get();
+ m_imageElement = imageElement.ptr();
}
-float ImageDocument::scale() const
+void ImageDocument::imageUpdated()
{
+ ASSERT(m_imageElement);
+
+ if (m_imageSizeIsKnown)
+ return;
+
+ LayoutSize imageSize = this->imageSize();
+ if (imageSize.isEmpty())
+ return;
+
+ m_imageSizeIsKnown = true;
+
+ if (m_shouldShrinkImage) {
#if PLATFORM(IOS)
- // On iOS big images are subsampled to make them smaller. So, don't resize them.
- return 1;
+ FloatSize screenSize = page()->chrome().screenSize();
+ if (imageSize.width() > screenSize.width())
+ processViewport(String::format("width=%u", static_cast<unsigned>(imageSize.width().toInt())), ViewportArguments::ImageDocument);
+ if (page())
+ page()->chrome().client().imageOrMediaDocumentSizeChanged(IntSize(imageSize.width(), imageSize.height()));
#else
+ // Call windowSizeChanged for its side effect of sizing the image.
+ windowSizeChanged();
+#endif
+ }
+}
+
+#if !PLATFORM(IOS)
+float ImageDocument::scale()
+{
if (!m_imageElement)
return 1;
- FrameView* view = frame()->view();
+ FrameView* view = this->view();
if (!view)
return 1;
- LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
- LayoutSize windowSize = LayoutSize(view->width(), view->height());
+ LayoutSize imageSize = this->imageSize();
- float widthScale = static_cast<float>(windowSize.width()) / imageSize.width();
- float heightScale = static_cast<float>(windowSize.height()) / imageSize.height();
+ IntSize viewportSize = view->visibleSize();
+ float widthScale = viewportSize.width() / imageSize.width().toFloat();
+ float heightScale = viewportSize.height() / imageSize.height().toFloat();
return std::min(widthScale, heightScale);
-#endif
}
void ImageDocument::resizeImageToFit()
{
-#if PLATFORM(IOS)
- // On iOS big images are subsampled to make them smaller. So, don't resize them.
-#else
if (!m_imageElement)
return;
- LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
+ LayoutSize imageSize = this->imageSize();
float scale = this->scale();
m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomIn);
-#endif
-}
-
-void ImageDocument::imageClicked(int x, int y)
-{
-#if PLATFORM(IOS)
- // On iOS big images are subsampled to make them smaller. So, don't resize them.
- UNUSED_PARAM(x);
- UNUSED_PARAM(y);
-#else
- if (!m_imageSizeIsKnown || imageFitsInWindow())
- return;
-
- m_shouldShrinkImage = !m_shouldShrinkImage;
-
- if (m_shouldShrinkImage)
- windowSizeChanged();
- else {
- restoreImageSize();
-
- updateLayout();
-
- float scale = this->scale();
-
- int scrollX = static_cast<int>(x / scale - (float)frame()->view()->width() / 2);
- int scrollY = static_cast<int>(y / scale - (float)frame()->view()->height() / 2);
-
- frame()->view()->setScrollPosition(IntPoint(scrollX, scrollY));
- }
-#endif
-}
-
-void ImageDocument::imageUpdated()
-{
- ASSERT(m_imageElement);
-
- if (m_imageSizeIsKnown)
- return;
-
- if (m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this)).isEmpty())
- return;
-
- m_imageSizeIsKnown = true;
-
- if (shouldShrinkToFit()) {
- // Force resizing of the image
- windowSizeChanged();
- }
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
}
void ImageDocument::restoreImageSize()
{
if (!m_imageElement || !m_imageSizeIsKnown)
return;
-
- LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
- m_imageElement->setWidth(imageSize.width());
- m_imageElement->setHeight(imageSize.height());
-
+
+ LayoutSize imageSize = this->imageSize();
+ m_imageElement->setWidth(imageSize.width().toUnsigned());
+ m_imageElement->setHeight(imageSize.height().toUnsigned());
+
if (imageFitsInWindow())
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
-
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
+
m_didShrinkImage = false;
}
-bool ImageDocument::imageFitsInWindow() const
+bool ImageDocument::imageFitsInWindow()
{
if (!m_imageElement)
return true;
- FrameView* view = frame()->view();
+ FrameView* view = this->view();
if (!view)
return true;
- LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
-#if PLATFORM(IOS)
- LayoutSize windowSize = view->contentsToScreen(view->visibleContentRect()).size();
-#else
- LayoutSize windowSize = LayoutSize(view->width(), view->height());
-#endif
- return imageSize.width() <= windowSize.width() && imageSize.height() <= windowSize.height();
+ LayoutSize imageSize = this->imageSize();
+ IntSize viewportSize = view->visibleSize();
+ return imageSize.width() <= viewportSize.width() && imageSize.height() <= viewportSize.height();
}
+
void ImageDocument::windowSizeChanged()
{
if (!m_imageElement || !m_imageSizeIsKnown)
@@ -358,32 +350,18 @@ void ImageDocument::windowSizeChanged()
bool fitsInWindow = imageFitsInWindow();
-#if PLATFORM(IOS)
- if (fitsInWindow)
- return;
-
- LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
- LayoutRect visibleScreenSize = frame()->view()->contentsToScreen(frame()->view()->visibleContentRect());
-
- float widthScale = static_cast<float>(visibleScreenSize.width()) / imageSize.width();
- float heightScale = static_cast<float>(visibleScreenSize.height()) / imageSize.height();
- if (widthScale < heightScale)
- processViewport(String::format("width=%d", imageSize.width().toInt()), ViewportArguments::ImageDocument);
- else
- processViewport(String::format("width=%d", static_cast<int>(1.0f + (1.0f - heightScale)) * imageSize.width().toInt()), ViewportArguments::ImageDocument);
-#else
// If the image has been explicitly zoomed in, restore the cursor if the image fits
// and set it to a zoom out cursor if the image doesn't fit
if (!m_shouldShrinkImage) {
if (fitsInWindow)
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
return;
}
if (m_didShrinkImage) {
- // If the window has been resized so that the image fits, restore the image size
+ // If the window has been resized so that the image fits, restore the image size,
// otherwise update the restored image size.
if (fitsInWindow)
restoreImageSize();
@@ -396,38 +374,49 @@ void ImageDocument::windowSizeChanged()
m_didShrinkImage = true;
}
}
-#endif
-}
-
-CachedImage* ImageDocument::cachedImage()
-{
- if (!m_imageElement)
- createDocumentStructure();
-
- return m_imageElement->cachedImage();
}
-bool ImageDocument::shouldShrinkToFit() const
+void ImageDocument::imageClicked(int x, int y)
{
- return frame()->settings().shrinksStandaloneImagesToFit() && frame()->isMainFrame();
+ if (!m_imageSizeIsKnown || imageFitsInWindow())
+ return;
+
+ m_shouldShrinkImage = !m_shouldShrinkImage;
+
+ if (m_shouldShrinkImage) {
+ // Call windowSizeChanged for its side effect of sizing the image.
+ windowSizeChanged();
+ } else {
+ restoreImageSize();
+
+ updateLayout();
+
+ float scale = this->scale();
+
+ IntSize viewportSize = view()->visibleSize();
+ int scrollX = static_cast<int>(x / scale - viewportSize.width() / 2.0f);
+ int scrollY = static_cast<int>(y / scale - viewportSize.height() / 2.0f);
+
+ view()->setScrollPosition(IntPoint(scrollX, scrollY));
+ }
}
void ImageEventListener::handleEvent(ScriptExecutionContext*, Event* event)
{
if (event->type() == eventNames().resizeEvent)
- m_doc->windowSizeChanged();
- else if (event->type() == eventNames().clickEvent && event->isMouseEvent()) {
- MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
- m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
+ m_document.windowSizeChanged();
+ else if (event->type() == eventNames().clickEvent && is<MouseEvent>(*event)) {
+ MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
+ m_document.imageClicked(mouseEvent.offsetX(), mouseEvent.offsetY());
}
}
-bool ImageEventListener::operator==(const EventListener& listener)
+bool ImageEventListener::operator==(const EventListener& other) const
{
- if (const ImageEventListener* imageEventListener = ImageEventListener::cast(&listener))
- return m_doc == imageEventListener->m_doc;
- return false;
+ // All ImageEventListener objects compare as equal; OK since there is only one per document.
+ return other.type() == ImageEventListenerType;
}
+#endif
// --------
@@ -437,11 +426,11 @@ ImageDocumentElement::~ImageDocumentElement()
m_imageDocument->disconnectImageElement();
}
-void ImageDocumentElement::didMoveToNewDocument(Document* oldDocument)
+void ImageDocumentElement::didMoveToNewDocument(Document& oldDocument)
{
if (m_imageDocument) {
m_imageDocument->disconnectImageElement();
- m_imageDocument = 0;
+ m_imageDocument = nullptr;
}
HTMLImageElement::didMoveToNewDocument(oldDocument);
}