diff --git a/tools/cldr-apps/js/src/esm/cldrStatus.mjs b/tools/cldr-apps/js/src/esm/cldrStatus.mjs
index 98b1d0a9812..862b875c6ec 100644
--- a/tools/cldr-apps/js/src/esm/cldrStatus.mjs
+++ b/tools/cldr-apps/js/src/esm/cldrStatus.mjs
@@ -79,8 +79,8 @@ function updateAll(status) {
if (status.phase) {
setPhase(status.phase);
}
- if (status.ddlPhase) {
- setDdlPhase(status.ddlPhase);
+ if (status.extendedPhase) {
+ setExtendedPhase(status.extendedPhase);
}
if (status.specialHeader) {
setSpecialHeader(status.specialHeader);
@@ -303,16 +303,18 @@ function getPhase() {
return phase;
}
-let ddlPhase = "";
function setPhase(p) {
phase = p;
}
-function getDdlPhase() {
- return ddlPhase;
+
+let extendedPhase = "";
+
+function getExtendedPhase() {
+ return extendedPhase;
}
-function setDdlPhase(p) {
- ddlPhase = p;
+function setExtendedPhase(p) {
+ extendedPhase = p;
}
/**
@@ -490,12 +492,12 @@ export {
getCurrentPage,
getCurrentSection,
getCurrentSpecial,
+ getExtendedPhase,
getIsPhaseBeta,
getIsUnofficial,
getNewVersion,
getOrganizationName,
getPermissions,
- getDdlPhase,
getPhase,
getRunningStamp,
getSessionId,
@@ -517,6 +519,7 @@ export {
setCurrentPage,
setCurrentSection,
setCurrentSpecial,
+ setExtendedPhase,
setIsDisconnected,
setIsPhaseBeta,
setIsUnofficial,
@@ -524,7 +527,6 @@ export {
setOrganizationName,
setPermissions,
setPhase,
- setDdlPhase,
setSessionId,
setSessionMessage,
setSpecialHeader,
diff --git a/tools/cldr-apps/js/src/views/MainHeader.vue b/tools/cldr-apps/js/src/views/MainHeader.vue
index 637526f2e1a..46b77c9e032 100644
--- a/tools/cldr-apps/js/src/views/MainHeader.vue
+++ b/tools/cldr-apps/js/src/views/MainHeader.vue
@@ -5,9 +5,9 @@
{{ stVersion }} {{ stPhase }}
(extended)
@@ -111,7 +111,7 @@ export default {
stPhase: null,
stVersion: null,
tcLocale: true,
- ddlException: false,
+ extendedException: false,
unreadAnnouncementCount: 0,
userName: null,
voteCountMenu: null,
@@ -176,17 +176,11 @@ export default {
this.sessionMessage = cldrStatus.getSessionMessage();
this.specialHeader = cldrStatus.getSpecialHeader();
this.stVersion = "Survey Tool " + cldrStatus.getNewVersion();
- this.tcLocale = cldrLoad?.getLocaleInfo(loc)?.tc;
- if (!loc || this.tcLocale) {
+ this.extendedException = cldrLoad.getLocaleInfo(loc)?.extended;
+ if (!loc || !this.extendedException) {
this.stPhase = cldrStatus.getPhase();
- this.ddlException = false;
- } else {
- this.stPhase = cldrStatus.getDdlPhase();
- if (cldrStatus.getDdlPhase() != cldrStatus.getPhase()) {
- this.ddlException = true;
- } else {
- this.ddlException = false;
- }
+ } else if (this.extendedException) {
+ this.stPhase = cldrStatus.getExtendedPhase();
}
cldrAnnounce.getUnreadCount(this.setUnreadCount);
},
@@ -290,7 +284,7 @@ label {
width: 16ch;
}
-.ddlException {
+.extendedException {
background-color: yellow;
}
diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/util/CLDRConfigImpl.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/util/CLDRConfigImpl.java
index 35138d194f5..83d9f379857 100644
--- a/tools/cldr-apps/src/main/java/org/unicode/cldr/util/CLDRConfigImpl.java
+++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/util/CLDRConfigImpl.java
@@ -461,8 +461,8 @@ public CheckCLDR.Phase getPhase() {
}
@Override
- public CheckCLDR.Phase getDDLPhase() {
- return SurveyMain.getOverallDDLPhase().toCheckCLDRPhase();
+ public CheckCLDR.Phase getExtendedPhase() {
+ return SurveyMain.getOverallExtendedPhase().toCheckCLDRPhase();
}
@Override
diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyAjax.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyAjax.java
index 5d92275b499..b743b70c393 100644
--- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyAjax.java
+++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyAjax.java
@@ -1119,6 +1119,7 @@ private static JSONObject createJSONLocMap(SurveyMain sm) throws JSONException {
locale.put("dcParent", dcParent);
locale.put("dcChild", dcChild);
locale.put("tc", SubmissionLocales.isTcLocale(loc));
+ locale.put("extended", SubmissionLocales.isOpenForExtendedSubmission(loc));
locale.put(
"type",
Factory.getSourceTreeType(disk.getSourceDirectoryForLocale(loc.getBaseName())));
diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyMain.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyMain.java
index 95076d37a27..ecc92b56372 100644
--- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyMain.java
+++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyMain.java
@@ -210,7 +210,7 @@ public String display() {
// ===== Configuration state
private static Phase currentPhase = Phase.VETTING;
- private static Phase currentDdlPhase = Phase.VETTING;
+ private static Phase currentExtendedPhase = Phase.VETTING;
/** set by CLDR_PHASE property. * */
private static String oldVersion = "OLDVERSION";
@@ -2825,30 +2825,35 @@ private void doStartup() {
+ phaseString);
}
currentPhase = newPhase;
- String ddlPhaseString = survprops.getProperty("CLDR_DDL_PHASE", null);
- Phase ddlPhase = null;
+ String extendedPhaseString = survprops.getProperty("CLDR_EXTENDED_PHASE", null);
+ Phase extendedPhase = null;
try {
- if (ddlPhaseString != null && !ddlPhaseString.isEmpty()) {
+ if (extendedPhaseString != null && !extendedPhaseString.isEmpty()) {
if (currentPhase == Phase.READONLY) {
busted(
- "Error: Cannot have a CLDR_DDL_PHASE when CLDR_PHASE=READONLY. Remove the CLDR_DDL_PHASE.");
+ "Error: Cannot have a CLDR_EXTENDED_PHASE when CLDR_PHASE=READONLY. Remove the CLDR_EXTENDED_PHASE.");
}
- ddlPhase = (Phase.valueOf(ddlPhaseString));
+ extendedPhase = (Phase.valueOf(extendedPhaseString));
}
} catch (IllegalArgumentException iae) {
- logger.warning("Error trying to parse CLDR_DDL_PHASE: " + iae);
+ logger.warning("Error trying to parse CLDR_EXTENDED_PHASE: " + iae);
}
- if (ddlPhase == null) {
- ddlPhase = newPhase;
- logger.warning("CLDR_DDL_PHASE matches main phase " + ddlPhase);
+ if (extendedPhase == null) {
+ extendedPhase = newPhase;
+ logger.warning("CLDR_EXTENDED_PHASE unset, so will use main phase " + newPhase);
}
- currentDdlPhase = ddlPhase;
+ currentExtendedPhase = extendedPhase;
}
logger.info(
"Phase: "
+ getOverallSurveyPhase()
+ ", CheckCLDR Phase: "
- + getOverallSurveyPhase().toCheckCLDRPhase());
+ + getOverallSurveyPhase().toCheckCLDRPhase()
+ + ", Extended Phase: "
+ + currentExtendedPhase);
+ logger.info(
+ "CLDR_EXTENDED_SUBMISSION="
+ + String.join(" ", SubmissionLocales.ADDITIONAL_EXTENDED_SUBMISSION));
progress.update("Setup props..");
newVersion = survprops.getProperty(CLDR_NEWVERSION, CLDR_NEWVERSION);
oldVersion = survprops.getProperty(CLDR_OLDVERSION, CLDR_OLDVERSION);
@@ -3601,7 +3606,7 @@ public static Phase getOverallSurveyPhase() {
public static Phase surveyPhase(CLDRLocale locale) {
return (SubmissionLocales.isTcLocale(locale)
? getOverallSurveyPhase()
- : getOverallDDLPhase());
+ : getOverallExtendedPhase());
}
/**
@@ -3615,8 +3620,8 @@ public static CheckCLDR.Phase checkCLDRPhase(CLDRLocale loc) {
* the DDL (non-TC) overall phase. It is preferred to use one of the phase functions which takes
* a locale.
*/
- public static Phase getOverallDDLPhase() {
- return currentDdlPhase;
+ public static Phase getOverallExtendedPhase() {
+ return currentExtendedPhase;
}
public static String getOldVersion() {
@@ -3691,7 +3696,7 @@ private class StatusForFrontEnd implements JSONString {
private final int pages = SurveyMain.pages;
private Object permissions = null;
private final Phase phase = getOverallSurveyPhase();
- private final Phase ddlPhase = getOverallDDLPhase();
+ private final Phase extendedPhase = getOverallExtendedPhase();
private String sessionId = null;
private final String specialHeader = getSpecialHeaderText();
private final long surveyRunningStamp = SurveyMain.surveyRunningStamp.current();
@@ -3725,7 +3730,7 @@ private JSONObject toJSONObject() throws JSONException {
.put("pages", pages)
.put("permissions", permissions)
.put("phase", phase)
- .put("ddlPhase", ddlPhase)
+ .put("extendedPhase", extendedPhase)
.put("sessionId", sessionId)
.put("sessionMessage", sessionMessage)
.put("specialHeader", specialHeader)
diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/test/SubmissionLocales.java b/tools/cldr-code/src/main/java/org/unicode/cldr/test/SubmissionLocales.java
index 471f25fb161..11a8a19650e 100644
--- a/tools/cldr-code/src/main/java/org/unicode/cldr/test/SubmissionLocales.java
+++ b/tools/cldr-code/src/main/java/org/unicode/cldr/test/SubmissionLocales.java
@@ -12,6 +12,7 @@
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CLDRLocale;
import org.unicode.cldr.util.GrammarInfo;
import org.unicode.cldr.util.Level;
@@ -70,6 +71,16 @@ public final class SubmissionLocales {
/** Subset of CLDR_LOCALES, minus special which are only those which are TC orgs */
public static final Set TC_ORG_LOCALES;
+ /** Space-separated list of TC locales to extend submission */
+ public static final String DEFAULT_EXTENDED_SUBMISSION = "";
+
+ /** Additional TC locales which have extended submission. Do not add non-tc locales here. */
+ public static final Set ADDITIONAL_EXTENDED_SUBMISSION =
+ ImmutableSet.copyOf(
+ CLDRConfig.getInstance()
+ .getProperty("CLDR_EXTENDED_SUBMISSION", "")
+ .split(" "));
+
/**
* Set to true iff ONLY grammar locales should be limited submission {@link
* GrammarInfo#getGrammarLocales()}
@@ -250,6 +261,10 @@ public static Set getReportsAvailableInLimited() {
return LIMITED_SUBMISSION_REPORTS;
}
+ /**
+ * @returns true if the locale or its parent is considered a TC Org Locale. Returns true for
+ * ROOT.
+ */
public static boolean isTcLocale(CLDRLocale loc) {
if (loc == CLDRLocale.ROOT
|| SubmissionLocales.TC_ORG_LOCALES.contains(loc.getBaseName())) {
@@ -262,4 +277,26 @@ public static boolean isTcLocale(CLDRLocale loc) {
return isTcLocale(loc.getParent());
}
}
+
+ /**
+ * @returns true if the locale or its parent is considered a TC Org Locale. Returns true for
+ * ROOT.
+ */
+ public static boolean isOpenForExtendedSubmission(CLDRLocale loc) {
+ if (loc == CLDRLocale.ROOT) {
+ return false; // root is never open
+ } else if (SubmissionLocales.ADDITIONAL_EXTENDED_SUBMISSION.contains(loc.getBaseName())) {
+ // explicitly listed locale is a open for additional
+ return true;
+ } else if (SubmissionLocales.TC_ORG_LOCALES.contains(loc.getBaseName())) {
+ // TC locale but not listed as extended - NOT open for extended submission.
+ return false;
+ } else if (loc.isParentRoot()) {
+ // Not a TC locale, so it's open.
+ return true;
+ } else {
+ // child locale of an open locale is open
+ return isOpenForExtendedSubmission(loc.getParent());
+ }
+ }
}
diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/CLDRConfig.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/CLDRConfig.java
index 9d813ce37b4..4d1f1131908 100644
--- a/tools/cldr-code/src/main/java/org/unicode/cldr/util/CLDRConfig.java
+++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/CLDRConfig.java
@@ -401,9 +401,10 @@ public synchronized Phase getPhase() {
}
/**
- * @returns the phase for DDL (non-TC) locales. Defaults to same as main phase.
+ * @returns the phase for extended submission locales. Defaults to same as main phase. {@link
+ * SubmissionLocales#isOpenForExtendedSubmission}
*/
- public Phase getDDLPhase() {
+ public Phase getExtendedPhase() {
// by default, same as main phase.
return getPhase();
}
diff --git a/tools/cldr-code/src/test/java/org/unicode/cldr/test/TestSubmissionLocales.java b/tools/cldr-code/src/test/java/org/unicode/cldr/test/TestSubmissionLocales.java
index 7880722db4d..5fc20a5bdf5 100644
--- a/tools/cldr-code/src/test/java/org/unicode/cldr/test/TestSubmissionLocales.java
+++ b/tools/cldr-code/src/test/java/org/unicode/cldr/test/TestSubmissionLocales.java
@@ -8,6 +8,8 @@
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
+import java.util.List;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
@@ -80,9 +82,13 @@ public static final boolean bool(final String s) {
"de, true",
"de_IT, true",
"csw, false",
+ "csw_CA, false",
"cho_US, false",
"zh, true",
"zh_Hant_MO, true",
+ "smj, false",
+ "smj_NO, false",
+ "smj_SE, false",
})
public void testIsTcLocale(final String loc, final String tf) {
final CLDRLocale l = CLDRLocale.getInstance(loc);
@@ -90,4 +96,44 @@ public void testIsTcLocale(final String loc, final String tf) {
final Boolean isCldr = Boolean.parseBoolean(tf);
assertEquals(isCldr, SubmissionLocales.isTcLocale(l));
}
+
+ @ParameterizedTest
+ @CsvSource({
+ // loc, isTc
+ "root, true",
+ "de, true",
+ "de_IT, true",
+ "csw, false",
+ "csw_CA, false",
+ "cho_US, false",
+ "zh, true",
+ "zh_Hant_MO, true",
+ "smj, false",
+ "smj_NO, false",
+ "smj_SE, false",
+ })
+ public void testIsExtendedSubmissionLocale(final String loc, final String tf) {
+ final CLDRLocale l = CLDRLocale.getInstance(loc);
+ assertNotNull(l, loc);
+ final Boolean isExtendedSubmission = Boolean.parseBoolean(tf);
+ assertEquals(isExtendedSubmission, SubmissionLocales.isOpenForExtendedSubmission(l));
+ }
+
+ @Test
+ public void textAdditionalVsTcLocale() {
+ final List extendedSubmissionButNotTcLocales =
+ SubmissionLocales.ADDITIONAL_EXTENDED_SUBMISSION.stream()
+ .map(l -> CLDRLocale.getInstance(l))
+ .filter(l -> !SubmissionLocales.isTcLocale(l))
+ .collect(Collectors.toList());
+ assertTrue(
+ extendedSubmissionButNotTcLocales.isEmpty(),
+ () ->
+ "Locales in SubmissionLocales.ADDITIONAL_EXTENDED_SUBMISSION that should be removed as they are not TC locales: "
+ + String.join(
+ " ",
+ extendedSubmissionButNotTcLocales.stream()
+ .map(l -> l.getBaseName())
+ .collect(Collectors.toList())));
+ }
}