diff options
author | John Reck <jreck@google.com> | 2010-11-04 12:00:17 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2010-11-09 11:35:04 -0800 |
commit | e14391e94c850b8bd03680c23b38978db68687a8 (patch) | |
tree | 3fed87e6620fecaf3edc7259ae58a11662bedcb2 /WebCore/inspector | |
parent | 1bd705833a68f07850cf7e204b26f8d328d16951 (diff) | |
download | external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.zip external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.gz external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.bz2 |
Merge Webkit at r70949: Initial merge by git.
Change-Id: I77b8645c083b5d0da8dba73ed01d4014aab9848e
Diffstat (limited to 'WebCore/inspector')
58 files changed, 3281 insertions, 1756 deletions
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl index 85c30a8..331e504 100644 --- a/WebCore/inspector/Inspector.idl +++ b/WebCore/inspector/Inspector.idl @@ -94,12 +94,7 @@ module core { // This method is going to be broken down into smaller parts. [handler=Controller] void populateScriptObjects(); - [handler=Controller] void getSettings(out Object settings); [handler=Controller] void getInspectorState(out Object state); - [handler=Controller] void storeLastActivePanel(in String panelName); - - [handler=Controller] void saveApplicationSettings(in String settings); - [handler=Controller] void saveSessionSettings(in String settings); [handler=Controller] void setSearchingForNode(in boolean enabled, out boolean newState); @@ -112,19 +107,19 @@ module core { [handler=Controller] void startTimelineProfiler(); [handler=Controller] void stopTimelineProfiler(); - [handler=Resource] void cachedResources(out Array resources); - [handler=Resource] void resourceContent(in unsigned long frameID, in String url, out String content); - [notify] void identifierForInitialRequest(out long identifier, out String url, out unsigned long frameID, out boolean isMainResource); + [handler=Resource] void cachedResources(out Object resources); + [handler=Resource] void resourceContent(in unsigned long frameId, in String url, in boolean base64Encode, out String content); + [notify] void identifierForInitialRequest(out long identifier, out String url, out Object loader); [notify] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse); [notify] void markResourceAsCached(out long identifier); [notify] void didReceiveResponse(out long identifier, out double time, out String resourceType, out Object response); [notify] void didReceiveContentLength(out long identifier, out double time, out long lengthReceived); [notify] void didFinishLoading(out long identifier, out double finishTime); [notify] void didFailLoading(out long identifier, out double time, out String localizedDescription); - [notify] void didLoadResourceFromMemoryCache(out double time, out unsigned long frameID, out Object resource); + [notify] void didLoadResourceFromMemoryCache(out double time, out Object resource); [notify] void setOverrideContent(out long identifier, out String sourceString, out String type); - [notify] void didCommitLoad(out unsigned long frameID); - [notify] void frameDetachedFromParent(out unsigned long frameID); + [notify] void didCommitLoadForFrame(out unsigned long parentFrameId, out Object loader); + [notify] void frameDetachedFromParent(out unsigned long frameId); [notify] void didCreateWebSocket(out unsigned long identifier, out String requestURL); [notify] void willSendWebSocketHandshakeRequest(out unsigned long identifier, out double time, out Object request); diff --git a/WebCore/inspector/InspectorCSSAgent.cpp b/WebCore/inspector/InspectorCSSAgent.cpp index e0fab85..d1f7412 100644 --- a/WebCore/inspector/InspectorCSSAgent.cpp +++ b/WebCore/inspector/InspectorCSSAgent.cpp @@ -49,7 +49,8 @@ #include <wtf/Vector.h> #include <wtf/text/CString.h> - +// Currently implemented model: +// // cssProperty = { // name : <string>, // value : <string>, @@ -62,85 +63,57 @@ // endOffset : <number>, // Optional - property text end offset in enclosing style declaration. Absent for computed styles and such. // } // +// name + value + priority : present when the property is enabled +// text : present when the property is disabled +// +// For disabled properties, startOffset === endOffset === insertion point for the property. +// // status: // "disabled" == property disabled by user // "active" == property participates in the computed style calculation // "inactive" == property does no participate in the computed style calculation (i.e. overridden by a subsequent property with the same name) // "style" == property is active and originates from the WebCore CSSStyleDeclaration rather than CSS source code (e.g. implicit longhand properties) // -// // cssStyle = { -// styleId : <number>, // Optional -// styleSheetId : <number>, // Parent: -1 for inline styles (<foo style="..">) -// cssProperties : [ +// styleId : <string>, // Optional +// cssProperties : [ // #cssProperty, // ... // #cssProperty -// ], -// shorthandValues : { +// ], +// shorthandValues : { // shorthandName1 : shorthandValue1, // shorthandName2 : shorthandValue2 -// }, -// cssText : <string>, // declaration text -// properties : { } // ??? +// }, +// cssText : <string>, // Optional - declaration text +// properties : { width, height } // } // -// // TODO: -// // - convert disabledProperties to enabled flag. -// // - convert width, height to properties -// // cssRule = { -// ruleId : <number>, -// selectorText : <string> -// sourceURL : <string> -// sourceLine : <string> -// styleSheetId : <number> // also found in style -// origin : <string> // "" || "user-agent" || "user" || "inspector" +// ruleId : <string>, // Optional +// selectorText : <string>, +// sourceURL : <string>, +// sourceLine : <string>, +// origin : <string>, // "" || "user-agent" || "user" || "inspector" // style : #cssStyle // } // -// // TODO: -// // - fix origin -// // - add sourceURL -// // - fix parentStyleSheetId -// // cssStyleSheet = { // styleSheetId : <number> -// href : <string> +// sourceURL : <string> // title : <string> // disabled : <boolean> -// documentNodeId : <number> // rules : [ // #cssRule, // ... // #cssRule // ] +// text : <string> // Optional - whenever the text is available for a text-based stylesheet // } namespace WebCore { // static -PassRefPtr<InspectorObject> InspectorCSSAgent::buildObjectForStyle(CSSStyleDeclaration* style, const String& fullStyleId, CSSStyleSourceData* sourceData) -{ - RefPtr<InspectorObject> result = InspectorObject::create(); - if (!fullStyleId.isEmpty()) - result->setString("id", fullStyleId); - - result->setString("width", style->getPropertyValue("width")); - result->setString("height", style->getPropertyValue("height")); - Vector<CSSPropertySourceData>* propertyData = 0; - - if (sourceData) { - result->setNumber("startOffset", sourceData->styleBodyRange.start); - result->setNumber("endOffset", sourceData->styleBodyRange.end); - propertyData = &sourceData->propertyData; - } - populateObjectWithStyleProperties(style, result.get(), propertyData); - - return result.release(); -} - -// static CSSStyleSheet* InspectorCSSAgent::parentStyleSheet(StyleBase* styleBase) { if (!styleBase) @@ -164,7 +137,6 @@ CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(StyleBase* styleBase) return static_cast<CSSStyleRule*>(rule); } - InspectorCSSAgent::InspectorCSSAgent(InspectorDOMAgent* domAgent, InspectorFrontend* frontend) : m_domAgent(domAgent) , m_frontend(frontend) @@ -246,7 +218,10 @@ void InspectorCSSAgent::getComputedStyleForNode2(long nodeId, RefPtr<InspectorVa if (!defaultView) return; - *style = buildObjectForStyle(defaultView->getComputedStyle(element, "").get(), ""); + RefPtr<CSSStyleDeclaration> computedStyle = defaultView->getComputedStyle(element, ""); + Vector<InspectorStyleProperty> properties; + RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyle.get(), 0); + *style = inspectorStyle->buildObjectForStyle(); } void InspectorCSSAgent::getInheritedStylesForNode2(long nodeId, RefPtr<InspectorArray>* style) @@ -263,7 +238,7 @@ void InspectorCSSAgent::getInheritedStylesForNode2(long nodeId, RefPtr<Inspector if (parentElement->style() && parentElement->style()->length()) { InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(element); if (styleSheet) - parentStyle->setObject("inlineStyle", styleSheet->buildObjectForStyle(styleSheet->styleForId("0"))); + parentStyle->setObject("inlineStyle", styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId::createFromParts(styleSheet->id(), "0")))); } CSSStyleSelector* parentSelector = parentElement->ownerDocument()->styleSelector(); @@ -308,43 +283,48 @@ void InspectorCSSAgent::setStyleSheetText2(const String& styleSheetId, const Str inspectorStyleSheet->setText(text); } -void InspectorCSSAgent::setStyleText2(const String& fullStyleId, const String& text, RefPtr<InspectorValue>* result) +void InspectorCSSAgent::setPropertyText2(const String& fullStyleId, long propertyIndex, const String& text, bool overwrite, RefPtr<InspectorValue>* result) { - Vector<String> idParts; - fullStyleId.split(':', idParts); - ASSERT(idParts.size() == 2); + InspectorCSSId compoundId(fullStyleId); + ASSERT(!compoundId.isEmpty()); - InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(idParts.at(0)); + InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(compoundId.styleSheetId()); if (!inspectorStyleSheet) return; - if (!inspectorStyleSheet->setStyleText(idParts.at(1), text)) - return; - - *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(idParts.at(1))); + bool success = inspectorStyleSheet->setPropertyText(compoundId, propertyIndex, text, overwrite); + if (success) + *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); } -void InspectorCSSAgent::toggleProperty2(const String&, long, bool) +void InspectorCSSAgent::toggleProperty2(const String& fullStyleId, long propertyIndex, bool disable, RefPtr<InspectorValue>* result) { - // FIXME(apavlov): implement + InspectorCSSId compoundId(fullStyleId); + ASSERT(!compoundId.isEmpty()); + + InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(compoundId.styleSheetId()); + if (!inspectorStyleSheet) + return; + + bool success = inspectorStyleSheet->toggleProperty(compoundId, propertyIndex, disable); + if (success) + *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); } void InspectorCSSAgent::setRuleSelector2(const String& fullRuleId, const String& selector, RefPtr<InspectorValue>* result) { - Vector<String> idParts; - fullRuleId.split(':', idParts); - ASSERT(idParts.size() == 2); + InspectorCSSId compoundId(fullRuleId); + ASSERT(!compoundId.isEmpty()); - InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(idParts.at(0)); + InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(compoundId.styleSheetId()); if (!inspectorStyleSheet) return; - const String& ruleId = idParts.at(1); - bool success = inspectorStyleSheet->setRuleSelector(ruleId, selector); + bool success = inspectorStyleSheet->setRuleSelector(compoundId, selector); if (!success) return; - *result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(ruleId)); + *result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId)); } void InspectorCSSAgent::addRule2(const long contextNodeId, const String& selector, RefPtr<InspectorValue>* result) @@ -379,130 +359,6 @@ Element* InspectorCSSAgent::inlineStyleElement(CSSStyleDeclaration* style) return static_cast<Element*>(node); } -// static -void InspectorCSSAgent::populateObjectWithStyleProperties(CSSStyleDeclaration* style, InspectorObject* result, Vector<CSSPropertySourceData>* propertyData) -{ - RefPtr<InspectorArray> properties = InspectorArray::create(); - RefPtr<InspectorObject> shorthandValues = InspectorObject::create(); - HashMap<String, RefPtr<InspectorObject> > propertyNameToPreviousActiveProperty; - HashSet<String> foundShorthands; - HashSet<String> sourcePropertyNames; - if (propertyData) { - for (Vector<CSSPropertySourceData>::const_iterator it = propertyData->begin(); it != propertyData->end(); ++it) { - const CSSPropertySourceData& propertyEntry = *it; - RefPtr<InspectorObject> property = InspectorObject::create(); - properties->pushObject(property); - const String& name = propertyEntry.name; - sourcePropertyNames.add(name); - property->setString("name", name); - property->setString("value", propertyEntry.value); - property->setString("priority", propertyEntry.important ? "important" : ""); - property->setString("status", "active"); - property->setBoolean("parsedOk", propertyEntry.parsedOk); - property->setNumber("startOffset", propertyEntry.range.start); - property->setNumber("endOffset", propertyEntry.range.end); - if (propertyEntry.parsedOk) { - property->setBoolean("implicit", false); - String shorthand = style->getPropertyShorthand(name); - property->setString("shorthandName", shorthand); - if (!shorthand.isEmpty() && !foundShorthands.contains(shorthand)) { - foundShorthands.add(shorthand); - shorthandValues->setString(shorthand, shorthandValue(style, shorthand)); - } - } else { - property->setBoolean("implicit", false); - property->setString("shorthandName", ""); - } - HashMap<String, RefPtr<InspectorObject> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(name); - if (activeIt != propertyNameToPreviousActiveProperty.end()) { - activeIt->second->setString("status", "inactive"); - activeIt->second->setString("shorthandName", ""); - } - propertyNameToPreviousActiveProperty.set(name, property); - } - } - - for (int i = 0, size = style->length(); i < size; ++i) { - String name = style->item(i); - if (sourcePropertyNames.contains(name)) - continue; - - sourcePropertyNames.add(name); - RefPtr<InspectorObject> property = InspectorObject::create(); - properties->pushObject(property); - property->setString("name", name); - property->setString("value", style->getPropertyValue(name)); - property->setString("priority", style->getPropertyPriority("name")); - property->setBoolean("implicit", style->isPropertyImplicit(name)); - property->setBoolean("parsedOk", true); - property->setString("status", "style"); - String shorthand = style->getPropertyShorthand(name); - property->setString("shorthandName", shorthand); - if (!shorthand.isEmpty() && !foundShorthands.contains(shorthand)) { - foundShorthands.add(shorthand); - shorthandValues->setString(shorthand, shorthandValue(style, shorthand)); - } - } - - result->setArray("properties", properties); - result->setObject("shorthandValues", shorthandValues); -} - -// static -String InspectorCSSAgent::shorthandValue(CSSStyleDeclaration* style, const String& shorthandProperty) -{ - String value = style->getPropertyValue(shorthandProperty); - if (value.isEmpty()) { - for (unsigned i = 0; i < style->length(); ++i) { - String individualProperty = style->item(i); - if (style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - if (style->isPropertyImplicit(individualProperty)) - continue; - String individualValue = style->getPropertyValue(individualProperty); - if (individualValue == "initial") - continue; - if (value.length()) - value.append(" "); - value.append(individualValue); - } - } - return value; -} - -// static -String InspectorCSSAgent::shorthandPriority(CSSStyleDeclaration* style, const String& shorthandProperty) -{ - String priority = style->getPropertyPriority(shorthandProperty); - if (priority.isEmpty()) { - for (unsigned i = 0; i < style->length(); ++i) { - String individualProperty = style->item(i); - if (style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - priority = style->getPropertyPriority(individualProperty); - break; - } - } - return priority; -} - - -// static -Vector<String> InspectorCSSAgent::longhandProperties(CSSStyleDeclaration* style, const String& shorthandProperty) -{ - Vector<String> properties; - HashSet<String> foundProperties; - for (unsigned i = 0; i < style->length(); ++i) { - String individualProperty = style->item(i); - if (foundProperties.contains(individualProperty) || style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - - foundProperties.add(individualProperty); - properties.append(individualProperty); - } - return properties; -} - InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element) { NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element); @@ -622,7 +478,8 @@ PassRefPtr<InspectorObject> InspectorCSSAgent::buildObjectForAttributeStyles(Ele Attribute* attribute = attributes->attributeItem(i); if (attribute->style()) { String attributeName = attribute->localName(); - styleAttributes->setObject(attributeName.utf8().data(), buildObjectForStyle(attribute->style(), "")); + RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), attribute->style(), 0); + styleAttributes->setObject(attributeName.utf8().data(), inspectorStyle->buildObjectForStyle()); } } diff --git a/WebCore/inspector/InspectorCSSAgent.h b/WebCore/inspector/InspectorCSSAgent.h index eb6013b..341d09a 100644 --- a/WebCore/inspector/InspectorCSSAgent.h +++ b/WebCore/inspector/InspectorCSSAgent.h @@ -56,7 +56,6 @@ public: return adoptRef(new InspectorCSSAgent(domAgent, frontend)); } - static PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*, const String& fullStyleId, CSSStyleSourceData* = 0); static CSSStyleSheet* parentStyleSheet(StyleBase*); static CSSStyleRule* asCSSStyleRule(StyleBase*); @@ -73,8 +72,8 @@ public: void getAllStyles2(RefPtr<InspectorArray>* styles); void getStyleSheet2(const String& styleSheetId, RefPtr<InspectorValue>* result); void setStyleSheetText2(const String& styleSheetId, const String& text); - void setStyleText2(const String& styleId, const String& text, RefPtr<InspectorValue>* result); - void toggleProperty2(const String& styleId, long propertyOrdinal, bool disabled); + void setPropertyText2(const String& styleId, long propertyIndex, const String& text, bool overwrite, RefPtr<InspectorValue>* result); + void toggleProperty2(const String& styleId, long propertyIndex, bool disable, RefPtr<InspectorValue>* result); void setRuleSelector2(const String& ruleId, const String& selector, RefPtr<InspectorValue>* result); void addRule2(const long contextNodeId, const String& selector, RefPtr<InspectorValue>* result); void getSupportedCSSProperties(RefPtr<InspectorArray>* result); @@ -82,21 +81,17 @@ public: private: typedef HashMap<String, RefPtr<InspectorStyleSheet> > IdToInspectorStyleSheet; typedef HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet> > CSSStyleSheetToInspectorStyleSheet; - typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle> > NodeToInspectorStyleSheet; // for bogus "stylesheets" with inline node styles + typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle> > NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles typedef HashMap<RefPtr<Document>, RefPtr<InspectorStyleSheet> > DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets static Element* inlineStyleElement(CSSStyleDeclaration*); - static void populateObjectWithStyleProperties(CSSStyleDeclaration*, InspectorObject* result, Vector<CSSPropertySourceData>* propertyData); - static String shorthandValue(CSSStyleDeclaration*, const String& shorthandProperty); - static String shorthandPriority(CSSStyleDeclaration*, const String& shorthandProperty); - static Vector<String> longhandProperties(CSSStyleDeclaration*, const String& shorthandProperty); InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element); Element* elementForId(long nodeId); InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*); InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent); - InspectorStyleSheet* styleSheetForId(const String& styleSheetId); + InspectorStyleSheet* styleSheetForId(const String&); String detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument); PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList* ruleList); diff --git a/WebCore/inspector/InspectorCSSStore.cpp b/WebCore/inspector/InspectorCSSStore.cpp index e0b658f..b75f11b 100644 --- a/WebCore/inspector/InspectorCSSStore.cpp +++ b/WebCore/inspector/InspectorCSSStore.cpp @@ -44,6 +44,7 @@ #include "HTMLHeadElement.h" #include "InspectorController.h" #include "InspectorResource.h" +#include "InspectorResourceAgent.h" #include "Node.h" #include "PlatformString.h" #include "SharedBuffer.h" @@ -142,7 +143,7 @@ String InspectorCSSStore::styleSheetText(long styleSheetId) bool InspectorCSSStore::resourceStyleSheetText(CSSStyleSheet* styleSheet, String* result) { - return m_inspectorController->resourceContentForURL(styleSheet->finalURL(), styleSheet->document(), result); + return InspectorResourceAgent::resourceContent(styleSheet->document()->frame(), styleSheet->finalURL(), result); } String InspectorCSSStore::inlineStyleSheetText(CSSStyleSheet* styleSheet) diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp index f99d487..956ef7e 100644 --- a/WebCore/inspector/InspectorController.cpp +++ b/WebCore/inspector/InspectorController.cpp @@ -24,7 +24,7 @@ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -68,7 +68,6 @@ #include "InspectorFrontendClient.h" #include "InspectorInstrumentation.h" #include "InspectorProfilerAgent.h" -#include "InspectorResource.h" #include "InspectorResourceAgent.h" #include "InspectorState.h" #include "InspectorStorageAgent.h" @@ -101,6 +100,11 @@ #include <wtf/ListHashSet.h> #include <wtf/RefCounted.h> #include <wtf/StdLibExtras.h> +#include <wtf/UnusedParam.h> + +#if LEGACY_RESOURCE_TRACKING_ENABLED +#include "InspectorResource.h" +#endif #if ENABLE(DATABASE) #include "Database.h" @@ -123,8 +127,6 @@ static const char* const domNativeBreakpointType = "DOM"; static const char* const eventListenerNativeBreakpointType = "EventListener"; static const char* const xhrNativeBreakpointType = "XHR"; -// FIXME: move last panel setting to the front-end -const char* const InspectorController::LastActivePanel = "lastActivePanel"; const char* const InspectorController::ElementsPanel = "elements"; const char* const InspectorController::ConsolePanel = "console"; const char* const InspectorController::ScriptsPanel = "scripts"; @@ -140,11 +142,10 @@ InspectorController::InspectorController(Page* page, InspectorClient* client) , m_client(client) , m_openingFrontend(false) , m_cssStore(new InspectorCSSStore(this)) + , m_mainResourceIdentifier(0) , m_loadEventTime(-1.0) , m_domContentEventTime(-1.0) , m_expiredConsoleMessageCount(0) - , m_showAfterVisible(LastActivePanel) - , m_sessionSettings(InspectorObject::create()) , m_groupLevel(0) , m_previousMessage(0) , m_settingsLoaded(false) @@ -169,7 +170,9 @@ InspectorController::~InspectorController() ASSERT(!m_inspectedPage); ASSERT(!m_highlightedNode); +#if LEGACY_RESOURCE_TRACKING_ENABLED deleteAllValues(m_frameResources); +#endif releaseFrontendLifetimeAgents(); @@ -226,20 +229,12 @@ bool InspectorController::searchingForNodeInPage() const return m_state->getBoolean(InspectorState::searchingForNode); } +#if LEGACY_RESOURCE_TRACKING_ENABLED bool InspectorController::resourceTrackingEnabled() const { return m_state->getBoolean(InspectorState::resourceTrackingEnabled); } - -void InspectorController::saveApplicationSettings(const String& settings) -{ - m_state->setString(InspectorState::frontendSettings, settings); -} - -void InspectorController::saveSessionSettings(const String& settingsJSON) -{ - m_sessionSettings = InspectorValue::parseJSON(settingsJSON); -} +#endif void InspectorController::getInspectorState(RefPtr<InspectorObject>* state) { @@ -257,13 +252,6 @@ void InspectorController::restoreInspectorStateFromCookie(const String& inspecto startTimelineProfiler(); } -void InspectorController::getSettings(RefPtr<InspectorObject>* settings) -{ - *settings = InspectorObject::create(); - (*settings)->setString("application", m_state->getString(InspectorState::frontendSettings)); - (*settings)->setString("session", m_sessionSettings->toJSONString()); -} - void InspectorController::inspect(Node* node) { if (!enabled()) @@ -275,10 +263,8 @@ void InspectorController::inspect(Node* node) node = node->parentNode(); m_nodeToFocus = node; - if (!m_frontend) { - m_showAfterVisible = ElementsPanel; + if (!m_frontend) return; - } focusNode(); } @@ -414,11 +400,6 @@ void InspectorController::markTimeline(const String& message) timelineAgent()->didMarkTimeline(message); } -void InspectorController::storeLastActivePanel(const String& panelName) -{ - m_state->setString(InspectorState::lastActivePanel, panelName); -} - void InspectorController::mouseDidMoveOverElement(const HitTestResult& result, unsigned) { if (!enabled() || !searchingForNodeInPage()) @@ -500,8 +481,10 @@ void InspectorController::connectFrontend() releaseFrontendLifetimeAgents(); m_frontend = new InspectorFrontend(m_client); m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_frontend.get()); - // FIXME: enable resource agent once front-end is ready. - // m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_frontend.get()); + +#if !LEGACY_RESOURCE_TRACKING_ENABLED + m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_frontend.get()); +#endif #if ENABLE(DATABASE) m_storageAgent = InspectorStorageAgent::create(m_frontend.get()); @@ -556,10 +539,6 @@ void InspectorController::showPanel(const String& panel) m_showAfterVisible = panel; return; } - - if (panel == LastActivePanel) - return; - m_frontend->showPanel(panel); } @@ -576,8 +555,6 @@ void InspectorController::disconnectFrontend() if (!m_frontend) return; - setConsoleMessagesEnabled(false); - m_frontend.clear(); InspectorInstrumentation::frontendDeleted(); @@ -596,8 +573,6 @@ void InspectorController::disconnectFrontend() unbindAllResources(); stopTimelineProfiler(); - m_showAfterVisible = LastActivePanel; - hideHighlight(); #if ENABLE(JAVASCRIPT_DEBUGGER) @@ -611,7 +586,9 @@ void InspectorController::disconnectFrontend() void InspectorController::releaseFrontendLifetimeAgents() { +#if !LEGACY_RESOURCE_TRACKING_ENABLED m_resourceAgent.clear(); +#endif // m_domAgent is RefPtr. Remove DOM listeners first to ensure that there are // no references to the DOM agent from the DOM tree. @@ -636,19 +613,22 @@ void InspectorController::populateScriptObjects() if (!m_frontend) return; - if (m_showAfterVisible == LastActivePanel) - m_showAfterVisible = m_state->getString(InspectorState::lastActivePanel); - - showPanel(m_showAfterVisible); + if (!m_showAfterVisible.isEmpty()) { + showPanel(m_showAfterVisible); + m_showAfterVisible = ""; + } #if ENABLE(JAVASCRIPT_DEBUGGER) if (m_profilerAgent->enabled()) m_frontend->profilerWasEnabled(); #endif +#if LEGACY_RESOURCE_TRACKING_ENABLED ResourcesMap::iterator resourcesEnd = m_resources.end(); for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) it->second->updateScriptObject(m_frontend.get()); +#endif + if (m_domContentEventTime != -1.0) m_frontend->domContentEventFired(m_domContentEventTime); if (m_loadEventTime != -1.0) @@ -711,10 +691,12 @@ void InspectorController::restoreProfiler() void InspectorController::unbindAllResources() { +#if LEGACY_RESOURCE_TRACKING_ENABLED ResourcesMap::iterator resourcesEnd = m_resources.end(); for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) it->second->releaseScriptObject(0); - +#endif + #if ENABLE(DATABASE) DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end(); for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) @@ -729,6 +711,7 @@ void InspectorController::unbindAllResources() m_timelineAgent->reset(); } +#if LEGACY_RESOURCE_TRACKING_ENABLED void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoader* loaderToKeep) { ASSERT_ARG(resourceMap, resourceMap); @@ -747,15 +730,18 @@ void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoad } } } +#endif void InspectorController::didCommitLoad(DocumentLoader* loader) { if (!enabled()) return; +#if !LEGACY_RESOURCE_TRACKING_ENABLED if (m_resourceAgent) m_resourceAgent->didCommitLoad(loader); - +#endif + ASSERT(m_inspectedPage); if (loader->frame() == m_inspectedPage->mainFrame()) { @@ -787,7 +773,6 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) unbindAllResources(); m_cssStore->reset(); - m_sessionSettings = InspectorObject::create(); if (m_frontend) { m_frontend->reset(); m_domAgent->reset(); @@ -803,6 +788,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) #endif if (m_frontend) { +#if LEGACY_RESOURCE_TRACKING_ENABLED if (!loader->frameLoader()->isLoadingFromCachedPage()) { ASSERT(m_mainResource && m_mainResource->isSameLoader(loader)); // We don't add the main resource until its load is committed. This is @@ -816,28 +802,36 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) // identifierForInitialRequest. m_mainResource = 0; } +#endif + m_mainResourceIdentifier = 0; m_frontend->didCommitLoad(); m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); } } +#if LEGACY_RESOURCE_TRACKING_ENABLED for (Frame* frame = loader->frame(); frame; frame = frame->tree()->traverseNext(loader->frame())) if (ResourcesMap* resourceMap = m_frameResources.get(frame)) pruneResources(resourceMap, loader); +#endif } -void InspectorController::frameDetachedFromParent(Frame* frame) +void InspectorController::frameDetachedFromParent(Frame* rootFrame) { if (!enabled()) return; +#if LEGACY_RESOURCE_TRACKING_ENABLED + for (Frame* frame = rootFrame; frame; frame = frame->tree()->traverseNext(rootFrame)) + if (ResourcesMap* resourceMap = m_frameResources.get(frame)) + removeAllResources(resourceMap); +#else if (m_resourceAgent) - m_resourceAgent->frameDetachedFromParent(frame); - - if (ResourcesMap* resourceMap = m_frameResources.get(frame)) - removeAllResources(resourceMap); + m_resourceAgent->frameDetachedFromParent(rootFrame); +#endif } +#if LEGACY_RESOURCE_TRACKING_ENABLED void InspectorController::addResource(InspectorResource* resource) { m_resources.set(resource->identifier(), resource); @@ -893,24 +887,14 @@ InspectorResource* InspectorController::getTrackedResource(unsigned long identif return 0; } - -InspectorResource* InspectorController::resourceForURL(const String& url) -{ - for (InspectorController::ResourcesMap::iterator resIt = m_resources.begin(); resIt != m_resources.end(); ++resIt) { - if (resIt->second->requestURL().string() == url) - return resIt->second.get(); - } - return 0; -} +#endif void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, const CachedResource* cachedResource) { if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource); - +#if LEGACY_RESOURCE_TRACKING_ENABLED // If the resource URL is already known, we don't need to add it again since this is just a cached load. if (m_knownResources.contains(cachedResource->url())) return; @@ -932,6 +916,10 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource); +#endif } void InspectorController::identifierForInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) @@ -941,9 +929,10 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier, ASSERT(m_inspectedPage); bool isMainResource = isMainResourceLoader(loader, request.url()); + if (isMainResource) + m_mainResourceIdentifier = identifier; - if (m_resourceAgent) - m_resourceAgent->identifierForInitialRequest(identifier, request.url(), loader, isMainResource); +#if LEGACY_RESOURCE_TRACKING_ENABLED ensureSettingsLoaded(); if (!isMainResource && !resourceTrackingEnabled()) @@ -960,6 +949,10 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier, if (m_frontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->identifierForInitialRequest(identifier, request.url(), loader); +#endif } void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loader, const KURL& url) @@ -996,23 +989,22 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->willSendRequest(identifier, request, redirectResponse); + request.setReportLoadTiming(true); + // Only enable raw headers if front-end is attached, as otherwise we may lack + // permissions to fetch the headers. + if (m_frontend) + request.setReportRawHeaders(true); + + bool isMainResource = m_mainResourceIdentifier == identifier; - bool isMainResource = (m_mainResource && m_mainResource->identifier() == identifier); if (m_timelineAgent) m_timelineAgent->willSendResourceRequest(identifier, isMainResource, request); +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; - request.setReportLoadTiming(true); - // Only enable raw headers if front-end is attached, as otherwise we may lack - // permissions to fetch the headers. - if (m_frontend) - request.setReportRawHeaders(true); - if (!redirectResponse.isNull()) { // Redirect may have empty URL and we'd like to not crash with invalid HashMap entry. // See http/tests/misc/will-send-request-returns-null-on-redirect.html @@ -1038,6 +1030,10 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ if (resource != m_mainResource && m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->willSendRequest(identifier, request, redirectResponse); +#endif } void InspectorController::markResourceAsCached(unsigned long identifier) @@ -1045,11 +1041,13 @@ void InspectorController::markResourceAsCached(unsigned long identifier) if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->markResourceAsCached(identifier); - +#if LEGACY_RESOURCE_TRACKING_ENABLED if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) resource->markAsCached(); +#else + if (m_resourceAgent) + m_resourceAgent->markResourceAsCached(identifier); +#endif } void InspectorController::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response) @@ -1057,15 +1055,19 @@ void InspectorController::didReceiveResponse(unsigned long identifier, DocumentL if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->didReceiveResponse(identifier, loader, response); - +#if LEGACY_RESOURCE_TRACKING_ENABLED if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) { resource->updateResponse(response); if (resource != m_mainResource && m_frontend) resource->updateScriptObject(m_frontend.get()); } + UNUSED_PARAM(loader); +#else + if (m_resourceAgent) + m_resourceAgent->didReceiveResponse(identifier, loader, response); +#endif + if (response.httpStatusCode() >= 400) { String message = makeString("Failed to load resource: the server responded with a status of ", String::number(response.httpStatusCode()), " (", response.httpStatusText(), ')'); addMessageToConsole(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 0, response.url().string()); @@ -1077,9 +1079,7 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->didReceiveContentLength(identifier, lengthReceived); - +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; @@ -1088,6 +1088,10 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int if (resource != m_mainResource && m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didReceiveContentLength(identifier, lengthReceived); +#endif } void InspectorController::didFinishLoading(unsigned long identifier, double finishTime) @@ -1095,12 +1099,10 @@ void InspectorController::didFinishLoading(unsigned long identifier, double fini if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->didFinishLoading(identifier, finishTime); - if (m_timelineAgent) m_timelineAgent->didFinishLoadingResource(identifier, false, finishTime); +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; @@ -1110,6 +1112,10 @@ void InspectorController::didFinishLoading(unsigned long identifier, double fini // No need to mute this event for main resource since it happens after did commit load. if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didFinishLoading(identifier, finishTime); +#endif } void InspectorController::didFailLoading(unsigned long identifier, const ResourceError& error) @@ -1117,27 +1123,29 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->didFailLoading(identifier, error); - if (m_timelineAgent) m_timelineAgent->didFinishLoadingResource(identifier, true, 0); String message = "Failed to load resource"; - if (!error.localizedDescription().isEmpty()) - message += ": " + error.localizedDescription(); - addMessageToConsole(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 0, error.failingURL()); + if (!error.localizedDescription().isEmpty()) + message += ": " + error.localizedDescription(); + addMessageToConsole(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 0, error.failingURL()); +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; - resource->markFailed(); + resource->markFailed(error.localizedDescription()); resource->endTiming(0); // No need to mute this event for main resource since it happens after did commit load. if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didFailLoading(identifier, error); +#endif } void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber) @@ -1145,12 +1153,10 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::XHR); - if (m_state->getBoolean(InspectorState::monitoringXHR)) addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, "XHR finished loading: \"" + url + "\".", sendLineNumber, sendURL); +#if LEGACY_RESOURCE_TRACKING_ENABLED if (!resourceTrackingEnabled()) return; @@ -1162,6 +1168,10 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::XHR); +#endif } void InspectorController::scriptImported(unsigned long identifier, const String& sourceString) @@ -1169,9 +1179,7 @@ void InspectorController::scriptImported(unsigned long identifier, const String& if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::Script); - +#if LEGACY_RESOURCE_TRACKING_ENABLED if (!resourceTrackingEnabled()) return; @@ -1183,8 +1191,13 @@ void InspectorController::scriptImported(unsigned long identifier, const String& if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::Script); +#endif } +#if LEGACY_RESOURCE_TRACKING_ENABLED void InspectorController::setResourceTrackingEnabled(bool enable) { if (!enabled()) @@ -1193,9 +1206,11 @@ void InspectorController::setResourceTrackingEnabled(bool enable) ASSERT(m_inspectedPage); m_state->setBoolean(InspectorState::resourceTrackingEnabled, enable); } +#endif void InspectorController::setResourceTrackingEnabled(bool enable, bool always, bool* newState) { +#if LEGACY_RESOURCE_TRACKING_ENABLED *newState = enable; if (always) @@ -1209,6 +1224,11 @@ void InspectorController::setResourceTrackingEnabled(bool enable, bool always, b if (enable) reloadPage(); +#else + UNUSED_PARAM(enable); + UNUSED_PARAM(always); + UNUSED_PARAM(newState); +#endif } void InspectorController::ensureSettingsLoaded() @@ -1368,33 +1388,35 @@ void InspectorController::getCookies(RefPtr<InspectorArray>* cookies, WTF::Strin // always return the same true/false value. bool rawCookiesImplemented = false; - ResourcesMap::iterator resourcesEnd = m_resources.end(); - for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) { - Document* document = it->second->frame()->document(); - Vector<Cookie> docCookiesList; - rawCookiesImplemented = getRawCookies(document, it->second->requestURL(), docCookiesList); - - if (!rawCookiesImplemented) { - // FIXME: We need duplication checking for the String representation of cookies. - ExceptionCode ec = 0; - stringCookiesList += document->cookie(ec); - // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here - // because "document" is the document of the main frame of the page. - ASSERT(!ec); - } else { - int cookiesSize = docCookiesList.size(); - for (int i = 0; i < cookiesSize; i++) { - if (!rawCookiesList.contains(docCookiesList[i])) - rawCookiesList.add(docCookiesList[i]); + for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree()->traverseNext(m_inspectedPage->mainFrame())) { + Document* document = frame->document(); + const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources(); + CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); + for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) { + Vector<Cookie> docCookiesList; + rawCookiesImplemented = getRawCookies(document, KURL(ParsedURLString, it->second->url()), docCookiesList); + + if (!rawCookiesImplemented) { + // FIXME: We need duplication checking for the String representation of cookies. + ExceptionCode ec = 0; + stringCookiesList += document->cookie(ec); + // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here + // because "document" is the document of the main frame of the page. + ASSERT(!ec); + } else { + int cookiesSize = docCookiesList.size(); + for (int i = 0; i < cookiesSize; i++) { + if (!rawCookiesList.contains(docCookiesList[i])) + rawCookiesList.add(docCookiesList[i]); + } } } } if (rawCookiesImplemented) *cookies = buildArrayForCookies(rawCookiesList); - else { + else *cookiesString = stringCookiesList; - } } PassRefPtr<InspectorArray> InspectorController::buildArrayForCookies(ListHashSet<Cookie>& cookiesList) @@ -1426,11 +1448,14 @@ PassRefPtr<InspectorObject> InspectorController::buildObjectForCookie(const Cook void InspectorController::deleteCookie(const String& cookieName, const String& domain) { - ResourcesMap::iterator resourcesEnd = m_resources.end(); - for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) { - Document* document = it->second->frame()->document(); - if (document->url().host() == domain) - WebCore::deleteCookie(document, it->second->requestURL(), cookieName); + for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree()->traverseNext(m_inspectedPage->mainFrame())) { + Document* document = frame->document(); + if (document->url().host() != domain) + continue; + const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources(); + CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); + for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) + WebCore::deleteCookie(document, KURL(ParsedURLString, it->second->url()), cookieName); } } @@ -1528,21 +1553,22 @@ void InspectorController::didCreateWebSocket(unsigned long identifier, const KUR return; ASSERT(m_inspectedPage); - if (m_resourceAgent) - m_resourceAgent->didCreateWebSocket(identifier, requestURL); - +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = InspectorResource::createWebSocket(identifier, requestURL, documentURL); addResource(resource.get()); if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didCreateWebSocket(identifier, requestURL); + UNUSED_PARAM(documentURL); +#endif } void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request) { - if (m_resourceAgent) - m_resourceAgent->willSendWebSocketHandshakeRequest(identifier, request); - +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; @@ -1550,13 +1576,15 @@ void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identi resource->updateWebSocketRequest(request); if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->willSendWebSocketHandshakeRequest(identifier, request); +#endif } void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response) { - if (m_resourceAgent) - m_resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response); - +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; @@ -1566,13 +1594,15 @@ void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long ide resource->updateWebSocketResponse(response); if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response); +#endif } void InspectorController::didCloseWebSocket(unsigned long identifier) { - if (m_resourceAgent) - m_resourceAgent->didCloseWebSocket(identifier); - +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = getTrackedResource(identifier); if (!resource) return; @@ -1580,6 +1610,10 @@ void InspectorController::didCloseWebSocket(unsigned long identifier) resource->endTiming(0); if (m_frontend) resource->updateScriptObject(m_frontend.get()); +#else + if (m_resourceAgent) + m_resourceAgent->didCloseWebSocket(identifier); +#endif } #endif // ENABLE(WEB_SOCKETS) @@ -1793,9 +1827,7 @@ void InspectorController::didEvaluateForTestInFrontend(long callId, const String String InspectorController::breakpointsSettingKey() { DEFINE_STATIC_LOCAL(String, keyPrefix, ("breakpoints:")); - if (!m_mainResource) - return ""; - return keyPrefix + InspectorDebuggerAgent::md5Base16(m_mainResource->requestURL()); + return keyPrefix + InspectorDebuggerAgent::md5Base16(m_inspectedPage->mainFrame()->loader()->url().string()); } PassRefPtr<InspectorValue> InspectorController::loadBreakpoints() @@ -2127,55 +2159,18 @@ void InspectorController::setInspectorExtensionAPI(const String& source) void InspectorController::getResourceContent(unsigned long identifier, bool encode, String* content) { +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> resource = m_resources.get(identifier); if (!resource) { *content = String(); return; } *content = encode ? resource->sourceBytes() : resource->sourceString(); -} - -bool InspectorController::resourceContentForURL(const KURL& url, Document* frameDocument, String* result) -{ - if (!frameDocument) - return false; - - String textEncodingName; - RefPtr<SharedBuffer> buffer; - if (equalIgnoringFragmentIdentifier(url, frameDocument->frame()->loader()->documentLoader()->requestURL())) { - textEncodingName = frameDocument->inputEncoding(); - buffer = frameDocument->frame()->loader()->provisionalDocumentLoader()->mainResourceData(); - } else { - const String& urlString = url.string(); - CachedResource* cachedResource = frameDocument->cachedResourceLoader()->cachedResource(urlString); - if (!cachedResource) - cachedResource = cache()->resourceForURL(urlString); - - ASSERT(cachedResource); // FIXME(apavlov): This might be too aggressive. - - bool isUnpurgeable = true; - if (cachedResource->isPurgeable()) { - // If the resource is purgeable then make it unpurgeable to get - // its data. This might fail, in which case we return an - // empty String. - if (!cachedResource->makePurgeable(false)) - isUnpurgeable = false; - } - if (isUnpurgeable) { - textEncodingName = cachedResource->encoding(); - buffer = cachedResource->data(); - } - } - - if (buffer) { - TextEncoding encoding(textEncodingName); - if (!encoding.isValid()) - encoding = WindowsLatin1Encoding(); - *result = encoding.decode(buffer->data(), buffer->size()); - return true; - } - - return false; +#else + UNUSED_PARAM(identifier); + UNUSED_PARAM(encode); + UNUSED_PARAM(content); +#endif } void InspectorController::reloadPage() diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h index 6d4d9e0..80d094f 100644 --- a/WebCore/inspector/InspectorController.h +++ b/WebCore/inspector/InspectorController.h @@ -67,7 +67,6 @@ class InspectorFrontend; class InspectorFrontendClient; class InspectorObject; class InspectorProfilerAgent; -class InspectorResource; class InspectorResourceAgent; class InspectorState; class InspectorStorageAgent; @@ -87,6 +86,12 @@ class SharedBuffer; class Storage; class StorageArea; +#define LEGACY_RESOURCE_TRACKING_ENABLED 1 + +#if LEGACY_RESOURCE_TRACKING_ENABLED +class InspectorResource; +#endif + #if ENABLE(OFFLINE_WEB_APPLICATIONS) class InspectorApplicationCacheAgent; #endif @@ -98,12 +103,13 @@ class WebSocketHandshakeResponse; class InspectorController : public Noncopyable { public: +#if LEGACY_RESOURCE_TRACKING_ENABLED typedef HashMap<unsigned long, RefPtr<InspectorResource> > ResourcesMap; typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap; +#endif typedef HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap; typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap; - static const char* const LastActivePanel; static const char* const ConsolePanel; static const char* const ElementsPanel; static const char* const ProfilesPanel; @@ -124,10 +130,6 @@ public: Page* inspectedPage() const { return m_inspectedPage; } void reloadPage(); - void saveApplicationSettings(const String& settings); - void saveSessionSettings(const String&); - void getSettings(RefPtr<InspectorObject>*); - void restoreInspectorStateFromCookie(const String& inspectorCookie); void inspect(Node*); @@ -173,9 +175,11 @@ public: void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber); void scriptImported(unsigned long identifier, const String& sourceString); - void setResourceTrackingEnabled(bool enabled); void setResourceTrackingEnabled(bool enabled, bool always, bool* newState); +#if LEGACY_RESOURCE_TRACKING_ENABLED + void setResourceTrackingEnabled(bool enabled); bool resourceTrackingEnabled() const; +#endif void ensureSettingsLoaded(); @@ -218,9 +222,10 @@ public: void didCloseWebSocket(unsigned long identifier); #endif +#if LEGACY_RESOURCE_TRACKING_ENABLED const ResourcesMap& resources() const { return m_resources; } - InspectorResource* resourceForURL(const String& url); - bool resourceContentForURL(const KURL& url, Document* loaderDocument, String* result); +#endif + bool hasFrontend() const { return m_frontend; } void drawNodeHighlight(GraphicsContext&) const; @@ -294,7 +299,6 @@ private: void setSearchingForNode(bool enabled, bool* newState); void setMonitoringXHREnabled(bool enabled, bool* newState); - void storeLastActivePanel(const String& panelName); InspectorDOMAgent* domAgent() { return m_domAgent.get(); } void releaseFrontendLifetimeAgents(); @@ -320,13 +324,14 @@ private: void addConsoleMessage(PassOwnPtr<ConsoleMessage>); +#if LEGACY_RESOURCE_TRACKING_ENABLED void addResource(InspectorResource*); void removeResource(InspectorResource*); InspectorResource* getTrackedResource(unsigned long identifier); - void getResourceContent(unsigned long identifier, bool encode, String* content); - void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0); void removeAllResources(ResourcesMap* map) { pruneResources(map); } +#endif + void getResourceContent(unsigned long identifier, bool encode, String* content); bool isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl); @@ -345,7 +350,6 @@ private: bool m_openingFrontend; OwnPtr<InspectorFrontend> m_frontend; RefPtr<InspectorDOMAgent> m_domAgent; - RefPtr<InspectorResourceAgent> m_resourceAgent; RefPtr<InspectorStorageAgent> m_storageAgent; OwnPtr<InspectorCSSStore> m_cssStore; OwnPtr<InspectorTimelineAgent> m_timelineAgent; @@ -354,12 +358,15 @@ private: #if ENABLE(OFFLINE_WEB_APPLICATIONS) OwnPtr<InspectorApplicationCacheAgent> m_applicationCacheAgent; #endif - RefPtr<Node> m_nodeToFocus; +#if LEGACY_RESOURCE_TRACKING_ENABLED RefPtr<InspectorResource> m_mainResource; ResourcesMap m_resources; HashSet<String> m_knownResources; FrameResourcesMap m_frameResources; +#endif + RefPtr<InspectorResourceAgent> m_resourceAgent; + unsigned long m_mainResourceIdentifier; double m_loadEventTime; double m_domContentEventTime; Vector<OwnPtr<ConsoleMessage> > m_consoleMessages; @@ -374,9 +381,6 @@ private: #endif String m_showAfterVisible; RefPtr<Node> m_highlightedNode; -#if ENABLE(INSPECTOR) - RefPtr<InspectorValue> m_sessionSettings; -#endif unsigned m_groupLevel; ConsoleMessage* m_previousMessage; bool m_settingsLoaded; diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp index f5c5f8b..cfb55fc 100644 --- a/WebCore/inspector/InspectorDOMAgent.cpp +++ b/WebCore/inspector/InspectorDOMAgent.cpp @@ -1219,11 +1219,11 @@ void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<Inspector result->setObject("styleAttributes", buildObjectForAttributeStyles(element)); result->setArray("pseudoElements", buildArrayForPseudoElements(element, authorOnly)); - RefPtr<InspectorObject> currentStyle = result; + RefPtr<InspectorArray> inheritedStyles = InspectorArray::create(); Element* parentElement = element->parentElement(); while (parentElement) { RefPtr<InspectorObject> parentStyle = InspectorObject::create(); - currentStyle->setObject("parent", parentStyle); + inheritedStyles->pushObject(parentStyle); if (parentElement->style() && parentElement->style()->length()) parentStyle->setObject("inlineStyle", buildObjectForStyle(parentElement->style(), true)); @@ -1232,8 +1232,8 @@ void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<Inspector parentStyle->setArray("matchedCSSRules", buildArrayForCSSRules(parentElement->ownerDocument(), parentMatchedRules.get())); parentElement = parentElement->parentElement(); - currentStyle = parentStyle; } + result->setArray("inherited", inheritedStyles); *styles = result.release(); } @@ -1396,6 +1396,7 @@ void InspectorDOMAgent::applyStyleText(long styleId, const String& styleText, co // Notify caller that the property was successfully deleted. if (!styleTextLength) { *success = true; + *styleObject = buildObjectForStyle(style, true); return; } @@ -1544,18 +1545,15 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyle(CSSStyleDecla { RefPtr<InspectorObject> result = InspectorObject::create(); if (bind) { - long styleId = cssStore()->bindStyle(style); - result->setNumber("id", styleId); - CSSStyleSheet* parentStyleSheet = InspectorCSSStore::getParentStyleSheet(style); - if (parentStyleSheet) - result->setNumber("parentStyleSheetId", cssStore()->bindStyleSheet(parentStyleSheet)); - - DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(styleId, false); - if (disabledStyle) - result->setArray("disabled", buildArrayForDisabledStyleProperties(disabledStyle)); + result->setNumber("styleId", cssStore()->bindStyle(style)); + CSSStyleSheet* styleSheet = InspectorCSSStore::getParentStyleSheet(style); + if (styleSheet) + result->setNumber("styleSheetId", cssStore()->bindStyleSheet(styleSheet)); } - result->setString("width", style->getPropertyValue("width")); - result->setString("height", style->getPropertyValue("height")); + RefPtr<InspectorObject> properties = InspectorObject::create(); + properties->setString("width", style->getPropertyValue("width")); + properties->setString("height", style->getPropertyValue("height")); + result->setObject("properties", properties); populateObjectWithStyleProperties(style, result.get()); return result.release(); } @@ -1569,44 +1567,55 @@ void InspectorDOMAgent::populateObjectWithStyleProperties(CSSStyleDeclaration* s for (unsigned i = 0; i < style->length(); ++i) { RefPtr<InspectorObject> property = InspectorObject::create(); String name = style->item(i); + String value = style->getPropertyValue(name); + String priority = style->getPropertyPriority(name); property->setString("name", name); - property->setString("priority", style->getPropertyPriority(name)); + property->setString("value", value); + property->setString("priority", priority); + property->setString("text", name + ": " + value + (priority.length() ? " !" + priority : "") + ";"); property->setBoolean("implicit", style->isPropertyImplicit(name)); + property->setBoolean("parsedOk", true); + property->setString("status", "style"); String shorthand = style->getPropertyShorthand(name); - property->setString("shorthand", shorthand); + property->setString("shorthandName", shorthand); if (!shorthand.isEmpty() && !foundShorthands.contains(shorthand)) { foundShorthands.add(shorthand); shorthandValues->setString(shorthand, shorthandValue(style, shorthand)); } - property->setString("value", style->getPropertyValue(name)); properties->pushObject(property.release()); } - result->setArray("properties", properties); + result->setArray("cssProperties", properties); + result->setString("cssText", style->cssText()); result->setObject("shorthandValues", shorthandValues); -} -PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForDisabledStyleProperties(DisabledStyleDeclaration* declaration) -{ - RefPtr<InspectorArray> properties = InspectorArray::create(); - for (DisabledStyleDeclaration::iterator it = declaration->begin(); it != declaration->end(); ++it) { + DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(cssStore()->bindStyle(style), false); + if (!disabledStyle) + return; + + for (DisabledStyleDeclaration::iterator it = disabledStyle->begin(); it != disabledStyle->end(); ++it) { RefPtr<InspectorObject> property = InspectorObject::create(); - property->setString("name", it->first); - property->setString("value", it->second.first); - property->setString("priority", it->second.second); + String name = it->first; + String value = it->second.first; + String priority = it->second.second; + property->setString("name", name); + property->setString("value", value); + property->setString("priority", priority); + property->setString("text", name + ": " + value + (priority.length() ? " !" + priority : "") + ";"); + property->setBoolean("implicit", false); + property->setBoolean("parsedOk", true); + property->setString("status", "disabled"); properties->pushObject(property.release()); } - return properties.release(); } PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyleSheet(Document* ownerDocument, CSSStyleSheet* styleSheet) { RefPtr<InspectorObject> result = InspectorObject::create(); long id = cssStore()->bindStyleSheet(styleSheet); - result->setNumber("id", id); - result->setBoolean("disabled", styleSheet->disabled()); - result->setString("href", styleSheet->href()); + result->setNumber("styleSheetId", id); + result->setString("sourceURL", styleSheet->href()); result->setString("title", styleSheet->title()); - result->setNumber("documentElementId", m_documentNodeToIdMap.get(styleSheet->document())); + result->setBoolean("disabled", styleSheet->disabled()); RefPtr<InspectorArray> cssRules = InspectorArray::create(); PassRefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet, true); if (cssRuleList) { @@ -1616,7 +1625,7 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyleSheet(Document cssRules->pushObject(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); } } - result->setArray("cssRules", cssRules.release()); + result->setArray("rules", cssRules.release()); return result.release(); } @@ -1626,27 +1635,28 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForRule(Document* owne RefPtr<InspectorObject> result = InspectorObject::create(); result->setString("selectorText", rule->selectorText()); - result->setString("cssText", rule->cssText()); result->setNumber("sourceLine", rule->sourceLine()); - result->setString("documentURL", documentURLString(ownerDocument)); - if (parentStyleSheet) { - RefPtr<InspectorObject> parentStyleSheetValue = InspectorObject::create(); - parentStyleSheetValue->setString("href", parentStyleSheet->href()); - parentStyleSheetValue->setNumber("id", cssStore()->bindStyleSheet(parentStyleSheet)); - result->setObject("parentStyleSheet", parentStyleSheetValue.release()); - } - bool isUserAgent = parentStyleSheet && !parentStyleSheet->ownerNode() && parentStyleSheet->href().isEmpty(); - bool isUser = parentStyleSheet && parentStyleSheet->ownerNode() && parentStyleSheet->ownerNode()->nodeName() == "#document"; - result->setBoolean("isUserAgent", isUserAgent); - result->setBoolean("isUser", isUser); - result->setBoolean("isViaInspector", rule->parentStyleSheet() == cssStore()->inspectorStyleSheet(ownerDocument, false)); + + String origin; + bool canBind = true; + if (parentStyleSheet && !parentStyleSheet->ownerNode() && parentStyleSheet->href().isEmpty()) { + origin = "user-agent"; + canBind = false; + } else if (parentStyleSheet && parentStyleSheet->ownerNode() && parentStyleSheet->ownerNode()->nodeName() == "#document") { + origin = "user"; + canBind = false; + } else if (rule->parentStyleSheet() == cssStore()->inspectorStyleSheet(ownerDocument, false)) + origin = "inspector"; + result->setString("origin", origin); + + if (origin.isEmpty()) + result->setString("sourceURL", parentStyleSheet && !parentStyleSheet->href().isEmpty() ? parentStyleSheet->href() : (ownerDocument ? ownerDocument->url().string() : "")); // Bind editable scripts only. - bool bind = !isUserAgent && !isUser; - result->setObject("style", buildObjectForStyle(rule->style(), bind)); + result->setObject("style", buildObjectForStyle(rule->style(), canBind)); - if (bind) - result->setNumber("id", cssStore()->bindRule(rule)); + if (canBind) + result->setNumber("ruleId", cssStore()->bindRule(rule)); return result.release(); } diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h index 03e4d8d..6c5fd4b 100644 --- a/WebCore/inspector/InspectorDOMAgent.h +++ b/WebCore/inspector/InspectorDOMAgent.h @@ -207,7 +207,6 @@ namespace WebCore { PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*, bool bind); void populateObjectWithStyleProperties(CSSStyleDeclaration*, InspectorObject* result); - PassRefPtr<InspectorArray> buildArrayForDisabledStyleProperties(DisabledStyleDeclaration*); PassRefPtr<InspectorObject> buildObjectForRule(Document* ownerDocument, CSSStyleRule*); PassRefPtr<InspectorObject> buildObjectForStyleSheet(Document* ownerDocument, CSSStyleSheet*); Vector<String> longhandProperties(CSSStyleDeclaration*, const String& shorthandProperty); diff --git a/WebCore/inspector/InspectorDOMStorageResource.cpp b/WebCore/inspector/InspectorDOMStorageResource.cpp index c8d76ba..cfd5f9f 100644 --- a/WebCore/inspector/InspectorDOMStorageResource.cpp +++ b/WebCore/inspector/InspectorDOMStorageResource.cpp @@ -100,7 +100,9 @@ void InspectorDOMStorageResource::startReportingChangesToFrontend() void InspectorDOMStorageResource::handleEvent(ScriptExecutionContext*, Event* event) { ASSERT(m_frontend); - ASSERT(eventNames().storageEvent == event->type()); + if (event->type() != eventNames().storageEvent || !event->isStorageEvent()) + return; + StorageEvent* storageEvent = static_cast<StorageEvent*>(event); Storage* storage = storageEvent->storageArea(); ExceptionCode ec = 0; diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp index a7eacf6..ebd03e6 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.cpp +++ b/WebCore/inspector/InspectorDebuggerAgent.cpp @@ -62,6 +62,7 @@ InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorCon , m_frontend(frontend) , m_pausedScriptState(0) , m_breakpointsLoaded(false) + , m_javaScriptPauseScheduled(false) { } @@ -144,6 +145,8 @@ void InspectorDebuggerAgent::getScriptSource(const String& sourceID, String* scr void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data) { + if (m_javaScriptPauseScheduled) + return; m_breakProgramDetails = InspectorObject::create(); m_breakProgramDetails->setNumber("eventType", type); m_breakProgramDetails->setValue("eventData", data); @@ -152,6 +155,8 @@ void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type void InspectorDebuggerAgent::cancelPauseOnNextStatement() { + if (m_javaScriptPauseScheduled) + return; m_breakProgramDetails = 0; ScriptDebugServer::shared().setPauseOnNextStatement(false); } @@ -159,6 +164,7 @@ void InspectorDebuggerAgent::cancelPauseOnNextStatement() void InspectorDebuggerAgent::pause() { schedulePauseOnNextStatement(JavaScriptPauseEventType, InspectorObject::create()); + m_javaScriptPauseScheduled = true; } void InspectorDebuggerAgent::resume() @@ -309,6 +315,7 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState) m_breakProgramDetails->setValue("callFrames", currentCallFrames()); m_frontend->pausedScript(m_breakProgramDetails); + m_javaScriptPauseScheduled = false; } void InspectorDebuggerAgent::didContinue() diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h index 3825042..9501ac8 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.h +++ b/WebCore/inspector/InspectorDebuggerAgent.h @@ -106,6 +106,7 @@ private: bool m_breakpointsLoaded; static InspectorDebuggerAgent* s_debuggerAgentOnBreakpoint; RefPtr<InspectorObject> m_breakProgramDetails; + bool m_javaScriptPauseScheduled; }; } // namespace WebCore diff --git a/WebCore/inspector/InspectorInstrumentation.cpp b/WebCore/inspector/InspectorInstrumentation.cpp index ae89266..94202c1 100644 --- a/WebCore/inspector/InspectorInstrumentation.cpp +++ b/WebCore/inspector/InspectorInstrumentation.cpp @@ -412,6 +412,28 @@ void InspectorInstrumentation::didWriteHTMLImpl(const InspectorInstrumentationCo timelineAgent->didWriteHTML(endLine); } +#if ENABLE(WEB_SOCKETS) +void InspectorInstrumentation::didCreateWebSocketImpl(InspectorController* inspectorController, unsigned long identifier, const KURL& requestURL, const KURL& documentURL) +{ + inspectorController->didCreateWebSocket(identifier, requestURL, documentURL); +} + +void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InspectorController* inspectorController, unsigned long identifier, const WebSocketHandshakeRequest& request) +{ + inspectorController->willSendWebSocketHandshakeRequest(identifier, request); +} + +void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InspectorController* inspectorController, unsigned long identifier, const WebSocketHandshakeResponse& response) +{ + inspectorController->didReceiveWebSocketHandshakeResponse(identifier, response); +} + +void InspectorInstrumentation::didCloseWebSocketImpl(InspectorController* inspectorController, unsigned long identifier) +{ + inspectorController->didCloseWebSocket(identifier); +} +#endif + bool InspectorInstrumentation::hasFrontend(InspectorController* inspectorController) { return inspectorController->hasFrontend(); diff --git a/WebCore/inspector/InspectorInstrumentation.h b/WebCore/inspector/InspectorInstrumentation.h index e728a5e..1b62ecb 100644 --- a/WebCore/inspector/InspectorInstrumentation.h +++ b/WebCore/inspector/InspectorInstrumentation.h @@ -42,11 +42,17 @@ class CharacterData; class Element; class InspectorController; class InspectorTimelineAgent; +class KURL; class Node; class ResourceRequest; class ResourceResponse; class XMLHttpRequest; +#if ENABLE(WEB_SOCKETS) +class WebSocketHandshakeRequest; +class WebSocketHandshakeResponse; +#endif + typedef pair<InspectorController*, int> InspectorInstrumentationCookie; class InspectorInstrumentation { @@ -90,6 +96,13 @@ public: static InspectorInstrumentationCookie willWriteHTML(Document*, unsigned int length, unsigned int startLine); static void didWriteHTML(const InspectorInstrumentationCookie&, unsigned int endLine); +#if ENABLE(WEB_SOCKETS) + static void didCreateWebSocket(ScriptExecutionContext*, unsigned long identifier, const KURL& requestURL, const KURL& documentURL); + static void willSendWebSocketHandshakeRequest(ScriptExecutionContext*, unsigned long identifier, const WebSocketHandshakeRequest&); + static void didReceiveWebSocketHandshakeResponse(ScriptExecutionContext*, unsigned long identifier, const WebSocketHandshakeResponse&); + static void didCloseWebSocket(ScriptExecutionContext*, unsigned long identifier); +#endif + #if ENABLE(INSPECTOR) static void frontendCreated() { s_frontendCounter += 1; } static void frontendDeleted() { s_frontendCounter -= 1; } @@ -140,6 +153,13 @@ private: static InspectorInstrumentationCookie willWriteHTMLImpl(InspectorController*, unsigned int length, unsigned int startLine); static void didWriteHTMLImpl(const InspectorInstrumentationCookie&, unsigned int endLine); +#if ENABLE(WEB_SOCKETS) + static void didCreateWebSocketImpl(InspectorController*, unsigned long identifier, const KURL& requestURL, const KURL& documentURL); + static void willSendWebSocketHandshakeRequestImpl(InspectorController*, unsigned long identifier, const WebSocketHandshakeRequest&); + static void didReceiveWebSocketHandshakeResponseImpl(InspectorController*, unsigned long identifier, const WebSocketHandshakeResponse&); + static void didCloseWebSocketImpl(InspectorController*, unsigned long identifier); +#endif + static InspectorController* inspectorControllerForContext(ScriptExecutionContext*); static InspectorController* inspectorControllerForDocument(Document*); static InspectorController* inspectorControllerForFrame(Frame*); @@ -460,6 +480,39 @@ inline void InspectorInstrumentation::didWriteHTML(const InspectorInstrumentatio #endif } +#if ENABLE(WEB_SOCKETS) +inline void InspectorInstrumentation::didCreateWebSocket(ScriptExecutionContext* context, unsigned long identifier, const KURL& requestURL, const KURL& documentURL) +{ +#if ENABLE(INSPECTOR) + if (InspectorController* inspectorController = inspectorControllerForContext(context)) + didCreateWebSocketImpl(inspectorController, identifier, requestURL, documentURL); +#endif +} + +inline void InspectorInstrumentation::willSendWebSocketHandshakeRequest(ScriptExecutionContext* context, unsigned long identifier, const WebSocketHandshakeRequest& request) +{ +#if ENABLE(INSPECTOR) + if (InspectorController* inspectorController = inspectorControllerForContext(context)) + willSendWebSocketHandshakeRequestImpl(inspectorController, identifier, request); +#endif +} + +inline void InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(ScriptExecutionContext* context, unsigned long identifier, const WebSocketHandshakeResponse& response) +{ +#if ENABLE(INSPECTOR) + if (InspectorController* inspectorController = inspectorControllerForContext(context)) + didReceiveWebSocketHandshakeResponseImpl(inspectorController, identifier, response); +#endif +} + +inline void InspectorInstrumentation::didCloseWebSocket(ScriptExecutionContext* context, unsigned long identifier) +{ +#if ENABLE(INSPECTOR) + if (InspectorController* inspectorController = inspectorControllerForContext(context)) + didCloseWebSocketImpl(inspectorController, identifier); +#endif +} +#endif #if ENABLE(INSPECTOR) inline InspectorController* InspectorInstrumentation::inspectorControllerForContext(ScriptExecutionContext* context) diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp index 05b1bff..9b3f95d 100644 --- a/WebCore/inspector/InspectorResource.cpp +++ b/WebCore/inspector/InspectorResource.cpp @@ -302,6 +302,7 @@ void InspectorResource::updateScriptObject(InspectorFrontend* frontend) if (m_changes.hasChange(CompletionChange)) { jsonObject->setBoolean("failed", m_failed); + jsonObject->setString("localizedFailDescription", m_localizedFailDescription); jsonObject->setBoolean("finished", m_finished); jsonObject->setBoolean("didCompletionChange", true); } @@ -436,9 +437,10 @@ void InspectorResource::endTiming(double actualEndTime) m_changes.set(CompletionChange); } -void InspectorResource::markFailed() +void InspectorResource::markFailed(const String& localizedDescription) { m_failed = true; + m_localizedFailDescription = localizedDescription; m_changes.set(CompletionChange); } diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h index aa6001f..aa4c3b1 100644 --- a/WebCore/inspector/InspectorResource.h +++ b/WebCore/inspector/InspectorResource.h @@ -116,7 +116,7 @@ namespace WebCore { void startTiming(); void endTiming(double actualEndTime); - void markFailed(); + void markFailed(const String& localizedDescription); void addLength(int lengthReceived); private: @@ -175,6 +175,7 @@ namespace WebCore { bool m_cached; bool m_finished; bool m_failed; + String m_localizedFailDescription; int m_length; int m_responseStatusCode; String m_responseStatusText; diff --git a/WebCore/inspector/InspectorResourceAgent.cpp b/WebCore/inspector/InspectorResourceAgent.cpp index f49e1d7..2e965b6 100644 --- a/WebCore/inspector/InspectorResourceAgent.cpp +++ b/WebCore/inspector/InspectorResourceAgent.cpp @@ -199,17 +199,23 @@ static PassRefPtr<InspectorObject> buildObjectForResourceResponse(const Resource return responseObject; } -static PassRefPtr<InspectorObject> buildObjectForMainResource(Frame* frame) +static PassRefPtr<InspectorObject> buildObjectForDocumentLoader(DocumentLoader* loader) +{ + RefPtr<InspectorObject> documentLoaderObject = InspectorObject::create(); + documentLoaderObject->setNumber("frameId", reinterpret_cast<uintptr_t>(loader->frame())); + documentLoaderObject->setNumber("loaderId", reinterpret_cast<uintptr_t>(loader)); + documentLoaderObject->setString("url", loader->requestURL().string()); + return documentLoaderObject; +} + +static PassRefPtr<InspectorObject> buildObjectForFrameResource(Frame* frame) { FrameLoader* frameLoader = frame->loader(); DocumentLoader* loader = frameLoader->documentLoader(); RefPtr<InspectorObject> resourceObject = InspectorObject::create(); resourceObject->setString("url", loader->url().string()); - resourceObject->setString("host", loader->url().host()); - resourceObject->setString("path", loader->url().path()); - resourceObject->setString("lastPathComponent", loader->url().lastPathComponent()); - resourceObject->setString("type", "Document"); + resourceObject->setObject("loader", buildObjectForDocumentLoader(loader)); resourceObject->setObject("request", buildObjectForResourceRequest(loader->request())); resourceObject->setObject("response", buildObjectForResourceResponse(loader->response())); return resourceObject; @@ -236,21 +242,20 @@ static String cachedResourceTypeString(const CachedResource& cachedResource) } } -static PassRefPtr<InspectorObject> buildObjectForCachedResource(const CachedResource& cachedResource) +static PassRefPtr<InspectorObject> buildObjectForCachedResource(DocumentLoader* loader, const CachedResource& cachedResource) { RefPtr<InspectorObject> resourceObject = InspectorObject::create(); resourceObject->setString("url", cachedResource.url()); resourceObject->setString("type", cachedResourceTypeString(cachedResource)); resourceObject->setNumber("encodedSize", cachedResource.encodedSize()); resourceObject->setObject("response", buildObjectForResourceResponse(cachedResource.response())); + resourceObject->setObject("loader", buildObjectForDocumentLoader(loader)); return resourceObject; } -static PassRefPtr<InspectorObject> buildObjectForFrameResources(Frame* frame) +static void populateObjectWithFrameResources(Frame* frame, PassRefPtr<InspectorObject> frameResources) { - RefPtr<InspectorObject> frameResources = InspectorObject::create(); - frameResources->setNumber("frameID", reinterpret_cast<uintptr_t>(frame)); - frameResources->setObject("mainResource", buildObjectForMainResource(frame)); + frameResources->setObject("resource", buildObjectForFrameResource(frame)); RefPtr<InspectorArray> subresources = InspectorArray::create(); frameResources->setArray("subresources", subresources); @@ -258,19 +263,19 @@ static PassRefPtr<InspectorObject> buildObjectForFrameResources(Frame* frame) CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) { CachedResource* cachedResource = it->second.get(); - if (cachedResource) - subresources->pushValue(buildObjectForCachedResource(*cachedResource)); + RefPtr<InspectorObject> cachedResourceObject = buildObjectForCachedResource(frame->loader()->documentLoader(), *cachedResource); + subresources->pushValue(cachedResourceObject); } - return frameResources; } InspectorResourceAgent::~InspectorResourceAgent() { } -void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifier, const KURL& url, DocumentLoader* loader, bool isMainResource) +void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifier, const KURL& url, DocumentLoader* loader) { - m_frontend->identifierForInitialRequest(identifier, url.string(), reinterpret_cast<uintptr_t>(loader->frame()), isMainResource); + RefPtr<InspectorObject> loaderObject = buildObjectForDocumentLoader(loader); + m_frontend->identifierForInitialRequest(identifier, url.string(), loaderObject); } void InspectorResourceAgent::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) @@ -321,8 +326,7 @@ void InspectorResourceAgent::didFailLoading(unsigned long identifier, const Reso void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* loader, const CachedResource* resource) { - Frame* frame = loader->frame(); - m_frontend->didLoadResourceFromMemoryCache(currentTime(), reinterpret_cast<uintptr_t>(frame), buildObjectForCachedResource(*resource)); + m_frontend->didLoadResourceFromMemoryCache(currentTime(), buildObjectForCachedResource(loader, *resource)); } void InspectorResourceAgent::setOverrideContent(unsigned long identifier, const String& sourceString, InspectorResource::Type type) @@ -342,10 +346,28 @@ void InspectorResourceAgent::setOverrideContent(unsigned long identifier, const m_frontend->setOverrideContent(identifier, sourceString, typeString); } +static PassRefPtr<InspectorObject> buildObjectForFrameTree(Frame* frame, bool dumpResources) +{ + RefPtr<InspectorObject> frameObject = InspectorObject::create(); + frameObject->setNumber("parentId", reinterpret_cast<uintptr_t>(frame->tree()->parent())); + frameObject->setNumber("id", reinterpret_cast<uintptr_t>(frame)); + if (dumpResources) + populateObjectWithFrameResources(frame, frameObject); + RefPtr<InspectorArray> childrenArray; + for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { + if (!childrenArray) { + childrenArray = InspectorArray::create(); + frameObject->setArray("children", childrenArray); + } + childrenArray->pushObject(buildObjectForFrameTree(child, dumpResources)); + } + return frameObject; +} + void InspectorResourceAgent::didCommitLoad(DocumentLoader* loader) { - Frame* frame = loader->frame(); - m_frontend->didCommitLoad(reinterpret_cast<uintptr_t>(frame)); + Frame* parentFrame = loader->frame()->tree()->parent(); + m_frontend->didCommitLoadForFrame(reinterpret_cast<uintptr_t>(parentFrame), buildObjectForDocumentLoader(loader)); } void InspectorResourceAgent::frameDetachedFromParent(Frame* frame) @@ -353,7 +375,6 @@ void InspectorResourceAgent::frameDetachedFromParent(Frame* frame) m_frontend->frameDetachedFromParent(reinterpret_cast<uintptr_t>(frame)); } - #if ENABLE(WEB_SOCKETS) // FIXME: More this into the front-end? @@ -404,19 +425,20 @@ void InspectorResourceAgent::didCloseWebSocket(unsigned long identifier) } #endif // ENABLE(WEB_SOCKETS) -void InspectorResourceAgent::cachedResources(RefPtr<InspectorArray>* resources) +void InspectorResourceAgent::cachedResources(RefPtr<InspectorObject>* object) { - for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame())) - (*resources)->pushObject(buildObjectForFrameResources(frame)); + *object = buildObjectForFrameTree(m_page->mainFrame(), true); } -void InspectorResourceAgent::resourceContent(unsigned long frameID, const String& url, String* content) +void InspectorResourceAgent::resourceContent(unsigned long frameId, const String& url, bool base64Encode, String* content) { - RefPtr<InspectorArray> frameResources = InspectorArray::create(); for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame())) { - if (reinterpret_cast<uintptr_t>(frame) != frameID) + if (reinterpret_cast<uintptr_t>(frame) != frameId) continue; - InspectorResourceAgent::resourceContent(frame, KURL(ParsedURLString, url), content); + if (base64Encode) + InspectorResourceAgent::resourceContentBase64(frame, KURL(ParsedURLString, url), content); + else + InspectorResourceAgent::resourceContent(frame, KURL(ParsedURLString, url), content); break; } } diff --git a/WebCore/inspector/InspectorResourceAgent.h b/WebCore/inspector/InspectorResourceAgent.h index f0bead8..1cdd292 100644 --- a/WebCore/inspector/InspectorResourceAgent.h +++ b/WebCore/inspector/InspectorResourceAgent.h @@ -77,7 +77,7 @@ public: ~InspectorResourceAgent(); - void identifierForInitialRequest(unsigned long identifier, const KURL&, DocumentLoader*, bool isMainResource); + void identifierForInitialRequest(unsigned long identifier, const KURL&, DocumentLoader*); void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); void markResourceAsCached(unsigned long identifier); void didReceiveResponse(unsigned long identifier, DocumentLoader* laoder, const ResourceResponse&); @@ -97,8 +97,8 @@ public: #endif // Called from frontend - void cachedResources(RefPtr<InspectorArray>*); - void resourceContent(unsigned long frameID, const String& url, String* content); + void cachedResources(RefPtr<InspectorObject>*); + void resourceContent(unsigned long frameID, const String& url, bool base64Encode, String* content); private: InspectorResourceAgent(Page* page, InspectorFrontend* frontend); diff --git a/WebCore/inspector/InspectorState.cpp b/WebCore/inspector/InspectorState.cpp index 44065c0..e6d3044 100644 --- a/WebCore/inspector/InspectorState.cpp +++ b/WebCore/inspector/InspectorState.cpp @@ -45,9 +45,7 @@ InspectorState::InspectorState(InspectorClient* client) registerBoolean(timelineProfilerEnabled, false, "timelineProfilerEnabled", (const char*)0); registerBoolean(searchingForNode, false, "searchingForNodeEnabled", (const char*)0); registerBoolean(profilerAlwaysEnabled, false, (const char*)0, "profilerEnabled"); - registerString(frontendSettings, "", (const char*)0, "frontendSettings"); registerBoolean(debuggerAlwaysEnabled, false, (const char*)0, "debuggerEnabled"); - registerString(lastActivePanel, InspectorController::LastActivePanel, (const char*)0, "lastActivePanel"); registerBoolean(inspectorStartsAttached, true, (const char*)0, "InspectorStartsAttached"); registerLong(inspectorAttachedHeight, InspectorController::defaultAttachedHeight, (const char*)0, "inspectorAttachedHeight"); registerLong(pauseOnExceptionsState, 0, "pauseOnExceptionsState", (const char*)0); diff --git a/WebCore/inspector/InspectorState.h b/WebCore/inspector/InspectorState.h index 5707600..387f3c7 100644 --- a/WebCore/inspector/InspectorState.h +++ b/WebCore/inspector/InspectorState.h @@ -1,101 +1,100 @@ -/*
- * Copyright (C) 2010 Google 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorState_h
-#define InspectorState_h
-
-#if ENABLE(INSPECTOR)
-
-#include "InspectorValues.h"
-#include "PlatformString.h"
-
-#include <wtf/HashMap.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class InspectorClient;
-
-class InspectorState {
-public:
- enum InspectorPropertyId {
- monitoringXHR = 1,
- resourceTrackingEnabled,
- resourceTrackingAlwaysEnabled,
- timelineProfilerEnabled,
- searchingForNode,
- profilerAlwaysEnabled,
- frontendSettings,
- debuggerAlwaysEnabled,
- lastActivePanel,
- inspectorStartsAttached,
- inspectorAttachedHeight,
- pauseOnExceptionsState,
- consoleMessagesEnabled,
- lastPropertyId
- };
-
- InspectorState(InspectorClient* client);
-
- PassRefPtr<InspectorObject> generateStateObjectForFrontend();
- void restoreFromInspectorCookie(const String& jsonString);
- void loadFromSettings();
- String getFrontendAlias(InspectorPropertyId propertyId);
-
- bool getBoolean(InspectorPropertyId propertyId);
- String getString(InspectorPropertyId propertyId);
- long getLong(InspectorPropertyId propertyId);
-
- void setBoolean(InspectorPropertyId propertyId, bool value) { setValue(propertyId, InspectorBasicValue::create(value), value ? "true" : "false"); }
- void setString(InspectorPropertyId propertyId, const String& value) { setValue(propertyId, InspectorString::create(value), value); }
- void setLong(InspectorPropertyId propertyId, long value) { setValue(propertyId, InspectorBasicValue::create((double)value), String::number(value)); }
-
-private:
- void updateCookie();
- void setValue(InspectorPropertyId propertyId, PassRefPtr<InspectorValue> value, const String& stringValue);
-
- struct Property {
- static Property create(PassRefPtr<InspectorValue> value, const String& frontendAlias, const String& preferenceName);
- String m_frontendAlias;
- String m_preferenceName;
- RefPtr<InspectorValue> m_value;
- };
- typedef HashMap<long, Property> PropertyMap;
- PropertyMap m_properties;
-
- void registerBoolean(InspectorPropertyId propertyId, bool value, const String& frontendAlias, const String& preferenceName);
- void registerString(InspectorPropertyId propertyId, const String& value, const String& frontendAlias, const String& preferenceName);
- void registerLong(InspectorPropertyId propertyId, long value, const String& frontendAlias, const String& preferenceName);
-
- InspectorClient* m_client;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INSPECTOR)
-#endif // !defined(InspectorState_h)
+/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY GOOGLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef InspectorState_h +#define InspectorState_h + +#if ENABLE(INSPECTOR) + +#include "InspectorValues.h" +#include "PlatformString.h" + +#include <wtf/HashMap.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class InspectorClient; + +class InspectorState { +public: + enum InspectorPropertyId { + monitoringXHR = 1, + resourceTrackingEnabled, + resourceTrackingAlwaysEnabled, + timelineProfilerEnabled, + searchingForNode, + profilerAlwaysEnabled, + debuggerAlwaysEnabled, + lastActivePanel, + inspectorStartsAttached, + inspectorAttachedHeight, + pauseOnExceptionsState, + consoleMessagesEnabled, + lastPropertyId + }; + + InspectorState(InspectorClient* client); + + PassRefPtr<InspectorObject> generateStateObjectForFrontend(); + void restoreFromInspectorCookie(const String& jsonString); + void loadFromSettings(); + String getFrontendAlias(InspectorPropertyId propertyId); + + bool getBoolean(InspectorPropertyId propertyId); + String getString(InspectorPropertyId propertyId); + long getLong(InspectorPropertyId propertyId); + + void setBoolean(InspectorPropertyId propertyId, bool value) { setValue(propertyId, InspectorBasicValue::create(value), value ? "true" : "false"); } + void setString(InspectorPropertyId propertyId, const String& value) { setValue(propertyId, InspectorString::create(value), value); } + void setLong(InspectorPropertyId propertyId, long value) { setValue(propertyId, InspectorBasicValue::create((double)value), String::number(value)); } + +private: + void updateCookie(); + void setValue(InspectorPropertyId propertyId, PassRefPtr<InspectorValue> value, const String& stringValue); + + struct Property { + static Property create(PassRefPtr<InspectorValue> value, const String& frontendAlias, const String& preferenceName); + String m_frontendAlias; + String m_preferenceName; + RefPtr<InspectorValue> m_value; + }; + typedef HashMap<long, Property> PropertyMap; + PropertyMap m_properties; + + void registerBoolean(InspectorPropertyId propertyId, bool value, const String& frontendAlias, const String& preferenceName); + void registerString(InspectorPropertyId propertyId, const String& value, const String& frontendAlias, const String& preferenceName); + void registerLong(InspectorPropertyId propertyId, long value, const String& frontendAlias, const String& preferenceName); + + InspectorClient* m_client; +}; + +} // namespace WebCore + +#endif // ENABLE(INSPECTOR) +#endif // !defined(InspectorState_h) diff --git a/WebCore/inspector/InspectorStyleSheet.cpp b/WebCore/inspector/InspectorStyleSheet.cpp index 11cd649..dc2a47a 100644 --- a/WebCore/inspector/InspectorStyleSheet.cpp +++ b/WebCore/inspector/InspectorStyleSheet.cpp @@ -98,6 +98,369 @@ RefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned i namespace WebCore { +PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const +{ + RefPtr<InspectorObject> result = InspectorObject::create(); + if (!m_styleId.isEmpty()) + result->setString("styleId", m_styleId.asString()); + + RefPtr<InspectorObject> propertiesObject = InspectorObject::create(); + propertiesObject->setString("width", m_style->getPropertyValue("width")); + propertiesObject->setString("height", m_style->getPropertyValue("height")); + + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style) : 0; + if (sourceData) { + propertiesObject->setNumber("startOffset", sourceData->styleSourceData->styleBodyRange.start); + propertiesObject->setNumber("endOffset", sourceData->styleSourceData->styleBodyRange.end); + } + result->setObject("properties", propertiesObject); + + populateObjectWithStyleProperties(result.get()); + + return result.release(); +} + +bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, bool overwrite) +{ + ASSERT(m_parentStyleSheet); + if (!m_parentStyleSheet->ensureParsedDataReady()) + return false; + + Vector<InspectorStyleProperty> allProperties; + populateAllProperties(&allProperties); + + unsigned propertyStart = 0; // Need to initialize to make the compiler happy. + long propertyLengthDelta; + + if (overwrite) { + ASSERT(index < allProperties.size()); + InspectorStyleProperty& property = allProperties.at(index); + propertyStart = property.sourceData.range.start; + unsigned propertyEnd = property.sourceData.range.end; + unsigned oldLength = propertyEnd - propertyStart; + unsigned newLength = propertyText.length(); + propertyLengthDelta = newLength - oldLength; + + if (!property.disabled) { + bool success = replacePropertyInStyleText(property, propertyText); + if (!success) + return false; + } else { + property.rawText = propertyText; + if (!propertyText.length()) { + bool success = enableProperty(index, allProperties); + return success; + } + } + } else { + // Insert at index. + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style); + if (!sourceData) + return false; + String text; + bool success = styleText(&text); + if (!success) + return false; + propertyLengthDelta = propertyText.length(); + + bool insertLast = true; + if (index < allProperties.size()) { + InspectorStyleProperty& property = allProperties.at(index); + if (property.hasSource) { + propertyStart = property.sourceData.range.start; + // If inserting before a disabled property, it should be shifted, too. + insertLast = false; + } + } + if (insertLast) + propertyStart = sourceData->styleSourceData->styleBodyRange.end; + + text.insert(propertyText, propertyStart); + m_parentStyleSheet->setStyleText(m_style, text); + } + + // Recompute subsequent disabled property ranges. + shiftDisabledProperties(disabledIndexByOrdinal(index, true, allProperties), propertyLengthDelta); + + return true; +} + +bool InspectorStyle::toggleProperty(unsigned index, bool disable) +{ + ASSERT(m_parentStyleSheet); + if (!m_parentStyleSheet->ensureParsedDataReady()) + return false; // Can toggle only source-based properties. + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style); + if (!sourceData) + return false; // No source data for the style. + + Vector<InspectorStyleProperty> allProperties; + populateAllProperties(&allProperties); + if (index >= allProperties.size()) + return false; // Outside of property range. + + InspectorStyleProperty& property = allProperties.at(index); + if (property.disabled == disable) + return true; // Idempotent operation. + + bool success; + if (!disable) + success = enableProperty(index, allProperties); + else + success = disableProperty(index, allProperties); + + return success; +} + +// static +unsigned InspectorStyle::disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties) +{ + unsigned disabledIndex = 0; + for (unsigned i = 0, size = allProperties.size(); i < size; ++i) { + InspectorStyleProperty& property = allProperties.at(i); + if (property.disabled) { + if (i == ordinal || (canUseSubsequent && i > ordinal)) + return disabledIndex; + ++disabledIndex; + } + } + + return UINT_MAX; +} + +bool InspectorStyle::styleText(String* result) +{ + // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully. + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style); + if (!sourceData) + return false; + + String styleSheetText; + bool success = m_parentStyleSheet->text(&styleSheetText); + if (!success) + return false; + + SourceRange& bodyRange = sourceData->styleSourceData->styleBodyRange; + *result = styleSheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start); + return true; +} + +bool InspectorStyle::disableProperty(unsigned indexToDisable, Vector<InspectorStyleProperty>& allProperties) +{ + // Precondition: |indexToEnable| points to an enabled property. + const InspectorStyleProperty& property = allProperties.at(indexToDisable); + InspectorStyleProperty disabledProperty(property); + disabledProperty.disabled = true; + unsigned propertyStart = property.sourceData.range.start; + // This may have to be negated below. + long propertyLength = property.sourceData.range.end - propertyStart; + disabledProperty.sourceData.range.end = propertyStart; + String oldStyleText; + bool success = styleText(&oldStyleText); + if (!success) + return false; + disabledProperty.rawText = oldStyleText.substring(propertyStart, propertyLength); + success = replacePropertyInStyleText(property, ""); + if (!success) + return false; + + // Add disabled property at correct position. + unsigned insertionIndex = disabledIndexByOrdinal(indexToDisable, true, allProperties); + if (insertionIndex == UINT_MAX) + m_disabledProperties.append(disabledProperty); + else { + m_disabledProperties.insert(insertionIndex, disabledProperty); + shiftDisabledProperties(insertionIndex + 1, -propertyLength); // Property removed from text - shift these back. + } + return true; +} + +bool InspectorStyle::enableProperty(unsigned indexToEnable, Vector<InspectorStyleProperty>& allProperties) +{ + // Precondition: |indexToEnable| points to a disabled property. + unsigned disabledIndex = disabledIndexByOrdinal(indexToEnable, false, allProperties); + if (disabledIndex == UINT_MAX) + return false; + + InspectorStyleProperty disabledProperty = m_disabledProperties.at(disabledIndex); + m_disabledProperties.remove(disabledIndex); + bool success = replacePropertyInStyleText(disabledProperty, disabledProperty.rawText); + if (success) + shiftDisabledProperties(disabledIndex, disabledProperty.rawText.length()); + return success; +} + +bool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* result) const +{ + HashSet<String> foundShorthands; + HashSet<String> sourcePropertyNames; + unsigned disabledIndex = 0; + unsigned disabledLength = m_disabledProperties.size(); + InspectorStyleProperty disabledProperty; + if (disabledIndex < disabledLength) + disabledProperty = m_disabledProperties.at(disabledIndex); + + RefPtr<CSSRuleSourceData> sourceData = (m_parentStyleSheet && m_parentStyleSheet->ensureParsedDataReady()) ? m_parentStyleSheet->ruleSourceDataFor(m_style) : 0; + Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0; + if (sourcePropertyData) { + for (Vector<CSSPropertySourceData>::const_iterator it = sourcePropertyData->begin(); it != sourcePropertyData->end(); ++it) { + while (disabledIndex < disabledLength && disabledProperty.sourceData.range.start <= it->range.start) { + result->append(disabledProperty); + if (++disabledIndex < disabledLength) + disabledProperty = m_disabledProperties.at(disabledIndex); + } + result->append(InspectorStyleProperty(*it, true, false)); + sourcePropertyNames.add(it->name); + } + } + + while (disabledIndex < disabledLength) { + disabledProperty = m_disabledProperties.at(disabledIndex++); + result->append(disabledProperty); + } + + for (int i = 0, size = m_style->length(); i < size; ++i) { + String name = m_style->item(i); + if (sourcePropertyNames.contains(name)) + continue; + + sourcePropertyNames.add(name); + result->append(InspectorStyleProperty(CSSPropertySourceData(name, m_style->getPropertyValue(name), !m_style->getPropertyPriority(name).isEmpty(), true, SourceRange()), false, false)); + } + + return true; +} + +void InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result) const +{ + Vector<InspectorStyleProperty> properties; + populateAllProperties(&properties); + + RefPtr<InspectorArray> propertiesObject = InspectorArray::create(); + RefPtr<InspectorObject> shorthandValues = InspectorObject::create(); + HashMap<String, RefPtr<InspectorObject> > propertyNameToPreviousActiveProperty; + HashSet<String> foundShorthands; + + for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) { + const CSSPropertySourceData& propertyEntry = it->sourceData; + const String& name = propertyEntry.name; + + RefPtr<InspectorObject> property = InspectorObject::create(); + propertiesObject->pushObject(property); + property->setString("status", it->disabled ? "disabled" : "active"); + property->setBoolean("parsedOk", propertyEntry.parsedOk); + if (!it->disabled) { + property->setString("name", name); + property->setString("value", propertyEntry.value); + property->setString("priority", propertyEntry.important ? "important" : ""); + if (it->hasSource) { + property->setBoolean("implicit", false); + property->setNumber("startOffset", propertyEntry.range.start); + property->setNumber("endOffset", propertyEntry.range.end); + + HashMap<String, RefPtr<InspectorObject> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(name); + if (activeIt != propertyNameToPreviousActiveProperty.end()) { + activeIt->second->setString("status", "inactive"); + activeIt->second->setString("shorthandName", ""); + } + propertyNameToPreviousActiveProperty.set(name, property); + } else { + property->setBoolean("implicit", m_style->isPropertyImplicit(name)); + property->setString("status", "style"); + } + } else + property->setString("text", it->rawText); + + if (propertyEntry.parsedOk) { + // Both for style-originated and parsed source properties. + String shorthand = m_style->getPropertyShorthand(name); + property->setString("shorthandName", shorthand); + if (!shorthand.isEmpty() && !foundShorthands.contains(shorthand)) { + foundShorthands.add(shorthand); + shorthandValues->setString(shorthand, shorthandValue(shorthand)); + } + } else + property->setString("shorthandName", ""); + } + + result->setArray("cssProperties", propertiesObject); + result->setObject("shorthandValues", shorthandValues); +} + + +void InspectorStyle::shiftDisabledProperties(unsigned fromIndex, long delta) +{ + for (unsigned i = fromIndex, size = m_disabledProperties.size(); i < size; ++i) { + SourceRange& range = m_disabledProperties.at(i).sourceData.range; + range.start += delta; + range.end += delta; + } +} + +bool InspectorStyle::replacePropertyInStyleText(const InspectorStyleProperty& property, const String& newText) +{ + // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully. + String text; + bool success = styleText(&text); + if (!success) + return false; + const SourceRange& range = property.sourceData.range; + text.replace(range.start, range.end - range.start, newText); + success = m_parentStyleSheet->setStyleText(m_style, text); + return success; +} + +String InspectorStyle::shorthandValue(const String& shorthandProperty) const +{ + String value = m_style->getPropertyValue(shorthandProperty); + if (value.isEmpty()) { + for (unsigned i = 0; i < m_style->length(); ++i) { + String individualProperty = m_style->item(i); + if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty) + continue; + if (m_style->isPropertyImplicit(individualProperty)) + continue; + String individualValue = m_style->getPropertyValue(individualProperty); + if (individualValue == "initial") + continue; + if (value.length()) + value.append(" "); + value.append(individualValue); + } + } + return value; +} + +String InspectorStyle::shorthandPriority(const String& shorthandProperty) const +{ + String priority = m_style->getPropertyPriority(shorthandProperty); + if (priority.isEmpty()) { + for (unsigned i = 0; i < m_style->length(); ++i) { + String individualProperty = m_style->item(i); + if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty) + continue; + priority = m_style->getPropertyPriority(individualProperty); + break; + } + } + return priority; +} + +Vector<String> InspectorStyle::longhandProperties(const String& shorthandProperty) const +{ + Vector<String> properties; + HashSet<String> foundProperties; + for (unsigned i = 0; i < m_style->length(); ++i) { + String individualProperty = m_style->item(i); + if (foundProperties.contains(individualProperty) || m_style->getPropertyShorthand(individualProperty) != shorthandProperty) + continue; + + foundProperties.add(individualProperty); + properties.append(individualProperty); + } + return properties; +} + InspectorStyleSheet::InspectorStyleSheet(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL) : m_id(id) , m_pageStyleSheet(pageStyleSheet) @@ -121,14 +484,15 @@ bool InspectorStyleSheet::setText(const String& text) m_parsedStyleSheet->setText(text); for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i) m_pageStyleSheet->remove(i); + m_inspectorStyles.clear(); m_pageStyleSheet->parseString(text, m_pageStyleSheet->useStrictParsing()); return true; } -bool InspectorStyleSheet::setRuleSelector(const String& ruleId, const String& selector) +bool InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String& selector) { - CSSStyleRule* rule = ruleForId(ruleId); + CSSStyleRule* rule = ruleForId(id); if (!rule) return false; CSSStyleSheet* styleSheet = InspectorCSSAgent::parentStyleSheet(rule); @@ -140,18 +504,16 @@ bool InspectorStyleSheet::setRuleSelector(const String& ruleId, const String& se if (!sourceData) return false; - const String& sheetText = m_parsedStyleSheet->text(); - String newStyleSheetText = sheetText.substring(0, sourceData->selectorListRange.start); - newStyleSheetText += selector; - newStyleSheetText += sheetText.right(sheetText.length() - sourceData->selectorListRange.end); - m_parsedStyleSheet->setText(newStyleSheetText); + String sheetText = m_parsedStyleSheet->text(); + sheetText.replace(sourceData->selectorListRange.start, sourceData->selectorListRange.end - sourceData->selectorListRange.start, selector); + m_parsedStyleSheet->setText(sheetText); return true; } CSSStyleRule* InspectorStyleSheet::addRule(const String& selector) { - String text; - bool success = styleSheetText(&text); + String styleSheetText; + bool success = text(&styleSheetText); if (!success) return 0; @@ -164,23 +526,24 @@ CSSStyleRule* InspectorStyleSheet::addRule(const String& selector) CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(rules->item(rules->length() - 1)); ASSERT(rule); - if (text.length()) - text += "\n"; + if (styleSheetText.length()) + styleSheetText += "\n"; - text += selector; - text += " {}"; - m_parsedStyleSheet->setText(text); + styleSheetText += selector; + styleSheetText += " {}"; + m_parsedStyleSheet->setText(styleSheetText); return rule; } -CSSStyleRule* InspectorStyleSheet::ruleForId(const String& id) const +CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const { if (!m_pageStyleSheet) return 0; + ASSERT(!id.isEmpty()); bool ok; - unsigned index = id.toUInt(&ok); + unsigned index = id.ordinal().toUInt(&ok); if (!ok) return 0; @@ -204,19 +567,20 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyleSheet() return 0; RefPtr<InspectorObject> result = InspectorObject::create(); - result->setString("id", id()); result->setBoolean("disabled", styleSheet->disabled()); - result->setString("href", styleSheet->href()); + result->setString("sourceURL", styleSheet->href()); result->setString("title", styleSheet->title()); RefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet, true); RefPtr<InspectorArray> cssRules = buildArrayForRuleList(cssRuleList.get()); - result->setArray("cssRules", cssRules.release()); + result->setArray("rules", cssRules.release()); String styleSheetText; bool success = text(&styleSheetText); if (success) result->setString("text", styleSheetText); + result->setString("styleSheetId", id()); + return result.release(); } @@ -228,27 +592,13 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForRule(CSSStyleRule RefPtr<InspectorObject> result = InspectorObject::create(); result->setString("selectorText", rule->selectorText()); - result->setString("cssText", rule->cssText()); + result->setString("sourceURL", !styleSheet->href().isEmpty() ? styleSheet->href() : m_documentURL); result->setNumber("sourceLine", rule->sourceLine()); - result->setString("documentURL", m_documentURL); - - RefPtr<InspectorObject> parentStyleSheetValue = InspectorObject::create(); - parentStyleSheetValue->setString("id", id()); - parentStyleSheetValue->setString("href", styleSheet->href()); - result->setObject("parentStyleSheet", parentStyleSheetValue.release()); result->setString("origin", m_origin); - RefPtr<CSSRuleSourceData> sourceData; - if (ensureParsedDataReady()) - sourceData = ruleSourceDataFor(rule->style()); - if (sourceData) { - result->setNumber("selectorStartOffset", sourceData->selectorListRange.start); - result->setNumber("selectorEndOffset", sourceData->selectorListRange.end); - } - result->setObject("style", buildObjectForStyle(rule->style())); if (canBind()) - result->setString("id", fullRuleId(rule)); + result->setString("ruleId", ruleId(rule).asString()); return result.release(); } @@ -259,12 +609,48 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyle(CSSStyleDec if (ensureParsedDataReady()) sourceData = ruleSourceDataFor(style); - RefPtr<InspectorObject> result = InspectorCSSAgent::buildObjectForStyle(style, fullStyleId(style), sourceData ? sourceData->styleSourceData.get() : 0); - result->setString("parentStyleSheetId", id()); + RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(ruleOrStyleId(style)); + RefPtr<InspectorObject> result = inspectorStyle->buildObjectForStyle(); + + // Style text cannot be retrieved without stylesheet, so set cssText here. + if (sourceData) { + String sheetText; + bool success = text(&sheetText); + if (success) { + const SourceRange& bodyRange = sourceData->styleSourceData->styleBodyRange; + result->setString("cssText", sheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start)); + } + } + return result.release(); } -CSSStyleDeclaration* InspectorStyleSheet::styleForId(const String& id) const +bool InspectorStyleSheet::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite) +{ + RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id); + if (!inspectorStyle) + return false; + + return inspectorStyle->setPropertyText(propertyIndex, text, overwrite); +} + +bool InspectorStyleSheet::toggleProperty(const InspectorCSSId& id, unsigned propertyIndex, bool disable) +{ + RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id); + if (!inspectorStyle) + return false; + + bool success = inspectorStyle->toggleProperty(propertyIndex, disable); + if (success) { + if (disable) + rememberInspectorStyle(inspectorStyle); + else if (!inspectorStyle->hasDisabledProperties()) + forgetInspectorStyle(inspectorStyle->cssStyle()); + } + return success; +} + +CSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) const { CSSStyleRule* rule = ruleForId(id); if (!rule) @@ -273,13 +659,36 @@ CSSStyleDeclaration* InspectorStyleSheet::styleForId(const String& id) const return rule->style(); } -bool InspectorStyleSheet::setStyleText(const String& styleId, const String& newText) +PassRefPtr<InspectorStyle> InspectorStyleSheet::inspectorStyleForId(const InspectorCSSId& id) { - CSSStyleDeclaration* style = styleForId(styleId); + CSSStyleDeclaration* style = styleForId(id); if (!style) - return false; + return 0; + + InspectorStyleMap::iterator it = m_inspectorStyles.find(style); + if (it == m_inspectorStyles.end()) { + RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(id, style, this); + return inspectorStyle.release(); + } + return it->second; +} - return innerSetStyleText(style, newText); +void InspectorStyleSheet::rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle) +{ + m_inspectorStyles.set(inspectorStyle->cssStyle(), inspectorStyle); +} + +void InspectorStyleSheet::forgetInspectorStyle(CSSStyleDeclaration* style) +{ + m_inspectorStyles.remove(style); +} + +InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) const +{ + unsigned index = ruleIndexByStyle(style); + if (index != UINT_MAX) + return InspectorCSSId::createFromParts(id(), String::number(index)); + return InspectorCSSId(); } Document* InspectorStyleSheet::ownerDocument() const @@ -328,7 +737,7 @@ bool InspectorStyleSheet::ensureText() const return true; String text; - bool success = styleSheetText(&text); + bool success = originalStyleSheetText(&text); if (success) m_parsedStyleSheet->setText(text); @@ -362,12 +771,7 @@ bool InspectorStyleSheet::ensureSourceData(Node* ownerNode) return m_parsedStyleSheet->hasSourceData(); } -void InspectorStyleSheet::innerSetStyleSheetText(const String& newText) -{ - m_parsedStyleSheet->setText(newText); -} - -bool InspectorStyleSheet::innerSetStyleText(CSSStyleDeclaration* style, const String& text) +bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text) { if (!pageStyleSheet()) return false; @@ -379,14 +783,14 @@ bool InspectorStyleSheet::innerSetStyleText(CSSStyleDeclaration* style, const St if (!success) return false; - String id = ruleOrStyleId(style); + InspectorCSSId id = ruleOrStyleId(style); if (id.isEmpty()) return false; ExceptionCode ec = 0; style->setCssText(text, ec); if (!ec) - innerSetStyleSheetText(patchedStyleSheetText); + m_parsedStyleSheet->setText(patchedStyleSheetText); return !ec; } @@ -407,10 +811,8 @@ bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* st String text = m_parsedStyleSheet->text(); ASSERT(bodyEnd <= text.length()); // bodyEnd is exclusive - String patchedText = text.substring(0, bodyStart); - patchedText += newStyleText; - patchedText += text.substring(bodyEnd, text.length()); - *result = patchedText; + text.replace(bodyStart, bodyEnd - bodyStart, newStyleText); + *result = text; return true; } @@ -426,9 +828,9 @@ CSSStyleRule* InspectorStyleSheet::findPageRuleWithStyle(CSSStyleDeclaration* st return 0; } -String InspectorStyleSheet::fullRuleId(CSSStyleRule* rule) const +InspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const { - return fullRuleOrStyleId(rule->style()); + return ruleOrStyleId(rule->style()); } void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle) @@ -444,15 +846,18 @@ void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle) if (!parsedRule) continue; if (parsedRule->style() == pageStyle) { - if (parsedRule->style()->cssText() != pageStyle->cssText()) - innerSetStyleText(pageStyle, pageStyle->cssText()); + if (parsedRule->style()->cssText() != pageStyle->cssText()) { + // Clear the disabled properties for the invalid style here. + m_inspectorStyles.remove(pageStyle); + setStyleText(pageStyle, pageStyle->cssText()); + } break; } } m_isRevalidating = false; } -bool InspectorStyleSheet::styleSheetText(String* result) const +bool InspectorStyleSheet::originalStyleSheetText(String* result) const { String text; bool success = inlineStyleSheetText(&text); @@ -465,7 +870,7 @@ bool InspectorStyleSheet::styleSheetText(String* result) const bool InspectorStyleSheet::resourceStyleSheetText(String* result) const { - if (!m_pageStyleSheet) + if (!m_pageStyleSheet || !ownerDocument()) return false; return InspectorResourceAgent::resourceContent(ownerDocument()->frame(), m_pageStyleSheet->finalURL(), result); @@ -509,12 +914,12 @@ InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const Strin , m_ruleSourceData(0) { ASSERT(element); + m_inspectorStyle = InspectorStyle::create(InspectorCSSId::createFromParts(id, "0"), inlineStyle(), this); } -bool InspectorStyleSheetForInlineStyle::setStyleText(const String& styleId, const String& text) +bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text) { - ASSERT(styleId == "0"); - UNUSED_PARAM(styleId); + ASSERT_UNUSED(style, style == inlineStyle()); ExceptionCode ec = 0; m_element->setAttribute("style", text, ec); m_ruleSourceData.clear(); @@ -541,6 +946,12 @@ bool InspectorStyleSheetForInlineStyle::ensureParsedDataReady() return true; } +PassRefPtr<InspectorStyle> InspectorStyleSheetForInlineStyle::inspectorStyleForId(const InspectorCSSId& id) +{ + ASSERT_UNUSED(id, id.ordinal() == "0"); + return m_inspectorStyle; +} + CSSStyleDeclaration* InspectorStyleSheetForInlineStyle::inlineStyle() const { return m_element->style(); diff --git a/WebCore/inspector/InspectorStyleSheet.h b/WebCore/inspector/InspectorStyleSheet.h index 38ab777..06c4093 100644 --- a/WebCore/inspector/InspectorStyleSheet.h +++ b/WebCore/inspector/InspectorStyleSheet.h @@ -26,16 +26,14 @@ #define InspectorStyleSheet_h #include "CSSPropertySourceData.h" -#include "Document.h" #include "InspectorValues.h" #include "PlatformString.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> -#include <wtf/UnusedParam.h> +#include <wtf/Vector.h> class ParsedStyleSheet; @@ -43,13 +41,102 @@ namespace WebCore { class CSSRuleList; class CSSStyleDeclaration; +class CSSStyleSheet; +class Document; class Element; +class InspectorStyleSheet; class Node; #if ENABLE(INSPECTOR) +class InspectorCSSId { +public: + static InspectorCSSId createFromParts(const String& styleSheetId, const String& ordinal) { return InspectorCSSId(styleSheetId + ":" + ordinal); } + + InspectorCSSId() { } + explicit InspectorCSSId(const String& id) + { + id.split(':', m_idParts); + ASSERT(m_idParts.size() == 2); + } + + const String& styleSheetId() const { ASSERT(m_idParts.size() == 2); return m_idParts.at(0); } + const String& ordinal() const { ASSERT(m_idParts.size() == 2); return m_idParts.at(1); } + bool isEmpty() const { return m_idParts.isEmpty(); } + String asString() const + { + if (isEmpty()) + return String(); + + return m_idParts.at(0) + ":" + m_idParts.at(1); + } + +private: + Vector<String> m_idParts; +}; + +struct InspectorStyleProperty { + InspectorStyleProperty() + { + } + + InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource, bool disabled) + : sourceData(sourceData) + , hasSource(hasSource) + , disabled(disabled) + { + } + + CSSPropertySourceData sourceData; + bool hasSource; + bool disabled; + String rawText; +}; + +class InspectorStyle : public RefCounted<InspectorStyle> { +public: + static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, CSSStyleDeclaration* style, InspectorStyleSheet* parentStyleSheet) + { + return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet)); + } + + InspectorStyle(const InspectorCSSId& styleId, CSSStyleDeclaration* style, InspectorStyleSheet* parentStyleSheet) + : m_styleId(styleId) + , m_style(style) + , m_parentStyleSheet(parentStyleSheet) + { + ASSERT(style); + } + + CSSStyleDeclaration* cssStyle() const { return m_style; } + PassRefPtr<InspectorObject> buildObjectForStyle() const; + bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); } + bool setPropertyText(unsigned index, const String& text, bool overwrite); + bool toggleProperty(unsigned index, bool disable); + +private: + static unsigned disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties); + + bool styleText(String* result); + bool disableProperty(unsigned indexToDisable, Vector<InspectorStyleProperty>& allProperties); + bool enableProperty(unsigned indexToEnable, Vector<InspectorStyleProperty>& allProperties); + bool populateAllProperties(Vector<InspectorStyleProperty>* result) const; + void populateObjectWithStyleProperties(InspectorObject* result) const; + void shiftDisabledProperties(unsigned fromIndex, long offset); + bool replacePropertyInStyleText(const InspectorStyleProperty& property, const String& newText); + String shorthandValue(const String& shorthandProperty) const; + String shorthandPriority(const String& shorthandProperty) const; + Vector<String> longhandProperties(const String& shorthandProperty) const; + + InspectorCSSId m_styleId; + CSSStyleDeclaration* m_style; + InspectorStyleSheet* m_parentStyleSheet; + Vector<InspectorStyleProperty> m_disabledProperties; +}; + class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> { public: + typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap; static PassRefPtr<InspectorStyleSheet> create(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL) { return adoptRef(new InspectorStyleSheet(id, pageStyleSheet, origin, documentURL)); @@ -61,46 +148,55 @@ public: const String& id() const { return m_id; } CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet; } bool setText(const String&); - bool setRuleSelector(const String& ruleId, const String& selector); + bool setRuleSelector(const InspectorCSSId&, const String& selector); CSSStyleRule* addRule(const String& selector); - CSSStyleRule* ruleForId(const String&) const; + CSSStyleRule* ruleForId(const InspectorCSSId&) const; PassRefPtr<InspectorObject> buildObjectForStyleSheet(); PassRefPtr<InspectorObject> buildObjectForRule(CSSStyleRule*); PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*); - virtual CSSStyleDeclaration* styleForId(const String&) const; - virtual bool setStyleText(const String& styleId, const String& text); + bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite); + bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable); + + virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const; protected: bool canBind() const { return m_origin != "userAgent" && m_origin != "user"; } - String fullRuleOrStyleId(CSSStyleDeclaration* style) const { return id() + ":" + ruleOrStyleId(style); } - String ruleOrStyleId(CSSStyleDeclaration* style) const { unsigned index = ruleIndexByStyle(style); return index == UINT_MAX ? "" : String::number(index); } + InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const; virtual Document* ownerDocument() const; virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const; virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const; virtual bool ensureParsedDataReady(); + virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&); + virtual void rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle); + virtual void forgetInspectorStyle(CSSStyleDeclaration* style); + + // Also accessed by friend class InspectorStyle. + virtual bool setStyleText(CSSStyleDeclaration*, const String&); private: bool text(String* result) const; bool ensureText() const; bool ensureSourceData(Node* ownerNode); - void innerSetStyleSheetText(const String& newText); - bool innerSetStyleText(CSSStyleDeclaration*, const String&); bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result); CSSStyleRule* findPageRuleWithStyle(CSSStyleDeclaration*); - String fullRuleId(CSSStyleRule* rule) const; - String fullStyleId(CSSStyleDeclaration* style) const { return fullRuleOrStyleId(style); } + InspectorCSSId ruleId(CSSStyleRule* rule) const; + InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); } void revalidateStyle(CSSStyleDeclaration*); - bool styleSheetText(String* result) const; + bool originalStyleSheetText(String* result) const; bool resourceStyleSheetText(String* result) const; bool inlineStyleSheetText(String* result) const; PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList*); + String m_id; CSSStyleSheet* m_pageStyleSheet; String m_origin; String m_documentURL; bool m_isRevalidating; ParsedStyleSheet* m_parsedStyleSheet; + InspectorStyleMap m_inspectorStyles; + + friend class InspectorStyle; }; class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet { @@ -111,14 +207,19 @@ public: } InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin); - virtual CSSStyleDeclaration* styleForId(const String& id) const { ASSERT(id == "0"); UNUSED_PARAM(id); return inlineStyle(); } - virtual bool setStyleText(const String& styleId, const String& text); + virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, id.ordinal() == "0"); return inlineStyle(); } protected: virtual Document* ownerDocument() const; - virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT(style == inlineStyle()); UNUSED_PARAM(style); return m_ruleSourceData; } + virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; } virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; } virtual bool ensureParsedDataReady(); + virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&); + virtual void rememberInspectorStyle(RefPtr<InspectorStyle>) { } + virtual void forgetInspectorStyle(CSSStyleDeclaration*) { } + + // Also accessed by friend class InspectorStyle. + virtual bool setStyleText(CSSStyleDeclaration*, const String&); private: CSSStyleDeclaration* inlineStyle() const; @@ -126,6 +227,7 @@ private: Element* m_element; RefPtr<CSSRuleSourceData> m_ruleSourceData; + RefPtr<InspectorStyle> m_inspectorStyle; }; #endif diff --git a/WebCore/inspector/front-end/ApplicationCacheItemsView.js b/WebCore/inspector/front-end/ApplicationCacheItemsView.js index f450938..f5147e3 100644 --- a/WebCore/inspector/front-end/ApplicationCacheItemsView.js +++ b/WebCore/inspector/front-end/ApplicationCacheItemsView.js @@ -64,7 +64,7 @@ WebInspector.ApplicationCacheItemsView = function(treeElement, appcacheDomain) this._appcacheDomain = appcacheDomain; this._emptyMsgElement = document.createElement("div"); - this._emptyMsgElement.className = "storage-table-empty"; + this._emptyMsgElement.className = "storage-empty-view"; this._emptyMsgElement.textContent = WebInspector.UIString("No Application Cache information available."); this.element.appendChild(this._emptyMsgElement); diff --git a/WebCore/inspector/front-end/AuditLauncherView.js b/WebCore/inspector/front-end/AuditLauncherView.js index a922715..d4bbf90 100644 --- a/WebCore/inspector/front-end/AuditLauncherView.js +++ b/WebCore/inspector/front-end/AuditLauncherView.js @@ -269,6 +269,7 @@ WebInspector.AuditLauncherView.prototype = { this._selectAllClicked(this._selectAllCheckboxElement.checked); this.updateResourceTrackingState(); this._updateButton(); + this._updateResourceProgress(); }, _updateResourceProgress: function() diff --git a/WebCore/inspector/front-end/AuditRules.js b/WebCore/inspector/front-end/AuditRules.js index cd9f13e..515ce8e 100644 --- a/WebCore/inspector/front-end/AuditRules.js +++ b/WebCore/inspector/front-end/AuditRules.js @@ -286,8 +286,8 @@ WebInspector.AuditRules.UnusedCssRule.prototype = { var testedSelectors = {}; for (var i = 0; i < styleSheets.length; ++i) { var styleSheet = styleSheets[i]; - for (var curRule = 0; curRule < styleSheet.cssRules.length; ++curRule) { - var rule = styleSheet.cssRules[curRule]; + for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) { + var rule = styleSheet.rules[curRule]; if (rule.selectorText.match(pseudoSelectorRegexp)) continue; selectors.push(rule.selectorText); @@ -307,9 +307,10 @@ WebInspector.AuditRules.UnusedCssRule.prototype = { var stylesheetSize = 0; var unusedStylesheetSize = 0; var unusedRules = []; - for (var curRule = 0; curRule < styleSheet.cssRules.length; ++curRule) { - var rule = styleSheet.cssRules[curRule]; - var textLength = rule.cssText ? rule.cssText.length : 0; + for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) { + var rule = styleSheet.rules[curRule]; + // FIXME: replace this by an exact computation once source ranges are available + var textLength = rule.style.cssText ? rule.style.cssText.length + rule.selectorText.length : 0; stylesheetSize += textLength; if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selectorText]) continue; @@ -322,7 +323,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = { if (!unusedRules.length) continue; - var url = styleSheet.href ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.href) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal); + var url = styleSheet.sourceURL ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal); var pctUnused = Math.round(100 * unusedStylesheetSize / stylesheetSize); if (!summary) summary = result.addChild("", true); @@ -657,7 +658,7 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = { if (completeSrc) src = completeSrc; - const computedStyle = new WebInspector.CSSStyleDeclaration(styles.computedStyle); + const computedStyle = WebInspector.CSSStyleDeclaration.parsePayload(styles.computedStyle); if (computedStyle.getPropertyValue("position") === "absolute") { if (!context.imagesLeft) doneCallback(context); @@ -668,7 +669,7 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = { var heightFound = "height" in styles.styleAttributes; for (var i = styles.matchedCSSRules.length - 1; i >= 0 && !(widthFound && heightFound); --i) { - var style = WebInspector.CSSStyleDeclaration.parseRule(styles.matchedCSSRules[i]).style; + var style = WebInspector.CSSRule.parsePayload(styles.matchedCSSRules[i]).style; if (style.getPropertyValue("width") !== "") widthFound = true; if (style.getPropertyValue("height") !== "") diff --git a/WebCore/inspector/front-end/AuditsPanel.js b/WebCore/inspector/front-end/AuditsPanel.js index f6cbed0..b4eb202 100644 --- a/WebCore/inspector/front-end/AuditsPanel.js +++ b/WebCore/inspector/front-end/AuditsPanel.js @@ -130,8 +130,8 @@ WebInspector.AuditsPanel.prototype = { _executeAudit: function(categories, resultCallback) { var resources = []; - for (var id in WebInspector.resources) - resources.push(WebInspector.resources[id]); + for (var id in WebInspector.networkResources) + resources.push(WebInspector.networkResources[id]); var rulesRemaining = 0; for (var i = 0; i < categories.length; ++i) @@ -205,8 +205,8 @@ WebInspector.AuditsPanel.prototype = { { this._resourceTrackingCallback = callback; - if (!WebInspector.panels.resources.resourceTrackingEnabled) { - InspectorBackend.enableResourceTracking(false); + if (WebInspector.panels.resources && !WebInspector.panels.resources.resourceTrackingEnabled) { + WebInspector.panels.resources.toggleResourceTracking(false); this._updateLauncherViewControls(true); } else InspectorBackend.reloadPage(); @@ -256,7 +256,7 @@ WebInspector.AuditsPanel.prototype = { show: function() { WebInspector.Panel.prototype.show.call(this); - this._updateLauncherViewControls(WebInspector.panels.resources.resourceTrackingEnabled); + this._updateLauncherViewControls(!WebInspector.panels.resources || WebInspector.panels.resources.resourceTrackingEnabled); }, reset: function() diff --git a/WebCore/inspector/front-end/CSSStyleModel.js b/WebCore/inspector/front-end/CSSStyleModel.js index e3e9b4f..702c923 100644 --- a/WebCore/inspector/front-end/CSSStyleModel.js +++ b/WebCore/inspector/front-end/CSSStyleModel.js @@ -32,15 +32,84 @@ WebInspector.CSSStyleModel = function() { } +WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray) +{ + var result = []; + for (var i = 0; i < ruleArray.length; ++i) + result.push(WebInspector.CSSRule.parsePayload(ruleArray[i])); + return result; +} + WebInspector.CSSStyleModel.prototype = { - getStylesAsync: function(nodeId, authOnly, userCallback) + getStylesAsync: function(nodeId, userCallback) { - InspectorBackend.getStyles(nodeId, authOnly, userCallback); + function callback(userCallback, payload) + { + if (!payload) { + if (userCallback) + userCallback(null); + return; + } + + var result = {}; + if ("inlineStyle" in payload) + result.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(payload.inlineStyle); + + result.computedStyle = WebInspector.CSSStyleDeclaration.parsePayload(payload.computedStyle); + result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(payload.matchedCSSRules); + + result.styleAttributes = {}; + for (var name in payload.styleAttributes) + result.styleAttributes[name] = WebInspector.CSSStyleDeclaration.parsePayload(payload.styleAttributes[name]); + + result.pseudoElements = []; + for (var i = 0; i < payload.pseudoElements.length; ++i) { + var entryPayload = payload.pseudoElements[i]; + result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.rules) }); + } + + result.inherited = []; + for (var i = 0; i < payload.inherited.length; ++i) { + var entryPayload = payload.inherited[i]; + var entry = {}; + if ("inlineStyle" in entryPayload) + entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle); + if ("matchedCSSRules" in entryPayload) + entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.matchedCSSRules); + result.inherited.push(entry); + } + + if (userCallback) + userCallback(result); + } + + InspectorBackend.getStyles(nodeId, false, callback.bind(null, userCallback)); }, getComputedStyleAsync: function(nodeId, userCallback) { - InspectorBackend.getComputedStyle(nodeId, userCallback); + function callback(userCallback, stylePayload) + { + if (!stylePayload) + userCallback(null); + else + userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload)); + } + + InspectorBackend.getComputedStyle(nodeId, callback.bind(null, userCallback)); + }, + + getInlineStyleAsync: function(nodeId, userCallback) + { + function callback(userCallback, stylePayload) + { + if (!stylePayload) + userCallback(null); + else + userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload)); + } + + InspectorBackend.getInlineStyle(nodeId, callback.bind(null, userCallback)); }, setRuleSelector: function(ruleId, newContent, nodeId, successCallback, failureCallback) @@ -73,39 +142,8 @@ WebInspector.CSSStyleModel.prototype = { InspectorBackend.addRule(newContent, nodeId, callback); }, - toggleStyleEnabled: function(styleId, propertyName, disabled, userCallback) - { - function callback(newPayload) - { - if (!newPayload) { - userCallback(null); - return; - } - - var newStyle = WebInspector.CSSStyleDeclaration.parseStyle(newPayload); - userCallback(newStyle); - } - - InspectorBackend.toggleStyleEnabled(styleId, propertyName, disabled, callback); - }, - setCSSText: function(styleId, cssText) { InspectorBackend.setStyleText(styleId, cssText); - }, - - applyStyleText: function(styleId, styleText, propertyName, successCallback, failureCallback) - { - function callback(success, newPayload) - { - if (!success) - failureCallback(); - else { - var newStyle = newPayload ? WebInspector.CSSStyleDeclaration.parseStyle(newPayload) : null; - successCallback(newStyle); - } - } - - InspectorBackend.applyStyleText(styleId, styleText, propertyName, callback); } } diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index 8cd5d52..deca21c 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -48,7 +48,7 @@ WebInspector.ConsoleView = function(drawer) this.promptElement.className = "source-code"; this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true); this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + "."); - WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this); + this.prompt.history = WebInspector.applicationSettings.consoleHistory; this.topGroup = new WebInspector.ConsoleGroup(null, 0); this.messagesElement.insertBefore(this.topGroup.element, this.promptElement); @@ -102,11 +102,6 @@ WebInspector.ConsoleView = function(drawer) } WebInspector.ConsoleView.prototype = { - _settingsLoaded: function() - { - this.prompt.history = WebInspector.applicationSettings.consoleHistory; - }, - _updateFilter: function(e) { var isMac = WebInspector.isMac(); @@ -225,11 +220,15 @@ WebInspector.ConsoleView.prototype = { this._incrementErrorWarningCount(msg); // Add message to the resource panel - if (msg.url in WebInspector.resourceURLMap) { - msg.resource = WebInspector.resourceURLMap[msg.url]; - if (WebInspector.panels.resources) - WebInspector.panels.resources.addMessageToResource(msg.resource, msg); - } + if (!Preferences.networkPanelEnabled) { + var resource = WebInspector.resourceForURL(msg.url); + if (resource) { + msg.resource = resource; + if (WebInspector.panels.resources) + WebInspector.panels.resources.addMessageToResource(msg.resource, msg); + } + } else + WebInspector.resourceManager.addConsoleMessage(msg); this.commandSincePreviousMessage = false; this.previousMessage = msg; @@ -303,6 +302,8 @@ WebInspector.ConsoleView.prototype = { { if (WebInspector.panels.resources) WebInspector.panels.resources.clearMessages(); + if (WebInspector.resourceManager) + WebInspector.resourceManager.clearConsoleMessages(); this.messages = []; @@ -678,7 +679,7 @@ WebInspector.ConsoleMessage.prototype = { case WebInspector.ConsoleMessage.MessageType.Trace: case WebInspector.ConsoleMessage.MessageType.UncaughtException: var ol = document.createElement("ol"); - ol.addStyleClass("stack-trace"); + ol.className = "outline-disclosure"; var treeOutline = new TreeOutline(ol); var messageText; if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) diff --git a/WebCore/inspector/front-end/CookieItemsView.js b/WebCore/inspector/front-end/CookieItemsView.js index 88cbe05..b2da875 100644 --- a/WebCore/inspector/front-end/CookieItemsView.js +++ b/WebCore/inspector/front-end/CookieItemsView.js @@ -27,12 +27,141 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.CookieItemsView = function(treeElement, cookieDomain) +WebInspector.CookiesTable = function() { WebInspector.View.call(this); - this.element.addStyleClass("storage-view"); this.element.addStyleClass("table"); +} + +WebInspector.CookiesTable.prototype = { + resize: function() + { + if (!this._dataGrid) + return; + + if (this._autoSizingDone) + this._dataGrid.updateWidths(); + else { + this._autoSizingDone = true; + this._dataGrid.autoSizeColumns(4, 45, 1); + } + }, + + _createDataGrid: function(expandable) + { + var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} }; + columns[0].title = WebInspector.UIString("Name"); + columns[0].sortable = true; + columns[0].disclosure = expandable; + columns[1].title = WebInspector.UIString("Value"); + columns[1].sortable = true; + columns[2].title = WebInspector.UIString("Domain"); + columns[2].sortable = true; + columns[3].title = WebInspector.UIString("Path"); + columns[3].sortable = true; + columns[4].title = WebInspector.UIString("Expires"); + columns[4].sortable = true; + columns[5].title = WebInspector.UIString("Size"); + columns[5].aligned = "right"; + columns[5].sortable = true; + columns[6].title = WebInspector.UIString("HTTP"); + columns[6].aligned = "centered"; + columns[6].sortable = true; + columns[7].title = WebInspector.UIString("Secure"); + columns[7].aligned = "centered"; + columns[7].sortable = true; + + var deleteCallback = this._deleteCookieCallback ? this._deleteCookieCallback.bind(this) : null; + this._dataGrid = new WebInspector.DataGrid(columns, null, deleteCallback); + this._dataGrid.addEventListener("sorting changed", this._populateDataGrid, this); + this.element.appendChild(this._dataGrid.element); + }, + + _populateCookies: function(parentNode, cookies) + { + var selectedCookie = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.cookie : null; + parentNode.removeChildren(); + if (!cookies) + return; + this._sortCookies(cookies); + var totalSize = 0; + for (var i = 0; i < cookies.length; ++i) { + var cookieNode = this._createGridNode(cookies[i]); + parentNode.appendChild(cookieNode); + if (selectedCookie === cookies[i]) + cookieNode.selected = true; + } + }, + + _sortCookies: function(cookies) + { + var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1; + + function localeCompare(field, cookie1, cookie2) + { + return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "") + } + + function numberCompare(field, cookie1, cookie2) + { + return sortDirection * (cookie1[field] - cookie2[field]); + } + + function expiresCompare(cookie1, cookie2) + { + if (cookie1.session !== cookie2.session) + return sortDirection * (cookie1.session ? 1 : -1); + + if (cookie1.session) + return 0; + + return sortDirection * (cookie1.expires - cookie2.expires); + } + + var comparator; + switch (parseInt(this._dataGrid.sortColumnIdentifier)) { + case 0: comparator = localeCompare.bind(this, "name"); break; + case 1: comparator = localeCompare.bind(this, "value"); break; + case 2: comparator = localeCompare.bind(this, "domain"); break; + case 3: comparator = localeCompare.bind(this, "path"); break; + case 4: comparator = expiresCompare; break; + case 5: comparator = numberCompare.bind(this, "size"); break; + case 6: comparator = localeCompare.bind(this, "httpOnly"); break; + case 7: comparator = localeCompare.bind(this, "secure"); break; + default: localeCompare.bind(this, "name"); + } + + cookies.sort(comparator); + }, + + _createGridNode: function(cookie) + { + var data = {}; + data[0] = cookie.name; + data[1] = cookie.value; + data[2] = cookie.domain || ""; + data[3] = cookie.path || ""; + data[4] = cookie.type === WebInspector.Cookie.Type.Request ? "" : + (cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString()); + data[5] = cookie.size; + data[6] = (cookie.httpOnly ? "\u2713" : ""); // Checkmark + data[7] = (cookie.secure ? "\u2713" : ""); // Checkmark + + var node = new WebInspector.DataGridNode(data); + node.cookie = cookie; + node.selectable = true; + return node; + } +}; + +WebInspector.CookiesTable.prototype.__proto__ = WebInspector.View.prototype; + +WebInspector.CookieItemsView = function(treeElement, cookieDomain) +{ + WebInspector.CookiesTable.call(this); + + this.element.addStyleClass("storage-view"); this.deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item"); this.deleteButton.visible = false; @@ -45,7 +174,7 @@ WebInspector.CookieItemsView = function(treeElement, cookieDomain) this._cookieDomain = cookieDomain; this._emptyMsgElement = document.createElement("div"); - this._emptyMsgElement.className = "storage-table-empty"; + this._emptyMsgElement.className = "storage-empty-view"; this._emptyMsgElement.textContent = WebInspector.UIString("This site has no cookies."); this.element.appendChild(this._emptyMsgElement); } @@ -79,7 +208,6 @@ WebInspector.CookieItemsView.prototype = { this._filterCookiesForDomain(allCookies); else this._cookies = allCookies; - if (!this._cookies.length) { // Nothing to show. this._emptyMsgElement.removeStyleClass("hidden"); @@ -120,12 +248,13 @@ WebInspector.CookieItemsView.prototype = { var resourceURLsForDocumentURL = []; this._totalSize = 0; - for (var id in WebInspector.resources) { - var resource = WebInspector.resources[id]; + function populateResourcesForDocuments(resource) + { var url = resource.documentURL.asParsedURL(); if (url && url.host == this._cookieDomain) resourceURLsForDocumentURL.push(resource.url); } + WebInspector.forAllResources(populateResourcesForDocuments.bind(this)); for (var i = 0; i < allCookies.length; ++i) { var pushed = false; @@ -143,101 +272,9 @@ WebInspector.CookieItemsView.prototype = { } }, - _createDataGrid: function() - { - var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} }; - columns[0].title = WebInspector.UIString("Name"); - columns[0].sortable = true; - columns[1].title = WebInspector.UIString("Value"); - columns[1].sortable = true; - columns[2].title = WebInspector.UIString("Domain"); - columns[2].sortable = true; - columns[3].title = WebInspector.UIString("Path"); - columns[3].sortable = true; - columns[4].title = WebInspector.UIString("Expires"); - columns[4].sortable = true; - columns[5].title = WebInspector.UIString("Size"); - columns[5].aligned = "right"; - columns[5].sortable = true; - columns[6].title = WebInspector.UIString("HTTP"); - columns[6].aligned = "centered"; - columns[6].sortable = true; - columns[7].title = WebInspector.UIString("Secure"); - columns[7].aligned = "centered"; - columns[7].sortable = true; - - this._dataGrid = new WebInspector.DataGrid(columns, null, this._deleteCookieCallback.bind(this)); - this._dataGrid.addEventListener("sorting changed", this._populateDataGrid, this); - this.element.appendChild(this._dataGrid.element); - this._dataGrid.updateWidths(); - }, - _populateDataGrid: function() { - var selectedCookie = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.cookie : null; - var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1; - - function localeCompare(field, cookie1, cookie2) - { - return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "") - } - - function numberCompare(field, cookie1, cookie2) - { - return sortDirection * (cookie1[field] - cookie2[field]); - } - - function expiresCompare(cookie1, cookie2) - { - if (cookie1.session !== cookie2.session) - return sortDirection * (cookie1.session ? 1 : -1); - - if (cookie1.session) - return 0; - - return sortDirection * (cookie1.expires - cookie2.expires); - } - - var comparator; - switch (parseInt(this._dataGrid.sortColumnIdentifier)) { - case 0: comparator = localeCompare.bind(this, "name"); break; - case 1: comparator = localeCompare.bind(this, "value"); break; - case 2: comparator = localeCompare.bind(this, "domain"); break; - case 3: comparator = localeCompare.bind(this, "path"); break; - case 4: comparator = expiresCompare; break; - case 5: comparator = numberCompare.bind(this, "size"); break; - case 6: comparator = localeCompare.bind(this, "httpOnly"); break; - case 7: comparator = localeCompare.bind(this, "secure"); break; - default: localeCompare.bind(this, "name"); - } - - this._cookies.sort(comparator); - - this._dataGrid.removeChildren(); - var nodeToSelect; - for (var i = 0; i < this._cookies.length; ++i) { - var data = {}; - var cookie = this._cookies[i]; - data[0] = cookie.name; - data[1] = cookie.value; - data[2] = cookie.domain; - data[3] = cookie.path; - data[4] = (cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString()); - data[5] = Number.bytesToString(cookie.size, WebInspector.UIString); - data[6] = (cookie.httpOnly ? "\u2713" : ""); // Checkmark - data[7] = (cookie.secure ? "\u2713" : ""); // Checkmark - - var node = new WebInspector.DataGridNode(data); - node.cookie = cookie; - node.selectable = true; - this._dataGrid.appendChild(node); - if (cookie === selectedCookie) - nodeToSelect = node; - } - if (nodeToSelect) - nodeToSelect.selected = true; - else - this._dataGrid.children[0].selected = true; + this._populateCookies(this._dataGrid, this._cookies); }, _createSimpleDataGrid: function() @@ -273,12 +310,6 @@ WebInspector.CookieItemsView.prototype = { this._dataGrid.children[0].selected = true; }, - resize: function() - { - if (this._dataGrid) - this._dataGrid.updateWidths(); - }, - _deleteButtonClicked: function(event) { if (!this._dataGrid || !this._dataGrid.selectedNode) @@ -300,4 +331,5 @@ WebInspector.CookieItemsView.prototype = { } } -WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.View.prototype; +WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.CookiesTable.prototype; + diff --git a/WebCore/inspector/front-end/CookieParser.js b/WebCore/inspector/front-end/CookieParser.js index 2be5df7..f96be0b 100755 --- a/WebCore/inspector/front-end/CookieParser.js +++ b/WebCore/inspector/front-end/CookieParser.js @@ -54,7 +54,7 @@ WebInspector.CookieParser.prototype = { if (kv.key.charAt(0) === "$" && this._lastCookie) this._lastCookie.addAttribute(kv.key.slice(1), kv.value); else if (kv.key.toLowerCase() !== "$version" && typeof kv.value === "string") - this._addCookie(kv); + this._addCookie(kv, WebInspector.Cookie.Type.Request); this._advanceAndCheckCookieDelimiter(); } this._flushCookie(); @@ -69,7 +69,7 @@ WebInspector.CookieParser.prototype = { if (this._lastCookie) this._lastCookie.addAttribute(kv.key, kv.value); else - this._addCookie(kv); + this._addCookie(kv, WebInspector.Cookie.Type.Response); if (this._advanceAndCheckCookieDelimiter()) this._flushCookie(); } @@ -128,14 +128,14 @@ WebInspector.CookieParser.prototype = { return match[0].match("\n") !== null; }, - _addCookie: function(keyValue) + _addCookie: function(keyValue, type) { if (this._lastCookie) this._lastCookie.size = keyValue.position - this._lastCookiePosition; - // Mozilla bug 169091: Mozilla, IE and Chrome treat signle token (w/o "=") as + // Mozilla bug 169091: Mozilla, IE and Chrome treat single token (w/o "=") as // specifying a value for a cookie with empty name. - this._lastCookie = keyValue.value ? new WebInspector.Cookie(keyValue.key, keyValue.value) : - new WebInspector.Cookie("", keyValue.key); + this._lastCookie = keyValue.value ? new WebInspector.Cookie(keyValue.key, keyValue.value, type) : + new WebInspector.Cookie("", keyValue.key, type); this._lastCookiePosition = keyValue.position; this._cookies.push(this._lastCookie); } @@ -151,10 +151,11 @@ WebInspector.CookieParser.parseSetCookie = function(header) return (new WebInspector.CookieParser()).parseSetCookie(header); } -WebInspector.Cookie = function(name, value) +WebInspector.Cookie = function(name, value, type) { this.name = name; this.value = value; + this.type = type; this._attributes = {}; } @@ -202,3 +203,8 @@ WebInspector.Cookie.prototype = { this._attributes[key.toLowerCase()] = value; } } + +WebInspector.Cookie.Type = { + Request: 0, + Response: 1 +}; diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js index 5153fb1..470e775 100644 --- a/WebCore/inspector/front-end/DOMAgent.js +++ b/WebCore/inspector/front-end/DOMAgent.js @@ -526,90 +526,78 @@ WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callb WebInspector.CSSStyleDeclaration = function(payload) { - this.id = payload.id; - this.parentStyleSheetId = payload.parentStyleSheetId; - this.width = payload.width; - this.height = payload.height; - this.__disabledProperties = {}; - this.__disabledPropertyValues = {}; - this.__disabledPropertyPriorities = {}; - if (payload.disabled) { - for (var i = 0; i < payload.disabled.length; ++i) { - var property = payload.disabled[i]; - this.__disabledProperties[property.name] = true; - this.__disabledPropertyValues[property.name] = property.value; - this.__disabledPropertyPriorities[property.name] = property.priority; - } - } - + this.id = payload.styleId; + this.properties = payload.properties; this._shorthandValues = payload.shorthandValues; - this._propertyMap = {}; - this._longhandProperties = {}; - this.length = payload.properties.length; - - for (var i = 0; i < this.length; ++i) { - var property = payload.properties[i]; + this._livePropertyMap = {}; // LIVE properties (source-based or style-based) : { name -> CSSProperty } + this._allProperties = []; // ALL properties: [ CSSProperty ] + this._longhandProperties = {}; // shorthandName -> [ CSSProperty ] + this.__disabledProperties = {}; // DISABLED properties: { index -> CSSProperty } + var payloadPropertyCount = payload.cssProperties.length; + + var propertyIndex = 0; + for (var i = 0; i < payloadPropertyCount; ++i) { + var property = new WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]); + this._allProperties.push(property); + if (property.disabled) + this.__disabledProperties[i] = property; + if (!property.active && !property.styleBased) + continue; var name = property.name; - this[i] = name; - this._propertyMap[name] = property; + this[propertyIndex] = name; + this._livePropertyMap[name] = property; // Index longhand properties. - if (property.shorthand) { + if (property.shorthand) { // only for parsed var longhands = this._longhandProperties[property.shorthand]; if (!longhands) { longhands = []; this._longhandProperties[property.shorthand] = longhands; } - longhands.push(name); + longhands.push(property); } + ++propertyIndex; } + this.length = propertyIndex; } -WebInspector.CSSStyleDeclaration.parseStyle = function(payload) +WebInspector.CSSStyleDeclaration.parsePayload = function(payload) { return new WebInspector.CSSStyleDeclaration(payload); } -WebInspector.CSSStyleDeclaration.parseRule = function(payload) -{ - var rule = {}; - rule.id = payload.id; - rule.selectorText = payload.selectorText; - rule.style = new WebInspector.CSSStyleDeclaration(payload.style); - rule.style.parentRule = rule; - rule.isUserAgent = payload.isUserAgent; - rule.isUser = payload.isUser; - rule.isViaInspector = payload.isViaInspector; - rule.sourceLine = payload.sourceLine; - rule.documentURL = payload.documentURL; - if (payload.parentStyleSheet) - rule.parentStyleSheet = { href: payload.parentStyleSheet.href }; - - return rule; -} - WebInspector.CSSStyleDeclaration.prototype = { + get allProperties() + { + return this._allProperties; + }, + + getLiveProperty: function(name) + { + return this._livePropertyMap[name]; + }, + getPropertyValue: function(name) { - var property = this._propertyMap[name]; + var property = this._livePropertyMap[name]; return property ? property.value : ""; }, getPropertyPriority: function(name) { - var property = this._propertyMap[name]; + var property = this._livePropertyMap[name]; return property ? property.priority : ""; }, getPropertyShorthand: function(name) { - var property = this._propertyMap[name]; + var property = this._livePropertyMap[name]; return property ? property.shorthand : ""; }, isPropertyImplicit: function(name) { - var property = this._propertyMap[name]; + var property = this._livePropertyMap[name]; return property ? property.implicit : ""; }, @@ -651,7 +639,8 @@ WebInspector.CSSStyleDeclaration.prototype = { getShorthandValue: function(shorthandProperty) { - return this._shorthandValues[shorthandProperty]; + var property = this.getLiveProperty(shorthandProperty); + return property ? property.value : this._shorthandValues[shorthandProperty]; }, getShorthandPriority: function(shorthandProperty) @@ -662,6 +651,166 @@ WebInspector.CSSStyleDeclaration.prototype = { var longhands = this._longhandProperties[shorthandProperty]; return longhands ? this.getPropertyPriority(longhands[0]) : null; + }, + + appendProperty: function(propertyName, propertyValue, userCallback) + { + function setPropertyCallback(userCallback, success, stylePayload) + { + if (!success) + userCallback(null); + else + userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload)); + } + + // FIXME(apavlov): this should be migrated to the new InspectorCSSAgent API once it is enabled. + InspectorBackend.applyStyleText(this.id, propertyName + ": " + propertyValue + ";", propertyName, setPropertyCallback.bind(this, userCallback)); + }, + + propertyAt: function(index) + { + return (index < this.allProperties.length) ? this.allProperties[index] : null; + } +} + +WebInspector.CSSRule = function(payload) +{ + this.id = payload.ruleId; + this.selectorText = payload.selectorText; + this.sourceLine = payload.sourceLine; + this.sourceURL = payload.sourceURL; + this.origin = payload.origin; + this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style); + this.style.parentRule = this; +} + +WebInspector.CSSRule.parsePayload = function(payload) +{ + return new WebInspector.CSSRule(payload); +} + +WebInspector.CSSRule.prototype = { + get isUserAgent() + { + return this.origin === "user-agent"; + }, + + get isUser() + { + return this.origin === "user"; + }, + + get isViaInspector() + { + return this.origin === "inspector"; + }, + + get isRegular() + { + return this.origin === ""; + } +} + +WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, shorthand, text) +{ + this.ownerStyle = ownerStyle; + this.index = index; + this.name = name; + this.value = value; + this.priority = priority; + this.status = status; + this.parsedOk = parsedOk; + this.implicit = implicit; + this.shorthand = shorthand; + this.text = text; +} + +WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload) +{ + var result = new WebInspector.CSSProperty( + ownerStyle, index, payload.name, payload.value, payload.priority, payload.status, payload.parsedOk, payload.implicit, payload.shorthandName, payload.text); + return result; +} + +WebInspector.CSSProperty.prototype = { + get propertyText() + { + if (this.text !== undefined) + return this.text; + + return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";"; + }, + + get isLive() + { + return this.active || this.styleBased; + }, + + get active() + { + return this.status === "active"; + }, + + get styleBased() + { + return this.status === "style"; + }, + + get inactive() + { + return this.status === "inactive"; + }, + + get disabled() + { + return this.status === "disabled"; + }, + + // Replaces "propertyName: propertyValue [!important];" in the stylesheet by an arbitrary propertyText. + setText: function(propertyText, userCallback) + { + function callback(userCallback, success, stylePayload) + { + if (!userCallback) + return; + if (!success) + userCallback(null); + else { + var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload); + userCallback(style); + } + } + + if (!this.ownerStyle) + throw "No ownerStyle for property"; + InspectorBackend.applyStyleText(this.ownerStyle.id, propertyText, this.name, callback.bind(this, userCallback)); + }, + + setValue: function(newValue, userCallback) + { + var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";" + this.setText(text, userCallback); + }, + + setDisabled: function(disabled, userCallback) + { + if (!this.ownerStyle && userCallback) + userCallback(null); + if (disabled === this.disabled && userCallback) + userCallback(this.ownerStyle); + + function callback(userCallback, stylePayload) + { + if (!userCallback) + return; + if (!stylePayload) + userCallback(null); + else { + var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload); + userCallback(style); + } + } + InspectorBackend.toggleStyleEnabled(this.ownerStyle.id, this.name, disabled, callback.bind(this, userCallback)); } } diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js index 3007497..bc429d9 100644 --- a/WebCore/inspector/front-end/DataGrid.js +++ b/WebCore/inspector/front-end/DataGrid.js @@ -308,7 +308,7 @@ WebInspector.DataGrid.prototype = { return this._dataTableBody; }, - autoSizeColumns: function(minPercent, maxPercent) + autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel) { if (minPercent) minPercent = Math.min(minPercent, Math.floor(100 / this._columnCount)); @@ -317,8 +317,9 @@ WebInspector.DataGrid.prototype = { for (var columnIdentifier in columns) widths[columnIdentifier] = (columns[columnIdentifier].title || "").length; - for (var i = 0; i < this.children.length; ++i) { - var node = this.children[i]; + var children = maxDescentLevel ? this._enumerateChildren(this, [], maxDescentLevel + 1) : this.children; + for (var i = 0; i < children.length; ++i) { + var node = children[i]; for (var columnIdentifier in columns) { var text = node.data[columnIdentifier] || ""; if (text.length > widths[columnIdentifier]) @@ -371,6 +372,17 @@ WebInspector.DataGrid.prototype = { this.updateWidths(); }, + _enumerateChildren: function(rootNode, result, maxLevel) + { + if (!rootNode.root) + result.push(rootNode); + if (!maxLevel) + return; + for (var i = 0; i < rootNode.children.length; ++i) + this._enumerateChildren(rootNode.children[i], result, maxLevel - 1); + return result; + }, + // Updates the widths of the table, including the positions of the column // resizers. // @@ -388,7 +400,8 @@ WebInspector.DataGrid.prototype = { var tableWidth = this._dataTable.offsetWidth; var numColumns = headerTableColumns.length; - if (!this._columnWidthsInitialized) { + // Do not attempt to use offsetes if we're not attached to the document tree yet. + if (!this._columnWidthsInitialized && this.element.offsetWidth) { // Give all the columns initial widths now so that during a resize, // when the two columns that get resized get a percent value for // their widths, all the other columns already have percent values diff --git a/WebCore/inspector/front-end/DatabaseTableView.js b/WebCore/inspector/front-end/DatabaseTableView.js index 5440763..b234b9a 100644 --- a/WebCore/inspector/front-end/DatabaseTableView.js +++ b/WebCore/inspector/front-end/DatabaseTableView.js @@ -61,7 +61,7 @@ WebInspector.DatabaseTableView.prototype = { var dataGrid = WebInspector.panels.storage.dataGridForResult(columnNames, values); if (!dataGrid) { var emptyMsgElement = document.createElement("div"); - emptyMsgElement.className = "storage-table-empty"; + emptyMsgElement.className = "storage-empty-view"; emptyMsgElement.textContent = WebInspector.UIString("The “%s”\ntable is empty.", this.tableName); this.element.appendChild(emptyMsgElement); return; diff --git a/WebCore/inspector/front-end/EventListenersSidebarPane.js b/WebCore/inspector/front-end/EventListenersSidebarPane.js index e2ad259..3354191 100644 --- a/WebCore/inspector/front-end/EventListenersSidebarPane.js +++ b/WebCore/inspector/front-end/EventListenersSidebarPane.js @@ -46,7 +46,11 @@ WebInspector.EventListenersSidebarPane = function() option.label = WebInspector.UIString("Selected Node Only"); this.settingsSelectElement.appendChild(option); - WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this); + var filter = WebInspector.applicationSettings.eventListenersFilter; + if (filter === "all") + this.settingsSelectElement[0].selected = true; + else if (filter === "selected") + this.settingsSelectElement[1].selected = true; this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false); this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false); @@ -54,15 +58,6 @@ WebInspector.EventListenersSidebarPane = function() } WebInspector.EventListenersSidebarPane.prototype = { - _settingsLoaded: function() - { - var filter = WebInspector.applicationSettings.eventListenersFilter; - if (filter === "all") - this.settingsSelectElement[0].selected = true; - if (filter === "selected") - this.settingsSelectElement[1].selected = true; - }, - update: function(node) { var body = this.bodyElement; diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js index 9ab4c0c..5e593f7 100644 --- a/WebCore/inspector/front-end/ExtensionServer.js +++ b/WebCore/inspector/front-end/ExtensionServer.js @@ -240,11 +240,16 @@ WebInspector.ExtensionServer.prototype = { var id = message.id; var resource = null; - resource = WebInspector.resources[id] || WebInspector.resourceForURL(id); + resource = WebInspector.networkResources[id] || WebInspector.resourceForURL(id); if (!resource) return this._status.E_NOTFOUND(typeof id + ": " + id); - WebInspector.panels.resources.showResource(resource, message.line); - WebInspector.showPanel("resources"); + if (Preferences.networkPanelEnabled) { + WebInspector.panels.storage.showResource(resource, message.line); + WebInspector.showPanel("storage"); + } else { + WebInspector.panels.resources.showResource(resource, message.line); + WebInspector.showPanel("resources"); + } }, _dispatchCallback: function(requestId, port, result) @@ -256,14 +261,14 @@ WebInspector.ExtensionServer.prototype = { { function resourceWrapper(id) { - return WebInspector.extensionServer._convertResource(WebInspector.resources[id]); + return WebInspector.extensionServer._convertResource(WebInspector.networkResources[id]); } var response; if (request.id) - response = WebInspector.resources[request.id] ? resourceWrapper(request.id) : this._status.E_NOTFOUND(request.id); + response = WebInspector.networkResources[request.id] ? resourceWrapper(request.id) : this._status.E_NOTFOUND(request.id); else - response = Object.keys(WebInspector.resources).map(resourceWrapper); + response = Object.keys(WebInspector.networkResources).map(resourceWrapper); return response; }, @@ -272,7 +277,7 @@ WebInspector.ExtensionServer.prototype = { var ids; var response = []; - function onContentAvailable(id, encoded, content) + function onContentAvailable(id, content, encoded) { var resourceContent = { id: id, @@ -293,13 +298,12 @@ WebInspector.ExtensionServer.prototype = { for (var i = 0; i < ids.length; ++i) { var id = ids[i]; - var resource = WebInspector.resources[id]; + var resource = WebInspector.networkResources[id]; + if (!resource) response.push(this._status.E_NOTFOUND(id)); - else { - var encode = !WebInspector.Resource.Type.isTextType(resource.type); - WebInspector.getEncodedResourceContent(id, encode, onContentAvailable.bind(this, id, encode)); - } + else + resource.getContent(onContentAvailable.bind(this, id)); } if (response.length === ids.length) this._dispatchCallback(message.requestId, port, response); @@ -446,8 +450,3 @@ WebInspector.addExtensions = function(extensions) } WebInspector.extensionServer = new WebInspector.ExtensionServer(); - -WebInspector.getEncodedResourceContent = function(identifier, encode, callback) -{ - InspectorBackend.getResourceContent(identifier, encode, callback); -} diff --git a/WebCore/inspector/front-end/FontView.js b/WebCore/inspector/front-end/FontView.js index b011204..78a7e70 100644 --- a/WebCore/inspector/front-end/FontView.js +++ b/WebCore/inspector/front-end/FontView.js @@ -69,6 +69,7 @@ WebInspector.FontView.prototype = { resize: function() { this.updateFontPreviewSize(); + WebInspector.ResourceView.prototype.resize.call(this); }, updateFontPreviewSize: function() diff --git a/WebCore/inspector/front-end/HAREntry.js b/WebCore/inspector/front-end/HAREntry.js index 2b8f41b..f3bfb06 100644 --- a/WebCore/inspector/front-end/HAREntry.js +++ b/WebCore/inspector/front-end/HAREntry.js @@ -180,7 +180,7 @@ WebInspector.HAREntry.prototype = { var startTime = timing[start]; return typeof startTime !== "number" || startTime === -1 ? -1 : Math.round(timing[end] - startTime); } -}; +} WebInspector.HAREntry._toMilliseconds = function(time) { @@ -203,7 +203,7 @@ WebInspector.HARLog.prototype = { version: webKitVersion ? webKitVersion[1] : "n/a" }, pages: this._buildPages(), - entries: Object.keys(WebInspector.resources).map(this._convertResource) + entries: Object.keys(WebInspector.networkResources).map(this._convertResource) } }, @@ -221,17 +221,15 @@ WebInspector.HARLog.prototype = { buildMainResourceTimings: function() { - var resourcesPanel = WebInspector.panels.resources; - var startTime = WebInspector.mainResource.startTime; return { - onContentLoad: this._pageEventTime(resourcesPanel.mainResourceDOMContentTime), - onLoad: this._pageEventTime(resourcesPanel.mainResourceLoadTime), + onContentLoad: this._pageEventTime(WebInspector.mainResourceDOMContentTime), + onLoad: this._pageEventTime(WebInspector.mainResourceLoadTime), } }, _convertResource: function(id) { - return (new WebInspector.HAREntry(WebInspector.resources[id])).build(); + return (new WebInspector.HAREntry(WebInspector.networkResources[id])).build(); }, _pageEventTime: function(time) @@ -241,4 +239,4 @@ WebInspector.HARLog.prototype = { return -1; return WebInspector.HAREntry._toMilliseconds(time - startTime); } -}; +} diff --git a/WebCore/inspector/front-end/ImageView.js b/WebCore/inspector/front-end/ImageView.js index 06ca4a4..7cff056 100644 --- a/WebCore/inspector/front-end/ImageView.js +++ b/WebCore/inspector/front-end/ImageView.js @@ -49,10 +49,14 @@ WebInspector.ImageView.prototype = { this.imagePreviewElement = document.createElement("img"); this.imagePreviewElement.addStyleClass("resource-image-view"); - this.imagePreviewElement.setAttribute("src", this.resource.url); - this._container.appendChild(this.imagePreviewElement); + function onResourceContent(element, content) + { + this.imagePreviewElement.setAttribute("src", this.resource.contentURL); + } + this.resource.getContent(onResourceContent.bind(this)); + this._container = document.createElement("div"); this._container.className = "info"; this.contentElement.appendChild(this._container); diff --git a/WebCore/inspector/front-end/Images/frame.png b/WebCore/inspector/front-end/Images/frame.png Binary files differnew file mode 100644 index 0000000..0d1953c --- /dev/null +++ b/WebCore/inspector/front-end/Images/frame.png diff --git a/WebCore/inspector/front-end/Images/networkIcon.png b/WebCore/inspector/front-end/Images/networkIcon.png Binary files differindex 982424d..ba10bba 100644 --- a/WebCore/inspector/front-end/Images/networkIcon.png +++ b/WebCore/inspector/front-end/Images/networkIcon.png diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js index 24b270b..2d60f69 100644 --- a/WebCore/inspector/front-end/InjectedScript.js +++ b/WebCore/inspector/front-end/InjectedScript.js @@ -268,7 +268,7 @@ InjectedScript.prototype = { // We don't want local variables to be shadowed by global ones when evaluating on CallFrame. if (!isEvalOnCallFrame) expression = "with (window) {\n" + expression + "\n} "; - expression = "with (window.console._commandLineAPI) {\n" + expression + "\n}"; + expression = "with (window ? window.console._commandLineAPI : {}) {\n" + expression + "\n}"; var value = evalFunction.call(object, expression); delete inspectedWindow.console._commandLineAPI; diff --git a/WebCore/inspector/front-end/MetricsSidebarPane.js b/WebCore/inspector/front-end/MetricsSidebarPane.js index 18bc240..3784ce8 100644 --- a/WebCore/inspector/front-end/MetricsSidebarPane.js +++ b/WebCore/inspector/front-end/MetricsSidebarPane.js @@ -46,24 +46,24 @@ WebInspector.MetricsSidebarPane.prototype = { } var self = this; - var callback = function(stylePayload) { - if (!stylePayload) + var callback = function(style) { + if (!style) return; - var style = WebInspector.CSSStyleDeclaration.parseStyle(stylePayload); self._update(style); }; - InspectorBackend.getComputedStyle(node.id, callback); + WebInspector.cssModel.getComputedStyleAsync(node.id, callback); - var inlineStyleCallback = function(stylePayload) { - if (!stylePayload) + var inlineStyleCallback = function(style) { + if (!style) return; - self._inlineStyleId = stylePayload.id; + self.inlineStyle = style; }; - InspectorBackend.getInlineStyle(node.id, inlineStyleCallback); + WebInspector.cssModel.getInlineStyleAsync(node.id, inlineStyleCallback); }, _update: function(style) { + // Updating with computed style. var metricsElement = document.createElement("div"); metricsElement.className = "metrics"; @@ -116,23 +116,23 @@ WebInspector.MetricsSidebarPane.prototype = { for (var i = 0; i < boxes.length; ++i) { var name = boxes[i]; - if (name === "margin" && noMarginDisplayType[style.display]) + if (name === "margin" && noMarginDisplayType[style.getPropertyValue("display")]) continue; - if (name === "padding" && noPaddingDisplayType[style.display]) + if (name === "padding" && noPaddingDisplayType[style.getPropertyValue("display")]) continue; - if (name === "position" && noPositionType[style.position]) + if (name === "position" && noPositionType[style.getPropertyValue("position")]) continue; var boxElement = document.createElement("div"); boxElement.className = name; if (name === "content") { - var width = style.width.replace(/px$/, ""); + var width = style.getPropertyValue("width").replace(/px$/, ""); var widthElement = document.createElement("span"); widthElement.textContent = width; widthElement.addEventListener("dblclick", this.startEditing.bind(this, widthElement, "width", "width"), false); - var height = style.height.replace(/px$/, ""); + var height = style.getPropertyValue("height").replace(/px$/, ""); var heightElement = document.createElement("span"); heightElement.textContent = height; heightElement.addEventListener("dblclick", this.startEditing.bind(this, heightElement, "height", "height"), false); @@ -185,7 +185,7 @@ WebInspector.MetricsSidebarPane.prototype = { editingCommitted: function(element, userInput, previousContent, context) { - if (!this._inlineStyleId) { + if (!this.inlineStyle) { // Element has no renderer. return this.editingCancelled(element, context); // nothing changed, so cancel } @@ -203,14 +203,36 @@ WebInspector.MetricsSidebarPane.prototype = { userInput += "px"; var self = this; - var callback = function(success) { - if (!success) + var callback = function(style) { + if (!style) return; + self.inlineStyle = style; self.dispatchEventToListeners("metrics edited"); self.update(); }; - InspectorBackend.setStyleProperty(this._inlineStyleId, context.styleProperty, userInput, callback); + function setEnabledValueCallback(context, style) + { + var property = style.getLiveProperty(context.styleProperty); + if (!property) + style.appendProperty(context.styleProperty, userInput, callback); + else + property.setValue(userInput, callback); + } + + var allProperties = this.inlineStyle.allProperties; + for (var i = 0; i < allProperties.length; ++i) { + var property = allProperties[i]; + if (property.name !== context.styleProperty || property.inactive) + continue; + if (property.disabled) + property.setDisabled(false, setEnabledValueCallback.bind(null, context)); + else + property.setValue(userInput, callback); + return; + } + + this.inlineStyle.appendProperty(context.styleProperty, userInput, callback); } } diff --git a/WebCore/inspector/front-end/NetworkPanel.js b/WebCore/inspector/front-end/NetworkPanel.js index 8eed425..c666e54 100644 --- a/WebCore/inspector/front-end/NetworkPanel.js +++ b/WebCore/inspector/front-end/NetworkPanel.js @@ -36,6 +36,8 @@ WebInspector.NetworkPanel = function() this.sidebarElement.className = "network-sidebar"; this._resources = []; + this._resourcesById = {}; + this._lastIdentifier = 0; this._staleResources = []; this._resourceGridNodes = {}; this._mainResourceLoadTime = -1; @@ -51,9 +53,13 @@ WebInspector.NetworkPanel = function() this._viewsContainerElement = document.createElement("div"); this._viewsContainerElement.id = "network-views"; this._viewsContainerElement.className = "hidden"; - this.element.appendChild(this._viewsContainerElement); + var closeButtonElement = document.createElement("button"); + closeButtonElement.className = "network-close-button"; + closeButtonElement.addEventListener("click", this._toggleGridMode.bind(this), false); + this._viewsContainerElement.appendChild(closeButtonElement); + this._createSortingFunctions(); this._createTable(); this._createTimelineGrid(); @@ -180,7 +186,7 @@ WebInspector.NetworkPanel.prototype = { columns.type.title = WebInspector.UIString("Type"); columns.type.sortable = true; - columns.type.width = "7%"; + columns.type.width = "10%"; columns.size.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Size"), WebInspector.UIString("Transfer")); columns.size.sortable = true; @@ -194,7 +200,7 @@ WebInspector.NetworkPanel.prototype = { columns.timeline.title = ""; columns.timeline.sortable = false; - columns.timeline.width = "40%"; + columns.timeline.width = "37%"; columns.timeline.sort = "ascending"; this._dataGrid = new WebInspector.DataGrid(columns); @@ -251,7 +257,7 @@ WebInspector.NetworkPanel.prototype = { timelineSorting.appendChild(option); var header = this._dataGrid.headerTableHeader("timeline"); - header.firstChild.appendChild(timelineSorting); + header.replaceChild(timelineSorting, header.firstChild); timelineSorting.addEventListener("click", function(event) { event.stopPropagation() }, false); timelineSorting.addEventListener("change", this._sortByTimeline.bind(this), false); @@ -609,15 +615,10 @@ WebInspector.NetworkPanel.prototype = { this._clearButton.addEventListener("click", this._reset.bind(this), false); this._largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "network-larger-resources-status-bar-item"); - WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this); - this._largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false); - }, - - _settingsLoaded: function() - { this._largerResourcesButton.toggled = WebInspector.applicationSettings.resourcesLargeRows; if (!WebInspector.applicationSettings.resourcesLargeRows) this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows); + this._largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false); }, set mainResourceLoadTime(x) @@ -758,6 +759,7 @@ WebInspector.NetworkPanel.prototype = { this._calculator.reset(); this._resources = []; + this._resourcesById = {}; this._staleResources = []; this._resourceGridNodes = {}; @@ -773,9 +775,17 @@ WebInspector.NetworkPanel.prototype = { this._resetSummaryBar(); }, + get resources() + { + return this._resourcesById; + }, + addResource: function(resource) { this._resources.push(resource); + if (!resource.identifier) + resource.identifier = "network:" + this._lastIdentifier++; + this._resourcesById[resource.identifier] = resource; this.refreshResource(resource); }, @@ -787,12 +797,9 @@ WebInspector.NetworkPanel.prototype = { if (!resource || !resource._resourcesView) return; - if (this._resourceViewTypeMatchesResource(resource, resource._resourcesView)) - return; - - var newView = this._createResourceView(resource); - if (newView.__proto__ === resource._resourcesView.__proto__) + if (WebInspector.ResourceManager.resourceViewTypeMatchesResource(resource, resource._resourcesView)) return; + var newView = WebInspector.ResourceManager.createResourceView(resource); var oldView = resource._resourcesView; var oldViewParentNode = oldView.visible ? oldView.element.parentNode : null; @@ -831,7 +838,7 @@ WebInspector.NetworkPanel.prototype = { if (this.visibleResource && this.visibleResource._resourcesView) this.visibleResource._resourcesView.hide(); - var view = this._resourceViewForResource(resource); + var view = WebInspector.ResourceManager.resourceViewForResource(resource); view.headersVisible = true; view.show(this._viewsContainerElement); @@ -861,15 +868,6 @@ WebInspector.NetworkPanel.prototype = { this.updateSidebarWidth(); }, - _resourceViewForResource: function(resource) - { - if (!resource) - return null; - if (!resource._resourcesView) - resource._resourcesView = this._createResourceView(resource); - return resource._resourcesView; - }, - _toggleLargerResources: function() { WebInspector.applicationSettings.resourcesLargeRows = !WebInspector.applicationSettings.resourcesLargeRows; @@ -883,48 +881,15 @@ WebInspector.NetworkPanel.prototype = { this._largerResourcesButton.title = WebInspector.UIString("Use large resource rows."); this._dataGrid.element.addStyleClass("small"); this._timelineGrid.element.addStyleClass("small"); + this._viewsContainerElement.addStyleClass("small"); } else { this._largerResourcesButton.title = WebInspector.UIString("Use small resource rows."); this._dataGrid.element.removeStyleClass("small"); this._timelineGrid.element.removeStyleClass("small"); + this._viewsContainerElement.removeStyleClass("small"); } }, - _createResourceView: function(resource) - { - switch (resource.category) { - case WebInspector.resourceCategories.documents: - case WebInspector.resourceCategories.stylesheets: - case WebInspector.resourceCategories.scripts: - case WebInspector.resourceCategories.xhr: - return new WebInspector.SourceView(resource); - case WebInspector.resourceCategories.images: - return new WebInspector.ImageView(resource); - case WebInspector.resourceCategories.fonts: - return new WebInspector.FontView(resource); - default: - return new WebInspector.ResourceView(resource); - } - }, - - _resourceViewTypeMatchesResource: function(resource, resourceView) - { - switch (resource.category) { - case WebInspector.resourceCategories.documents: - case WebInspector.resourceCategories.stylesheets: - case WebInspector.resourceCategories.scripts: - case WebInspector.resourceCategories.xhr: - return resourceView instanceof WebInspector.SourceView; - case WebInspector.resourceCategories.images: - return resourceView instanceof WebInspector.ImageView; - case WebInspector.resourceCategories.fonts: - return resourceView instanceof WebInspector.FontView; - default: - return resourceView instanceof WebInspector.ResourceView; - } - return false; - }, - _getPopoverAnchor: function(element) { var anchor = element.enclosingNodeOrSelfWithClass("network-graph-bar") || element.enclosingNodeOrSelfWithClass("network-graph-label"); @@ -1060,10 +1025,10 @@ WebInspector.NetworkPanel.prototype = { widths.name = 20; widths.method = 7; widths.status = 8; - widths.type = 7; + widths.type = 10; widths.size = 10; widths.time = 10; - widths.timeline = 40; + widths.timeline = 37; } this._dataGrid.showColumn("timeline"); @@ -1496,7 +1461,15 @@ WebInspector.NetworkDataGridNode.prototype = { if (this._resource.category === WebInspector.resourceCategories.images) { var previewImage = document.createElement("img"); previewImage.className = "image-network-icon-preview"; - previewImage.src = this._resource.url; + + function onResourceContent() + { + previewImage.src = this._resource.contentURL; + } + if (Preferences.useDataURLForResourceImageIcons) + this._resource.getContent(onResourceContent.bind(this)); + else + previewImage.src = this._resource.url; var iconElement = document.createElement("div"); iconElement.className = "icon"; diff --git a/WebCore/inspector/front-end/Panel.js b/WebCore/inspector/front-end/Panel.js index 2a4104f..ec9250c 100644 --- a/WebCore/inspector/front-end/Panel.js +++ b/WebCore/inspector/front-end/Panel.js @@ -34,7 +34,7 @@ WebInspector.Panel = function(name) this.element.addStyleClass(name); this._panelName = name; - WebInspector.applicationSettings.installSetting(this._sidebarWidthSettingName(), this._panelName + "-sidebar-width", undefined); + WebInspector.applicationSettings.installApplicationSetting(this._sidebarWidthSettingName(), undefined); } // Should by in sync with style declarations. diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js index fe2f7d2..1a2ce96 100644 --- a/WebCore/inspector/front-end/Resource.js +++ b/WebCore/inspector/front-end/Resource.js @@ -34,6 +34,7 @@ WebInspector.Resource = function(identifier, url) this._endTime = -1; this._requestMethod = ""; this._category = WebInspector.resourceCategories.other; + this._pendingContentCallbacks = []; } // Keep these in sync with WebCore::InspectorResource::Type @@ -74,11 +75,11 @@ WebInspector.Resource.Type = { case this.Script: return "script"; case this.XHR: - return "XHR"; + return "xhr"; case this.Media: return "media"; case this.WebSocket: - return "WebSocket"; + return "websocket"; case this.Other: default: return "other"; @@ -105,9 +106,16 @@ WebInspector.Resource.prototype = { this.path = parsedURL ? parsedURL.path : ""; this.lastPathComponent = ""; if (parsedURL && parsedURL.path) { - var lastSlashIndex = parsedURL.path.lastIndexOf("/"); + // First cut the query params. + var path = parsedURL.path; + var indexOfQuery = path.indexOf("?"); + if (indexOfQuery !== -1) + path = path.substring(0, indexOfQuery); + + // Then take last path component. + var lastSlashIndex = path.lastIndexOf("/"); if (lastSlashIndex !== -1) - this.lastPathComponent = parsedURL.path.substring(lastSlashIndex + 1); + this.lastPathComponent = path.substring(lastSlashIndex + 1); } this.lastPathComponentLowerCase = this.lastPathComponent.toLowerCase(); }, @@ -247,6 +255,8 @@ WebInspector.Resource.prototype = { if (x) { this._checkWarnings(); this.dispatchEventToListeners("finished"); + if (this._pendingContentCallbacks.length) + this._requestContent(); } }, @@ -267,17 +277,7 @@ WebInspector.Resource.prototype = { set category(x) { - if (this._category === x) - return; - - var oldCategory = this._category; - if (oldCategory) - oldCategory.removeResource(this); - this._category = x; - - if (this._category) - this._category.addResource(this); }, get cached() @@ -530,6 +530,7 @@ WebInspector.Resource.prototype = { set errors(x) { this._errors = x; + this.dispatchEventToListeners("errors-warnings-updated"); }, get warnings() @@ -540,6 +541,14 @@ WebInspector.Resource.prototype = { set warnings(x) { this._warnings = x; + this.dispatchEventToListeners("errors-warnings-updated"); + }, + + clearErrorsAndWarnings: function() + { + this._warnings = 0; + this._errors = 0; + this.dispatchEventToListeners("errors-warnings-updated"); }, _mimeTypeIsConsistentWithType: function() @@ -556,6 +565,9 @@ WebInspector.Resource.prototype = { || this.type === WebInspector.Resource.Type.WebSocket) return true; + if (!this.mimeType) + return true; // Might be not known for cached resources with null responses. + if (this.mimeType in WebInspector.MIMETypes) return this.type in WebInspector.MIMETypes[this.mimeType]; @@ -575,7 +587,7 @@ WebInspector.Resource.prototype = { case WebInspector.Warnings.IncorrectMIMEType.id: if (!this._mimeTypeIsConsistentWithType()) msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other, - WebInspector.ConsoleMessage.MessageType.Log, + WebInspector.ConsoleMessage.MessageType.Log, WebInspector.ConsoleMessage.MessageLevel.Warning, -1, this.url, @@ -591,13 +603,48 @@ WebInspector.Resource.prototype = { WebInspector.console.addMessage(msg); }, - getContents: function(callback) + set content(content) + { + this._content = content; + }, + + getContent: function(callback) + { + if (this._content) { + callback(this._content, this._contentEncoded); + return; + } + this._pendingContentCallbacks.push(callback); + if (this.finished) + this._requestContent(); + }, + + get contentURL() + { + const maxDataUrlSize = 1024 * 1024; + // If resource content is not available or won't fit a data URL, fall back to using original URL. + if (!this._content || this._content.length > maxDataUrlSize) + return this.url; + + return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content; + }, + + _requestContent: function() { - // FIXME: eventually, cached resources will have no identifiers. - if (this.frameID) - InspectorBackend.resourceContent(this.frameID, this.url, callback); - else - InspectorBackend.getResourceContent(this.identifier, false, callback); + if (this._contentRequested) + return; + this._contentRequested = true; + this._contentEncoded = !WebInspector.Resource.Type.isTextType(this.type); + + function onResourceContent(data) + { + this._content = data; + var callbacks = this._pendingContentCallbacks.slice(); + for (var i = 0; i < callbacks.length; ++i) + callbacks[i](this._content, this._contentEncoded); + this._pendingContentCallbacks.length = 0; + } + WebInspector.ResourceManager.getContent(this, this._contentEncoded, onResourceContent.bind(this)); } } diff --git a/WebCore/inspector/front-end/ResourceCategory.js b/WebCore/inspector/front-end/ResourceCategory.js index 7d95a1f..43c7c2b 100644 --- a/WebCore/inspector/front-end/ResourceCategory.js +++ b/WebCore/inspector/front-end/ResourceCategory.js @@ -31,40 +31,11 @@ WebInspector.ResourceCategory = function(name, title, color) this.name = name; this.title = title; this.color = color; - this.resources = []; } WebInspector.ResourceCategory.prototype = { - toString: function() { return this.title; - }, - - addResource: function(resource) - { - var a = resource; - var resourcesLength = this.resources.length; - for (var i = 0; i < resourcesLength; ++i) { - var b = this.resources[i]; - if (a.lastPathComponentLowerCase && b.lastPathComponentLowerCase) - if (a.lastPathComponentLowerCase < b.lastPathComponentLowerCase) - break; - else if (a.name && b.name) - if (a.name < b.name) - break; - } - - this.resources.splice(i, 0, resource); - }, - - removeResource: function(resource) - { - this.resources.remove(resource, true); - }, - - removeAllResources: function(resource) - { - this.resources = []; } } diff --git a/WebCore/inspector/front-end/ResourceManager.js b/WebCore/inspector/front-end/ResourceManager.js index 7244cea..62273ee 100644 --- a/WebCore/inspector/front-end/ResourceManager.js +++ b/WebCore/inspector/front-end/ResourceManager.js @@ -40,16 +40,17 @@ WebInspector.ResourceManager = function() "didFailLoading", "didLoadResourceFromMemoryCache", "setOverrideContent", - "didCommitLoad", + "didCommitLoadForFrame", "frameDetachedFromParent", "didCreateWebSocket", "willSendWebSocketHandshakeRequest", "didReceiveWebSocketHandshakeResponse", "didCloseWebSocket"); - this._resources = {}; - this._resourcesByFrame = {}; - this._lastCachedId = 0; + this._resourcesById = {}; + this._resourcesByURL = {}; + this._resourceTreeModel = new WebInspector.ResourceTreeModel(); + InspectorBackend.cachedResources(this._processCachedResources.bind(this)); } WebInspector.ResourceManager.prototype = { @@ -59,62 +60,69 @@ WebInspector.ResourceManager.prototype = { WebInspector[arguments[i]] = this[arguments[i]].bind(this); }, - identifierForInitialRequest: function(identifier, url, frameID, isMainResource) + identifierForInitialRequest: function(identifier, url, loader) { - var resource = new WebInspector.Resource(identifier, url); - if (isMainResource) + var resource = this._createResource(identifier, url, loader); + if (loader.url === url) { resource.isMainResource = true; - this._resources[identifier] = resource; - - if (frameID) { - resource.frameID = frameID; - var resourcesForFrame = this._resourcesByFrame[frameID]; - if (!resourcesForFrame) { - resourcesForFrame = []; - this._resourcesByFrame[frameID] = resourcesForFrame; - } - resourcesForFrame.push(resource); + WebInspector.mainResource = resource; } - if (WebInspector.panels.network) - WebInspector.panels.network.addResource(resource); + // It is important to bind resource url early (before scripts compile). + this._bindResourceURL(resource); + + WebInspector.panels.network.addResource(resource); + WebInspector.panels.audits.resourceStarted(resource); + }, + + _createResource: function(identifier, url, loader) + { + var resource = new WebInspector.Resource(identifier, url); + resource.loader = loader; + resource.documentURL = loader.url; + + this._resourcesById[identifier] = resource; + return resource; }, willSendRequest: function(identifier, time, request, redirectResponse) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; // Redirect may have empty URL and we'd like to not crash with invalid HashMap entry. // See http/tests/misc/will-send-request-returns-null-on-redirect.html - if (!redirectResponse.isNull && request.url.length) { + var isRedirect = !redirectResponse.isNull && request.url.length; + if (isRedirect) { resource.endTime = time; this.didReceiveResponse(identifier, time, "Other", redirectResponse); resource = this._appendRedirect(resource.identifier, request.url); } - resource.requestMethod = request.httpMethod; - resource.requestHeaders = request.httpHeaderFields; - resource.requestFormData = request.requestFormData; + this._updateResourceWithRequest(resource, request); resource.startTime = time; - if (WebInspector.panels.network) + if (isRedirect) { + WebInspector.panels.network.addResource(resource); + WebInspector.panels.audits.resourceStarted(resource); + } else WebInspector.panels.network.refreshResource(resource); }, - _appendRedirect: function(identifier, redirectURL) + _updateResourceWithRequest: function(resource, request) { - // We always store last redirect by the original id key. Rest of the redirects are referenced from within the last one. - - var originalResource = this._resources[identifier]; - var redirectIdentifier = originalResource.identifier + ":" + (originalResource.redirects ? originalResource.redirects.length : 0); - originalResource.identifier = redirectIdentifier; - this._resources[redirectIdentifier] = originalResource; + resource.requestMethod = request.httpMethod; + resource.requestHeaders = request.httpHeaderFields; + resource.requestFormData = request.requestFormData; + }, - this.identifierForInitialRequest(identifier, redirectURL, originalResource.frameID); + _appendRedirect: function(identifier, redirectURL) + { + var originalResource = this._resourcesById[identifier]; + originalResource.identifier = null; - var newResource = this._resources[identifier]; + var newResource = this._createResource(identifier, redirectURL, originalResource.loader); newResource.redirects = originalResource.redirects || []; delete originalResource.redirects; newResource.redirects.push(originalResource); @@ -123,23 +131,32 @@ WebInspector.ResourceManager.prototype = { markResourceAsCached: function(identifier) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; resource.cached = true; - - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); }, didReceiveResponse: function(identifier, time, resourceType, response) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; - + this._updateResourceWithResponse(resource, response); resource.type = WebInspector.Resource.Type[resourceType]; + resource.responseReceivedTime = time; + + WebInspector.panels.network.refreshResource(resource); + this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource); + }, + + _updateResourceWithResponse: function(resource, response) + { + if (resource.isNull) + return; + resource.mimeType = response.mimeType; resource.expectedContentLength = response.expectedContentLength; resource.textEncodingName = response.textEncodingName; @@ -150,7 +167,6 @@ WebInspector.ResourceManager.prototype = { resource.responseHeaders = response.httpHeaderFields; resource.connectionReused = response.connectionReused; resource.connectionID = response.connectionID; - resource.responseReceivedTime = time; if (response.wasCached) resource.cached = true; @@ -161,101 +177,105 @@ WebInspector.ResourceManager.prototype = { resource.requestHeaders = response.rawHeaders.requestHeaders; resource.responseHeaders = response.rawHeaders.responseHeaders; } - - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); }, didReceiveContentLength: function(identifier, time, lengthReceived) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; resource.resourceSize += lengthReceived; resource.endTime = time; - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); }, didFinishLoading: function(identifier, finishTime) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; resource.finished = true; resource.endTime = finishTime; - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.audits.resourceFinished(resource); + WebInspector.extensionServer.notifyResourceFinished(resource); + delete this._resourcesById[identifier]; }, didFailLoading: function(identifier, time, localizedDescription) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; resource.failed = true; + resource.localizedFailDescription = localizedDescription; + resource.finished = true; resource.endTime = time; - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.audits.resourceFinished(resource); + WebInspector.extensionServer.notifyResourceFinished(resource); + delete this._resourcesById[identifier]; }, - didLoadResourceFromMemoryCache: function(time, frameID, cachedResource) + didLoadResourceFromMemoryCache: function(time, cachedResource) { - var identifier = "cached:" + this._lastCachedId++; - this.identifierForInitialRequest(identifier, cachedResource.url, frameID); - - var resource = this._resources[identifier]; + var resource = this._createResource(null, cachedResource.url, cachedResource.loader); + this._updateResourceWithCachedResource(resource, cachedResource); resource.cached = true; - resource.startTime = resource.responseReceivedTime = time; - resource.resourceSize = cachedResource.encodedSize(); + resource.startTime = resource.responseReceivedTime = resource.endTime = time; - this.didReceiveResponse(identifier, time, cachedResource.response); + WebInspector.panels.network.addResource(resource); + WebInspector.panels.audits.resourceStarted(resource); + WebInspector.panels.audits.resourceFinished(resource); + this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource); + }, + + _updateResourceWithCachedResource: function(resource, cachedResource) + { + resource.type = WebInspector.Resource.Type[cachedResource.type]; + resource.resourceSize = cachedResource.encodedSize; + this._updateResourceWithResponse(resource, cachedResource.response); }, setOverrideContent: function(identifier, sourceString, type) { - var resource = this._resources[identifier]; + var resource = WebInspector.panels.network.resources[identifier]; if (!resource) return; resource.type = WebInspector.Resource.Type[type]; - resource.overridenContent = sourceString; - - if (WebInspector.panels.network) - WebInspector.panels.network.addResource(resource); + resource.content = sourceString; + WebInspector.panels.network.refreshResource(resource); }, - didCommitLoad: function(frameID) + didCommitLoadForFrame: function(parentFrameId, loader) { + this._resourceTreeModel.didCommitLoadForFrame(parentFrameId, loader); }, - frameDetachedFromParent: function(frameID) + frameDetachedFromParent: function(frameId) { - var resourcesForFrame = this._resourcesByFrame[frameID]; - for (var i = 0; resourcesForFrame && i < resourcesForFrame.length; ++i) - delete this._resources[resourcesForFrame[i].identifier]; - delete this._resourcesByFrame[frameID]; + this._resourceTreeModel.frameDetachedFromParent(frameId); }, didCreateWebSocket: function(identifier, requestURL) { this.identifierForInitialRequest(identifier, requestURL); - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; resource.type = WebInspector.Resource.Type.WebSocket; - if (WebInspector.panels.network) - WebInspector.panels.network.addResource(resource); + WebInspector.panels.network.addResource(resource); }, willSendWebSocketHandshakeRequest: function(identifier, time, request) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; @@ -264,13 +284,12 @@ WebInspector.ResourceManager.prototype = { resource.webSocketRequestKey3 = request.webSocketRequestKey3; resource.startTime = time; - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); }, didReceiveWebSocketHandshakeResponse: function(identifier, time, response) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; @@ -280,18 +299,293 @@ WebInspector.ResourceManager.prototype = { resource.webSocketChallengeResponse = response.webSocketChallengeResponse; resource.responseReceivedTime = time; - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); }, didCloseWebSocket: function(identifier, time) { - var resource = this._resources[identifier]; + var resource = this._resourcesById[identifier]; if (!resource) return; resource.endTime = time; - if (WebInspector.panels.network) - WebInspector.panels.network.refreshResource(resource); + WebInspector.panels.network.refreshResource(resource); + }, + + _processCachedResources: function(mainFramePayload) + { + var mainResource = this._addFramesRecursively(null, mainFramePayload); + WebInspector.mainResource = mainResource; + mainResource.isMainResource = true; + }, + + _addFramesRecursively: function(parentFrameId, framePayload) + { + var frameResource = this._createResource(null, framePayload.resource.url, framePayload.resource.loader); + this._updateResourceWithRequest(frameResource, framePayload.resource.request); + this._updateResourceWithResponse(frameResource, framePayload.resource.response); + frameResource.type = WebInspector.Resource.Type["Document"]; + frameResource.finished = true; + this._bindResourceURL(frameResource); + + this._resourceTreeModel.addOrUpdateFrame(parentFrameId, framePayload.id, frameResource.displayName); + this._resourceTreeModel.addResourceToFrame(framePayload.id, frameResource); + + for (var i = 0; framePayload.children && i < framePayload.children.length; ++i) + this._addFramesRecursively(framePayload.id, framePayload.children[i]); + + if (!framePayload.subresources) + return; + + for (var i = 0; i < framePayload.subresources.length; ++i) { + var cachedResource = framePayload.subresources[i]; + var resource = this._createResource(null, cachedResource.url, cachedResource.loader); + this._updateResourceWithCachedResource(resource, cachedResource); + resource.finished = true; + this._bindResourceURL(resource); + this._resourceTreeModel.addResourceToFrame(framePayload.id, resource); + } + return frameResource; + }, + + resourceForURL: function(url) + { + // FIXME: receive frameId here. + var entry = this._resourcesByURL[url]; + if (entry instanceof Array) + return entry[0]; + return entry; + }, + + addConsoleMessage: function(msg) + { + var resource = this.resourceForURL(msg.url); + if (!resource) + return; + + switch (msg.level) { + case WebInspector.ConsoleMessage.MessageLevel.Warning: + resource.warnings += msg.repeatDelta; + break; + case WebInspector.ConsoleMessage.MessageLevel.Error: + resource.errors += msg.repeatDelta; + break; + } + + var view = WebInspector.ResourceManager.resourceViewForResource(resource); + if (view.addMessage) + view.addMessage(msg); + }, + + clearConsoleMessages: function() + { + function callback(resource) + { + resource.clearErrorsAndWarnings(); + } + this._resourceTreeModel.forAllResources(callback); + }, + + forAllResources: function(callback) + { + this._resourceTreeModel.forAllResources(callback); + }, + + _bindResourceURL: function(resource) + { + var resourceForURL = this._resourcesByURL[resource.url]; + if (!resourceForURL) + this._resourcesByURL[resource.url] = resource; + else if (resourceForURL instanceof Array) + resourceForURL.push(resource); + else + this._resourcesByURL[resource.url] = [resourceForURL]; + }, + + _unbindResourceURL: function(resource) + { + var resourceForURL = this._resourcesByURL[resource.url]; + if (!resourceForURL) + return; + + if (resourceForURL instanceof Array) { + resourceForURL.remove(resource, true); + if (resourceForURL.length === 1) + this._resourcesByURL[resource.url] = resourceForURL[0]; + return; + } + + delete this._resourcesByURL[resource.url]; + } +} + +WebInspector.ResourceManager.createResourceView = function(resource) +{ + switch (resource.category) { + case WebInspector.resourceCategories.documents: + case WebInspector.resourceCategories.stylesheets: + case WebInspector.resourceCategories.scripts: + case WebInspector.resourceCategories.xhr: + return new WebInspector.SourceView(resource); + case WebInspector.resourceCategories.images: + return new WebInspector.ImageView(resource); + case WebInspector.resourceCategories.fonts: + return new WebInspector.FontView(resource); + default: + return new WebInspector.ResourceView(resource); + } +} + +WebInspector.ResourceManager.resourceViewTypeMatchesResource = function(resource, resourceView) +{ + switch (resource.category) { + case WebInspector.resourceCategories.documents: + case WebInspector.resourceCategories.stylesheets: + case WebInspector.resourceCategories.scripts: + case WebInspector.resourceCategories.xhr: + return resourceView.__proto__ === WebInspector.SourceView.prototype; + case WebInspector.resourceCategories.images: + return resourceView.__proto__ === WebInspector.ImageView.prototype; + case WebInspector.resourceCategories.fonts: + return resourceView.__proto__ === WebInspector.FontView.prototype; + default: + return resourceView.__proto__ === WebInspector.ResourceView.prototype; + } +} + +WebInspector.ResourceManager.resourceViewForResource = function(resource) +{ + if (!resource) + return null; + if (!resource._resourcesView) + resource._resourcesView = WebInspector.ResourceManager.createResourceView(resource); + return resource._resourcesView; +} + +WebInspector.ResourceManager.existingResourceViewForResource = function(resource) +{ + if (!resource) + return null; + return resource._resourcesView; +} + +WebInspector.ResourceManager.getContent = function(resource, base64Encode, callback) +{ + // FIXME: eventually, cached resources will have no identifiers. + if (resource.loader) + InspectorBackend.resourceContent(resource.loader.frameId, resource.url, base64Encode, callback); + else + InspectorBackend.getResourceContent(resource.identifier, base64Encode, callback); +} + +WebInspector.ResourceTreeModel = function() +{ + this._resourcesByFrameId = {}; + this._subframes = {}; +} + +WebInspector.ResourceTreeModel.prototype = { + addOrUpdateFrame: function(parentFrameId, frameId, displayName) + { + WebInspector.panels.storage.addOrUpdateFrame(parentFrameId, frameId, displayName); + var subframes = this._subframes[parentFrameId]; + if (!subframes) { + subframes = {}; + this._subframes[parentFrameId || 0] = subframes; + } + subframes[frameId] = true; + }, + + didCommitLoadForFrame: function(parentFrameId, loader) + { + // parentFrameId === 0 is when main frame navigation happens. + this._clearChildFramesAndResources(parentFrameId ? loader.frameId : 0, loader.loaderId); + + var tmpResource = new WebInspector.Resource(null, loader.url); + this.addOrUpdateFrame(parentFrameId, loader.frameId, tmpResource.displayName); + + var resourcesForFrame = this._resourcesByFrameId[loader.frameId]; + for (var i = 0; resourcesForFrame && i < resourcesForFrame.length; ++i) { + WebInspector.resourceManager._bindResourceURL(resourcesForFrame[i]); + WebInspector.panels.storage.addResourceToFrame(loader.frameId, resourcesForFrame[i]); + } + }, + + frameDetachedFromParent: function(frameId) + { + this._clearChildFramesAndResources(frameId, 0); + WebInspector.panels.storage.removeFrame(frameId); + }, + + _clearChildFramesAndResources: function(frameId, loaderId) + { + WebInspector.panels.storage.removeResourcesFromFrame(frameId); + + this._clearResources(frameId, loaderId); + var subframes = this._subframes[frameId]; + if (!subframes) + return; + + for (var childFrameId in subframes) { + WebInspector.panels.storage.removeFrame(childFrameId); + this._clearChildFramesAndResources(childFrameId, loaderId); + } + delete this._subframes[frameId]; + }, + + addResourceToFrame: function(frameId, resource) + { + var resourcesForFrame = this._resourcesByFrameId[frameId]; + if (!resourcesForFrame) { + resourcesForFrame = []; + this._resourcesByFrameId[frameId] = resourcesForFrame; + } + resourcesForFrame.push(resource); + + WebInspector.panels.storage.addResourceToFrame(frameId, resource); + }, + + _clearResources: function(frameId, loaderToPreserveId) + { + var resourcesForFrame = this._resourcesByFrameId[frameId]; + if (!resourcesForFrame) + return; + + var preservedResourcesForFrame = []; + for (var i = 0; i < resourcesForFrame.length; ++i) { + var resource = resourcesForFrame[i]; + if (resource.loader.loaderId === loaderToPreserveId) { + preservedResourcesForFrame.push(resource); + continue; + } + WebInspector.resourceManager._unbindResourceURL(resource); + } + + delete this._resourcesByFrameId[frameId]; + if (preservedResourcesForFrame.length) + this._resourcesByFrameId[frameId] = preservedResourcesForFrame; + }, + + forAllResources: function(callback) + { + this._callForFrameResources(0, callback); + }, + + _callForFrameResources: function(frameId, callback) + { + var resources = this._resourcesByFrameId[frameId]; + for (var i = 0; resources && i < resources.length; ++i) { + if (callback(resources[i])) + return true; + } + + var frames = this._subframes[frameId]; + if (frames) { + for (var id in frames) { + if (this._callForFrameResources(id, callback)) + return true; + } + } + return false; } } diff --git a/WebCore/inspector/front-end/ResourceView.js b/WebCore/inspector/front-end/ResourceView.js index 862569f..ffb229d 100644 --- a/WebCore/inspector/front-end/ResourceView.js +++ b/WebCore/inspector/front-end/ResourceView.js @@ -139,14 +139,20 @@ WebInspector.ResourceView.prototype = { this._selectTab(); }, + resize: function() + { + if (this._cookiesView && !this._cookiesView.element.hasStyleClass("hidden")) + this._cookiesView.resize(); + }, + _selectTab: function() { - if (this._headersVisible) { - if (!this.hasContentTab() || WebInspector.applicationSettings.resourceViewTab === "headers") - this._selectHeadersTab(); - else - this.selectContentTab(); - } else + var preferredTab = WebInspector.applicationSettings.resourceViewTab; + if (this._headersVisible && this._cookiesView && preferredTab === "cookies") + this._selectCookiesTab(); + else if (this._headersVisible && (!this.hasContentTab() || preferredTab === "headers")) + this._selectHeadersTab(); + else this._innerSelectContentTab(); }, @@ -170,11 +176,18 @@ WebInspector.ResourceView.prototype = { return false; }, + _selectCookiesTab: function(updatePrefs) + { + if (updatePrefs) + WebInspector.applicationSettings.resourceViewTab = "cookies"; + this.tabbedPane.selectTabById("cookies"); + this._cookiesView.resize(); + }, + _innerSelectContentTab: function() { this.tabbedPane.selectTabById("content"); - if ("resize" in this) - this.resize(); + this.resize(); if (this.hasContentTab()) this.contentTabSelected(); }, @@ -283,6 +296,7 @@ WebInspector.ResourceView.prototype = { additionalRow = {header: "(Key3)", value: this.resource.webSocketRequestKey3}; this._refreshHeaders(WebInspector.UIString("Request Headers"), this.resource.sortedRequestHeaders, additionalRow, this.requestHeadersTreeElement); this._refreshFormData(); + this._refreshCookies(); }, _refreshResponseHeaders: function() @@ -291,6 +305,7 @@ WebInspector.ResourceView.prototype = { if (typeof this.resource.webSocketChallengeResponse !== "undefined") additionalRow = {header: "(Challenge Response)", value: this.resource.webSocketChallengeResponse}; this._refreshHeaders(WebInspector.UIString("Response Headers"), this.resource.sortedResponseHeaders, additionalRow, this.responseHeadersTreeElement); + this._refreshCookies(); }, _refreshHTTPInformation: function() @@ -347,7 +362,80 @@ WebInspector.ResourceView.prototype = { headerTreeElement.selectable = false; headersTreeElement.appendChild(headerTreeElement); } + }, + + _refreshCookies: function() + { + if (!this._cookiesView) { + if (!this.resource.requestCookies && !this.resource.responseCookies) + return; + this._cookiesView = new WebInspector.ResourceCookiesTab(); + this.tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView.element, this._selectCookiesTab.bind(this, true)); + } + this._cookiesView.requestCookies = this.resource.requestCookies; + this._cookiesView.responseCookies = this.resource.responseCookies; } } WebInspector.ResourceView.prototype.__proto__ = WebInspector.View.prototype; + +WebInspector.ResourceCookiesTab = function() +{ + WebInspector.CookiesTable.call(this); + this.element.addStyleClass("resource-view-cookies"); + this._requestCookies = []; + this._responseCookies = []; + this._createDataGrid(true); + this._requestCookiesNode = this._createFolder(WebInspector.UIString("Request Cookies")); + this._responseCookiesNode = this._createFolder(WebInspector.UIString("Response Cookies")); +} + +WebInspector.ResourceCookiesTab.prototype = { + set requestCookies(cookies) + { + if (this._requestCookies === cookies) + return; + this._requestCookies = cookies; + this._populateCookies(this._requestCookiesNode, this._requestCookies); + }, + + set responseCookies(cookies) + { + if (this._responseCookies === cookies) + return; + this._responseCookies = cookies; + this._populateCookies(this._responseCookiesNode, this._responseCookies); + }, + + _populateDataGrid: function() + { + this._populateCookies(this._requestCookiesNode, this._requestCookies); + this._populateCookies(this._responseCookiesNode, this._responseCookies); + }, + + _populateCookies: function(parentNode, cookies) + { + WebInspector.CookiesTable.prototype._populateCookies.call(this, parentNode, cookies); + var totalSize = 0; + if (cookies) { + for (var i = 0; i < cookies.length; ++i) + totalSize += cookies[i].size; + } + parentNode.expanded = true; + parentNode.data[5] = totalSize; + parentNode.refresh(); + }, + + _createFolder: function(name) + { + var data = [ name, "", "", "", "", 0, "", "" ]; + var node = new WebInspector.DataGridNode(data); + node.selectable = true; + node.expanded = true; + this._dataGrid.appendChild(node); + node.element.addStyleClass("row-group"); + return node; + } +}; + +WebInspector.ResourceCookiesTab.prototype.__proto__ = WebInspector.CookiesTable.prototype; diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js index ae67bef..b35fc4b 100644 --- a/WebCore/inspector/front-end/ResourcesPanel.js +++ b/WebCore/inspector/front-end/ResourcesPanel.js @@ -30,7 +30,7 @@ WebInspector.ResourcesPanel = function() { WebInspector.Panel.call(this, "resources"); - + this.resourceURLMap = {}; this._items = []; this._staleItems = []; @@ -439,26 +439,22 @@ WebInspector.ResourcesPanel.prototype = { this.element.appendChild(this.panelEnablerView.element); this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item"); - this.enableToggleButton.addEventListener("click", this._toggleResourceTracking.bind(this), false); + this.enableToggleButton.addEventListener("click", this.toggleResourceTracking.bind(this), false); }, _createStatusbarButtons: function() { this.largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "resources-larger-resources-status-bar-item"); - WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this); - this.largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false); - this.sortingSelectElement = document.createElement("select"); - this.sortingSelectElement.className = "status-bar-item"; - this.sortingSelectElement.addEventListener("change", this._changeSortingFunction.bind(this), false); - }, - - _settingsLoaded: function() - { this.largerResourcesButton.toggled = WebInspector.applicationSettings.resourcesLargeRows; if (!WebInspector.applicationSettings.resourcesLargeRows) this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows); this._loadSortOptions(); + + this.largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false); + this.sortingSelectElement = document.createElement("select"); + this.sortingSelectElement.className = "status-bar-item"; + this.sortingSelectElement.addEventListener("change", this._changeSortingFunction.bind(this), false); }, _loadSortOptions: function() @@ -557,7 +553,7 @@ WebInspector.ResourcesPanel.prototype = { var resource = this._resources[i]; if (!resource._itemsTreeElement || !resource._itemsTreeElement.selectable) continue; - var resourceView = this.resourceViewForResource(resource); + var resourceView = WebInspector.ResourceManager.resourceViewForResource(resource); if (!resourceView.performSearch || resourceView === visibleView) continue; views.push(resourceView); @@ -752,10 +748,12 @@ WebInspector.ResourcesPanel.prototype = { this.sortingSelectElement.addStyleClass("hidden"); this.panelEnablerView.visible = true; } + this.resourceURLMap = {}; }, addResource: function(resource) { + this.resourceURLMap[resource.url] = resource; this._resources.push(resource); }, @@ -770,6 +768,7 @@ WebInspector.ResourcesPanel.prototype = { resource.errors = 0; delete resource._resourcesView; + delete this.resourceURLMap[resource.url]; }, addMessageToResource: function(resource, msg) @@ -789,7 +788,7 @@ WebInspector.ResourcesPanel.prototype = { if (!this.currentQuery && resource._itemsTreeElement) resource._itemsTreeElement.updateErrorsAndWarnings(); - var view = this.resourceViewForResource(resource); + var view = WebInspector.ResourceManager.resourceViewForResource(resource); if (view.addMessage) view.addMessage(msg); }, @@ -823,10 +822,10 @@ WebInspector.ResourcesPanel.prototype = { if (!resource || !resource._resourcesView) return; - if (this._resourceViewIsConsistentWithCategory(resource, resource._resourcesView)) + if (WebInspector.ResourceManager.resourceViewTypeMatchesResource(resource, resource._resourcesView)) return; + var newView = WebInspector.ResourceManager.createResourceView(resource); - var newView = this._createResourceView(resource); if (!this.currentQuery && resource._itemsTreeElement) resource._itemsTreeElement.updateErrorsAndWarnings(); @@ -868,7 +867,7 @@ WebInspector.ResourcesPanel.prototype = { if (this.visibleResource && this.visibleResource._resourcesView) this.visibleResource._resourcesView.hide(); - var view = this.resourceViewForResource(resource); + var view = WebInspector.ResourceManager.resourceViewForResource(resource); view.headersVisible = true; view.show(this.viewsContainerElement); @@ -909,32 +908,6 @@ WebInspector.ResourcesPanel.prototype = { this.updateSidebarWidth(); }, - resourceViewForResource: function(resource) - { - if (!resource) - return null; - if (!resource._resourcesView) - resource._resourcesView = this._createResourceView(resource); - return resource._resourcesView; - }, - - sourceFrameForResource: function(resource) - { - var view = this.resourceViewForResource(resource); - if (!view) - return null; - - if (!view.setupSourceFrameIfNeeded) - return null; - - // Setting up the source frame requires that we be attached. - if (!this.element.parentNode) - this.attach(); - - view.setupSourceFrameIfNeeded(); - return view.sourceFrame; - }, - _sortResourcesIfNeeded: function() { this.sortItems(this.sortingFunction); @@ -1068,40 +1041,6 @@ WebInspector.ResourcesPanel.prototype = { this.calculator = this.summaryBar.calculator = selectedOption.calculator; }, - _resourceViewIsConsistentWithCategory: function(resource, resourceView) - { - switch (resource.category) { - case WebInspector.resourceCategories.documents: - case WebInspector.resourceCategories.stylesheets: - case WebInspector.resourceCategories.scripts: - case WebInspector.resourceCategories.xhr: - return resourceView.__proto__ === WebInspector.SourceView.prototype; - case WebInspector.resourceCategories.images: - return resourceView.__proto__ === WebInspector.ImageView.prototype; - case WebInspector.resourceCategories.fonts: - return resourceView.__proto__ === WebInspector.FontView.prototype; - default: - return resourceView.__proto__ === WebInspector.ResourceView.prototype; - } - }, - - _createResourceView: function(resource) - { - switch (resource.category) { - case WebInspector.resourceCategories.documents: - case WebInspector.resourceCategories.stylesheets: - case WebInspector.resourceCategories.scripts: - case WebInspector.resourceCategories.xhr: - return new WebInspector.SourceView(resource); - case WebInspector.resourceCategories.images: - return new WebInspector.ImageView(resource); - case WebInspector.resourceCategories.fonts: - return new WebInspector.FontView(resource); - default: - return new WebInspector.ResourceView(resource); - } - }, - setSidebarWidth: function(width) { if (this.visibleResource) { @@ -1126,10 +1065,10 @@ WebInspector.ResourcesPanel.prototype = { { if (this._resourceTrackingEnabled) return; - this._toggleResourceTracking(this.panelEnablerView.alwaysEnabled); + this.toggleResourceTracking(this.panelEnablerView.alwaysEnabled); }, - _toggleResourceTracking: function(optionalAlways) + toggleResourceTracking: function(optionalAlways) { function callback(newState) { if (newState) @@ -1142,7 +1081,7 @@ WebInspector.ResourcesPanel.prototype = { this.largerResourcesButton.visible = false; this.sortingSelectElement.visible = false; WebInspector.resources = {}; - WebInspector.resourceURLMap = {}; + this.resourceURLMap = {}; InspectorBackend.setResourceTrackingEnabled(false, true, callback); } else { this.largerResourcesButton.visible = true; @@ -1723,7 +1662,15 @@ WebInspector.ResourceSidebarTreeElement.prototype = { if (this.resource.category === WebInspector.resourceCategories.images) { var previewImage = document.createElement("img"); previewImage.className = "image-resource-icon-preview"; - previewImage.src = this.resource.url; + + function onResourceContent() + { + previewImage.src = this.resource.contentURL; + } + if (Preferences.useDataURLForResourceImageIcons) + this.resource.getContent(onResourceContent.bind(this)); + else + previewImage.src = this.resource.url; this.iconElement = document.createElement("div"); this.iconElement.className = "icon"; diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index 0a653c9..8125c1e 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -241,7 +241,7 @@ WebInspector.ScriptsPanel.prototype = { var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType); this._sourceIDMap[sourceID] = script; - var resource = WebInspector.resourceURLMap[sourceURL]; + var resource = WebInspector.resourceForURL(sourceURL); if (resource) { if (resource.finished) { // Resource is finished, bind the script right away. @@ -289,7 +289,7 @@ WebInspector.ScriptsPanel.prototype = { var sourceFrame; if (breakpoint.url) { - var resource = WebInspector.resourceURLMap[breakpoint.url]; + var resource = WebInspector.resourceForURL(breakpoint.url); if (resource && resource.finished) sourceFrame = this._sourceFrameForScriptOrResource(resource); } @@ -570,11 +570,24 @@ WebInspector.ScriptsPanel.prototype = { _sourceFrameForScriptOrResource: function(scriptOrResource) { if (scriptOrResource instanceof WebInspector.Resource) - return WebInspector.panels.resources.sourceFrameForResource(scriptOrResource); + return this._sourceFrameForResource(scriptOrResource); if (scriptOrResource instanceof WebInspector.Script) return this.sourceFrameForScript(scriptOrResource); }, + _sourceFrameForResource: function(resource) + { + var view = WebInspector.ResourceManager.resourceViewForResource(resource); + if (!view) + return null; + + if (!view.setupSourceFrameIfNeeded) + return null; + + view.setupSourceFrameIfNeeded(); + return view.sourceFrame; + }, + _showScriptOrResource: function(scriptOrResource, options) { // options = {line:, shouldHighlightLine:, fromBackForwardAction:, initialLoad:} @@ -585,9 +598,7 @@ WebInspector.ScriptsPanel.prototype = { var view; if (scriptOrResource instanceof WebInspector.Resource) { - if (!WebInspector.panels.resources) - return null; - view = WebInspector.panels.resources.resourceViewForResource(scriptOrResource); + view = WebInspector.ResourceManager.resourceViewForResource(scriptOrResource); view.headersVisible = false; } else if (scriptOrResource instanceof WebInspector.Script) view = this.scriptViewForScript(scriptOrResource); diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js index c6da14d..3fb81f5 100644 --- a/WebCore/inspector/front-end/Settings.js +++ b/WebCore/inspector/front-end/Settings.js @@ -45,96 +45,74 @@ var Preferences = { onlineDetectionEnabled: true, nativeInstrumentationEnabled: false, resourceExportEnabled: false, - networkPanelEnabled: false + networkPanelEnabled: false, + useDataURLForResourceImageIcons: true } -WebInspector.Settings = function(sessionScope) +WebInspector.Settings = function() { - this._sessionScope = sessionScope; - this._store = {}; -} + this.installApplicationSetting("colorFormat", "hex"); + this.installApplicationSetting("consoleHistory", []); + this.installApplicationSetting("eventListenersFilter", "all"); + this.installApplicationSetting("lastViewedScriptFile", "application"); + this.installApplicationSetting("resourcesLargeRows", true); + this.installApplicationSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"}); + this.installApplicationSetting("resourceViewTab", "content"); + this.installApplicationSetting("showInheritedComputedStyleProperties", false); + this.installApplicationSetting("showUserAgentStyles", true); + this.installApplicationSetting("watchExpressions", []); + this.installApplicationSetting("lastActivePanel", "elements"); -WebInspector.Settings.initialize = function() -{ - WebInspector.applicationSettings = new WebInspector.Settings(false); - WebInspector.sessionSettings = new WebInspector.Settings(true); + this.installProjectSetting("breakpoints", {}); +} - function populateApplicationSettings(settingsString) +WebInspector.Settings.prototype = { + installApplicationSetting: function(key, defaultValue) { - WebInspector.applicationSettings._load(settingsString); - WebInspector.applicationSettings.installSetting("eventListenersFilter", "event-listeners-filter", "all"); - WebInspector.applicationSettings.installSetting("colorFormat", "color-format", "hex"); - WebInspector.applicationSettings.installSetting("resourcesLargeRows", "resources-large-rows", true); - WebInspector.applicationSettings.installSetting("watchExpressions", "watch-expressions", []); - WebInspector.applicationSettings.installSetting("lastViewedScriptFile", "last-viewed-script-file"); - WebInspector.applicationSettings.installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false); - WebInspector.applicationSettings.installSetting("showUserAgentStyles", "show-user-agent-styles", true); - WebInspector.applicationSettings.installSetting("resourceViewTab", "resource-view-tab", "content"); - WebInspector.applicationSettings.installSetting("consoleHistory", "console-history", []); - WebInspector.applicationSettings.installSetting("resourcesSortOptions", "resources-sort-options", {timeOption: "responseTime", sizeOption: "transferSize"}); - - WebInspector.applicationSettings.dispatchEventToListeners("loaded"); - } + this.__defineGetter__(key, this._get.bind(this, key, defaultValue)); + this.__defineSetter__(key, this._set.bind(this, key)); + }, - function populateSessionSettings(settingsString) + installProjectSetting: function(key, defaultValue) { - WebInspector.sessionSettings._load(settingsString); - WebInspector.sessionSettings.dispatchEventToListeners("loaded"); - } - - InspectorBackend.getSettings(function(settings) { - populateApplicationSettings(settings.application); - populateSessionSettings(settings.session); - }); -} + this.__defineGetter__(key, this._getProjectSetting.bind(this, key, defaultValue)); + this.__defineSetter__(key, this._setProjectSetting.bind(this, key)); + }, -WebInspector.Settings.prototype = { - reset: function() + _get: function(key, defaultValue) { - this._store = {}; - // FIXME: restore default values (bug 42820) - this.dispatchEventToListeners("loaded"); + if (key in window.localStorage) { + try { + return JSON.parse(window.localStorage[key]); + } catch(e) { + window.localStorage.removeItem(key); + } + } + return defaultValue; }, - _load: function(settingsString) + _set: function(key, value) { - try { - var loadedStore = JSON.parse(settingsString); - } catch (e) { - // May fail; - loadedStore = {}; - } - if (!loadedStore) - return; - for (var propertyName in loadedStore) - this._store[propertyName] = loadedStore[propertyName]; + window.localStorage[key] = JSON.stringify(value); }, - installSetting: function(name, propertyName, defaultValue) + _getProjectSetting: function(key, defaultValue) { - this.__defineGetter__(name, this._get.bind(this, propertyName)); - this.__defineSetter__(name, this._set.bind(this, propertyName)); - if (!(propertyName in this._store)) - this._store[propertyName] = defaultValue; + return this._get(this._formatProjectKey(key), defaultValue); }, - _get: function(propertyName) + _setProjectSetting: function(key, value) { - return this._store[propertyName]; + return this._set(this._formatProjectKey(key), value); }, - _set: function(propertyName, newValue) + _formatProjectKey: function(key) { - this._store[propertyName] = newValue; - try { - var store = JSON.stringify(this._store); - if (this._sessionScope) - InspectorBackend.saveSessionSettings(store); - else - InspectorBackend.saveApplicationSettings(store); - } catch (e) { - // May fail; - } + var url = this._mainResourceURL; + var fragmentIndex = url.indexOf("#"); + if (fragmentIndex !== -1) + url = url.substring(0, fragmentIndex); + return key + "." + url; } } diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js index 8092505..bfdc058 100644 --- a/WebCore/inspector/front-end/SourceView.js +++ b/WebCore/inspector/front-end/SourceView.js @@ -73,6 +73,7 @@ WebInspector.SourceView.prototype = { this.sourceFrame.resize(); if (this.localSourceFrame) this.localSourceFrame.resize(); + WebInspector.ResourceView.prototype.resize.call(this); }, setupSourceFrameIfNeeded: function() @@ -83,7 +84,7 @@ WebInspector.SourceView.prototype = { this.attach(); delete this._frameNeedsSetup; - this.resource.getContents(this._contentLoaded.bind(this)); + this.resource.getContent(this._contentLoaded.bind(this)); }, hasContentTab: function() diff --git a/WebCore/inspector/front-end/StoragePanel.js b/WebCore/inspector/front-end/StoragePanel.js index e033b57..2fa54c2 100644 --- a/WebCore/inspector/front-end/StoragePanel.js +++ b/WebCore/inspector/front-end/StoragePanel.js @@ -32,28 +32,36 @@ WebInspector.StoragePanel = function(database) WebInspector.Panel.call(this, "storage"); this.createSidebar(); + this.sidebarElement.addStyleClass("outline-disclosure filter-all children small"); + this.sidebarTreeElement.removeStyleClass("sidebar-tree"); + + if (Preferences.networkPanelEnabled) { + this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "frame-storage-tree-item"); + this.sidebarTree.appendChild(this.resourcesListTreeElement); + this.resourcesListTreeElement.expand(); + this._treeElementForFrameId = {}; + } - this.databasesListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("DATABASES"), {}, true); + this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Databases"), "database-storage-tree-item"); this.sidebarTree.appendChild(this.databasesListTreeElement); this.databasesListTreeElement.expand(); - this.localStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("LOCAL STORAGE"), {}, true); + this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "domstorage-storage-tree-item local-storage"); this.sidebarTree.appendChild(this.localStorageListTreeElement); this.localStorageListTreeElement.expand(); - this.sessionStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("SESSION STORAGE"), {}, true); + this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "domstorage-storage-tree-item session-storage"); this.sidebarTree.appendChild(this.sessionStorageListTreeElement); this.sessionStorageListTreeElement.expand(); - this.cookieListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("COOKIES"), {}, true); + this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "cookie-storage-tree-item"); this.sidebarTree.appendChild(this.cookieListTreeElement); this.cookieListTreeElement.expand(); - - this.applicationCacheListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("APPLICATION CACHE"), {}, true); + this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "application-cache-storage-tree-item"); this.sidebarTree.appendChild(this.applicationCacheListTreeElement); this.applicationCacheListTreeElement.expand(); - + this.storageViews = document.createElement("div"); this.storageViews.id = "storage-views"; this.element.appendChild(this.storageViews); @@ -61,13 +69,15 @@ WebInspector.StoragePanel = function(database) this.storageViewStatusBarItemsContainer = document.createElement("div"); this.storageViewStatusBarItemsContainer.className = "status-bar-items"; - this.reset(); + this._databases = []; + this._domStorage = []; + this._cookieViews = {}; } WebInspector.StoragePanel.prototype = { get toolbarItemLabel() { - return WebInspector.UIString("Storage"); + return Preferences.networkPanelEnabled ? WebInspector.UIString("Resources") : WebInspector.UIString("Storage"); }, get statusBarItems() @@ -77,27 +87,18 @@ WebInspector.StoragePanel.prototype = { reset: function() { - if (this._databases) { - var databasesLength = this._databases.length; - for (var i = 0; i < databasesLength; ++i) { - var database = this._databases[i]; - - delete database._tableViews; - delete database._queryView; - } + for (var i = 0; i < this._databases.length; ++i) { + var database = this._databases[i]; + delete database._tableViews; + delete database._queryView; } - this._databases = []; - if (this._domStorage) { - var domStorageLength = this._domStorage.length; - for (var i = 0; i < domStorageLength; ++i) { - var domStorage = this._domStorage[i]; - - delete domStorage._domStorageView; - } + var domStorageLength = this._domStorage.length; + for (var i = 0; i < this._domStorage.length; ++i) { + var domStorage = this._domStorage[i]; + delete domStorage._domStorageView; } - this._domStorage = []; this._cookieViews = {}; @@ -109,36 +110,112 @@ WebInspector.StoragePanel.prototype = { this.localStorageListTreeElement.removeChildren(); this.sessionStorageListTreeElement.removeChildren(); this.cookieListTreeElement.removeChildren(); - this.applicationCacheListTreeElement.removeChildren(); this.storageViews.removeChildren(); this.storageViewStatusBarItemsContainer.removeChildren(); - + if (this.sidebarTree.selectedTreeElement) this.sidebarTree.selectedTreeElement.deselect(); }, + addOrUpdateFrame: function(parentFrameId, frameId, displayName) + { + var frameTreeElement = this._treeElementForFrameId[frameId]; + if (frameTreeElement) { + frameTreeElement.displayName = displayName; + return; + } + + var parentTreeElement = parentFrameId ? this._treeElementForFrameId[parentFrameId] : this.resourcesListTreeElement; + if (!parentTreeElement) { + console.warning("No frame with id:" + parentFrameId + " to route " + displayName + " to.") + return; + } + + var frameTreeElement = new WebInspector.FrameTreeElement(this, frameId, displayName); + this._treeElementForFrameId[frameId] = frameTreeElement; + + // Insert in the alphabetical order, first frames, then resources. + var children = parentTreeElement.children; + for (var i = 0; i < children.length; ++i) { + var child = children[i]; + if (!(child instanceof WebInspector.FrameTreeElement)) { + parentTreeElement.insertChild(frameTreeElement, i); + return; + } + if (child.displayName.localeCompare(frameTreeElement.displayName) > 0) { + parentTreeElement.insertChild(frameTreeElement, i); + return; + } + } + parentTreeElement.appendChild(frameTreeElement); + }, + + removeFrame: function(frameId) + { + var frameTreeElement = this._treeElementForFrameId[frameId]; + if (!frameTreeElement) + return; + delete this._treeElementForFrameId[frameId]; + if (frameTreeElement.parent) + frameTreeElement.parent.removeChild(frameTreeElement); + }, + + addResourceToFrame: function(frameId, resource) + { + var frameTreeElement = this._treeElementForFrameId[frameId]; + if (!frameTreeElement) { + // This is a frame's main resource, it will be retained + // and re-added by the resource manager; + return; + } + + var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this, resource); + + // Insert in the alphabetical order, first frames, then resources. Document resource goes first. + var children = frameTreeElement.children; + for (var i = 0; i < children.length; ++i) { + var child = children[i]; + if (!(child instanceof WebInspector.FrameResourceTreeElement)) + continue; + + if (resource.type === WebInspector.Resource.Type.Document || + (child._resource.type !== WebInspector.Resource.Type.Document && child._resource.displayName.localeCompare(resource.displayName) > 0)) { + frameTreeElement.insertChild(resourceTreeElement, i); + return; + } + } + frameTreeElement.appendChild(resourceTreeElement); + }, + + removeResourcesFromFrame: function(frameId) + { + var frameTreeElement = this._treeElementForFrameId[frameId]; + if (frameTreeElement) + frameTreeElement.removeChildren(); + }, + addDatabase: function(database) { this._databases.push(database); - var databaseTreeElement = new WebInspector.DatabaseSidebarTreeElement(database); + var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database); database._databasesTreeElement = databaseTreeElement; this.databasesListTreeElement.appendChild(databaseTreeElement); }, addCookieDomain: function(domain) { - var cookieDomainTreeElement = new WebInspector.CookieSidebarTreeElement(domain); + var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain); this.cookieListTreeElement.appendChild(cookieDomainTreeElement); }, addDOMStorage: function(domStorage) { this._domStorage.push(domStorage); - var domStorageTreeElement = new WebInspector.DOMStorageSidebarTreeElement(domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage")); + var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage")); domStorage._domStorageTreeElement = domStorageTreeElement; if (domStorage.isLocalStorage) this.localStorageListTreeElement.appendChild(domStorageTreeElement); @@ -148,7 +225,7 @@ WebInspector.StoragePanel.prototype = { addApplicationCache: function(domain) { - var applicationCacheTreeElement = new WebInspector.ApplicationCacheSidebarTreeElement(domain); + var applicationCacheTreeElement = new WebInspector.ApplicationCacheTreeElement(this, domain); this.applicationCacheListTreeElement.appendChild(applicationCacheTreeElement); }, @@ -174,14 +251,47 @@ WebInspector.StoragePanel.prototype = { } }, + canShowSourceLine: function(url, line) + { + return !!WebInspector.resourceManager.resourceForURL(url); + }, + + showSourceLine: function(url, line) + { + this.showResource(WebInspector.resourceManager.resourceForURL(url), line); + }, + + showResource: function(resource, line) + { + var resourceTreeElement = this._findTreeElementForResource(resource); + if (resourceTreeElement) { + resourceTreeElement.reveal(); + resourceTreeElement.select(); + } + + if (line) { + var view = WebInspector.ResourceManager.resourceViewForResource(resource); + view.selectContentTab(true); + if (view.revealLine) + view.revealLine(line); + if (view.highlightLine) + view.highlightLine(line); + } + return true; + }, + + _showResourceView: function(resource) + { + var view = WebInspector.ResourceManager.resourceViewForResource(resource); + view.headersVisible = false; + this._innerShowView(view); + }, + showDatabase: function(database, tableName) { if (!database) return; - if (this.visibleView) - this.visibleView.hide(); - var view; if (tableName) { if (!("_tableViews" in database)) @@ -199,7 +309,7 @@ WebInspector.StoragePanel.prototype = { } } - this._genericViewSetup(view); + this._innerShowView(view); }, showDOMStorage: function(domStorage) @@ -207,9 +317,6 @@ WebInspector.StoragePanel.prototype = { if (!domStorage) return; - if (this.visibleView) - this.visibleView.hide(); - var view; view = domStorage._domStorageView; if (!view) { @@ -217,42 +324,47 @@ WebInspector.StoragePanel.prototype = { domStorage._domStorageView = view; } - this._genericViewSetup(view); + this._innerShowView(view); }, showCookies: function(treeElement, cookieDomain) { - if (this.visibleView) - this.visibleView.hide(); - var view = this._cookieViews[cookieDomain]; if (!view) { view = new WebInspector.CookieItemsView(treeElement, cookieDomain); this._cookieViews[cookieDomain] = view; } - this._genericViewSetup(view); + this._innerShowView(view); }, showApplicationCache: function(treeElement, appcacheDomain) { - if (this.visibleView) - this.visibleView.hide(); - var view = this._applicationCacheView; if (!view) { view = new WebInspector.ApplicationCacheItemsView(treeElement, appcacheDomain); this._applicationCacheView = view; } - this._genericViewSetup(view); + this._innerShowView(view); if ("_cachedApplicationCacheViewStatus" in this) this._applicationCacheView.updateStatus(this._cachedApplicationCacheViewStatus); }, - _genericViewSetup: function(view) + showCategoryView: function(categoryName) + { + if (!this._categoryView) + this._categoryView = new WebInspector.StorageCategoryView(); + this._categoryView.setText(categoryName); + this._innerShowView(this._categoryView); + }, + + _innerShowView: function(view) { + if (this.visibleView) + this.visibleView.hide(); + view.show(this.storageViews); this.visibleView = view; @@ -418,201 +530,413 @@ WebInspector.StoragePanel.prototype = { this.storageViews.style.left = width + "px"; this.storageViewStatusBarItemsContainer.style.left = width + "px"; this.resize(); - } -} + }, -WebInspector.StoragePanel.prototype.__proto__ = WebInspector.Panel.prototype; + get searchableViews() + { + var views = []; -WebInspector.DatabaseSidebarTreeElement = function(database) -{ - this.database = database; + if (!Preferences.networkPanelEnabled) + return views; - WebInspector.SidebarTreeElement.call(this, "database-sidebar-tree-item", "", "", database, true); + const visibleView = this.visibleView; + if (visibleView instanceof WebInspector.ResourceView && visibleView.performSearch) + views.push(visibleView); - this.refreshTitles(); -} + function callback(resourceTreeElement) + { + var resource = resourceTreeElement._resource; + var resourceView = WebInspector.ResourceManager.resourceViewForResource(resource); + if (resourceView.performSearch && resourceView !== visibleView) + views.push(resourceView); + } + this._forAllResourceTreeElements(callback); + return views; + }, -WebInspector.DatabaseSidebarTreeElement.prototype = { - onselect: function() + _forAllResourceTreeElements: function(callback) { - WebInspector.panels.storage.showDatabase(this.database); + var stop = false; + for (var treeElement = this.resourcesListTreeElement; !stop && treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.resourcesListTreeElement, true)) { + if (treeElement instanceof WebInspector.FrameResourceTreeElement) + stop = callback(treeElement); + } }, - oncollapse: function() + searchMatchFound: function(view, matches) { - // Request a refresh after every collapse so the next - // expand will have an updated table list. - this.shouldRefreshChildren = true; + if (!view.resource) + return; + var treeElement = this._findTreeElementForResource(view.resource); + if (treeElement) + treeElement.searchMatchFound(matches); }, - onpopulate: function() + _findTreeElementForResource: function(resource) { - this.removeChildren(); + function isAncestor(ancestor, object) + { + console.error("There should be no calls to isAncestor, but there was one for ", object); + return false; + } - var self = this; - function tableNamesCallback(tableNames) + function getParent(object) { - var tableNamesLength = tableNames.length; - for (var i = 0; i < tableNamesLength; ++i) - self.appendChild(new WebInspector.SidebarDatabaseTableTreeElement(self.database, tableNames[i])); + console.error("There should be no calls to getParent, but there was one for ", object); + return null; + } + + return this.sidebarTree.findTreeElement(resource, isAncestor, getParent); + }, + + searchCanceled: function(startingNewSearch) + { + WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch); + + if (startingNewSearch) + return; + + function callback(resourceTreeElement) + { + resourceTreeElement._errorsWarningsUpdated(); + } + this._forAllResourceTreeElements(callback); + }, + + performSearch: function(query) + { + function callback(resourceTreeElement) + { + resourceTreeElement._resetBubble(); } - this.database.getTableNames(tableNamesCallback); + this._forAllResourceTreeElements(callback); + WebInspector.Panel.prototype.performSearch.call(this, query); }, - get mainTitle() + showView: function(view) + { + if (view) + this.showResource(view.resource); + } +} + +WebInspector.StoragePanel.prototype.__proto__ = WebInspector.Panel.prototype; + +WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClass, hasChildren) +{ + TreeElement.call(this, "", representedObject, hasChildren); + this._storagePanel = storagePanel; + this._titleText = title; + this._iconClass = iconClass; +} + +WebInspector.BaseStorageTreeElement.prototype = { + onattach: function() { - return this.database.name; + this.listItemElement.removeChildren(); + this.listItemElement.addStyleClass(this._iconClass); + + var selectionElement = document.createElement("div"); + selectionElement.className = "selection"; + this.listItemElement.appendChild(selectionElement); + + this.imageElement = document.createElement("img"); + this.imageElement.className = "icon"; + this.listItemElement.appendChild(this.imageElement); + + this.titleElement = document.createElement("div"); + this.titleElement.className = "base-storage-tree-element-title"; + this.titleElement.textContent = this._titleText; + this.listItemElement.appendChild(this.titleElement); }, - set mainTitle(x) + onreveal: function() { - // Do nothing. + if (this.listItemElement) + this.listItemElement.scrollIntoViewIfNeeded(false); }, - get subtitle() + set titleText(titleText) { - return this.database.displayDomain; + this._titleText = titleText; + this.titleElement.textContent = this._titleText; }, - set subtitle(x) + isEventWithinDisclosureTriangle: function() { - // Do nothing. + // Override it since we use margin-left in place of treeoutline's text-indent. + // Hence we need to take padding into consideration. This all is needed for leading + // icons in the tree. + const paddingLeft = 14; + var left = this.listItemElement.totalOffsetLeft + paddingLeft; + return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren; } } -WebInspector.DatabaseSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype; +WebInspector.BaseStorageTreeElement.prototype.__proto__ = TreeElement.prototype; -WebInspector.SidebarDatabaseTableTreeElement = function(database, tableName) +WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, iconClass) { - this.database = database; - this.tableName = tableName; - - WebInspector.SidebarTreeElement.call(this, "database-table-sidebar-tree-item small", tableName, "", null, false); + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClass, true); + this._categoryName = categoryName; } -WebInspector.SidebarDatabaseTableTreeElement.prototype = { +WebInspector.StorageCategoryTreeElement.prototype = { onselect: function() { - WebInspector.panels.storage.showDatabase(this.database, this.tableName); + this._storagePanel.showCategoryView(this._categoryName); } } +WebInspector.StorageCategoryTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; -WebInspector.SidebarDatabaseTableTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype; - -WebInspector.DOMStorageSidebarTreeElement = function(domStorage, className) +WebInspector.FrameTreeElement = function(storagePanel, frameId, displayName) { + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, "frame-storage-tree-item"); + this._frameId = frameId; + this._displayName = displayName; +} - this.domStorage = domStorage; +WebInspector.FrameTreeElement.prototype = { + onselect: function() + { + this._storagePanel.showCategoryView(this._displayName); + }, - WebInspector.SidebarTreeElement.call(this, "domstorage-sidebar-tree-item " + className, domStorage, "", null, false); + get displayName() + { + return this._displayName; + }, - this.refreshTitles(); + set displayName(displayName) + { + this._displayName = displayName; + this.titleText = displayName; + } +} +WebInspector.FrameTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; + +WebInspector.FrameResourceTreeElement = function(storagePanel, resource) +{ + WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, "resource-sidebar-tree-item resources-category-" + resource.category.name); + this._resource = resource; + this._resource.addEventListener("errors-warnings-updated", this._errorsWarningsUpdated, this); + this.tooltip = resource.url; } -WebInspector.DOMStorageSidebarTreeElement.prototype = { +WebInspector.FrameResourceTreeElement.prototype = { onselect: function() { - WebInspector.panels.storage.showDOMStorage(this.domStorage); + this._storagePanel._showResourceView(this._resource); }, - get mainTitle() + ondblclick: function(event) { - return this.domStorage.domain ? this.domStorage.domain : WebInspector.UIString("Local Files"); + InspectorBackend.openInInspectedWindow(this._resource.url); }, - set mainTitle(x) + onattach: function() { - // Do nothing. + WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); + + if (this._resource.category === WebInspector.resourceCategories.images) { + var previewImage = document.createElement("img"); + previewImage.className = "image-resource-icon-preview"; + previewImage.src = this._resource.url; + + var iconElement = document.createElement("div"); + iconElement.className = "icon"; + iconElement.appendChild(previewImage); + this.listItemElement.replaceChild(iconElement, this.imageElement); + } + + this._statusElement = document.createElement("div"); + this._statusElement.className = "status"; + this.listItemElement.insertBefore(this._statusElement, this.titleElement); + + this.listItemElement.draggable = true; + this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false); }, - get subtitle() + _ondragstart: function(event) { - return ""; //this.database.displayDomain; + event.dataTransfer.setData("text/plain", this._resource.url); + event.dataTransfer.setData("text/uri-list", this._resource.url + "\r\n"); + event.dataTransfer.effectAllowed = "copy"; + return true; + }, + + _setBubbleText: function(x) + { + if (!this._bubbleElement) { + this._bubbleElement = document.createElement("div"); + this._bubbleElement.className = "bubble"; + this._statusElement.appendChild(this._bubbleElement); + } + + this._bubbleElement.textContent = x; + }, + + _resetBubble: function() + { + if (this._bubbleElement) { + this._bubbleElement.textContent = ""; + this._bubbleElement.removeStyleClass("search-matches"); + this._bubbleElement.removeStyleClass("warning"); + this._bubbleElement.removeStyleClass("error"); + } + }, + + searchMatchFound: function(matches) + { + this._resetBubble(); + + this._setBubbleText(matches); + this._bubbleElement.addStyleClass("search-matches"); + + // Expand, do not scroll into view. + var currentAncestor = this.parent; + while (currentAncestor && !currentAncestor.root) { + if (!currentAncestor.expanded) + currentAncestor.expand(); + currentAncestor = currentAncestor.parent; + } }, - set subtitle(x) + _errorsWarningsUpdated: function() { - // Do nothing. + // FIXME: move to the Script/SourceView. + if (!this._resource.warnings && !this._resource.errors) { + var view = WebInspector.ResourceManager.existingResourceViewForResource(this._resource); + if (view && view.clearMessages) + view.clearMessages(); + } + + if (this._storagePanel.currentQuery) + return; + + this._resetBubble(); + + if (this._resource.warnings || this._resource.errors) + this._setBubbleText(this._resource.warnings + this._resource.errors); + + if (this._resource.warnings) + this._bubbleElement.addStyleClass("warning"); + + if (this._resource.errors) + this._bubbleElement.addStyleClass("error"); } } -WebInspector.DOMStorageSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype; +WebInspector.FrameResourceTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; -WebInspector.CookieSidebarTreeElement = function(cookieDomain) +WebInspector.DatabaseTreeElement = function(storagePanel, database) { - WebInspector.SidebarTreeElement.call(this, "cookie-sidebar-tree-item", cookieDomain, "", null, false); - this._cookieDomain = cookieDomain; - this._subtitle = ""; - - this.refreshTitles(); + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, "database-storage-tree-item", true); + this._database = database; } -WebInspector.CookieSidebarTreeElement.prototype = { +WebInspector.DatabaseTreeElement.prototype = { onselect: function() { - WebInspector.panels.storage.showCookies(this, this._cookieDomain); + this._storagePanel.showDatabase(this._database); }, - get mainTitle() + oncollapse: function() { - return this._cookieDomain ? this._cookieDomain : WebInspector.UIString("Local Files"); + // Request a refresh after every collapse so the next + // expand will have an updated table list. + this.shouldRefreshChildren = true; }, - set mainTitle(x) + onpopulate: function() { - // Do nothing. - }, + this.removeChildren(); + + function tableNamesCallback(tableNames) + { + var tableNamesLength = tableNames.length; + for (var i = 0; i < tableNamesLength; ++i) + this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i])); + } + this._database.getTableNames(tableNamesCallback.bind(this)); + } + +} +WebInspector.DatabaseTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; + +WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName) +{ + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, "database-storage-tree-item"); + this._database = database; + this._tableName = tableName; +} - get subtitle() +WebInspector.DatabaseTableTreeElement.prototype = { + onselect: function() { - return this._subtitle; - }, + this._storagePanel.showDatabase(this._database, this._tableName); + } +} +WebInspector.DatabaseTableTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; + +WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className) +{ + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.domain ? domStorage.domain : WebInspector.UIString("Local Files"), "domstorage-storage-tree-item " + className); + this._domStorage = domStorage; +} - set subtitle(x) +WebInspector.DOMStorageTreeElement.prototype = { + onselect: function() { - this._subtitle = x; - this.refreshTitles(); + this._storagePanel.showDOMStorage(this._domStorage); } } +WebInspector.DOMStorageTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; -WebInspector.CookieSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype; +WebInspector.CookieTreeElement = function(storagePanel, cookieDomain) +{ + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), "cookie-storage-tree-item"); + this._cookieDomain = cookieDomain; +} -WebInspector.ApplicationCacheSidebarTreeElement = function(appcacheDomain) +WebInspector.CookieTreeElement.prototype = { + onselect: function() + { + this._storagePanel.showCookies(this, this._cookieDomain); + } +} +WebInspector.CookieTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; + +WebInspector.ApplicationCacheTreeElement = function(storagePanel, appcacheDomain) { - WebInspector.SidebarTreeElement.call(this, "application-cache-sidebar-tree-item", appcacheDomain, "", null, false); + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, appcacheDomain ? appcacheDomain : WebInspector.UIString("Local Files"), "application-cache-storage-tree-item"); this._appcacheDomain = appcacheDomain; - this._subtitle = ""; - this._mainTitle = this._appcacheDomain; - this.refreshTitles(); } -WebInspector.ApplicationCacheSidebarTreeElement.prototype = { +WebInspector.ApplicationCacheTreeElement.prototype = { onselect: function() { - WebInspector.panels.storage.showApplicationCache(this, this._appcacheDomain); - }, + this._storagePanel.showApplicationCache(this, this._appcacheDomain); + } +} +WebInspector.ApplicationCacheTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; - get mainTitle() - { - return this._mainTitle; - }, +WebInspector.StorageCategoryView = function() +{ + WebInspector.View.call(this); - set mainTitle(x) - { - this._mainTitle = x; - this.refreshTitles(); - }, + this.element.addStyleClass("storage-view"); - get subtitle() - { - return this._subtitle; - }, + this._emptyMsgElement = document.createElement("div"); + this._emptyMsgElement.className = "storage-empty-view"; + this.element.appendChild(this._emptyMsgElement); +} - set subtitle(x) +WebInspector.StorageCategoryView.prototype = { + setText: function(text) { - this._subtitle = x; - this.refreshTitles(); + this._emptyMsgElement.textContent = text; } } -WebInspector.ApplicationCacheSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype; +WebInspector.StorageCategoryView.prototype.__proto__ = WebInspector.View.prototype; diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js index 36d854c..cc97520 100644 --- a/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/WebCore/inspector/front-end/StylesSidebarPane.js @@ -60,7 +60,13 @@ WebInspector.StylesSidebarPane = function(computedStylePane) this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false); this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false); - WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this); + var format = WebInspector.applicationSettings.colorFormat; + if (format === "hex") + this.settingsSelectElement[0].selected = true; + else if (format === "rgb") + this.settingsSelectElement[1].selected = true; + else if (format === "hsl") + this.settingsSelectElement[2].selected = true; this.titleElement.appendChild(this.settingsSelectElement); this._computedStylePane = computedStylePane; @@ -95,17 +101,6 @@ WebInspector.StylesSidebarPane.PseudoIdNames = [ ]; WebInspector.StylesSidebarPane.prototype = { - _settingsLoaded: function() - { - var format = WebInspector.applicationSettings.colorFormat; - if (format === "hex") - this.settingsSelectElement[0].selected = true; - if (format === "rgb") - this.settingsSelectElement[1].selected = true; - if (format === "hsl") - this.settingsSelectElement[2].selected = true; - }, - _contextMenuEventFired: function(event) { var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link"); @@ -160,7 +155,7 @@ WebInspector.StylesSidebarPane.prototype = { if (refresh) WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this)); else - WebInspector.cssModel.getStylesAsync(node.id, !WebInspector.applicationSettings.showUserAgentStyles, stylesCallback.bind(this)); + WebInspector.cssModel.getStylesAsync(node.id, stylesCallback.bind(this)); }, _refreshUpdate: function(node, computedStyle, editedSection) @@ -201,8 +196,8 @@ WebInspector.StylesSidebarPane.prototype = { // Add rules in reverse order to match the cascade order. for (var j = pseudoElementCSSRules.rules.length - 1; j >= 0; --j) { - var rule = WebInspector.CSSStyleDeclaration.parseRule(pseudoElementCSSRules.rules[j]); - styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet, rule: rule }); + var rule = pseudoElementCSSRules.rules[j]; + styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule }); } usedProperties = {}; disabledComputedProperties = {}; @@ -213,7 +208,7 @@ WebInspector.StylesSidebarPane.prototype = { _refreshStyleRules: function(sections, computedStyle) { - var nodeComputedStyle = new WebInspector.CSSStyleDeclaration(computedStyle); + var nodeComputedStyle = computedStyle; var styleRules = []; for (var i = 0; sections && i < sections.length; ++i) { var section = sections[i]; @@ -229,7 +224,7 @@ WebInspector.StylesSidebarPane.prototype = { _rebuildStyleRules: function(node, styles) { - var nodeComputedStyle = new WebInspector.CSSStyleDeclaration(styles.computedStyle); + var nodeComputedStyle = styles.computedStyle; this.sections = {}; var styleRules = []; @@ -238,7 +233,7 @@ WebInspector.StylesSidebarPane.prototype = { var styleAttributes = {}; for (var name in styles.styleAttributes) { - var attrStyle = { style: new WebInspector.CSSStyleDeclaration(styles.styleAttributes[name]), editable: false }; + var attrStyle = { style: styles.styleAttributes[name], editable: false }; attrStyle.selectorText = WebInspector.panels.elements.treeOutline.nodeNameToCorrectCase(node.nodeName) + "[" + name; if (node.getAttribute(name)) attrStyle.selectorText += "=" + node.getAttribute(name); @@ -248,7 +243,7 @@ WebInspector.StylesSidebarPane.prototype = { // Show element's Style Attributes if (styles.inlineStyle && node.nodeType === Node.ELEMENT_NODE) { - var inlineStyle = { selectorText: "element.style", style: new WebInspector.CSSStyleDeclaration(styles.inlineStyle), isAttribute: true }; + var inlineStyle = { selectorText: "element.style", style: styles.inlineStyle, isAttribute: true }; styleRules.push(inlineStyle); } @@ -256,12 +251,11 @@ WebInspector.StylesSidebarPane.prototype = { if (styles.matchedCSSRules.length) styleRules.push({ isStyleSeparator: true, text: WebInspector.UIString("Matched CSS Rules") }); for (var i = styles.matchedCSSRules.length - 1; i >= 0; --i) { - var rule = WebInspector.CSSStyleDeclaration.parseRule(styles.matchedCSSRules[i]); - styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet, rule: rule }); + var rule = styles.matchedCSSRules[i]; + styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule }); } // Walk the node structure and identify styles with inherited properties. - var parentStyles = styles.parent; var parentNode = node.parentNode; function insertInheritedNodeSeparator(node) { @@ -271,11 +265,12 @@ WebInspector.StylesSidebarPane.prototype = { styleRules.push(entry); } - while (parentStyles) { + for (var parentOrdinal = 0; parentOrdinal < styles.inherited.length; ++parentOrdinal) { + var parentStyles = styles.inherited[parentOrdinal]; var separatorInserted = false; if (parentStyles.inlineStyle) { if (this._containsInherited(parentStyles.inlineStyle)) { - var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: new WebInspector.CSSStyleDeclaration(parentStyles.inlineStyle), isAttribute: true, isInherited: true }; + var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: parentStyles.inlineStyle, isAttribute: true, isInherited: true }; if (!separatorInserted) { insertInheritedNodeSeparator(parentNode); separatorInserted = true; @@ -288,14 +283,13 @@ WebInspector.StylesSidebarPane.prototype = { var rulePayload = parentStyles.matchedCSSRules[i]; if (!this._containsInherited(rulePayload.style)) continue; - var rule = WebInspector.CSSStyleDeclaration.parseRule(rulePayload); + var rule = rulePayload; if (!separatorInserted) { insertInheritedNodeSeparator(parentNode); separatorInserted = true; } - styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet, rule: rule, isInherited: true }); + styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, isInherited: true }); } - parentStyles = parentStyles.parent; parentNode = parentNode.parentNode; } return styleRules; @@ -303,18 +297,6 @@ WebInspector.StylesSidebarPane.prototype = { _markUsedProperties: function(styleRules, usedProperties, disabledComputedProperties) { - function deleteDisabledProperty(style, name) - { - if (!style || !name) - return; - if (style.__disabledPropertyValues) - delete style.__disabledPropertyValues[name]; - if (style.__disabledPropertyPriorities) - delete style.__disabledPropertyPriorities[name]; - if (style.__disabledProperties) - delete style.__disabledProperties[name]; - } - var priorityUsed = false; // Walk the style rules and make a list of all used and overloaded properties. @@ -328,10 +310,14 @@ WebInspector.StylesSidebarPane.prototype = { styleRule.usedProperties = {}; var style = styleRule.style; - for (var j = 0; j < style.length; ++j) { - var name = style[j]; + var allProperties = style.allProperties; + for (var j = 0; j < allProperties.length; ++j) { + var property = allProperties[j]; + if (!property.isLive) + continue; + var name = property.name; - if (!priorityUsed && style.getPropertyPriority(name).length) + if (!priorityUsed && property.priority.length) priorityUsed = true; // If the property name is already used by another rule then this rule's @@ -350,22 +336,12 @@ WebInspector.StylesSidebarPane.prototype = { styleRule.usedProperties["font-weight"] = true; styleRule.usedProperties["line-height"] = true; } - - // Delete any disabled properties, since the property does exist. - // This prevents it from showing twice. - deleteDisabledProperty(style, name); - deleteDisabledProperty(style, style.getPropertyShorthand(name)); } // Add all the properties found in this style to the used properties list. // Do this here so only future rules are affect by properties used in this rule. for (var name in styleRules[i].usedProperties) usedProperties[name] = true; - - // Remember all disabled properties so they show up in computed style. - if (style.__disabledProperties) - for (var name in style.__disabledProperties) - disabledComputedProperties[name] = true; } if (priorityUsed) { @@ -378,9 +354,13 @@ WebInspector.StylesSidebarPane.prototype = { continue; var style = styleRules[i].style; - for (var j = 0; j < style.length; ++j) { - var name = style[j]; - if (style.getPropertyPriority(name).length) { + var allProperties = style.allProperties; + for (var j = 0; j < allProperties.length; ++j) { + var property = allProperties[j]; + if (!property.isLive) + continue; + var name = property.name; + if (property.priority.length) { if (!(name in foundPriorityProperties)) styleRules[i].usedProperties[name] = true; else @@ -464,21 +444,13 @@ WebInspector.StylesSidebarPane.prototype = { return sections; }, - _containsInherited: function(payload) - { - if (this._arrayContainsInheritedProperty(payload.properties)) - return true; - if (payload.disabled && this._arrayContainsInheritedProperty(payload.disabled)) - return true; - return false; - }, - - _arrayContainsInheritedProperty: function(properties) + _containsInherited: function(style) { + var properties = style.allProperties; for (var i = 0; i < properties.length; ++i) { var property = properties[i]; // Does this style contain non-overridden inherited property? - if (property.name in WebInspector.StylesSidebarPane.InheritedProperties) + if (property.isLive && property.name in WebInspector.StylesSidebarPane.InheritedProperties) return true; } return false; @@ -590,16 +562,11 @@ WebInspector.ComputedStyleSidebarPane = function() var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited"), "sidebar-pane-subtitle"); this.titleElement.appendChild(showInheritedCheckbox.element); - function settingsLoaded() - { - if (WebInspector.applicationSettings.showInheritedComputedStyleProperties) { - this.bodyElement.addStyleClass("show-inherited"); - showInheritedCheckbox.checked = true; - } + if (WebInspector.applicationSettings.showInheritedComputedStyleProperties) { + this.bodyElement.addStyleClass("show-inherited"); + showInheritedCheckbox.checked = true; } - WebInspector.applicationSettings.addEventListener("loaded", settingsLoaded.bind(this)); - function showInheritedToggleFunction(event) { WebInspector.applicationSettings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked; @@ -661,16 +628,16 @@ WebInspector.StylePropertiesSection = function(styleRule, editable, isInherited, } var subtitle = ""; - if (this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.href) - this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.parentStyleSheet.href, this.rule.sourceLine)); + if (this.styleRule.sourceURL) + this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.sourceURL, this.rule.sourceLine)); else if (isUserAgent) subtitle = WebInspector.UIString("user agent stylesheet"); else if (isUser) subtitle = WebInspector.UIString("user stylesheet"); else if (isViaInspector) subtitle = WebInspector.UIString("via inspector"); - else if (this.rule && this.rule.documentURL) - this.subtitleElement.appendChild(linkifyUncopyable(this.rule.documentURL, this.rule.sourceLine)); + else if (this.rule && this.rule.sourceURL) + this.subtitleElement.appendChild(linkifyUncopyable(this.rule.sourceURL, this.rule.sourceLine)); if (isInherited) this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style. @@ -691,49 +658,42 @@ WebInspector.StylePropertiesSection.prototype = { // Overriding with empty body. }, - isPropertyInherited: function(property) + isPropertyInherited: function(propertyName) { if (this.isInherited) { // While rendering inherited stylesheet, reverse meaning of this property. // Render truly inherited properties with black, i.e. return them as non-inherited. - return !(property in WebInspector.StylesSidebarPane.InheritedProperties); + return !(propertyName in WebInspector.StylesSidebarPane.InheritedProperties); } return false; }, - isPropertyOverloaded: function(property, shorthand) + isPropertyOverloaded: function(propertyName, shorthand) { if (!this._usedProperties || this.noAffect) return false; - if (this.isInherited && !(property in WebInspector.StylesSidebarPane.InheritedProperties)) { + if (this.isInherited && !(propertyName in WebInspector.StylesSidebarPane.InheritedProperties)) { // In the inherited sections, only show overrides for the potentially inherited properties. return false; } - var used = (property in this._usedProperties); + var used = (propertyName in this._usedProperties); if (used || !shorthand) return !used; // Find out if any of the individual longhand properties of the shorthand // are used, if none are then the shorthand is overloaded too. - var longhandProperties = this.styleRule.style.getLonghandProperties(property); + var longhandProperties = this.styleRule.style.getLonghandProperties(propertyName); for (var j = 0; j < longhandProperties.length; ++j) { var individualProperty = longhandProperties[j]; - if (individualProperty in this._usedProperties) + if (individualProperty.name in this._usedProperties) return false; } return true; }, - isPropertyDisabled: function(property) - { - if (!this.styleRule.style.__disabledPropertyValues) - return false; - return property in this.styleRule.style.__disabledPropertyValues; - }, - update: function(full) { if (full) { @@ -759,39 +719,56 @@ WebInspector.StylePropertiesSection.prototype = { onpopulate: function() { + function sorter(a, b) + { + return a.name.localeCompare(b.name); + } + var style = this.styleRule.style; - var foundShorthands = {}; - var disabledProperties = style.__disabledPropertyValues || {}; + var handledProperties = {}; + var shorthandNames = {}; this.uniqueProperties = []; - for (var i = 0; i < style.length; ++i) - this.uniqueProperties.push(style[i]); + var allProperties = style.allProperties; + for (var i = 0; i < allProperties.length; ++i) + this.uniqueProperties.push(allProperties[i]); - for (var name in disabledProperties) - this.uniqueProperties.push(name); + this.uniqueProperties.sort(sorter); - this.uniqueProperties.sort(); + // Collect all shorthand names. + for (var i = 0; i < this.uniqueProperties.length; ++i) { + var property = this.uniqueProperties[i]; + if (property.disabled) + continue; + if (property.shorthand) + shorthandNames[property.shorthand] = true; + } for (var i = 0; i < this.uniqueProperties.length; ++i) { - var name = this.uniqueProperties[i]; - var disabled = name in disabledProperties; - var shorthand = !disabled ? style.getPropertyShorthand(name) : null; + var property = this.uniqueProperties[i]; + var disabled = property.disabled; + if (!disabled && this.disabledComputedProperties && !(property.name in this.usedProperties) && property.name in this.disabledComputedProperties) + disabled = true; - if (shorthand && shorthand in foundShorthands) + var shorthand = !disabled ? property.shorthand : null; + + if (shorthand && shorthand in handledProperties) continue; if (shorthand) { - foundShorthands[shorthand] = true; - name = shorthand; + property = style.getLiveProperty(shorthand); + if (!property) + property = new WebInspector.CSSProperty(style, style.allProperties.length, shorthand, style.getShorthandValue(shorthand), style.getShorthandPriority(shorthand), "style", true, true, ""); } - var isShorthand = (shorthand ? true : false); - var inherited = this.isPropertyInherited(name); - var overloaded = this.isPropertyOverloaded(name, isShorthand); + var isShorthand = !!(property.isLive && (shorthand || shorthandNames[property.name])); + var inherited = this.isPropertyInherited(property.name); + var overloaded = this.isPropertyOverloaded(property.name, isShorthand); - var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, name, isShorthand, inherited, overloaded, disabled); + var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, isShorthand, inherited, overloaded); this.propertiesTreeOutline.appendChild(item); + handledProperties[property.name] = property; } }, @@ -808,7 +785,9 @@ WebInspector.StylePropertiesSection.prototype = { addNewBlankProperty: function() { - var item = new WebInspector.StylePropertyTreeElement(this.styleRule, this.styleRule.style, "", false, false, false, false); + var style = this.styleRule.style; + var property = new WebInspector.CSSProperty(style, style.allProperties.length, "", "", "", "style", true, false, false, undefined); + var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, false, false, false); this.propertiesTreeOutline.appendChild(item); item.listItemElement.textContent = ""; item._newProperty = true; @@ -894,7 +873,7 @@ WebInspector.StylePropertiesSection.prototype = { } self.rule = newRule; - self.styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, parentStyleSheet: newRule.parentStyleSheet, rule: newRule }; + self.styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.sourceURL, rule: newRule }; var oldIdentifier = this.identifier; self.identifier = newRule.selectorText + ":" + self.subtitleElement.textContent; @@ -937,9 +916,9 @@ WebInspector.ComputedStylePropertiesSection.prototype = { // Overriding with empty body. }, - _isPropertyInherited: function(property) + _isPropertyInherited: function(propertyName) { - return !(property in this._usedProperties) && !(property in this._alwaysShowComputedProperties) && !(property in this._disabledComputedProperties); + return !(propertyName in this._usedProperties) && !(propertyName in this._alwaysShowComputedProperties) && !(propertyName in this._disabledComputedProperties); }, update: function() @@ -956,19 +935,25 @@ WebInspector.ComputedStylePropertiesSection.prototype = { onpopulate: function() { + function sorter(a, b) + { + return a.name.localeCompare(b.name); + } + var style = this.styleRule.style; var uniqueProperties = []; - for (var i = 0; i < style.length; ++i) - uniqueProperties.push(style[i]); - uniqueProperties.sort(); + var allProperties = style.allProperties; + for (var i = 0; i < allProperties.length; ++i) + uniqueProperties.push(allProperties[i]); + uniqueProperties.sort(sorter); this._propertyTreeElements = {}; for (var i = 0; i < uniqueProperties.length; ++i) { - var name = uniqueProperties[i]; - var inherited = this._isPropertyInherited(name); - var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, name, false, inherited, false, false); + var property = uniqueProperties[i]; + var inherited = this._isPropertyInherited(property.name); + var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, false, inherited, false); this.propertiesTreeOutline.appendChild(item); - this._propertyTreeElements[name] = item; + this._propertyTreeElements[property.name] = item; } }, @@ -980,21 +965,21 @@ WebInspector.ComputedStylePropertiesSection.prototype = { continue; for (var j = 0; j < section.uniqueProperties.length; ++j) { - var name = section.uniqueProperties[j]; - if (section.isPropertyDisabled(name)) + var property = section.uniqueProperties[j]; + if (property.disabled) continue; - if (section.isInherited && !(name in WebInspector.StylesSidebarPane.InheritedProperties)) + if (section.isInherited && !(property.name in WebInspector.StylesSidebarPane.InheritedProperties)) continue; - var treeElement = this._propertyTreeElements[name]; + var treeElement = this._propertyTreeElements[property.name]; if (treeElement) { var selectorText = section.styleRule.selectorText; - var value = section.styleRule.style.getPropertyValue(name); + var value = property.value; var title = "<span style='color: gray'>" + selectorText + "</span> - " + value; var subtitle = " <span style='float:right'>" + section.subtitleElement.innerHTML + "</span>"; var childElement = new TreeElement(title + subtitle, null, false); treeElement.appendChild(childElement); - if (section.isPropertyOverloaded(name)) + if (section.isPropertyOverloaded(property.name)) childElement.listItemElement.addStyleClass("overloaded"); } } @@ -1060,15 +1045,14 @@ WebInspector.BlankStylePropertiesSection.prototype = { WebInspector.BlankStylePropertiesSection.prototype.__proto__ = WebInspector.StylePropertiesSection.prototype; -WebInspector.StylePropertyTreeElement = function(styleRule, style, name, shorthand, inherited, overloaded, disabled) +WebInspector.StylePropertyTreeElement = function(styleRule, style, property, shorthand, inherited, overloaded) { this._styleRule = styleRule; this.style = style; - this.name = name; + this.property = property; this.shorthand = shorthand; this._inherited = inherited; this._overloaded = overloaded; - this._disabled = disabled; // Pass an empty title, the title gets made later in onattach. TreeElement.call(this, "", null, shorthand); @@ -1103,29 +1087,31 @@ WebInspector.StylePropertyTreeElement.prototype = { get disabled() { - return this._disabled; + return this.property.disabled; }, - set disabled(x) + get name() { - if (x === this._disabled) - return; - this._disabled = x; - this.updateState(); + return this.property.name; }, get priority() { - if (this.disabled && this.style.__disabledPropertyPriorities && this.name in this.style.__disabledPropertyPriorities) - return this.style.__disabledPropertyPriorities[this.name]; - return (this.shorthand ? this.style.getShorthandPriority(this.name) : this.style.getPropertyPriority(this.name)); + if (this.disabled) + return this.property.priority; + return (this.shorthand ? this.style.getShorthandPriority(this.name) : this.property.priority); }, get value() { - if (this.disabled && this.style.__disabledPropertyValues && this.name in this.style.__disabledPropertyValues) - return this.style.__disabledPropertyValues[this.name]; - return (this.shorthand ? this.style.getShorthandValue(this.name) : this.style.getPropertyValue(this.name)); + if (this.disabled) + return this.property.value; + return (this.shorthand ? this.style.getShorthandValue(this.name) : this.property.value); + }, + + get parsedOk() + { + return this.property.parsedOk; }, onattach: function() @@ -1145,11 +1131,14 @@ WebInspector.StylePropertyTreeElement.prototype = { this.updateState(); - var enabledCheckboxElement = document.createElement("input"); - enabledCheckboxElement.className = "enabled-button"; - enabledCheckboxElement.type = "checkbox"; - enabledCheckboxElement.checked = !this.disabled; - enabledCheckboxElement.addEventListener("change", this.toggleEnabled.bind(this), false); + var enabledCheckboxElement; + if (this.parsedOk) { + enabledCheckboxElement = document.createElement("input"); + enabledCheckboxElement.className = "enabled-button"; + enabledCheckboxElement.type = "checkbox"; + enabledCheckboxElement.checked = !this.disabled; + enabledCheckboxElement.addEventListener("change", this.toggleEnabled.bind(this), false); + } var nameElement = document.createElement("span"); nameElement.className = "webkit-css-property"; @@ -1186,7 +1175,8 @@ WebInspector.StylePropertyTreeElement.prototype = { { var container = document.createDocumentFragment(); container.appendChild(document.createTextNode("url(")); - container.appendChild(WebInspector.linkifyURLAsNode(url, url, null, (url in WebInspector.resourceURLMap))); + var hasResource = !!WebInspector.resourceForURL(url); + container.appendChild(WebInspector.linkifyURLAsNode(url, url, null, hasResource)); container.appendChild(document.createTextNode(")")); return container; } @@ -1297,7 +1287,7 @@ WebInspector.StylePropertyTreeElement.prototype = { return; // Append the checkbox for root elements of an editable section. - if (this.treeOutline.section && this.treeOutline.section.editable && this.parent.root) + if (enabledCheckboxElement && this.treeOutline.section && this.treeOutline.section.editable && this.parent.root) this.listItemElement.appendChild(enabledCheckboxElement); this.listItemElement.appendChild(nameElement); this.listItemElement.appendChild(document.createTextNode(": ")); @@ -1310,7 +1300,7 @@ WebInspector.StylePropertyTreeElement.prototype = { this.listItemElement.appendChild(document.createTextNode(";")); - this.tooltip = this.name + ": " + valueElement.textContent + (priority ? " " + priority : ""); + this.tooltip = this.property.propertyText; }, updateAll: function(updateAllRules) @@ -1322,33 +1312,28 @@ WebInspector.StylePropertyTreeElement.prototype = { else if (this.treeOutline.section) this.treeOutline.section.update(true); else - this.updateTitle(); // FIXME: this will not show new properties. But we don't hit his case yet. + this.updateTitle(); // FIXME: this will not show new properties. But we don't hit this case yet. }, toggleEnabled: function(event) { var disabled = !event.target.checked; - var self = this; function callback(newStyle) { if (!newStyle) return; - self.style = newStyle; - self._styleRule.style = self.style; - - // Set the disabled property here, since the code above replies on it not changing - // until after the value and priority are retrieved. - self.disabled = disabled; + this.style = newStyle; + this._styleRule.style = newStyle; - if (self.treeOutline.section && self.treeOutline.section.pane) - self.treeOutline.section.pane.dispatchEventToListeners("style property toggled"); + if (this.treeOutline.section && this.treeOutline.section.pane) + this.treeOutline.section.pane.dispatchEventToListeners("style property toggled"); - self.updateAll(true); + this.updateAll(true); } - WebInspector.cssModel.toggleStyleEnabled(this.style.id, this.name, disabled, callback); + this.property.setDisabled(disabled, callback.bind(this)); }, updateState: function() @@ -1385,14 +1370,16 @@ WebInspector.StylePropertyTreeElement.prototype = { var longhandProperties = this.style.getLonghandProperties(this.name); for (var i = 0; i < longhandProperties.length; ++i) { - var name = longhandProperties[i]; + var name = longhandProperties[i].name; + if (this.treeOutline.section) { var inherited = this.treeOutline.section.isPropertyInherited(name); var overloaded = this.treeOutline.section.isPropertyOverloaded(name); } - var item = new WebInspector.StylePropertyTreeElement(this._styleRule, this.style, name, false, inherited, overloaded); + var liveProperty = this.style.getLiveProperty(name); + var item = new WebInspector.StylePropertyTreeElement(this._styleRule, this.style, liveProperty, false, inherited, overloaded); this.appendChild(item); } }, @@ -1680,39 +1667,37 @@ WebInspector.StylePropertyTreeElement.prototype = { } } - var self = this; - - function failureCallback() + function callback(newStyle) { - // The user typed something, but it didn't parse. Just abort and restore - // the original title for this property. If this was a new attribute and - // we couldn't parse, then just remove it. - if (self._newProperty) { - self.parent.removeChild(self); + if (!newStyle) { + // The user typed something, but it didn't parse. Just abort and restore + // the original title for this property. If this was a new attribute and + // we couldn't parse, then just remove it. + if (this._newProperty) { + this.parent.removeChild(this); + return; + } + if (updateInterface) + this.updateTitle(); return; } - if (updateInterface) - self.updateTitle(); - } - function successCallback(newStyle) - { if (!styleTextLength) { // Do remove ourselves from UI when the property removal is confirmed. - self.parent.removeChild(self); + this.parent.removeChild(this); } else { - self.style = newStyle; - self._styleRule.style = self.style; + this.style = newStyle; + this._styleRule.style = this.style; } if (section && section.pane) section.pane.dispatchEventToListeners("style edited"); if (updateInterface) - self.updateAll(true); + this.updateAll(true); } - WebInspector.cssModel.applyStyleText(this.style.id, styleText, this.name, successCallback, failureCallback); + this.property.setText(styleText, callback.bind(this)); } } diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js index 28dad23..11b0e03 100644 --- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js +++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js @@ -31,11 +31,11 @@ WebInspector.WatchExpressionsSidebarPane = function() { WebInspector.SidebarPane.call(this, WebInspector.UIString("Watch Expressions")); - WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this); + this.reset(); } WebInspector.WatchExpressionsSidebarPane.prototype = { - _settingsLoaded: function() + reset: function() { this.bodyElement.removeChildren(); diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc index 1e5a508..481f8b3 100644 --- a/WebCore/inspector/front-end/WebKit.qrc +++ b/WebCore/inspector/front-end/WebKit.qrc @@ -158,6 +158,7 @@ <file>Images/excludeButtonGlyph.png</file> <file>Images/focusButtonGlyph.png</file> <file>Images/forward.png</file> + <file>Images/frame.png</file> <file>Images/gearButtonGlyph.png</file> <file>Images/glossyHeader.png</file> <file>Images/glossyHeaderPressed.png</file> diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css index 0662954..429e749 100644 --- a/WebCore/inspector/front-end/inspector.css +++ b/WebCore/inspector/front-end/inspector.css @@ -715,11 +715,6 @@ body.platform-linux .monospace, body.platform-linux .source-code { content: url(Images/treeDownTriangleBlack.png); } -.console-message.repeated-message > ol.stack-trace { - margin-top: -14px; - margin-left: 18px; -} - .console-group-messages .section .header .title { color: black; font-weight: normal; @@ -903,6 +898,29 @@ body.platform-linux .monospace, body.platform-linux .source-code { top: 20px; } +.resource-view .resource-view-cookies { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + overflow: auto; + padding: 12px; +} + +.resource-view.headers-visible .resource-view-cookies { + top: 20px; +} + +.resource-view-cookies.table .data-grid { + height: 100%; +} + +.resource-view-cookies .data-grid .row-group { + font-weight: bold; + font-size: 11px; +} + .webkit-line-gutter-backdrop { /* Keep this in sync with view-source.css (.webkit-line-gutter-backdrop) */ width: 31px; @@ -1190,7 +1208,6 @@ body.platform-linux .monospace, body.platform-linux .source-code { margin-left: -12px; } -.stack-trace li.parent::before, .outline-disclosure li.parent::before { content: url(Images/treeRightTriangleBlack.png); float: left; @@ -1200,32 +1217,26 @@ body.platform-linux .monospace, body.platform-linux .source-code { padding-right: 2px; } -.stack-trace li.parent::before, .outline-disclosure li.parent::before { content: url(Images/treeRightTriangleBlack.png); } -.stack-trace ol:focus li.parent.selected::before, .outline-disclosure ol:focus li.parent.selected::before { content: url(Images/treeRightTriangleWhite.png); } -.stack-trace li.parent.expanded::before, .outline-disclosure li.parent.expanded::before { content: url(Images/treeDownTriangleBlack.png); } -.stack-trace ol:focus li.parent.expanded.selected::before, .outline-disclosure ol:focus li.parent.expanded.selected::before { content: url(Images/treeDownTriangleWhite.png); } -.stack-trace ol.children, .outline-disclosure ol.children { display: none; } -.stack-trace ol.children.expanded, .outline-disclosure ol.children.expanded { display: block; } @@ -1430,21 +1441,17 @@ body.inactive .placard.selected { padding-bottom: 3px; } -.properties-tree ol, .stack-trace ol, ol.stack-trace { +.properties-tree ol { display: none; margin: 0; -webkit-padding-start: 12px; list-style: none; } -.properties-tree ol.expanded, .stack-trace ol, ol.stack-trace { +.properties-tree ol.expanded { display: block; } -ol.stack-trace { - -webkit-padding-start: 0px; -} - .event-listener-breakpoints .event-category { font-size: 12px; font-weight: bold; @@ -1897,27 +1904,31 @@ body.inactive .sidebar { background-color: rgb(232, 232, 232); } -.database-sidebar-tree-item .icon { +.frame-storage-tree-item .icon { + content: url(Images/frame.png); +} + +.database-storage-tree-item .icon { content: url(Images/database.png); } -.database-table-sidebar-tree-item .icon { +.database-table-storage-tree-item .icon { content: url(Images/databaseTable.png); } -.domstorage-sidebar-tree-item.local-storage .icon { +.domstorage-storage-tree-item.local-storage .icon { content: url(Images/localStorage.png); } -.domstorage-sidebar-tree-item.session-storage .icon { +.domstorage-storage-tree-item.session-storage .icon { content: url(Images/sessionStorage.png); } -.cookie-sidebar-tree-item .icon { +.cookie-storage-tree-item .icon { content: url(Images/cookie.png); } -.application-cache-sidebar-tree-item .icon { +.application-cache-storage-tree-item .icon { content: url(Images/applicationCache.png); } @@ -1929,6 +1940,72 @@ body.inactive .sidebar { bottom: 0; } +.storage.panel .sidebar { + padding-left: 0; + z-index: 10; +} + +.storage.panel .sidebar li { + height: 17px; + white-space: nowrap; + text-indent: 0; + margin-left: -2px; +} + +.storage.panel .sidebar li.parent { + text-indent: 0; + margin-left: -12px; +} + +.storage.panel .sidebar li.selected { + color: white; + text-shadow: rgba(0, 0, 0, 0.33) 0 1px 0; + font-weight: bold; +} + +.storage.panel .sidebar li .selection { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177))); + border-top: 1px solid #979797; + height: 17px; +} + +.storage.panel .sidebar :focus li .selection { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170))); + border-top: 1px solid rgb(68, 128, 200); +} + +body.inactive .storage.panel .sidebar li .selection { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138))); + border-top: 1px solid rgb(151, 151, 151); +} + +.storage.panel .sidebar .icon { + width: 16px; + height: 16px; + float: left; +} + +.storage.panel .base-storage-tree-element-title { + overflow: hidden; + position: relative; + text-overflow: ellipsis; + padding-left: 2px; + top: 1px; +} + +.storage.panel .status { + float: right; + height: 16px; + margin-top: 1px; + margin-left: 4px; + line-height: 1em; +} + +.storage.panel li .status .bubble { + height: 13px; + padding-top: 0; +} + .storage-view { display: none; overflow: hidden; @@ -1952,7 +2029,7 @@ body.inactive .sidebar { height: 100%; } -.storage-view.table .storage-table-empty, .storage-view.table .storage-table-error { +.storage-empty-view, .storage-view.table .storage-table-error { position: absolute; top: 0; bottom: 25%; @@ -3167,7 +3244,7 @@ body.inactive .sidebar-tree-item .disclosure-button:active { margin-right: 3px; } -.sidebar-tree-item .status { +li .status { float: right; height: 16px; margin-top: 9px; @@ -3175,11 +3252,11 @@ body.inactive .sidebar-tree-item .disclosure-button:active { line-height: 1em; } -.sidebar-tree-item .status:empty { +li .status:empty { display: none; } -.sidebar-tree-item .status .bubble { +li .status .bubble { display: inline-block; height: 14px; min-width: 16px; @@ -3198,20 +3275,20 @@ body.inactive .sidebar-tree-item .disclosure-button:active { -webkit-border-radius: 7px; } -.sidebar-tree-item .status .bubble:empty { +li .status .bubble:empty { display: none; } -.sidebar-tree-item.selected .status .bubble { +li.selected .status .bubble { background-color: white !important; color: rgb(132, 154, 190) !important; } -:focus .sidebar-tree-item.selected .status .bubble { +:focus li.selected .status .bubble { color: rgb(36, 98, 172) !important; } -body.inactive .sidebar-tree-item.selected .status .bubble { +body.inactive li.selected .status .bubble { color: rgb(159, 159, 159) !important; } @@ -3362,7 +3439,7 @@ body.inactive .sidebar-tree-item.selected { content: ""; } -.resource-sidebar-tree-item.resources-category-images .image-resource-icon-preview { +.resources-category-images .image-resource-icon-preview { position: absolute; margin: auto; top: 3px; @@ -3380,7 +3457,7 @@ body.inactive .sidebar-tree-item.selected { content: ""; } -.children.small .resource-sidebar-tree-item.resources-category-images .image-resource-icon-preview { +.children.small .resources-category-images .image-resource-icon-preview { top: 2px; bottom: 1px; left: 3px; @@ -3432,15 +3509,15 @@ body.inactive .sidebar-tree-item.selected { padding-left: 13px !important; } -.sidebar-tree-item.selected .bubble.search-matches { +li.selected .bubble.search-matches { background-image: url(Images/searchSmallBlue.png); } -:focus .sidebar-tree-item.selected .bubble.search-matches { +:focus li.selected .bubble.search-matches { background-image: url(Images/searchSmallBrightBlue.png); } -body.inactive .sidebar-tree-item.selected .bubble.search-matches { +body.inactive li.selected .bubble.search-matches { background-image: url(Images/searchSmallGray.png); } diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index 9bd88d6..f5a70c8 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -50,7 +50,6 @@ var WebInspector = { resources: {}, - resourceURLMap: {}, cookieDomains: {}, applicationCacheDomains: {}, missingLocalizedStrings: {}, @@ -182,7 +181,7 @@ var WebInspector = { for (var panelName in WebInspector.panels) { if (WebInspector.panels[panelName] === x) { - InspectorBackend.storeLastActivePanel(panelName); + WebInspector.applicationSettings.lastActivePanel = panelName; this._panelHistory.setPanel(panelName); } } @@ -226,10 +225,17 @@ var WebInspector = { var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(','); if (hiddenPanels.indexOf("elements") === -1) this.panels.elements = new WebInspector.ElementsPanel(); + + if (Preferences.networkPanelEnabled) { + if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1) + this.panels.storage = new WebInspector.StoragePanel(); + if (hiddenPanels.indexOf("network") === -1) + this.panels.network = new WebInspector.NetworkPanel(); + } else if (hiddenPanels.indexOf("resources") === -1) + this.panels.resources = new WebInspector.ResourcesPanel(); + if (Preferences.networkPanelEnabled && hiddenPanels.indexOf("network") === -1) this.panels.network = new WebInspector.NetworkPanel(); - if (hiddenPanels.indexOf("resources") === -1) - this.panels.resources = new WebInspector.ResourcesPanel(); if (hiddenPanels.indexOf("scripts") === -1) this.panels.scripts = new WebInspector.ScriptsPanel(); if (hiddenPanels.indexOf("timeline") === -1) @@ -240,8 +246,12 @@ var WebInspector = { if (Preferences.heapProfilerPresent) this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType()); } - if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1) - this.panels.storage = new WebInspector.StoragePanel(); + + if (!Preferences.networkPanelEnabled) { + if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1) + this.panels.storage = new WebInspector.StoragePanel(); + } + if (hiddenPanels.indexOf("audits") === -1) this.panels.audits = new WebInspector.AuditsPanel(); if (hiddenPanels.indexOf("console") === -1) @@ -441,6 +451,33 @@ var WebInspector = { { this.currentPanel = this.panels.elements; this.panels.elements.updateFocusedNode(nodeId); + }, + + get networkResources() + { + if (Preferences.networkPanelEnabled) + return this.panels.network.resources; + else + return this.resources; + }, + + forAllResources: function(callback) + { + if (Preferences.networkPanelEnabled) + WebInspector.resourceManager.forAllResources(callback); + else { + for (var id in this.resources) { + if (callback(this.resources[id])) + return; + } + } + }, + + resourceForURL: function(url) + { + if (Preferences.networkPanelEnabled) + return this.resourceManager.resourceForURL(url); + return this.panels.resources.resourceURLMap[url]; } } @@ -493,8 +530,8 @@ WebInspector.doLoadedDone = function() document.body.addStyleClass("port-" + port); InspectorFrontendHost.loaded(); - WebInspector.Settings.initialize(); - + WebInspector.applicationSettings = new WebInspector.Settings(); + this._registerShortcuts(); // set order of some sections explicitly @@ -507,8 +544,8 @@ WebInspector.doLoadedDone = function() // this.changes = new WebInspector.ChangesView(this.drawer); // TODO: Remove class="hidden" from inspector.html on button#changes-status-bar-item this.drawer.visibleView = this.console; - // FIXME: uncomment when ready. - // this.resourceManager = new WebInspector.ResourceManager(); + if (Preferences.networkPanelEnabled) + this.resourceManager = new WebInspector.ResourceManager(); this.domAgent = new WebInspector.DOMAgent(); this.resourceCategories = { @@ -536,6 +573,11 @@ WebInspector.doLoadedDone = function() for (var panelName in this.panels) previousToolbarItem = WebInspector.addPanelToolbarIcon(toolbarElement, this.panels[panelName], previousToolbarItem); + if (Preferences.networkPanelEnabled) { + this.panels.storage._toolbarItem.removeStyleClass("storage"); + this.panels.storage._toolbarItem.addStyleClass("resources"); + } + this.Tips = { ResourceNotCompressed: {id: 0, message: WebInspector.UIString("You could save bandwidth by having your web server compress this transfer with gzip or zlib.")} }; @@ -588,14 +630,22 @@ WebInspector.doLoadedDone = function() WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled; if ("pauseOnExceptionsState" in inspectorState) WebInspector.panels.scripts.updatePauseOnExceptionsState(inspectorState.pauseOnExceptionsState); - if (inspectorState.resourceTrackingEnabled) - WebInspector.panels.resources.resourceTrackingWasEnabled(); - else - WebInspector.panels.resources.resourceTrackingWasDisabled(); + if (WebInspector.panels.resources) { + if (inspectorState.resourceTrackingEnabled) + WebInspector.panels.resources.resourceTrackingWasEnabled(); + else + WebInspector.panels.resources.resourceTrackingWasDisabled(); + } } InspectorBackend.getInspectorState(populateInspectorState); - InspectorBackend.populateScriptObjects(); + function onPopulateScriptObjects() + { + if (!WebInspector.currentPanel) + WebInspector.showPanel(WebInspector.applicationSettings.lastActivePanel); + } + InspectorBackend.populateScriptObjects(onPopulateScriptObjects); + InspectorBackend.setConsoleMessagesEnabled(true); // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available. @@ -768,7 +818,7 @@ WebInspector.documentClick = function(event) if (parsedURL.host === "show-panel") { var panel = parsedURL.path.substring(1); if (WebInspector.panels[panel]) - WebInspector.currentPanel = WebInspector.panels[panel]; + WebInspector.showPanel(panel); } return; } @@ -794,8 +844,13 @@ WebInspector.openResource = function(resourceURL, inResourcesPanel) { var resource = WebInspector.resourceForURL(resourceURL); if (inResourcesPanel && resource) { - WebInspector.panels.resources.showResource(resource); - WebInspector.showPanel("resources"); + if (Preferences.networkPanelEnabled) { + WebInspector.panels.storage.showResource(resource); + WebInspector.showPanel("storage"); + } else { + WebInspector.panels.resources.showResource(resource); + WebInspector.showPanel("resources"); + } } else InspectorBackend.openInInspectedWindow(resource ? resource.url : resourceURL); } @@ -1214,12 +1269,14 @@ WebInspector.selectDOMStorage = function(o) WebInspector.updateResource = function(payload) { + if (Preferences.networkPanelEnabled) + return; + var identifier = payload.id; var resource = this.resources[identifier]; if (!resource) { resource = new WebInspector.Resource(identifier, payload.url); this.resources[identifier] = resource; - this.resourceURLMap[resource.url] = resource; this.panels.resources.addResource(resource); this.panels.audits.resourceStarted(resource); } @@ -1267,6 +1324,7 @@ WebInspector.updateResource = function(payload) if (payload.didCompletionChange) { resource.failed = payload.failed; + resource.localizedFailDescription = payload.localizedFailDescription; resource.finished = payload.finished; if (this.panels.audits) this.panels.audits.resourceFinished(resource); @@ -1286,28 +1344,33 @@ WebInspector.updateResource = function(payload) WebInspector.domContentEventFired = function(time) { - this.panels.resources.mainResourceDOMContentTime = time; + if (this.panels.resources) + this.panels.resources.mainResourceDOMContentTime = time; this.panels.audits.mainResourceDOMContentTime = time; if (this.panels.network) this.panels.network.mainResourceDOMContentTime = time; + this.mainResourceDOMContentTime = time; } WebInspector.loadEventFired = function(time) { - this.panels.resources.mainResourceLoadTime = time; + if (this.panels.resources) + this.panels.resources.mainResourceLoadTime = time; this.panels.audits.mainResourceLoadTime = time; if (this.panels.network) this.panels.network.mainResourceLoadTime = time; + this.mainResourceLoadTime = time; } WebInspector.removeResource = function(identifier) { + if (Preferences.networkPanelEnabled) + return; + var resource = this.resources[identifier]; if (!resource) return; - resource.category.removeResource(resource); - delete this.resourceURLMap[resource.url]; delete this.resources[identifier]; if (this.panels.resources) @@ -1449,18 +1512,13 @@ WebInspector.reset = function() panel.reset(); } - this.sessionSettings.reset(); - - for (var category in this.resourceCategories) - this.resourceCategories[category].removeAllResources(); - this.resources = {}; - this.resourceURLMap = {}; this.cookieDomains = {}; this.applicationCacheDomains = {}; this.highlightDOMNode(0); - delete this.mainResource; + if (!Preferences.networkPanelEnabled) + delete this.mainResource; this.console.clearMessages(); this.extensionServer.notifyInspectorReset(); @@ -1669,7 +1727,8 @@ WebInspector.displayNameForURL = function(url) { if (!url) return ""; - var resource = this.resourceURLMap[url]; + + var resource = this.resourceForURL(url); if (resource) return resource.displayName; @@ -1687,28 +1746,16 @@ WebInspector.displayNameForURL = function(url) return url.trimURL(WebInspector.mainResource.domain); } -WebInspector.resourceForURL = function(url) -{ - if (url in this.resourceURLMap) - return this.resourceURLMap[url]; - - // No direct match found. Search for resources that contain - // a substring of the URL. - for (var resourceURL in this.resourceURLMap) { - if (resourceURL.hasSubstring(url)) - return this.resourceURLMap[resourceURL]; - } - - return null; -} - WebInspector._choosePanelToShowSourceLine = function(url, line, preferredPanel) { preferredPanel = preferredPanel || "resources"; + if (Preferences.networkPanelEnabled && preferredPanel === "resources") + preferredPanel = "storage"; + var panel = this.panels[preferredPanel]; if (panel && panel.canShowSourceLine(url, line)) return panel; - panel = this.panels.resources; + panel = Preferences.networkPanelEnabled ? this.panels.storage : this.panels.resources; return panel.canShowSourceLine(url, line) ? panel : null; } @@ -1747,7 +1794,8 @@ WebInspector.linkifyStringAsFragment = function(string) title = WebInspector.panels.profiles.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]); var realURL = (linkString.indexOf("www.") === 0 ? "http://" + linkString : linkString); - container.appendChild(WebInspector.linkifyURLAsNode(realURL, title, null, (realURL in WebInspector.resourceURLMap))); + var hasResourceWithURL = !!WebInspector.resourceForURL(realURL); + container.appendChild(WebInspector.linkifyURLAsNode(realURL, title, null, hasResourceWithURL)); string = string.substring(linkIndex + linkString.length, string.length); } @@ -1815,13 +1863,17 @@ WebInspector.resourceURLForRelatedNode = function(node, url) } // documentURL not found or has bad value - for (var resourceURL in WebInspector.resourceURLMap) { - var parsedURL = resourceURL.asParsedURL(); - if (parsedURL && parsedURL.path === url) - return resourceURL; + var resourceURL = url; + function callback(resource) + { + if (resource.path === url) { + resourceURL = resource.url; + return true; + } } - return url; -}, + WebInspector.forAllResources(callback); + return resourceURL; +} WebInspector.completeURL = function(baseURL, href) { @@ -1918,9 +1970,10 @@ WebInspector.doPerformSearch = function(query, forceSearch, isBackwardSearch, re for (var panelName in this.panels) { var panel = this.panels[panelName]; - if (panel.currentQuery && panel.searchCanceled) - panel.searchCanceled(); + var hadCurrentQuery = !!panel.currentQuery; delete panel.currentQuery; + if (hadCurrentQuery && panel.searchCanceled) + panel.searchCanceled(); } this.updateSearchMatchesCount(); diff --git a/WebCore/inspector/front-end/networkPanel.css b/WebCore/inspector/front-end/networkPanel.css index 773fe99..215681f 100644 --- a/WebCore/inspector/front-end/networkPanel.css +++ b/WebCore/inspector/front-end/networkPanel.css @@ -24,11 +24,16 @@ .network.panel .data-grid td { line-height: 17px; + height: 37px; border-right: 1px solid rgb(210, 210, 210); -webkit-user-select: none; vertical-align: middle; } +.network.panel .data-grid.small td { + height: 17px; +} + .network.panel .data-grid th { border-bottom: 1px solid rgb(64%, 64%, 64%); height: 30px; @@ -414,6 +419,10 @@ background-color: rgba(0, 0, 255, 0.5); } +.network.panel .resources-dividers { + z-index: 0; +} + .network.panel .resources-dividers-label-bar { background-color: transparent; border: none; @@ -535,6 +544,19 @@ left: 0; } +.network-close-button { + position: absolute; + width: 14px; + height: 14px; + background-image: url(Images/closeButtons.png); + background-position: 0 0; + background-color: transparent; + border: 0 none transparent; + top: 4px; + right: 5px; + z-index: 10; +} + .network.panel .data-grid.full-grid-mode .viewer-column { display: none; } @@ -582,7 +604,19 @@ padding-top: 5px; } -.network.panel .resource-view.headers-visible .resource-view-content { +#network-views .resource-view.headers-visible .resource-view-content { + top: 31px; +} + +#network-views.small .resource-view.headers-visible .resource-view-content { + top: 23px; +} + +#network-views .resource-view-headers { + top: 31px; +} + +#network-views.small .resource-view-headers { top: 23px; } @@ -591,7 +625,12 @@ color: black; } -.network.panel .resource-view .tabbed-pane-header { +#network-views .resource-view .tabbed-pane-header { + height: 31px; + padding-top: 11px; +} + +#network-views.small .resource-view .tabbed-pane-header { height: 23px; padding-top: 3px; } |