Page MenuHomeWildfire Games

Pass callback function to PushGuiPage and unify PopGuiPage/PopGuiPageCB
ClosedPublic

Authored by elexis on Nov 29 2018, 2:36 PM.

Details

Summary

PushGuiPage:
JS can open child GUI pages with the PushGuiPage command.
If the parent GUI page wants to execute a callback function upon closing of the child GUI page,
then the PushGuiPage function needs to pass the name of a global function.

Instead, PushGuiPage should receive the function, not the name of the function.

Use cases:

  • Inlining functions to reduce globals and fragmentation of the code (for example gamesetup.js / #5322 or functions_msgbox.js).
  • Syntax errors at code interpret time instead of runtime errors if the function name contains a typo.

Prior to rP14496, this was the case.

PopGuiPage:
rP14496 also introduced PopGuiPageCB, which is to be called in order to close with callback arguments (whereas PopGuiPage closes without callback arguments).
The alternative function can be removed by having the PopGuiPage call the callback functions if it was passed to PushGuiPage.

Notice however that this also makes it possible for the child GUI page to decide that the parent GUI page may not perform the callback function.
This behavior was used by the structree / civinfo switch-page button added in rP21339.
The code of that revision looks like a workaround and the code rewritten here appears like a different workaround
(because globals should be avoided and the parent GUI page should avoid having to specify implementation details of child GUI pages).

Test Plan

The C++ diff is the critical part, because it is easy to trigger garbage collection segfaults if the C++ code is wrong in any way.
To verify that it's not broken, one can

  • open and close every GUI page once
  • open multiple GUI pages consecutively
  • read the garbage collection docs and spidermonkey specs without becoming any wiser.

Diff Detail

Repository
rP 0 A.D. Public Repository
Branch
/ps/trunk
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 6475
Build 10721: Vulcan BuildJenkins
Build 10720: arc lint + arc unit

Event Timeline

elexis created this revision.Nov 29 2018, 2:36 PM
elexis updated this revision to Diff 7012.Nov 29 2018, 2:44 PM

Remove core.js closePage function formerly used by viewer.js.

Vulcan added a subscriber: Vulcan.Nov 29 2018, 2:45 PM

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Default...
Executing section Source...
Executing section JS...

binaries/data/mods/public/gui/reference/common/core.js
|  31| »   do·{
|    | [NORMAL] ESLintBear (brace-rules/brace-on-same-line):
|    | Opening curly brace appears on the same line as controlling statement.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
| 452| 452| 				continue;
| 453| 453| 
| 454| 454| 			if (state.pack.progress == 0)
| 455|    |-			{
|    | 455|+			
| 456| 456| 				if (state.pack.packed)
| 457| 457| 					checks.unpackButton = true;
| 458| 458| 				else
| 459| 459| 					checks.packButton = true;
| 460|    |-			}
|    | 460|+			
| 461| 461| 			else if (state.pack.packed)
| 462| 462| 				checks.unpackCancelButton = true;
| 463| 463| 			else
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
| 941| 941| 			"player": data.player
| 942| 942| 		});
| 943| 943| 
| 944|    |-		let unitIds = data.unitEntStates.map(status => status.id)
|    | 944|+		let unitIds = data.unitEntStates.map(status => status.id);
| 945| 945| 		let [buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] =
| 946| 946| 			getTrainingStatus(unitIds, data.item, data.playerState);
| 947| 947| 

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 944| »   »   let·unitIds·=·data.unitEntStates.map(status·=>·status.id)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
| 873| 873| 	Engine.GetGUIObjectByName("barterHelp").hidden = !canBarter;
| 874| 874| 
| 875| 875| 	if (canBarter)
| 876|    |-		g_ResourceData.GetCodes().forEach((resCode, i) => { barterUpdateCommon(resCode, i, "barter", g_ViewedPlayer) });
|    | 876|+		g_ResourceData.GetCodes().forEach((resCode, i) => { barterUpdateCommon(resCode, i, "barter", g_ViewedPlayer); });
| 877| 877| }
| 878| 878| 
| 879| 879| function getIdleLandTradersText(traderNumber)
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
|1138|1138| 				g_CivInfo.page = data.lastPage;
|1139|1139| 
|1140|1140| 			if (data.nextPage)
|1141|    |-				openStrucTree(data.nextPage)
|    |1141|+				openStrucTree(data.nextPage);
|1142|1142| 			else
|1143|1143| 				resumeGame();
|1144|1144| 		});

binaries/data/mods/public/gui/session/menu.js
| 482| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 557| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 623| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 623| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 876| »   »   g_ResourceData.GetCodes().forEach((resCode,·i)·=>·{·barterUpdateCommon(resCode,·i,·"barter",·g_ViewedPlayer)·});
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.

binaries/data/mods/public/gui/session/menu.js
|1141| »   »   »   »   openStrucTree(data.nextPage)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.

binaries/data/mods/mod/gui/msgbox/msgbox.js
|  48| »   switch·(captions.length)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/reference/structree/structree.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/reference/structree/structree.js
|   4|   4| var g_BuildList = {};
|   5|   5| 
|   6|   6| /**
|   7|    |- * Array of template names that can be trained from a unit, given a civ and unit template name.  
|    |   7|+ * Array of template names that can be trained from a unit, given a civ and unit template name.
|   8|   8|  */
|   9|   9| var g_TrainList = {};
|  10|  10| 
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/mod/gui/termsdialog/termsdialog.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/mod/gui/termsdialog/termsdialog.js
|  47|  47| function initLanguageSelection()
|  48|  48| {
|  49|  49| 	let languageLabel = Engine.GetGUIObjectByName("languageLabel");
|  50|    |-	let languageLabelWidth = Engine.GetTextWidth(languageLabel.font, languageLabel.caption)
|    |  50|+	let languageLabelWidth = Engine.GetTextWidth(languageLabel.font, languageLabel.caption);
|  51|  51| 	languageLabel.size = "0 0 " + languageLabelWidth + " 100%";
|  52|  52| 
|  53|  53| 	let languageDropdown = Engine.GetGUIObjectByName("languageDropdown");

binaries/data/mods/mod/gui/termsdialog/termsdialog.js
|  50| »   let·languageLabelWidth·=·Engine.GetTextWidth(languageLabel.font,·languageLabel.caption)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 119| 119| 			sprintf(
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122|    |-				option.min !== undefined && option.max === undefined ?
|    | 122|+					option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123|    |-					translateWithContext("option number", "Min: %(min)s") :
|    | 123|+						translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124|    |-				option.min === undefined && option.max !== undefined ?
|    | 124|+						option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125|    |-					translateWithContext("option number", "Max: %(max)s") :
|    | 125|+							translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126|    |-					"",
|    | 126|+							"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
| 129| 129| 					"max": option.max

binaries/data/mods/public/gui/options/options.js
| 235| »   »   »   let·value·=·optionType.guiToValue(control);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'value' is already declared in the upper scope.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 489| 489| 	Engine.GetGUIObjectByName("summaryText").caption =
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492|    |-		g_GameData.gui.isReplay ?
|    | 492|+			g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493|    |-			translate("Scores at the end of the game.") :
|    | 493|+				translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494|    |-		g_GameData.gui.disconnected ?
|    | 494|+				g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495|    |-			translate("You have been disconnected.") :
|    | 495|+					translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496|    |-		!assignedState ?
|    | 496|+					!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497|    |-			translate("You have left the game.") :
|    | 497|+						translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498|    |-		assignedState.state == "won" ?
|    | 498|+						assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499|    |-			translate("You have won the battle!") :
|    | 499|+							translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500|    |-		assignedState.state == "defeated" ?
|    | 500|+							assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501|    |-			translate("You have been defeated…") :
|    | 501|+								translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502|    |-			translate("You have abandoned the game.");
|    | 502|+								translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
| 506| 506| 			"time": timeToString(g_GameData.sim.timeElapsed)
| 507|    |-	});
|    | 507|+		});
| 508| 508| 
| 509| 509| 	let mapType = g_Settings.MapTypes.find(type => type.Name == g_GameData.sim.mapSettings.mapType);
| 510| 510| 	let mapSize = g_Settings.MapSizes.find(size => size.Tiles == g_GameData.sim.mapSettings.Size || 0);
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  62|  62| var g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|    |-		"label": translateWithContext("team", "None"),
|    |  65|+	"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|    |-		"id": -1
|    |  66|+	"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|    |-	}].concat(
|    |  67|+}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|    |-		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    |  68|+	Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|    |-			"label": i + 1,
|    |  69|+		"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|  72| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|    |-			"id": i
|    |  70|+		"id": i
|  71|  71| 		}))
|  72|  72| 	)
|  73|  73| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|    |-		}))
|    |  71|+	}))
|  72|  72| 	)
|  73|  73| );
|  74|  74| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|    |-	)
|    |  72|+)
|  73|  73| );
|  74|  74| 
|  75|  75| /**
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  78|  78| var g_RelicCountList = Object.keys(g_CivData).map((civ, i) => i + 1);
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|    |-		"name": translateWithContext("civilization", "Random"),
|    |  81|+	"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|    |-		"tooltip": translate("Picks one civilization at random when the game starts."),
|    |  82|+	"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|    |-		"color": g_ColorRandom,
|    |  83|+	"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|    |-		"code": "random"
|    |  84|+	"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|    |-	}].concat(
|    |  85|+}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|    |-		Object.keys(g_CivData).filter(
|    |  86|+	Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|    |-			civ => g_CivData[civ].SelectableInGameSetup
|    |  87|+		civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|    |-		).map(civ => ({
|    |  88|+	).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|    |-			"name": g_CivData[civ].Name,
|    |  89|+		"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|    |-			"tooltip": g_CivData[civ].History,
|    |  90|+		"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|    |-			"color": g_ColorRegular,
|    |  91|+		"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|    |-			"code": civ
|    |  92|+		"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|    |-		})).sort(sortNameIgnoreCase)
|    |  93|+	})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|  96|  96| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|    |-	)
|    |  94|+)
|  95|  95| );
|  96|  96| 
|  97|  97| /**
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1237|1237| 			offset = -Math.min(slideSpeed * dt, maxOffset);
|1238|1238| 	}
|1239|1239| 
|1240|    |-	updateSettingsPanelPosition(offset);	
|    |1240|+	updateSettingsPanelPosition(offset);
|1241|1241| }
|1242|1242| 
|1243|1243| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1765|1765| 	let biomeList;
|1766|1766| 
|1767|1767| 	if (g_GameAttributes.mapType == "random" && g_GameAttributes.settings.SupportedBiomes)
|1768|    |-	{
|    |1768|+	
|1769|1769| 		if (typeof g_GameAttributes.settings.SupportedBiomes == "string")
|1770|1770| 			biomeList = g_Settings.Biomes.filter(biome => biome.Id.startsWith(g_GameAttributes.settings.SupportedBiomes));
|1771|1771| 		else
|1772|1772| 			biomeList = g_Settings.Biomes.filter(
|1773|1773| 				biome => g_GameAttributes.settings.SupportedBiomes.indexOf(biome.Id) != -1);
|1774|    |-	}
|    |1774|+	
|1775|1775| 
|1776|1776| 	g_BiomeList = biomeList && prepareForDropdown(
|1777|1777| 		[{

binaries/data/mods/public/gui/gamesetup/gamesetup.js
|2009| »   while·(g_IsNetworked)
|    | [NORMAL] ESLintBear (no-unmodified-loop-condition):
|    | 'g_IsNetworked' is not modified in this loop.

Link to build: https://jenkins.wildfiregames.com/job/differential/805/

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Default...
Executing section Source...
Executing section JS...

binaries/data/mods/mod/gui/msgbox/msgbox.js
|  48| »   switch·(captions.length)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/reference/structree/structree.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/reference/structree/structree.js
|   4|   4| var g_BuildList = {};
|   5|   5| 
|   6|   6| /**
|   7|    |- * Array of template names that can be trained from a unit, given a civ and unit template name.  
|    |   7|+ * Array of template names that can be trained from a unit, given a civ and unit template name.
|   8|   8|  */
|   9|   9| var g_TrainList = {};
|  10|  10| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
| 452| 452| 				continue;
| 453| 453| 
| 454| 454| 			if (state.pack.progress == 0)
| 455|    |-			{
|    | 455|+			
| 456| 456| 				if (state.pack.packed)
| 457| 457| 					checks.unpackButton = true;
| 458| 458| 				else
| 459| 459| 					checks.packButton = true;
| 460|    |-			}
|    | 460|+			
| 461| 461| 			else if (state.pack.packed)
| 462| 462| 				checks.unpackCancelButton = true;
| 463| 463| 			else
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/selection_panels.js
| 941| 941| 			"player": data.player
| 942| 942| 		});
| 943| 943| 
| 944|    |-		let unitIds = data.unitEntStates.map(status => status.id)
|    | 944|+		let unitIds = data.unitEntStates.map(status => status.id);
| 945| 945| 		let [buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] =
| 946| 946| 			getTrainingStatus(unitIds, data.item, data.playerState);
| 947| 947| 

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 944| »   »   let·unitIds·=·data.unitEntStates.map(status·=>·status.id)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
| 873| 873| 	Engine.GetGUIObjectByName("barterHelp").hidden = !canBarter;
| 874| 874| 
| 875| 875| 	if (canBarter)
| 876|    |-		g_ResourceData.GetCodes().forEach((resCode, i) => { barterUpdateCommon(resCode, i, "barter", g_ViewedPlayer) });
|    | 876|+		g_ResourceData.GetCodes().forEach((resCode, i) => { barterUpdateCommon(resCode, i, "barter", g_ViewedPlayer); });
| 877| 877| }
| 878| 878| 
| 879| 879| function getIdleLandTradersText(traderNumber)
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/session/menu.js
|1138|1138| 				g_CivInfo.page = data.lastPage;
|1139|1139| 
|1140|1140| 			if (data.nextPage)
|1141|    |-				openStrucTree(data.nextPage)
|    |1141|+				openStrucTree(data.nextPage);
|1142|1142| 			else
|1143|1143| 				resumeGame();
|1144|1144| 		});

binaries/data/mods/public/gui/session/menu.js
| 482| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 557| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 623| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 623| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 876| »   »   g_ResourceData.GetCodes().forEach((resCode,·i)·=>·{·barterUpdateCommon(resCode,·i,·"barter",·g_ViewedPlayer)·});
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.

binaries/data/mods/public/gui/session/menu.js
|1141| »   »   »   »   openStrucTree(data.nextPage)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  62|  62| var g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|    |-		"label": translateWithContext("team", "None"),
|    |  65|+	"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|    |-		"id": -1
|    |  66|+	"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|    |-	}].concat(
|    |  67|+}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|    |-		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    |  68|+	Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|    |-			"label": i + 1,
|    |  69|+		"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|  72| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|    |-			"id": i
|    |  70|+		"id": i
|  71|  71| 		}))
|  72|  72| 	)
|  73|  73| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|    |-		}))
|    |  71|+	}))
|  72|  72| 	)
|  73|  73| );
|  74|  74| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|    |-	)
|    |  72|+)
|  73|  73| );
|  74|  74| 
|  75|  75| /**
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  78|  78| var g_RelicCountList = Object.keys(g_CivData).map((civ, i) => i + 1);
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|    |-		"name": translateWithContext("civilization", "Random"),
|    |  81|+	"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|    |-		"tooltip": translate("Picks one civilization at random when the game starts."),
|    |  82|+	"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|    |-		"color": g_ColorRandom,
|    |  83|+	"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|    |-		"code": "random"
|    |  84|+	"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|    |-	}].concat(
|    |  85|+}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|    |-		Object.keys(g_CivData).filter(
|    |  86|+	Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|    |-			civ => g_CivData[civ].SelectableInGameSetup
|    |  87|+		civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|    |-		).map(civ => ({
|    |  88|+	).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|    |-			"name": g_CivData[civ].Name,
|    |  89|+		"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|    |-			"tooltip": g_CivData[civ].History,
|    |  90|+		"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|    |-			"color": g_ColorRegular,
|    |  91|+		"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|    |-			"code": civ
|    |  92|+		"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|    |-		})).sort(sortNameIgnoreCase)
|    |  93|+	})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|  96|  96| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|    |-	)
|    |  94|+)
|  95|  95| );
|  96|  96| 
|  97|  97| /**
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1237|1237| 			offset = -Math.min(slideSpeed * dt, maxOffset);
|1238|1238| 	}
|1239|1239| 
|1240|    |-	updateSettingsPanelPosition(offset);	
|    |1240|+	updateSettingsPanelPosition(offset);
|1241|1241| }
|1242|1242| 
|1243|1243| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1765|1765| 	let biomeList;
|1766|1766| 
|1767|1767| 	if (g_GameAttributes.mapType == "random" && g_GameAttributes.settings.SupportedBiomes)
|1768|    |-	{
|    |1768|+	
|1769|1769| 		if (typeof g_GameAttributes.settings.SupportedBiomes == "string")
|1770|1770| 			biomeList = g_Settings.Biomes.filter(biome => biome.Id.startsWith(g_GameAttributes.settings.SupportedBiomes));
|1771|1771| 		else
|1772|1772| 			biomeList = g_Settings.Biomes.filter(
|1773|1773| 				biome => g_GameAttributes.settings.SupportedBiomes.indexOf(biome.Id) != -1);
|1774|    |-	}
|    |1774|+	
|1775|1775| 
|1776|1776| 	g_BiomeList = biomeList && prepareForDropdown(
|1777|1777| 		[{

binaries/data/mods/public/gui/gamesetup/gamesetup.js
|2009| »   while·(g_IsNetworked)
|    | [NORMAL] ESLintBear (no-unmodified-loop-condition):
|    | 'g_IsNetworked' is not modified in this loop.
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/mod/gui/termsdialog/termsdialog.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/mod/gui/termsdialog/termsdialog.js
|  47|  47| function initLanguageSelection()
|  48|  48| {
|  49|  49| 	let languageLabel = Engine.GetGUIObjectByName("languageLabel");
|  50|    |-	let languageLabelWidth = Engine.GetTextWidth(languageLabel.font, languageLabel.caption)
|    |  50|+	let languageLabelWidth = Engine.GetTextWidth(languageLabel.font, languageLabel.caption);
|  51|  51| 	languageLabel.size = "0 0 " + languageLabelWidth + " 100%";
|  52|  52| 
|  53|  53| 	let languageDropdown = Engine.GetGUIObjectByName("languageDropdown");

binaries/data/mods/mod/gui/termsdialog/termsdialog.js
|  50| »   let·languageLabelWidth·=·Engine.GetTextWidth(languageLabel.font,·languageLabel.caption)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 489| 489| 	Engine.GetGUIObjectByName("summaryText").caption =
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492|    |-		g_GameData.gui.isReplay ?
|    | 492|+			g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493|    |-			translate("Scores at the end of the game.") :
|    | 493|+				translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494|    |-		g_GameData.gui.disconnected ?
|    | 494|+				g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495|    |-			translate("You have been disconnected.") :
|    | 495|+					translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496|    |-		!assignedState ?
|    | 496|+					!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497|    |-			translate("You have left the game.") :
|    | 497|+						translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498|    |-		assignedState.state == "won" ?
|    | 498|+						assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499|    |-			translate("You have won the battle!") :
|    | 499|+							translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500|    |-		assignedState.state == "defeated" ?
|    | 500|+							assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501|    |-			translate("You have been defeated…") :
|    | 501|+								translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502|    |-			translate("You have abandoned the game.");
|    | 502|+								translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/summary/summary.js
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
| 506| 506| 			"time": timeToString(g_GameData.sim.timeElapsed)
| 507|    |-	});
|    | 507|+		});
| 508| 508| 
| 509| 509| 	let mapType = g_Settings.MapTypes.find(type => type.Name == g_GameData.sim.mapSettings.mapType);
| 510| 510| 	let mapSize = g_Settings.MapSizes.find(size => size.Tiles == g_GameData.sim.mapSettings.Size || 0);
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 119| 119| 			sprintf(
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122|    |-				option.min !== undefined && option.max === undefined ?
|    | 122|+					option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123|    |-					translateWithContext("option number", "Min: %(min)s") :
|    | 123|+						translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124|    |-				option.min === undefined && option.max !== undefined ?
|    | 124|+						option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125|    |-					translateWithContext("option number", "Max: %(max)s") :
|    | 125|+							translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/options/options.js
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126|    |-					"",
|    | 126|+							"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
| 129| 129| 					"max": option.max

binaries/data/mods/public/gui/options/options.js
| 235| »   »   »   let·value·=·optionType.guiToValue(control);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'value' is already declared in the upper scope.

binaries/data/mods/public/gui/reference/common/core.js
|  26| »   do·{
|    | [NORMAL] ESLintBear (brace-rules/brace-on-same-line):
|    | Opening curly brace appears on the same line as controlling statement.

Link to build: https://jenkins.wildfiregames.com/job/differential/806/

The patch now forbid to use different values passed to the GUI stack, only functions. Before the patch someone could easily add another param (with C++/JS modifications).

source/gui/GUIManager.cpp
115

Why different runtimes?

source/gui/GUIManager.h
162

Does it mean that function can't be changed then? Because before the patch someone could change the function.

The patch now forbid to use different values passed to the GUI stack, only functions.

I think you didn't read the patch right, because with and without the patch, one passes exactly one argument (that must be cloneable) to the callback function init called from PushGuiPage, and exactly one argument given by the PopGuiPage to the close function passed to PushGuiPage.
The patch does not remove any argument, but moves one property of the initarguments to a separate function argument.
Notice how wrong it logically is to add the function name of the close function to the arguments of function init(data).
So even the contrary - the currently committed code forbids to pass objects with an unrelated callback property to the init function, whereas with this patch that restriction is removed.

Before the patch someone could easily add another param (with C++/JS modifications).

This point seems different from the one of your first sentence.
I think with this sentence you mean that the argument pattern of

JSI_GUIManager::PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction)

could become

JSI_GUIManager::PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue callbackFunction, JS::HandleValue initData1, JS::HandleValue initData2, JS::HandleValue initData3, JS::HandleValue initData4, JS::HandleValue initData5, JS::HandleValue initData6, JS::HandleValue initData7, JS::HandleValue initData8, JS::HandleValue initData9, JS::HandleValue initData10 )

and thus allowing to pass up to 10 arguments to the init function.

The patch still doesn't forbid anyone to implement that, but yes, it does mean that the JS argument order would have to be changed to pass the close-callback function prior to the init-arguments.

To me it makes sense that we first pass the page name to open, then the arguments that are passed to that page, then the function specified which is called when the page is closed; i.e. chronological / logical order.

Notice that you can store arbitrary arguments in one argument in JS, so there is not much gain in implementing pageName, closeFunction, arg1, ..., argN and breaking the logical order.

Take an actual code example, and you also see that it can even be more confusing with arg1, ..., argN:

	Engine.PushGuiPage(
		"page_aiconfig.xml",
		ai => {
			g_LastViewedAIPlayer = -1;

			if (!ai.save || !g_IsController)
				return;

			g_GameAttributes.settings.PlayerData[ai.playerSlot].AI = ai.id;
			g_GameAttributes.settings.PlayerData[ai.playerSlot].AIDiff = ai.difficulty;
			g_GameAttributes.settings.PlayerData[ai.playerSlot].AIBehavior = ai.behavior;

			updateGameAttributes();
		},
		playerSlot,
		g_GameAttributes.settings.PlayerData[playerSlot].AI,
		g_GameAttributes.settings.PlayerData[playerSlot].AIDiff,
		g_GameAttributes.settings.PlayerData[playerSlot].AIBehavior
);

Compared to what I have in the diff proposed here:

	Engine.PushGuiPage(
		"page_aiconfig.xml",
		{
			"playerSlot": playerSlot,
			"id": g_GameAttributes.settings.PlayerData[playerSlot].AI,
			"difficulty": g_GameAttributes.settings.PlayerData[playerSlot].AIDiff,
			"behavior": g_GameAttributes.settings.PlayerData[playerSlot].AIBehavior
		},
		ai => {
			g_LastViewedAIPlayer = -1;

			if (!ai.save || !g_IsController)
				return;

			g_GameAttributes.settings.PlayerData[ai.playerSlot].AI = ai.id;
			g_GameAttributes.settings.PlayerData[ai.playerSlot].AIDiff = ai.difficulty;
			g_GameAttributes.settings.PlayerData[ai.playerSlot].AIBehavior = ai.behavior;

			updateGameAttributes();
		});
elexis marked an inline comment as done.Nov 29 2018, 3:55 PM
elexis added inline comments.
source/gui/GUIManager.h
162

Read the patch again to see how callbackPageName was used previously.

In D1684#66778, @elexis wrote:

The patch now forbid to use different values passed to the GUI stack, only functions.

I think you didn't read the patch right

I think you didn't read my comment right :)

Before the patch someone could easily add another param (with C++/JS modifications).

This point seems different from the one of your first sentence.

Nope.

The patch now forbid to use different values passed to the GUI stack, only functions.

I said nothing about the function call in JS, I said values to the GUI stack. It means that you can use the object to add another params (that I said in the second sentence).

This point seems different from the one of your first sentence.
I think with this sentence you mean that the argument pattern of

JSI_GUIManager::PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue initData, JS::HandleValue callbackFunction)

could become

JSI_GUIManager::PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue callbackFunction, JS::HandleValue initData1, JS::HandleValue initData2, JS::HandleValue initData3, JS::HandleValue initData4, JS::HandleValue initData5, JS::HandleValue initData6, JS::HandleValue initData7, JS::HandleValue initData8, JS::HandleValue initData9, JS::HandleValue initData10 )

As you see, I was right, with the patch you need to change a more number of lines to add new values to the GUI stack.

source/gui/GUIManager.h
162

I didn't ask how it's used in JS. I'm worrying about flexibility/constraints on the C++ part. Before the patch someone may change a callback after the push.

As you see, I was right, with the patch you need to change a more number of lines to add new values to the GUI stack.
The patch now forbid to use different values passed to the GUI stack, only functions.

"Only functions" is the part that makes no sense to me

In D1684#66783, @elexis wrote:

As you see, I was right, with the patch you need to change a more number of lines to add new values to the GUI stack.
The patch now forbid to use different values passed to the GUI stack, only functions.

"Only functions" is the part that makes no sense to me

BTW, I don't say that this diff makes things worse, that "only functions" make the GUI worse. I only need to know constraints/behaviours of our C++ code. So good work!

wraitii requested changes to this revision.Dec 31 2018, 9:56 AM
wraitii added a subscriber: wraitii.

Good change imo, see comments and it can probably committed.

source/gui/GUIManager.cpp
115

Can't this be done at GUIPage init instead? It looks a bit odd right now (and explains vlad's comment)

147

Why the cleanup?

This revision now requires changes to proceed.Dec 31 2018, 9:56 AM

Quick-glance review by Yves on January 17th:

Eine Funktion anstatt den Namen zu übergeben scheint grundsäztlich besser zu sein. Ich habe mir den Patch aber nur grob angeschaut.
Aufgefallen sind mir die init und reset Aufrufe auf PersistentRooteValue. Ich glaube das sollte nicht wiederholt passieren.
Die Runtime wird nach meinem Verständnis sowieso einmalig fix definiert und kann und muss dann nicht mehr geändert werden. 
Ich glaube man kann einfach mit dem "=" operator eine JS::UndefinedValue() zuweisen, habe es aber nicht ausprobiert.

and some feedback by leper on 2019-06-09.

source/gui/GUIManager.cpp
115

Why different runtimes?

The feature in this patch is that PushPage optionally receives a JS function that will be executed when closing the page.
This callbackFunction is allocated in srcScriptInterface, so not using that would be a crime, even if it is the same runtime.

m_PageStack.back().callbackFunction is the unset callback function of the new GUI page to be pushed.

Can't this be done at GUIPage init instead?

Yes, it can be moved, but including LoadPage in the SGUIPage constructor (i.e. calling LoadPage prior to push_back) reveals a bug in the codebase - some functions called in the CGUI` page constructor just end up fetching data from the topmost page instead of the constructed page itself (which breaks if the page isn't on the stack yet). A bit dirty, I will clean this ahead, but upload the version with everything combined as a backup to this diff.

147

I remember bruteforce-coding this reset calls as it kept segfaulting for days. I have to check again.

elexis updated this revision to Diff 9026.Jul 21 2019, 2:58 AM

Unify the back() calls by moving the statements into the SGUIPage ctor. Contains lots of unrelated cleanup, as backup.

Krinkle added inline comments.
binaries/data/mods/mod/gui/pregame/mainmenu.js
1 ↗(On Diff #9026)

Oops? :)

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/159/display/redirect

with the patch you need to change a more number of lines to add new values to the GUI stack.

There is the JS::AutoValueArray type if one wants to use multiple values.

But you would agree that having the order of arguments reflect the processing order?
i.e. first argument/s is/are the ones passed to init, and then the function called upon page closed?
In that case one would be forced to use exactly one JS value, unless one wants to split the JS calls like this
let page = Engine.PushGUIPage(arg1, arg2); page2.setCloseCallback(fooFunction), but this might be problematic since the init code of the new page will be executed before the close handler is assigned if at all.

source/gui/GUIManager.h
162

The variable was never used, but the data was stored in initData without this patch.
To me it sounds wrong to change the callback function, because that can be done within JS, but if someone wants that freedom, is he free to modify callbackFunction, it's not constant.

elexis updated this revision to Diff 9028.Jul 21 2019, 4:56 AM

Rebase following rP22520, remove oops

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Source...

source/gui/scripting/JSInterface_GUIManager.cpp
|   1| /*·Copyright·(C)·2018·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2018"

source/gui/GUIutil.h
|  27| 
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classGUITooltip{' is invalid C code. Use --std or --language to configure the language.

source/gui/GUItext.cpp
|   1| /*·Copyright·(C)·2017·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2017"

source/gui/scripting/JSInterface_GUIManager.h
|   1| /*·Copyright·(C)·2018·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2018"

source/gui/scripting/JSInterface_GUIManager.h
|  24| namespace·JSI_GUIManager
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'namespaceJSI_GUIManager{' is invalid C code. Use --std or --language to configure the language.

source/gui/CGUISprite.h
| 167| »   void·Invalidate();
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classCClientArea{' is invalid C code. Use --std or --language to configure the language.

source/gui/GUIRenderer.cpp
|   1| /*·Copyright·(C)·2015·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2015"

source/gui/GUIManager.h
|  47| class·CGUIManager
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classCGUIManager{' is invalid C code. Use --std or --language to configure the language.

source/gui/tests/test_ParseString.h
|   1| /*·Copyright·(C)·2014·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2014"

source/gui/tests/test_ParseString.h
|  24| class·TestGuiParseString·:·public·CxxTest::TestSuite
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classTestGuiParseString:' is invalid C code. Use --std or --language to configure the language.

source/gui/CGUI.cpp
|1680| »   m_ScrollBarStyles[name]·=·scrollbar;
|    | [MAJOR] CPPCheckBear (uninitStructMember):
|    | Uninitialized struct member: scrollbar.m_ScrollWheel

source/gui/CGUI.cpp
|1680| »   m_ScrollBarStyles[name]·=·scrollbar;
|    | [MAJOR] CPPCheckBear (uninitStructMember):
|    | Uninitialized struct member: scrollbar.m_ScrollSpeed

source/gui/CGUI.cpp
|1680| »   m_ScrollBarStyles[name]·=·scrollbar;
|    | [MAJOR] CPPCheckBear (uninitStructMember):
|    | Uninitialized struct member: scrollbar.m_ScrollButtons

source/gui/GUIRenderer.h
|  34| namespace·GUIRenderer
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'namespaceGUIRenderer{' is invalid C code. Use --std or --language to configure the language.

source/gui/GUIutil.cpp
|   1| /*·Copyright·(C)·2016·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2016"
Executing section JS...

binaries/data/mods/mod/gui/msgbox/msgbox.js
|  48| »   switch·(captions.length)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 452| 452| 				continue;
| 453| 453| 
| 454| 454| 			if (state.pack.progress == 0)
| 455|    |-			{
|    | 455|+			
| 456| 456| 				if (state.pack.packed)
| 457| 457| 					checks.unpackButton = true;
| 458| 458| 				else
| 459| 459| 					checks.packButton = true;
| 460|    |-			}
|    | 460|+			
| 461| 461| 			else if (state.pack.packed)
| 462| 462| 				checks.unpackCancelButton = true;
| 463| 463| 			else
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/reference/common/core.js
|  26| »   do·{
|    | [NORMAL] ESLintBear (brace-rules/brace-on-same-line):
|    | Opening curly brace appears on the same line as controlling statement.
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/reference/structree/structree.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/reference/structree/structree.js
|   4|   4| var g_BuildList = {};
|   5|   5| 
|   6|   6| /**
|   7|    |- * Array of template names that can be trained from a unit, given a civ and unit template name.  
|    |   7|+ * Array of template names that can be trained from a unit, given a civ and unit template name.
|   8|   8|  */
|   9|   9| var g_TrainList = {};
|  10|  10| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  62|  62| var g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|    |-		"label": translateWithContext("team", "None"),
|    |  65|+	"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|    |-		"id": -1
|    |  66|+	"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|    |-	}].concat(
|    |  67|+}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|    |-		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    |  68|+	Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|    |-			"label": i + 1,
|    |  69|+		"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|  72| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|    |-			"id": i
|    |  70|+		"id": i
|  71|  71| 		}))
|  72|  72| 	)
|  73|  73| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|    |-		}))
|    |  71|+	}))
|  72|  72| 	)
|  73|  73| );
|  74|  74| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|    |-	)
|    |  72|+)
|  73|  73| );
|  74|  74| 
|  75|  75| /**
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  78|  78| var g_RelicCountList = Object.keys(g_CivData).map((civ, i) => i + 1);
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|    |-		"name": translateWithContext("civilization", "Random"),
|    |  81|+	"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|    |-		"tooltip": translate("Picks one civilization at random when the game starts."),
|    |  82|+	"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|    |-		"color": g_ColorRandom,
|    |  83|+	"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|    |-		"code": "random"
|    |  84|+	"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|    |-	}].concat(
|    |  85|+}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|    |-		Object.keys(g_CivData).filter(
|    |  86|+	Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|    |-			civ => g_CivData[civ].SelectableInGameSetup
|    |  87|+		civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|    |-		).map(civ => ({
|    |  88|+	).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|    |-			"name": g_CivData[civ].Name,
|    |  89|+		"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|    |-			"tooltip": g_CivData[civ].History,
|    |  90|+		"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|    |-			"color": g_ColorRegular,
|    |  91|+		"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|    |-			"code": civ
|    |  92|+		"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|    |-		})).sort(sortNameIgnoreCase)
|    |  93|+	})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|  96|  96| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|    |-	)
|    |  94|+)
|  95|  95| );
|  96|  96| 
|  97|  97| /**
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1240|1240| 			offset = -Math.min(slideSpeed * dt, maxOffset);
|1241|1241| 	}
|1242|1242| 
|1243|    |-	updateSettingsPanelPosition(offset);	
|    |1243|+	updateSettingsPanelPosition(offset);
|1244|1244| }
|1245|1245| 
|1246|1246| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1774|1774| 	let biomeList;
|1775|1775| 
|1776|1776| 	if (g_GameAttributes.mapType == "random" && g_GameAttributes.settings.SupportedBiomes)
|1777|    |-	{
|    |1777|+	
|1778|1778| 		if (typeof g_GameAttributes.settings.SupportedBiomes == "string")
|1779|1779| 			biomeList = g_Settings.Biomes.filter(biome => biome.Id.startsWith(g_GameAttributes.settings.SupportedBiomes));
|1780|1780| 		else
|1781|1781| 			biomeList = g_Settings.Biomes.filter(
|1782|1782| 				biome => g_GameAttributes.settings.SupportedBiomes.indexOf(biome.Id) != -1);
|1783|    |-	}
|    |1783|+	
|1784|1784| 
|1785|1785| 	g_BiomeList = biomeList && prepareForDropdown(
|1786|1786| 		[{

binaries/data/mods/public/gui/gamesetup/gamesetup.js
|2018| »   while·(g_IsNetworked)
|    | [NORMAL] ESLintBear (no-unmodified-loop-condition):
|    | 'g_IsNetworked' is not modified in this loop.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 489| 489| 	Engine.GetGUIObjectByName("summaryText").caption =
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492|    |-		g_GameData.gui.isReplay ?
|    | 492|+			g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493|    |-			translate("Scores at the end of the game.") :
|    | 493|+				translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494|    |-		g_GameData.gui.disconnected ?
|    | 494|+				g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495|    |-			translate("You have been disconnected.") :
|    | 495|+					translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496|    |-		!assignedState ?
|    | 496|+					!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497|    |-			translate("You have left the game.") :
|    | 497|+						translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498|    |-		assignedState.state == "won" ?
|    | 498|+						assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499|    |-			translate("You have won the battle!") :
|    | 499|+							translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500|    |-		assignedState.state == "defeated" ?
|    | 500|+							assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501|    |-			translate("You have been defeated…") :
|    | 501|+								translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502|    |-			translate("You have abandoned the game.");
|    | 502|+								translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
| 506| 506| 			"time": timeToString(g_GameData.sim.timeElapsed)
| 507|    |-	});
|    | 507|+		});
| 508| 508| 
| 509| 509| 	let mapType = g_Settings.MapTypes.find(type => type.Name == g_GameData.sim.mapSettings.mapType);
| 510| 510| 	let mapSize = g_Settings.MapSizes.find(size => size.Tiles == g_GameData.sim.mapSettings.Size || 0);
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/menu.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/menu.js
|1138|1138| 				g_CivInfo.page = data.lastPage;
|1139|1139| 
|1140|1140| 			if (data.nextPage)
|1141|    |-				openStrucTree(data.nextPage)
|    |1141|+				openStrucTree(data.nextPage);
|1142|1142| 			else
|1143|1143| 				resumeGame();
|1144|1144| 		});

binaries/data/mods/public/gui/session/menu.js
| 482| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 514| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 557| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 623| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 623| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
|1141| »   »   »   »   openStrucTree(data.nextPage)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 119| 119| 			sprintf(
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122|    |-				option.min !== undefined && option.max === undefined ?
|    | 122|+					option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123|    |-					translateWithContext("option number", "Min: %(min)s") :
|    | 123|+						translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124|    |-				option.min === undefined && option.max !== undefined ?
|    | 124|+						option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125|    |-					translateWithContext("option number", "Max: %(max)s") :
|    | 125|+							translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126|    |-					"",
|    | 126|+							"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
| 129| 129| 					"max": option.max

binaries/data/mods/public/gui/options/options.js
| 235| »   »   »   let·value·=·optionType.guiToValue(control);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'value' is already declared in the upper scope.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/160/display/redirect

Haven't tested yet, but this still looks good to me and if you've tested it enough I'd encourage you to commit.

source/gui/GUIManager.h
162

I'm guessing if one does
Engine.PushGUiPage({}, SomeFunction) then does 'someFunction = () => "whatever")`, then the call-back will still call the originally passed function, per JS reference rules, and not the one at someFunction.

Thus I think this callback can't be changed from JS code once passed

elexis added inline comments.Jul 25 2019, 12:51 PM
source/gui/GUIManager.h
162

Engine.PushGUiPage(..., candy ? candyHandler : whateverHandler) and seems much cleaner to me than changing it inretrospect, because it means the reader discovers the callback functions when he first reads the line, rather than being misled to believe that the whateverHandler is going to be the one when it's somewhere else in the code replaced with candyHandler.

wraitii added inline comments.Jul 25 2019, 12:58 PM
source/gui/GUIManager.h
162

Oh I completely agree I was just trying to clarify things.

In D1684#87801, @elexis wrote:

Quick-glance review by Yves on January 17th:

Ich glaube man kann einfach mit dem "=" operator eine JS::UndefinedValue() zuweisen, habe es aber nicht ausprobiert.

Translation:

I belive one can assign JS::UndefinedValue() using the = operator, but I didn't test.

There is also setUndefined(). The new case uses a shared_ptr, so it can drop the entire value upon reset, rather than the value resetting its internal value.

binaries/data/mods/mod/gui/common/functions_msgbox.js
2

The function is created an executed in the same GUI page, so it's actually not passed around.
Passing functions around isn't paintful currently (sm38, sm45). It doesn't work with the Structured-Clone algorithm, but the JS::HandleValue, JS::PersistentRooted, JS::Heap types can hold a variable rooted only in the runtime, not the context. We will see if that changes for future SM versions, but I expect SM won't lose functionality.

source/gui/GUIManager.cpp
121

One doesn't have to Root the object to test if it is a function. This means we only need the ScriptRuntime here to init the Persistent value, making this slightly easier to digest for the reader.

source/gui/GUIManager.h
167

Notice that SGUIPage is copied around for fun & nonprofit each tick. Using shared_ptr in the updated version.
This should be changed by having the pagestack store smart pointers instead of the structure, and the structure not use pointers for each member. (But since that patch requires changes to the Pop page function, I rather remove that first and use a shared_ptr here now and remove the ptr later. Also that patch will lead to fixing the other pagestack iteration issues marked in the TODOs in this file.)

Notice that storing it in the SGUIPage instead of CGUI means that it will survive the hotloading gui reset.

elexis updated this revision to Diff 9326.Aug 14 2019, 8:47 PM

Rebase following preliminary commits.

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Source...

source/gui/GUIManager.h
|  47| class·CGUIManager
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'classCGUIManager{' is invalid C code. Use --std or --language to configure the language.

source/gui/scripting/JSInterface_GUIManager.h
|   1| /*·Copyright·(C)·2018·Wildfire·Games.
|    | [NORMAL] LicenseYearBear:
|    | License should have "2019" year instead of "2018"

source/gui/scripting/JSInterface_GUIManager.h
|  24| namespace·JSI_GUIManager
|    | [MAJOR] CPPCheckBear (syntaxError):
|    | Code 'namespaceJSI_GUIManager{' is invalid C code. Use --std or --language to configure the language.
Executing section JS...
|    | [NORMAL] ESLintBear (space-before-function-paren):
|    | Unexpected space before function parentheses.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/selection_panels.js
| 763| 763| 				addResearchToQueue(data.item.researchFacilityId, t);
| 764| 764| 			})(tech);
| 765| 765| 
| 766|    |-			button.onPressRight = (t => function () {
|    | 766|+			button.onPressRight = (t => function() {
| 767| 767| 				showTemplateDetails(
| 768| 768| 					t,
| 769| 769| 					GetTemplateData(data.unitEntStates.find(state => state.id == data.item.researchFacilityId).template).nativeCiv);

binaries/data/mods/public/gui/session/selection_panels.js
|  48| »   »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
|  59| »   »   switch·(data.item)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/selection_panels.js
| 731| »   »   »   »   »   »   switch·(entity.check)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/reference/common/core.js
|  26| »   do·{
|    | [NORMAL] ESLintBear (brace-rules/brace-on-same-line):
|    | Opening curly brace appears on the same line as controlling statement.

binaries/data/mods/mod/gui/msgbox/msgbox.js
|  48| »   switch·(captions.length)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 489| 489| 	Engine.GetGUIObjectByName("summaryText").caption =
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492|    |-		g_GameData.gui.isReplay ?
|    | 492|+			g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 490| 490| 		g_GameData.gui.isInGame ?
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493|    |-			translate("Scores at the end of the game.") :
|    | 493|+				translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 491| 491| 			translate("Current Scores") :
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494|    |-		g_GameData.gui.disconnected ?
|    | 494|+				g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 492| 492| 		g_GameData.gui.isReplay ?
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495|    |-			translate("You have been disconnected.") :
|    | 495|+					translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 493| 493| 			translate("Scores at the end of the game.") :
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496|    |-		!assignedState ?
|    | 496|+					!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 494| 494| 		g_GameData.gui.disconnected ?
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497|    |-			translate("You have left the game.") :
|    | 497|+						translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 495| 495| 			translate("You have been disconnected.") :
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498|    |-		assignedState.state == "won" ?
|    | 498|+						assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 496| 496| 		!assignedState ?
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499|    |-			translate("You have won the battle!") :
|    | 499|+							translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 497| 497| 			translate("You have left the game.") :
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500|    |-		assignedState.state == "defeated" ?
|    | 500|+							assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 498| 498| 		assignedState.state == "won" ?
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501|    |-			translate("You have been defeated…") :
|    | 501|+								translate("You have been defeated…") :
| 502| 502| 			translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 499| 499| 			translate("You have won the battle!") :
| 500| 500| 		assignedState.state == "defeated" ?
| 501| 501| 			translate("You have been defeated…") :
| 502|    |-			translate("You have abandoned the game.");
|    | 502|+								translate("You have abandoned the game.");
| 503| 503| 
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/summary/summary.js
| 504| 504| 	Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(
| 505| 505| 		translate("Game time elapsed: %(time)s"), {
| 506| 506| 			"time": timeToString(g_GameData.sim.timeElapsed)
| 507|    |-	});
|    | 507|+		});
| 508| 508| 
| 509| 509| 	let mapType = g_Settings.MapTypes.find(type => type.Name == g_GameData.sim.mapSettings.mapType);
| 510| 510| 	let mapSize = g_Settings.MapSizes.find(size => size.Tiles == g_GameData.sim.mapSettings.Size || 0);
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/menu.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/menu.js
|1127|1127| 				g_CivInfo.page = data.lastPage;
|1128|1128| 
|1129|1129| 			if (data.nextPage)
|1130|    |-				openStrucTree(data.nextPage)
|    |1130|+				openStrucTree(data.nextPage);
|1131|1131| 			else
|1132|1132| 				resumeGame();
|1133|1133| 		});

binaries/data/mods/public/gui/session/menu.js
| 471| »   »   button.onPress·=·(function(player,·stance)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'stance' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 503| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 503| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'resCode' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 503| »   »   button.onPress·=·(function(i,·resCode,·button)·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 546| »   button.onPress·=·(function(i)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 612| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'i' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
| 612| »   button.onPress·=·(function(i,·button)·{·return·function()·{
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'button' is already declared in the upper scope.

binaries/data/mods/public/gui/session/menu.js
|1130| »   »   »   »   openStrucTree(data.nextPage)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  62|  62| var g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|    |-		"label": translateWithContext("team", "None"),
|    |  65|+	"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  63|  63| 
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|    |-		"id": -1
|    |  66|+	"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  64|  64| var g_PlayerTeamList = prepareForDropdown([{
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|    |-	}].concat(
|    |  67|+}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  65|  65| 		"label": translateWithContext("team", "None"),
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|    |-		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    |  68|+	Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  66|  66| 		"id": -1
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|    |-			"label": i + 1,
|    |  69|+		"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|  72| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  67|  67| 	}].concat(
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|    |-			"id": i
|    |  70|+		"id": i
|  71|  71| 		}))
|  72|  72| 	)
|  73|  73| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  68|  68| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|    |-		}))
|    |  71|+	}))
|  72|  72| 	)
|  73|  73| );
|  74|  74| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  69|  69| 			"label": i + 1,
|  70|  70| 			"id": i
|  71|  71| 		}))
|  72|    |-	)
|    |  72|+)
|  73|  73| );
|  74|  74| 
|  75|  75| /**
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  78|  78| var g_RelicCountList = Object.keys(g_CivData).map((civ, i) => i + 1);
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|    |-		"name": translateWithContext("civilization", "Random"),
|    |  81|+	"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  79|  79| 
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|    |-		"tooltip": translate("Picks one civilization at random when the game starts."),
|    |  82|+	"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  80|  80| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|    |-		"color": g_ColorRandom,
|    |  83|+	"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  81|  81| 		"name": translateWithContext("civilization", "Random"),
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|    |-		"code": "random"
|    |  84|+	"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  82|  82| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|    |-	}].concat(
|    |  85|+}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  83|  83| 		"color": g_ColorRandom,
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|    |-		Object.keys(g_CivData).filter(
|    |  86|+	Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  84|  84| 		"code": "random"
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|    |-			civ => g_CivData[civ].SelectableInGameSetup
|    |  87|+		civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  85|  85| 	}].concat(
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|    |-		).map(civ => ({
|    |  88|+	).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  86|  86| 		Object.keys(g_CivData).filter(
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|    |-			"name": g_CivData[civ].Name,
|    |  89|+		"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  87|  87| 			civ => g_CivData[civ].SelectableInGameSetup
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|    |-			"tooltip": g_CivData[civ].History,
|    |  90|+		"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  88|  88| 		).map(civ => ({
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|    |-			"color": g_ColorRegular,
|    |  91|+		"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  89|  89| 			"name": g_CivData[civ].Name,
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|    |-			"code": civ
|    |  92|+		"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  90|  90| 			"tooltip": g_CivData[civ].History,
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|    |-		})).sort(sortNameIgnoreCase)
|    |  93|+	})).sort(sortNameIgnoreCase)
|  94|  94| 	)
|  95|  95| );
|  96|  96| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  91|  91| 			"color": g_ColorRegular,
|  92|  92| 			"code": civ
|  93|  93| 		})).sort(sortNameIgnoreCase)
|  94|    |-	)
|    |  94|+)
|  95|  95| );
|  96|  96| 
|  97|  97| /**
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1240|1240| 			offset = -Math.min(slideSpeed * dt, maxOffset);
|1241|1241| 	}
|1242|1242| 
|1243|    |-	updateSettingsPanelPosition(offset);	
|    |1243|+	updateSettingsPanelPosition(offset);
|1244|1244| }
|1245|1245| 
|1246|1246| /**
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/reference/structree/structree.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/reference/structree/structree.js
|   4|   4| var g_BuildList = {};
|   5|   5| 
|   6|   6| /**
|   7|    |- * Array of template names that can be trained from a unit, given a civ and unit template name.  
|    |   7|+ * Array of template names that can be trained from a unit, given a civ and unit template name.
|   8|   8|  */
|   9|   9| var g_TrainList = {};
|  10|  10| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 119| 119| 			sprintf(
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122|    |-				option.min !== undefined && option.max === undefined ?
|    | 122|+					option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 120| 120| 				option.min !== undefined && option.max !== undefined ?
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123|    |-					translateWithContext("option number", "Min: %(min)s") :
|    | 123|+						translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 121| 121| 					translateWithContext("option number", "Min: %(min)s, Max: %(max)s") :
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124|    |-				option.min === undefined && option.max !== undefined ?
|    | 124|+						option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 122| 122| 				option.min !== undefined && option.max === undefined ?
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125|    |-					translateWithContext("option number", "Max: %(max)s") :
|    | 125|+							translateWithContext("option number", "Max: %(max)s") :
| 126| 126| 					"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/options/options.js
| 123| 123| 					translateWithContext("option number", "Min: %(min)s") :
| 124| 124| 				option.min === undefined && option.max !== undefined ?
| 125| 125| 					translateWithContext("option number", "Max: %(max)s") :
| 126|    |-					"",
|    | 126|+							"",
| 127| 127| 				{
| 128| 128| 					"min": option.min,
| 129| 129| 					"max": option.max

binaries/data/mods/public/gui/options/options.js
| 235| »   »   »   let·value·=·optionType.guiToValue(control);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'value' is already declared in the upper scope.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/376/display/redirect

Recap:

Current behavior of PushGuiPage(pageName, arguments, callback) (for civ/structree in rP21339, utilizing Pop/PopCB split in rP14496).:

  • (1) The page is closed without callback function being called
  • (2) a different page is opened that decides to call the callback handler when that gets closed

Expected behavior of PushGuiPage(pageName, arguments, callback):

  • The callback function is called when the newly pushed page is closed.
  • The callback function is not called when a different page is closed.

Also consider this code:

		for (let i = 0; i < 5; ++i)
			Engine.PushGuiPage("page_splashscreen.xml", {}, () => { warn("close " + i)});

It's deceptive code however, since the callback handler will be called in its parent GUI page, not in the page that defined it.

For example this will only work for the last page if called from mainmenu.js:

		for (let i = 0; i < 5; ++i)
			Engine.PushGuiPage("page_splashscreen.xml", {}, () => { warn("close " + i + uneval(Engine.GetGUIObjectByName("submenu").name) )});

So the function is executed correctly, it's just not executed in the GUI page that the author might expect in case he does things like pushing multiple pages from the current page.
Another issue is that PushPage pushes on top of the stack. But shouldn't it be inserted after the current page if its not the topmost one rather? Similar to JSI*IGUIObject pulling the current object from the JS private context, the same could happen here.

If one wants to support pushing multiple pages, one needs to implement a map that has GUI page pointers and maps to the callback function.
But if one goes that way, there will have to be many more things to take care of if one wants to be consequential.

The proposed code doesn't add a regresssion, as the previous code breaks in the same place:
Without the patch:

		for (let i = 0; i < 5; ++i)
			Engine.PushGuiPage("page_splashscreen.xml", { "callback": "SplashScreenClosedCallback" }});

This works once and bugs 4x as well.

But with the patch, one can call the function in the context GUI context of the pushed page.

Notice that Pushing multiple pages from the same page is kind of violating the stack and callback rule already:
Page 1 pushes Page2, Page3, Page, 4,, Page, 5, so there are 3 pages between Page 1 and Page 5, yet Page 1 wants to be informed when Page 5 closes.
The assumption of the callback author is that if a page is closed, that the current page has focus, is on top, and might push another page. But it might not want to do that if it's not the topmost page and defer that to later.
It seems like it's always broken with this model if there is code after PopPage or PushPage.

So I can and will only work with the stack model until the model is revisted and not implement shenanigans that don't even have a use case, whereas the proposed diff has multiple use cases (messagebox, simpler PopPage code, parent ensured to have its callback called, being able to inline functions for #5322).

binaries/data/mods/mod/gui/common/functions_msgbox.js
33

With the proposed code one can stack messageboxes from the same page and have the correct callback handler called:

for (let i = 0; i < 5; ++i)

		messageBox(600 - i * 5, 300 - i*5, "caption" + i, "text", [translate("OK")], [() => { warn("hello " + i); }]);

Whereas the previous code opened one message box and complained 4 times.

So what's the "new" stack model that this patch introduces exactly?
Is the current GUI Model that we can only have one "axis", so pushing 5 times from the same pages results in:

  • Main -> Page1 -> Page2 -> Page3

Instead of the (more expected):

Main -> Page 1
     -> Page 2
     -> Page 3

?

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/395/display/redirect

None, this doesn't change the stack model.

typedef std::vector<SGUIPage> PageStackType;
PageStackType m_PageStack;

The issue mentioned happens with and without the patch:

Opening 5 pages from the current page:

		for (let i = 0; i < 5; ++i)
			Engine.PushGuiPage("page_splashscreen.xml", { "callback": "SplashScreenClosedCallback" }});

means that the callback handler is called when the popped page is closed for the parent then, not the parent now.

This is broken before and after, just slightly less broken now because functions that dont depend on a GUI page can still be performed (for example saving something to config) whereas before they failed at finding the function with the given name.

Fixing this would require each GUI page to keep references to the other GUI pages, which is close to or might be better done with redesigning the stack model, which can be done better in a separate patch and doesn't infuence much of this patch.

Also we don't have any code currently that does such a thing and no conceivable use case, but it's theoretically possible.

Vladislav was so kind to check the patch again, especially for the shared_ptr resigin on the SGUIPage.
http://irclogs.wildfiregames.com/2019-08/2019-08-14-QuakeNet-%230ad-dev.log

20:54 < Vladislav> elexis: I agree with your current shared_ptr, since SGUIPage has other members in shared_ptr. But it might (or should) be improved. We may write a smart lock.

At last did a test with valgrind, pushed and popped dialogs around a bit, didn't find any leaks in GUIManager, and CGUI only has Draw() leaks relating to textures afaik.

This revision was not accepted when it landed; it landed in state Needs Review.Aug 16 2019, 8:46 PM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Owners added a subscriber: Restricted Owners Package.Aug 16 2019, 8:46 PM