@@ -207,13 +207,29 @@ function getSelectedTeams()
207207 return JSON . parse ( cookieVal ) ;
208208}
209209
210- function getScoreboard ( )
210+ function getScoreboards ( mobile )
211211{
212- var scoreboard = document . getElementsByClassName ( "scoreboard" ) ;
213- if ( scoreboard === null || scoreboard [ 0 ] === null || scoreboard [ 0 ] === undefined ) {
212+ const scoreboards = document . getElementsByClassName ( "scoreboard" ) ;
213+ if ( scoreboards === null || scoreboards [ 0 ] === null || scoreboards [ 0 ] === undefined ) {
214214 return null ;
215215 }
216- return scoreboard [ 0 ] . rows ;
216+ let scoreboardRows = { } ;
217+ const mobileScoreboardClass = 'mobile-scoreboard' ;
218+ const desktopScoreboardClass = 'desktop-scoreboard' ;
219+ for ( let i = 0 ; i < scoreboards . length ; i ++ ) {
220+ if ( scoreboards [ i ] . classList . contains ( mobileScoreboardClass ) ) {
221+ scoreboardRows . mobile = scoreboards [ i ] . rows ;
222+ } else if ( scoreboards [ i ] . classList . contains ( desktopScoreboardClass ) ) {
223+ scoreboardRows . desktop = scoreboards [ i ] . rows ;
224+ }
225+ }
226+ if ( mobile === undefined ) {
227+ return scoreboardRows ;
228+ } else if ( mobile ) {
229+ return scoreboardRows . mobile ;
230+ } else {
231+ return scoreboardRows . desktop ;
232+ }
217233}
218234
219235function getRank ( row )
@@ -226,7 +242,7 @@ function getHeartCol(row) {
226242 var td = null ;
227243 // search for td before the team name
228244 for ( var i = 1 ; i < 4 ; i ++ ) {
229- if ( tds [ i ] . className == "scoretn" ) {
245+ if ( tds [ i ] . classList . contains ( "scoretn" ) ) {
230246 td = tds [ i - 1 ] ;
231247 break ;
232248 }
@@ -249,16 +265,28 @@ function getTeamname(row)
249265 return row . getAttribute ( "data-team-id" ) ;
250266}
251267
252- function toggle ( id , show )
268+ function toggle ( id , show , mobile )
253269{
254- var scoreboard = getScoreboard ( ) ;
270+ var scoreboard = getScoreboards ( mobile ) ;
255271 if ( scoreboard === null ) return ;
256272
273+ // Filter out all rows that do not have a data-team-id attribute or have
274+ // the class `scoreheader`.
275+ // The mobile scoreboard has them, and we need to ignore them.
276+ scoreboard = Array . from ( scoreboard )
277+ . filter (
278+ row => row . getAttribute ( "data-team-id" )
279+ || row . classList . contains ( "scoreheader" )
280+ ) ;
281+
257282 var favTeams = getSelectedTeams ( ) ;
258283 // count visible favourite teams (if filtered)
259284 var visCnt = 0 ;
260285 for ( var i = 0 ; i < favTeams . length ; i ++ ) {
261286 for ( var j = 0 ; j < scoreboard . length ; j ++ ) {
287+ if ( ! scoreboard [ j ] . getAttribute ( "data-team-id" ) ) {
288+ continue ;
289+ }
262290 var scoreTeamname = getTeamname ( scoreboard [ j ] ) ;
263291 if ( scoreTeamname === null ) {
264292 continue ;
@@ -302,69 +330,99 @@ function toggle(id, show)
302330 } ) ;
303331}
304332
305- function addHeart ( rank , row , id , isFav )
333+ function addHeart ( rank , row , id , isFav , mobile )
306334{
307335 var heartCol = getHeartCol ( row ) ;
308336 var iconClass = isFav ? "fas fa-heart" : "far fa-heart" ;
309- return heartCol . innerHTML + "<span class=\"heart " + iconClass + "\" onclick=\"toggle(" + id + "," + ( isFav ? "false" : "true" ) + ")\"></span>" ;
337+ return heartCol . innerHTML + "<span class=\"heart " + iconClass + "\" onclick=\"toggle(" + id + "," + ( isFav ? "false" : "true" ) + "," + mobile + " )\"></span>";
310338}
311339
312340function initFavouriteTeams ( )
313341{
314- var scoreboard = getScoreboard ( ) ;
315- if ( scoreboard === null ) {
342+ const scoreboards = getScoreboards ( ) ;
343+ if ( scoreboards === null ) {
316344 return ;
317345 }
318346
319347 var favTeams = getSelectedTeams ( ) ;
320- var toAdd = new Array ( ) ;
321- var cntFound = 0 ;
322- var lastRank = 0 ;
323- for ( var j = 0 ; j < scoreboard . length ; j ++ ) {
324- var found = false ;
325- var teamname = getTeamname ( scoreboard [ j ] ) ;
326- if ( teamname === null ) {
327- continue ;
328- }
329- var firstCol = getRank ( scoreboard [ j ] ) ;
330- var heartCol = getHeartCol ( scoreboard [ j ] ) ;
331- var rank = firstCol . innerHTML ;
332- for ( var i = 0 ; i < favTeams . length ; i ++ ) {
333- if ( teamname === favTeams [ i ] ) {
334- found = true ;
335- heartCol . innerHTML = addHeart ( rank , scoreboard [ j ] , j , found ) ;
336- toAdd [ cntFound ] = scoreboard [ j ] . cloneNode ( true ) ;
337- if ( rank . trim ( ) . length === 0 ) {
338- // make rank explicit in case of tie
339- getRank ( toAdd [ cntFound ] ) . innerHTML += lastRank ;
348+ Object . keys ( scoreboards ) . forEach ( function ( key ) {
349+ var toAdd = new Array ( ) ;
350+ var toAddMobile = new Array ( ) ;
351+ var cntFound = 0 ;
352+ var lastRank = 0 ;
353+ const scoreboard = scoreboards [ key ] ;
354+ const mobile = key === 'mobile' ;
355+ let teamIndex = 1 ;
356+ for ( var j = 0 ; j < scoreboard . length ; j ++ ) {
357+ var found = false ;
358+ var teamname = getTeamname ( scoreboard [ j ] ) ;
359+ if ( teamname === null ) {
360+ continue ;
361+ }
362+ var firstCol = getRank ( scoreboard [ j ] ) ;
363+ var heartCol = getHeartCol ( scoreboard [ j ] ) ;
364+ var rank = firstCol . innerHTML ;
365+ for ( var i = 0 ; i < favTeams . length ; i ++ ) {
366+ if ( teamname === favTeams [ i ] ) {
367+ found = true ;
368+ heartCol . innerHTML = addHeart ( rank , scoreboard [ j ] , teamIndex , found , mobile ) ;
369+ toAdd [ cntFound ] = scoreboard [ j ] . cloneNode ( true ) ;
370+ if ( mobile ) {
371+ toAddMobile [ cntFound ] = scoreboard [ j + 1 ] . cloneNode ( true ) ;
372+ }
373+ if ( rank . trim ( ) . length === 0 ) {
374+ // make rank explicit in case of tie
375+ getRank ( toAdd [ cntFound ] ) . innerHTML += lastRank ;
376+ }
377+ scoreboard [ j ] . style . background = "lightyellow" ;
378+ const scoretn = scoreboard [ j ] . querySelector ( '.scoretn' ) ;
379+ if ( scoretn && scoretn . classList . contains ( 'cl_FFFFFF' ) ) {
380+ scoretn . classList . remove ( 'cl_FFFFFF' ) ;
381+ scoretn . classList . add ( 'cl_FFFFE0' ) ;
382+ }
383+ if ( mobile ) {
384+ scoreboard [ j + 1 ] . style . background = "lightyellow" ;
385+ }
386+ cntFound ++ ;
387+ break ;
340388 }
341- scoreboard [ j ] . style . background = "lightyellow" ;
342- cntFound ++ ;
343- break ;
344389 }
390+ if ( ! found ) {
391+ heartCol . innerHTML = addHeart ( rank , scoreboard [ j ] , teamIndex , found , mobile ) ;
392+ }
393+ if ( rank !== "" ) {
394+ lastRank = rank ;
395+ }
396+
397+ teamIndex ++ ;
345398 }
346- if ( ! found ) {
347- heartCol . innerHTML = addHeart ( rank , scoreboard [ j ] , j , found ) ;
348- }
349- if ( rank !== "" ) {
350- lastRank = rank ;
351- }
352- }
353399
354- // copy favourite teams to the top of the scoreboard
355- for ( var i = 0 ; i < cntFound ; i ++ ) {
356- var copy = toAdd [ i ] ;
357- var style = "" ;
358- if ( i === 0 ) {
359- style += "border-top: 2px solid black;" ;
400+ let addCounter = 1 ;
401+ const copyRow = function ( i , copy , addTopBorder , addBottomBorder , noMiddleBorder ) {
402+ let style = "" ;
403+ if ( noMiddleBorder ) {
404+ style += "border-bottom-width: 0;" ;
405+ }
406+ if ( addTopBorder && i === 0 ) {
407+ style += "border-top: 2px solid black;" ;
408+ }
409+ if ( addBottomBorder && i === cntFound - 1 ) {
410+ style += "border-bottom: thick solid black;" ;
411+ }
412+ copy . setAttribute ( "style" , style ) ;
413+ const tbody = scoreboard [ 1 ] . parentNode ;
414+ tbody . insertBefore ( copy , scoreboard [ addCounter ] ) ;
415+ addCounter ++ ;
360416 }
361- if ( i === cntFound - 1 ) {
362- style += "border-bottom: thick solid black;" ;
417+
418+ // copy favourite teams to the top of the scoreboard
419+ for ( let i = 0 ; i < cntFound ; i ++ ) {
420+ copyRow ( i , toAdd [ i ] , true , ! mobile , mobile ) ;
421+ if ( mobile ) {
422+ copyRow ( i , toAddMobile [ i ] , false , true , false ) ;
423+ }
363424 }
364- copy . setAttribute ( "style" , style ) ;
365- var tbody = scoreboard [ 1 ] . parentNode ;
366- tbody . insertBefore ( copy , scoreboard [ i + 1 ] ) ;
367- }
425+ } ) ;
368426}
369427
370428// This function is a specific addition for using DOMjudge within a
0 commit comments