diff --git a/vasl_templates/webapp/static/html-editor.js b/vasl_templates/webapp/static/html-editor.js index b3d0d92..2c8ce25 100644 --- a/vasl_templates/webapp/static/html-editor.js +++ b/vasl_templates/webapp/static/html-editor.js @@ -170,12 +170,7 @@ function unloadTrumbowyg( $ctrl, removeFirstPara ) } } - // remove superfluous
tags - val = strReplaceAll( val, "

", "

" ) ; - while ( val.substring( val.length-4 ) === "
" ) - val = val.substring( 0, val.length-4 ).trim() ; - - return val ; + return _tidyHTML( val ) ; } // -------------------------------------------------------------------- @@ -355,6 +350,12 @@ function onEditHtmlTextbox( $ctrl, objName ) { } ) ; } +function unloadHtmlTextbox( $ctrl ) +{ + // unload the HTML textbox + return _tidyHTML( $ctrl.html() ) ; +} + // -------------------------------------------------------------------- function sanitizeParams( params ) @@ -379,3 +380,41 @@ function sanitizeHTML( val ) { USE_PROFILES: { html: true } } ) ; } + +// -------------------------------------------------------------------- + +var $gTranslateHtmlDiv = null ; + +function translateHTML( val ) +{ + // FUDGE! Allowing users to edit content in an HTML textbox introduced a problem when checking + // if they had made any changes. We have a lot of HTML content in data files (e.g. vehicle/ordnance + // capabilities and comments), and when we load them into an HTML textbox, we don't always get + // exactly the same thing back e.g. "×2" comes back as "\xd72" :-/ + // Fixing up this kind of thing in the data files would be a big job, and wouldn't even be guaranteed + // to work, since what happens is surely browser-dependent, and so the only way to detect if this + // is happening is to load the content into a contenteditable and see what we get back. Sigh... + + if ( $gTranslateHtmlDiv === null ) { + $gTranslateHtmlDiv = $( "
" ) ; + $( "body" ).append( $gTranslateHtmlDiv ) ; + } + $gTranslateHtmlDiv.html( val ) ; + return $gTranslateHtmlDiv.html() ; +} + +function _tidyHTML( val ) +{ + val = val.trim() ; + + // remove superfluous
tags + val = strReplaceAll( val, "

", "

" ) ; + while ( val.substring( val.length-4 ) === "
" ) + val = val.substring( 0, val.length-4 ).trim() ; + + // remove superfluous

blocks + if ( val.substring(0,3) === "

" && val.substring(val.length-4) === "

" && val.indexOf("

",1) === -1 ) + val = val.substring( 3, val.length-4 ) ; + + return val ; +} diff --git a/vasl_templates/webapp/static/snippets.js b/vasl_templates/webapp/static/snippets.js index bafb47f..c5c8bb5 100644 --- a/vasl_templates/webapp/static/snippets.js +++ b/vasl_templates/webapp/static/snippets.js @@ -971,7 +971,7 @@ function unload_snippet_params( unpack_scenario_date, template_id ) if ( $elem.hasClass( "trumbowyg-editor" ) ) val = unloadTrumbowyg( $elem, false ) ; else if ( $elem.hasClass( "html-textbox" ) ) - val = $elem.html() ; + val = unloadHtmlTextbox( $elem ) ; else val = $elem.val() ; params[ $elem.attr("name") ] = val ; diff --git a/vasl_templates/webapp/static/vo2.js b/vasl_templates/webapp/static/vo2.js index a2d46a9..b58a216 100644 --- a/vasl_templates/webapp/static/vo2.js +++ b/vasl_templates/webapp/static/vo2.js @@ -23,8 +23,8 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) return data ; } - function get_default_capabilities( vo_entry, params, show_warnings ) { - return make_capabilities( + function get_default_capabilities( vo_entry, params, show_warnings, translate ) { + var caps = make_capabilities( false, vo_entry, vo_type, params[ "PLAYER_"+player_no ], @@ -32,9 +32,21 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) params.SCENARIO_THEATER, params.SCENARIO_YEAR, params.SCENARIO_MONTH, show_warnings ) ; + if ( translate ) { + caps.forEach( function( comment, index ) { + caps[index] = translateHTML( comment ) ; + } ) ; + } + return caps ; } - function get_default_comments( vo_entry ) { - return vo_entry.comments ? vo_entry.comments : [] ; + function get_default_comments( vo_entry, translate ) { + var comments = vo_entry.comments ? vo_entry.comments : [] ; + if ( translate ) { + comments.forEach( function( comment, index ) { + comments[index] = translateHTML( comment ) ; + } ) ; + } + return comments ; } function load_entries( $sortable, entries ) { @@ -46,9 +58,7 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) function unload_entries( $sortable ) { var entries = [] ; $sortable.find( "div.html-textbox" ).each( function() { - var val = $(this).html().trim() ; - while ( val.substr( val.length-4 ) === "
" ) - val = val.substr( 0, val.length-4 ) ; + var val = unloadHtmlTextbox( $(this) ) ; if ( val.length > 0 ) entries.push( val ) ; } ) ; @@ -70,11 +80,11 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) var vo_entry = $entry.data( "sortable2-data" ).vo_entry ; var capabilities = $entry.data( "sortable2-data" ).custom_capabilities ; if ( ! capabilities ) - capabilities = get_default_capabilities( vo_entry, params, true ).slice() ; + capabilities = get_default_capabilities( vo_entry, params, true, false ).slice() ; var elite = $entry.data( "sortable2-data" ).elite ; var comments = $entry.data( "sortable2-data" ).custom_comments ; if ( ! comments ) - comments = get_default_comments( vo_entry ) ; + comments = get_default_comments( vo_entry, false ) ; // load the dialog var vo_image_id = $entry.data( "sortable2-data" ).vo_image_id ; @@ -147,7 +157,7 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) var curr_params = $reset_capabilities.data( "params" ) ; $dlg.find( ".header .vo-name" ).html( make_vo_name( curr_vo_entry.name, false ) ) ; load_entries( $capabilities, - get_default_capabilities( curr_vo_entry, curr_params, false ) + get_default_capabilities( curr_vo_entry, curr_params, false, false ) ) ; $elite.prop( "checked", false ) ; } @@ -155,7 +165,7 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) $reset_comments.data( { vo_entry: vo_entry, params: params } ) ; function on_reset_comments() { var curr_vo_entry = $reset_capabilities.data( "vo_entry" ) ; - load_entries( $comments, get_default_comments(curr_vo_entry) ) ; + load_entries( $comments, get_default_comments( curr_vo_entry, false ) ) ; } function update_for_elite( delta ) { @@ -262,14 +272,14 @@ function _do_edit_ob_vo( $entry, player_no, vo_type ) $entry.data( "sortable2-data" ).vo_image_id = data.vo_image_id ; $entry.data( "sortable2-data" ).elite = data.elite ; // save the capabilities and comments - if ( data.capabilities.join() !== get_default_capabilities( vo_entry, params, false ).join() ) + if ( data.capabilities.join() !== get_default_capabilities( vo_entry, params, false, true ).join() ) $entry.data( "sortable2-data" ).custom_capabilities = data.capabilities ; else { // the capabilities are the same as the default - no need to retain these custom settings delete $entry.data( "sortable2-data" ).custom_capabilities ; } // save the comments - if ( data.comments.join() !== get_default_comments( vo_entry ).join() ) { + if ( data.comments.join() !== get_default_comments( vo_entry, true ).join() ) { $entry.data( "sortable2-data" ).custom_comments = data.comments ; } else { diff --git a/vasl_templates/webapp/tests/test_ob.py b/vasl_templates/webapp/tests/test_ob.py index 9ccabb9..1c0c964 100644 --- a/vasl_templates/webapp/tests/test_ob.py +++ b/vasl_templates/webapp/tests/test_ob.py @@ -16,15 +16,15 @@ from vasl_templates.webapp.tests.utils import \ def test_ob_setup( webapp, webdriver ): """Test generating OB setup snippets.""" - _do_test_ob_entries( webapp, webdriver, "ob_setups", False ) + _do_test_ob_entries( webapp, webdriver, "ob_setups" ) def test_ob_notes( webapp, webdriver ): """Test generating OB note snippets.""" - _do_test_ob_entries( webapp, webdriver, "ob_notes", True ) + _do_test_ob_entries( webapp, webdriver, "ob_notes" ) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def _do_test_ob_entries( webapp, webdriver, ob_type, has_para ): +def _do_test_ob_entries( webapp, webdriver, ob_type ): """Test generating OB setup/notes.""" # initialize @@ -73,12 +73,7 @@ def _do_test_ob_entries( webapp, webdriver, ob_type, has_para ): "[German] [updated {} #2] (col=[OBCOL:german/OBCOL-BORDER:german]) (width=[200px])".format( ob_type ) ) check_snippet( sortable1, 0, - "[German] [{}{} #1{}] (col=[OBCOL:german/OBCOL-BORDER:german]) (width=[100px])".format( - "

" if has_para else "", - ob_type, - "

" if has_para else "" - ) - ) + "[German] [{} #1] (col=[OBCOL:german/OBCOL-BORDER:german]) (width=[100px])".format( ob_type ) ) # delete an OB setup/note by dragging it into the trash assert get_sortable_entry_count( sortable1 ) == 2