From 3e83177a1c8836d1b740b9b586acd3b1d268cf6e Mon Sep 17 00:00:00 2001 From: Nicholas Paun Date: Thu, 2 Jan 2025 15:55:37 -0800 Subject: [PATCH] Revert "Revert "html-rewriter: Support streaming content replacements (#3211)"" This reverts commit 010d64acbce5aff0f0af3ca69be79cc2c3cc7e2d. --- deps/rust/cargo.bzl | 8 +- src/workerd/api/html-rewriter.c++ | 297 +++++++++++++++--- src/workerd/api/html-rewriter.h | 80 +++-- src/workerd/api/tests/htmlrewriter-test.js | 150 +++++++++ .../generated-snapshot/2021-11-03/index.d.ts | 55 +++- types/generated-snapshot/2021-11-03/index.ts | 55 +++- .../generated-snapshot/2022-01-31/index.d.ts | 55 +++- types/generated-snapshot/2022-01-31/index.ts | 55 +++- .../generated-snapshot/2022-03-21/index.d.ts | 55 +++- types/generated-snapshot/2022-03-21/index.ts | 55 +++- .../generated-snapshot/2022-08-04/index.d.ts | 55 +++- types/generated-snapshot/2022-08-04/index.ts | 55 +++- .../generated-snapshot/2022-10-31/index.d.ts | 55 +++- types/generated-snapshot/2022-10-31/index.ts | 55 +++- .../generated-snapshot/2022-11-30/index.d.ts | 55 +++- types/generated-snapshot/2022-11-30/index.ts | 55 +++- .../generated-snapshot/2023-03-01/index.d.ts | 55 +++- types/generated-snapshot/2023-03-01/index.ts | 55 +++- .../generated-snapshot/2023-07-01/index.d.ts | 55 +++- types/generated-snapshot/2023-07-01/index.ts | 55 +++- .../experimental/index.d.ts | 55 +++- .../generated-snapshot/experimental/index.ts | 55 +++- types/generated-snapshot/oldest/index.d.ts | 55 +++- types/generated-snapshot/oldest/index.ts | 55 +++- 24 files changed, 1320 insertions(+), 315 deletions(-) diff --git a/deps/rust/cargo.bzl b/deps/rust/cargo.bzl index 0d3fb541a6a..b7d40f38304 100644 --- a/deps/rust/cargo.bzl +++ b/deps/rust/cargo.bzl @@ -16,10 +16,10 @@ PACKAGES = { "cxx": crate.spec(version = "1"), "cxxbridge-cmd": crate.spec(version = "1"), "flate2": crate.spec(version = "1"), - "lol_html_c_api": crate.spec( - git = "https://github.com/cloudflare/lol-html.git", - rev = "cac9f2f59aea8ad803286b0aae0d667926f441c7", - ), + # Commit hash refers to lol-html v2.1.0. We then access the nested lol_html_c_api crate within. + # TODO(npaun): The next release of lol-html could change the way we access the nested crate. + # Check once https://github.com/cloudflare/lol-html/pull/247 is in a release. + "lol_html_c_api": crate.spec(git = "https://github.com/cloudflare/lol-html.git", rev = "cac9f2f59aea8ad803286b0aae0d667926f441c7"), "nix": crate.spec(version = "0"), "pico-args": crate.spec(version = "0"), "proc-macro2": crate.spec(version = "1"), diff --git a/src/workerd/api/html-rewriter.c++ b/src/workerd/api/html-rewriter.c++ index 25b25da8e1e..f08b5ba5b5b 100644 --- a/src/workerd/api/html-rewriter.c++ +++ b/src/workerd/api/html-rewriter.c++ @@ -235,6 +235,12 @@ class Rewriter final: public WritableStreamSink { // Implementation for `Element::onEndTag` to avoid exposing private details of Rewriter. void onEndTag(lol_html_element_t* element, ElementCallbackFunction&& callback); + lol_html_streaming_handler_t registerReplacer(jsg::Ref content, bool isHtml); + + ~Rewriter() { + KJ_ASSERT(registeredReplacers.size() == 0, "Some replacers were leaked by lol-html"); + } + private: // Wait for the write promise (if any) produced by our `output()` callback, then, if there is a // stored exception, abort the wrapped WritableStreamSink with it, then return the exception. @@ -266,6 +272,15 @@ class Rewriter final: public WritableStreamSink { friend class ::workerd::api::HTMLRewriter; + // Keeps track of streams currently being used as replacement content for tokens. + // lol-html will invoke replacerThunk with a pointer to the RegisteredReplacer to be used. + class RegisteredReplacer { + public: + Rewriter& rewriter; + bool isHtml; + jsg::Ref stream; + }; + struct RegisteredHandler { // A back-reference to the rewriter which owns this particular registered handler. Rewriter& rewriter; @@ -295,6 +310,15 @@ class Rewriter final: public WritableStreamSink { // used again. void removeEndTagHandler(RegisteredHandler& registration); + // Field stores a list of readable streams that are being used by lol-html for replacements + kj::HashMap> registeredReplacers; + + static int replacerThunk(lol_html_streaming_sink_t* sink, void* userData); + kj::Promise replacerThunkPromise( + lol_html_streaming_sink_t* sink, RegisteredReplacer& registration); + int replacerThunkImpl(lol_html_streaming_sink_t* sink, RegisteredReplacer& registration); + static void removeRegisteredReplacer(void* userData); + // Must be constructed AFTER the registered handler vector, since the function which constructs // this (buildRewriter()) modifies that vector. kj::Own rewriter; @@ -579,6 +603,122 @@ kj::Promise Rewriter::thunkPromise(CType* content, RegisteredHandler& regi }); } +lol_html_streaming_handler_t Rewriter::registerReplacer( + jsg::Ref content, bool isHtml) { + auto replacer = kj::heap(*this, isHtml, kj::mv(content)); + auto userData = replacer.get(); + registeredReplacers.insert(userData, kj::mv(replacer)); + + return { + .user_data = userData, + .write_all_callback = Rewriter::replacerThunk, + .drop_callback = Rewriter::removeRegisteredReplacer, + }; +} + +// Adapter that allows pumping a ReadableStream to a pre-established lol_html +// streaming sink, named `sink`. Writes of arbitrary bytes and sizes are allowed, +// but the content must be valid UTF-8 or lol_html will reject it. +class ReplacerStreamSink final: public WritableStreamSink { + public: + ReplacerStreamSink(lol_html_streaming_sink_t* sink, bool isHtml): sink(sink), isHtml(isHtml) {} + + kj::Promise write(kj::ArrayPtr buffer) override KJ_WARN_UNUSED_RESULT { + auto err = lol_html_streaming_sink_write_utf8_chunk( + sink, buffer.asChars().begin(), buffer.size(), isHtml); + if (err != 0) { + return getLastError(); + } + + return kj::READY_NOW; + } + + kj::Promise write(kj::ArrayPtr> pieces) override { + for (auto bytes: pieces) { + auto err = lol_html_streaming_sink_write_utf8_chunk( + sink, bytes.asChars().begin(), bytes.size(), isHtml); + if (err != 0) { + return getLastError(); + } + } + + return kj::READY_NOW; + } + + kj::Promise end() override KJ_WARN_UNUSED_RESULT { + // Nothing specific needs to be done to tell lol_html we're done writing the stream + return kj::READY_NOW; + } + + void abort(kj::Exception reason) override { + // Nothing specific needs to be done. The rewriter will be poisoned in replacerThunkImpl, + // and lol_html will bubble up the error through to write. + } + + private: + lol_html_streaming_sink_t* sink; + bool isHtml; +}; + +int Rewriter::replacerThunk(lol_html_streaming_sink_t* sink, void* userData) { + auto& registration = *reinterpret_cast(userData); + return registration.rewriter.replacerThunkImpl(sink, registration); +} + +int Rewriter::replacerThunkImpl( + lol_html_streaming_sink_t* sink, RegisteredReplacer& registeredHandler) { + if (isPoisoned()) { + // Handlers disabled due to exception. + KJ_LOG(ERROR, "poisoned rewriter should not be able to call handlers"); + return -1; + } + + try { + KJ_IF_SOME(exception, kj::runCatchingExceptions([&] { + // V8 has a thread local pointer that points to where the stack limit is on this thread which + // is tested for overflows when we enter any JS code. However since we're running in a fiber + // here, we're in an entirely different stack that V8 doesn't know about, so it gets confused + // and may think we've overflowed our stack. evalLater will run thunkPromise on the main stack + // to keep V8 from getting confused. + auto promise = kj::evalLater([&]() { return replacerThunkPromise(sink, registeredHandler); }); + promise.wait(KJ_ASSERT_NONNULL(maybeWaitScope)); + })) { + // Exception in handler. We need to abort the streaming parser, but can't do so just yet: we + // need to unwind the stack because we're probably still inside a cool_thing_rewriter_write(). + // We can't unwind with an exception across the Rust/C++ boundary, so instead we'll keep this + // exception around and disable all later handlers + maybePoison(kj::mv(exception)); + return -1; + } + } catch (kj::CanceledException) { + // The fiber is being canceled. Same as runCatchingExceptions, we need to abort the parser, + // but can't since we're still inside cool_thing_rewriter_write(). This isn't handled by + // runCatchingExceptions since CanceledException isn't a kj exception, and we wouldn't want + // runCatchingExceptions to handle it anyway. We set canceled to true and once we leave Rust, + // we rethrow it to properly cancel the fiber. + canceled = true; + return -1; + } + return 0; +} + +kj::Promise Rewriter::replacerThunkPromise( + lol_html_streaming_sink_t* sink, RegisteredReplacer& registration) { + return ioContext.run([this, sink, ®istration](Worker::Lock& lock) -> kj::Promise { + jsg::AsyncContextFrame::Scope asyncContextScope(lock, maybeAsyncContext); + + auto streamSink = kj::heap(sink, registration.isHtml); + return ioContext.waitForDeferredProxy( + registration.stream->pumpTo(lock, kj::mv(streamSink), true)); + }); +} + +void Rewriter::removeRegisteredReplacer(void* userData) { + auto& registration = *reinterpret_cast(userData); + KJ_REQUIRE(registration.rewriter.registeredReplacers.erase(userData), + "Tried to remove replacer that was not registered"); +} + void Rewriter::onEndTag(lol_html_element_t* element, ElementCallbackFunction&& callback) { auto registeredHandler = Rewriter::RegisteredHandler{*this, kj::mv(callback)}; // NOTE: this gets freed in `thunkPromise` above. @@ -608,6 +748,7 @@ void Rewriter::outputImpl(kj::ArrayPtr buffer) { } auto bufferCopy = kj::heapArray(buffer); + KJ_IF_SOME(wp, writePromise) { writePromise = wp.then([this, bufferCopy = kj::mv(bufferCopy)]() mutable { return inner->write(bufferCopy.asPtr()).attach(kj::mv(bufferCopy)); @@ -617,6 +758,40 @@ void Rewriter::outputImpl(kj::ArrayPtr buffer) { } } +// ======================================================================================= +// HTMLRewriter::Token::ImplBase + +template +HTMLRewriter::Token::ImplBase::ImplBase(CType& element, Rewriter& rewriter) + : element(element), + rewriter(rewriter) {} +template +HTMLRewriter::Token::ImplBase::~ImplBase() noexcept(false) {} +template +template +void HTMLRewriter::Token::ImplBase::rewriteContentGeneric( + Content content, jsg::Optional options) { + auto isHtml = options.orDefault({}).html.orDefault(false); + + KJ_SWITCH_ONEOF(content) { + KJ_CASE_ONEOF(stringContent, kj::String) { + check(Func(&element, stringContent.cStr(), stringContent.size(), isHtml)); + } + + KJ_CASE_ONEOF(streamContent, jsg::Ref) { + auto handler = rewriter.registerReplacer(kj::mv(streamContent), isHtml); + check(StreamingFunc(&element, &handler)); + } + + KJ_CASE_ONEOF(responseContent, jsg::Ref) { + KJ_IF_SOME(body, responseContent->getBody()) { + auto handler = rewriter.registerReplacer(kj::mv(body), isHtml); + check(StreamingFunc(&element, &handler)); + } + // Otherwise if no body, there is no replacement to make + } + } +} // ======================================================================================= // Element @@ -690,31 +865,53 @@ jsg::Ref Element::removeAttribute(kj::String name) { } namespace { - kj::String unwrapContent(Content content) { return kj::mv(JSG_REQUIRE_NONNULL(content.tryGet(), TypeError, - "Replacing HTML content using a ReadableStream or Response object is not " + "Replacing content in HTML comments using a ReadableStream or Response object is not " "implemented. You must provide a string.")); } - } // namespace -#define DEFINE_CONTENT_REWRITER_FUNCTION(camel, snake) \ - jsg::Ref Element::camel(Content content, jsg::Optional options) { \ - auto stringContent = unwrapContent(kj::mv(content)); \ - check(lol_html_element_##snake(&checkToken(impl).element, stringContent.cStr(), \ - stringContent.size(), options.orDefault({}).html.orDefault(false))); \ - return JSG_THIS; \ - } +jsg::Ref Element::before(Content content, jsg::Optional options) { + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), options); + return JSG_THIS; +} + +jsg::Ref Element::after(Content content, jsg::Optional options) { + checkToken(impl).rewriteContentGeneric( + kj::mv(content), options); + return JSG_THIS; +} + +jsg::Ref Element::prepend(Content content, jsg::Optional options) { + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), options); + return JSG_THIS; +} -DEFINE_CONTENT_REWRITER_FUNCTION(before, before) -DEFINE_CONTENT_REWRITER_FUNCTION(after, after) -DEFINE_CONTENT_REWRITER_FUNCTION(prepend, prepend) -DEFINE_CONTENT_REWRITER_FUNCTION(append, append) -DEFINE_CONTENT_REWRITER_FUNCTION(replace, replace) -DEFINE_CONTENT_REWRITER_FUNCTION(setInnerContent, set_inner_content) +jsg::Ref Element::append(Content content, jsg::Optional options) { + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), options); + return JSG_THIS; +} -#undef DEFINE_CONTENT_REWRITER_FUNCTION +jsg::Ref Element::replace(Content content, jsg::Optional options) { + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), options); + return JSG_THIS; +} + +jsg::Ref Element::setInnerContent(Content content, jsg::Optional options) { + checkToken(impl) + .rewriteContentGeneric(kj::mv(content), options); + return JSG_THIS; +} jsg::Ref Element::remove() { lol_html_element_remove(&checkToken(impl).element); @@ -731,39 +928,38 @@ void Element::onEndTag(ElementCallbackFunction&& callback) { knownImpl.rewriter.onEndTag(&knownImpl.element, kj::mv(callback)); } -EndTag::EndTag(CType& endTag, Rewriter&): impl(endTag) {} +EndTag::EndTag(CType& endTag, Rewriter& rewriter) { + impl.emplace(endTag, rewriter); +} void EndTag::htmlContentScopeEnd() { impl = kj::none; } kj::String EndTag::getName() { - auto text = LolString(lol_html_end_tag_name_get(&checkToken(impl))); + auto text = LolString(lol_html_end_tag_name_get(&checkToken(impl).element)); return kj::str(text.asChars()); } void EndTag::setName(kj::String text) { - check(lol_html_end_tag_name_set(&checkToken(impl), text.cStr(), text.size())); + check(lol_html_end_tag_name_set(&checkToken(impl).element, text.cStr(), text.size())); } jsg::Ref EndTag::before(Content content, jsg::Optional options) { - auto stringContent = unwrapContent(kj::mv(content)); - check(lol_html_end_tag_before(&checkToken(impl), stringContent.cStr(), stringContent.size(), - options.orDefault({}).html.orDefault(false))); - + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), kj::mv(options)); return JSG_THIS; } jsg::Ref EndTag::after(Content content, jsg::Optional options) { - auto stringContent = unwrapContent(kj::mv(content)); - check(lol_html_end_tag_after(&checkToken(impl), stringContent.cStr(), stringContent.size(), - options.orDefault({}).html.orDefault(false))); - + checkToken(impl).rewriteContentGeneric( + kj::mv(content), kj::mv(options)); return JSG_THIS; } jsg::Ref EndTag::remove() { - lol_html_end_tag_remove(&checkToken(impl)); + lol_html_end_tag_remove(&checkToken(impl).element); return JSG_THIS; } @@ -771,8 +967,6 @@ void Element::htmlContentScopeEnd() { impl = kj::none; } -Element::Impl::Impl(CType& element, Rewriter& rewriter): element(element), rewriter(rewriter) {} - Element::Impl::~Impl() noexcept(false) { for (auto& jsIter: attributesIterators) { static_cast(*jsIter).htmlContentScopeEnd(); @@ -828,6 +1022,8 @@ bool Comment::getRemoved() { } jsg::Ref Comment::before(Content content, jsg::Optional options) { + // TODO(someday): If lol-html adds support for streaming replacements for comments, this + // function will need to be updated. auto stringContent = unwrapContent(kj::mv(content)); check(lol_html_comment_before(&checkToken(impl), stringContent.cStr(), stringContent.size(), options.orDefault({}).html.orDefault(false))); @@ -836,6 +1032,8 @@ jsg::Ref Comment::before(Content content, jsg::Optional } jsg::Ref Comment::after(Content content, jsg::Optional options) { + // TODO(someday): If lol-html adds support for streaming replacements for comments, this + // function will need to be updated. auto stringContent = unwrapContent(kj::mv(content)); check(lol_html_comment_after(&checkToken(impl), stringContent.cStr(), stringContent.size(), options.orDefault({}).html.orDefault(false))); @@ -844,6 +1042,8 @@ jsg::Ref Comment::after(Content content, jsg::Optional } jsg::Ref Comment::replace(Content content, jsg::Optional options) { + // TODO(someday): If lol-html adds support for streaming replacements for comments, this + // function will need to be updated. auto stringContent = unwrapContent(kj::mv(content)); check(lol_html_comment_replace(&checkToken(impl), stringContent.cStr(), stringContent.size(), options.orDefault({}).html.orDefault(false))); @@ -864,49 +1064,48 @@ void Comment::htmlContentScopeEnd() { // ======================================================================================= // Text -Text::Text(CType& text, Rewriter&): impl(text) {} +Text::Text(CType& text, Rewriter& rewriter) { + impl.emplace(text, rewriter); +} kj::String Text::getText() { - auto content = lol_html_text_chunk_content_get(&checkToken(impl)); + auto content = lol_html_text_chunk_content_get(&checkToken(impl).element); return kj::heapString(content.data, content.len); } bool Text::getLastInTextNode() { // NOTE: No error checking seems required by this function -- it returns a bool directly. - return lol_html_text_chunk_is_last_in_text_node(&checkToken(impl)); + return lol_html_text_chunk_is_last_in_text_node(&checkToken(impl).element); } bool Text::getRemoved() { // NOTE: No error checking seems required by this function -- it returns a bool directly. - return lol_html_text_chunk_is_removed(&checkToken(impl)); + return lol_html_text_chunk_is_removed(&checkToken(impl).element); } jsg::Ref Text::before(Content content, jsg::Optional options) { - auto stringContent = unwrapContent(kj::mv(content)); - check(lol_html_text_chunk_before(&checkToken(impl), stringContent.cStr(), stringContent.size(), - options.orDefault({}).html.orDefault(false))); - + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), kj::mv(options)); return JSG_THIS; } jsg::Ref Text::after(Content content, jsg::Optional options) { - auto stringContent = unwrapContent(kj::mv(content)); - check(lol_html_text_chunk_after(&checkToken(impl), stringContent.cStr(), stringContent.size(), - options.orDefault({}).html.orDefault(false))); - + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), kj::mv(options)); return JSG_THIS; } jsg::Ref Text::replace(Content content, jsg::Optional options) { - auto stringContent = unwrapContent(kj::mv(content)); - check(lol_html_text_chunk_replace(&checkToken(impl), stringContent.cStr(), stringContent.size(), - options.orDefault({}).html.orDefault(false))); - + checkToken(impl) + .rewriteContentGeneric( + kj::mv(content), kj::mv(options)); return JSG_THIS; } jsg::Ref Text::remove() { - lol_html_text_chunk_remove(&checkToken(impl)); + lol_html_text_chunk_remove(&checkToken(impl).element); return JSG_THIS; } @@ -945,6 +1144,8 @@ void Doctype::htmlContentScopeEnd() { DocumentEnd::DocumentEnd(CType& documentEnd, Rewriter&): impl(documentEnd) {} jsg::Ref DocumentEnd::append(Content content, jsg::Optional options) { + // TODO(someday): If lol-html adds support for streaming replacements for the document end, + // this function will need to be updated. auto stringContent = unwrapContent(kj::mv(content)); check(lol_html_doc_end_append(&checkToken(impl), stringContent.cStr(), stringContent.size(), options.orDefault({}).html.orDefault(false))); diff --git a/src/workerd/api/html-rewriter.h b/src/workerd/api/html-rewriter.h index 1c9678fbf42..ec9e7d8a14a 100644 --- a/src/workerd/api/html-rewriter.h +++ b/src/workerd/api/html-rewriter.h @@ -118,6 +118,21 @@ class HTMLRewriter: public jsg::Object { kj::Own impl; }; +// A chunk of text or HTML which can be passed to content token mutation functions. +using Content = kj::OneOf, jsg::Ref>; +// TODO(soon): Support ReadableStream/Response types. Requires fibers or lol-html saveable state. + +// Options bag which can be passed to content token mutation functions. +struct ContentOptions { + // True if the Content being passed to the mutation function is HTML. If false, the content will + // be escaped (HTML entity-encoded). + jsg::Optional html; + + JSG_STRUCT(html); +}; + +class Rewriter; + // ======================================================================================= // HTML Content Tokens // @@ -140,23 +155,25 @@ class HTMLRewriter: public jsg::Object { class HTMLRewriter::Token: public jsg::Object { public: virtual void htmlContentScopeEnd() = 0; -}; -// A chunk of text or HTML which can be passed to content token mutation functions. -using Content = kj::OneOf, jsg::Ref>; -// TODO(soon): Support ReadableStream/Response types. Requires fibers or lol-html saveable state. + // Each Token subclass has an inner ImplBase subclass which holds a reference + // to the rewriter, and the actual underlying lol-html C API handle for the token. + template + struct ImplBase { + ImplBase(CType& element, Rewriter& rewriter); + KJ_DISALLOW_COPY_AND_MOVE(ImplBase); + ~ImplBase() noexcept(false); -// Options bag which can be passed to content token mutation functions. -struct ContentOptions { - // True if the Content being passed to the mutation function is HTML. If false, the content will - // be escaped (HTML entity-encoded). - jsg::Optional html; + // Dispatches calls to the underlying lol_html methods for each event (e.g. before, after, replace). + // Handles replacements of each supported type (string, ReadableStream, Body). + template + void rewriteContentGeneric(Content content, jsg::Optional options); - JSG_STRUCT(html); + CType& element; + Rewriter& rewriter; + }; }; -class Rewriter; - class Element final: public HTMLRewriter::Token { public: using CType = lol_html_Element; @@ -214,28 +231,16 @@ class Element final: public HTMLRewriter::Token { JSG_TS_ROOT(); JSG_TS_OVERRIDE({ - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; - setInnerContent(content: string, options?: ContentOptions): Element; - - onEndTag(handler: (tag: EndTag) => void | Promise): void; + onEndTag(handler: (tag: EndTag) => void | Promise): void; }); - // Require content to be a string, and specify parameter type for onEndTag - // callback function + // Specify parameter type for onEndTag callback function } private: - struct Impl { - Impl(CType& element, Rewriter&); - KJ_DISALLOW_COPY_AND_MOVE(Impl); + struct Impl: public HTMLRewriter::Token::ImplBase { + using HTMLRewriter::Token::ImplBase::ImplBase; ~Impl() noexcept(false); - - CType& element; kj::Vector> attributesIterators; - Rewriter& rewriter; }; kj::Maybe impl; @@ -278,7 +283,7 @@ class EndTag final: public HTMLRewriter::Token { public: using CType = lol_html_EndTag; - explicit EndTag(CType& tag, Rewriter&); + explicit EndTag(CType& tag, Rewriter& rewriter); kj::String getName(); void setName(kj::String); @@ -295,15 +300,10 @@ class EndTag final: public HTMLRewriter::Token { JSG_METHOD(remove); JSG_TS_ROOT(); - JSG_TS_OVERRIDE({ - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; - }); - // Require content to be a string } private: - kj::Maybe impl; + kj::Maybe> impl; void htmlContentScopeEnd() override; }; @@ -352,7 +352,7 @@ class Text final: public HTMLRewriter::Token { public: using CType = lol_html_TextChunk; - explicit Text(CType& text, Rewriter&); + explicit Text(CType& text, Rewriter& rewriter); kj::String getText(); @@ -376,16 +376,10 @@ class Text final: public HTMLRewriter::Token { JSG_METHOD(remove); JSG_TS_ROOT(); - JSG_TS_OVERRIDE({ - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; - }); - // Require content to be a string } private: - kj::Maybe impl; + kj::Maybe> impl; void htmlContentScopeEnd() override; }; diff --git a/src/workerd/api/tests/htmlrewriter-test.js b/src/workerd/api/tests/htmlrewriter-test.js index aea8ca0a990..7bd0a970901 100644 --- a/src/workerd/api/tests/htmlrewriter-test.js +++ b/src/workerd/api/tests/htmlrewriter-test.js @@ -610,6 +610,156 @@ export const manualWriting2 = { }, }; +export const streamingReplacement = { + async test() { + const { readable, writable } = new TransformStream(); + + const response = new HTMLRewriter() + .on('*', { + async element(element) { + const dataStream = ( + await fetch('data:,the quick brown fox jumped over the lazy dog%20') + ).body; + element.prepend(dataStream, { html: false }); + }, + }) + .transform(new Response(readable)); + + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + await writer.write(encoder.encode('')); + await writer.write(encoder.encode('bar')); + await writer.write(encoder.encode('')); + await writer.close(); + + // This variation uses the JavaScript TransformStream, so we can + // initiate the read after doing the writes. + const promise = response.text(); + strictEqual( + await promise, + `the quick brown fox jumped over the lazy dog bar` + ); + }, +}; + +export const streamingReplacementHTML = { + async test() { + const { readable, writable } = new TransformStream(); + + const response = new HTMLRewriter() + .on('*', { + async element(element) { + const dataStream = ( + await fetch('data:,such markup much wow ') + ).body; + element.prepend(dataStream, { html: true }); + }, + }) + .transform(new Response(readable)); + + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + await writer.write(encoder.encode('')); + await writer.write(encoder.encode('bar')); + await writer.write(encoder.encode('')); + await writer.close(); + + // This variation uses the JavaScript TransformStream, so we can + // initiate the read after doing the writes. + const promise = response.text(); + strictEqual( + await promise, + `such markup much wowbar` + ); + }, +}; + +export const streamingReplacementReplace = { + async test() { + const { readable, writable } = new TransformStream(); + + const response = new HTMLRewriter() + .on('.dinosaur', { + async element(element) { + const dataStream = (await fetch('data:,goodbye world')).body; + element.replace(dataStream, { html: false }); + }, + }) + .transform(new Response(readable)); + + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + await writer.write(encoder.encode('')); + await writer.write( + encoder.encode('
hello world
') + ); + await writer.write(encoder.encode('')); + await writer.close(); + + // This variation uses the JavaScript TransformStream, so we can + // initiate the read after doing the writes. + const promise = response.text(); + strictEqual(await promise, `goodbye world`); + }, +}; + +export const streamingReplacementMultiple = { + async test() { + const { readable, writable } = new TransformStream(); + + const response = new HTMLRewriter() + .on('*', { + async element(element) { + element.prepend(await fetch('data:,alpha%20')); + element.append(await fetch('data:,%20gamma')); + }, + }) + .transform(new Response(readable)); + + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + await writer.write(encoder.encode('')); + await writer.write(encoder.encode('beta')); + await writer.write(encoder.encode('')); + await writer.close(); + + // This variation uses the JavaScript TransformStream, so we can + // initiate the read after doing the writes. + const promise = response.text(); + strictEqual(await promise, `alpha beta gamma`); + }, +}; + +export const streamingReplacementBadUTF8 = { + async test() { + const { readable, writable } = new TransformStream(); + + const response = new HTMLRewriter() + .on('*', { + async element(element) { + element.prepend(await fetch('data:,garbage%e2%28%a1')); + }, + }) + .transform(new Response(readable)); + + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + await writer.write(encoder.encode('')); + await writer.write(encoder.encode('bar')); + await writer.write(encoder.encode('')); + await writer.close(); + + // This variation uses the JavaScript TransformStream, so we can + // initiate the read after doing the writes. + await rejects(response.text(), { message: 'Parser error: Invalid UTF-8' }); + }, +}; + export const appendOnEnd = { async test() { const kInput = diff --git a/types/generated-snapshot/2021-11-03/index.d.ts b/types/generated-snapshot/2021-11-03/index.d.ts index 6fe7508dd82..659ad689fe6 100755 --- a/types/generated-snapshot/2021-11-03/index.d.ts +++ b/types/generated-snapshot/2021-11-03/index.d.ts @@ -1416,20 +1416,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1444,9 +1468,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2021-11-03/index.ts b/types/generated-snapshot/2021-11-03/index.ts index f9742194c25..e9582ba1a31 100755 --- a/types/generated-snapshot/2021-11-03/index.ts +++ b/types/generated-snapshot/2021-11-03/index.ts @@ -1421,20 +1421,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1449,9 +1473,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2022-01-31/index.d.ts b/types/generated-snapshot/2022-01-31/index.d.ts index b72e0ebfa19..6c3ba3db2c0 100755 --- a/types/generated-snapshot/2022-01-31/index.d.ts +++ b/types/generated-snapshot/2022-01-31/index.d.ts @@ -1422,20 +1422,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1450,9 +1474,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2022-01-31/index.ts b/types/generated-snapshot/2022-01-31/index.ts index 03709d2b9f7..3c731c385a6 100755 --- a/types/generated-snapshot/2022-01-31/index.ts +++ b/types/generated-snapshot/2022-01-31/index.ts @@ -1427,20 +1427,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1455,9 +1479,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2022-03-21/index.d.ts b/types/generated-snapshot/2022-03-21/index.d.ts index 5de78f6e2d5..2868897506c 100755 --- a/types/generated-snapshot/2022-03-21/index.d.ts +++ b/types/generated-snapshot/2022-03-21/index.d.ts @@ -1440,20 +1440,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1468,9 +1492,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2022-03-21/index.ts b/types/generated-snapshot/2022-03-21/index.ts index 0c8eeef7df9..644d47b6c0a 100755 --- a/types/generated-snapshot/2022-03-21/index.ts +++ b/types/generated-snapshot/2022-03-21/index.ts @@ -1445,20 +1445,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1473,9 +1497,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2022-08-04/index.d.ts b/types/generated-snapshot/2022-08-04/index.d.ts index eb0483b9b26..b351125be5f 100755 --- a/types/generated-snapshot/2022-08-04/index.d.ts +++ b/types/generated-snapshot/2022-08-04/index.d.ts @@ -1440,20 +1440,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1468,9 +1492,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2022-08-04/index.ts b/types/generated-snapshot/2022-08-04/index.ts index d60f657a56a..63c668152d0 100755 --- a/types/generated-snapshot/2022-08-04/index.ts +++ b/types/generated-snapshot/2022-08-04/index.ts @@ -1445,20 +1445,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1473,9 +1497,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2022-10-31/index.d.ts b/types/generated-snapshot/2022-10-31/index.d.ts index 885c1c23c0c..594a890fcbf 100755 --- a/types/generated-snapshot/2022-10-31/index.d.ts +++ b/types/generated-snapshot/2022-10-31/index.d.ts @@ -1440,20 +1440,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1468,9 +1492,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2022-10-31/index.ts b/types/generated-snapshot/2022-10-31/index.ts index 13f5db8ba95..35de138200f 100755 --- a/types/generated-snapshot/2022-10-31/index.ts +++ b/types/generated-snapshot/2022-10-31/index.ts @@ -1445,20 +1445,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1473,9 +1497,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2022-11-30/index.d.ts b/types/generated-snapshot/2022-11-30/index.d.ts index c3cd040d4dd..d2caca14f7b 100755 --- a/types/generated-snapshot/2022-11-30/index.d.ts +++ b/types/generated-snapshot/2022-11-30/index.d.ts @@ -1445,20 +1445,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1473,9 +1497,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2022-11-30/index.ts b/types/generated-snapshot/2022-11-30/index.ts index c2c7f426d8e..fab2ff3ab52 100755 --- a/types/generated-snapshot/2022-11-30/index.ts +++ b/types/generated-snapshot/2022-11-30/index.ts @@ -1450,20 +1450,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1478,9 +1502,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2023-03-01/index.d.ts b/types/generated-snapshot/2023-03-01/index.d.ts index ea598ceffea..196c9dabbe8 100755 --- a/types/generated-snapshot/2023-03-01/index.d.ts +++ b/types/generated-snapshot/2023-03-01/index.d.ts @@ -1445,20 +1445,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1473,9 +1497,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2023-03-01/index.ts b/types/generated-snapshot/2023-03-01/index.ts index d070e0470d8..e18feea7837 100755 --- a/types/generated-snapshot/2023-03-01/index.ts +++ b/types/generated-snapshot/2023-03-01/index.ts @@ -1450,20 +1450,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1478,9 +1502,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/2023-07-01/index.d.ts b/types/generated-snapshot/2023-07-01/index.d.ts index 9df7235e7d6..9c8abe97f32 100755 --- a/types/generated-snapshot/2023-07-01/index.d.ts +++ b/types/generated-snapshot/2023-07-01/index.d.ts @@ -1445,20 +1445,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1473,9 +1497,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/2023-07-01/index.ts b/types/generated-snapshot/2023-07-01/index.ts index dabd5224051..141aaa0cd55 100755 --- a/types/generated-snapshot/2023-07-01/index.ts +++ b/types/generated-snapshot/2023-07-01/index.ts @@ -1450,20 +1450,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1478,9 +1502,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/experimental/index.d.ts b/types/generated-snapshot/experimental/index.d.ts index a75f632eff7..3bb56e2899c 100755 --- a/types/generated-snapshot/experimental/index.d.ts +++ b/types/generated-snapshot/experimental/index.d.ts @@ -1453,20 +1453,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1481,9 +1505,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/experimental/index.ts b/types/generated-snapshot/experimental/index.ts index a175c5ebe17..8968dc55578 100755 --- a/types/generated-snapshot/experimental/index.ts +++ b/types/generated-snapshot/experimental/index.ts @@ -1458,20 +1458,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1486,9 +1510,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd { diff --git a/types/generated-snapshot/oldest/index.d.ts b/types/generated-snapshot/oldest/index.d.ts index 8ccf49c7ecc..d91fb1a8a53 100755 --- a/types/generated-snapshot/oldest/index.d.ts +++ b/types/generated-snapshot/oldest/index.d.ts @@ -1416,20 +1416,44 @@ interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } interface Comment { @@ -1444,9 +1468,18 @@ interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } interface DocumentEnd { diff --git a/types/generated-snapshot/oldest/index.ts b/types/generated-snapshot/oldest/index.ts index f8a068217e1..ad6de110a82 100755 --- a/types/generated-snapshot/oldest/index.ts +++ b/types/generated-snapshot/oldest/index.ts @@ -1421,20 +1421,44 @@ export interface Element { hasAttribute(name: string): boolean; setAttribute(name: string, value: string): Element; removeAttribute(name: string): Element; - before(content: string, options?: ContentOptions): Element; - after(content: string, options?: ContentOptions): Element; - prepend(content: string, options?: ContentOptions): Element; - append(content: string, options?: ContentOptions): Element; - replace(content: string, options?: ContentOptions): Element; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + prepend( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + append( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; remove(): Element; removeAndKeepContent(): Element; - setInnerContent(content: string, options?: ContentOptions): Element; + setInnerContent( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Element; onEndTag(handler: (tag: EndTag) => void | Promise): void; } export interface EndTag { name: string; - before(content: string, options?: ContentOptions): EndTag; - after(content: string, options?: ContentOptions): EndTag; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): EndTag; remove(): EndTag; } export interface Comment { @@ -1449,9 +1473,18 @@ export interface Text { readonly text: string; readonly lastInTextNode: boolean; readonly removed: boolean; - before(content: string, options?: ContentOptions): Text; - after(content: string, options?: ContentOptions): Text; - replace(content: string, options?: ContentOptions): Text; + before( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + after( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; + replace( + content: string | ReadableStream | Response, + options?: ContentOptions, + ): Text; remove(): Text; } export interface DocumentEnd {