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

    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);
    boolean elementShouldAutoComplete(in Element inputElement) 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);
    void setContinuousSpellCheckingEnabled(in boolean enabled) raises (DOMException);

    boolean isOverwriteModeEnabled(in Document document) raises (DOMException);
    void toggleOverwriteModeEnabled(in Document document) 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;
    const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 8;
    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[] shortcutIconURLs(in Document document);
    DOMString[] allIconURLs(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);

    void setHeaderHeight(in Document document, in float height);
    void setFooterHeight(in Document document, in float height);

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

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

    void forceReload(in boolean endToEnd);

    [Conditional=VIDEO] void simulateAudioInterruption(in Node node);

    [Conditional=ENCRYPTED_MEDIA_V2] void initializeMockCDM();

    [Conditional=SPEECH_SYNTHESIS] void enableMockSpeechSynthesizer();

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

    boolean isSelectPopupVisible(in Node node);
};
