PassRefPtrWillBeRawPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
    const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, LocalFrame* frame)
{
    RefPtrWillBeRawPtr<Document> ownerDocument(sourceNode->document());
    bool sourceIsDocument = (sourceNode == ownerDocument.get());
    String documentSource = sourceString;

    RefPtrWillBeRawPtr<Document> result = nullptr;
    DocumentInit init(sourceIsDocument ? ownerDocument->url() : KURL(), frame);

    bool forceXHTML = sourceMIMEType == "text/plain";
    if (forceXHTML)
        transformTextStringToXHTMLDocumentString(documentSource);

    if (frame) {
        RefPtrWillBeRawPtr<Document> oldDocument = frame->document();
        oldDocument->detach();
        result = frame->localDOMWindow()->installNewDocument(sourceMIMEType, init, forceXHTML);

        // Before parsing, we need to save & detach the old document and get the new document
        // in place. We have to do this only if we're rendering the result document.
        if (FrameView* view = frame->view())
            view->clear();

        if (oldDocument) {
            DocumentXSLT::from(*result).setTransformSourceDocument(oldDocument.get());
            result->updateSecurityOrigin(oldDocument->securityOrigin());
            result->setCookieURL(oldDocument->cookieURL());

            RefPtr<ContentSecurityPolicy> csp = ContentSecurityPolicy::create();
            csp->copyStateFrom(oldDocument->contentSecurityPolicy());
            result->initContentSecurityPolicy(csp);
        }
    } else {
        result = LocalDOMWindow::createDocument(sourceMIMEType, init, forceXHTML);
    }

    DocumentEncodingData data;
    data.setEncoding(sourceEncoding.isEmpty() ? UTF8Encoding() : WTF::TextEncoding(sourceEncoding));
    result->setEncodingData(data);
    result->setContent(documentSource);

    return result.release();
}