Bug 1959147 - Part 1: Migrate XSLT to Fluent. r=fluent-reviewers,flod,smaug

Differential Revision: https://phabricator.services.mozilla.com/D245695
This commit is contained in:
Pier Angelo Vendrame
2025-04-28 15:24:45 +00:00
parent 6e2060a9b5
commit 7e0a5dbd54
4 changed files with 242 additions and 19 deletions

View File

@@ -329,6 +329,9 @@ var allowlist = [
file: "resource://gre/localization/en-US/netwerk/necko.ftl",
},
// dom/xslt/xslt/txMozillaXSLTProcessor.cpp
{ file: "resource://gre/localization/en-US/dom/xslt.ftl" },
// A QA and dev debug tool.
{ file: "chrome://browser/content/places/interactionsViewer.html" },
];

View File

@@ -0,0 +1,51 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
## XSLT and XPath specific errors.
xslt-parse-failure = Parsing an XSLT stylesheet failed.
xpath-parse-failure = Parsing an XPath expression failed.
xslt-execution-failure = XSLT transformation failed.
xpath-unknown-function = Invalid XSLT/XPath function.
xslt-bad-recursion = XSLT Stylesheet (possibly) contains a recursion.
xslt-bad-value = Attribute value illegal in XSLT 1.0.
xslt-nodeset-expected = An XPath expression was expected to return a NodeSet.
xslt-aborted = XSLT transformation was terminated by <xsl:message>.
xslt-network-error = A network error occurred loading an XSLT stylesheet:
xslt-wrong-mime-type = An XSLT stylesheet does not have an XML mimetype:
xslt-load-recursion = An XSLT stylesheet directly or indirectly imports or includes itself:
xpath-bad-argument-count = An XPath function was called with the wrong number of arguments.
xpath-bad-extension-function = An unknown XPath extension function was called.
xpath-paren-expected = XPath parse failure: ) expected:
xpath-invalid-axis = XPath parse failure: invalid axis:
xpath-no-node-type-test = XPath parse failure: Name or Nodetype test expected:
xpath-bracket-expected = XPath parse failure: ] expected:
xpath-invalid-var-name = XPath parse failure: invalid variable name:
xpath-unexpected-end = XPath parse failure: unexpected end of expression:
xpath-operator-expected = XPath parse failure: operator expected:
xpath-unclosed-literal = XPath parse failure: unclosed literal:
xpath-bad-colon = XPath parse failure: : unexpected:
xpath-bad-bang = XPath parse failure: ! unexpected, negation is not():
xpath-illegal-char = XPath parse failure: illegal character found:
xpath-binary-expected = XPath parse failure: binary operator expected:
xslt-load-blocked-error = An XSLT stylesheet load was blocked for security reasons.
xpath-invalid-expression-evaluated = Evaluating an invalid expression.
xpath-unbalanced-curly-brace = Unbalanced curly brace.
xslt-bad-node-name = Creating an element with an invalid QName.
xslt-var-already-set = Variable binding shadows variable binding within the same template.
xslt-call-to-key-not-allowed = Call to the key function not allowed.
# Other failures, not found in the previous ones.
# Variables:
# $errorCode (String) - The error code (formatted in hexadecimal)
xslt-unknown-error = An unknown error has occurred ({ $errorCode })
## Messages for the XML error page.
##
## Variables:
## $error (string) - the specific XSLT or XPath error (a translated string
## from the previous section)
xslt-loading-error = Error loading stylesheet: { $error }
xslt-transform-error = Error during XSLT transformation: { $error }

View File

@@ -17,7 +17,6 @@
#include "txURIUtils.h"
#include "txXMLUtils.h"
#include "txUnknownHandler.h"
#include "txXSLTMsgsURL.h"
#include "txXSLTProcessor.h"
#include "nsIPrincipal.h"
#include "nsThreadUtils.h"
@@ -31,6 +30,7 @@
#include "mozilla/Components.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/XSLTProcessorBinding.h"
#include "mozilla/intl/Localization.h"
using namespace mozilla;
using namespace mozilla::dom;
@@ -987,6 +987,77 @@ nsresult txMozillaXSLTProcessor::setStylesheet(txStylesheet* aStylesheet) {
return NS_OK;
}
static mozilla::Maybe<nsLiteralCString> StatusCodeToL10nId(nsresult aStatus) {
switch (aStatus) {
case NS_ERROR_XSLT_PARSE_FAILURE:
return mozilla::Some("xslt-parse-failure"_ns);
case NS_ERROR_XPATH_PARSE_FAILURE:
return mozilla::Some("xpath-parse-failure"_ns);
case NS_ERROR_XSLT_ALREADY_SET:
return mozilla::Some("xslt-var-already-set"_ns);
case NS_ERROR_XSLT_EXECUTION_FAILURE:
return mozilla::Some("xslt-execution-failure"_ns);
case NS_ERROR_XPATH_UNKNOWN_FUNCTION:
return mozilla::Some("xpath-unknown-function"_ns);
case NS_ERROR_XSLT_BAD_RECURSION:
return mozilla::Some("xslt-bad-recursion"_ns);
case NS_ERROR_XSLT_BAD_VALUE:
return mozilla::Some("xslt-bad-value"_ns);
case NS_ERROR_XSLT_NODESET_EXPECTED:
return mozilla::Some("xslt-nodeset-expected"_ns);
case NS_ERROR_XSLT_ABORTED:
return mozilla::Some("xslt-aborted"_ns);
case NS_ERROR_XSLT_NETWORK_ERROR:
return mozilla::Some("xslt-network-error"_ns);
case NS_ERROR_XSLT_WRONG_MIME_TYPE:
return mozilla::Some("xslt-wrong-mime-type"_ns);
case NS_ERROR_XSLT_LOAD_RECURSION:
return mozilla::Some("xslt-load-recursion"_ns);
case NS_ERROR_XPATH_BAD_ARGUMENT_COUNT:
return mozilla::Some("xpath-bad-argument-count"_ns);
case NS_ERROR_XPATH_BAD_EXTENSION_FUNCTION:
return mozilla::Some("xpath-bad-extension-function"_ns);
case NS_ERROR_XPATH_PAREN_EXPECTED:
return mozilla::Some("xpath-paren-expected"_ns);
case NS_ERROR_XPATH_INVALID_AXIS:
return mozilla::Some("xpath-invalid-axis"_ns);
case NS_ERROR_XPATH_NO_NODE_TYPE_TEST:
return mozilla::Some("xpath-no-node-type-test"_ns);
case NS_ERROR_XPATH_BRACKET_EXPECTED:
return mozilla::Some("xpath-bracket-expected"_ns);
case NS_ERROR_XPATH_INVALID_VAR_NAME:
return mozilla::Some("xpath-invalid-var-name"_ns);
case NS_ERROR_XPATH_UNEXPECTED_END:
return mozilla::Some("xpath-unexpected-end"_ns);
case NS_ERROR_XPATH_OPERATOR_EXPECTED:
return mozilla::Some("xpath-operator-expected"_ns);
case NS_ERROR_XPATH_UNCLOSED_LITERAL:
return mozilla::Some("xpath-unclosed-literal"_ns);
case NS_ERROR_XPATH_BAD_COLON:
return mozilla::Some("xpath-bad-colon"_ns);
case NS_ERROR_XPATH_BAD_BANG:
return mozilla::Some("xpath-bad-bang"_ns);
case NS_ERROR_XPATH_ILLEGAL_CHAR:
return mozilla::Some("xpath-illegal-char"_ns);
case NS_ERROR_XPATH_BINARY_EXPECTED:
return mozilla::Some("xpath-binary-expected"_ns);
case NS_ERROR_XSLT_LOAD_BLOCKED_ERROR:
return mozilla::Some("xslt-load-blocked-error"_ns);
case NS_ERROR_XPATH_INVALID_EXPRESSION_EVALUATED:
return mozilla::Some("xpath-invalid-expression-evaluated"_ns);
case NS_ERROR_XPATH_UNBALANCED_CURLY_BRACE:
return mozilla::Some("xpath-unbalanced-curly-brace"_ns);
case NS_ERROR_XSLT_BAD_NODE_NAME:
return mozilla::Some("xslt-bad-node-name"_ns);
case NS_ERROR_XSLT_VAR_ALREADY_SET:
return mozilla::Some("xslt-var-already-set"_ns);
case NS_ERROR_XSLT_CALL_TO_KEY_NOT_ALLOWED:
return mozilla::Some("xslt-call-to-key-not-allowed"_ns);
default:
return mozilla::Nothing();
}
}
void txMozillaXSLTProcessor::reportError(nsresult aResult,
const char16_t* aErrorText,
const char16_t* aSourceText) {
@@ -999,25 +1070,38 @@ void txMozillaXSLTProcessor::reportError(nsresult aResult,
if (aErrorText) {
mErrorText.Assign(aErrorText);
} else {
nsCOMPtr<nsIStringBundleService> sbs =
mozilla::components::StringBundle::Service();
if (sbs) {
nsString errorText;
sbs->FormatStatusMessage(aResult, u"", errorText);
nsAutoString errorMessage;
nsCOMPtr<nsIStringBundle> bundle;
sbs->CreateBundle(XSLT_MSGS_URL, getter_AddRefs(bundle));
if (bundle) {
AutoTArray<nsString, 1> error = {errorText};
if (mStylesheet) {
bundle->FormatStringFromName("TransformError", error, errorMessage);
} else {
bundle->FormatStringFromName("LoadingError", error, errorMessage);
}
AutoTArray<nsCString, 1> resIds = {
"dom/xslt.ftl"_ns,
};
RefPtr<mozilla::intl::Localization> l10n =
mozilla::intl::Localization::Create(resIds, true);
if (l10n) {
nsAutoCString errorText;
auto statusId = StatusCodeToL10nId(aResult);
if (statusId) {
l10n->FormatValueSync(*statusId, {}, errorText, IgnoreErrors());
} else {
dom::Optional<intl::L10nArgs> l10nArgs;
l10nArgs.Construct();
auto errorArg = l10nArgs.Value().Entries().AppendElement();
errorArg->mKey = "errorCode";
errorArg->mValue.SetValue().SetAsUTF8String().AppendInt(
static_cast<uint32_t>(aResult), 16);
l10n->FormatValueSync("xslt-unknown-error"_ns, l10nArgs, errorText,
IgnoreErrors());
}
mErrorText.Assign(errorMessage);
dom::Optional<intl::L10nArgs> l10nArgs;
l10nArgs.Construct();
auto errorArg = l10nArgs.Value().Entries().AppendElement();
errorArg->mKey = "error";
errorArg->mValue.SetValue().SetAsUTF8String().Assign(errorText);
nsLiteralCString messageId =
mStylesheet ? "xslt-transform-error"_ns : "xslt-loading-error"_ns;
nsAutoCString errorMessage;
l10n->FormatValueSync(messageId, l10nArgs, errorMessage, IgnoreErrors());
mErrorText = NS_ConvertUTF8toUTF16(errorMessage);
}
}

View File

@@ -0,0 +1,85 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
from fluent.migrate.helpers import VARIABLE_REFERENCE
from fluent.migrate.transforms import COPY, REPLACE
def migrate(ctx):
"""Bug 1959147 - Migrate XSLT errors to Fluent, part {index}."""
xslt_source = "dom/chrome/xslt/xslt.properties"
global_strres_source = "dom/chrome/global-strres.properties"
target = "dom/dom/xslt.ftl"
xslt_errors = {
"xslt-parse-failure": "1",
"xpath-parse-failure": "2",
# 3 (NS_ERROR_XSLT_ALREADY_SET) is empty in xslt.properties.
# It seems it is always replaced with NS_ERROR_XSLT_VAR_ALREADY_SET.
"xslt-execution-failure": "4",
"xpath-unknown-function": "5",
"xslt-bad-recursion": "6",
"xslt-bad-value": "7",
"xslt-nodeset-expected": "8",
"xslt-aborted": "9",
"xslt-network-error": "10",
"xslt-wrong-mime-type": "11",
"xslt-load-recursion": "12",
"xpath-bad-argument-count": "13",
"xpath-bad-extension-function": "14",
"xpath-paren-expected": "15",
"xpath-invalid-axis": "16",
"xpath-no-node-type-test": "17",
"xpath-bracket-expected": "18",
"xpath-invalid-var-name": "19",
"xpath-unexpected-end": "20",
"xpath-operator-expected": "21",
"xpath-unclosed-literal": "22",
"xpath-bad-colon": "23",
"xpath-bad-bang": "24",
"xpath-illegal-char": "25",
"xpath-binary-expected": "26",
"xslt-load-blocked-error": "27",
"xpath-invalid-expression-evaluated": "28",
"xpath-unbalanced-curly-brace": "29",
"xslt-bad-node-name": "30",
"xslt-var-already-set": "31",
"xslt-call-to-key-not-allowed": "32",
}
ctx.add_transforms(
target,
target,
[
FTL.Message(id=FTL.Identifier(ftl_id), value=COPY(xslt_source, prop_id))
for ftl_id, prop_id in xslt_errors.items()
],
)
ctx.add_transforms(
target,
target,
[
FTL.Message(
id=FTL.Identifier("xslt-unknown-error"),
value=REPLACE(
global_strres_source,
"16389",
{"%1$S": VARIABLE_REFERENCE("errorCode")},
),
),
FTL.Message(
id=FTL.Identifier("xslt-loading-error"),
value=REPLACE(
xslt_source, "LoadingError", {"%1$S": VARIABLE_REFERENCE("error")}
),
),
FTL.Message(
id=FTL.Identifier("xslt-transform-error"),
value=REPLACE(
xslt_source, "TransformError", {"%1$S": VARIABLE_REFERENCE("error")}
),
),
],
)