Attachment #377396: chrome patch rev 1 for bug #492008

View | Details | Raw Unified | Return to bug 492008
Collapse All | Expand All

(-)a/chrome/public/nsIToolkitChromeRegistry.idl (-25 / +1 lines)
Line     Link Here 
 Lines 36-79    Link Here 
36
 *
36
 *
37
 * ***** END LICENSE BLOCK ***** */
37
 * ***** END LICENSE BLOCK ***** */
38
38
39
#include "nsIChromeRegistry.idl"
39
#include "nsIChromeRegistry.idl"
40
40
41
interface nsIURI;
41
interface nsIURI;
42
interface nsIUTF8StringEnumerator;
42
interface nsIUTF8StringEnumerator;
43
43
44
[scriptable, uuid(94490b3f-f094-418e-b1b9-73878d29bff3)]
44
[scriptable, uuid(8727651c-9530-45a0-b81e-0e0690c30c50)]
45
interface nsIToolkitChromeRegistry : nsIXULChromeRegistry
45
interface nsIToolkitChromeRegistry : nsIXULChromeRegistry
46
{
46
{
47
  /**
47
  /**
48
   * The "canonical" manifest is a plaintext file which sits outside of a
49
   * JAR file. To provide backwards-compatibility with contents.rdf, we provide
50
   * this function which reads a contents.rdf manifest and writes it to a file.
51
   *
52
   * @param aOldManifestURI  The URI of an old manifest to read, without
53
   *                         the trailing "contents.rdf", e.g.
54
   *                         "jar:resource:///chrome/foo.jar!/content/foo/" or
55
   *                         "file://path/to/contents/rdf/"
56
   * @param aFile            The URI of a manifest file to write. It's a good
57
   *                         idea to use a resource: URI if possible.
58
   * @param aBaseURI         The base URI for relative path creation
59
   *                         "jar:resource:///chrome/foo.jar!/content/foo/"
60
   *                         this is a separate param from aOldManifestURI so
61
   *                         the "contents.rdf" can be read outside of the jar
62
   *                         to keep the zipreader cache from holding it open.
63
   * @param aAppend          Whether we should append to an existing manifest
64
   *                         or truncate and start empty.
65
   * @param aSkinOnly        Only allow skin packages.
66
   */
67
  void processContentsManifest(in nsIURI aOldManifestURI, in nsIURI aFile,
68
                               in nsIURI aBaseURI, in boolean aAppend,
69
                               in boolean aSkinOnly);
70
71
  /**
72
   * If the OS has a "high-visibility" or "disabled-friendly" theme set,
48
   * If the OS has a "high-visibility" or "disabled-friendly" theme set,
73
   * we want to force mozilla into the classic theme, which (for the most part
49
   * we want to force mozilla into the classic theme, which (for the most part
74
   * obeys the system color/font settings. We cannot do this at initialization,
50
   * obeys the system color/font settings. We cannot do this at initialization,
75
   * because it depends on the toolkit (GTK2) being initialized, which is
51
   * because it depends on the toolkit (GTK2) being initialized, which is
76
   * not the case in some embedding situations. Embedders have to manually
52
   * not the case in some embedding situations. Embedders have to manually
77
   * call this method during the startup process.
53
   * call this method during the startup process.
78
   */
54
   */
79
  void checkForOSAccessibility();
55
  void checkForOSAccessibility();
(-)a/chrome/src/nsChromeRegistry.cpp (-600 lines)
Line     Link Here 
 Lines 110-148    Link Here 
110
#include "nsISupportsArray.h"
110
#include "nsISupportsArray.h"
111
#include "nsIVersionComparator.h"
111
#include "nsIVersionComparator.h"
112
#include "nsIWindowMediator.h"
112
#include "nsIWindowMediator.h"
113
#include "nsIXPConnect.h"
113
#include "nsIXPConnect.h"
114
#include "nsIXULAppInfo.h"
114
#include "nsIXULAppInfo.h"
115
#include "nsIXULRuntime.h"
115
#include "nsIXULRuntime.h"
116
#include "nsPresShellIterator.h"
116
#include "nsPresShellIterator.h"
117
117
118
#ifdef MOZ_XUL
119
// keep all the RDF stuff together, in case we can remove it in the far future
120
#include "rdf.h"
121
#include "nsRDFCID.h"
122
#include "nsIRDFService.h"
123
#include "nsIRDFDataSource.h"
124
#include "nsIRDFObserver.h"
125
#include "nsIRDFRemoteDataSource.h"
126
#include "nsIRDFXMLSink.h"
127
#include "nsIRDFResource.h"
128
#include "nsIRDFDataSource.h"
129
#include "nsIRDFContainer.h"
130
#include "nsIRDFContainerUtils.h"
131
132
#define CHROME_URI "http://www.mozilla.org/rdf/chrome#"
133
134
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, packages);
135
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, package);
136
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, name);
137
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, platformPackage);
138
139
#endif
140
141
#define UILOCALE_CMD_LINE_ARG "UILocale"
118
#define UILOCALE_CMD_LINE_ARG "UILocale"
142
119
143
#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
120
#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
144
#define SELECTED_LOCALE_PREF "general.useragent.locale"
121
#define SELECTED_LOCALE_PREF "general.useragent.locale"
145
#define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
122
#define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
146
123
147
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
124
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
148
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
125
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 Lines 480-510   getUILangCountry(nsACString& aUILang) Link Here 
480
  return NS_OK;
457
  return NS_OK;
481
}
458
}
482
459
483
nsresult
460
nsresult
484
nsChromeRegistry::Init()
461
nsChromeRegistry::Init()
485
{
462
{
486
  nsresult rv;
463
  nsresult rv;
487
464
488
  // these atoms appear in almost every chrome registry contents.rdf
489
  // in some form or another. making static atoms prevents the atoms
490
  // from constantly being created/destroyed during parsing
491
  
492
  static const nsStaticAtom atoms[] = {
493
    { "chrome",        nsnull },
494
    { "NC",            nsnull },
495
    { "allowScripts",  nsnull },
496
    { "package",       nsnull },
497
    { "packages",      nsnull },
498
    { "hasOverlays",   nsnull },
499
  };
500
501
  NS_RegisterStaticAtoms(atoms, NS_ARRAY_LENGTH(atoms));
502
  
503
  // Check to see if necko and the JAR protocol handler are registered yet
465
  // Check to see if necko and the JAR protocol handler are registered yet
504
  // if not, somebody is doing work during XPCOM registration that they
466
  // if not, somebody is doing work during XPCOM registration that they
505
  // shouldn't be doing. See bug 292549, where JS components are trying
467
  // shouldn't be doing. See bug 292549, where JS components are trying
506
  // to call Components.utils.import("chrome:///") early in registration
468
  // to call Components.utils.import("chrome:///") early in registration
507
469
508
  nsCOMPtr<nsIIOService> io (do_GetIOService());
470
  nsCOMPtr<nsIIOService> io (do_GetIOService());
509
  if (!io) return NS_ERROR_FAILURE;
471
  if (!io) return NS_ERROR_FAILURE;
510
472
 Lines 1192-1252   nsChromeRegistry::CheckForNewChrome() Link Here 
1192
  mOverlayHash.Clear();
1154
  mOverlayHash.Clear();
1193
  mStyleHash.Clear();
1155
  mStyleHash.Clear();
1194
  mOverrideTable.Clear();
1156
  mOverrideTable.Clear();
1195
1157
1196
  nsCOMPtr<nsIURI> manifestURI;
1158
  nsCOMPtr<nsIURI> manifestURI;
1197
  rv = NS_NewURI(getter_AddRefs(manifestURI),
1159
  rv = NS_NewURI(getter_AddRefs(manifestURI),
1198
                 NS_LITERAL_CSTRING("resource:///chrome/app-chrome.manifest"));
1160
                 NS_LITERAL_CSTRING("resource:///chrome/app-chrome.manifest"));
1199
1161
1200
  // this is the main manifest; if it doesn't exist we generate it from
1201
  // installed-chrome.txt. When the build system learns about the new system,
1202
  // this code can go away.
1203
1204
  nsCOMPtr<nsIFileURL> manifestFileURL (do_QueryInterface(manifestURI));
1162
  nsCOMPtr<nsIFileURL> manifestFileURL (do_QueryInterface(manifestURI));
1205
  NS_ASSERTION(manifestFileURL, "Not a nsIFileURL!");
1163
  NS_ASSERTION(manifestFileURL, "Not a nsIFileURL!");
1206
  NS_ENSURE_TRUE(manifestFileURL, NS_ERROR_UNEXPECTED);
1164
  NS_ENSURE_TRUE(manifestFileURL, NS_ERROR_UNEXPECTED);
1207
1165
1208
  nsCOMPtr<nsIFile> manifest;
1166
  nsCOMPtr<nsIFile> manifest;
1209
  manifestFileURL->GetFile(getter_AddRefs(manifest));
1167
  manifestFileURL->GetFile(getter_AddRefs(manifest));
1210
  NS_ENSURE_TRUE(manifest, NS_ERROR_FAILURE);
1168
  NS_ENSURE_TRUE(manifest, NS_ERROR_FAILURE);
1211
1169
1212
  PRBool exists;
1170
  PRBool exists;
1213
  rv = manifest->Exists(&exists);
1171
  rv = manifest->Exists(&exists);
1214
  NS_ENSURE_SUCCESS(rv, rv);
1172
  NS_ENSURE_SUCCESS(rv, rv);
1215
1173
1216
#ifdef DEBUG
1217
  // In debug builds, installed-chrome.txt may change during development;
1218
  // we just rebuild it every time because we're not worried about startup
1219
  // time or other bad/goodness.
1220
  if (exists) {
1221
    manifest->Remove(PR_FALSE);
1222
    exists = PR_FALSE;
1223
  }
1224
#endif
1225
1226
  if (!exists) {
1227
    nsCOMPtr<nsIFile> installed;
1228
    manifest->Clone(getter_AddRefs(installed));
1229
    if (!installed)
1230
      return NS_ERROR_OUT_OF_MEMORY;
1231
1232
    nsCOMPtr<nsILocalFile> linstalled (do_QueryInterface(installed));
1233
    NS_ENSURE_TRUE(linstalled, NS_NOINTERFACE);
1234
1235
    linstalled->SetNativeLeafName(NS_LITERAL_CSTRING("installed-chrome.txt"));
1236
1237
    rv = linstalled->Exists(&exists);
1238
    NS_ENSURE_SUCCESS(rv, rv);
1239
1240
    // process installed-chrome.txt into app-chrome.manifest
1241
    if (exists)
1242
      ProcessNewChromeFile(linstalled, manifestURI);
1243
  }
1244
1245
  nsCOMPtr<nsIProperties> dirSvc (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
1174
  nsCOMPtr<nsIProperties> dirSvc (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
1246
  NS_ENSURE_TRUE(dirSvc, NS_ERROR_FAILURE);
1175
  NS_ENSURE_TRUE(dirSvc, NS_ERROR_FAILURE);
1247
1176
1248
  // check the extra chrome directories
1177
  // check the extra chrome directories
1249
  nsCOMPtr<nsISimpleEnumerator> chromeML;
1178
  nsCOMPtr<nsISimpleEnumerator> chromeML;
1250
  rv = dirSvc->Get(NS_CHROME_MANIFESTS_FILE_LIST, NS_GET_IID(nsISimpleEnumerator),
1179
  rv = dirSvc->Get(NS_CHROME_MANIFESTS_FILE_LIST, NS_GET_IID(nsISimpleEnumerator),
1251
                   getter_AddRefs(chromeML));
1180
                   getter_AddRefs(chromeML));
1252
  if (NS_FAILED(rv)) {
1181
  if (NS_FAILED(rv)) {
 Lines 1353-1487   nsChromeRegistry::WrappersEnabled(nsIURI Link Here 
1353
    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
1282
    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
1354
                                                    & (nsACString&) package,
1283
                                                    & (nsACString&) package,
1355
                                                    PL_DHASH_LOOKUP));
1284
                                                    PL_DHASH_LOOKUP));
1356
1285
1357
  return PL_DHASH_ENTRY_IS_LIVE(entry) &&
1286
  return PL_DHASH_ENTRY_IS_LIVE(entry) &&
1358
         entry->flags & PackageEntry::XPCNATIVEWRAPPERS;
1287
         entry->flags & PackageEntry::XPCNATIVEWRAPPERS;
1359
}
1288
}
1360
1289
1361
nsresult
1362
nsChromeRegistry::ProcessNewChromeFile(nsILocalFile *aListFile, nsIURI* aManifest)
1363
{
1364
  nsresult rv;
1365
1366
  PRFileDesc *file;
1367
  rv = aListFile->OpenNSPRFileDesc(PR_RDONLY, 0, &file);
1368
  NS_ENSURE_SUCCESS(rv, rv);
1369
1370
  PRInt32 n, size;
1371
  char *buf;
1372
1373
  size = PR_Available(file);
1374
  if (size == -1) {
1375
    rv = NS_ERROR_UNEXPECTED;
1376
    goto end;
1377
  }
1378
1379
  buf = (char *) malloc(size + 1);
1380
  if (!buf) {
1381
    rv = NS_ERROR_OUT_OF_MEMORY;
1382
    goto end;
1383
  }
1384
1385
  n = PR_Read(file, buf, size);
1386
  if (n > 0)
1387
    rv = ProcessNewChromeBuffer(buf, size, aManifest);
1388
  free(buf);
1389
1390
end:
1391
  PR_Close(file);
1392
  return rv;
1393
}
1394
1395
nsresult
1396
nsChromeRegistry::ProcessNewChromeBuffer(char *aBuffer, PRInt32 aLength,
1397
                                         nsIURI* aManifest)
1398
{
1399
  nsresult rv = NS_OK;
1400
  char   *bufferEnd = aBuffer + aLength;
1401
  char   *chromeType,      // "content", "locale" or "skin"
1402
         *chromeProfile,   // "install" or "profile"
1403
         *chromeLocType,   // type of location (local path or URL)
1404
         *chromeLocation;  // base location of chrome (jar file)
1405
1406
  nsCOMPtr<nsIURI> baseURI;
1407
1408
  // process chromeType, chromeProfile, chromeLocType, chromeLocation
1409
  while (aBuffer < bufferEnd) {
1410
    // parse one line of installed-chrome.txt
1411
    chromeType = aBuffer;
1412
    while (aBuffer < bufferEnd && *aBuffer != ',')
1413
      ++aBuffer;
1414
    *aBuffer = '\0';
1415
1416
    chromeProfile = ++aBuffer;
1417
    if (aBuffer >= bufferEnd)
1418
      break;
1419
1420
    while (aBuffer < bufferEnd && *aBuffer != ',')
1421
      ++aBuffer;
1422
    *aBuffer = '\0';
1423
1424
    chromeLocType = ++aBuffer;
1425
    if (aBuffer >= bufferEnd)
1426
      break;
1427
1428
    while (aBuffer < bufferEnd && *aBuffer != ',')
1429
      ++aBuffer;
1430
    *aBuffer = '\0';
1431
1432
    chromeLocation = ++aBuffer;
1433
    if (aBuffer >= bufferEnd)
1434
      break;
1435
1436
    while (aBuffer < bufferEnd &&
1437
           (*aBuffer != '\r' && *aBuffer != '\n' && *aBuffer != ' '))
1438
      ++aBuffer;
1439
    *aBuffer = '\0';
1440
1441
    // process the line
1442
    // We don't do skin or locale selection from installed-chrome.txt since
1443
    // ffox 0.9. Just ignore the "select" lines.
1444
    if (strcmp(chromeLocType,"select")) {
1445
      if (!strcmp(chromeLocType, "path")) {
1446
        // location is a (full) path. convert it to an URL.
1447
1448
        /* this is some convoluted shit... this creates a file, inits it with
1449
         * the path parsed above (chromeLocation), makes a url, and inits it
1450
         * with the file created. the purpose of this is just to have the
1451
         * canonical url of the stupid thing.
1452
         */
1453
        nsCOMPtr<nsILocalFile> chromeFile;
1454
        rv = NS_NewNativeLocalFile(nsDependentCString(chromeLocation),
1455
                                   PR_TRUE, getter_AddRefs(chromeFile));
1456
        NS_ENSURE_SUCCESS(rv, rv);
1457
1458
        /* 
1459
         * all we want here is the canonical url
1460
         */
1461
        rv = NS_NewFileURI(getter_AddRefs(baseURI), chromeFile);
1462
        if (NS_FAILED(rv)) return rv;
1463
      }
1464
      else {
1465
        rv = NS_NewURI(getter_AddRefs(baseURI), chromeLocation);
1466
        if (NS_FAILED(rv)) return rv;
1467
      }
1468
1469
      ProcessContentsManifest(baseURI, aManifest, baseURI, PR_TRUE,
1470
                              strcmp(chromeType, "skin") == 0);
1471
    }
1472
    
1473
    while (aBuffer < bufferEnd && (*aBuffer == '\0' || *aBuffer == ' ' || *aBuffer == '\r' || *aBuffer == '\n'))
1474
      ++aBuffer;
1475
  }
1476
1477
  return NS_OK;
1478
}
1479
1480
NS_IMETHODIMP nsChromeRegistry::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
1290
NS_IMETHODIMP nsChromeRegistry::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
1481
{
1291
{
1482
  nsresult rv = NS_OK;
1292
  nsresult rv = NS_OK;
1483
1293
1484
  if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
1294
  if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
1485
    nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
1295
    nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
1486
    NS_ASSERTION(prefs, "Bad observer call!");
1296
    NS_ASSERTION(prefs, "Bad observer call!");
1487
1297
 Lines 1522-1947   NS_IMETHODIMP nsChromeRegistry::Observe( Link Here 
1522
  }
1332
  }
1523
  else {
1333
  else {
1524
    NS_ERROR("Unexpected observer topic!");
1334
    NS_ERROR("Unexpected observer topic!");
1525
  }
1335
  }
1526
1336
1527
  return rv;
1337
  return rv;
1528
}
1338
}
1529
1339
1530
#ifdef MOZ_XUL
1531
static nsresult
1532
GetContainerEnumerator(nsIRDFDataSource* ds, nsIRDFResource* res,
1533
                       nsISimpleEnumerator* *aResult, PRInt32 *aCountResult = nsnull)
1534
{
1535
  nsresult rv;
1536
1537
  nsCOMPtr<nsIRDFContainer> container
1538
    (do_CreateInstance("@mozilla.org/rdf/container;1"));
1539
  NS_ENSURE_TRUE(container, NS_ERROR_FAILURE);
1540
1541
  rv = container->Init(ds, res);
1542
  if (NS_FAILED(rv)) return rv;
1543
1544
  if (aCountResult)
1545
    container->GetCount(aCountResult);
1546
1547
  return container->GetElements(aResult);
1548
}
1549
1550
static void
1551
FollowLiteral(nsIRDFDataSource* ds, nsIRDFResource* res,
1552
              nsIRDFResource* arc, nsACString& result)
1553
{
1554
  nsresult rv;
1555
1556
  nsCOMPtr<nsIRDFNode> node;
1557
  rv = ds->GetTarget(res, arc, PR_TRUE, getter_AddRefs(node));
1558
  if (NS_FAILED(rv) || !node) {
1559
    result.Truncate();
1560
    return;
1561
  }
1562
1563
  nsCOMPtr<nsIRDFLiteral> literal (do_QueryInterface(node));
1564
  if (!literal) {
1565
    NS_ERROR("Arc found, but doesn't point to expected literal!");
1566
    result.Truncate();
1567
    return;
1568
  }
1569
1570
  const PRUnichar* value;
1571
  literal->GetValueConst(&value);
1572
  CopyUTF16toUTF8(value, result);
1573
}
1574
1575
static void
1576
FollowResource(nsIRDFDataSource* ds, nsIRDFResource* res, nsIRDFResource* arc,
1577
               nsIRDFResource* *result)
1578
{
1579
  nsresult rv;
1580
1581
  nsCOMPtr<nsIRDFNode> node;
1582
  rv = ds->GetTarget(res, arc, PR_TRUE, getter_AddRefs(node));
1583
  if (NS_FAILED(rv) || !node) {
1584
    *result = nsnull;
1585
    return;
1586
  }
1587
1588
  CallQueryInterface(node, result);
1589
}
1590
1591
static void
1592
GetRelativePath(nsIURI* base, nsIURI* relative, nsACString& result)
1593
{
1594
  nsresult rv;
1595
1596
  nsCOMPtr<nsIJARURI> jarrelative (do_QueryInterface(relative));
1597
  if (jarrelative) {
1598
    nsCOMPtr<nsIURI> jarbase;
1599
    jarrelative->GetJARFile(getter_AddRefs(jarbase));
1600
1601
    nsCAutoString relativeBase;
1602
    GetRelativePath(base, jarbase, relativeBase);
1603
1604
    nsCAutoString jarEntry;
1605
    jarrelative->GetJAREntry(jarEntry);
1606
1607
    result.Assign(NS_LITERAL_CSTRING("jar:"));
1608
    result.Append(relativeBase);
1609
    result.Append(NS_LITERAL_CSTRING("!/"));
1610
    result.Append(jarEntry);
1611
    return;
1612
  }
1613
1614
  nsCOMPtr<nsIURL> baseURL (do_QueryInterface(base));
1615
  if (!baseURL) {
1616
    relative->GetSpec(result);
1617
    return;
1618
  }
1619
1620
  rv = baseURL->GetRelativeSpec(relative, result);
1621
  if (NS_FAILED(rv)) {
1622
    relative->GetSpec(result);
1623
  }
1624
}
1625
1626
static const PRInt32 kNSPR_APPEND_FLAGS = PR_WRONLY | PR_CREATE_FILE | PR_APPEND;
1627
static const PRInt32 kNSPR_TRUNCATE_FLAGS = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
1628
1629
NS_IMETHODIMP
1630
nsChromeRegistry::ProcessContentsManifest(nsIURI* aOldManifest, nsIURI* aFile,
1631
                                          nsIURI* aBaseURI, PRBool aAppend,
1632
                                          PRBool aSkinOnly)
1633
{
1634
  nsresult rv;
1635
1636
  nsCAutoString relativePath;
1637
  GetRelativePath(aFile, aBaseURI, relativePath);
1638
1639
  nsCAutoString spec;
1640
  aOldManifest->GetSpec(spec);
1641
1642
  NS_ASSERTION(spec.Last() == '/', "installed-chrome manifest URI doesn't end in a slash! It probably won't work.");
1643
1644
  spec.AppendLiteral("contents.rdf");
1645
1646
  nsCOMPtr<nsIRDFService> rdfs (do_GetService("@mozilla.org/rdf/rdf-service;1"));
1647
  NS_ENSURE_TRUE(rdfs, NS_ERROR_FAILURE);
1648
1649
  nsCOMPtr<nsIRDFResource> namearc, platformarc;
1650
  rdfs->GetResource(NS_LITERAL_CSTRING(kURICHROME_name),
1651
                    getter_AddRefs(namearc));
1652
  rdfs->GetResource(NS_LITERAL_CSTRING(kURICHROME_platformPackage),
1653
                    getter_AddRefs(platformarc));
1654
  if (!(namearc && platformarc))
1655
    return NS_ERROR_FAILURE;
1656
1657
  nsCOMPtr<nsIRDFDataSource> ds;
1658
  rv = rdfs->GetDataSourceBlocking(spec.get(), getter_AddRefs(ds));
1659
  if (NS_FAILED(rv)) {
1660
    LogMessage("Failed to load old-style contents.rdf at '%s'.",
1661
               spec.get());
1662
    return rv;
1663
  }
1664
1665
  nsCOMPtr<nsIFileURL> fileURL (do_QueryInterface(aFile));
1666
  NS_ENSURE_TRUE(fileURL, NS_ERROR_INVALID_ARG);
1667
1668
  nsCOMPtr<nsIFile> file;
1669
  rv = fileURL->GetFile(getter_AddRefs(file));
1670
  NS_ENSURE_SUCCESS(rv, rv);
1671
1672
  nsCOMPtr<nsILocalFile> lfile (do_QueryInterface(file));
1673
  NS_ENSURE_TRUE(lfile, NS_ERROR_NO_INTERFACE);
1674
1675
  PRFileDesc* fd;
1676
  rv = lfile->OpenNSPRFileDesc(aAppend ? kNSPR_APPEND_FLAGS : kNSPR_TRUNCATE_FLAGS,
1677
                               0664, &fd);
1678
  NS_ENSURE_SUCCESS(rv, rv);
1679
1680
  if (aAppend)
1681
    PR_Write(fd, "\n", 1);
1682
1683
  nsCOMPtr<nsIRDFResource> root;
1684
  rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:skin:root"),
1685
                         getter_AddRefs(root));
1686
  if (NS_SUCCEEDED(rv))
1687
    ProcessProvider(fd, rdfs, ds, root, PR_FALSE, relativePath);
1688
1689
  rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:stylesheets"),
1690
                         getter_AddRefs(root));
1691
  if (NS_SUCCEEDED(rv))
1692
    ProcessOverlays(fd, ds, root, NS_LITERAL_CSTRING("style"));
1693
1694
  if (!aSkinOnly) {
1695
    rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:locale:root"),
1696
                           getter_AddRefs(root));
1697
    if (NS_SUCCEEDED(rv))
1698
      ProcessProvider(fd, rdfs, ds, root, PR_TRUE, relativePath);
1699
1700
    rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:overlays"),
1701
                         getter_AddRefs(root));
1702
    if (NS_SUCCEEDED(rv))
1703
      ProcessOverlays(fd, ds, root, NS_LITERAL_CSTRING("overlay"));
1704
1705
    /* content packages are easier, but different */
1706
1707
    rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:package:root"),
1708
                           getter_AddRefs(root));
1709
1710
    nsCOMPtr<nsISimpleEnumerator> packages;
1711
    if (NS_SUCCEEDED(rv))
1712
      rv = GetContainerEnumerator(ds, root, getter_AddRefs(packages));
1713
1714
    if (NS_SUCCEEDED(rv)) {
1715
      PRBool more;
1716
      nsCOMPtr<nsISupports> next;
1717
      nsCOMPtr<nsIRDFResource> package;
1718
1719
      while (NS_SUCCEEDED(packages->HasMoreElements(&more)) && more) {
1720
        packages->GetNext(getter_AddRefs(next));
1721
1722
        package = do_QueryInterface(next);
1723
        if (!package) {
1724
          NS_WARNING("Arc from urn:mozilla:package:root points to non-resource node.");
1725
          continue;
1726
        }
1727
1728
        nsCAutoString name;
1729
        FollowLiteral(ds, package, namearc, name);
1730
        if (name.IsEmpty())
1731
          continue;
1732
1733
        nsCAutoString isPlatform;
1734
        FollowLiteral(ds, package, platformarc, isPlatform);
1735
        name.Insert(NS_LITERAL_CSTRING("content\t"), 0);
1736
        name.Append('\t');
1737
        name.Append(relativePath);
1738
        if (!isPlatform.IsEmpty())
1739
          name.AppendLiteral("\tplatform");
1740
1741
        name.AppendLiteral(NS_LINEBREAK);
1742
        PR_Write(fd, name.get(), name.Length());
1743
      }
1744
    }
1745
  }
1746
1747
  PR_Close(fd);
1748
1749
  return NS_OK;
1750
}
1751
1752
static void
1753
GetResourceName(nsIRDFResource* res, nsACString& result)
1754
{
1755
  // we need to get the provider name. Instead of doing something sane,
1756
  // we munge the resource URI, looking from the right for colons.
1757
1758
  nsCAutoString providerURI;
1759
  res->GetValueUTF8(providerURI);
1760
1761
  PRInt32 found = providerURI.RFindChar(':');
1762
  if (found == kNotFound) {
1763
    result.Truncate();
1764
    return;
1765
  }
1766
1767
  result.Assign(Substring(providerURI, found + 1));
1768
}
1769
1770
1771
void
1772
nsChromeRegistry::ProcessProvider(PRFileDesc *fd, nsIRDFService* aRDFs,
1773
                                  nsIRDFDataSource* aDS, nsIRDFResource* aRoot,
1774
                                  PRBool aIsLocale, const nsACString& aBaseURL)
1775
{
1776
  NS_NAMED_LITERAL_CSTRING(kSlash, "/");
1777
  NS_NAMED_LITERAL_CSTRING(kTab, "\t");
1778
1779
  nsresult rv;
1780
1781
  nsCOMPtr<nsIRDFResource> packagesarc;
1782
  aRDFs->GetResource(NS_LITERAL_CSTRING(kURICHROME_packages),
1783
                    getter_AddRefs(packagesarc));
1784
  if (!packagesarc) return;
1785
1786
  nsCOMPtr<nsISimpleEnumerator> providers;
1787
  rv = GetContainerEnumerator(aDS, aRoot, getter_AddRefs(providers));
1788
  if (NS_FAILED(rv)) {
1789
    return;
1790
  }
1791
1792
  nsCOMPtr<nsISupports> next;
1793
1794
  PRBool more;
1795
  while (NS_SUCCEEDED(providers->HasMoreElements(&more)) && more) {
1796
    providers->GetNext(getter_AddRefs(next));
1797
    NS_ASSERTION(next, "GetNext failed after HasMoreElements succeeded.");
1798
1799
    nsCOMPtr<nsIRDFResource> provider (do_QueryInterface(next));
1800
    if (!provider) {
1801
      NS_WARNING("Provider isn't a nsIRDFResource.");
1802
      continue;
1803
    }
1804
1805
    nsCAutoString providerName;
1806
    GetResourceName(provider, providerName);
1807
    if (providerName.IsEmpty()) {
1808
      NS_WARNING("Couldn't calculate resource name.");
1809
      continue;
1810
    }
1811
1812
    nsCOMPtr<nsIRDFResource> packages;
1813
    FollowResource(aDS, provider, packagesarc, getter_AddRefs(packages));
1814
    if (!packages) {
1815
      NS_WARNING("No chrome:packages arc found!");
1816
      continue;
1817
    }
1818
1819
    PRInt32 count;
1820
    nsCOMPtr<nsISimpleEnumerator> packageList;
1821
    rv = GetContainerEnumerator(aDS, packages, getter_AddRefs(packageList), &count);
1822
    if (NS_FAILED(rv)) {
1823
      NS_WARNING("chrome:packages was not a sequence.");
1824
      continue;
1825
    }
1826
1827
    nsCOMPtr<nsISupports> nextPackage;
1828
1829
    PRBool morePackages;
1830
    while (NS_SUCCEEDED(packageList->HasMoreElements(&morePackages)) &&
1831
           morePackages) {
1832
      packageList->GetNext(getter_AddRefs(nextPackage));
1833
1834
      nsCOMPtr<nsIRDFResource> packageRes (do_QueryInterface(nextPackage));
1835
      if (!packageRes) {
1836
        NS_WARNING("chrome:packages Seq points to a non-resource!");
1837
        continue;
1838
      }
1839
1840
      nsCAutoString packageName;
1841
      GetResourceName(packageRes, packageName);
1842
      if (packageName.IsEmpty()) {
1843
        NS_WARNING("couldn't extract a package name.");
1844
        continue;
1845
      }
1846
1847
      nsCAutoString line;
1848
1849
      if (aIsLocale)
1850
        line.AppendLiteral("locale\t");
1851
      else
1852
        line.AppendLiteral("skin\t");
1853
1854
      line += packageName + kTab + providerName + kTab + aBaseURL;
1855
      if (count > 1) {
1856
        line += packageName + kSlash;
1857
      }
1858
      line.AppendLiteral(NS_LINEBREAK);
1859
      PR_Write(fd, line.get(), line.Length());
1860
    }
1861
  }
1862
}
1863
1864
static void
1865
GetLiteralText(nsIRDFLiteral* lit, nsACString& result)
1866
{
1867
  const PRUnichar* value;
1868
  lit->GetValueConst(&value);
1869
  CopyUTF16toUTF8(value, result);
1870
}
1871
1872
void
1873
nsChromeRegistry::ProcessOverlays(PRFileDesc *fd, nsIRDFDataSource* aDS,
1874
                                  nsIRDFResource* aRoot,
1875
                                  const nsCSubstring& aType)
1876
{
1877
  NS_NAMED_LITERAL_CSTRING(kTab, "\t");
1878
  NS_NAMED_LITERAL_CSTRING(kLinebreak, NS_LINEBREAK);
1879
1880
  nsresult rv;
1881
1882
  nsCOMPtr<nsISimpleEnumerator> overlaids;
1883
  rv = GetContainerEnumerator(aDS, aRoot, getter_AddRefs(overlaids));
1884
  if (NS_FAILED(rv)) {
1885
    return;
1886
  }
1887
1888
  nsCOMPtr<nsISupports> next;
1889
  PRBool more;
1890
  while (NS_SUCCEEDED(overlaids->HasMoreElements(&more)) && more) {
1891
    overlaids->GetNext(getter_AddRefs(next));
1892
    NS_ASSERTION(next, "GetNext failed after HasMoreElements succeeded.");
1893
1894
    nsCOMPtr<nsIRDFResource> overlaid (do_QueryInterface(next));
1895
    if (!overlaid) {
1896
      NS_WARNING("Overlay arc is not a nsIRDFResource.");
1897
      continue;
1898
    }
1899
1900
    nsCAutoString overlaidName;
1901
    overlaid->GetValueUTF8(overlaidName);
1902
1903
    nsCOMPtr<nsISimpleEnumerator> overlays;
1904
    rv = GetContainerEnumerator(aDS, overlaid, getter_AddRefs(overlays));
1905
    if (NS_FAILED(rv))
1906
      continue;
1907
1908
    while (NS_SUCCEEDED(overlays->HasMoreElements(&more)) && more) {
1909
      overlays->GetNext(getter_AddRefs(next));
1910
      NS_ASSERTION(next, "GetNext failed after HasMoreElements succeeded.");
1911
1912
      nsCOMPtr<nsIRDFLiteral> overlay (do_QueryInterface(next));
1913
      if (!overlay) {
1914
        NS_WARNING("Overlay was not an RDF literal.");
1915
        continue;
1916
      }
1917
1918
      nsCAutoString overlayName;
1919
      GetLiteralText(overlay, overlayName);
1920
1921
      overlayName.Insert(aType + kTab + overlaidName + kTab, 0);
1922
      overlayName.Append(kLinebreak);
1923
      PR_Write(fd, overlayName.get(), overlayName.Length());
1924
    }
1925
  }
1926
}
1927
1928
#else // MOZ_XUL
1929
1930
NS_IMETHODIMP
1931
nsChromeRegistry::ProcessContentsManifest(nsIURI* aOldManifest, nsIURI* aFile,
1932
                                          nsIURI* aBaseURI, PRBool aAppend,
1933
                                          PRBool aSkinOnly)
1934
{
1935
  return NS_ERROR_NOT_IMPLEMENTED;
1936
}
1937
1938
#endif // MOZ_XUL
1939
1940
nsresult
1340
nsresult
1941
nsChromeRegistry::ProcessManifest(nsILocalFile* aManifest, PRBool aSkinOnly)
1341
nsChromeRegistry::ProcessManifest(nsILocalFile* aManifest, PRBool aSkinOnly)
1942
{
1342
{
1943
  nsresult rv;
1343
  nsresult rv;
1944
1344
1945
  PRFileDesc* fd;
1345
  PRFileDesc* fd;
1946
  rv = aManifest->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
1346
  rv = aManifest->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
1947
  NS_ENSURE_SUCCESS(rv, rv);
1347
  NS_ENSURE_SUCCESS(rv, rv);

Return to bug 492008