layout/inspector/inCSSValueSearch.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "inCSSValueSearch.h"
michael@0 6
michael@0 7 #include "mozilla/dom/StyleSheetList.h"
michael@0 8 #include "nsCSSStyleSheet.h"
michael@0 9 #include "nsIComponentManager.h"
michael@0 10 #include "nsIServiceManager.h"
michael@0 11 #include "nsReadableUtils.h"
michael@0 12 #include "nsIDOMDocument.h"
michael@0 13 #include "nsIDOMStyleSheetList.h"
michael@0 14 #include "nsIDOMCSSStyleSheet.h"
michael@0 15 #include "nsIDOMCSSRuleList.h"
michael@0 16 #include "nsIDOMCSSStyleRule.h"
michael@0 17 #include "nsIDOMCSSStyleDeclaration.h"
michael@0 18 #include "nsIDOMCSSImportRule.h"
michael@0 19 #include "nsIDOMCSSMediaRule.h"
michael@0 20 #include "nsIDOMCSSSupportsRule.h"
michael@0 21 #include "nsIURI.h"
michael@0 22 #include "nsIDocument.h"
michael@0 23 #include "nsNetUtil.h"
michael@0 24
michael@0 25 using namespace mozilla;
michael@0 26
michael@0 27 ///////////////////////////////////////////////////////////////////////////////
michael@0 28 inCSSValueSearch::inCSSValueSearch()
michael@0 29 : mResults(nullptr),
michael@0 30 mProperties(nullptr),
michael@0 31 mResultCount(0),
michael@0 32 mPropertyCount(0),
michael@0 33 mIsActive(false),
michael@0 34 mHoldResults(true),
michael@0 35 mReturnRelativeURLs(true),
michael@0 36 mNormalizeChromeURLs(false)
michael@0 37 {
michael@0 38 nsCSSProps::AddRefTable();
michael@0 39 mProperties = new nsCSSProperty[100];
michael@0 40 }
michael@0 41
michael@0 42 inCSSValueSearch::~inCSSValueSearch()
michael@0 43 {
michael@0 44 delete[] mProperties;
michael@0 45 delete mResults;
michael@0 46 nsCSSProps::ReleaseTable();
michael@0 47 }
michael@0 48
michael@0 49 NS_IMPL_ISUPPORTS(inCSSValueSearch, inISearchProcess, inICSSValueSearch)
michael@0 50
michael@0 51 ///////////////////////////////////////////////////////////////////////////////
michael@0 52 // inISearchProcess
michael@0 53
michael@0 54 NS_IMETHODIMP
michael@0 55 inCSSValueSearch::GetIsActive(bool *aIsActive)
michael@0 56 {
michael@0 57 *aIsActive = mIsActive;
michael@0 58 return NS_OK;
michael@0 59 }
michael@0 60
michael@0 61 NS_IMETHODIMP
michael@0 62 inCSSValueSearch::GetResultCount(int32_t *aResultCount)
michael@0 63 {
michael@0 64 *aResultCount = mResultCount;
michael@0 65 return NS_OK;
michael@0 66 }
michael@0 67
michael@0 68 NS_IMETHODIMP
michael@0 69 inCSSValueSearch::GetHoldResults(bool *aHoldResults)
michael@0 70 {
michael@0 71 *aHoldResults = mHoldResults;
michael@0 72 return NS_OK;
michael@0 73 }
michael@0 74
michael@0 75 NS_IMETHODIMP
michael@0 76 inCSSValueSearch::SetHoldResults(bool aHoldResults)
michael@0 77 {
michael@0 78 mHoldResults = aHoldResults;
michael@0 79 return NS_OK;
michael@0 80 }
michael@0 81
michael@0 82 NS_IMETHODIMP
michael@0 83 inCSSValueSearch::SearchSync()
michael@0 84 {
michael@0 85 InitSearch();
michael@0 86
michael@0 87 if (!mDocument) {
michael@0 88 return NS_OK;
michael@0 89 }
michael@0 90
michael@0 91 nsCOMPtr<nsIDocument> document = do_QueryInterface(mDocument);
michael@0 92 MOZ_ASSERT(document);
michael@0 93
michael@0 94 nsCOMPtr<nsIURI> baseURI = document->GetBaseURI();
michael@0 95
michael@0 96 nsRefPtr<dom::StyleSheetList> sheets = document->StyleSheets();
michael@0 97 MOZ_ASSERT(sheets);
michael@0 98
michael@0 99 uint32_t length = sheets->Length();
michael@0 100 for (uint32_t i = 0; i < length; ++i) {
michael@0 101 nsRefPtr<nsCSSStyleSheet> sheet = sheets->Item(i);
michael@0 102 SearchStyleSheet(sheet, baseURI);
michael@0 103 }
michael@0 104
michael@0 105 // XXX would be nice to search inline style as well.
michael@0 106
michael@0 107 return NS_OK;
michael@0 108 }
michael@0 109
michael@0 110 NS_IMETHODIMP
michael@0 111 inCSSValueSearch::SearchAsync(inISearchObserver *aObserver)
michael@0 112 {
michael@0 113 InitSearch();
michael@0 114 mObserver = aObserver;
michael@0 115
michael@0 116 return NS_OK;
michael@0 117 }
michael@0 118
michael@0 119
michael@0 120 NS_IMETHODIMP
michael@0 121 inCSSValueSearch::SearchStop()
michael@0 122 {
michael@0 123 KillSearch(inISearchObserver::IN_INTERRUPTED);
michael@0 124 return NS_OK;
michael@0 125 }
michael@0 126
michael@0 127 NS_IMETHODIMP
michael@0 128 inCSSValueSearch::SearchStep(bool* _retval)
michael@0 129 {
michael@0 130
michael@0 131 return NS_OK;
michael@0 132 }
michael@0 133
michael@0 134
michael@0 135 NS_IMETHODIMP
michael@0 136 inCSSValueSearch::GetStringResultAt(int32_t aIndex, nsAString& _retval)
michael@0 137 {
michael@0 138 if (mHoldResults) {
michael@0 139 nsAutoString* result = mResults->ElementAt(aIndex);
michael@0 140 _retval = *result;
michael@0 141 } else if (aIndex == mResultCount-1) {
michael@0 142 _retval = mLastResult;
michael@0 143 } else {
michael@0 144 return NS_ERROR_FAILURE;
michael@0 145 }
michael@0 146 return NS_OK;
michael@0 147 }
michael@0 148
michael@0 149 NS_IMETHODIMP
michael@0 150 inCSSValueSearch::GetIntResultAt(int32_t aIndex, int32_t *_retval)
michael@0 151 {
michael@0 152 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 153 }
michael@0 154
michael@0 155 NS_IMETHODIMP
michael@0 156 inCSSValueSearch::GetUIntResultAt(int32_t aIndex, uint32_t *_retval)
michael@0 157 {
michael@0 158 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 159 }
michael@0 160
michael@0 161 ///////////////////////////////////////////////////////////////////////////////
michael@0 162 // inICSSValueSearch
michael@0 163
michael@0 164 NS_IMETHODIMP
michael@0 165 inCSSValueSearch::GetDocument(nsIDOMDocument** aDocument)
michael@0 166 {
michael@0 167 *aDocument = mDocument;
michael@0 168 NS_IF_ADDREF(*aDocument);
michael@0 169 return NS_OK;
michael@0 170 }
michael@0 171
michael@0 172 NS_IMETHODIMP
michael@0 173 inCSSValueSearch::SetDocument(nsIDOMDocument* aDocument)
michael@0 174 {
michael@0 175 mDocument = aDocument;
michael@0 176 return NS_OK;
michael@0 177 }
michael@0 178
michael@0 179 NS_IMETHODIMP
michael@0 180 inCSSValueSearch::GetBaseURL(char16_t** aBaseURL)
michael@0 181 {
michael@0 182 if (!(*aBaseURL = ToNewUnicode(mBaseURL)))
michael@0 183 return NS_ERROR_OUT_OF_MEMORY;
michael@0 184 return NS_OK;
michael@0 185 }
michael@0 186
michael@0 187 NS_IMETHODIMP
michael@0 188 inCSSValueSearch::SetBaseURL(const char16_t* aBaseURL)
michael@0 189 {
michael@0 190 mBaseURL.Assign(aBaseURL);
michael@0 191 return NS_OK;
michael@0 192 }
michael@0 193
michael@0 194 NS_IMETHODIMP
michael@0 195 inCSSValueSearch::GetReturnRelativeURLs(bool* aReturnRelativeURLs)
michael@0 196 {
michael@0 197 *aReturnRelativeURLs = mReturnRelativeURLs;
michael@0 198 return NS_OK;
michael@0 199 }
michael@0 200
michael@0 201 NS_IMETHODIMP
michael@0 202 inCSSValueSearch::SetReturnRelativeURLs(bool aReturnRelativeURLs)
michael@0 203 {
michael@0 204 mReturnRelativeURLs = aReturnRelativeURLs;
michael@0 205 return NS_OK;
michael@0 206 }
michael@0 207
michael@0 208 NS_IMETHODIMP
michael@0 209 inCSSValueSearch::GetNormalizeChromeURLs(bool *aNormalizeChromeURLs)
michael@0 210 {
michael@0 211 *aNormalizeChromeURLs = mNormalizeChromeURLs;
michael@0 212 return NS_OK;
michael@0 213 }
michael@0 214
michael@0 215 NS_IMETHODIMP
michael@0 216 inCSSValueSearch::SetNormalizeChromeURLs(bool aNormalizeChromeURLs)
michael@0 217 {
michael@0 218 mNormalizeChromeURLs = aNormalizeChromeURLs;
michael@0 219 return NS_OK;
michael@0 220 }
michael@0 221
michael@0 222 NS_IMETHODIMP
michael@0 223 inCSSValueSearch::AddPropertyCriteria(const char16_t *aPropName)
michael@0 224 {
michael@0 225 nsCSSProperty prop =
michael@0 226 nsCSSProps::LookupProperty(nsDependentString(aPropName),
michael@0 227 nsCSSProps::eIgnoreEnabledState);
michael@0 228 mProperties[mPropertyCount] = prop;
michael@0 229 mPropertyCount++;
michael@0 230 return NS_OK;
michael@0 231 }
michael@0 232
michael@0 233 NS_IMETHODIMP
michael@0 234 inCSSValueSearch::GetTextCriteria(char16_t** aTextCriteria)
michael@0 235 {
michael@0 236 if (!(*aTextCriteria = ToNewUnicode(mTextCriteria)))
michael@0 237 return NS_ERROR_OUT_OF_MEMORY;
michael@0 238 return NS_OK;
michael@0 239 }
michael@0 240
michael@0 241 NS_IMETHODIMP
michael@0 242 inCSSValueSearch::SetTextCriteria(const char16_t* aTextCriteria)
michael@0 243 {
michael@0 244 mTextCriteria.Assign(aTextCriteria);
michael@0 245 return NS_OK;
michael@0 246 }
michael@0 247
michael@0 248 ///////////////////////////////////////////////////////////////////////////////
michael@0 249 // inCSSValueSearch
michael@0 250
michael@0 251 nsresult
michael@0 252 inCSSValueSearch::InitSearch()
michael@0 253 {
michael@0 254 if (mHoldResults) {
michael@0 255 mResults = new nsTArray<nsAutoString *>();
michael@0 256 }
michael@0 257
michael@0 258 mResultCount = 0;
michael@0 259
michael@0 260 return NS_OK;
michael@0 261 }
michael@0 262
michael@0 263 nsresult
michael@0 264 inCSSValueSearch::KillSearch(int16_t aResult)
michael@0 265 {
michael@0 266 mIsActive = true;
michael@0 267 mObserver->OnSearchEnd(this, aResult);
michael@0 268
michael@0 269 return NS_OK;
michael@0 270 }
michael@0 271
michael@0 272 nsresult
michael@0 273 inCSSValueSearch::SearchStyleSheet(nsIDOMCSSStyleSheet* aStyleSheet, nsIURI* aBaseURL)
michael@0 274 {
michael@0 275 nsCOMPtr<nsIURI> baseURL;
michael@0 276 nsAutoString href;
michael@0 277 aStyleSheet->GetHref(href);
michael@0 278 if (href.IsEmpty())
michael@0 279 baseURL = aBaseURL;
michael@0 280 else
michael@0 281 NS_NewURI(getter_AddRefs(baseURL), href, nullptr, aBaseURL);
michael@0 282
michael@0 283 nsCOMPtr<nsIDOMCSSRuleList> rules;
michael@0 284 nsresult rv = aStyleSheet->GetCssRules(getter_AddRefs(rules));
michael@0 285 NS_ENSURE_SUCCESS(rv, rv);
michael@0 286
michael@0 287 return SearchRuleList(rules, baseURL);
michael@0 288 }
michael@0 289
michael@0 290 nsresult
michael@0 291 inCSSValueSearch::SearchRuleList(nsIDOMCSSRuleList* aRuleList, nsIURI* aBaseURL)
michael@0 292 {
michael@0 293 uint32_t length;
michael@0 294 aRuleList->GetLength(&length);
michael@0 295 for (uint32_t i = 0; i < length; ++i) {
michael@0 296 nsCOMPtr<nsIDOMCSSRule> rule;
michael@0 297 aRuleList->Item(i, getter_AddRefs(rule));
michael@0 298 uint16_t type;
michael@0 299 rule->GetType(&type);
michael@0 300 switch (type) {
michael@0 301 case nsIDOMCSSRule::STYLE_RULE: {
michael@0 302 nsCOMPtr<nsIDOMCSSStyleRule> styleRule = do_QueryInterface(rule);
michael@0 303 SearchStyleRule(styleRule, aBaseURL);
michael@0 304 } break;
michael@0 305 case nsIDOMCSSRule::IMPORT_RULE: {
michael@0 306 nsCOMPtr<nsIDOMCSSImportRule> importRule = do_QueryInterface(rule);
michael@0 307 nsCOMPtr<nsIDOMCSSStyleSheet> childSheet;
michael@0 308 importRule->GetStyleSheet(getter_AddRefs(childSheet));
michael@0 309 if (childSheet)
michael@0 310 SearchStyleSheet(childSheet, aBaseURL);
michael@0 311 } break;
michael@0 312 case nsIDOMCSSRule::MEDIA_RULE: {
michael@0 313 nsCOMPtr<nsIDOMCSSMediaRule> mediaRule = do_QueryInterface(rule);
michael@0 314 nsCOMPtr<nsIDOMCSSRuleList> childRules;
michael@0 315 mediaRule->GetCssRules(getter_AddRefs(childRules));
michael@0 316 SearchRuleList(childRules, aBaseURL);
michael@0 317 } break;
michael@0 318 case nsIDOMCSSRule::SUPPORTS_RULE: {
michael@0 319 nsCOMPtr<nsIDOMCSSSupportsRule> supportsRule = do_QueryInterface(rule);
michael@0 320 nsCOMPtr<nsIDOMCSSRuleList> childRules;
michael@0 321 supportsRule->GetCssRules(getter_AddRefs(childRules));
michael@0 322 SearchRuleList(childRules, aBaseURL);
michael@0 323 } break;
michael@0 324 default:
michael@0 325 // XXX handle nsIDOMCSSRule::PAGE_RULE if we ever support it
michael@0 326 break;
michael@0 327 }
michael@0 328 }
michael@0 329 return NS_OK;
michael@0 330 }
michael@0 331
michael@0 332 nsresult
michael@0 333 inCSSValueSearch::SearchStyleRule(nsIDOMCSSStyleRule* aStyleRule, nsIURI* aBaseURL)
michael@0 334 {
michael@0 335 nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
michael@0 336 nsresult rv = aStyleRule->GetStyle(getter_AddRefs(decl));
michael@0 337 NS_ENSURE_SUCCESS(rv, rv);
michael@0 338
michael@0 339 uint32_t length;
michael@0 340 decl->GetLength(&length);
michael@0 341 nsAutoString property, value;
michael@0 342 for (uint32_t i = 0; i < length; ++i) {
michael@0 343 decl->Item(i, property);
michael@0 344 // XXX This probably ought to use GetPropertyCSSValue if it were
michael@0 345 // implemented.
michael@0 346 decl->GetPropertyValue(property, value);
michael@0 347 SearchStyleValue(value, aBaseURL);
michael@0 348 }
michael@0 349 return NS_OK;
michael@0 350 }
michael@0 351
michael@0 352 nsresult
michael@0 353 inCSSValueSearch::SearchStyleValue(const nsAFlatString& aValue, nsIURI* aBaseURL)
michael@0 354 {
michael@0 355 if (StringBeginsWith(aValue, NS_LITERAL_STRING("url(")) &&
michael@0 356 StringEndsWith(aValue, NS_LITERAL_STRING(")"))) {
michael@0 357 const nsASingleFragmentString &url =
michael@0 358 Substring(aValue, 4, aValue.Length() - 5);
michael@0 359 // XXXldb Need to do more with |mReturnRelativeURLs|, perhaps?
michael@0 360 nsCOMPtr<nsIURI> uri;
michael@0 361 nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, aBaseURL);
michael@0 362 NS_ENSURE_SUCCESS(rv, rv);
michael@0 363 nsAutoCString spec;
michael@0 364 uri->GetSpec(spec);
michael@0 365 nsAutoString *result = new NS_ConvertUTF8toUTF16(spec);
michael@0 366 if (mReturnRelativeURLs)
michael@0 367 EqualizeURL(result);
michael@0 368 mResults->AppendElement(result);
michael@0 369 ++mResultCount;
michael@0 370 }
michael@0 371
michael@0 372 return NS_OK;
michael@0 373 }
michael@0 374
michael@0 375 nsresult
michael@0 376 inCSSValueSearch::EqualizeURL(nsAutoString* aURL)
michael@0 377 {
michael@0 378 if (mNormalizeChromeURLs) {
michael@0 379 if (aURL->Find("chrome://", false, 0, 1) >= 0) {
michael@0 380 uint32_t len = aURL->Length();
michael@0 381 char16_t* result = new char16_t[len-8];
michael@0 382 const char16_t* src = aURL->get();
michael@0 383 uint32_t i = 9;
michael@0 384 uint32_t milestone = 0;
michael@0 385 uint32_t s = 0;
michael@0 386 while (i < len) {
michael@0 387 if (src[i] == '/') {
michael@0 388 milestone += 1;
michael@0 389 }
michael@0 390 if (milestone != 1) {
michael@0 391 result[i-9-s] = src[i];
michael@0 392 } else {
michael@0 393 s++;
michael@0 394 }
michael@0 395 i++;
michael@0 396 }
michael@0 397 result[i-9-s] = 0;
michael@0 398
michael@0 399 aURL->Assign(result);
michael@0 400 delete [] result;
michael@0 401 }
michael@0 402 } else {
michael@0 403 }
michael@0 404
michael@0 405 return NS_OK;
michael@0 406 }

mercurial