diff options
Diffstat (limited to 'layout/inspector/inCSSValueSearch.cpp')
-rw-r--r-- | layout/inspector/inCSSValueSearch.cpp | 407 |
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; +} |