Changeset 72683 in webkit


Ignore:
Timestamp:
Nov 24, 2010 10:03:41 AM (13 years ago)
Author:
caseq@chromium.org
Message:

2010-11-24 Andrey Kosyakov <caseq@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: extension API cleanup
https://bugs.webkit.org/show_bug.cgi?id=50019

  • inspector/front-end/ElementsPanel.js: (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged): (WebInspector.ElementsPanel):
  • inspector/front-end/ExtensionAPI.js: See bug for summary of extension API changes. (WebInspector.injectedExtensionAPI.Resources.resourceDispatch): (WebInspector.injectedExtensionAPI): (WebInspector.injectedExtensionAPI.Resources.prototype.getHAR): (WebInspector.injectedExtensionAPI.ResourceImpl.prototype.getContent): (WebInspector.injectedExtensionAPI.Panels.prototype.create): (WebInspector.injectedExtensionAPI.PanelImpl): (WebInspector.injectedExtensionAPI.PanelWithSidebarImpl): (WebInspector.injectedExtensionAPI.PanelWithSidebarImpl.prototype.createSidebarPane): (WebInspector.injectedExtensionAPI.PanelWithSidebarImpl.prototype.createWatchExpressionSidebarPane): (WebInspector.injectedExtensionAPI.ElementsPanel): (WebInspector.injectedExtensionAPI.ExtensionSidebarPaneImpl.prototype.setHeight): (WebInspector.injectedExtensionAPI.Audits.prototype.addCategory): (WebInspector.injectedExtensionAPI.AuditCategoryImpl.auditResultDispatch): (WebInspector.injectedExtensionAPI.AuditCategoryImpl): (WebInspector.injectedExtensionAPI.AuditResultImpl.prototype.get Severity): (WebInspector.injectedExtensionAPI.InspectedWindow): (WebInspector.injectedExtensionAPI.InspectedWindow.prototype.eval):
  • inspector/front-end/ExtensionCommon.js: (WebInspector.commonExtensionSymbols):
  • inspector/front-end/ExtensionServer.js: (WebInspector.ExtensionServer): (WebInspector.ExtensionServer.prototype.notifyObjectSelected): (WebInspector.ExtensionServer.prototype.notifyResourceFinished): (WebInspector.ExtensionServer.prototype.notifyPageLoaded): (WebInspector.ExtensionServer.prototype.notifyPageDOMContentLoaded): (WebInspector.ExtensionServer.prototype._onCreatePanel): (WebInspector.ExtensionServer.prototype._onReload): (WebInspector.ExtensionServer.prototype._onGetHAR): (WebInspector.ExtensionServer.prototype._onGetResourceContent): (WebInspector.ExtensionServer.prototype._onAddAuditCategory): (WebInspector.ExtensionServer.prototype._buildExtensionAPIInjectedScript):
  • inspector/front-end/HAREntry.js: (WebInspector.HARLog): (WebInspector.HARLog.prototype.build): (WebInspector.HARLog.prototype._convertResource):
  • inspector/front-end/inspector.js: (WebInspector.domContentEventFired): (WebInspector.loadEventFired): (WebInspector.didCommitLoad):

2010-11-24 Andrey Kosyakov <caseq@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: extension API cleanup
Improve synchronization between different parts of the test to reduce flakiness.
https://bugs.webkit.org/show_bug.cgi?id=50019

  • http/tests/inspector/inspector-test2.js: Clean inspected page test output before pushing output from front-end. (initialize_InspectorTest.InspectorTest.completeTest): Delay test completion until page's onload is completed after reload. (initialize_InspectorTest.InspectorTest.addResult.clearResults): (initialize_InspectorTest.InspectorTest.reloadPageIfNeeded): (output):
  • inspector/extensions-api-expected.txt:
  • inspector/extensions-audits-api-expected.txt:
  • inspector/extensions-audits-expected.txt:
  • inspector/extensions-audits-tests.js: (extension_runAudits): (initialize_ExtensionsAuditsTest.InspectorTest.startExtensionAudits.onAuditsDone): (initialize_ExtensionsAuditsTest.InspectorTest.startExtensionAudits): (initialize_ExtensionsAuditsTest): (test):
  • inspector/extensions-eval-expected.txt:
  • inspector/extensions-eval.html:
  • inspector/extensions-events-expected.txt:
  • inspector/extensions-events.html:
  • inspector/extensions-resources-expected.txt:
  • inspector/extensions-resources.html:
  • inspector/extensions-test.js: (initialize_ExtensionsTest.InspectorTest.dispatchOnMessage): (initialize_ExtensionsTest.InspectorTest.runExtensionTests): (initialize_ExtensionsTest.extensionOutput): (initialize_ExtensionsTest.dumpSidebarContent): (initialize_ExtensionsTest.reloadPage):
  • inspector/extensions.html:
  • inspector/resources/extension-main.html:
  • inspector/resources/extension-main.js: (fetchTests.callback): (fetchTests): (onTestsDone): (dispatchOnFrontend):
Location:
trunk
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r72682 r72683  
     12010-11-24  Andrey Kosyakov  <caseq@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: extension API cleanup
     6        Improve synchronization between different parts of the test to reduce flakiness.
     7        https://bugs.webkit.org/show_bug.cgi?id=50019
     8
     9        * http/tests/inspector/inspector-test2.js: Clean inspected page test output before pushing output from front-end.
     10        (initialize_InspectorTest.InspectorTest.completeTest): Delay test completion until page's onload is completed after reload.
     11        (initialize_InspectorTest.InspectorTest.addResult.clearResults):
     12        (initialize_InspectorTest.InspectorTest.reloadPageIfNeeded):
     13        (output):
     14        * inspector/extensions-api-expected.txt:
     15        * inspector/extensions-audits-api-expected.txt:
     16        * inspector/extensions-audits-expected.txt:
     17        * inspector/extensions-audits-tests.js:
     18        (extension_runAudits):
     19        (initialize_ExtensionsAuditsTest.InspectorTest.startExtensionAudits.onAuditsDone):
     20        (initialize_ExtensionsAuditsTest.InspectorTest.startExtensionAudits):
     21        (initialize_ExtensionsAuditsTest):
     22        (test):
     23        * inspector/extensions-eval-expected.txt:
     24        * inspector/extensions-eval.html:
     25        * inspector/extensions-events-expected.txt:
     26        * inspector/extensions-events.html:
     27        * inspector/extensions-resources-expected.txt:
     28        * inspector/extensions-resources.html:
     29        * inspector/extensions-test.js:
     30        (initialize_ExtensionsTest.InspectorTest.dispatchOnMessage):
     31        (initialize_ExtensionsTest.InspectorTest.runExtensionTests):
     32        (initialize_ExtensionsTest.extensionOutput):
     33        (initialize_ExtensionsTest.dumpSidebarContent):
     34        (initialize_ExtensionsTest.reloadPage):
     35        * inspector/extensions.html:
     36        * inspector/resources/extension-main.html:
     37        * inspector/resources/extension-main.js:
     38        (fetchTests.callback):
     39        (fetchTests):
     40        (onTestsDone):
     41        (dispatchOnFrontend):
     42
    1432010-11-23  Jeremy Orlow  <jorlow@chromium.org>
    244
  • trunk/LayoutTests/http/tests/inspector/inspector-test2.js

    r71035 r72683  
    3939        addResultToPage(text);
    4040    else {
     41        clearResults();
    4142        for (var i = 0; i < results.length; ++i)
    4243            addResultToPage(results[i]);
    4344        resultsSynchronized = true;
     45    }
     46
     47    function clearResults()
     48    {
     49        InspectorTest.evaluateInPage("Array.prototype.forEach.call(document.body.querySelectorAll('div.output'), function(node) { node.parentNode.removeChild(node); })");
    4450    }
    4551
     
    8894        InspectorTest._pageWasReloaded = true;
    8995        InspectorTest.reloadPage(callback);
    90     } else
    91         callback();
     96    } else {
     97        if (callback)
     98            callback();
     99    }
    92100}
    93101
     
    230238{
    231239    var outputElement = document.createElement("div");
    232     outputElement.id = "output";
     240    outputElement.className = "output";
    233241    outputElement.style.whiteSpace = "pre";
    234242    outputElement.appendChild(document.createTextNode(text));
  • trunk/LayoutTests/inspector/extensions-api-expected.txt

    r71911 r72683  
    11Tests public interface of WebInspector Extensions API
    22
    3 Page reloaded.
    43Started extension.
    54Running tests...
     
    109    }
    1110    inspectedWindow : {
     11        onDOMContentLoaded : {
     12            addListener : <function>
     13            removeListener : <function>
     14        }
    1215        onLoaded : {
    1316            addListener : <function>
     
    1821            removeListener : <function>
    1922        }
    20         onDOMContentLoaded : {
    21             addListener : <function>
    22             removeListener : <function>
    23         }
    2423        reload : <function>
    25         evaluate : <function>
     24        eval : <function>
    2625    }
    2726    panels : {
    2827        elements : {
     28            createSidebarPane : <function>
     29            createWatchExpressionSidebarPane : <function>
    2930            onSelectionChanged : {
    3031                addListener : <function>
    3132                removeListener : <function>
    3233            }
    33             createSidebarPane : <function>
    34             createWatchExpressionSidebarPane : <function>
    35         }
    36         scripts : {
    37             onSelectionChanged : {
    38                 addListener : <function>
    39                 removeListener : <function>
    40             }
    41             createSidebarPane : <function>
    42             createWatchExpressionSidebarPane : <function>
    4334        }
    4435        create : <function>
     
    6051            Other : "other"
    6152        }
    62         getAll : <function>
    63         get : <function>
    64         getPageTimings : <function>
    65         getContent : <function>
     53        getHAR : <function>
    6654    }
    6755    onReset : {
  • trunk/LayoutTests/inspector/extensions-audits-api-expected.txt

    r71911 r72683  
    11Tests audits support in WebInspector Extensions API
    22
    3 Page reloaded.
    43Started extension.
    54Running tests...
     
    1211    }
    1312}
     13  Extension audits
    1414category.onAuditStarted fired, results dump follows:
    1515{
     
    3535    addChild : <function>
    3636}
    37   Extension audits
    3837All tests done.
    3938
  • trunk/LayoutTests/inspector/extensions-audits-expected.txt

    r66596 r72683  
    11Tests audits support in WebInspector Extensions API
    22
    3 Page reloaded.
    43Started extension.
    54Running tests...
    65RUNNING TEST: extension_testAudits
    76Added audit category.
    8 category.onAuditStarted fired
    9 failedCategory.onAuditStarted fired, throwing exception
    107  Extension audits
    118    Failed rule (42)
     
    2623     this rule always passes ok
    2724  Extension audits that fail
     25category.onAuditStarted fired
     26failedCategory.onAuditStarted fired, throwing exception
    2827All tests done.
    2928
  • trunk/LayoutTests/inspector/extensions-audits-tests.js

    r66477 r72683  
    11function extension_runAudits(callback)
    22{
    3     function onMessage(event)
    4     {
    5         if (event.data === "audits-complete")
    6             callback();
    7     }
    8     window.addEventListener("message", onMessage, false);
    9     top.postMessage("run-audits", "*");
     3    dispatchOnFrontend({ command: "run-audits" }, callback);
    104}
    115
     
    137var initialize_ExtensionsAuditsTest = function()
    148{
    15     InspectorTest.startExtensionAudits = function()
     9    InspectorTest.startExtensionAudits = function(message, port)
    1610    {
    1711        const launcherView = WebInspector.panels.audits._launcherView;
     
    2822        {
    2923            InspectorTest.collectAuditResults();
    30             for (var i = 0; i < frames.length; ++i)
    31                 frames[i].postMessage("audits-complete", "*");
     24            port.postMessage("");
    3225        }
     26        InspectorTest._addSniffer(WebInspector.panels.audits, "_auditFinishedCallback", onAuditsDone, true);
    3327
    34         InspectorTest._addSniffer(WebInspector.panels.audits, "_auditFinishedCallback", onAuditsDone, true);
    3528        launcherView._launchButtonClicked();
    3629    }
     
    4235    InspectorTest.runExtensionTests();
    4336}
    44 
  • trunk/LayoutTests/inspector/extensions-eval-expected.txt

    r66601 r72683  
    11Tests WebInspector extension API
    22
    3 Page reloaded.
    43Started extension.
    54Running tests...
  • trunk/LayoutTests/inspector/extensions-eval.html

    r66601 r72683  
    99function extension_testEvalOk(nextTest)
    1010{
    11     webInspector.inspectedWindow.evaluate("inspectedValue", callbackAndNextTest(extension_onEvaluate, nextTest));
     11    webInspector.inspectedWindow.eval("inspectedValue", callbackAndNextTest(extension_onEval, nextTest));
    1212}
    1313
    1414function extension_testEvalFailed(nextTest)
    1515{
    16     webInspector.inspectedWindow.evaluate("document.body", callbackAndNextTest(extension_onEvaluate, nextTest));
     16    webInspector.inspectedWindow.eval("document.body", callbackAndNextTest(extension_onEval, nextTest));
    1717}
    1818
    1919function extension_testEvalDefinesGlobalSymbols(nextTest)
    2020{
    21     webInspector.inspectedWindow.evaluate("function extensionFunc() {}");
    22     webInspector.inspectedWindow.evaluate("extensionVar = 42;");
    23     webInspector.inspectedWindow.evaluate("({ func: typeof window.extensionFunc, variable: window.extensionVar })", callbackAndNextTest(extension_onEvaluate, nextTest));
     21    webInspector.inspectedWindow.eval("function extensionFunc() {}");
     22    webInspector.inspectedWindow.eval("extensionVar = 42;");
     23    webInspector.inspectedWindow.eval("({ func: typeof window.extensionFunc, variable: window.extensionVar })", callbackAndNextTest(extension_onEval, nextTest));
    2424}
    2525
    2626function extension_testEvalStatement(nextTest)
    2727{
    28     webInspector.inspectedWindow.evaluate("var x = 3; while (--x); x", callbackAndNextTest(extension_onEvaluate, nextTest));
     28    webInspector.inspectedWindow.eval("var x = 3; while (--x); x", callbackAndNextTest(extension_onEval, nextTest));
    2929}
    3030
    3131function extension_testEvalUndefined(nextTest)
    3232{
    33     webInspector.inspectedWindow.evaluate("undefined", callbackAndNextTest(extension_onEvaluate, nextTest));
     33    webInspector.inspectedWindow.eval("undefined", callbackAndNextTest(extension_onEval, nextTest));
    3434}
    3535
    3636function extension_testEvalConsoleAPI(nextTest)
    3737{
    38     webInspector.inspectedWindow.evaluate("typeof inspect", callbackAndNextTest(extension_onEvaluate, nextTest));
     38    webInspector.inspectedWindow.eval("typeof inspect", callbackAndNextTest(extension_onEval, nextTest));
    3939}
    4040
    41 function extension_onEvaluate(result)
     41function extension_onEval(value, isException)
    4242{
    43     output("Evaluate: " + JSON.stringify(result.value) + " (exception: " + result.isException + ")");
     43    output("Evaluate: " + JSON.stringify(value) + " (exception: " + isException + ")");
    4444}
    4545
  • trunk/LayoutTests/inspector/extensions-events-expected.txt

    r71107 r72683  
    22Tests WebInspector extension API
    33
    4 Page reloaded.
    54Started extension.
    65Running tests...
    76RUNNING TEST: extension_testOnResourceFinished
    8 Got callback, arguments dump follows:
    9 {
    10     0 : {
    11         id : <number>
    12         type : "other"
    13         har : <object>
    14     }
    15 }
     7onFinished fired
    168RUNNING TEST: extension_testOnSelectionChanged
    17 Got callback, arguments dump follows:
    18 {
    19     0 : "DOMNode"
    20     1 : undefined
    21 }
     9onSelectionChanged fired
     10RUNNING TEST: extension_testPageLoadEvents
     11onDOMContentLoaded fired: number
     12onLoaded fired: number
     13Page reloaded.
    2214All tests done.
    2315
  • trunk/LayoutTests/inspector/extensions-events.html

    r66601 r72683  
    55<script type="text/javascript">
    66
    7 function extension_callback(nondetermenisticProps)
    8 {
    9     output("Got callback, arguments dump follows:");
    10     dumpObject(Array.prototype.slice.call(arguments, 1), nondetermenisticProps);
    11 }
    127
    138function extension_testOnSelectionChanged(nextTest)
    149{
    15     webInspector.panels.elements.onSelectionChanged.addListener(callbackAndNextTest(bind(extension_callback, null, null), nextTest));
    16     webInspector.inspectedWindow.evaluate("inspect(document.body.children[0])");
     10    function onSelectionChanged()
     11    {
     12        webInspector.panels.elements.onSelectionChanged.removeListener(onSelectionChanged);
     13        output("onSelectionChanged fired");
     14        nextTest();
     15    }
     16    webInspector.panels.elements.onSelectionChanged.addListener(onSelectionChanged);
     17    webInspector.inspectedWindow.eval("inspect(document.body.children[0])");
    1718}
    1819
    1920function extension_testOnResourceFinished(nextTest)
    2021{
    21     var nondetermenisticProps = {
    22         har: 1,
    23         id: 1
    24     };
    25     webInspector.resources.onFinished.addListener(callbackAndNextTest(bind(extension_callback, null, nondetermenisticProps), nextTest));
    26     webInspector.inspectedWindow.evaluate("var xhr = new XMLHttpRequest(); xhr.open('GET', '" + location.href + "', false); xhr.send(null);");
     22    function onFinished()
     23    {
     24        webInspector.resources.onFinished.removeListener(onFinished);
     25        output("onFinished fired");
     26        nextTest();
     27    }
     28    webInspector.resources.onFinished.addListener(onFinished);
     29    webInspector.inspectedWindow.eval("var xhr = new XMLHttpRequest(); xhr.open('GET', '" + location.href + "', false); xhr.send(null);");
     30}
     31
     32function extension_testPageLoadEvents(nextTest)
     33{
     34    var callbackCount = 0;
     35    webInspector.inspectedWindow.onDOMContentLoaded.addListener(function(time) {
     36        output("onDOMContentLoaded fired: " + typeof time);
     37    });
     38    webInspector.inspectedWindow.onLoaded.addListener(function(time) {
     39        output("onLoaded fired: " + typeof time);
     40        if (++callbackCount > 1)
     41            nextTest();
     42    });
     43    dispatchOnFrontend({ command: "reload" }, function() {
     44        if (++callbackCount > 1)
     45            nextTest();
     46    });
    2747}
    2848
  • trunk/LayoutTests/inspector/extensions-expected.txt

    r71911 r72683  
    11Tests WebInspector extension API
    22
    3 Page reloaded.
    43Started extension.
    54Running tests...
     
    87Panel created
    98{
    10     onSelectionChanged : {
    11         addListener : <function>
    12         removeListener : <function>
    13     }
    14     createSidebarPane : <function>
    15     createWatchExpressionSidebarPane : <function>
    169    onSearch : {
    1710        addListener : <function>
     
    2316{
    2417    setHeight : <function>
    25     setExpanded : <function>
    2618}
    2719RUNNING TEST: extension_testExtensionWatchSidebarExpression
    28 Sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: Objectf4: Array[0]f5: Array[3]f6: Objectf7: 42f8: Locationf9: HTMLCollection[26]f10: function () {}__proto__: Object
     20Sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: Objectf4: Array[0]f5: Array[3]f6: Objectf7: 42f8: Locationf9: HTMLCollection[18]f10: function () {}__proto__: Object
    2921RUNNING TEST: extension_testExtensionWatchSidebarObject
    3022Watch sidebar created, callback arguments dump follows:
     
    3830        setObject : <function>
    3931        setHeight : <function>
    40         setExpanded : <function>
    4132    }
    4233}
  • trunk/LayoutTests/inspector/extensions-resources-expected.txt

    r70248 r72683  
    55Started extension.
    66Running tests...
    7 RUNNING TEST: extension_testGetAllResources
    8 resource: .../tests/inspector/inspector-test2.js, type: script
    9 resource: .../LayoutTests/inspector/extensions-resources.html, type: document
    10 resource: .../LayoutTests/inspector/extensions-resources.html, type: xhr
    11 resource: .../LayoutTests/inspector/extensions-test.js, type: script
    12 resource: .../inspector/resources/abe.png, type: image
    13 resource: .../inspector/resources/Ahem.ttf, type: font
    14 resource: .../inspector/resources/audits-style1.css, type: stylesheet
    15 resource: .../inspector/resources/missing-image.png, type: other
    16 RUNNING TEST: extension_testGetInvalidResource
    17 Attempted to retrieve invalid resource: {"code":"E_NOTFOUND","description":"Object not found: %s","details":[2128506],"isError":true}
    18 RUNNING TEST: extension_testGetPageTimings
    19 Got callback from getPageTimings, pageTimings dump follows
    20 {
    21     onContentLoad : <number>
    22     onLoad : <number>
    23 }
     7RUNNING TEST: extension_testGetHAR
     8resource: .../tests/inspector/inspector-test2.js
     9resource: .../LayoutTests/inspector/extensions-resources.html
     10resource: .../LayoutTests/inspector/extensions-resources.html
     11resource: .../LayoutTests/inspector/extensions-test.js
     12resource: .../inspector/resources/abe.png
     13resource: .../inspector/resources/Ahem.ttf
     14resource: .../inspector/resources/audits-style1.css
     15resource: .../inspector/resources/missing-image.png
    2416RUNNING TEST: extension_testGetResourceContent
    2517{
    26     0 : {
    27         code : "E_NOTFOUND"
    28         description : "Object not found: %s"
    29         details : {
    30             0 : 2126506
    31         }
    32         isError : true
    33     }
    34     1 : {
    35         id : <number>
    36         encoding : ""
    37         content : ".some-style {
     18    0 : ".some-style {
    3819    vertical-align: middle;
    3920}"
    40     }
    41     2 : {
    42         id : <number>
    43         encoding : "base64"
    44         content : "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"
    45     }
    46     3 : {
    47         id : <number>
    48         encoding : "base64"
    49         content : ""
    50     }
     21    1 : ""
     22}
     23RUNNING TEST: extension_testGetResourceContentEncoded
     24{
     25    0 : "iVBORw0KGgoAAAANSUhEUgAAAEwAAABnCAIAAAAlnjOJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAgAElEQVR4nG18aWwc53n/zOzM7MzsfS93eR+ieIikpEhRSMmWLceKbTlHHcWuEzvNl7Qogh6figJFgaJo+6kFCjRAg7b/wklQF01huGkVqXIdybUs6qYkkuIlLsVdcsnl3vfs7Bz/Dz/O65Hc+UAs95h53/e5fs/ved6XvnLliiAIkiSxLGsYhqqqmqYZhiFJEsMwDMPQNE1RFE3T+FfTNI7jNE1rNpsMwzgcDk3TarWaLMs2m42m6Xa73W63dV2naZqmaUVROI4zDEOWZVVVbTYbwzC6rquq6nQ6OY5rNpuqqgqCIIoiwzA2m81ms2EkuImu6+12u9VqsSzL8zzHcbgJhtRsNvHCZrkwDF3XDcPQdZ1lWZZhGIqiDMPQNA0zpCiK4zhMDx/hTYqiWJbFg202myiKgiBUKpVSqeTxeDRNoyjKbrczDFOv19vtNsMwdrsd70uSRFGUpmk0TbMs22g02u22oig2m83lcgmCYBiGoiiGYdA0bbPZsDT4ia7ruC0mQFEUmT9GRZsXmTxkhnmyeJdMmqIoSMxms+H3+IjIs91u22w2QRAwiHa7LQjCwMBAtVptNBqqqjIMYxgGFpvneciEpmmsWqvVwqdutxsyxDex8HgcGQOeqKqqYRj4OdEsiAQDI9MjI8c7hnntTxcLg5uyLAuFwb3IJHEjv99fr9cpioJ2lctlWZYZhnE6nTzPNxqNer2uqipugl9BWaClPM9jmXme53kez1VVVVEUu93ucrlqtZr1t0RuWDvKvMgEiOiIxhKzIprIkg8wdXIXVVXJ7awqkc1mY7GYJEk7OzuJRKLRaDidTrfbnclkfD6fIAiQm91u13W9VqsxDCMIAsuyWHioAEVRiqJomsYwDGyMoij8FUURiwKREtUlOgU54yNi+WRu5IKN7IsNC0AsDZdVy5957fV6DcO4efPme++99z//8z+GYYTDYZ7nR0ZGRkZGhoaG4E4wdLvdDj9EURTxGUQOeBZUl6IoWZZbrZYkSRAjRkkEiL+YFfGIEBcRI9784rBZuAee562W+owd4wcYmcfj+cUvfvH3f//3d+/edTgcsVis2WxmMpnNzc21tbXR0dFoNMrzvCAIoVAoHA7LspzL5QzDiEajDoejVCoVi0Vd191uN5RFkqRQKBQMBiEuKDP+4l/MBIqAsWFW+BcrQgRIZmhVeFaWZWgX+SWmBF2CYhC91XV9Z2dndnZ2aWnJ4/H4/f69vT1ZlgOBAMdxe3t7qqqur6/XarV2uz04OHj48OGtra3FxUVZlg8cOOByuVZXVzc2NnRdj0ajoijyPC+KYiwWGx0dHRgY8Hq9fr8fM7QKBMqFAdCWC6tg/ZdcVlulP/roIyy83W6HOkHuNput3W5rmoZ/8TOO44rF4uuvv64oSr1e9/l8HMeFw2GfzyfLcnd39+DgoMfjKZfLiUQikUjk8/ne3l5YYLFYzGaz5XIZHlWW5Xg8PjU1NTw8zDBMPp+nadrv9/M8H4/H3W63KIrxeDwajXIcp+u6LMuVSsXlcum6Xq1WodXQBSIMCBZ2QQx4P4QQr0OcOJQEVvGMiW5vb1erVV3XFUVpNBpYdVVVh4aGstlsKpXyer09PT39/f3d3d3VanVzc3Nvby+VSuVyORinruu4eblczmQyTqdT1/VkMpnL5XRdFwTBZrPV6/Vms+n1esfGxs6cOfP888+Louh2u3Vd5zjO7/djAoqiQPusUyIeFFPbRwK0JfLAAPA9q+pzHIfVymazxGspigK/Ui6XHz16JEkSx3F40+l09vb2dnZ2QrC6rrdaLcRYso6FQmFhYWF3d9dmsxWLRQiZ53m73W6321mW3draSiQS8/Pzs7Oz3/3udw8ePNhqtfDoSqUiCAKRkDUQYBEhVfhU1rBcVgDRbrdhqMShIaBls1m8Cd1GrG+32wQhYV1KpdLi4uLa2trk5GS9XoccKpUK5mm32ymKajQa+Xy+UCgg5DIMI4oiQBzDMA6HQxTFbDabSCTq9fqhQ4cOHjyIRzudTk3TXC4X4ASxQ6uzhNZAcp+DASussYYgMkng1fX19Waz2W63eZ4n8VBRFNgMYADmgH8rlQr0BTLHGuNuUA34GEgAklQUpVKp5PN5j8eDGNhoNBKJBOAxVBSBqlgs4llEOa2KSZu4l7Xa2zOOi3wbr2VZLhaLGxsbBDrjqbiRLMtOp5PgdSAYt9tdKBTISkP4WBTgZswTYJCoGcwSC0dRVLvdrtVqxWKRoqiOjo56vd5qter1OsIeFIc2MToJB0CduCdrxQpWR0wsk8DaZrOZz+eTySRN05IkSZJUq9XgfgVBCIfD0AiGYdxuN/KGSqXi8XhgpbQJX9vtNlARAhXcG8/zUP5WqwU5Q+wYrtPp3NnZWVhYiEQigiDAcCiKikajlUqFwF3ERowWd8Pkn4J1VgsmYsQk8fhqtbq1tdVut91ut9vthspJkiSKIoTZarVkWSbQmef5arVKVAjo/Bm8BuNhGAZAD+CWYRgAQNyNoqibN2/+5Cc/efLkyeTk5OjoqM/nKxQK9XqdRAvc8IvhgAJ2pU1Ah9kTcCcIQrPZhEpkMhmPx1MqlTiO83g8rVZrb28PobXZbBYKBSIiEog1TVNVleM4uERJkmCWHo+nu7v71KlTHo/HbrdnMpmHDx8uLy9DsRGfobGyLPM873K54Ic2NjZ+/OMfd3d3/8mf/MmhQ4fcbne9Xif6iVlggaCrJJywBBnQT+M9hmGq1SrBVj6fr9lsrqys1Go1Ak0Nw2g0Go1GA6OxomcSDAnCajabFEUNDg5+61vfeu211wKBgNPpZFm2XC4/efLkzp07Fy9evHnzJmMmaLVazTAMh8Oh63qpVIK3p2k6mUx+8MEHkUhEFEWHw/FM/mAN+5+DAZLFWMEAHGC9Xvd4PO12Gy7+8ePH169fR8Akwoc/FAQBVoeI0mq1cFugtna77ff7jx07dubMmampqWAwiPAF6woGg7FYbHx8fHBwcHx8/Fe/+lWtVqMoyuv11uv1vb09SZK6uroqlQpuW61WL1y48Oabb4bDYbgx6yS/6DgpimKx2AQlkIUh6wG3ubW19fHHHy8tLTmdTiS4RE8Q91qtFuaPp9rt9mAw6Pf7jxw5Mjo6OjU1FY1GYfxgOoANcCuHw+H3+7/61a9OTU2NjY1dvHjx008/bbVayE5UVS2VSg6HQ1VVGGEmk0mn07FYDA+1Yh2M2TpJmqZZ4t8JJMBXVVUVRREq12637969e/XqVQwLnl2SJOgPbtTT0+P1ej0eD5TT4/H09fV1dXW99tprZAU5jmNZVpblUqkUCAQMwyCcCHLlrq6uH/zgB4cPH37//fcvXbpULpcFQdA0rdVqwYBrtRrP861Wa3Z2dnx8nCCQZ5SWMrNTiGo/n8RbJIWDE2dZFjRUrVa7f//+9vY2LARenud5n88niqLP5wsEArFYLBgMRiIRl8vF87zb7e7o6AiHw6VSSRAEnufhh3Bbn8+H8AO/wnEcqBObzaZp2pe+9CW/3z8yMnL16tU7d+7IstzX15fP5wOBgKIoFEUpivLZZ59B8iRBsc6TspAJNE2zRImJJPE9nuehS5IkbWxsJBIJOGvIMBAIDA8Pd3d3e73eeDze1dXFcZwkSU6nU5IkUBvgphwOB5YPtqppGshBxNJ92MWy0Bo8vVwui6L42muvjY6O/vM///OVK1dKpRJE7XA46vW6ruuZTOb27ds9PT0+n49Mz7AwG1YagSUEjzVjhuVUKhW8yGazhULB6XSm02me5/1+/8TExMmTJ7u7uxEng8FgKBQCEoJHYVlW1/VGo2G32xVFAX7AxPA1wF3DMBAeRVG02WytVksQBIfDgfjp8/mCwSByFIZhIG1ZliGlhw8fQua0mXBaDfKpdARrjGfDqbIsC/0BebO7u8txXCAQqFQqTqezXq8fPnz4lVdeOXLkiMfjcblc8XgcYifTw63hQkneoCgKwdMkm8P6apqG3ApfQ0Byu91er3dwcLC/v98wDI/Hk0wmX331VQg8mUw+efJkfn4+k8k0Gg08FJQaQjdtITT2n0S0lMhdFEUomN1uD4fDSGTB5Rw7diwajbIsG4lEEA9gV4RlgxJi7axYioBJ60Otl2EYPM8DG0ELRkdHDx8+3NHRAQNjGOadd95BYgmxA98DDCPAgoaG/eMvQyjzZ9wsISAEQXC73WArGIZB+i9JkizLdrtdFEXDzMeRCsLkoAUej4cgB+sKGpY01wqSCcWGrN8wjL6+vhMnToyOjrbb7f7+/mq1OjMzMz09HYvFEokEQBISS8pk+mD2Vui2P8ln1pWsh91ux7eDwSCSPUmSYLSA7BRFQVdbT18knyYSfoZNszo5q6iBb51Op91uB//U2dk5OjoaDAZpml5eXq7VaiMjI8PDw5FIZGVlJZ/PI1ATnpHgWHLtJzhk0sTHwvWpqgr4euDAgXA4TDIMEMGNRkPTNEmSms0mSXNwQ+gqYBD9Baz/TEwjF8FM0FsAGkmSOjs7z549u76+Pj8/f+fOnUKhwHHcq6++2mg0lpeXK5UKYg/KLcAP1mVliMO1XlgMWZar1aqmaR6PZ3h4OBgMIqxhAojglUql2WxWKpVGo9FsNlutFoaIDAOFEHKRxSZh2jo9KAh0p16vI/dHcux2u8+ePXvo0KFSqXTx4sVCobC7u9tsNn0+3/LycjKZVBQFIBEB3Jo667r+1D+k4IMLrh/8v2EYKGOBfSkUCiB74BjtdnulUqlUKtVqtVarYcKKoiB2k4sADyjwM/MECKHM0pAsy6gmIIxFIpHf+q3f6ujoePz4MVb58uXL29vbGxsbCwsLe3t7giDAFAlX/jl2tU6SsoBYCMThcDidzkajsb29nU6nkX+5XC4QdvF4HP4NGTMcoJX8hz8ksZdMhjLRlVWSmKSiKD6fz2azweAZs4LSarVGRkb6+vqazWaxWAwGg48ePdrb2zt8+PDy8vLw8HA0GsXSwAta6at94MZYWEkk+4qiuN3uarVqs9lCodDs7Cwkw7JsMpnM5/Oqqnq93oMHD1IUBSEjgquq6nA4kCsHg0GGYSqVCrw0SaYhrmKxCJWGSQPWNhoNSE+SpHQ6TVEUGMByufzgwYNHjx5xHJdOpwOBANidlZUVlmWdTmdHRwfoQiwWKBVcLBYeb1FmmAY6J5a5srJy//79TCaj63o6nUbkwILBQyC1I3U7VVVhWgBokiQhF2s2mxzHORwOeBSPx4MnQuaKoqiqGgwGm80mYlg+n9/Y2Ojp6Tl69Giz2Uwmk6VSSdd1QBSWZZvNZr1eX1paMgxjfHz82LFjkUhEluVCoYBUc1+SEB1jKRDAQSGjp2m6VqvdvXv3xo0bmUzG6/Vms9mBgYGhoSGfz9fZ2QlKG7XnVquFeFitVj0eD8uy0GpS9BVFEWlKsViUZRl4A/kqFgWhGNELA5ibm8tms0ePHl1eXp6fnwdG7+7ubrVa4XB4e3u7VqupqprP54vFoqqqwP12u93KXT1lkzBWTBuJOc/z+Xx+YWFhc3MTEbXZbCJ8YRCQPH4iSRIMW1VVfBkEKZTT4XDIspxKpRYWFh4+fFgqlaanp0dGRkjBr1QqwQtguWVZxiOWl5d3dnYkSYJ/LhaLoiiePXt2aGioUqn89Kc/3d7ehhEKglAul1mWxVoQj82S+PZMUEaIU1U1lUptbm4C32matra21mw2FxYWoLRutzsQCPj9/p6envHxcaQv8HJQ7Eqlks1mq9VqsVhcXFx8+PAhtA41EiSiWE24R1mW4b1kWUaOBr+dy+VqtZrb7Q6FQocPHx4YGLh169adO3egd+12u1QqAXUR0E8gx+eSNL5QWqYoql6vl0olVVUBdHRdz2azxWIRSYZhGAB9kiSBm3K73WBfOjs7l5eXnzx54nK55ubmVlZWcrlcOp0G1+x0Ojc2Nj788ENkEi+++OLY2BjHcdVqFXgdBS+PxwMGhKKobDar67rX6xVF8d69e7u7u9euXdve3vZ6vUhWZFluNpvo50Bu/bm6WqMzYylZkyDm8Xh6enoKhUIqlUL6g4QDtJqiKKjkoCjgdDq7u7vD4fC7774ry/KHH36Yy+VSqZSiKBg3ypLValUUxe3tbYqiotHo1tZWR0dHMBiE6yLppSAIrVYrl8vJspzJZFwu17Fjx+r1+tzcnCiKL7/8siRJV65cAc8CWgxBm8Thz70rwatWeWqaBmwdi8VqtdrW1lYqldJ1HeDGZrOJokhRFDwEbAmU7O7ubjQa/Z3f+Z2urq5UKoUg5HQ6KYqq1Wo0TYPIRIqzs7Nz4cKFX//61ydPnnznnXemp6fRD0LTdLFYbLVacM7lchmDGRoaWl5ehgv8xje+AZJ6e3u72WzyPB8KhcB3kRT88zhJ0zSoR6SzHMcRZgVLcuDAgUwm8+DBA57nQc/BMSLnRD+Ew+HAp5qmzczMgBQ+f/78+++/Xy6XEQY1TfN6vaVSqa+v7+DBg4IgoGglCMLNmzcFQUA1HiQgSpQ2m21nZ4em6Xa7PTAwkM1mk8lkNBoNBAKITMeOHWu32+Fw+Etf+lK1WkWstgqMoijbm2++yViqCAQWEcoU4spms48ePUIRjjBAbrcbX/D5fPl8niQcfX19wWDQ5/PF43G4omQyWa/XCWjO5/OyLI+Ojo6Pj4OVLxaLTqfz4MGD0WgUfoum6VKpdOvWrUQiIYpib2+vpmnpdBr17FgsNjIy4vf7Ozo6hoaGRkdHA4EAbbLyGB6Zl+3NN98k2IpkdEhDCfYDFbKysrK7u0vEiDQKxSyKovAmgM758+dPnjzZ1dWFfBoVdTjGbDaL2km9Xr93797KygpN0+FwGPrcarWmpqYcDgeqZtVqtVAolMvlAwcOnDx5slgszs3NIcDCx0ajUVmWI5GIJEn7msmyYNuesknK0o5EcgU4Zagf6Bm/3x+Px9fW1gjjhkzK6XQiL6lUKsCr7XYbmAYPiMViL730Ur1e/+ijjyiKisVikUhkfX29v7//+PHjp06darfb+XxeEASoTLPZBH5ASjk1NVUoFHp7eycnJ1VVvXnzZqVSQe0MvgDkoCzLKLCTVBaVRYzB9p3vfEc3a2YkFUK0QDYM2EnTNIIVwBpN06IoglMCeoYkWZaNx+NvvPEGXGWj0UBVY3h4GFAeYbC7u7tWq+VyuWAwePz48UOHDoVCIa/X29/f73Q6UQgD9e5wOPL5/MDAwODgIMMwCwsL6+vruq6Pjo4+99xzSGtRMgKZqJvtaKTVgwa5bLVRImJIHFoOYQ4MDBw8eDCVSoGb8nq9dru9Wq22Wi2XywX17unpeeWVV7785S8zDFMsFgFE+vv78/k8OPUTJ05Uq9Xd3d3Tp08fOHDg6NGjSOLAryNsIMOiKMputyNaBoNBu90+MDAwMTFx//59u93e1dXl9/vBHuTz+XA43Gq1arWa1+slZU+S39jeeOMNoLBnsj4gQFJLQ9KEeNDb24uhdHZ2ut1uvEgkEmNjY+fOnXvxxRf9fn+pVFIUBZoMKONyuTY2NtbW1qLR6Pe+972pqSm/3+/z+UD5YTRdXV2ot5OsTZblzc3NeDwOnrJQKOzs7HR1dX3ta18bGRlBI+L169dBKRmG4Xa70a5hZdBt3/zmN0mV25raoVSMgGGYTYDFYjEUCr344ouqqq6urqIat7q6WigUXn755eeee25iYgJrGQ6H7XZ7sVjEcjQaja985Ss9PT2qqm5tbc3OzgJYgzcCbAK0APOPul2j0chmsysrK8Fg0OVyGYZRrVbz+XxPT8/09LTf71dV9eOPP/7bv/1bXddRp3C5XOVyGV8mc2EbjQZBrftmarMhkAAKwywlSUJ3ZzgcpijqzJkzLMsuLCwcPHjwhRdecDqdMzMz6+vrGxsbBw4cQOBOJpPo7wElkUqlent7z549+8Ybb+Tz+d3dXThVkhJAgKQIrSjK+vr67u7ur3/960OHDoGYjUajf/iHfwhoCkxy//79UCiEEIAV9Hq9yJ+I0rKAASSEUCbbRcgIw+xEZFlWkqTbt2+Lojg8PDw5OTk4OIi0mOO41dXVXC73wgsvkB5CAEBFUbq6utbX1x0OR6VSgVV7PJ54PI56EQYEIkLXdaxLPp9fXV29evXqjRs3QPOUSiWfzwdfSpkMxubmZjAYfPnll48fP+7xeIDpEfDgXfcNkHr6IlgBgduw9L2wLItF2tnZKRaLfr8/FosBJ0UikcHBwXa7jWKBYRhggARB6OzsvH//Pjq+sFijo6MoLYIKJM9CXp/JZFRVTafTq6ur169f39zcHBwcrFardrvd7/e7XC58MxAIoBA+ODh46tSpQ4cOwS5IbGMspDZjJdFos+cXRBBJFCmTMUCL5Pb2dqVSQWKKJMvlcv3yl7/c2dlByw5QC4IH5FatVi9dugS8trGxgTCIXBnEPGqPW1tb5XK5UqnIstxut3d2dpxOZzweB35Akom8DKsvSdLY2Fg4HEYU8Xq9DMOgMYTED4qiTODzf/WAQJIEJxhmcXtzcxOtcDzPRyIRXdc//PDDTz/99Pjx4x0dHaIooubRbrez2WypVMIq5PP5n/zkJwAowIPwMdDYcrlcLBbX1tYWFxevX7+u6zpqzJFIZGBgYHR0lHDqLpdLFMVGo1Gr1VwuVzQaRWoOeIApwF1TZpK831hkPF3cM0wSGqknXiCIjY2N/exnPwNVIQgCWInLly+Pj4+HQqFkMtnV1YX6LFFXQJZwOPznf/7niUTir/7qr3w+HywZ2l6r1VCiKRQKq6urXq+3u7v78ePH4+PjIyMjXq/3ypUrzz//PEgDQP9CoaDrOhwsSiPNZrNUKoF5slofTdP7AP2LF2A6TBFoBh4/GAxevXp1aWkJmeSdO3fu3bvXbrcbjcbCwsKDBw8g/EajgZwAOSGauHp6ej788MNEIhGLxQgcA6yD656bm2NZdnBwMBqNZjKZ8fHx8fHx27dv//Vf/3UoFHI6ndVqdWNjI5/PI4EG3EHuBieH1A8RgciMNZ4m7YnGAuzCs5NaFcMwkUjk9OnT//Vf/3X58mWwVZVKxe12+/3++fl5iqI+/vhju93e398PmJrNZtHf86d/+qfvvPPO+vr6+++/v7a29tZbb3V2dlIUJUkS6AK0fA8ODoqimEqlXn/9dWTn9+7dUxTlz/7sz37v936vp6cnn8+HQqHR0VFJkkCLQrakvM9YyEdIkoWiA0mRZgqb2dwDD4T+A9yCpunTp09/8MEHSCn8fj9SrcnJyUajsbm5abPZyuXyrVu3kFXzPO90Ot944w2Hw8Gy7He/+12O437+85//3d/9XW9v78TExK1btwYGBl566SVBEI4ePepwOFCQhHImk0nQJbFYrNFo+Hy+kZERQRDA+gGvwjR0y2YEeCYSBVnCczNmQw9lNkUTeIULVqQoSjgcPnLkyOzsLJLacDg8Pj5OGvnQJYa6iNfrPXLkyAsvvHD69GkQH0eOHNF1vVqt/ud//ifDMF1dXd/+9rf/4i/+Ynl5+R//8R9DoRCcOUILlml0dLSrqysWi/X39/f09Ljdbqw4nL9haSanLdVBYncURdneeustEjnIDCFSABfyJsqPILWKxeK1a9dEUQSd0d3dPTAwsLOzg9ZORVHQPPHlL3/5/PnzJ06c6O7ups1qDFDxiy++uLa2dufOnWPHjmUymSdPngwNDQUCATheURThlnZ3d71e74kTJ8bHxzs6OuBaEehJ5eYZnhHztMYL22/+5m+S5IMYq+3pC9YM+xZFERXvzz77DL/CHqa9vT1d1yORCH5CUVQ4HD5//vzRo0dBmeLLCGLj4+Oqqk5MTExOTl66dKlYLJ47d25kZCSbzYZCIYZh0PiN6mAkEkEQwhyQtaI6SKzu/5wkefOpfS4kKtJmIyvkjq5uqC52BPT29p46deru3bs2m61WqyWTSXQUqKpaLBbD4TDw5NbWVj6fhxusVqtgJUF2QErf/va3GYb5f//v/4Hd7OzsxFOAzoPBIEh6xuyBgh0SQhRlc0JwW6egWzq1WILdiELvB1CWbZtbi0jmous6AH00Gh0fH79//z5FUWhi8fl8Pp8vlUo1m81sNlupVDRNy+Vyly9fRtMLzJVhmN3d3UQiMTIycuTIEUVRhoeH2+12PB73+Xx43+l0KoqSSCRWVlZA4cDBYHpQY8rC+lslZFjaXcjFkmaNz5Eew8DxGGaXCHQDrxuNBohmlJkB0ND8fubMGfRU5/P5ubk5t9vd09MTiUSQKMbjcU3Tstns0tLSvXv3DMP41re+FYvFHj9+rOt6JpNJpVLY2KSq6u7u7pMnT/b29jiO6+zsJHVVZCdES0HE0JYmJMPs3bFOeH83wTM+CqGGBFMSZuCfUPZJJpMURSGr5jju8ePH9XpdluXz58+fO3fu3LlzsVgMZTws/+rq6vz8vNfrffXVV7/2ta8BLdRqNTSBXr16lef5l19+2W6353I59K7wPN/b24s8mDSoIQaC4NHMbQGUhfu3Tmd/kgiGpERJfA9t7kzb98KmMWBWHo8nFAopiiJJUqPR6Orq4nl+eXlZFMWf/vSnV65c6evrw6c2my0ej3/yySd2u/3dd9/9yle+sre3p2laPp9PpVKhUOjKlSterzcYDKbTaXBQyWRS07RUKtXT00Oql7B5VI2azSYqi+intbofDNXqdWiaZrWn90h8/oGpxkRpcaHDJhAI7OzsRCKRTCajaRryklgsVq1Ws9lsq9V6/PhxpVKp1+uxWCyfz09MTPzoRz8aHh4ul8toD0kkEltbW/fv30c1Ce2iyWRSlmVZlh8+fLi5uYkOHo7jUqkU3A/gIaAvtiEgrmJsutlaZjzdycJaMZ7VMq3ithq63+8vFAoo1oMcQfoTiUTQoDA2NlYqlQqFwvPPPx+Px7u7u+12+8TExMjISDKZdLlcpVLp5s2bV65cAfptNmOG1FkAAA94SURBVJtut9tut8fj8VQqtbi4WKlUrl+/3t/fPz4+DsNBEgPKt1qtulwuTdPAIcFE6ae7eI2n26BYku/Qlm2k5K/1I/weE/vXf/3XdDpdq9V6e3tBRmCBHQ7HK6+80tnZ+emnn3Z2dv7whz9E/z8WZX19/cGDB//7v/8riuLS0hIADWATdKdSqXzyySe41cmTJwcGBtC45vf7Z2dnZVk+fPgwx3EojSDDtJrl/3nRNM1aExPr9Ej8pC3N2/Cudrt9ZWUFbZGhUAjLjJ2wL7300sGDB2u12sTEhCiKc3Nz+Xx+eXn5xo0biL3z8/OPHj06c+YMAr3dbocCcxy3tra2u7u7t7fn9Xq//vWvz8zMQHQ8z2PLxNLSks/ni0QiaDIDH/lFBbTi033nQjJjq/lRZtvFM8qt6zosHu0eYEO6urp0Xd/a2urs7CwWi//93/8diUQMw9ja2jp48OBnn30GrIfi4YEDB4g/q9frWDVM4+7du4gZKHWgykBRFPKmYDD43nvvOZ3O1157rbOzE0R7q9UiTDmZrVWGxIOypEeJsmx1oZ6OtuRf8BRTU1O//OUvQVVQFFUul0OhULlc3t3djcfjDx8+LBaLmqatr6/Lslyr1Xp6egKBQL1eT6fT2GmI9I+iKFQvKpVKsVjM5XIdHR3Yb+ZwOFwuFzYPYwfe9vb2r371K1VVX3/9db/fj/zYKkPiHa3DpsiWCTIr6+svThKEEM/zp06dmpiYePDggaZpiUQCUMHr9W5sbJRKJZqmc7mcz+djWTadTkuSRLxuMBjE/iRsLgEh0G63UXIEMJ6enu7p6cEcGIYB2eFwOARBWFlZQcSanp52u92CIDQajWf8jW7uuyKTtP3u7/6ubrbXMZaOKbIFwmZuvsXzHA4HOsJDoVCpVFpfX0c7PJp+gN3hGOx2ez6fBzeB1mNshEJpDUgNThLlGjxubGzs9OnTg4ODsVgMXQ4YdzKZvHTpkqIopVIplUohE3Q6nbBniPQZIX0uSfgY0vpBfAzpkiOKSlEUGofRnnf48GFZlre3t5eXl2G94NQY85ABBHFi2Na/FEXhSAHDbInAtAOBgM/ni0aj0EaScGDhQKuCAfyXf/mX+fn5r371qydPnoRxAqmjXQNBnkxnH8VbJ/MMCHwmbEJzEEheeukllmUvXry4tLS0sbFBWdJzTdNQq0TUQcHP6sMQ/aCrSJE9Hs/AwAB2vzqdTsyfMU8t2Nvbg/1LkqQoyu7uLlzx4uJif3//oUOHent70Y9eq9Xq9Tq4+X2gZk2uiWYTko4kzcBDUF3U6prNZkdHx+uvvz44OHjz5s2/+Zu/qVarsiyjYRFlVs3cc61bmkDJC+iqYRhIvuF1gXLAxKLeSNM0x3EbGxvwkbVaTRAE7Di6fv36vXv34vH40NDQgQMHhoaGhoaGurq6gsEg4QAA4lmrw4X/BM4ApiVBBX4fbgD7JUqlktvt9vl8oFttNpvD4SgWi81mE5vvCaxnLH0l8OSoAsGYcYYC+sBnZmZCoZBhdmaQLWerq6tut9vpdGYyGWyhJIPc3t5OJBKXLl2KRCJTU1PHjh3r6+uLxWJ+vx+9yKxu2aNmjS2UpenFeJoyMcyqNeQ2Pz//s5/9rFwud3Z2Tk9PP3nyBOgE4eGLmkKZPe6NRgOtdmhHnJyc/P73vx+LxYjV2Gw2lCjT6TQaXFELaLfbaGVxuVxoCEekTafT+Xz+xo0bgiBMT08PDg5OTk729/ezJKWyzoGykCBwP8SIDcMA2wlbR9Xp4sWLTqfT7/fPzMw4nc5PP/0U0rbGXsosYIObIbtIAV9mZmbefvvtkydPgiICLwEL1HV9cXEReRl+aM2esbkGvAz8TbPZbDQaP//5z8GbRKNRxsrT4UIthBA81k9JWQaMaKVSuXTp0kcffQQ2HXsGoWyU2SxvRb/kWTRNV6tVwzDgdcbGxv7gD/7g3Llzm5ub0CDgUlhspVK5ffs2MCCsACkBqUwT/0SMHwhJVdXHjx9fu3ZtnymHfhOpGuYhHSRmWmke4IGlpaXLly9fvnwZUbHVao2Pj6N4jvo+Foj0vYD7g9IibAQCAVmW+/v7/+iP/ujs2bP1eh0RH4EnEAigLUGW5WvXrlEUhZoHGq4cDgdcINkvZuUpAcuAB2022/5+AWQSmCQppJHOSkyYYRhFUdCDurS0tLq6+ujRI+zjhlsHmI5GoyMjIysrK6VSKRwO7+3t+Xw+UD4oQrfbbZfLtbe3t7Oz89xzz/3oRz964YUXqtWqqqp+v79arTqdTuA+TdP8fv+FCxfQPYhFR+5imHsYSRZCm+0NcGxoV9hnMwBlIDF4FKw35oxghZ2D2WwWfVkrKytLS0u5XK7RaMDF46Yov4bD4W984xutVuvChQt7e3tutxtFdUwAAaZcLr/11ls8z3/zm99EOQAtsoqiICtCaczhcJTL5Y8++ghwHJ6MuGhoLAnyxMoIH/s54gGDwJqnuJDkQzfPTgLpmEgk7t27t7a2trCwkMvlUMqFryOdPTB9lmWnpqYCgQCojZWVFUgmn8+jlD82Nvbbv/3bMzMzYEbQjuf3+x0Ox97eXiAQIBsPaZr+4IMP0HZqM9vnNfOgBJQ3yQYUEtut0Z4yWQ7WZh6iZE0+EI5LpVI2m0Wy+/Dhw62tLWAoqDTRcCihzWYDKK/VakePHu3v7z9z5sytW7euXLny6NEjVVU9Hs/3vve9d999d3JyEn4F3TI41KRer6PTAnemKOrGjRvvv/9+qVQi8IUIgIAH2qTantFba/BnGcvZGSzLAnyiXAFcuri4uLKyAvqY3AgOTTV3Y7HmXiAUQmA/6LA7e/bsm2+++d577yUSie985zvnzp2z2WylUokxS6UMwzgcDkVRwGs0Gg2v14tTEmZnZzc3NzEZOGr4Z1gdARu0JcWnzI1wT3VJkleM2b6DvdgPHjxYXV2dm5vDlih0aPI8j40DJKIQgAZsjWegJQBN8YIgTE5O/uVf/iW6CFDxhpME+kNZGquDZaLM6j26EAk8JBGIsOMEsRD4SXIRxkIdP7VJFOdRpNPpTCZz/fr19fX19fV1hHUU0kFkoX+NYCsojCAIPT09DocDDgMdZl6vF57GZrORYiaYaGB9zArRC9qBSeLv9PT0L37xCxSVyRlUuGjz6C2CN2E7RJ+hklB7lpiiLMvpdHphYWFubm5jY2NjYwP3QrkGO/ph6BRFhcNhdC2oqgrIQpuVBVmWFxYW/uEf/uHRo0cAsUNDQ/F4vFAoLC8vt1qt0dHRycnJkZGRUCjU29uLdlHN3IzA8/zt27ebzebhw4cvXLiAOIHTxzRNQzaLjevIE6C9iJwIj1AT0v0IlWZRk1pbWwPLRE7cIYUQkkPo5mYz+N56vY4UAQfNLC0tdXV1ZbPZP/7jP37w4IHf789kMg6Hg3DtWIt0Ov3JJ58UCoVoNNrR0XHgwIHp6Wmg6kAgcPHixffee29+fj4Wi8EbuVyuTCbDmYduYTDgB9HWR1sOAuPMbYyGueGVpmkW29kXFxfv37+/srKSzWZV8yw5kvtRJj9AURQcDO6OlmSO47xe7zvvvDMxMaFp2vz8/N27dwEk0NBFFMxm7hpB9RvtvLdu3fqP//gPFCT9fj86WyRJymQynZ2duVwO/kkzT30hWMowm+8QWlVzszHeh+/Y967Xr1/f2NiYn5/f3NxELs9ZzpQgjpggWABXPAlYj6Koc+fO/eAHP+jo6Mhms48fPwbDjUQBZQzOPMkPgR54DUoFGIwVcTqdlUoFFZ6dnR14XbRhw/MBGyJEQ8nxPlYBoqbNsx1JdGQ//vjjXC6XyWTQPs2YJ6gQ1uSZFKRer8OXoLkDX/v+978fCoVkWUbTGHwYEk7AWrTYY5MsECZlHjtQrVYFQYDqdnZ2plIphmFKpRJYHxghaipEoRCxOPNIQ9wQk8SWCQyMdF2xDx48QGTHURCkpqmZm0fwLyGUSLyq1WroIMZOVaC/9fX127dv0zQNh0mOl8BtCQ+CgaLXHIejwCAzmczs7CwkGQgE4MaBZhmzPYxwbkDkECl8BCmi0jSNHVH72JXoHkFD+DawCGVpXCLZOpaTFM+OHDkC0T18+PCf/umfPvnkExxRhhozfCa4RhR2oAhkazbP8zgLrdVq4aAtnDKl6zo2idI0TQybRD8SJ9GroZp74ciRm2RDGsMwbDAYRNAjEtPNU6qIX2UslWaQ1oqikGTn1KlTEMiPf/zjf/u3f3O5XDAGdCuCidsnWszTVSuVis/n29vb83g8oigC93u93kKh4PF4kIVhDwbMGBAKDt94mv6mzQ4Jm3nwJmaOg1/2K6uIFoaFL9TN6jxuAdUn9CSIBvBUoii6XK4jR45wHJfL5WZnZ3ESEUVR1WoV5I0kSbBJxH3gaYQfELboU4dpdHR0BAKBRCLR0dEB/gahGJ13uBUgHkCl1+vFeTpYPtwcrrVcLmNDrqqq+5QkgUiUSTQBGVJfqOEBJWMEuq6j7YRlWVQEEHWxscnn8yFeo2yKwI3td3D9LMui5N7V1RUKhTDVer3e39+/srISCoUQ0CuVCnwvyjCwTHRh4YQZMuBarVYul+GukR4BirGk+5yx8OqGpSBLdIO2lI2QSePwRHDk2GxGKEag3L29vUgkgv3tiOMohIEQOnHixCuvvDI5OYnJAEs1m83l5eXf//3fRxc/9kYz5mGB1uU2TMrbMDvKyDtkI8c+3LEO3QoASN2S3BTfMcyyD8qvw8PDHMc1m83PPvtMURQIpFqtlstlNJzB142Ojn79618/ceIEWlYo83RRGDkyb9o8dbRSqWCl4H4QhAgYoCyHamKDraqqdrsdZ6ugSwNNaaBOdF1nyaysAAAOjUzbePpUVZL4CIIwMDAAc4dDyuVyOL4Zg/B4PI1G4+zZs2+//fbMzAz291JmfwMkQ8IAYGqtVrt27Rp8I8dxbrfb4XDUajXEQzhn2jwYFaEIt4LnBxjAO3BCNpvt8/4QzdLTAnRijTyUuW+LsP2gZHp6ehCyfvjDH3q93g8++ADNSn6/H24gHo+//fbbv/Ebv6FpGjYiYw8bUSJVVQH0UDy22+3ZbDYajWJfGEVRrLlNBH9J2Qb2RlAXY1arMD3MgpRGWKgfZSndWXWYepqJxS5cGEkwGAwGg4Zh8Dx/+vTpvr4+p9P57//+76BkBEHo7u4+d+7c8ePHDcPY2dnBQXCKooAEQEuM3W5HkqnreqPRePjwYTqdRij2+XzYI4F0jzYJGoRoZEi6rgMqIBBgIdrtdqFQMEzu5/8DJc+cUchdTDsAAAAASUVORK5CYII="
     26    1 : "base64"
    5127}
    5228RUNNING TEST: extension_testResourceNotification
  • trunk/LayoutTests/inspector/extensions-resources.html

    r70762 r72683  
    1515<script type="text/javascript">
    1616
    17 function extension_testGetAllResources(nextTest)
     17function extension_testGetHAR(nextTest)
    1818{
    19     function compareResources(a, b)
     19    function compareEntries(a, b)
    2020    {
    21         return a.har.request.url.toLowerCase().localeCompare(b.har.request.url.toLowerCase());
     21        return a.request.url.toLowerCase().localeCompare(b.request.url.toLowerCase());
    2222    }
    2323
    24     function onResource(result)
     24    function onHAR(result)
    2525    {
    26         var resources = result.sort(compareResources);
     26        result.entries.sort(compareEntries);
    2727
    28         for (var i = 0; i < resources.length; ++i)
    29             output("resource: " + resources[i].har.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1") + ", type: " + resources[i].type);
     28        for (var i = 0; i < result.entries.length; ++i)
     29            output("resource: " + result.entries[i].request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
    3030    }
    3131    extension_doXHR(function() {
    32         webInspector.resources.getAll(callbackAndNextTest(onResource, nextTest));
     32        webInspector.resources.getHAR(callbackAndNextTest(onHAR, nextTest));
    3333    });
    34 }
    35 
    36 function extension_testGetInvalidResource(nextTest)
    37 {
    38     function onResource(result)
    39     {
    40         output("Attempted to retrieve invalid resource: " + JSON.stringify(result));
    41     }
    42     webInspector.resources.get(2128506, callbackAndNextTest(onResource, nextTest));
    43 }
    44 
    45 function extension_testGetPageTimings(nextTest)
    46 {
    47     function onTimings(result)
    48     {
    49         output("Got callback from getPageTimings, pageTimings dump follows");
    50         dumpObject(result, { onContentLoad: 1, onLoad: 1 });
    51     }
    52     webInspector.resources.getPageTimings(callbackAndNextTest(onTimings, nextTest));
    5334}
    5435
     
    6243function extension_doXHR(callback)
    6344{
    64     webInspector.inspectedWindow.evaluate("doXHR()", callback);
     45    webInspector.inspectedWindow.eval("doXHR()", callback);
    6546}
    6647
     
    6950    function onResourceFinished(resource)
    7051    {
    71         output("Resource finished: " + resource.har.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
     52        output("Resource finished: " + resource.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
    7253    }
    7354
     
    7859function extension_getResourceByUrl(urls, callback)
    7960{
    80     function onGotResources(response)
     61    function onHAR(response)
    8162    {
    82         var ids = [];
    83         for (var i = 0; i < response.length; ++i) {
     63        var entries = response.entries;
     64        for (var i = 0; i < entries.length; ++i) {
    8465            for (var url = 0; url < urls.length; ++url) {
    85                 if (urls[url].test(response[i].har.request.url))
    86                     ids.push(response[i].id);
     66                if (urls[url].test(entries[i].request.url)) {
     67                    callback(entries[i]);
     68                    return;
     69                }
    8770            }
    8871        }
    89         callback(ids);
    9072    }
    91     webInspector.resources.getAll(onGotResources);
     73    webInspector.resources.getHAR(onHAR);
    9274}
    9375
    94 function extension_onResourceBodies(response)
     76function extension_onResourceBody(content, encoding)
    9577{
    96     function compareBodies(a, b)
    97     {
    98         return ((a.response && a.response.content) || "").localeCompare((b.response && b.response.content) || "");
    99     }
    100     dumpObject(response, { id: 1 });
     78    dumpObject(Array.prototype.slice.call(arguments));
    10179}
    10280
    10381function extension_testGetResourceContent(nextTest)
    10482{
    105     extension_getResourceByUrl([/audits-style1.css$/], function(ids) {
    106         webInspector.resources.getContent(ids[0], callbackAndNextTest(extension_onResourceBodies, nextTest));
     83    extension_getResourceByUrl([/audits-style1.css$/], function(resource) {
     84        resource.getContent(callbackAndNextTest(extension_onResourceBody, nextTest));
    10785    });
    10886}
    10987
    110 function extension_testGetResourceContent(nextTest)
     88function extension_testGetResourceContentEncoded(nextTest)
    11189{
    112     extension_getResourceByUrl([/abe.png$/, /missing-image.png$/, /audits-style1.css$/ ], function(ids) {
    113         ids.push(2126506); // Non-existent resource id.
    114         webInspector.resources.getContent(ids, callbackAndNextTest(extension_onResourceBodies, nextTest));
     90    extension_getResourceByUrl([/abe.png$/ ], function(resource) {
     91        resource.getContent(callbackAndNextTest(extension_onResourceBody, nextTest));
    11592    });
     93}
     94
     95var test = function()
     96{
     97    InspectorTest.reloadPage(InspectorTest.runExtensionTests);
    11698}
    11799
  • trunk/LayoutTests/inspector/extensions-test.js

    r71107 r72683  
    2222    function onMessage(event)
    2323    {
    24         if (event.data !== messageId)
     24        if (typeof(event.data) !== "object" || event.data.command !== messageId)
    2525            return;
    2626        if (!recurring)
    2727            window.removeEventListener("message", onMessage, false);
    28         callback();
    29         if (event.ports && event.ports[0])
    30             event.ports[0].postMessage("");
     28        var port = event.ports && event.ports[0];
     29        if (callback(event.data, port) && port)
     30            port.postMessage("");
    3131    }
    3232    window.addEventListener("message", onMessage, false);
     
    3535InspectorTest.runExtensionTests = function()
    3636{
    37     function addExtension(callback)
    38     {
    39         InjectedScriptAccess.getDefault().evaluate("location.href", "console", function(result) {
    40             var extensionURL = result.description.replace(/\/[^/]*$/, "/resources/extension-main.html");
    41             WebInspector.addExtensions([{ startPage: extensionURL }]);
    42             if (callback)
    43                 callback();
    44         });
    45     }
    46     InspectorTest.dispatchOnMessage("extension-tests-done", function() {
    47         InspectorTest.completeTest();
     37    InjectedScriptAccess.getDefault().evaluate("location.href", "console", function(result) {
     38        var extensionURL = result.description.replace(/\/[^/]*$/, "/resources/extension-main.html");
     39        WebInspector.addExtensions([{ startPage: extensionURL }]);
    4840    });
    49     InspectorTest.reloadPageIfNeeded(addExtension);
    5041}
    5142
    52 InspectorTest.dumpSidebarContent = function()
     43InspectorTest.dispatchOnMessage("extension-tests-done", InspectorTest.completeTest, true);
     44
     45function extensionOutput(message)
    5346{
    54     var sidebarPanes = WebInspector.panels.scripts.sidebarPanes;
     47    InspectorTest.addResult(message.text);
     48}
     49InspectorTest.dispatchOnMessage("output", extensionOutput, true);
     50
     51function dumpSidebarContent()
     52{
     53    var sidebarPanes = WebInspector.panels.elements.sidebarPanes;
    5554    // the sidebar of interest is presumed to always be last.
    5655    var sidebar = sidebarPanes[Object.keys(sidebarPanes).pop()];
    5756    InspectorTest.addResult("Sidebar content: " + sidebar.bodyElement.textContent);
     57    return true;
    5858}
     59InspectorTest.dispatchOnMessage("dump-sidebar-content", dumpSidebarContent, true);
    5960
    60 InspectorTest.dispatchOnMessage("dump-sidebar-content", InspectorTest.dumpSidebarContent, true);
     61function reloadPage(data, port)
     62{
     63    InspectorTest.reloadPage(function() {
     64        port.postMessage("");
     65    });
     66}
     67InspectorTest.dispatchOnMessage("reload", reloadPage, true);
    6168
    6269}
  • trunk/LayoutTests/inspector/extensions.html

    r71107 r72683  
    1212        dumpObject(panel);
    1313    }
    14     webInspector.panels.create("Test Panel", "extension-panel.html", "extension-panel.png", callbackAndNextTest(onPanelCreated, nextTest));
     14    webInspector.panels.create("Test Panel", "extension-panel.png", "extension-panel.html", callbackAndNextTest(onPanelCreated, nextTest));
    1515    output("done createPanel");
    1616}
     
    2323        dumpObject(sidebar);
    2424    }
    25     webInspector.panels.scripts.createSidebarPane("Test Sidebar", "extension-sidebar.html", callbackAndNextTest(onSidebarCreated, nextTest));
     25    webInspector.panels.elements.createSidebarPane("Test Sidebar", "extension-sidebar.html", callbackAndNextTest(onSidebarCreated, nextTest));
    2626}
    2727
    2828function extension_dumpSidebarContent(nextTest)
    2929{
    30     dispatchOnFrontend("dump-sidebar-content", nextTest);
     30    dispatchOnFrontend({ command: "dump-sidebar-content" }, nextTest);
    3131}
    3232
     
    4949        });
    5050    }
    51     webInspector.panels.scripts.createWatchExpressionSidebarPane("Watch Test: Object", onSidebarCreated);
     51    webInspector.panels.elements.createWatchExpressionSidebarPane("Watch Test: Object", onSidebarCreated);
    5252}
    5353
     
    7575        sidebar.setExpression("(" + expression.toString() + ")();", "title");
    7676    }
    77     webInspector.panels.scripts.createWatchExpressionSidebarPane("Watch Test: Expression", onSidebarCreated);
     77    webInspector.panels.elements.createWatchExpressionSidebarPane("Watch Test: Expression", onSidebarCreated);
    7878}
    7979
  • trunk/LayoutTests/inspector/resources/extension-main.html

    r66480 r72683  
    33<script src="../../http/tests/inspector/inspector-test.js"></script>
    44<script type="text/javascript">
    5 function output(message, callback)
     5function output(message)
    66{
    7     webInspector.inspectedWindow.evaluate("output(unescape('" + escape(message) + "'));", callback);
     7    top.postMessage({ command: "output", text: message }, "*");
    88}
    99
    1010output("Started extension.");
    1111</script>
    12 
    1312<script src="extension-main.js"></script>
    1413</head>
  • trunk/LayoutTests/inspector/resources/extension-main.js

    r71107 r72683  
    33    function callback(result)
    44    {
    5          window.eval(result.value);
     5         window.eval(result);
    66         runTests();
    77    }
    8     webInspector.inspectedWindow.evaluate("extensionFunctions()", callback);
     8    webInspector.inspectedWindow.eval("extensionFunctions()", callback);
    99}
    1010
     
    2626function onTestsDone()
    2727{
    28     output("All tests done.", function() {
    29         top.postMessage("extension-tests-done","*");
    30     });
     28    output("All tests done.");
     29    top.postMessage({ command: "extension-tests-done" }, "*");
    3130}
    3231
     
    5049    var channel = new MessageChannel();
    5150    channel.port1.start();
    52     channel.port1.addEventListener("message", callbackWrapper, false);
     51    if (callback)
     52        channel.port1.addEventListener("message", callbackWrapper, false);
    5353    top.postMessage(message, [ channel.port2 ], "*");
    5454}
  • trunk/WebCore/ChangeLog

    r72682 r72683  
     12010-11-24  Andrey Kosyakov  <caseq@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: extension API cleanup
     6        https://bugs.webkit.org/show_bug.cgi?id=50019
     7
     8        * inspector/front-end/ElementsPanel.js:
     9        (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
     10        (WebInspector.ElementsPanel):
     11        * inspector/front-end/ExtensionAPI.js: See bug for summary of extension API changes.
     12        (WebInspector.injectedExtensionAPI.Resources.resourceDispatch):
     13        (WebInspector.injectedExtensionAPI):
     14        (WebInspector.injectedExtensionAPI.Resources.prototype.getHAR):
     15        (WebInspector.injectedExtensionAPI.ResourceImpl.prototype.getContent):
     16        (WebInspector.injectedExtensionAPI.Panels.prototype.create):
     17        (WebInspector.injectedExtensionAPI.PanelImpl):
     18        (WebInspector.injectedExtensionAPI.PanelWithSidebarImpl):
     19        (WebInspector.injectedExtensionAPI.PanelWithSidebarImpl.prototype.createSidebarPane):
     20        (WebInspector.injectedExtensionAPI.PanelWithSidebarImpl.prototype.createWatchExpressionSidebarPane):
     21        (WebInspector.injectedExtensionAPI.ElementsPanel):
     22        (WebInspector.injectedExtensionAPI.ExtensionSidebarPaneImpl.prototype.setHeight):
     23        (WebInspector.injectedExtensionAPI.Audits.prototype.addCategory):
     24        (WebInspector.injectedExtensionAPI.AuditCategoryImpl.auditResultDispatch):
     25        (WebInspector.injectedExtensionAPI.AuditCategoryImpl):
     26        (WebInspector.injectedExtensionAPI.AuditResultImpl.prototype.get Severity):
     27        (WebInspector.injectedExtensionAPI.InspectedWindow):
     28        (WebInspector.injectedExtensionAPI.InspectedWindow.prototype.eval):
     29        * inspector/front-end/ExtensionCommon.js:
     30        (WebInspector.commonExtensionSymbols):
     31        * inspector/front-end/ExtensionServer.js:
     32        (WebInspector.ExtensionServer):
     33        (WebInspector.ExtensionServer.prototype.notifyObjectSelected):
     34        (WebInspector.ExtensionServer.prototype.notifyResourceFinished):
     35        (WebInspector.ExtensionServer.prototype.notifyPageLoaded):
     36        (WebInspector.ExtensionServer.prototype.notifyPageDOMContentLoaded):
     37        (WebInspector.ExtensionServer.prototype._onCreatePanel):
     38        (WebInspector.ExtensionServer.prototype._onReload):
     39        (WebInspector.ExtensionServer.prototype._onGetHAR):
     40        (WebInspector.ExtensionServer.prototype._onGetResourceContent):
     41        (WebInspector.ExtensionServer.prototype._onAddAuditCategory):
     42        (WebInspector.ExtensionServer.prototype._buildExtensionAPIInjectedScript):
     43        * inspector/front-end/HAREntry.js:
     44        (WebInspector.HARLog):
     45        (WebInspector.HARLog.prototype.build):
     46        (WebInspector.HARLog.prototype._convertResource):
     47        * inspector/front-end/inspector.js:
     48        (WebInspector.domContentEventFired):
     49        (WebInspector.loadEventFired):
     50        (WebInspector.didCommitLoad):
     51
    1522010-11-23  Jeremy Orlow  <jorlow@chromium.org>
    253
  • trunk/WebCore/inspector/front-end/ElementsPanel.js

    r70046 r72683  
    5959        if (this._focusedDOMNode) {
    6060            InspectorBackend.addInspectedNode(this._focusedDOMNode.id);
    61             WebInspector.extensionServer.notifyObjectSelected(this.panel.name, "DOMNode");
     61            WebInspector.extensionServer.notifyObjectSelected(this.panel.name);
    6262        }
    6363    };
  • trunk/WebCore/inspector/front-end/ExtensionAPI.js

    r71911 r72683  
    105105function Resources()
    106106{
    107     this.onFinished = new EventSink("resource-finished");
     107    function resourceDispatch(request)
     108    {
     109        var resource = request.arguments[1];
     110        resource.__proto__ = new Resource(request.arguments[0]);
     111        this._fire(resource);
     112    }
     113    this.onFinished = new EventSink("resource-finished", resourceDispatch);
    108114}
    109115
    110116Resources.prototype = {
    111     getAll: function(callback)
    112     {
    113         return extensionServer.sendRequest({ command: "getResources" }, callback);
    114     },
    115 
    116     get: function(id, callback)
    117     {
    118         return extensionServer.sendRequest({ command: "getResources", id: id }, callback);
    119     },
    120 
    121     getPageTimings: function(callback)
    122     {
    123         return extensionServer.sendRequest({ command: "getPageTimings" }, callback);
    124     },
    125 
    126     getContent: function(ids, callback)
    127     {
    128         return extensionServer.sendRequest({ command: "getResourceContent", ids: ids }, callback);
    129     }
    130 }
    131 
    132 var wellKnownPanelNames = [
    133     "elements",
    134     "scripts"
    135 ];
    136 
    137 function Panels()
    138 {
    139     var panels = [];
    140     function panelGetter(name)
    141     {
    142         return panels[name];
    143     }
    144 
    145     for (var i = 0; i < wellKnownPanelNames.length; ++i) {
    146         var name = wellKnownPanelNames[i];
    147         panels[name] = new Panel(name);
    148         this.__defineGetter__(name, bind(panelGetter, null, name));
    149     }
    150 }
    151 
    152 Panels.prototype = {
    153     create: function(label, pageURL, iconURL, callback)
    154     {
    155         var id = "extension-panel-" + extensionServer.nextObjectId();
     117    getHAR: function(callback)
     118    {
    156119        function callbackWrapper(result)
    157120        {
    158             if (result.isError)
    159                 callback(result);
    160             else {
    161                 panel = new ExtensionPanel(id);
    162                 callback(panel);
     121            var entries = (result && result.entries) || [];
     122            for (var i = 0; i < entries.length; ++i) {
     123                entries[i].__proto__ = new Resource(entries[i]._resourceId);
     124                delete entries[i]._resourceId;
    163125            }
    164         }
     126            callback(result);
     127        }
     128        return extensionServer.sendRequest({ command: "getHAR" }, callback && callbackWrapper);
     129    }
     130}
     131
     132function ResourceImpl(id)
     133{
     134    this._id = id;
     135}
     136
     137ResourceImpl.prototype = {
     138    getContent: function(callback)
     139    {
     140        function callbackWrapper(response)
     141        {
     142            callback(response.content, response.encoding);
     143        }
     144        extensionServer.sendRequest({ command: "getResourceContent", id: this._id }, callback && callbackWrapper);
     145    }
     146};
     147
     148function Panels()
     149{
     150    var panels = {
     151        elements: new ElementsPanel()
     152    };
     153
     154    function panelGetter(name)
     155    {
     156        return panels[name];
     157    }
     158    for (var panel in panels)
     159        this.__defineGetter__(panel, bind(panelGetter, null, panel));
     160}
     161
     162Panels.prototype = {
     163    create: function(title, iconURL, pageURL, callback)
     164    {
     165        var id = "extension-panel-" + extensionServer.nextObjectId();
    165166        var request = {
    166167            command: "createPanel",
    167168            id: id,
    168             label: label,
    169             url: expandURL(pageURL),
    170             icon: expandURL(iconURL)
     169            title: title,
     170            icon: expandURL(iconURL),
     171            url: expandURL(pageURL)
    171172        };
    172         extensionServer.sendRequest(request, callback && bind(callbackWrapper, this));
     173        extensionServer.sendRequest(request, callback && bind(callback, this, new ExtensionPanel(id)));
    173174    }
    174175}
     
    177178{
    178179    this._id = id;
     180}
     181
     182function PanelWithSidebarImpl(id)
     183{
     184    PanelImpl.call(this, id);
     185}
     186
     187PanelWithSidebarImpl.prototype = {
     188    createSidebarPane: function(title, url, callback)
     189    {
     190        var id = "extension-sidebar-" + extensionServer.nextObjectId();
     191        var request = {
     192            command: "createSidebarPane",
     193            panel: this._id,
     194            id: id,
     195            title: title,
     196            url: expandURL(url)
     197        };
     198        function callbackWrapper()
     199        {
     200            callback(new ExtensionSidebarPane(id));
     201        }
     202        extensionServer.sendRequest(request, callback && callbackWrapper);
     203    },
     204
     205    createWatchExpressionSidebarPane: function(title, callback)
     206    {
     207        var id = "watch-sidebar-" + extensionServer.nextObjectId();
     208        var request = {
     209            command: "createWatchExpressionSidebarPane",
     210            panel: this._id,
     211            id: id,
     212            title: title
     213        };
     214        function callbackWrapper()
     215        {
     216            callback(new WatchExpressionSidebarPane(id));
     217        }
     218        extensionServer.sendRequest(request, callback && callbackWrapper);
     219    }
     220}
     221
     222PanelWithSidebarImpl.prototype.__proto__ = PanelImpl.prototype;
     223
     224function ElementsPanel()
     225{
     226    var id = "elements";
     227    PanelWithSidebar.call(this, id);
    179228    this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
    180 }
    181 
    182 PanelImpl.prototype = {
    183     createSidebarPane: function(title, url, callback)
    184     {
    185         var id = "extension-sidebar-" + extensionServer.nextObjectId();
    186         function callbackWrapper(result)
    187         {
    188             if (result.isError)
    189                 callback(result);
    190             else
    191                 callback(new ExtensionSidebarPane(id));
    192         }
    193         extensionServer.sendRequest({ command: "createSidebarPane", panel: this._id, id: id, title: title, url: expandURL(url) }, callback && callbackWrapper);
    194     },
    195 
    196     createWatchExpressionSidebarPane: function(title, callback)
    197     {
    198         var id = "watch-sidebar-" + extensionServer.nextObjectId();
    199         function callbackWrapper(result)
    200         {
    201             if (result.isError)
    202                 callback(result);
    203             else
    204                 callback(new WatchExpressionSidebarPane(id));
    205         }
    206         extensionServer.sendRequest({ command: "createWatchExpressionSidebarPane", panel: this._id, id: id, title: title }, callback && callbackWrapper);
    207     }
    208229}
    209230
     
    223244    {
    224245        extensionServer.sendRequest({ command: "setSidebarHeight", id: this._id, height: height });
    225     },
    226 
    227     setExpanded: function(expanded)
    228     {
    229         extensionServer.sendRequest({ command: "setSidebarExpanded", id: this._id, expanded: expanded });
    230246    }
    231247}
     
    262278
    263279Audits.prototype = {
    264     addCategory: function(displayName, ruleCount)
     280    addCategory: function(displayName, resultCount)
    265281    {
    266282        var id = "extension-audit-category-" + extensionServer.nextObjectId();
    267         extensionServer.sendRequest({ command: "addAuditCategory", id: id, displayName: displayName, ruleCount: ruleCount });
     283        extensionServer.sendRequest({ command: "addAuditCategory", id: id, displayName: displayName, resultCount: resultCount });
    268284        return new AuditCategory(id);
    269285    }
     
    272288function AuditCategoryImpl(id)
    273289{
    274     function customDispatch(request)
     290    function auditResultDispatch(request)
    275291    {
    276292        var auditResult = new AuditResult(request.arguments[0]);
     
    283299    }
    284300    this._id = id;
    285     this.onAuditStarted = new EventSink("audit-started-" + id, customDispatch);
     301    this.onAuditStarted = new EventSink("audit-started-" + id, auditResultDispatch);
    286302}
    287303
     
    331347    get Severity()
    332348    {
    333         return private.audits.Severity;
     349        return apiPrivate.audits.Severity;
    334350    },
    335351
     
    361377function InspectedWindow()
    362378{
     379    this.onDOMContentLoaded = new EventSink("inspectedPageDOMContentLoaded");
    363380    this.onLoaded = new EventSink("inspectedPageLoaded");
    364381    this.onNavigated = new EventSink("inspectedURLChanged");
    365     this.onDOMContentLoaded = new EventSink("DOMContentLoaded");
    366382}
    367383
     
    372388    },
    373389
    374     evaluate: function(expression, callback)
     390    eval: function(expression, callback)
    375391    {
    376392        function callbackWrapper(result)
    377393        {
    378             if (result && !result.isException)
    379                 result.value = result.value === "undefined" ? undefined : JSON.parse(result.value);
    380             callback(result);
     394            var value = result.value;
     395            if (!result.isException)
     396                value = value === "undefined" ? undefined : JSON.parse(value);
     397            callback(value, result.isException);
    381398        }
    382399        return extensionServer.sendRequest({ command: "evaluateOnInspectedPage", expression: expression }, callback && callbackWrapper);
     
    482499}
    483500
    484 var EventSink = declareInterfaceClass(EventSinkImpl);
    485 var Panel = declareInterfaceClass(PanelImpl);
    486 var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
    487 var WatchExpressionSidebarPane = declareInterfaceClass(WatchExpressionSidebarPaneImpl);
    488501var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
    489502var AuditResult = declareInterfaceClass(AuditResultImpl);
     503var EventSink = declareInterfaceClass(EventSinkImpl);
     504var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
     505var Panel = declareInterfaceClass(PanelImpl);
     506var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
     507var Resource = declareInterfaceClass(ResourceImpl);
     508var WatchExpressionSidebarPane = declareInterfaceClass(WatchExpressionSidebarPaneImpl);
    490509
    491510var extensionServer = new ExtensionServerClient();
  • trunk/WebCore/inspector/front-end/ExtensionCommon.js

    r66477 r72683  
    2929 */
    3030
    31 WebInspector.commonExtensionSymbols = function(private)
     31WebInspector.commonExtensionSymbols = function(apiPrivate)
    3232{
    3333   
    34     if (!private.audits)
    35         private.audits = {};
     34    if (!apiPrivate.audits)
     35        apiPrivate.audits = {};
    3636
    37     private.audits.Severity = {
     37    apiPrivate.audits.Severity = {
    3838        Info: "info",
    3939        Warning: "warning",
  • trunk/WebCore/inspector/front-end/ExtensionServer.js

    r72090 r72683  
    3636    this._status = new WebInspector.ExtensionStatus();
    3737
    38     this._registerHandler("subscribe", this._onSubscribe.bind(this));
    39     this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
    40     this._registerHandler("getResources", this._onGetResources.bind(this));
    41     this._registerHandler("getResourceContent", this._onGetResourceContent.bind(this));
    42     this._registerHandler("getPageTimings", this._onGetPageTimings.bind(this));
     38    this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this));
     39    this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this));
    4340    this._registerHandler("createPanel", this._onCreatePanel.bind(this));
    4441    this._registerHandler("createSidebarPane", this._onCreateSidebar.bind(this));
    4542    this._registerHandler("createWatchExpressionSidebarPane", this._onCreateWatchExpressionSidebarPane.bind(this));
     43    this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this));
     44    this._registerHandler("getHAR", this._onGetHAR.bind(this));
     45    this._registerHandler("getResourceContent", this._onGetResourceContent.bind(this));
    4646    this._registerHandler("log", this._onLog.bind(this));
    47     this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this));
     47    this._registerHandler("reload", this._onReload.bind(this));
    4848    this._registerHandler("setSidebarHeight", this._onSetSidebarHeight.bind(this));
    49     this._registerHandler("setSidebarExpanded", this._onSetSidebarExpansion.bind(this));
    5049    this._registerHandler("setWatchSidebarContent", this._onSetWatchSidebarContent.bind(this));
    51 
    52     this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this));
    53     this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this));
    5450    this._registerHandler("stopAuditCategoryRun", this._onStopAuditCategoryRun.bind(this));
     51    this._registerHandler("subscribe", this._onSubscribe.bind(this));
     52    this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
     53
    5554
    5655    window.addEventListener("message", this._onWindowMessage.bind(this), false);
     
    6362    },
    6463
    65     notifyObjectSelected: function(panelId, objectType, objectId)
    66     {
    67         this._postNotification("panel-objectSelected-" + panelId, objectType, objectId);
     64    notifyObjectSelected: function(panelId, objectId)
     65    {
     66        this._postNotification("panel-objectSelected-" + panelId, objectId);
    6867    },
    6968
    7069    notifyResourceFinished: function(resource)
    7170    {
    72         this._postNotification("resource-finished", this._convertResource(resource));
     71        this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
    7372    },
    7473
     
    7877    },
    7978
    80     notifyInspectedPageLoaded: function()
    81     {
    82         this._postNotification("inspectedPageLoaded");
     79    notifyPageLoaded: function(milliseconds)
     80    {
     81        this._postNotification("inspectedPageLoaded", milliseconds);
     82    },
     83
     84    notifyPageDOMContentLoaded: function(milliseconds)
     85    {
     86        this._postNotification("inspectedPageDOMContentLoaded", milliseconds);
    8387    },
    8488
     
    107111    {
    108112        delete this._clientObjects[auditRun.id];
    109     },
    110 
    111     _convertResource: function(resource)
    112     {
    113         return {
    114             id: resource.identifier,
    115             type: WebInspector.Resource.Type.toString(resource.type),
    116             har: (new WebInspector.HAREntry(resource)).build(),
    117         };
    118113    },
    119114
     
    157152        if (id in this._clientObjects || id in WebInspector.panels)
    158153            return this._status.E_EXISTS(id);
    159         var panel = new WebInspector.ExtensionPanel(id, message.label, message.icon);
     154        var panel = new WebInspector.ExtensionPanel(id, message.title, message.icon);
    160155        this._clientObjects[id] = panel;
    161156
     
    217212    },
    218213
    219     _onSetSidebarExpansion: function(message)
    220     {
    221         var sidebar = this._clientObjects[message.id];
    222         if (!sidebar)
    223             return this._status.E_NOTFOUND(message.id);
    224         if (message.expanded)
    225             sidebar.expand();
    226         else
    227             sidebar.collapse();
    228     },
    229 
    230214    _onSetWatchSidebarContent: function(message)
    231215    {
     
    242226    {
    243227        WebInspector.log(message.message);
     228    },
     229
     230    _onReload: function()
     231    {
     232        InspectorBackend.reloadPage();
     233        return this._status.OK();
    244234    },
    245235
     
    287277    },
    288278
    289     _onGetResources: function(request)
    290     {
    291         function resourceWrapper(id)
     279    _onGetHAR: function(request)
     280    {
     281        var harLog = new WebInspector.HARLog();
     282        harLog.includeResourceIds = true;
     283        return harLog.build();
     284    },
     285
     286    _onGetResourceContent: function(message, port)
     287    {
     288        function onContentAvailable(content, encoded)
    292289        {
    293             return WebInspector.extensionServer._convertResource(WebInspector.networkResources[id]);
    294         }
    295 
    296         var response;
    297         if (request.id)
    298             response = WebInspector.networkResources[request.id] ? resourceWrapper(request.id) : this._status.E_NOTFOUND(request.id);
    299         else
    300             response = Object.keys(WebInspector.networkResources).map(resourceWrapper);
    301         return response;
    302     },
    303 
    304     _onGetResourceContent: function(message, port)
    305     {
    306         var ids;
    307         var response = [];
    308 
    309         function onContentAvailable(id, content, encoded)
    310         {
    311             var resourceContent = {
    312                 id: id,
     290            var response = {
    313291                encoding: encoded ? "base64" : "",
    314292                content: content
    315293            };
    316             response.push(resourceContent);
    317             if (response.length === ids.length)
    318                 this._dispatchCallback(message.requestId, port, response);
    319         }
    320 
    321         if (typeof message.ids === "number")
    322             ids = [ message.ids ];
    323         else if (message.ids instanceof Array)
    324             ids = message.ids;
    325         else
    326             return this._status.E_BADARGTYPE("message.ids", "Array", typeof message.ids);
    327 
    328         for (var i = 0; i < ids.length; ++i) {
    329             var id = ids[i];
    330             var resource = WebInspector.networkResources[id];
    331  
    332             if (!resource)
    333                 response.push(this._status.E_NOTFOUND(id));
    334             else
    335                 resource.requestContent(onContentAvailable.bind(this, id));
    336         }
    337         if (response.length === ids.length)
    338294            this._dispatchCallback(message.requestId, port, response);
    339     },
    340 
    341     _onGetPageTimings: function()
    342     {
    343         return (new WebInspector.HARLog()).buildMainResourceTimings();
     295        }
     296        var resource = WebInspector.networkResources[message.id];
     297        if (!resource)
     298            return this._status.E_NOTFOUND(message.id);
     299        resource.requestContent(onContentAvailable.bind(this));
    344300    },
    345301
    346302    _onAddAuditCategory: function(request)
    347303    {
    348         var category = new WebInspector.ExtensionAuditCategory(request.id, request.displayName, request.ruleCount);
     304        var category = new WebInspector.ExtensionAuditCategory(request.id, request.displayName, request.resultCount);
    349305        if (WebInspector.panels.audits.getCategory(category.id))
    350306            return this._status.E_EXISTS(category.id);
     
    410366        var platformAPI = WebInspector.buildPlatformExtensionAPI ? WebInspector.buildPlatformExtensionAPI() : "";
    411367        return "(function(){ " +
    412             "var private = {};" +
    413             "(" + WebInspector.commonExtensionSymbols.toString() + ")(private);" +
     368            "var apiPrivate = {};" +
     369            "(" + WebInspector.commonExtensionSymbols.toString() + ")(apiPrivate);" +
    414370            "(" + WebInspector.injectedExtensionAPI.toString() + ").apply(this, arguments);" +
    415371            "webInspector.resources.Types = " + JSON.stringify(resourceTypes) + ";" +
  • trunk/WebCore/inspector/front-end/HAREntry.js

    r70532 r72683  
    190190WebInspector.HARLog = function()
    191191{
     192    this.includeResourceIds = false;
    192193}
    193194
     
    204205            },
    205206            pages: this._buildPages(),
    206             entries: Object.keys(WebInspector.networkResources).map(this._convertResource)
     207            entries: Object.keys(WebInspector.networkResources).map(this._convertResource.bind(this))
    207208        }
    208209    },
     
    230231    _convertResource: function(id)
    231232    {
    232         return (new WebInspector.HAREntry(WebInspector.networkResources[id])).build();
     233        var entry = (new WebInspector.HAREntry(WebInspector.networkResources[id])).build();
     234        if (this.includeResourceIds)
     235            entry._resourceId = id;
     236        return entry;
    233237    },
    234238
  • trunk/WebCore/inspector/front-end/inspector.js

    r72531 r72683  
    12321232    if (this.panels.network)
    12331233        this.panels.network.mainResourceDOMContentTime = time;
     1234    this.extensionServer.notifyPageDOMContentLoaded((time - WebInspector.mainResource.startTime) * 1000);
    12341235    this.mainResourceDOMContentTime = time;
    12351236}
     
    12401241    if (this.panels.network)
    12411242        this.panels.network.mainResourceLoadTime = time;
     1243    this.extensionServer.notifyPageLoaded((time - WebInspector.mainResource.startTime) * 1000);
    12421244    this.mainResourceLoadTime = time;
    12431245}
     
    14041406    // Cleanup elements panel early on inspected page refresh.
    14051407    WebInspector.setDocument(null);
    1406     this.extensionServer.notifyInspectedPageLoaded();
    14071408}
    14081409
Note: See TracChangeset for help on using the changeset viewer.