/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     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 AND ITS CONTRIBUTORS "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 OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

[
    DoNotCheckConstants
] interface Internals {
    GCObservation observeGC(any observed);

    [RaisesException] DOMString elementLayoutTreeAsText(Element element);
    boolean isPreloaded(DOMString url);
    boolean isPreloadedBy(DOMString url, Document document);
    boolean isLoading(DOMString url);
    boolean isLoadingFromMemoryCache(DOMString url);

    // Call this function with the URL of a resource that has not yet been
    // fetched. It returns a promise that resolves with the priority of the
    // request, once it has been made.
    [CallWith=ScriptState] Promise<unsigned long> getResourcePriority(DOMString url, Document document);

    DOMString getResourceHeader(DOMString url, DOMString header, Document document);

    boolean doesWindowHaveUrlFragment(Window window);

    CSSStyleDeclaration computedStyleIncludingVisitedInfo(Node node);

    ShadowRoot createUserAgentShadowRoot(Element host);

    ShadowRoot shadowRoot(Element host);

    void setBrowserControlsState(float top_height, float bottom_height, boolean shrinksLayout);
    void setBrowserControlsShownRatio(float top_ratio, float bottom_ratio);

    Node effectiveRootScroller(Document document);

    [RaisesException] DOMString shadowRootType(Node root);
    [RaisesException] boolean hasShadowInsertionPoint(Node root);
    [RaisesException] boolean hasContentElement(Node root);
    [RaisesException] unsigned long countElementShadow(Node Root);
    DOMString shadowPseudoId(Element element);
    [RaisesException] boolean isValidContentSelect(Element contentElement);
    Node treeScopeRootNode(Node node);
    Node parentTreeScope(Node node);
    [RaisesException] unsigned short compareTreeScopePosition(Node treeScope1, Node treeScope2);
    [RaisesException] unsigned long updateStyleAndReturnAffectedElementCount();
    [RaisesException] unsigned long needsLayoutCount();
    [RaisesException] unsigned long hitTestCount(Document document);
    [RaisesException] unsigned long hitTestCacheHits(Document document);
    [RaisesException] Element? elementFromPoint(Document document, double x, double y, boolean ignoreClipping, boolean allowChildFrameContent);
    [RaisesException] void clearHitTestCache(Document document);

    // Allows inspection of the inner editor node.
    [RaisesException] Element? innerEditorElement(Element container);

    // Animation testing.
    [RaisesException] void pauseAnimations(double pauseTime);
    boolean isCompositedAnimation(Animation animation);
    void disableCompositedAnimation(Animation animation);
    void disableCSSAdditiveAnimations();

    // Advances an animated image. For BitmapImage (e.g., animated gifs) this
    // will advance to the next frame. For SVGImage, this will trigger an
    // animation update for CSS and advance the SMIL timeline by one frame.
    [RaisesException] void advanceImageAnimation(Element image);

    [RaisesException] Node nextSiblingInFlatTree(Node node);
    [RaisesException] Node firstChildInFlatTree(Node node);
    [RaisesException] Node lastChildInFlatTree(Node node);
    [RaisesException] Node nextInFlatTree(Node node);
    [RaisesException] Node previousInFlatTree(Node node);

    DOMString visiblePlaceholder(Element element);
    boolean isValidationMessageVisible(Element element);
    void selectColorInColorChooser(Element element, DOMString colorValue);
    void endColorChooser(Element element);

    // If the argument is omitted, the top-level document is used.
    boolean hasAutofocusRequest(optional Document document);
    [RaisesException] sequence<DOMString> formControlStateOfHistoryItem();
    [RaisesException] void setFormControlStateOfHistoryItem(sequence<DOMString> values);
    readonly attribute Window pagePopupWindow;

    [RaisesException] DOMRectReadOnly absoluteCaretBounds();

    DOMRectReadOnly boundingBox(Element element);

    [RaisesException] void setMarker(Document document, Range range, DOMString markerType);
    [RaisesException] unsigned long markerCountForNode(Node node, DOMString markerType);
    unsigned long activeMarkerCountForNode(Node node);
    [RaisesException] Range markerRangeForNode(Node node, DOMString markerType, unsigned long index);
    [RaisesException] DOMString markerDescriptionForNode(Node node, DOMString markerType, unsigned long index);
    [RaisesException] unsigned long markerBackgroundColorForNode(Node node, DOMString markerType, unsigned long index);
    [RaisesException] unsigned long markerUnderlineColorForNode(Node node, DOMString markerType, unsigned long index);
    [RaisesException] void addTextMatchMarker(Range range, DOMString matchStatus);
    [RaisesException] void addCompositionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue);
    [RaisesException] void addActiveSuggestionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue);
    [RaisesException] void addSuggestionMarker(Range range, sequence<DOMString> suggestions, DOMString suggestionHighlightColorValue, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue);
    void setTextMatchMarkersActive(Node node, unsigned long startOffset, unsigned long endOffset, boolean active);
    void setMarkedTextMatchesAreHighlighted(Document document, boolean highlight);

    [RaisesException] DOMString viewportAsText(Document document,
                                               float devicePixelRatio,
                                               long availableWidth,
                                               long availableHeight);

    [RaisesException] boolean elementShouldAutoComplete(Element inputElement);
    [RaisesException] DOMString suggestedValue(Element inputElement);
    [RaisesException] void setSuggestedValue(Element inputElement, DOMString value);
    [RaisesException] void setAutofilledValue(Element inputElement, DOMString value);
    [RaisesException] void setEditingValue(Element inputElement, DOMString value);
    [RaisesException] void setAutofilled(Element inputElement, boolean enabled);

    Range rangeFromLocationAndLength(Element scope, long rangeLocation, long rangeLength);
    unsigned long locationFromRange(Element scope, Range range);
    unsigned long lengthFromRange(Element scope, Range range);
    DOMString rangeAsText(Range range);

    [RaisesException] DOMPoint touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document document);
    [RaisesException] Node touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document document);
    [RaisesException] DOMPoint touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document document);
    [RaisesException] Node touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document document);

    [RaisesException] long lastSpellCheckRequestSequence(Document document);
    [RaisesException] long lastSpellCheckProcessedSequence(Document document);
    [RaisesException] void cancelCurrentSpellCheckRequest(Document document);
    [RaisesException] DOMString idleTimeSpellCheckerState(Document document);
    [RaisesException] void runIdleTimeSpellChecker(Document document);

    sequence<DOMString> userPreferredLanguages();
    void setUserPreferredLanguages(sequence<DOMString> languages);

    unsigned long mediaKeysCount();
    unsigned long mediaKeySessionCount();
    unsigned long contextLifecycleStateObserverObjectCount(Document document);
    unsigned long wheelEventHandlerCount(Document document);
    unsigned long scrollEventHandlerCount(Document document);
    unsigned long touchStartOrMoveEventHandlerCount(Document document);
    unsigned long touchEndOrCancelEventHandlerCount(Document document);
    unsigned long pointerEventHandlerCount(Document document);
    [RaisesException] HitTestLayerRectList touchEventTargetLayerRects(Document document);

    [RaisesException] boolean executeCommand(Document document, DOMString name, DOMString value);

    DOMString htmlNamespace();
    sequence<DOMString> htmlTags();
    DOMString svgNamespace();
    sequence<DOMString> svgTags();

    [RaisesException] NodeList nodesFromRect(Document document, long x, long y,
        unsigned long width, unsigned long height, boolean ignoreClipping,
        boolean allowChildFrameContent);

    [RaisesException] boolean hasSpellingMarker(Document document, long from, long length);
    [RaisesException] boolean hasGrammarMarker(Document document, long from, long length);
    [RaisesException] void replaceMisspelled(Document document, DOMString replacement);

    boolean canHyphenate(DOMString locale);
    void setMockHyphenation(DOMString locale);

    boolean isOverwriteModeEnabled(Document document);
    void toggleOverwriteModeEnabled(Document document);

    unsigned long numberOfScrollableAreas(Document document);

    boolean isPageBoxVisible(Document document, long pageNumber);

    readonly attribute InternalSettings settings;
    readonly attribute InternalRuntimeFlags runtimeFlags;
    readonly attribute unsigned long workerThreadCount;

    // Flag for layerTreeAsText.
    // The value must be kept in sync with the value of LayerTreeFlags in layers_as_json.h.
    // Other flags in LayerTreeFlags are not supported in internals API.
    const unsigned short LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS = 2;

    [RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);

    [RaisesException] boolean scrollsWithRespectTo(Element element1, Element element2);

    DOMString scrollingStateTreeAsText(Document document);
    [RaisesException] DOMString mainThreadScrollingReasons(Document document);
    [RaisesException] DOMRectList nonFastScrollableRects(Document document);
    [RaisesException] void markGestureScrollRegionDirty(Document document);

    void evictAllResources();

    unsigned long numberOfLiveNodes();
    unsigned long numberOfLiveDocuments();

    DOMString counterValue(Element element);
    [RaisesException] long pageNumber(Element element, optional float pageWidth = 800, optional float pageHeight = 600);
    sequence<DOMString> shortcutIconURLs(Document document);
    sequence<DOMString> allIconURLs(Document document);
    [RaisesException] long numberOfPages(optional double pageWidthInPixels = 800, optional double pageHeightInPixels = 600);
    [RaisesException] DOMString pageProperty(DOMString propertyName, long pageNumber);
    [RaisesException] DOMString pageSizeAndMarginsInPixels(long pageIndex, long width, long height, long marginTop, long marginRight, long marginBottom, long marginLeft);

    [RaisesException] float pageScaleFactor();
    [RaisesException] void setPageScaleFactor(float scaleFactor);
    [RaisesException] void setPageScaleFactorLimits(float minScaleFactor, float maxScaleFactor);

    [RaisesException] void setIsCursorVisible(Document document, boolean isVisible);

    // HTMLMediaElement, HTMLAudioElement and HTMLVideoElement.
    DOMString effectivePreload(HTMLMediaElement mediaElement);
    void mediaPlayerRemoteRouteAvailabilityChanged(HTMLMediaElement mediaElement, boolean available);
    void mediaPlayerPlayingRemotelyChanged(HTMLMediaElement mediaElement, boolean remote);
    void setPersistent(HTMLVideoElement video, boolean persistent);
    void forceStaleStateForMediaElement(HTMLMediaElement mediaElement, long state);
    boolean isMediaElementSuspended(HTMLMediaElement mediaElement);
    void setMediaControlsTestMode(HTMLMediaElement mediaElement, boolean enable);

    void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme);
    void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme, sequence<DOMString> policyAreas);
    void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(DOMString scheme);

    TypeConversions typeConversions();

    sequence<DOMString> getReferencedFilePaths();

    // These functions both reset the tracked repaint rects. They are intended to be used in the following order:
    //  startTrackingRepaints(), repaintRectsAsText(), stopTrackingRepaints().
    [RaisesException] void startTrackingRepaints(Document document);
    [RaisesException] void stopTrackingRepaints(Document document);

    // |node| should be Document, HTMLIFrameElement, or unspecified.
    // If |node| is an HTMLIFrameElement, it assumes node.contentDocument is
    // specified without security checks. Unspecified means this document.
    [RaisesException] void updateLayoutAndRunPostLayoutTasks(optional Node? node = null);

    [RaisesException] void forceFullRepaint(Document document);

    // Returns a list of draggable/non-draggable regions in the document.
    [RaisesException] DOMRectList draggableRegions(Document document);
    [RaisesException] DOMRectList nonDraggableRegions(Document document);

    // Returns a string with information about the mouse cursor used at the specified client location.
    DOMString getCurrentCursorInfo();

    readonly attribute boolean cursorUpdatePending;
    readonly attribute boolean fakeMouseMovePending;

    DOMString markerTextForListItem(Element element);

    SerializedScriptValue deserializeBuffer(ArrayBuffer buffer);
    ArrayBuffer serializeObject(SerializedScriptValue obj);

    [CallWith=ScriptState] any deserializeBufferContainingWasm(ArrayBuffer buffer);
    ArrayBuffer serializeWithInlineWasm(any obj);


    void forceReload(boolean endToEnd);

    DOMString getImageSourceURL(Element element);
    [RaisesException] void forceImageReload(Element element);

    DOMString selectMenuListText(HTMLSelectElement select);
    boolean isSelectPopupVisible(Node node);
    boolean selectPopupItemStyleIsRtl(Node select, long itemIndex);
    long selectPopupItemStyleFontHeight(Node select, long itemIndex);
    void resetTypeAheadSession(HTMLSelectElement select);

    StaticSelection getDragCaret();
    [RaisesException] StaticSelection getSelectionInFlatTree(Window window);
    // TODO(editing-dev): We should change |visibleSelection*| to
    // |StaticSelection|.
    readonly attribute Node? visibleSelectionAnchorNode;
    readonly attribute unsigned long visibleSelectionAnchorOffset;
    readonly attribute Node? visibleSelectionFocusNode;
    readonly attribute unsigned long visibleSelectionFocusOffset;
    [RaisesException] DOMRect selectionBounds();
    readonly attribute DOMString textAffinity;

    boolean loseSharedGraphicsContext3D();

    [RaisesException] void forceCompositingUpdate(Document document);

    [RaisesException] void setShouldRevealPassword(Element element, boolean reveal);

    [CallWith=ScriptState] Promise<any> createResolvedPromise(any value);
    [CallWith=ScriptState] Promise<any> createRejectedPromise(any reason);
    [CallWith=ScriptState] Promise<any> addOneToPromise(Promise<any> promise);
    [CallWith=ScriptState, RaisesException] Promise<any> promiseCheck(long arg1, boolean arg2, object arg3, DOMString arg4, sequence<DOMString> arg5);
    [CallWith=ScriptState] Promise<any> promiseCheckWithoutExceptionState(object arg1, DOMString arg2, DOMString... variadic);
    [CallWith=ScriptState] Promise<any> promiseCheckRange([EnforceRange] octet arg1);
    [CallWith=ScriptState] Promise<any> promiseCheckOverload(Location arg1);
    [CallWith=ScriptState] Promise<any> promiseCheckOverload(Document arg1);
    [CallWith=ScriptState] Promise<any> promiseCheckOverload(Location arg1, long arg2, long arg3);

    void setValueForUser(HTMLInputElement element, DOMString value);

    void setFocused(boolean focused);
    void setInitialFocus(boolean reverse);

    // When the FocuslessSpatialNavigation feature is enabled, spatial
    // navigation moves "interest" around a page, rather than focus. This
    // attribute returns the currently interested element on the page.
    readonly attribute Element? interestedElement;

    // This function is for testing HitRegions on Canvas2D.
    unsigned long countHitRegions(CanvasRenderingContext2D context);

    boolean isInCanvasFontCache(Document document, DOMString fontString);
    unsigned long canvasFontCacheMaxFonts();

    DictionaryTest dictionaryTest();
    RecordTest recordTest();
    SequenceTest sequenceTest();
    UnionTypesTest unionTypesTest();
    CallbackFunctionTest callbackFunctionTest();
    [RaisesException] void setScrollChain(ScrollState scrollState, sequence<Element> elements);
    void scheduleBlinkGC();

    DOMString selectedHTMLForClipboard();
    DOMString selectedTextForClipboard();

    void setVisualViewportOffset(long x, long y);

    boolean isUseCounted(Document document, unsigned long feature);
    boolean isCSSPropertyUseCounted(Document document, DOMString propertyName);
    boolean isAnimatedCSSPropertyUseCounted(Document document, DOMString propertyName);
    void clearUseCounter(Document document, unsigned long feature);

    sequence<DOMString> getCSSPropertyLonghands();
    sequence<DOMString> getCSSPropertyShorthands();
    sequence<DOMString> getCSSPropertyAliases();

    // Returns a promise that is resolved when |feature| is counted on
    // |document|'s UseCounter. When |feature| was already counted, it's
    // immediately resolved.
    [CallWith=ScriptState] Promise<boolean> observeUseCounter(Document document, unsigned long feature);

    readonly attribute unsigned long length;
    getter long (unsigned long index);
    iterable<long>;

    [Unscopable] readonly attribute DOMString unscopableAttribute;
    [Unscopable] DOMString unscopableMethod();

    void setCapsLockState(boolean enabled);

    // pseudo: One of ":focus", ":focus-within", ":active", and ":hover".
    [RaisesException] void setPseudoClassState(Element element, DOMString pseudo, boolean enabled);

    // Returns whether the scrollbar was able to be shown or hidden; not all platforms
    // support overlay scrollbars.
    boolean setScrollbarVisibilityInScrollableArea(Node node, boolean visible);

    [RaisesException] double monotonicTimeToZeroBasedDocumentTime(double platformTime);
    long long currentTimeTicks();

    DOMString getScrollAnimationState(Node node);

    DOMString getProgrammaticScrollAnimationState(Node node);

    DOMRect visualRect(Node node);

    OriginTrialsTest originTrialsTest();

    void crash();

    DOMString evaluateInInspectorOverlay(DOMString script);

    void setIsLowEndDevice(boolean isLowEndDevice);
    boolean isLowEndDevice();

    sequence<DOMString> supportedTextEncodingLabels();

    // When RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() and
    // simulateRasterUnderInvalidation(true) is called, all changed pixels will
    // be reported as raster under-invalidations.
    void simulateRasterUnderInvalidations(boolean enable);

    // The number of calls to update the blink lifecycle (see:
    // LocalFrameView::UpdateLifecyclePhasesInternal).
    unsigned long LifecycleUpdateCount();

    // Disable the 'delay' option for IntersectionObserver, so that observations
    // are recomputed on every frame.  This eliminates the need to add
    // setTimeout(..., delay_ms) calls to web tests to wait for notifications
    // to be generated.
    void DisableIntersectionObserverThrottleDelay();

    // Reports whether an iframe's browsing context runs in a separate process
    boolean isSiteIsolated(HTMLIFrameElement iframe);

    // Reports whether a parent document is propagating occlusion information
    // down to a child frame, for the purpose of servicing IntersectionObserver
    // instances that track visibility.
    boolean isTrackingOcclusionForIFrame(HTMLIFrameElement iframe);

    // Declare that the given |name| is in use by the embedder via the custom
    // element mechanism.
    [RaisesException] void addEmbedderCustomElementName(DOMString name);

    // https://html.spec.whatwg.org/C/#resolve-a-module-specifier
    // Throws TypeError on error.
    // Used for testing Import Maps https://github.com/domenic/import-maps
    [RaisesException] DOMString resolveModuleSpecifier(DOMString specifier, DOMString base_url, Document document);

    // Returns the current serialized import map of the Document.
    // TODO(crbug.com/927181): Currently this returns the "imports" value,
    // because Blink doesn't support scopes yet. Update this once scopes are
    // implemented.
    [RaisesException] DOMString getParsedImportMap(Document document);

    // Sets the scale for devtools device emulation.
    [RaisesException] void setDeviceEmulationScale(float scale);

    // Return a string that identifies |document|'s WindowAgent. You can use it
    // to distinguish different Agent instances (perhaps in a remote process).
    // The returned string is composed of the process ID and the memory address
    // of the Agent object.
    DOMString getDocumentAgentId(Document document);

    void useMockOverlayScrollbars();
    readonly attribute boolean overlayScrollbarsEnabled;
};
