summaryrefslogtreecommitdiffstats
path: root/layout/inspector/inCSSValueSearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/inspector/inCSSValueSearch.cpp')
-rw-r--r--layout/inspector/inCSSValueSearch.cpp407
1 files changed, 407 insertions, 0 deletions
diff --git a/layout/inspector/inCSSValueSearch.cpp b/layout/inspector/inCSSValueSearch.cpp
new file mode 100644
index 000000000..ecde09993
--- /dev/null
+++ b/layout/inspector/inCSSValueSearch.cpp
@@ -0,0 +1,407 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "inCSSValueSearch.h"
+
+#include "mozilla/StyleSheetInlines.h"
+#include "mozilla/dom/StyleSheetList.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsReadableUtils.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMStyleSheetList.h"
+#include "nsIDOMCSSStyleSheet.h"
+#include "nsIDOMCSSRuleList.h"
+#include "nsIDOMCSSStyleRule.h"
+#include "nsIDOMCSSStyleDeclaration.h"
+#include "nsIDOMCSSImportRule.h"
+#include "nsIDOMCSSMediaRule.h"
+#include "nsIDOMCSSSupportsRule.h"
+#include "nsIURI.h"
+#include "nsIDocument.h"
+#include "nsNetUtil.h"
+
+using namespace mozilla;
+
+///////////////////////////////////////////////////////////////////////////////
+inCSSValueSearch::inCSSValueSearch()
+ : mResults(nullptr),
+ mProperties(nullptr),
+ mResultCount(0),
+ mPropertyCount(0),
+ mIsActive(false),
+ mHoldResults(true),
+ mReturnRelativeURLs(true),
+ mNormalizeChromeURLs(false)
+{
+ nsCSSProps::AddRefTable();
+ mProperties = new nsCSSPropertyID[100];
+}
+
+inCSSValueSearch::~inCSSValueSearch()
+{
+ delete[] mProperties;
+ delete mResults;
+ nsCSSProps::ReleaseTable();
+}
+
+NS_IMPL_ISUPPORTS(inCSSValueSearch, inISearchProcess, inICSSValueSearch)
+
+///////////////////////////////////////////////////////////////////////////////
+// inISearchProcess
+
+NS_IMETHODIMP
+inCSSValueSearch::GetIsActive(bool *aIsActive)
+{
+ *aIsActive = mIsActive;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetResultCount(int32_t *aResultCount)
+{
+ *aResultCount = mResultCount;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetHoldResults(bool *aHoldResults)
+{
+ *aHoldResults = mHoldResults;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SetHoldResults(bool aHoldResults)
+{
+ mHoldResults = aHoldResults;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SearchSync()
+{
+ InitSearch();
+
+ if (!mDocument) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIDocument> document = do_QueryInterface(mDocument);
+ MOZ_ASSERT(document);
+
+ nsCOMPtr<nsIURI> baseURI = document->GetBaseURI();
+
+ RefPtr<dom::StyleSheetList> sheets = document->StyleSheets();
+ MOZ_ASSERT(sheets);
+
+ uint32_t length = sheets->Length();
+ for (uint32_t i = 0; i < length; ++i) {
+ RefPtr<StyleSheet> sheet = sheets->Item(i);
+ SearchStyleSheet(sheet, baseURI);
+ }
+
+ // XXX would be nice to search inline style as well.
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SearchAsync(inISearchObserver *aObserver)
+{
+ InitSearch();
+ mObserver = aObserver;
+
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+inCSSValueSearch::SearchStop()
+{
+ KillSearch(inISearchObserver::IN_INTERRUPTED);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SearchStep(bool* _retval)
+{
+
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+inCSSValueSearch::GetStringResultAt(int32_t aIndex, nsAString& _retval)
+{
+ if (mHoldResults) {
+ nsAutoString* result = mResults->ElementAt(aIndex);
+ _retval = *result;
+ } else if (aIndex == mResultCount-1) {
+ _retval = mLastResult;
+ } else {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetIntResultAt(int32_t aIndex, int32_t *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetUIntResultAt(int32_t aIndex, uint32_t *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// inICSSValueSearch
+
+NS_IMETHODIMP
+inCSSValueSearch::GetDocument(nsIDOMDocument** aDocument)
+{
+ *aDocument = mDocument;
+ NS_IF_ADDREF(*aDocument);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SetDocument(nsIDOMDocument* aDocument)
+{
+ mDocument = aDocument;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetBaseURL(char16_t** aBaseURL)
+{
+ if (!(*aBaseURL = ToNewUnicode(mBaseURL)))
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SetBaseURL(const char16_t* aBaseURL)
+{
+ mBaseURL.Assign(aBaseURL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetReturnRelativeURLs(bool* aReturnRelativeURLs)
+{
+ *aReturnRelativeURLs = mReturnRelativeURLs;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SetReturnRelativeURLs(bool aReturnRelativeURLs)
+{
+ mReturnRelativeURLs = aReturnRelativeURLs;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetNormalizeChromeURLs(bool *aNormalizeChromeURLs)
+{
+ *aNormalizeChromeURLs = mNormalizeChromeURLs;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SetNormalizeChromeURLs(bool aNormalizeChromeURLs)
+{
+ mNormalizeChromeURLs = aNormalizeChromeURLs;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::AddPropertyCriteria(const char16_t *aPropName)
+{
+ nsCSSPropertyID prop =
+ nsCSSProps::LookupProperty(nsDependentString(aPropName),
+ CSSEnabledState::eIgnoreEnabledState);
+ mProperties[mPropertyCount] = prop;
+ mPropertyCount++;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::GetTextCriteria(char16_t** aTextCriteria)
+{
+ if (!(*aTextCriteria = ToNewUnicode(mTextCriteria)))
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+inCSSValueSearch::SetTextCriteria(const char16_t* aTextCriteria)
+{
+ mTextCriteria.Assign(aTextCriteria);
+ return NS_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// inCSSValueSearch
+
+nsresult
+inCSSValueSearch::InitSearch()
+{
+ if (mHoldResults) {
+ mResults = new nsTArray<nsAutoString *>();
+ }
+
+ mResultCount = 0;
+
+ return NS_OK;
+}
+
+nsresult
+inCSSValueSearch::KillSearch(int16_t aResult)
+{
+ mIsActive = true;
+ mObserver->OnSearchEnd(this, aResult);
+
+ return NS_OK;
+}
+
+nsresult
+inCSSValueSearch::SearchStyleSheet(nsIDOMCSSStyleSheet* aStyleSheet, nsIURI* aBaseURL)
+{
+ nsCOMPtr<nsIURI> baseURL;
+ nsAutoString href;
+ aStyleSheet->GetHref(href);
+ if (href.IsEmpty())
+ baseURL = aBaseURL;
+ else
+ NS_NewURI(getter_AddRefs(baseURL), href, nullptr, aBaseURL);
+
+ nsCOMPtr<nsIDOMCSSRuleList> rules;
+ nsresult rv = aStyleSheet->GetCssRules(getter_AddRefs(rules));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return SearchRuleList(rules, baseURL);
+}
+
+nsresult
+inCSSValueSearch::SearchRuleList(nsIDOMCSSRuleList* aRuleList, nsIURI* aBaseURL)
+{
+ uint32_t length;
+ aRuleList->GetLength(&length);
+ for (uint32_t i = 0; i < length; ++i) {
+ nsCOMPtr<nsIDOMCSSRule> rule;
+ aRuleList->Item(i, getter_AddRefs(rule));
+ uint16_t type;
+ rule->GetType(&type);
+ switch (type) {
+ case nsIDOMCSSRule::STYLE_RULE: {
+ nsCOMPtr<nsIDOMCSSStyleRule> styleRule = do_QueryInterface(rule);
+ SearchStyleRule(styleRule, aBaseURL);
+ } break;
+ case nsIDOMCSSRule::IMPORT_RULE: {
+ nsCOMPtr<nsIDOMCSSImportRule> importRule = do_QueryInterface(rule);
+ nsCOMPtr<nsIDOMCSSStyleSheet> childSheet;
+ importRule->GetStyleSheet(getter_AddRefs(childSheet));
+ if (childSheet)
+ SearchStyleSheet(childSheet, aBaseURL);
+ } break;
+ case nsIDOMCSSRule::MEDIA_RULE: {
+ nsCOMPtr<nsIDOMCSSMediaRule> mediaRule = do_QueryInterface(rule);
+ nsCOMPtr<nsIDOMCSSRuleList> childRules;
+ mediaRule->GetCssRules(getter_AddRefs(childRules));
+ SearchRuleList(childRules, aBaseURL);
+ } break;
+ case nsIDOMCSSRule::SUPPORTS_RULE: {
+ nsCOMPtr<nsIDOMCSSSupportsRule> supportsRule = do_QueryInterface(rule);
+ nsCOMPtr<nsIDOMCSSRuleList> childRules;
+ supportsRule->GetCssRules(getter_AddRefs(childRules));
+ SearchRuleList(childRules, aBaseURL);
+ } break;
+ default:
+ // XXX handle nsIDOMCSSRule::PAGE_RULE if we ever support it
+ break;
+ }
+ }
+ return NS_OK;
+}
+
+nsresult
+inCSSValueSearch::SearchStyleRule(nsIDOMCSSStyleRule* aStyleRule, nsIURI* aBaseURL)
+{
+ nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
+ nsresult rv = aStyleRule->GetStyle(getter_AddRefs(decl));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t length;
+ decl->GetLength(&length);
+ nsAutoString property, value;
+ for (uint32_t i = 0; i < length; ++i) {
+ decl->Item(i, property);
+ // XXX This probably ought to use GetPropertyCSSValue if it were
+ // implemented.
+ decl->GetPropertyValue(property, value);
+ SearchStyleValue(value, aBaseURL);
+ }
+ return NS_OK;
+}
+
+nsresult
+inCSSValueSearch::SearchStyleValue(const nsAFlatString& aValue, nsIURI* aBaseURL)
+{
+ if (StringBeginsWith(aValue, NS_LITERAL_STRING("url(")) &&
+ StringEndsWith(aValue, NS_LITERAL_STRING(")"))) {
+ const nsASingleFragmentString &url =
+ Substring(aValue, 4, aValue.Length() - 5);
+ // XXXldb Need to do more with |mReturnRelativeURLs|, perhaps?
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, aBaseURL);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoCString spec;
+ rv = uri->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoString *result = new NS_ConvertUTF8toUTF16(spec);
+ if (mReturnRelativeURLs)
+ EqualizeURL(result);
+ mResults->AppendElement(result);
+ ++mResultCount;
+ }
+
+ return NS_OK;
+}
+
+nsresult
+inCSSValueSearch::EqualizeURL(nsAutoString* aURL)
+{
+ if (mNormalizeChromeURLs) {
+ if (aURL->Find("chrome://", false, 0, 1) >= 0) {
+ uint32_t len = aURL->Length();
+ char16_t* result = new char16_t[len-8];
+ const char16_t* src = aURL->get();
+ uint32_t i = 9;
+ uint32_t milestone = 0;
+ uint32_t s = 0;
+ while (i < len) {
+ if (src[i] == '/') {
+ milestone += 1;
+ }
+ if (milestone != 1) {
+ result[i-9-s] = src[i];
+ } else {
+ s++;
+ }
+ i++;
+ }
+ result[i-9-s] = 0;
+
+ aURL->Assign(result);
+ delete [] result;
+ }
+ } else {
+ }
+
+ return NS_OK;
+}