/*
 * 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 {
    DOMString address(Node node);

    GCObservation observeGC(any observed);

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

    void crash();

    [RaisesException] unsigned long numberOfScopedHTMLStyleChildren(Node scope);
    [RaisesException] CSSStyleDeclaration computedStyleIncludingVisitedInfo(Node node);

    [RaisesException] ShadowRoot ensureShadowRoot(Element host);
    [RaisesException] ShadowRoot shadowRoot(Element host);
    [RaisesException] ShadowRoot youngestShadowRoot(Element host);
    [RaisesException] ShadowRoot oldestShadowRoot(Element host);
    [RaisesException] ShadowRoot youngerShadowRoot(Node root);
    [RaisesException] ShadowRoot olderShadowRoot(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] Element createContentElement();
    [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);

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

    [RaisesException] DOMString[] formControlStateOfPreviousHistoryItem();
    [RaisesException] void setFormControlStateOfPreviousHistoryItem(sequence<DOMString> values);
    [RaisesException] void setEnableMockPagePopup(boolean enabled);
    readonly attribute PagePopupController pagePopupController;

    [RaisesException] ClientRect unscaledViewportRect();

    [RaisesException] ClientRect absoluteCaretBounds();

    [RaisesException] ClientRect boundingBox(Element element);

    [RaisesException] ClientRectList inspectorHighlightRects(Document document);

    [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 setScrollViewPosition(Document document, long x, long y);

    [RaisesException] void setPagination(Document document, DOMString mode, long gap, optional long pageLength);

    [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 paintControlTints(Document document);

    [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 wheelEventHandlerCount(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] NodeList paintOrderListBeforePromote(Element element);
    [RaisesException] NodeList paintOrderListAfterPromote(Element element);

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

    // The values of these constants must be kept in sync with those in RenderLayer.
    const unsigned short DO_NOT_FORCE_COMPOSITED_SCROLLING = 0;
    const unsigned short COMPOSITED_SCROLLING_ALWAYS_ON = 1;
    const unsigned short COMPOSITED_SCROLLING_ALWAYS_OFF = 2;
    [RaisesException] void setNeedsCompositedScrolling(Element element, unsigned short value);

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

    [RaisesException] DOMString repaintRectsAsText(Document document);

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

    void allowRoundingHacks();

    void insertAuthorCSS(Document document, DOMString css);
    void insertUserCSS(Document document, DOMString css);

    unsigned long numberOfLiveNodes();
    unsigned long numberOfLiveDocuments();
    sequence<DOMString> consoleMessageArgumentCounts(Document document);
    Window openDummyInspectorFrontend(DOMString url);
    void closeDummyInspectorFrontend();
    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 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);

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