~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/extensions/inspector/base/src/inCSSValueSearch.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Netscape Public License
 
5
 * Version 1.1 (the "License"); you may not use this file except in
 
6
 * compliance with the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/NPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is mozilla.org code.
 
15
 *
 
16
 * The Initial Developer of the Original Code is 
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 2001
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *   Joe Hewitt <hewitt@netscape.com> (original author)
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#include "inCSSValueSearch.h"
 
40
 
 
41
#include "nsIComponentManager.h"
 
42
#include "nsIServiceManager.h"
 
43
#include "nsVoidArray.h"
 
44
#include "nsReadableUtils.h"
 
45
#include "nsIDOMDocumentStyle.h"
 
46
#include "nsIDOM3Node.h"
 
47
#include "nsIDOMStyleSheetList.h"
 
48
#include "nsIDOMCSSStyleSheet.h"
 
49
#include "nsIDOMCSSRuleList.h"
 
50
#include "nsIDOMCSSStyleRule.h"
 
51
#include "nsIDOMCSSStyleDeclaration.h"
 
52
#include "nsIDOMCSSImportRule.h"
 
53
#include "nsIDOMCSSMediaRule.h"
 
54
#include "nsIURI.h"
 
55
#include "nsNetUtil.h"
 
56
 
 
57
static NS_DEFINE_CID(kInspectorCSSUtilsCID, NS_INSPECTORCSSUTILS_CID);
 
58
 
 
59
///////////////////////////////////////////////////////////////////////////////
 
60
inCSSValueSearch::inCSSValueSearch()
 
61
  : mResults(nsnull),
 
62
    mProperties(nsnull),
 
63
    mResultCount(0),
 
64
    mPropertyCount(0),
 
65
    mIsActive(PR_FALSE),
 
66
    mHoldResults(PR_TRUE),
 
67
    mReturnRelativeURLs(PR_TRUE),
 
68
    mNormalizeChromeURLs(PR_FALSE)
 
69
{
 
70
  mProperties = new nsCSSProperty[100];
 
71
  mCSSUtils = do_GetService(kInspectorCSSUtilsCID);
 
72
}
 
73
 
 
74
inCSSValueSearch::~inCSSValueSearch()
 
75
{
 
76
  delete[] mProperties;
 
77
  delete mResults;
 
78
}
 
79
 
 
80
NS_IMPL_ISUPPORTS2(inCSSValueSearch, inISearchProcess, inICSSValueSearch)
 
81
 
 
82
///////////////////////////////////////////////////////////////////////////////
 
83
// inISearchProcess
 
84
 
 
85
NS_IMETHODIMP 
 
86
inCSSValueSearch::GetIsActive(PRBool *aIsActive)
 
87
{
 
88
  *aIsActive = mIsActive;
 
89
  return NS_OK;
 
90
}
 
91
 
 
92
NS_IMETHODIMP 
 
93
inCSSValueSearch::GetResultCount(PRInt32 *aResultCount)
 
94
{
 
95
  *aResultCount = mResultCount;
 
96
  return NS_OK;
 
97
}
 
98
 
 
99
NS_IMETHODIMP 
 
100
inCSSValueSearch::GetHoldResults(PRBool *aHoldResults)
 
101
{
 
102
  *aHoldResults = mHoldResults;
 
103
  return NS_OK;
 
104
}
 
105
 
 
106
NS_IMETHODIMP 
 
107
inCSSValueSearch::SetHoldResults(PRBool aHoldResults)
 
108
{
 
109
  mHoldResults = aHoldResults;
 
110
  return NS_OK;
 
111
}
 
112
 
 
113
NS_IMETHODIMP 
 
114
inCSSValueSearch::SearchSync()
 
115
{
 
116
  InitSearch();
 
117
 
 
118
  nsCOMPtr<nsIURI> baseURL;
 
119
  nsCOMPtr<nsIDOM3Node> dom3Node = do_QueryInterface(mDocument);
 
120
  if (dom3Node) {
 
121
    nsAutoString uri;
 
122
    dom3Node->GetBaseURI(uri);
 
123
    NS_NewURI(getter_AddRefs(baseURL), uri);
 
124
  }
 
125
  
 
126
  nsCOMPtr<nsIDOMDocumentStyle> doc = do_QueryInterface(mDocument);
 
127
  if (doc) {
 
128
    nsCOMPtr<nsIDOMStyleSheetList> sheets;
 
129
    nsresult rv = doc->GetStyleSheets(getter_AddRefs(sheets));
 
130
    NS_ENSURE_SUCCESS(rv, NS_OK);
 
131
 
 
132
    PRUint32 length;
 
133
    sheets->GetLength(&length);
 
134
    for (PRUint32 i = 0; i < length; ++i) {
 
135
      nsCOMPtr<nsIDOMStyleSheet> sheet;
 
136
      sheets->Item(i, getter_AddRefs(sheet));
 
137
      nsCOMPtr<nsIDOMCSSStyleSheet> cssSheet = do_QueryInterface(sheet);
 
138
      if (cssSheet)
 
139
        SearchStyleSheet(cssSheet, baseURL);
 
140
    }
 
141
  }
 
142
 
 
143
  // XXX would be nice to search inline style as well.
 
144
 
 
145
  return NS_OK;
 
146
}
 
147
 
 
148
NS_IMETHODIMP 
 
149
inCSSValueSearch::SearchAsync(inISearchObserver *aObserver)
 
150
{
 
151
  InitSearch();
 
152
  mObserver = aObserver;
 
153
 
 
154
  return NS_OK;
 
155
}
 
156
 
 
157
 
 
158
NS_IMETHODIMP
 
159
inCSSValueSearch::SearchStop()
 
160
{
 
161
  KillSearch(inISearchObserver::INTERRUPTED);
 
162
  return NS_OK;
 
163
}
 
164
 
 
165
NS_IMETHODIMP
 
166
inCSSValueSearch::SearchStep(PRBool* _retval)
 
167
{
 
168
 
 
169
  return NS_OK;
 
170
}
 
171
 
 
172
 
 
173
NS_IMETHODIMP 
 
174
inCSSValueSearch::GetStringResultAt(PRInt32 aIndex, nsAString& _retval)
 
175
{
 
176
  if (mHoldResults) {
 
177
    nsAutoString* result = (nsAutoString*)mResults->ElementAt(aIndex);
 
178
    _retval = *result;
 
179
  } else if (aIndex == mResultCount-1) {
 
180
    _retval = mLastResult;
 
181
  } else {
 
182
    return NS_ERROR_FAILURE;
 
183
  }
 
184
  return NS_OK;
 
185
}
 
186
 
 
187
NS_IMETHODIMP 
 
188
inCSSValueSearch::GetIntResultAt(PRInt32 aIndex, PRInt32 *_retval)
 
189
{
 
190
  return NS_ERROR_NOT_IMPLEMENTED;
 
191
}
 
192
 
 
193
NS_IMETHODIMP 
 
194
inCSSValueSearch::GetUIntResultAt(PRInt32 aIndex, PRUint32 *_retval)
 
195
{
 
196
  return NS_ERROR_NOT_IMPLEMENTED;
 
197
}
 
198
 
 
199
///////////////////////////////////////////////////////////////////////////////
 
200
// inICSSValueSearch
 
201
 
 
202
NS_IMETHODIMP 
 
203
inCSSValueSearch::GetDocument(nsIDOMDocument** aDocument)
 
204
{
 
205
  *aDocument = mDocument;
 
206
  NS_IF_ADDREF(*aDocument);
 
207
  return NS_OK;
 
208
}
 
209
 
 
210
NS_IMETHODIMP 
 
211
inCSSValueSearch::SetDocument(nsIDOMDocument* aDocument)
 
212
{
 
213
  mDocument = aDocument;
 
214
  return NS_OK;
 
215
}
 
216
 
 
217
NS_IMETHODIMP 
 
218
inCSSValueSearch::GetBaseURL(PRUnichar** aBaseURL)
 
219
{
 
220
  if (!(*aBaseURL = ToNewUnicode(mBaseURL)))
 
221
    return NS_ERROR_OUT_OF_MEMORY;
 
222
  return NS_OK;
 
223
}
 
224
 
 
225
NS_IMETHODIMP 
 
226
inCSSValueSearch::SetBaseURL(const PRUnichar* aBaseURL)
 
227
{
 
228
  mBaseURL.Assign(aBaseURL);
 
229
  return NS_OK;
 
230
}
 
231
 
 
232
NS_IMETHODIMP 
 
233
inCSSValueSearch::GetReturnRelativeURLs(PRBool* aReturnRelativeURLs)
 
234
{
 
235
  *aReturnRelativeURLs = mReturnRelativeURLs;
 
236
  return NS_OK;
 
237
}
 
238
 
 
239
NS_IMETHODIMP 
 
240
inCSSValueSearch::SetReturnRelativeURLs(PRBool aReturnRelativeURLs)
 
241
{
 
242
  mReturnRelativeURLs = aReturnRelativeURLs;
 
243
  return NS_OK;
 
244
}
 
245
 
 
246
NS_IMETHODIMP 
 
247
inCSSValueSearch::GetNormalizeChromeURLs(PRBool *aNormalizeChromeURLs)
 
248
{
 
249
  *aNormalizeChromeURLs = mNormalizeChromeURLs;
 
250
  return NS_OK;
 
251
}
 
252
 
 
253
NS_IMETHODIMP
 
254
inCSSValueSearch::SetNormalizeChromeURLs(PRBool aNormalizeChromeURLs)
 
255
{
 
256
  mNormalizeChromeURLs = aNormalizeChromeURLs;
 
257
  return NS_OK;
 
258
}
 
259
 
 
260
NS_IMETHODIMP 
 
261
inCSSValueSearch::AddPropertyCriteria(const PRUnichar *aPropName)
 
262
{
 
263
  nsCSSProperty prop;
 
264
  mCSSUtils->LookupCSSProperty(nsDependentString(aPropName), &prop);
 
265
  mProperties[mPropertyCount] = prop;
 
266
  mPropertyCount++;
 
267
  return NS_OK;
 
268
}
 
269
 
 
270
NS_IMETHODIMP 
 
271
inCSSValueSearch::GetTextCriteria(PRUnichar** aTextCriteria)
 
272
{
 
273
  if (!(*aTextCriteria = ToNewUnicode(mTextCriteria)))
 
274
    return NS_ERROR_OUT_OF_MEMORY;
 
275
  return NS_OK;
 
276
}
 
277
 
 
278
NS_IMETHODIMP 
 
279
inCSSValueSearch::SetTextCriteria(const PRUnichar* aTextCriteria)
 
280
{
 
281
  mTextCriteria.Assign(aTextCriteria);
 
282
  return NS_OK;
 
283
}
 
284
 
 
285
///////////////////////////////////////////////////////////////////////////////
 
286
// inCSSValueSearch
 
287
 
 
288
nsresult
 
289
inCSSValueSearch::InitSearch()
 
290
{
 
291
  if (mHoldResults) {
 
292
    mResults = new nsVoidArray();
 
293
  }
 
294
  
 
295
  mResultCount = 0;
 
296
 
 
297
  return NS_OK;
 
298
}
 
299
 
 
300
nsresult
 
301
inCSSValueSearch::KillSearch(PRInt16 aResult)
 
302
{
 
303
  mIsActive = PR_TRUE;
 
304
  mObserver->OnSearchEnd(this, aResult);
 
305
 
 
306
  return NS_OK;
 
307
}
 
308
 
 
309
nsresult
 
310
inCSSValueSearch::SearchStyleSheet(nsIDOMCSSStyleSheet* aStyleSheet, nsIURI* aBaseURL)
 
311
{
 
312
  nsCOMPtr<nsIURI> baseURL;
 
313
  nsAutoString href;
 
314
  aStyleSheet->GetHref(href);
 
315
  if (href.IsEmpty())
 
316
    baseURL = aBaseURL;
 
317
  else
 
318
    NS_NewURI(getter_AddRefs(baseURL), href, nsnull, aBaseURL);
 
319
 
 
320
  nsCOMPtr<nsIDOMCSSRuleList> rules;
 
321
  nsresult rv = aStyleSheet->GetCssRules(getter_AddRefs(rules));
 
322
  NS_ENSURE_SUCCESS(rv, rv);
 
323
 
 
324
  return SearchRuleList(rules, baseURL);
 
325
}
 
326
 
 
327
nsresult
 
328
inCSSValueSearch::SearchRuleList(nsIDOMCSSRuleList* aRuleList, nsIURI* aBaseURL)
 
329
{
 
330
  PRUint32 length;
 
331
  aRuleList->GetLength(&length);
 
332
  for (PRUint32 i = 0; i < length; ++i) {
 
333
    nsCOMPtr<nsIDOMCSSRule> rule;
 
334
    aRuleList->Item(i, getter_AddRefs(rule));
 
335
    PRUint16 type;
 
336
    rule->GetType(&type);
 
337
    switch (type) {
 
338
      case nsIDOMCSSRule::STYLE_RULE: {
 
339
        nsCOMPtr<nsIDOMCSSStyleRule> styleRule = do_QueryInterface(rule);
 
340
        SearchStyleRule(styleRule, aBaseURL);
 
341
      } break;
 
342
      case nsIDOMCSSRule::IMPORT_RULE: {
 
343
        nsCOMPtr<nsIDOMCSSImportRule> importRule = do_QueryInterface(rule);
 
344
        nsCOMPtr<nsIDOMCSSStyleSheet> childSheet;
 
345
        importRule->GetStyleSheet(getter_AddRefs(childSheet));
 
346
        if (childSheet)
 
347
          SearchStyleSheet(childSheet, aBaseURL);
 
348
      } break;
 
349
      case nsIDOMCSSRule::MEDIA_RULE: {
 
350
        nsCOMPtr<nsIDOMCSSMediaRule> mediaRule = do_QueryInterface(rule);
 
351
        nsCOMPtr<nsIDOMCSSRuleList> childRules;
 
352
        mediaRule->GetCssRules(getter_AddRefs(childRules));
 
353
        SearchRuleList(childRules, aBaseURL);
 
354
      } break;
 
355
      default:
 
356
        // XXX handle nsIDOMCSSRule::PAGE_RULE if we ever support it
 
357
        break;
 
358
    }
 
359
  }
 
360
  return NS_OK;
 
361
}
 
362
 
 
363
nsresult
 
364
inCSSValueSearch::SearchStyleRule(nsIDOMCSSStyleRule* aStyleRule, nsIURI* aBaseURL)
 
365
{
 
366
  nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
 
367
  nsresult rv = aStyleRule->GetStyle(getter_AddRefs(decl));
 
368
  NS_ENSURE_SUCCESS(rv, rv);
 
369
  
 
370
  PRUint32 length;
 
371
  decl->GetLength(&length);
 
372
  nsAutoString property, value;
 
373
  for (PRUint32 i = 0; i < length; ++i) {
 
374
    decl->Item(i, property);
 
375
    // XXX This probably ought to use GetPropertyCSSValue if it were
 
376
    // implemented.
 
377
    decl->GetPropertyValue(property, value);
 
378
    SearchStyleValue(value, aBaseURL);
 
379
  }
 
380
  return NS_OK;
 
381
}
 
382
 
 
383
nsresult
 
384
inCSSValueSearch::SearchStyleValue(const nsAFlatString& aValue, nsIURI* aBaseURL)
 
385
{
 
386
  if (StringBeginsWith(aValue, NS_LITERAL_STRING("url(")) &&
 
387
      StringEndsWith(aValue, NS_LITERAL_STRING(")"))) {
 
388
    const nsASingleFragmentString &url =
 
389
      Substring(aValue, 4, aValue.Length() - 5);
 
390
    // XXXldb Need to do more with |mReturnRelativeURLs|, perhaps?
 
391
    nsCOMPtr<nsIURI> uri;
 
392
    nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nsnull, aBaseURL);
 
393
    NS_ENSURE_SUCCESS(rv, rv);
 
394
    nsCAutoString spec;
 
395
    uri->GetSpec(spec);
 
396
    nsAutoString *result = new NS_ConvertUTF8toUTF16(spec);
 
397
    if (mReturnRelativeURLs)
 
398
      EqualizeURL(result);
 
399
    mResults->AppendElement(result);
 
400
    ++mResultCount;
 
401
  }
 
402
 
 
403
  return NS_OK;
 
404
}
 
405
 
 
406
nsresult
 
407
inCSSValueSearch::EqualizeURL(nsAutoString* aURL)
 
408
{
 
409
  if (mNormalizeChromeURLs) {
 
410
    if (aURL->Find("chrome://", PR_FALSE, 0, 1) >= 0) {
 
411
      PRUint32 len = aURL->Length();
 
412
      char* result = new char[len-8];
 
413
      const PRUnichar* src = aURL->get();
 
414
      PRUint32 i = 9;
 
415
      PRUint32 milestone = 0;
 
416
      PRUint32 s = 0;
 
417
      while (i < len) {
 
418
        if (src[i] == '/') {
 
419
          milestone += 1;
 
420
        } 
 
421
        if (milestone != 1) {
 
422
          result[i-9-s] = src[i];
 
423
        } else {
 
424
          s++;
 
425
        }
 
426
        i++;
 
427
      }
 
428
      result[i-9-s] = 0;
 
429
 
 
430
      aURL->AssignWithConversion(result);
 
431
      delete [] result;
 
432
    }
 
433
  } else {
 
434
  }
 
435
 
 
436
  return NS_OK;
 
437
}