Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsStringBundleTextOverride.h"
8 #include "nsString.h"
10 #include "nsNetUtil.h"
11 #include "nsAppDirectoryServiceDefs.h"
13 // first we need a simple class which wraps a nsIPropertyElement and
14 // cuts out the leading URL from the key
15 class URLPropertyElement : public nsIPropertyElement
16 {
17 public:
18 URLPropertyElement(nsIPropertyElement *aRealElement, uint32_t aURLLength) :
19 mRealElement(aRealElement),
20 mURLLength(aURLLength)
21 { }
22 virtual ~URLPropertyElement() {}
24 NS_DECL_ISUPPORTS
25 NS_DECL_NSIPROPERTYELEMENT
27 private:
28 nsCOMPtr<nsIPropertyElement> mRealElement;
29 uint32_t mURLLength;
30 };
32 NS_IMPL_ISUPPORTS(URLPropertyElement, nsIPropertyElement)
34 // we'll tweak the key on the way through, and remove the url prefix
35 NS_IMETHODIMP
36 URLPropertyElement::GetKey(nsACString& aKey)
37 {
38 nsresult rv = mRealElement->GetKey(aKey);
39 if (NS_FAILED(rv)) return rv;
41 // chop off the url
42 aKey.Cut(0, mURLLength);
44 return NS_OK;
45 }
47 // values are unaffected
48 NS_IMETHODIMP
49 URLPropertyElement::GetValue(nsAString& aValue)
50 {
51 return mRealElement->GetValue(aValue);
52 }
54 // setters are kind of strange, hopefully we'll never be called
55 NS_IMETHODIMP
56 URLPropertyElement::SetKey(const nsACString& aKey)
57 {
58 // this is just wrong - ideally you'd take the key, append it to
59 // the url, and set that as the key. However, that would require
60 // us to hold onto a copy of the string, and that's a waste,
61 // considering nobody should ever be calling this.
62 NS_ERROR("This makes no sense!");
63 return NS_ERROR_NOT_IMPLEMENTED;
64 }
66 NS_IMETHODIMP
67 URLPropertyElement::SetValue(const nsAString& aValue)
68 {
69 return mRealElement->SetValue(aValue);
70 }
73 // this is a special enumerator which returns only the elements which
74 // are prefixed with a particular url
75 class nsPropertyEnumeratorByURL : public nsISimpleEnumerator
76 {
77 public:
78 nsPropertyEnumeratorByURL(const nsACString& aURL,
79 nsISimpleEnumerator* aOuter) :
80 mOuter(aOuter),
81 mURL(aURL)
82 {
83 // prepare the url once so we can use its value later
84 // persistent properties uses ":" as a delimiter, so escape
85 // that character
86 mURL.ReplaceSubstring(":", "%3A");
87 // there is always a # between the url and the real key
88 mURL.Append('#');
89 }
91 NS_DECL_ISUPPORTS
92 NS_DECL_NSISIMPLEENUMERATOR
94 virtual ~nsPropertyEnumeratorByURL() {}
95 private:
97 // actual enumerator of all strings from nsIProperties
98 nsCOMPtr<nsISimpleEnumerator> mOuter;
100 // the current element that is valid for this url
101 nsCOMPtr<nsIPropertyElement> mCurrent;
103 // the url in question, pre-escaped and with the # already in it
104 nsCString mURL;
105 };
107 //
108 // nsStringBundleTextOverride implementation
109 //
110 NS_IMPL_ISUPPORTS(nsStringBundleTextOverride,
111 nsIStringBundleOverride)
113 nsresult
114 nsStringBundleTextOverride::Init()
115 {
116 nsresult rv;
118 // check for existence of custom-strings.txt
120 nsCOMPtr<nsIFile> customStringsFile;
121 rv = NS_GetSpecialDirectory(NS_APP_CHROME_DIR,
122 getter_AddRefs(customStringsFile));
124 if (NS_FAILED(rv)) return rv;
126 // bail if not found - this will cause the service creation to
127 // bail as well, and cause this object to go away
129 customStringsFile->AppendNative(NS_LITERAL_CSTRING("custom-strings.txt"));
131 bool exists;
132 rv = customStringsFile->Exists(&exists);
133 if (NS_FAILED(rv) || !exists)
134 return NS_ERROR_FAILURE;
136 NS_WARNING("Using custom-strings.txt to override string bundles.");
137 // read in the custom bundle. Keys are in the form
138 // chrome://package/locale/foo.properties:keyname
140 nsAutoCString customStringsURLSpec;
141 rv = NS_GetURLSpecFromFile(customStringsFile, customStringsURLSpec);
142 if (NS_FAILED(rv)) return rv;
144 nsCOMPtr<nsIURI> uri;
145 rv = NS_NewURI(getter_AddRefs(uri), customStringsURLSpec);
146 if (NS_FAILED(rv)) return rv;
148 nsCOMPtr<nsIInputStream> in;
149 rv = NS_OpenURI(getter_AddRefs(in), uri);
150 if (NS_FAILED(rv)) return rv;
152 static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
153 mValues = do_CreateInstance(kPersistentPropertiesCID, &rv);
154 if (NS_FAILED(rv)) return rv;
156 rv = mValues->Load(in);
158 // turn this on to see the contents of custom-strings.txt
159 #ifdef DEBUG_alecf
160 nsCOMPtr<nsISimpleEnumerator> enumerator;
161 mValues->Enumerate(getter_AddRefs(enumerator));
162 NS_ASSERTION(enumerator, "no enumerator!\n");
164 printf("custom-strings.txt contains:\n");
165 printf("----------------------------\n");
167 bool hasMore;
168 enumerator->HasMoreElements(&hasMore);
169 do {
170 nsCOMPtr<nsISupports> sup;
171 enumerator->GetNext(getter_AddRefs(sup));
173 nsCOMPtr<nsIPropertyElement> prop = do_QueryInterface(sup);
175 nsAutoCString key;
176 nsAutoString value;
177 prop->GetKey(key);
178 prop->GetValue(value);
180 printf("%s = '%s'\n", key.get(), NS_ConvertUTF16toUTF8(value).get());
182 enumerator->HasMoreElements(&hasMore);
183 } while (hasMore);
184 #endif
186 return rv;
187 }
189 NS_IMETHODIMP
190 nsStringBundleTextOverride::GetStringFromName(const nsACString& aURL,
191 const nsACString& key,
192 nsAString& aResult)
193 {
194 // concatenate url#key to get the key to read
195 nsAutoCString combinedURL(aURL + NS_LITERAL_CSTRING("#") + key);
197 // persistent properties uses ":" as a delimiter, so escape that character
198 combinedURL.ReplaceSubstring(":", "%3A");
200 return mValues->GetStringProperty(combinedURL, aResult);
201 }
203 NS_IMETHODIMP
204 nsStringBundleTextOverride::EnumerateKeysInBundle(const nsACString& aURL,
205 nsISimpleEnumerator** aResult)
206 {
207 // enumerate all strings, and let the enumerator know
208 nsCOMPtr<nsISimpleEnumerator> enumerator;
209 mValues->Enumerate(getter_AddRefs(enumerator));
211 // make the enumerator wrapper and pass it off
212 nsPropertyEnumeratorByURL* propEnum =
213 new nsPropertyEnumeratorByURL(aURL, enumerator);
215 if (!propEnum) return NS_ERROR_OUT_OF_MEMORY;
217 NS_ADDREF(*aResult = propEnum);
219 return NS_OK;
220 }
223 //
224 // nsPropertyEnumeratorByURL implementation
225 //
228 NS_IMPL_ISUPPORTS(nsPropertyEnumeratorByURL, nsISimpleEnumerator)
230 NS_IMETHODIMP
231 nsPropertyEnumeratorByURL::GetNext(nsISupports **aResult)
232 {
233 if (!mCurrent) return NS_ERROR_UNEXPECTED;
235 // wrap mCurrent instead of returning it
236 *aResult = new URLPropertyElement(mCurrent, mURL.Length());
237 NS_ADDREF(*aResult);
239 // release it so we don't return it twice
240 mCurrent = nullptr;
242 return NS_OK;
243 }
245 NS_IMETHODIMP
246 nsPropertyEnumeratorByURL::HasMoreElements(bool * aResult)
247 {
248 bool hasMore;
249 mOuter->HasMoreElements(&hasMore);
250 while (hasMore) {
252 nsCOMPtr<nsISupports> supports;
253 mOuter->GetNext(getter_AddRefs(supports));
255 mCurrent = do_QueryInterface(supports);
257 if (mCurrent) {
258 nsAutoCString curKey;
259 mCurrent->GetKey(curKey);
261 if (StringBeginsWith(curKey, mURL))
262 break;
263 }
265 mOuter->HasMoreElements(&hasMore);
266 }
268 if (!hasMore)
269 mCurrent = nullptr;
271 *aResult = mCurrent ? true : false;
273 return NS_OK;
274 }