Commit e061c7f1 authored by joepeck@webkit.org's avatar joepeck@webkit.org

Web Inspector: Download Web Archive of Inspected Page

https://bugs.webkit.org/show_bug.cgi?id=119774

Reviewed by Timothy Hatcher.

Source/WebCore:

Add PageAgent.archive which will return a Base-64 encoded web archive
when successful. In order to then allow saving non-string files, extend
InspectorFrontendHost.save to allow for Base-64 encoded data.

* inspector/Inspector.json:
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::archive):
* inspector/InspectorPageAgent.h:
Introduce and implement PageAgent.archive. Create a Web Archive of the
page's main frame.

* inspector/InspectorFrontendClient.h:
* inspector/InspectorFrontendClientLocal.h:
(WebCore::InspectorFrontendClientLocal::save):
* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::save):
* inspector/InspectorFrontendHost.h:
* inspector/InspectorFrontendHost.idl:
Extend InspectorFrontendHost.save to include a base64Encoded param.

* inspector/front-end/FileManager.js:
* inspector/front-end/InspectorFrontendHostStub.js:
(.WebInspector.InspectorFrontendHostStub.prototype.save):
Misc. updates to the old inspector for function changes.

Source/WebInspectorUI:

* UserInterface/ContentBrowser.js:
(WebInspector.ContentBrowser.prototype._saveDataToFile):
Allow a custom save handler which will do all the work.

* UserInterface/DOMTreeContentView.js:
(WebInspector.DOMTreeContentView):
(WebInspector.DOMTreeContentView.prototype.get supportsSave):
(WebInspector.DOMTreeContentView.prototype.get saveData.saveHandler):
(WebInspector.DOMTreeContentView.prototype.get saveData):
Allow Save keyboard shortcut to download an archive viewing the DOM Tree.

* UserInterface/ResourceTreeElement.js:
(WebInspector.ResourceTreeElement.prototype._updateStatus):
* UserInterface/FrameTreeElement.js:
(WebInspector.FrameTreeElement):
(WebInspector.FrameTreeElement.prototype.updateStatusForMainFrame):
(WebInspector.FrameTreeElement.prototype._mainResourceDidChange):
(WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders):
(WebInspector.FrameTreeElement.prototype._reloadPageClicked):
(WebInspector.FrameTreeElement.prototype._downloadButtonClicked):
(WebInspector.FrameTreeElement.prototype._updateDownloadButton):
(WebInspector.FrameTreeElement.prototype._pageArchiveStarted):
(WebInspector.FrameTreeElement.prototype._pageArchiveEnded):
Move handling of main frame TreeElement buttons to FrameTreeElement.
Add a Download button, and enable/disable it appropriately.

* UserInterface/ResourceTreeElement.css:
* UserInterface/TreeElementStatusButton.css: Copied from Source/WebInspectorUI/UserInterface/ResourceTreeElement.css.
(.item > .status > .status-button):
(.item > .status > .status-button > svg *):
(.item.selected > .status > .status-button > svg *):
(.item.selected > .status > .status-button:active > svg *):
(.item > .status > .status-button.disabled > svg *):
(.item.selected > .status > .status-button.disabled > svg *):
* UserInterface/TreeElementStatusButton.js: Added.
(WebInspector.TreeElementStatusButton):
(WebInspector.TreeElementStatusButton.prototype.get element):
(WebInspector.TreeElementStatusButton.prototype.get hidden):
(WebInspector.TreeElementStatusButton.prototype.set hidden):
(WebInspector.TreeElementStatusButton.prototype.get enabled):
(WebInspector.TreeElementStatusButton.prototype.set enabled):
(WebInspector.TreeElementStatusButton.prototype._clicked):
Make buttons in the TreeElement status a generic class to share styling
and handling of the buttons. New "disabled" state with even more
transparent is used when the page is downloading.

* UserInterface/Main.html:
* UserInterface/Main.js:
(WebInspector.archiveMainFrame):
(WebInspector.canArchiveMainFrame):
Generic API for archiving the page and determining if you can archive it.

* UserInterface/InspectorBackendCommands.js:
* UserInterface/InspectorFrontendHostStub.js:
(.WebInspector.InspectorFrontendHostStub.prototype.save):
* UserInterface/Images/DownloadArrow.svg: Added.
* Localizations/en.lproj/localizedStrings.js:
Misc. updates and new files.

Source/WebKit/mac:

Update to support InspectorFrontendHost.save's new base64Encoded
parameter. It means the incoming content is binary data, not a string.

* WebCoreSupport/WebInspectorClient.h:
* WebCoreSupport/WebInspectorClient.mm:
(WebInspectorFrontendClient::save):

Source/WebKit2:

Update to support InspectorFrontendHost.save's new base64Encoded
parameter. It means the incoming content is binary data, not a string.

* UIProcess/WebInspectorProxy.cpp:
(WebKit::WebInspectorProxy::save):
* UIProcess/WebInspectorProxy.h:
* UIProcess/WebInspectorProxy.messages.in:
* UIProcess/efl/WebInspectorProxyEfl.cpp:
(WebKit::WebInspectorProxy::platformSave):
* UIProcess/gtk/WebInspectorProxyGtk.cpp:
(WebKit::WebInspectorProxy::platformSave):
* UIProcess/mac/WebInspectorProxyMac.mm:
(WebKit::WebInspectorProxy::platformSave):
* UIProcess/qt/WebInspectorProxyQt.cpp:
(WebKit::WebInspectorProxy::platformSave):
* WebProcess/WebCoreSupport/WebInspectorFrontendClient.cpp:
(WebKit::WebInspectorFrontendClient::save):
* WebProcess/WebCoreSupport/WebInspectorFrontendClient.h:
* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::save):
* WebProcess/WebPage/WebInspector.h:

LayoutTests:

* inspector-protocol/page/archive-expected.txt: Added.
* inspector-protocol/page/archive.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154828 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent be668e75
2013-08-29 Joseph Pecoraro <pecoraro@apple.com>
Web Inspector: Download Web Archive of Inspected Page
https://bugs.webkit.org/show_bug.cgi?id=119774
Reviewed by Timothy Hatcher.
* inspector-protocol/page/archive-expected.txt: Added.
* inspector-protocol/page/archive.html: Added.
2013-08-29 Robert Hogan <robert@webkit.org>
Positioned Replaced Elements That Aren't RenderReplaced get Incorrect Width
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/protocol-test.js"></script>
<script>
function test()
{
InspectorTest.sendCommand("Page.enable", {});
InspectorTest.sendCommand("Page.archive", {}, function(event) {
var data = event.result.data;
if (!data)
InspectorTest.log("FAIL: no data");
else if (data.length < 1000)
InspectorTest.log("FAIL: unexpectedly short data. A serialized archive should be pretty large.");
else
InspectorTest.log("PASS: Received archive data.");
InspectorTest.completeTest();
});
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
2013-08-29 Joseph Pecoraro <pecoraro@apple.com>
Web Inspector: Download Web Archive of Inspected Page
https://bugs.webkit.org/show_bug.cgi?id=119774
Reviewed by Timothy Hatcher.
Add PageAgent.archive which will return a Base-64 encoded web archive
when successful. In order to then allow saving non-string files, extend
InspectorFrontendHost.save to allow for Base-64 encoded data.
* inspector/Inspector.json:
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::archive):
* inspector/InspectorPageAgent.h:
Introduce and implement PageAgent.archive. Create a Web Archive of the
page's main frame.
* inspector/InspectorFrontendClient.h:
* inspector/InspectorFrontendClientLocal.h:
(WebCore::InspectorFrontendClientLocal::save):
* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::save):
* inspector/InspectorFrontendHost.h:
* inspector/InspectorFrontendHost.idl:
Extend InspectorFrontendHost.save to include a base64Encoded param.
* inspector/front-end/FileManager.js:
* inspector/front-end/InspectorFrontendHostStub.js:
(.WebInspector.InspectorFrontendHostStub.prototype.save):
Misc. updates to the old inspector for function changes.
2013-08-29 Robert Hogan <robert@webkit.org>
Positioned Replaced Elements That Aren't RenderReplaced get Incorrect Width
......@@ -424,6 +424,13 @@
{ "name": "accept", "type": "boolean", "description": "Whether to accept or dismiss the dialog." },
{ "name": "promptText", "type": "string", "optional": true, "description": "The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog." }
]
},
{
"name": "archive",
"description": "Grab an archive of the page.",
"returns": [
{ "name": "data", "type": "string", "description": "Base64-encoded web archive." }
]
}
],
"events": [
......
......@@ -68,7 +68,7 @@ public:
virtual void openInNewTab(const String& url) = 0;
virtual bool canSave() = 0;
virtual void save(const WTF::String& url, const WTF::String& content, bool forceSaveAs) = 0;
virtual void save(const WTF::String& url, const WTF::String& content, bool base64Encoded, bool forceSaveAs) = 0;
virtual void append(const WTF::String& url, const WTF::String& content) = 0;
virtual void inspectedURLChanged(const String&) = 0;
......
......@@ -68,7 +68,7 @@ public:
virtual void changeAttachedWindowWidth(unsigned);
virtual void openInNewTab(const String& url);
virtual bool canSave() { return false; }
virtual void save(const String&, const String&, bool) { }
virtual void save(const String&, const String&, bool, bool) { }
virtual void append(const String&, const String&) { }
virtual void attachWindow(DockSide) = 0;
......@@ -118,7 +118,7 @@ private:
friend class FrontendMenuProvider;
InspectorController* m_inspectorController;
Page* m_frontendPage;
Page* m_frontendPage;
// TODO(yurys): this ref shouldn't be needed.
RefPtr<InspectorFrontendHost> m_frontendHost;
OwnPtr<InspectorFrontendClientLocal::Settings> m_settings;
......
......@@ -240,10 +240,10 @@ bool InspectorFrontendHost::canSave()
return false;
}
void InspectorFrontendHost::save(const String& url, const String& content, bool forceSaveAs)
void InspectorFrontendHost::save(const String& url, const String& content, bool base64Encoded, bool forceSaveAs)
{
if (m_client)
m_client->save(url, content, forceSaveAs);
m_client->save(url, content, base64Encoded, forceSaveAs);
}
void InspectorFrontendHost::append(const String& url, const String& content)
......
......@@ -74,7 +74,7 @@ public:
void copyText(const String& text);
void openInNewTab(const String& url);
bool canSave();
void save(const String& url, const String& content, bool forceSaveAs);
void save(const String& url, const String& content, bool base64Encoded, bool forceSaveAs);
void append(const String& url, const String& content);
void close(const String& url);
......
......@@ -55,7 +55,7 @@
void copyText(DOMString text);
void openInNewTab(DOMString url);
boolean canSave();
void save(DOMString url, DOMString content, boolean forceSaveAs);
void save(DOMString url, DOMString content, boolean base64Encoded, boolean forceSaveAs);
void append(DOMString url, DOMString content);
void close(DOMString url);
......
......@@ -83,6 +83,10 @@
#include <wtf/text/Base64.h>
#include <wtf/text/StringBuilder.h>
#if ENABLE(WEB_ARCHIVE) && USE(CF)
#include "LegacyWebArchive.h"
#endif
namespace WebCore {
namespace PageAgentState {
......@@ -1328,6 +1332,29 @@ void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool a
*errorString = "Could not handle JavaScript dialog";
}
void InspectorPageAgent::archive(ErrorString* errorString, String* data)
{
Frame* frame = mainFrame();
if (!frame) {
*errorString = "No main frame";
return;
}
#if ENABLE(WEB_ARCHIVE) && USE(CF)
RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame);
if (!archive) {
*errorString = "Could not create web archive for main frame";
return;
}
RetainPtr<CFDataRef> buffer = archive->rawDataRepresentation();
*data = base64Encode(reinterpret_cast<const char*>(CFDataGetBytePtr(buffer.get())), CFDataGetLength(buffer.get()));
#else
UNUSED_PARAM(data);
*errorString = "No support for creating archives";
#endif
}
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
......@@ -131,6 +131,7 @@ public:
virtual void setCompositingBordersVisible(ErrorString*, bool);
virtual void captureScreenshot(ErrorString*, String* data);
virtual void handleJavaScriptDialog(ErrorString*, bool accept, const String* promptText);
virtual void archive(ErrorString*, String* data);
// Geolocation override helpers.
GeolocationPosition* overrideGeolocationPosition(GeolocationPosition*);
......
......@@ -61,7 +61,7 @@ WebInspector.FileManager.prototype = {
var savedURLs = WebInspector.settings.savedURLs.get();
delete savedURLs[url];
WebInspector.settings.savedURLs.set(savedURLs);
InspectorFrontendHost.save(url, content, forceSaveAs);
InspectorFrontendHost.save(url, content, false, forceSaveAs);
},
/**
......
......@@ -132,7 +132,7 @@ WebInspector.InspectorFrontendHostStub.prototype = {
return true;
},
save: function(url, content, forceSaveAs)
save: function(url, content, base64Encoded, forceSaveAs)
{
if (this._fileBuffers[url])
throw new Error("Concurrent file modification denied.");
......
2013-08-29 Joseph Pecoraro <pecoraro@apple.com>
Web Inspector: Download Web Archive of Inspected Page
https://bugs.webkit.org/show_bug.cgi?id=119774
Reviewed by Timothy Hatcher.
* UserInterface/ContentBrowser.js:
(WebInspector.ContentBrowser.prototype._saveDataToFile):
Allow a custom save handler which will do all the work.
* UserInterface/DOMTreeContentView.js:
(WebInspector.DOMTreeContentView):
(WebInspector.DOMTreeContentView.prototype.get supportsSave):
(WebInspector.DOMTreeContentView.prototype.get saveData.saveHandler):
(WebInspector.DOMTreeContentView.prototype.get saveData):
Allow Save keyboard shortcut to download an archive viewing the DOM Tree.
* UserInterface/ResourceTreeElement.js:
(WebInspector.ResourceTreeElement.prototype._updateStatus):
* UserInterface/FrameTreeElement.js:
(WebInspector.FrameTreeElement):
(WebInspector.FrameTreeElement.prototype.updateStatusForMainFrame):
(WebInspector.FrameTreeElement.prototype._mainResourceDidChange):
(WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders):
(WebInspector.FrameTreeElement.prototype._reloadPageClicked):
(WebInspector.FrameTreeElement.prototype._downloadButtonClicked):
(WebInspector.FrameTreeElement.prototype._updateDownloadButton):
(WebInspector.FrameTreeElement.prototype._pageArchiveStarted):
(WebInspector.FrameTreeElement.prototype._pageArchiveEnded):
Move handling of main frame TreeElement buttons to FrameTreeElement.
Add a Download button, and enable/disable it appropriately.
* UserInterface/ResourceTreeElement.css:
* UserInterface/TreeElementStatusButton.css: Copied from Source/WebInspectorUI/UserInterface/ResourceTreeElement.css.
(.item > .status > .status-button):
(.item > .status > .status-button > svg *):
(.item.selected > .status > .status-button > svg *):
(.item.selected > .status > .status-button:active > svg *):
(.item > .status > .status-button.disabled > svg *):
(.item.selected > .status > .status-button.disabled > svg *):
* UserInterface/TreeElementStatusButton.js: Added.
(WebInspector.TreeElementStatusButton):
(WebInspector.TreeElementStatusButton.prototype.get element):
(WebInspector.TreeElementStatusButton.prototype.get hidden):
(WebInspector.TreeElementStatusButton.prototype.set hidden):
(WebInspector.TreeElementStatusButton.prototype.get enabled):
(WebInspector.TreeElementStatusButton.prototype.set enabled):
(WebInspector.TreeElementStatusButton.prototype._clicked):
Make buttons in the TreeElement status a generic class to share styling
and handling of the buttons. New "disabled" state with even more
transparent is used when the page is downloading.
* UserInterface/Main.html:
* UserInterface/Main.js:
(WebInspector.archiveMainFrame):
(WebInspector.canArchiveMainFrame):
Generic API for archiving the page and determining if you can archive it.
* UserInterface/InspectorBackendCommands.js:
* UserInterface/InspectorFrontendHostStub.js:
(.WebInspector.InspectorFrontendHostStub.prototype.save):
* UserInterface/Images/DownloadArrow.svg: Added.
* Localizations/en.lproj/localizedStrings.js:
Misc. updates and new files.
2013-08-28 Joseph Pecoraro <pecoraro@apple.com>
Web Inspector: Give reload icon an :active state and allow CSS to style some SVG images
......
......@@ -276,12 +276,17 @@ WebInspector.ContentBrowser.prototype = {
if (!saveData)
return;
if (typeof saveData.customSaveHandler === "function") {
saveData.customSaveHandler(forceSaveAs);
return;
}
console.assert(saveData.url);
console.assert(typeof saveData.content === "string");
if (!saveData.url || typeof saveData.content !== "string")
return;
InspectorFrontendHost.save(saveData.url, saveData.content, forceSaveAs || saveData.forceSaveAs);
InspectorFrontendHost.save(saveData.url, saveData.content, false, forceSaveAs || saveData.forceSaveAs);
},
_save: function(event)
......
......@@ -29,12 +29,10 @@ WebInspector.DOMTreeContentView = function(domTree)
WebInspector.ContentView.call(this, domTree);
// The navigation item for the compositing borders button.
this._compositingBordersButtonNavigationItem = new WebInspector.ActivateButtonNavigationItem("layer-borders", WebInspector.UIString("Show compositing borders"), WebInspector.UIString("Hide compositing borders"), "Images/LayerBorders.svg", 16, 16);
this._compositingBordersButtonNavigationItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._toggleCompositingBorders, this);
this._compositingBordersButtonNavigationItem.enabled = !!PageAgent.getCompositingBordersVisible;
// The navigation item for the shadow tree toggle button.
WebInspector.showShadowDOMSetting.addEventListener(WebInspector.Setting.Event.Changed, this._showShadowDOMSettingChanged, this);
this._showsShadowDOMButtonNavigationItem = new WebInspector.ActivateButtonNavigationItem("shows-shadow-DOM", WebInspector.UIString("Show shadow DOM nodes"), WebInspector.UIString("Hide shadow DOM nodes"), "Images/ShadowDOM.svg", 16, 16);
this._showsShadowDOMButtonNavigationItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._toggleShowsShadowDOMSetting, this);
......@@ -148,6 +146,21 @@ WebInspector.DOMTreeContentView.prototype = {
selectedDOMNode.copyNode();
},
get supportsSave()
{
return WebInspector.canArchiveMainFrame();
},
get saveData()
{
function saveHandler(forceSaveAs)
{
WebInspector.archiveMainFrame();
}
return { customSaveHandler: saveHandler };
},
get supportsSearch()
{
return true;
......
......@@ -40,6 +40,12 @@ WebInspector.FrameTreeElement = function(frame, representedObject)
frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasAdded, this._childFrameWasAdded, this);
frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasRemoved, this._childFrameWasRemoved, this);
if (this._frame.isMainFrame()) {
this._downloadingPage = false;
WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveStarted, this._pageArchiveStarted, this);
WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveEnded, this._pageArchiveEnded, this);
}
this._updateParentStatus();
this.shouldRefreshChildren = true;
};
......@@ -102,6 +108,47 @@ WebInspector.FrameTreeElement.prototype = {
WebInspector.GeneralTreeElement.prototype.onattach.call(this);
},
// Called from ResourceTreeElement.
updateStatusForMainFrame: function()
{
function loadedImages()
{
if (!this._reloadButton || !this._downloadButton)
return;
var fragment = document.createDocumentFragment("div");
fragment.appendChild(this._downloadButton.element);
fragment.appendChild(this._reloadButton.element);
this.status = fragment;
delete this._loadingMainFrameButtons;
}
if (this._reloadButton && this._downloadButton) {
loadedImages.call(this);
return;
}
if (!this._loadingMainFrameButtons) {
this._loadingMainFrameButtons = true;
var tooltip = WebInspector.UIString("Reload page (%s)\nReload ignoring cache (%s)").format(WebInspector._reloadPageKeyboardShortcut.displayName, WebInspector._reloadPageIgnoringCacheKeyboardShortcut.displayName);
wrappedSVGDocument("Images/Reload.svg", null, tooltip, function(element) {
this._reloadButton = new WebInspector.TreeElementStatusButton(element);
this._reloadButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._reloadPageClicked, this);
loadedImages.call(this);
}.bind(this));
wrappedSVGDocument("Images/DownloadArrow.svg", null, WebInspector.UIString("Download Web Archive"), function(element) {
this._downloadButton = new WebInspector.TreeElementStatusButton(element);
this._downloadButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._downloadButtonClicked, this);
this._updateDownloadButton();
loadedImages.call(this);
}.bind(this));
}
},
// Overrides from TreeElement (Private).
onpopulate: function()
......@@ -191,6 +238,9 @@ WebInspector.FrameTreeElement.prototype = {
// shouldRefreshChildren will call onpopulate if expanded is true.
this._updateExpandedSetting();
if (this._frame.isMainFrame())
this._updateDownloadButton();
this.shouldRefreshChildren = true;
},
......@@ -486,6 +536,48 @@ WebInspector.FrameTreeElement.prototype = {
}
return false;
},
_reloadPageClicked: function(event)
{
// Ignore cache when the shift key is pressed.
PageAgent.reload(event.data.shiftKey);
},
_downloadButtonClicked: function(event)
{
WebInspector.archiveMainFrame();
},
_updateDownloadButton: function()
{
console.assert(this._frame.isMainFrame());
if (!this._downloadButton)
return;
if (!PageAgent.archive) {
this._downloadButton.hidden = true;
return;
}
if (this._downloadingPage) {
this._downloadButton.enabled = false;
return;
}
this._downloadButton.enabled = WebInspector.canArchiveMainFrame();
},
_pageArchiveStarted: function(event)
{
this._downloadingPage = true;
this._updateDownloadButton();
},
_pageArchiveEnded: function(event)
{
this._downloadingPage = false;
this._updateDownloadButton();
}
};
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright © 2013 Apple Inc. All rights reserved. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="M 8.5 14 L 3.5 8 L 7 8 L 7 2 L 10 2 L 10 8 L 13.5 8 Z M 8.5 14"/>
</svg>
......@@ -16,7 +16,6 @@ InspectorBackend.registerCommand("Inspector.disable", [], []);
// Memory.
InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory");
InspectorBackend.registerEvent("Memory.addNativeSnapshotChunk", ["chunk"]);
InspectorBackend.registerCommand("Memory.getDOMCounters", [], ["documents", "nodes", "jsEventListeners"]);
// Page.
......@@ -69,6 +68,7 @@ InspectorBackend.registerCommand("Page.getCompositingBordersVisible", [], ["resu
InspectorBackend.registerCommand("Page.setCompositingBordersVisible", [{"name": "visible", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.captureScreenshot", [], ["data"]);
InspectorBackend.registerCommand("Page.handleJavaScriptDialog", [{"name": "accept", "type": "boolean", "optional": false}, {"name": "promptText", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("Page.archive", [], ["data"]);
// Runtime.
InspectorBackend.registerRuntimeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Runtime");
......@@ -241,6 +241,7 @@ InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.namedFlowCreated", ["namedFlow"]);
InspectorBackend.registerEvent("CSS.namedFlowRemoved", ["documentNodeId", "flowName"]);
InspectorBackend.registerEvent("CSS.regionLayoutUpdated", ["namedFlow"]);
InspectorBackend.registerEvent("CSS.regionOversetChanged", ["namedFlow"]);
InspectorBackend.registerCommand("CSS.enable", [], []);
InspectorBackend.registerCommand("CSS.disable", [], []);
InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]);
......
......@@ -95,7 +95,7 @@ if (!window.InspectorFrontendHost) {
window.open(url, "_blank");
},
save: function(url, content, forceSaveAs)
save: function(url, content, base64Encoded, forceSaveAs)
{
},
......
......@@ -79,6 +79,7 @@
<link rel="stylesheet" href="ApplicationCacheFrameContentView.css">
<link rel="stylesheet" href="ApplicationCacheIcons.css">
<link rel="stylesheet" href="ResourceTreeElement.css">
<link rel="stylesheet" href="TreeElementStatusButton.css">
<link rel="stylesheet" href="InstrumentSidebarPanel.css">
<link rel="stylesheet" href="InstrumentIcons.css">
<link rel="stylesheet" href="TimelinesContentView.css">
......@@ -225,6 +226,7 @@
<script src="DOMStorageTreeElement.js"></script>
<script src="ApplicationCacheFrameTreeElement.js"></script>
<script src="ApplicationCacheManifestTreeElement.js"></script>
<script src="TreeElementStatusButton.js"></script>
<script src="IssueMessage.js"></script>
<script src="FrameTreeElement.js"></script>
<script src="CSSCompletions.js"></script>
......
......@@ -24,7 +24,9 @@
*/
WebInspector.Notification = {
GlobalModifierKeysDidChange: "global-modifiers-did-change"
GlobalModifierKeysDidChange: "global-modifiers-did-change",
PageArchiveStarted: "page-archive-started",
PageArchiveEnded: "page-archive-ended"
};
WebInspector.loaded = function()
......@@ -1715,3 +1717,29 @@ WebInspector.revertDomChanges = function(domChanges)
}
}
}
WebInspector.archiveMainFrame = function()
{
this.notifications.dispatchEventToListeners(WebInspector.Notification.PageArchiveStarted, event);
setTimeout(function() {
PageAgent.archive(function(error, data) {
this.notifications.dispatchEventToListeners(WebInspector.Notification.PageArchiveEnded, event);
if (error)
return;
var mainFrame = WebInspector.frameResourceManager.mainFrame;
var archiveName = mainFrame.mainResource.urlComponents.host || mainFrame.mainResource.displayName || "Archive";
var url = "web-inspector:///" + encodeURI(archiveName) + ".webarchive";
InspectorFrontendHost.save(url, data, true, true);
}.bind(this));
}.bind(this), 3000);
}
WebInspector.canArchiveMainFrame = function()
{
if (!PageAgent.archive)
return false;
return WebInspector.Resource.Type.fromMIMEType(WebInspector.frameResourceManager.mainFrame.mainResource.mimeType) === WebInspector.Resource.Type.Document;
}
......@@ -30,20 +30,3 @@
.item.resource.failed .subtitle {
color: rgba(224, 16, 16, 0.7) !important;
}
.item.resource > .status > .reload-button {
width: 16px;
height: 16px;
}
.item.resource > .status > .reload-button > svg * {
fill: rgb(112, 126, 139);
}
.item.resource.selected > .status > .reload-button > svg * {
fill: white;
}
.item.resource.selected > .status > .reload-button:active > svg * {
fill: rgba(255, 255, 255, 0.75);
}
......@@ -185,7 +185,7 @@ WebInspector.ResourceTreeElement.prototype = {
// Remove the spinner and replace with a reload button in case it's the main frame's main resource.
var frame = this._resource.parentFrame;
if (this._resource.isMainResource() && frame && frame.isMainFrame())
this._updateStatusWithMainFrameButtons();
this.updateStatusForMainFrame();
else
this.status = null;
} else {
......@@ -199,14 +199,6 @@ WebInspector.ResourceTreeElement.prototype = {
this.tooltip = this._resource.url;
},
_reloadPageClicked: function(event)
{
event.stopPropagation();
// Ignore cache when the shift key is pressed.
PageAgent.reload(event.shiftKey);
},
_urlDidChange: function(event)
{
this._updateTitles();
......
/*
* 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 INC. 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 INC. 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)