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

[
    OmitConstructor
] interface Internals {
    DOMString address(in Node node);

    DOMString elementRenderTreeAsText(in Element element) raises(DOMException);
    boolean isPreloaded(in DOMString url);
    boolean isLoadingFromMemoryCache(in DOMString url);

    unsigned long numberOfScopedHTMLStyleChildren(in Node scope) raises(DOMException);
    CSSStyleDeclaration computedStyleIncludingVisitedInfo(in Node node) raises(DOMException);

#if defined(ENABLE_SHADOW_DOM) && ENABLE_SHADOW_DOM
    ShadowRoot ensureShadowRoot(in Element host) raises (DOMException);
    ShadowRoot createShadowRoot(in Element host) raises (DOMException);
    ShadowRoot shadowRoot(in Element host) raises (DOMException);
    ShadowRoot youngestShadowRoot(in Element host) raises (DOMException);
    ShadowRoot oldestShadowRoot(in Element host) raises (DOMException);
    ShadowRoot youngerShadowRoot(in Node root) raises (DOMException);
    ShadowRoot olderShadowRoot(in Node root) raises (DOMException);
#else
    Node ensureShadowRoot(in Element host) raises (DOMException);
    Node createShadowRoot(in Element host) raises (DOMException);
    Node shadowRoot(in Element host) raises (DOMException);
    Node youngestShadowRoot(in Element host) raises (DOMException);
    Node oldestShadowRoot(in Element host) raises (DOMException);
    Node youngerShadowRoot(in Node root) raises (DOMException);
#endif
    DOMString shadowRootType(in Node root) raises (DOMException);
    boolean hasShadowInsertionPoint(in Node root) raises (DOMException);
    boolean hasContentElement(in Node root) raises (DOMException);
    unsigned long countElementShadow(in Node Root) raises (DOMException);
    Element includerFor(in Node node) raises (DOMException);
    DOMString shadowPseudoId(in Element element) raises (DOMException);
    void setShadowPseudoId(in Element element, in DOMString id) raises (DOMException);
    Element createContentElement() raises(DOMException);
    boolean isValidContentSelect(in Element contentElement) raises(DOMException);
    Node treeScopeRootNode(in Node node) raises (DOMException);
    Node parentTreeScope(in Node node) raises (DOMException);
    boolean hasSelectorForIdInShadow(in Element host, in DOMString id) raises (DOMException);
    boolean hasSelectorForClassInShadow(in Element host, in DOMString className) raises (DOMException);
    boolean hasSelectorForAttributeInShadow(in Element host, in DOMString attributeName) raises (DOMException);
    boolean hasSelectorForPseudoClassInShadow(in Element host, in DOMString pseudoClass) raises (DOMException);

    // CSS Animation testing.
    unsigned long numberOfActiveAnimations();
    void suspendAnimations(in Document document) raises (DOMException);
    void resumeAnimations(in Document document) raises (DOMException);
    boolean pauseAnimationAtTimeOnElement(in DOMString animationName, in double pauseTime, in Element element) raises (DOMException);
    boolean pauseAnimationAtTimeOnPseudoElement(in DOMString animationName, in double pauseTime, in Element element, in DOMString pseudoId) raises (DOMException);

    // CSS Transition testing.
    boolean pauseTransitionAtTimeOnElement(in DOMString propertyName, in double pauseTime, in Element element) raises (DOMException);
    boolean pauseTransitionAtTimeOnPseudoElement(in DOMString property, in double pauseTime, in Element element, in DOMString pseudoId) raises (DOMException);

    Node nextSiblingByWalker(in Node node) raises(DOMException);
    Node firstChildByWalker(in Node node) raises(DOMException);
    Node lastChildByWalker(in Node node) raises(DOMException);
    Node nextNodeByWalker(in Node node) raises(DOMException);
    Node previousNodeByWalker(in Node node) raises(DOMException);

    boolean attached(in Node node) raises(DOMException);

    DOMString visiblePlaceholder(in Element element);
#if defined(ENABLE_INPUT_TYPE_COLOR) && ENABLE_INPUT_TYPE_COLOR
    void selectColorInColorChooser(in Element element, in DOMString colorValue);
#endif
    DOMString[] formControlStateOfPreviousHistoryItem() raises(DOMException);
    void setFormControlStateOfPreviousHistoryItem(in sequence<DOMString> values) raises(DOMException);
    void setEnableMockPagePopup(in boolean enabled) raises(DOMException);
#if defined(ENABLE_PAGE_POPUP) && ENABLE_PAGE_POPUP
    readonly attribute PagePopupController pagePopupController;
#endif

    ClientRect absoluteCaretBounds() raises(DOMException);

    ClientRect boundingBox(in Element element) raises(DOMException);

    ClientRectList inspectorHighlightRects(in Document document) raises (DOMException);

    void setBackgroundBlurOnNode(in Node node, in long blurLength) raises(DOMException);

    unsigned long markerCountForNode(in Node node, in DOMString markerType) raises(DOMException);
    Range markerRangeForNode(in Node node, in DOMString markerType, in unsigned long index) raises(DOMException);
    DOMString markerDescriptionForNode(in Node node, in DOMString markerType, in unsigned long index) raises(DOMException);
    void addTextMatchMarker(in Range range, in boolean isActive);

    void setScrollViewPosition(in Document document, in long x, in long y) raises(DOMException);

    void setPagination(in Document document, in DOMString mode, in long gap, in [Optional] long pageLength) raises(DOMException);

    DOMString configurationForViewport(in Document document,
                                       in float devicePixelRatio,
                                       in long deviceWidth,
                                       in long deviceHeight,
                                       in long availableWidth,
                                       in long availableHeight) raises(DOMException);

    boolean wasLastChangeUserEdit(in Element textField) raises (DOMException);
    DOMString suggestedValue(in Element inputElement) raises (DOMException);
    void setSuggestedValue(in Element inputElement, in DOMString value) raises (DOMException);
    void setEditingValue(in Element inputElement, in DOMString value) raises (DOMException);
    void setAutofilled(in Element inputElement, in boolean enabled) raises(DOMException);

    void paintControlTints(in Document document) raises (DOMException);

    void scrollElementToRect(in Element element, in long x, in long y, in long w, in long h) raises (DOMException);

    Range rangeFromLocationAndLength(in Element scope, in long rangeLocation, in long rangeLength) raises (DOMException);
    unsigned long locationFromRange(in Element scope, in Range range) raises (DOMException);
    unsigned long lengthFromRange(in Element scope, in Range range) raises (DOMException);
    DOMString rangeAsText(in Range range) raises (DOMException);

    void setDelegatesScrolling(in boolean enabled, in Document document) raises (DOMException);
#if defined(ENABLE_TOUCH_ADJUSTMENT) && ENABLE_TOUCH_ADJUSTMENT
    WebKitPoint touchPositionAdjustedToBestClickableNode(in long x, in long y, in long width, in long height, in Document document) raises (DOMException);
    Node touchNodeAdjustedToBestClickableNode(in long x, in long y, in long width, in long height, in Document document) raises (DOMException);
    WebKitPoint touchPositionAdjustedToBestContextMenuNode(in long x, in long y, in long width, in long height, in Document document) raises (DOMException);
    Node touchNodeAdjustedToBestContextMenuNode(in long x, in long y, in long width, in long height, in Document document) raises (DOMException);
    ClientRect bestZoomableAreaForTouchPoint(in long x, in long y, in long width, in long height, in Document document) raises (DOMException);
#endif

    long lastSpellCheckRequestSequence(in Document document) raises (DOMException);
    long lastSpellCheckProcessedSequence(in Document document) raises (DOMException);

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

    unsigned long wheelEventHandlerCount(in Document document) raises (DOMException);
    unsigned long touchEventHandlerCount(in Document document) raises (DOMException);
#if defined(ENABLE_TOUCH_EVENT_TRACKING) && ENABLE_TOUCH_EVENT_TRACKING
    ClientRectList touchEventTargetClientRects(in Document document) raises (DOMException);
#endif

    NodeList nodesFromRect(in Document document, in long x, in long y,
        in unsigned long topPadding, in unsigned long rightPadding, in unsigned long bottomPadding, in unsigned long leftPadding,
        in boolean ignoreClipping, in boolean allowShadowContent, in boolean allowChildFrameContent) raises (DOMException);

    void emitInspectorDidBeginFrame();
    void emitInspectorDidCancelFrame();

    boolean hasSpellingMarker(in Document document, in long from, in long length) raises (DOMException);
    boolean hasGrammarMarker(in Document document, in long from, in long length) raises (DOMException);
    boolean hasAutocorrectedMarker(in Document document, in long from, in long length) raises (DOMException);

    unsigned long numberOfScrollableAreas(in Document document) raises (DOMException);

    boolean isPageBoxVisible(in Document document, in long pageNumber) raises (DOMException);

    readonly attribute InternalSettings settings;
    readonly attribute unsigned long workerThreadCount;

    // Flags for layerTreeAsText.
    const unsigned short LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1;
    const unsigned short LAYER_TREE_INCLUDES_TILE_CACHES = 2;
    const unsigned short LAYER_TREE_INCLUDES_REPAINT_RECTS = 4;
    DOMString layerTreeAsText(in Document document, in [Optional] unsigned short flags) raises (DOMException);

    DOMString scrollingStateTreeAsText(in Document document) raises (DOMException);
    DOMString mainThreadScrollingReasons(in Document document) raises (DOMException);
    ClientRectList nonFastScrollableRects(in Document document) raises (DOMException);

    DOMString repaintRectsAsText(in Document document) raises (DOMException);

    void garbageCollectDocumentResources(in Document document) raises (DOMException);

    void allowRoundingHacks();

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

#if defined(ENABLE_BATTERY_STATUS) && ENABLE_BATTERY_STATUS
    void setBatteryStatus(in Document document, in DOMString eventType, in boolean charging, in double chargingTime, in double dischargingTime, in double level) raises (DOMException);
#endif

#if defined(ENABLE_NETWORK_INFO) && ENABLE_NETWORK_INFO
    void setNetworkInformation(in Document document, in DOMString eventType, in double bandwidth, in boolean metered) raises (DOMException);
#endif

#if defined(ENABLE_PROXIMITY_EVENTS) && ENABLE_PROXIMITY_EVENTS
    void setDeviceProximity(in Document document, in DOMString eventType, in double value, in double min, in double max) raises (DOMException);
#endif

    [Conditional=INSPECTOR] unsigned long numberOfLiveNodes();
    [Conditional=INSPECTOR] unsigned long numberOfLiveDocuments();
    [Conditional=INSPECTOR] sequence<DOMString> consoleMessageArgumentCounts(in Document document);
    [Conditional=INSPECTOR] DOMWindow openDummyInspectorFrontend(in DOMString url);
    [Conditional=INSPECTOR] void closeDummyInspectorFrontend();
    [Conditional=INSPECTOR] void setInspectorResourcesDataSizeLimits(in long maximumResourcesContentSize, in long maximumSingleResourceContentSize) raises(DOMException);
    [Conditional=INSPECTOR] void setJavaScriptProfilingEnabled(in boolean creates) raises(DOMException);

    DOMString counterValue(in Element element);
    long pageNumber(in Element element, in [Optional] float pageWidth, in [Optional] float pageHeight);
    DOMString[] iconURLs(in Document document);
    long numberOfPages(in [Optional] double pageWidthInPixels, in [Optional] double pageHeightInPixels);
    DOMString pageProperty(in DOMString propertyName, in long pageNumber) raises (DOMException);
    DOMString pageSizeAndMarginsInPixels(in long pageIndex, in long width, in long height, in long marginTop, in long marginRight, in long marginBottom, in long marginLeft) raises (DOMException);

    void setPageScaleFactor(in float scaleFactor, in long x, in long y) raises(DOMException);

#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
    void webkitWillEnterFullScreenForElement(in Document document, in Element element);
    void webkitDidEnterFullScreenForElement(in Document document, in Element element);
    void webkitWillExitFullScreenForElement(in Document document, in Element element);
    void webkitDidExitFullScreenForElement(in Document document, in Element element);
#endif

    void registerURLSchemeAsBypassingContentSecurityPolicy(in DOMString scheme);
    void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(in 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.
    void startTrackingRepaints(in Document document) raises (DOMException);
    void stopTrackingRepaints(in Document document) raises (DOMException);

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

    DOMString markerTextForListItem(in Element element) raises (DOMException);

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

    void setUsesOverlayScrollbars(in boolean enabled);

    [Conditional=ENCRYPTED_MEDIA_V2] void initializeMockCDM();

    [Conditional=SPEECH_SYNTHESIS] void enableMockSpeechSynthesizer();
};
