/*
 * 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;
    readonly attribute boolean isFormControlsRefreshEnabled;

    // 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;
};
