/*
 * 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,
    ConstructorCallWith=ScriptState,
] interface Internals {
    DOMString address(Node node);

    GCObservation observeGC(any observed);

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

    boolean isSharingStyle(Element element1, Element element2);

    CSSStyleDeclaration computedStyleIncludingVisitedInfo(Node node);

    ShadowRoot createUserAgentShadowRoot(Element host);

    ShadowRoot shadowRoot(Element host);
    ShadowRoot youngestShadowRoot(Element host);
    ShadowRoot oldestShadowRoot(Element host);
    [RaisesException] ShadowRoot youngerShadowRoot(Node root);

    [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] boolean hasSelectorForIdInShadow(Element host, DOMString id);
    [RaisesException] boolean hasSelectorForClassInShadow(Element host, DOMString className);
    [RaisesException] boolean hasSelectorForAttributeInShadow(Element host, DOMString attributeName);
    [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);

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

    // Modifies m_desiredFrameStartTime in BitmapImage to advance the next frame time
    // for testing whether animated images work properly.
    [RaisesException] void advanceTimeForImage(Element image, double deltaTimeInSeconds);

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

    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] DOMString[] formControlStateOfHistoryItem();
    [RaisesException] void setFormControlStateOfHistoryItem(sequence<DOMString> values);
    readonly attribute Window pagePopupWindow;

    [RaisesException] ClientRect absoluteCaretBounds();

    ClientRect boundingBox(Element element);

    [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);
    void addTextMatchMarker(Range range, boolean isActive);
    void setMarkersActive(Node node, unsigned long startOffset, unsigned long endOffset, boolean active);
    void setMarkedTextMatchesAreHighlighted(Document document, boolean highlight);

    [RaisesException] void setFrameViewPosition(Document document, long x, long y);

    [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 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] ClientRect bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document document);

    [RaisesException] long lastSpellCheckRequestSequence(Document document);
    [RaisesException] long lastSpellCheckProcessedSequence(Document document);

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

    unsigned long activeDOMObjectCount(Document document);
    unsigned long wheelEventHandlerCount(Document document);
    unsigned long scrollEventHandlerCount(Document document);
    unsigned long touchStartOrMoveEventHandlerCount(Document document);
    unsigned long touchEndOrCancelEventHandlerCount(Document document);
    [RaisesException] LayerRectList 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 topPadding, unsigned long rightPadding, unsigned long bottomPadding, unsigned long leftPadding,
        boolean ignoreClipping, boolean allowChildFrameContent);

    boolean hasSpellingMarker(Document document, long from, long length);
    boolean hasGrammarMarker(Document document, long from, long length);
    void setContinuousSpellCheckingEnabled(boolean enabled);

    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;

    // Flags for layerTreeAsText.
    // The values of these constants must be kept in sync with the values of LayerTreeFlags in GraphicsLayerClient.h.
    const unsigned short LAYER_TREE_INCLUDES_DEBUG_INFO = 1;
    const unsigned short LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS = 2;
    const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 4;
    const unsigned short LAYER_TREE_INCLUDES_ROOT_LAYER = 8;
    const unsigned short LAYER_TREE_INCLUDES_CLIP_AND_SCROLL_PARENTS = 16;
    const unsigned short LAYER_TREE_INCLUDES_COMPOSITING_REASONS = 32;
    [RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);
    [RaisesException] DOMString elementLayerTreeAsText(Element element, optional unsigned short flags);

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

    DOMString scrollingStateTreeAsText(Document document);
    [RaisesException] DOMString mainThreadScrollingReasons(Document document);
    [RaisesException] ClientRectList nonFastScrollableRects(Document document);

    void evictAllResources();

    unsigned long numberOfLiveNodes();
    unsigned long numberOfLiveDocuments();
    DOMString dumpRefCountedInstanceCounts();
    sequence<DOMString> consoleMessageArgumentCounts(Document document);
    unsigned long[] setMemoryCacheCapacities(unsigned long minDeadBytes, unsigned long maxDeadBytes, unsigned long totalBytes);

    DOMString counterValue(Element element);
    [RaisesException] long pageNumber(Element element, optional float pageWidth = 800, optional float pageHeight = 600);
    DOMString[] shortcutIconURLs(Document document);
    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] void setPageScaleFactor(float scaleFactor);
    [RaisesException] void setPageScaleFactorLimits(float minScaleFactor, float maxScaleFactor);

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

    double effectiveMediaVolume(HTMLMediaElement mediaElement);
    DOMString effectivePreload(HTMLMediaElement mediaElement);
    void mediaPlayerRemoteRouteAvailabilityChanged(HTMLMediaElement mediaElement, boolean available);
    void mediaPlayerPlayingRemotelyChanged(HTMLMediaElement mediaElement, boolean remote);
    void setAllowHiddenVolumeControls(HTMLMediaElement mediaElement, boolean allow);

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

    TypeConversions typeConversions();

    // This is enabled only in Debug builds.
    // This is because we want to avoid putting the byte stream of testing private scripts
    // into the binary of Release builds.
    PrivateScriptTest privateScriptTest();

    DOMString[] getReferencedFilePaths();

    // These functions both reset the tracked repaint rects. They are intended to be used in the following order:
    //  startTrackingRepaints(), repaintRectsAsText(), stopTrackingRepaints().
    // TODO(wangxianzhu): Remove these functions when we no longer use repaint rects.
    [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 updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(optional Node? node = null);

    [RaisesException] void forceFullRepaint(Document document);

    // These functions both reset the tracked paint invalidation objects. They are intended to be used in the following order:
    //  startTrackingPaintInvalidationObjects(), trackedPaintInvalidationObjects(), stopTrackingPaintInvalidationObjects().
    void startTrackingPaintInvalidationObjects();
    void stopTrackingPaintInvalidationObjects();

    // Returns a list of debug strings for objects that were invalidated between
    // startTrackingPaintInvalidationObjects() and stopTrackingPaintInvalidationObjects().
    // If an object is invalidated multiple times, it will appear in the list multiple times.
    DOMString[] trackedPaintInvalidationObjects();

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

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

    readonly attribute boolean cursorUpdatePending;

    DOMString markerTextForListItem(Element element);

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

    void forceReload(boolean endToEnd);

    DOMString getImageSourceURL(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);

    [RaisesException] ClientRect selectionBounds();

    boolean loseSharedGraphicsContext3D();

    [RaisesException] void forceCompositingUpdate(Document document);

    void setZoomFactor(float factor);

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

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

    void setValueForUser(Element element, DOMString value);

    DOMString textSurroundingNode(Node node, long x, long y, unsigned long maxLength);

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

    boolean ignoreLayoutWithPendingStylesheets(Document document);

    // These functions are for testing NetInfo. You must call setNetworkStateNotifierTestOnly(true)
    // before calling setNetworkConnectionInfo.
    void setNetworkStateNotifierTestOnly(boolean testOnly);
    [RaisesException] void setNetworkConnectionInfo(DOMString type, double downlinkMaxMbps);

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

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

    DictionaryTest dictionaryTest();
    UnionTypesTest unionTypesTest();
    [RaisesException] void setScrollChain(ScrollState scrollState, Element[] elements);
    void forceBlinkGCWithoutV8GC();

    DOMString selectedHTMLForClipboard();
    DOMString selectedTextForClipboard();

    void setVisualViewportOffset(long x, long y);
    int visualViewportHeight();
    int visualViewportWidth();
    double visualViewportScrollX();
    double visualViewportScrollY();

    bool magnifyScaleAroundAnchor(float offset, float x, float y);

    boolean isUseCounted(Document document, long useCounterId);
    boolean isCSSPropertyUseCounted(Document document, DOMString propertyName);

    iterable<long>;

    [Unscopeable] readonly attribute DOMString unscopeableAttribute;
    [Unscopeable] DOMString unscopeableMethod();

    ClientRectList focusRingRects(Element element);
    ClientRectList outlineRects(Element element);
    void setCapsLockState(boolean enabled);

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

    [RaisesException] double monotonicTimeToZeroBasedDocumentTime(double platformTime);

    void setMediaElementNetworkState(HTMLMediaElement element, long state);

    // TODO(liberato): remove once autoplay gesture override experiment concludes.
    void triggerAutoplayViewportCheck(HTMLMediaElement mediaElement);

    DOMString getScrollAnimationState(Node node);

    DOMString getProgrammaticScrollAnimationState(Node node);
};
