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

    GCObservation observeGC(any observed);

    [RaisesException] DOMString elementRenderTreeAsText(Element element);
    boolean isPreloaded(DOMString url);
    boolean isLoadingFromMemoryCache(DOMString url);

    void crash();

    void setStyleResolverStatsEnabled(boolean enabled);
    [RaisesException] DOMString styleResolverStatsReport();
    [RaisesException] DOMString styleResolverStatsTotalsReport();

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

    [RaisesException] CSSStyleDeclaration computedStyleIncludingVisitedInfo(Node node);

    [RaisesException] ShadowRoot shadowRoot(Element host);
    [RaisesException] ShadowRoot youngestShadowRoot(Element host);
    [RaisesException] 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);
    [RaisesException] DOMString shadowPseudoId(Element element);
    [RaisesException] void setShadowPseudoId(Element element, DOMString id);
    [RaisesException] boolean isValidContentSelect(Element contentElement);
    [RaisesException] Node treeScopeRootNode(Node node);
    [RaisesException] 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] boolean hasSelectorForPseudoClassInShadow(Element host, DOMString pseudoClass);
    [RaisesException] unsigned short compareTreeScopePosition(Node treeScope1, Node treeScope2);
    [RaisesException] unsigned long updateStyleAndReturnAffectedElementCount();
    [RaisesException] unsigned long needsLayoutCount();

    // CSS Animation and Transition testing.
    unsigned long numberOfActiveAnimations();
    [RaisesException] void pauseAnimations(double pauseTime);

    [RaisesException] Node nextSiblingByWalker(Node node);
    [RaisesException] Node firstChildByWalker(Node node);
    [RaisesException] Node lastChildByWalker(Node node);
    [RaisesException] Node nextNodeByWalker(Node node);
    [RaisesException] Node previousNodeByWalker(Node node);

    DOMString visiblePlaceholder(Element element);

    void selectColorInColorChooser(Element element, DOMString colorValue);

    // 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);
    [RaisesException] void setEnableMockPagePopup(boolean enabled);
    readonly attribute PagePopupController pagePopupController;

    [RaisesException] ClientRect unscaledViewportRect();

    [RaisesException] ClientRect absoluteCaretBounds();

    [RaisesException] ClientRect boundingBox(Element element);

    [RaisesException] unsigned long markerCountForNode(Node node, DOMString markerType);
    [RaisesException] 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);
    [RaisesException] void setMarkersActive(Node node, unsigned long startOffset, unsigned long endOffset, boolean active);
    [RaisesException] void setMarkedTextMatchesAreHighlighted(Document document, boolean highlight);

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

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

    [RaisesException] boolean wasLastChangeUserEdit(Element textField);
    [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);

    [RaisesException] void scrollElementToRect(Element element, long x, long y, long w, long h);

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

    [RaisesException] WebKitPoint 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] WebKitPoint 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);

    [RaisesException] unsigned long activeDOMObjectCount(Document document);
    [RaisesException] unsigned long wheelEventHandlerCount(Document document);
    [RaisesException] unsigned long scrollEventHandlerCount(Document document);
    [RaisesException] unsigned long touchEventHandlerCount(Document document);
    [RaisesException] LayerRectList touchEventTargetLayerRects(Document document);


    [RaisesException] NodeList nodesFromRect(Document document, long x, long y,
        unsigned long topPadding, unsigned long rightPadding, unsigned long bottomPadding, unsigned long leftPadding,
        boolean ignoreClipping, boolean allowShadowContent, boolean allowChildFrameContent);

    void emitInspectorDidBeginFrame(optional long frameId);
    void emitInspectorDidCancelFrame();

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

    [RaisesException] boolean isOverwriteModeEnabled(Document document);
    [RaisesException] void toggleOverwriteModeEnabled(Document document);

    [RaisesException] unsigned long numberOfScrollableAreas(Document document);

    [RaisesException] boolean isPageBoxVisible(Document document, long pageNumber);

    readonly attribute InternalSettings settings;
    readonly attribute InternalProfilers profilers;
    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 LayerTreeAsTextBehaviorFlags in GraphicsLayerClient.h.
    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;
    [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);
    [RaisesException] boolean isUnclippedDescendant(Element element);

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

    [RaisesException] DOMString repaintRectsAsText(Document document);
    [RaisesException] ClientRectList repaintRects(Element element);

    [RaisesException] void garbageCollectDocumentResources(Document document);
    void evictAllResources();

    void allowRoundingHacks();

    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);
    [RaisesException] void setInspectorResourcesDataSizeLimits(long maximumResourcesContentSize, long maximumSingleResourceContentSize);

    DOMString counterValue(Element element);
    long pageNumber(Element element, optional float pageWidth, optional float pageHeight);
    DOMString[] shortcutIconURLs(Document document);
    DOMString[] allIconURLs(Document document);
    long numberOfPages(optional double pageWidthInPixels, optional double pageHeightInPixels);
    [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 setDeviceScaleFactor(float scaleFactor);

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

    void webkitWillEnterFullScreenForElement(Document document, Element element);
    void webkitDidEnterFullScreenForElement(Document document, Element element);
    void webkitWillExitFullScreenForElement(Document document, Element element);
    void webkitDidExitFullScreenForElement(Document document, Element element);

    void mediaPlayerRequestFullscreen(HTMLMediaElement mediaElement);

    void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme);
    void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(DOMString scheme);

    MallocStatistics mallocStatistics();
    TypeConversions typeConversions();

    DOMString[] getReferencedFilePaths();

    // These functions both reset the tracked repaint rects. They are inteded 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);

    [RaisesException] void forceFullRepaint(Document document);

    // 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.
    [RaisesException] DOMString getCurrentCursorInfo(Document document);

    [RaisesException] DOMString markerTextForListItem(Element element);

    [RaisesException] DOMString baseURL(Document document);

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

    void forceReload(boolean endToEnd);

    [RaisesException] DOMString getImageSourceURL(Element element);

    boolean isSelectPopupVisible(Node node);

    [RaisesException] ClientRect selectionBounds();

    boolean loseSharedGraphicsContext3D();

    [RaisesException] void forceCompositingUpdate(Document document);

    void setZoomFactor(float factor);

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

    [CallWith=ScriptState] Promise createPromise();
    [CallWith=ScriptState] Promise createResolvedPromise(any value);
    [CallWith=ScriptState] Promise createRejectedPromise(any reason);
    [CallWith=ExecutionContext] Promise addOneToPromise(Promise promise);

    void setValueForUser(Element element, DOMString value);

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

    void setFocused(boolean focused);

    [RaisesException] 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);
};
