1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/inspector/inCSSValueSearch.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,406 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "inCSSValueSearch.h" 1.9 + 1.10 +#include "mozilla/dom/StyleSheetList.h" 1.11 +#include "nsCSSStyleSheet.h" 1.12 +#include "nsIComponentManager.h" 1.13 +#include "nsIServiceManager.h" 1.14 +#include "nsReadableUtils.h" 1.15 +#include "nsIDOMDocument.h" 1.16 +#include "nsIDOMStyleSheetList.h" 1.17 +#include "nsIDOMCSSStyleSheet.h" 1.18 +#include "nsIDOMCSSRuleList.h" 1.19 +#include "nsIDOMCSSStyleRule.h" 1.20 +#include "nsIDOMCSSStyleDeclaration.h" 1.21 +#include "nsIDOMCSSImportRule.h" 1.22 +#include "nsIDOMCSSMediaRule.h" 1.23 +#include "nsIDOMCSSSupportsRule.h" 1.24 +#include "nsIURI.h" 1.25 +#include "nsIDocument.h" 1.26 +#include "nsNetUtil.h" 1.27 + 1.28 +using namespace mozilla; 1.29 + 1.30 +/////////////////////////////////////////////////////////////////////////////// 1.31 +inCSSValueSearch::inCSSValueSearch() 1.32 + : mResults(nullptr), 1.33 + mProperties(nullptr), 1.34 + mResultCount(0), 1.35 + mPropertyCount(0), 1.36 + mIsActive(false), 1.37 + mHoldResults(true), 1.38 + mReturnRelativeURLs(true), 1.39 + mNormalizeChromeURLs(false) 1.40 +{ 1.41 + nsCSSProps::AddRefTable(); 1.42 + mProperties = new nsCSSProperty[100]; 1.43 +} 1.44 + 1.45 +inCSSValueSearch::~inCSSValueSearch() 1.46 +{ 1.47 + delete[] mProperties; 1.48 + delete mResults; 1.49 + nsCSSProps::ReleaseTable(); 1.50 +} 1.51 + 1.52 +NS_IMPL_ISUPPORTS(inCSSValueSearch, inISearchProcess, inICSSValueSearch) 1.53 + 1.54 +/////////////////////////////////////////////////////////////////////////////// 1.55 +// inISearchProcess 1.56 + 1.57 +NS_IMETHODIMP 1.58 +inCSSValueSearch::GetIsActive(bool *aIsActive) 1.59 +{ 1.60 + *aIsActive = mIsActive; 1.61 + return NS_OK; 1.62 +} 1.63 + 1.64 +NS_IMETHODIMP 1.65 +inCSSValueSearch::GetResultCount(int32_t *aResultCount) 1.66 +{ 1.67 + *aResultCount = mResultCount; 1.68 + return NS_OK; 1.69 +} 1.70 + 1.71 +NS_IMETHODIMP 1.72 +inCSSValueSearch::GetHoldResults(bool *aHoldResults) 1.73 +{ 1.74 + *aHoldResults = mHoldResults; 1.75 + return NS_OK; 1.76 +} 1.77 + 1.78 +NS_IMETHODIMP 1.79 +inCSSValueSearch::SetHoldResults(bool aHoldResults) 1.80 +{ 1.81 + mHoldResults = aHoldResults; 1.82 + return NS_OK; 1.83 +} 1.84 + 1.85 +NS_IMETHODIMP 1.86 +inCSSValueSearch::SearchSync() 1.87 +{ 1.88 + InitSearch(); 1.89 + 1.90 + if (!mDocument) { 1.91 + return NS_OK; 1.92 + } 1.93 + 1.94 + nsCOMPtr<nsIDocument> document = do_QueryInterface(mDocument); 1.95 + MOZ_ASSERT(document); 1.96 + 1.97 + nsCOMPtr<nsIURI> baseURI = document->GetBaseURI(); 1.98 + 1.99 + nsRefPtr<dom::StyleSheetList> sheets = document->StyleSheets(); 1.100 + MOZ_ASSERT(sheets); 1.101 + 1.102 + uint32_t length = sheets->Length(); 1.103 + for (uint32_t i = 0; i < length; ++i) { 1.104 + nsRefPtr<nsCSSStyleSheet> sheet = sheets->Item(i); 1.105 + SearchStyleSheet(sheet, baseURI); 1.106 + } 1.107 + 1.108 + // XXX would be nice to search inline style as well. 1.109 + 1.110 + return NS_OK; 1.111 +} 1.112 + 1.113 +NS_IMETHODIMP 1.114 +inCSSValueSearch::SearchAsync(inISearchObserver *aObserver) 1.115 +{ 1.116 + InitSearch(); 1.117 + mObserver = aObserver; 1.118 + 1.119 + return NS_OK; 1.120 +} 1.121 + 1.122 + 1.123 +NS_IMETHODIMP 1.124 +inCSSValueSearch::SearchStop() 1.125 +{ 1.126 + KillSearch(inISearchObserver::IN_INTERRUPTED); 1.127 + return NS_OK; 1.128 +} 1.129 + 1.130 +NS_IMETHODIMP 1.131 +inCSSValueSearch::SearchStep(bool* _retval) 1.132 +{ 1.133 + 1.134 + return NS_OK; 1.135 +} 1.136 + 1.137 + 1.138 +NS_IMETHODIMP 1.139 +inCSSValueSearch::GetStringResultAt(int32_t aIndex, nsAString& _retval) 1.140 +{ 1.141 + if (mHoldResults) { 1.142 + nsAutoString* result = mResults->ElementAt(aIndex); 1.143 + _retval = *result; 1.144 + } else if (aIndex == mResultCount-1) { 1.145 + _retval = mLastResult; 1.146 + } else { 1.147 + return NS_ERROR_FAILURE; 1.148 + } 1.149 + return NS_OK; 1.150 +} 1.151 + 1.152 +NS_IMETHODIMP 1.153 +inCSSValueSearch::GetIntResultAt(int32_t aIndex, int32_t *_retval) 1.154 +{ 1.155 + return NS_ERROR_NOT_IMPLEMENTED; 1.156 +} 1.157 + 1.158 +NS_IMETHODIMP 1.159 +inCSSValueSearch::GetUIntResultAt(int32_t aIndex, uint32_t *_retval) 1.160 +{ 1.161 + return NS_ERROR_NOT_IMPLEMENTED; 1.162 +} 1.163 + 1.164 +/////////////////////////////////////////////////////////////////////////////// 1.165 +// inICSSValueSearch 1.166 + 1.167 +NS_IMETHODIMP 1.168 +inCSSValueSearch::GetDocument(nsIDOMDocument** aDocument) 1.169 +{ 1.170 + *aDocument = mDocument; 1.171 + NS_IF_ADDREF(*aDocument); 1.172 + return NS_OK; 1.173 +} 1.174 + 1.175 +NS_IMETHODIMP 1.176 +inCSSValueSearch::SetDocument(nsIDOMDocument* aDocument) 1.177 +{ 1.178 + mDocument = aDocument; 1.179 + return NS_OK; 1.180 +} 1.181 + 1.182 +NS_IMETHODIMP 1.183 +inCSSValueSearch::GetBaseURL(char16_t** aBaseURL) 1.184 +{ 1.185 + if (!(*aBaseURL = ToNewUnicode(mBaseURL))) 1.186 + return NS_ERROR_OUT_OF_MEMORY; 1.187 + return NS_OK; 1.188 +} 1.189 + 1.190 +NS_IMETHODIMP 1.191 +inCSSValueSearch::SetBaseURL(const char16_t* aBaseURL) 1.192 +{ 1.193 + mBaseURL.Assign(aBaseURL); 1.194 + return NS_OK; 1.195 +} 1.196 + 1.197 +NS_IMETHODIMP 1.198 +inCSSValueSearch::GetReturnRelativeURLs(bool* aReturnRelativeURLs) 1.199 +{ 1.200 + *aReturnRelativeURLs = mReturnRelativeURLs; 1.201 + return NS_OK; 1.202 +} 1.203 + 1.204 +NS_IMETHODIMP 1.205 +inCSSValueSearch::SetReturnRelativeURLs(bool aReturnRelativeURLs) 1.206 +{ 1.207 + mReturnRelativeURLs = aReturnRelativeURLs; 1.208 + return NS_OK; 1.209 +} 1.210 + 1.211 +NS_IMETHODIMP 1.212 +inCSSValueSearch::GetNormalizeChromeURLs(bool *aNormalizeChromeURLs) 1.213 +{ 1.214 + *aNormalizeChromeURLs = mNormalizeChromeURLs; 1.215 + return NS_OK; 1.216 +} 1.217 + 1.218 +NS_IMETHODIMP 1.219 +inCSSValueSearch::SetNormalizeChromeURLs(bool aNormalizeChromeURLs) 1.220 +{ 1.221 + mNormalizeChromeURLs = aNormalizeChromeURLs; 1.222 + return NS_OK; 1.223 +} 1.224 + 1.225 +NS_IMETHODIMP 1.226 +inCSSValueSearch::AddPropertyCriteria(const char16_t *aPropName) 1.227 +{ 1.228 + nsCSSProperty prop = 1.229 + nsCSSProps::LookupProperty(nsDependentString(aPropName), 1.230 + nsCSSProps::eIgnoreEnabledState); 1.231 + mProperties[mPropertyCount] = prop; 1.232 + mPropertyCount++; 1.233 + return NS_OK; 1.234 +} 1.235 + 1.236 +NS_IMETHODIMP 1.237 +inCSSValueSearch::GetTextCriteria(char16_t** aTextCriteria) 1.238 +{ 1.239 + if (!(*aTextCriteria = ToNewUnicode(mTextCriteria))) 1.240 + return NS_ERROR_OUT_OF_MEMORY; 1.241 + return NS_OK; 1.242 +} 1.243 + 1.244 +NS_IMETHODIMP 1.245 +inCSSValueSearch::SetTextCriteria(const char16_t* aTextCriteria) 1.246 +{ 1.247 + mTextCriteria.Assign(aTextCriteria); 1.248 + return NS_OK; 1.249 +} 1.250 + 1.251 +/////////////////////////////////////////////////////////////////////////////// 1.252 +// inCSSValueSearch 1.253 + 1.254 +nsresult 1.255 +inCSSValueSearch::InitSearch() 1.256 +{ 1.257 + if (mHoldResults) { 1.258 + mResults = new nsTArray<nsAutoString *>(); 1.259 + } 1.260 + 1.261 + mResultCount = 0; 1.262 + 1.263 + return NS_OK; 1.264 +} 1.265 + 1.266 +nsresult 1.267 +inCSSValueSearch::KillSearch(int16_t aResult) 1.268 +{ 1.269 + mIsActive = true; 1.270 + mObserver->OnSearchEnd(this, aResult); 1.271 + 1.272 + return NS_OK; 1.273 +} 1.274 + 1.275 +nsresult 1.276 +inCSSValueSearch::SearchStyleSheet(nsIDOMCSSStyleSheet* aStyleSheet, nsIURI* aBaseURL) 1.277 +{ 1.278 + nsCOMPtr<nsIURI> baseURL; 1.279 + nsAutoString href; 1.280 + aStyleSheet->GetHref(href); 1.281 + if (href.IsEmpty()) 1.282 + baseURL = aBaseURL; 1.283 + else 1.284 + NS_NewURI(getter_AddRefs(baseURL), href, nullptr, aBaseURL); 1.285 + 1.286 + nsCOMPtr<nsIDOMCSSRuleList> rules; 1.287 + nsresult rv = aStyleSheet->GetCssRules(getter_AddRefs(rules)); 1.288 + NS_ENSURE_SUCCESS(rv, rv); 1.289 + 1.290 + return SearchRuleList(rules, baseURL); 1.291 +} 1.292 + 1.293 +nsresult 1.294 +inCSSValueSearch::SearchRuleList(nsIDOMCSSRuleList* aRuleList, nsIURI* aBaseURL) 1.295 +{ 1.296 + uint32_t length; 1.297 + aRuleList->GetLength(&length); 1.298 + for (uint32_t i = 0; i < length; ++i) { 1.299 + nsCOMPtr<nsIDOMCSSRule> rule; 1.300 + aRuleList->Item(i, getter_AddRefs(rule)); 1.301 + uint16_t type; 1.302 + rule->GetType(&type); 1.303 + switch (type) { 1.304 + case nsIDOMCSSRule::STYLE_RULE: { 1.305 + nsCOMPtr<nsIDOMCSSStyleRule> styleRule = do_QueryInterface(rule); 1.306 + SearchStyleRule(styleRule, aBaseURL); 1.307 + } break; 1.308 + case nsIDOMCSSRule::IMPORT_RULE: { 1.309 + nsCOMPtr<nsIDOMCSSImportRule> importRule = do_QueryInterface(rule); 1.310 + nsCOMPtr<nsIDOMCSSStyleSheet> childSheet; 1.311 + importRule->GetStyleSheet(getter_AddRefs(childSheet)); 1.312 + if (childSheet) 1.313 + SearchStyleSheet(childSheet, aBaseURL); 1.314 + } break; 1.315 + case nsIDOMCSSRule::MEDIA_RULE: { 1.316 + nsCOMPtr<nsIDOMCSSMediaRule> mediaRule = do_QueryInterface(rule); 1.317 + nsCOMPtr<nsIDOMCSSRuleList> childRules; 1.318 + mediaRule->GetCssRules(getter_AddRefs(childRules)); 1.319 + SearchRuleList(childRules, aBaseURL); 1.320 + } break; 1.321 + case nsIDOMCSSRule::SUPPORTS_RULE: { 1.322 + nsCOMPtr<nsIDOMCSSSupportsRule> supportsRule = do_QueryInterface(rule); 1.323 + nsCOMPtr<nsIDOMCSSRuleList> childRules; 1.324 + supportsRule->GetCssRules(getter_AddRefs(childRules)); 1.325 + SearchRuleList(childRules, aBaseURL); 1.326 + } break; 1.327 + default: 1.328 + // XXX handle nsIDOMCSSRule::PAGE_RULE if we ever support it 1.329 + break; 1.330 + } 1.331 + } 1.332 + return NS_OK; 1.333 +} 1.334 + 1.335 +nsresult 1.336 +inCSSValueSearch::SearchStyleRule(nsIDOMCSSStyleRule* aStyleRule, nsIURI* aBaseURL) 1.337 +{ 1.338 + nsCOMPtr<nsIDOMCSSStyleDeclaration> decl; 1.339 + nsresult rv = aStyleRule->GetStyle(getter_AddRefs(decl)); 1.340 + NS_ENSURE_SUCCESS(rv, rv); 1.341 + 1.342 + uint32_t length; 1.343 + decl->GetLength(&length); 1.344 + nsAutoString property, value; 1.345 + for (uint32_t i = 0; i < length; ++i) { 1.346 + decl->Item(i, property); 1.347 + // XXX This probably ought to use GetPropertyCSSValue if it were 1.348 + // implemented. 1.349 + decl->GetPropertyValue(property, value); 1.350 + SearchStyleValue(value, aBaseURL); 1.351 + } 1.352 + return NS_OK; 1.353 +} 1.354 + 1.355 +nsresult 1.356 +inCSSValueSearch::SearchStyleValue(const nsAFlatString& aValue, nsIURI* aBaseURL) 1.357 +{ 1.358 + if (StringBeginsWith(aValue, NS_LITERAL_STRING("url(")) && 1.359 + StringEndsWith(aValue, NS_LITERAL_STRING(")"))) { 1.360 + const nsASingleFragmentString &url = 1.361 + Substring(aValue, 4, aValue.Length() - 5); 1.362 + // XXXldb Need to do more with |mReturnRelativeURLs|, perhaps? 1.363 + nsCOMPtr<nsIURI> uri; 1.364 + nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, aBaseURL); 1.365 + NS_ENSURE_SUCCESS(rv, rv); 1.366 + nsAutoCString spec; 1.367 + uri->GetSpec(spec); 1.368 + nsAutoString *result = new NS_ConvertUTF8toUTF16(spec); 1.369 + if (mReturnRelativeURLs) 1.370 + EqualizeURL(result); 1.371 + mResults->AppendElement(result); 1.372 + ++mResultCount; 1.373 + } 1.374 + 1.375 + return NS_OK; 1.376 +} 1.377 + 1.378 +nsresult 1.379 +inCSSValueSearch::EqualizeURL(nsAutoString* aURL) 1.380 +{ 1.381 + if (mNormalizeChromeURLs) { 1.382 + if (aURL->Find("chrome://", false, 0, 1) >= 0) { 1.383 + uint32_t len = aURL->Length(); 1.384 + char16_t* result = new char16_t[len-8]; 1.385 + const char16_t* src = aURL->get(); 1.386 + uint32_t i = 9; 1.387 + uint32_t milestone = 0; 1.388 + uint32_t s = 0; 1.389 + while (i < len) { 1.390 + if (src[i] == '/') { 1.391 + milestone += 1; 1.392 + } 1.393 + if (milestone != 1) { 1.394 + result[i-9-s] = src[i]; 1.395 + } else { 1.396 + s++; 1.397 + } 1.398 + i++; 1.399 + } 1.400 + result[i-9-s] = 0; 1.401 + 1.402 + aURL->Assign(result); 1.403 + delete [] result; 1.404 + } 1.405 + } else { 1.406 + } 1.407 + 1.408 + return NS_OK; 1.409 +}