package extractor import "errors" // ErrNotPromotable is returned when a Document cannot be promoted to an InteractiveBrowser. // This happens when the Document is not backed by a Playwright page (e.g. a mock or custom implementation). var ErrNotPromotable = errors.New("document is not promotable to InteractiveBrowser") // ErrNotDemotable is returned when an InteractiveBrowser cannot be demoted to a Document. // This happens when the InteractiveBrowser is not backed by a Playwright page. var ErrNotDemotable = errors.New("interactive browser is not demotable to Document") // ErrAlreadyDetached is returned when attempting to promote or demote an object that has // already been transferred. Each Document or InteractiveBrowser can only be promoted/demoted once. var ErrAlreadyDetached = errors.New("already detached") // PromoteToInteractive transfers ownership of the underlying Playwright page from a Document // to a new InteractiveBrowser. After promotion, the Document's Close method becomes a no-op // (the page is now owned by the returned InteractiveBrowser). // // The caller must keep the original Browser alive while the promoted InteractiveBrowser is in use, // since the Browser still owns the Playwright process and browser instance. // // Returns ErrNotPromotable if the Document is not backed by a Playwright page, // or ErrAlreadyDetached if the Document was already promoted. func PromoteToInteractive(doc Document) (InteractiveBrowser, error) { d, ok := doc.(*document) if !ok { return nil, ErrNotPromotable } if d.detached { return nil, ErrAlreadyDetached } d.detached = true return &interactiveBrowser{ pw: d.pw, browser: d.browser, ctx: d.page.Context(), page: d.page, }, nil } // DemoteToDocument transfers ownership of the underlying Playwright page from an // InteractiveBrowser back to a new Document. After demotion, the InteractiveBrowser's // Close method becomes a no-op (the page is now owned by the returned Document). // // Returns ErrNotDemotable if the InteractiveBrowser is not backed by a Playwright page, // or ErrAlreadyDetached if the InteractiveBrowser was already demoted. func DemoteToDocument(ib InteractiveBrowser) (Document, error) { b, ok := ib.(*interactiveBrowser) if !ok { return nil, ErrNotDemotable } if b.detached { return nil, ErrAlreadyDetached } b.detached = true return newDocument(b.pw, b.browser, b.page) }