diff --git a/xpfe/browser/resources/content/navigator.js b/xpfe/browser/resources/content/navigator.js index 598522b1305a..374f6663fbfe 100644 --- a/xpfe/browser/resources/content/navigator.js +++ b/xpfe/browser/resources/content/navigator.js @@ -1588,10 +1588,31 @@ function getShortcutOrURI(url) shortcutURL = gBookmarksService.resolveKeyword(cmd); // Bug 123006 : %s replace and URI escape, %S replace with raw value if (shortcutURL && text) { - shortcutURL = /%[sS]/.test(shortcutURL) ? - shortcutURL.replace(/%s/g, encodeURIComponent(text)) - .replace(/%S/g, text) : - null; + var encodedText = null; + var charset = ""; + const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/; + var matches = shortcutURL.match(re); + if (matches) { + shortcutURL = matches[1]; + charset = matches[2]; + } + else if (/%s/.test(shortcutURL)) { + try { + charset = BMSVC.getLastCharset(shortcutURL); + } catch (ex) { + } + } + + if (charset) + encodedText = escape(convertFromUnicode(charset, text)); + else // default case: charset=UTF-8 + encodedText = encodeURIComponent(text); + + if (encodedText && /%[sS]/.test(shortcutURL)) + shortcutURL = shortcutURL.replace(/%s/g, encodedText) + .replace(/%S/g, text); + else + shortcutURL = null; } } } @@ -2656,3 +2677,17 @@ function updateSavePageItems() var autoDownload = pref.getBoolPref("browser.download.autoDownload"); goSetMenuValue("savepage", autoDownload ? "valueSave" : "valueSaveAs"); } + +function convertFromUnicode(charset, str) +{ + try { + var unicodeConverter = Components + .classes["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Components.interfaces.nsIScriptableUnicodeConverter); + unicodeConverter.charset = charset; + str = unicodeConverter.ConvertFromUnicode(str); + return str + unicodeConverter.Finish(); + } catch(ex) { + return null; + } +} diff --git a/xpfe/components/bookmarks/public/nsIBookmarksService.idl b/xpfe/components/bookmarks/public/nsIBookmarksService.idl index 12280ff72738..a54863e1e8f9 100644 --- a/xpfe/components/bookmarks/public/nsIBookmarksService.idl +++ b/xpfe/components/bookmarks/public/nsIBookmarksService.idl @@ -98,6 +98,8 @@ interface nsIBookmarksService : nsISupports void updateLastVisitedDate(in string aURL, in wstring docCharset); + AString getLastCharset(in AUTF8String aURL); + string resolveKeyword(in wstring aName); void importSystemBookmarks(in nsIRDFResource aParentFolder); diff --git a/xpfe/components/bookmarks/src/nsBookmarksService.cpp b/xpfe/components/bookmarks/src/nsBookmarksService.cpp index 410aba04502b..5c1129b48014 100644 --- a/xpfe/components/bookmarks/src/nsBookmarksService.cpp +++ b/xpfe/components/bookmarks/src/nsBookmarksService.cpp @@ -3666,6 +3666,45 @@ nsBookmarksService::UpdateBookmarkLastModifiedDate(nsIRDFResource *aSource) return rv; } +NS_IMETHODIMP +nsBookmarksService::GetLastCharset(const nsACString &aURL, nsAString &aCharset) +{ + aCharset.Truncate(); + + nsCOMPtr urlLiteral; + nsresult rv = gRDF->GetLiteral(NS_ConvertUTF8toUCS2(aURL).get(), + getter_AddRefs(urlLiteral)); + + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr bookmark; + rv = GetSource(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmark)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr nodeType; + GetSynthesizedType(bookmark, getter_AddRefs(nodeType)); + if (nodeType == kNC_Bookmark) { + nsCOMPtr charsetNode; + rv = GetTarget(bookmark, kWEB_LastCharset, PR_TRUE, + getter_AddRefs(charsetNode)); + if (NS_FAILED(rv)) + return rv; + + if (charsetNode) { + nsCOMPtr charsetData(do_QueryInterface(charsetNode)); + if (charsetData) { + const PRUnichar *charset; + charsetData->GetValueConst(&charset); + aCharset.Assign(charset); + } + } + } + + return NS_OK; +} + NS_IMETHODIMP nsBookmarksService::ResolveKeyword(const PRUnichar *aUserInput, char **aShortcutURL) {