/*
 * 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,
    GarbageCollected,
    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 touchEventHandlerCount(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);

    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_REPAINT_RECTS = 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_PAINT_INVALIDATION_OBJECTS = 32;
    const unsigned short LAYER_TREE_INCLUDES_COMPOSITING_REASONS = 64;
    [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);
    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);

    void forceRestrictIFramePermissions();
    [RaisesException] double monotonicTimeToZeroBasedDocumentTime(double platformTime);

    void setMediaElementNetworkState(HTMLMediaElement element, long state);

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

    int getScrollAnimationState(Node node);
};
