/*
 * 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.
 */

enum EffectiveConnectionType {
    "slow-2g",
    "2g",
    "3g",
    "4g"
};

[
    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);
    unsigned long getResourcePriority (DOMString url, Document document);
    DOMString getResourceHeader (DOMString url, DOMString header, Document document);

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

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

    [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);
    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);
    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] 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 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 pausableObjectCount(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] 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);

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

    bool 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;

    // 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;
    const unsigned short LAYER_TREE_INCLUDES_PAINT_RECORDS = 64;
    const unsigned short OUTPUT_AS_LAYER_TREE = 0x4000;

    [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] DOMRectList nonFastScrollableRects(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 setMediaElementNetworkState(HTMLMediaElement element, long state);
    void setPersistent(HTMLVideoElement video, boolean persistent);

    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 updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(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);

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

    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, sequence<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(HTMLInputElement element, DOMString value);

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

    boolean ignoreLayoutWithPendingStylesheets(Document document);

    // These functions are for testing NetInfo. You must call clearNetworkConnectionInfoOverride() at the end.
    [RaisesException] void setNetworkConnectionInfoOverride(boolean onLine, DOMString type, double downlinkMaxMbps);
    [RaisesException] void setNetworkQualityInfoOverride(EffectiveConnectionType effective_type, unsigned long transport_rtt_msec, double downlink_throughput_mbps);
    void setSaveDataEnabled(boolean enabled);
    void clearNetworkConnectionInfoOverride();

    // 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 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, unsigned long feature);
    boolean isCSSPropertyUseCounted(Document document, DOMString propertyName);
    boolean isAnimatedCSSPropertyUseCounted(Document document, DOMString propertyName);

    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<bool> 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();

    DOMRectList focusRingRects(Element element);
    DOMRectList 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);

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

    // Bypass the threshold of 'script-compile' of long-task attribution in
    // PerformanceMonitor for testing. "PerformanceObserver should be observing
    // 'longtask' while calling BypassLongCompileThresholdOnce.
    [RaisesException] void BypassLongCompileThresholdOnce();
};
