2017-05-10 09:27:13 +02:00
/ *
2020-07-19 09:04:37 +02:00
savegame - editor . js v20200719
2017-05-10 09:27:13 +02:00
A library that lets you create easily a savegame editor . Made with vanilla JS .
2020-07-19 09:04:37 +02:00
by Marc Robledo 2016 - 2020
2017-05-10 09:27:13 +02:00
http : //www.marcrobledo.com/license
* /
/* LIBRARIES */
2019-04-16 11:21:05 +02:00
/* MODDED VERSION OF MarcFile.js v20181020 - Marc Robledo 2014-2018 - http://www.marcrobledo.com/license */
function MarcFile ( a , b ) { "object" == typeof a && a . files && ( a = a . files [ 0 ] ) ; var c = ! 1 ; if ( "object" == typeof a && a . name && a . size ) { if ( "function" != typeof window . FileReader ) throw new Error ( "Incompatible Browser" ) ; c = ! 0 , this . fileName = a . name , this . fileType = a . type , this . fileSize = a . size } else if ( "number" == typeof a ) this . fileName = "file.bin" , this . fileType = "application/octet-stream" , this . fileSize = a ; else throw new Error ( "Invalid source" ) ; if ( this . littleEndian = ! 1 , c ) this . _fileReader = new FileReader , this . _fileReader . marcFile = this , this . _fileReader . addEventListener ( "load" , function ( ) { this . marcFile . _u8array = new Uint8Array ( this . result ) , this . marcFile . _dataView = new DataView ( this . result ) , b && b . call ( ) } , ! 1 ) , this . _fileReader . readAsArrayBuffer ( a ) ; else if ( 0 < a ) { var d = new ArrayBuffer ( a ) ; this . _u8array = new Uint8Array ( d ) , this . _dataView = new DataView ( d ) , b && b . call ( ) } } MarcFile . prototype . IS _MACHINE _LITTLE _ENDIAN = function ( ) { var a = new ArrayBuffer ( 2 ) ; return new DataView ( a ) . setInt16 ( 0 , 256 , ! 0 ) , 256 === new Int16Array ( a ) [ 0 ] } ( ) , MarcFile . prototype . save = function ( ) { var a ; try { a = new Blob ( [ this . _u8array ] , { type : this . fileType } ) } catch ( c ) { if ( window . BlobBuilder = window . BlobBuilder || window . WebKitBlobBuilder || window . MozBlobBuilder || window . MSBlobBuilder , "InvalidStateError" === c . name && window . BlobBuilder ) { var b = new BlobBuilder ; b . append ( this . _u8array . buffer ) , a = b . getBlob ( this . fileType ) } else { throw new Error ( "Incompatible Browser" ) } } saveAs ( a , this . fileName ) } , MarcFile . prototype . readU8 = function ( a ) { return this . _u8array [ a ] } , MarcFile . prototype . readU16 = function ( a ) { return this . littleEndian ? this . _u8array [ a ] + ( this . _u8array [ a + 1 ] << 8 ) >>> 0 : ( this . _u8array [ a ] << 8 ) + this . _u8array [ a + 1 ] >>> 0 } , MarcFile . prototype . readU24 = function ( a ) { return this . littleEndian ? this . _u8array [ a ] + ( this . _u8array [ a + 1 ] << 8 ) + ( this . _u8array [ a + 2 ] << 16 ) >>> 0 : ( this . _u8array [ a ] << 16 ) + ( this . _u8array [ a + 1 ] << 8 ) + this . _u8array [ a + 2 ] >>> 0 } , MarcFile . prototype . readU32 = function ( a ) { return this . littleEndian ? this . _u8array [ a ] + ( this . _u8array [ a + 1 ] << 8 ) + ( this . _u8array [ a + 2 ] << 16 ) + ( this . _u8array [ a + 3 ] << 24 ) >>> 0 : ( this . _u8array [ a ] << 24 ) + ( this . _u8array [ a + 1 ] << 16 ) + ( this . _u8array [ a + 2 ] << 8 ) + this . _u8array [ a + 3 ] >>> 0 } , MarcFile . prototype . readS8 = function ( a ) { return this . _dataView . getInt8 ( a , this . littleEndian ) } , MarcFile . prototype . readS16 = function ( a ) { return this . _dataView . getInt16 ( a , this . littleEndian ) } , MarcFile . prototype . readS32 = function ( a ) { return this . _dataView . getInt32 ( a , this . littleEndian ) } , MarcFile . prototype . readF32 = function ( a ) { return this . _dataView . getFloat32 ( a , this . littleEndian ) } , MarcFile . prototype . readF64 = function ( a ) { return this . _dataView . getFloat64 ( a , this . littleEndian ) } , MarcFile . prototype . readBytes = function ( a , b ) { for ( var c = Array ( b ) , d = 0 ; d < b ; d ++ ) c [ d ] = this . _u8array [ a + d ] ; return c } , MarcFile . prototype . readString = function ( a , b ) { for ( var c = "" , d = 0 ; d < b && a + d < this . fileSize && 0 < this . _u8array [ a + d ] ; d ++ ) c += String . fromCharCode ( this . _u8array [ a + d ] ) ; return c } , MarcFile . prototype . writeU8 = function ( a , b ) { this . _u8array [ a ] = b } , MarcFile . prototype . writeU16 = function ( a , b ) { this . littleEndian ? ( this . _u8array [ a ] = 255 & b , this . _u8array [ a + 1 ] = b >> 8 ) : ( this . _u8array [ a ] = b >> 8 , this . _u8array [ a + 1 ] = 255 & b ) } , MarcFile . prototype . writeU24 = function ( a , b ) { this . littleEndian ? ( this . _u8array [ a ] = 255 & b , this . _u8array [ a + 1 ] = ( 65280 & b ) >> 8 , this . _u8array [ a + 2 ] = ( 16711680 & b ) >> 16 ) : ( this . _u8array [ a ] = ( 16711680 & b ) >> 16 , this . _u8array [ a + 1 ] = ( 65280 & b ) >> 8 , this . _u8array [ a + 2 ] = 255 & b ) } , MarcFile . prototype . writeU32 = function ( a , b ) { this . littleEndian ? ( this . _u8array [ a ] = 255 & b , this . _u8array [ a + 1 ] = ( 65280 & b ) >> 8 , this . _u8array [ a + 2 ] = ( 16711680 & b ) >> 16 , this . _u8array [ a + 3 ] = ( 4278190080 & b ) >> 24 ) : ( this . _u8array [ a ] = ( 4278190080 & b ) >> 24 , this . _u8array [ a + 1 ] = ( 16711680 & b ) >> 16 , this . _u8array [ a + 2 ] = ( 65280 & b ) >> 8 , this . _u8array [ a + 3 ] = 255 & b ) } , MarcFile . prototype . writeS8 = function ( a , b ) { this . _dataView . setInt8 ( a , b , this . littleEndian ) } , MarcFile . prototype . writeS16 = function ( a , b ) { this . _dataView . setInt16 ( a , b , this . littleEndian ) } , MarcFile . prototype . writeS32 = function ( a , b ) { this . _dataView . setInt32 ( a , b , this . littleEndian ) } , MarcFile . prototype . writeF32 = function ( a , b ) { this . _dataView . setFloat32 ( a , b , this . littleEndian ) } , MarcFile . prototype . writeF64 = function ( a , b ) { this . _dataView . setFloat64 ( a , b , this . littleEndian ) } , MarcFile . prototype . writeBytes = function ( b , c ) { for ( var
/* implement U16 string in MarcFile (PROVISIONAL!) */
MarcFile . prototype . readU16String = function ( pos , maxLength ) {
var cs = new Array ( maxLength ) ;
var str = '' ;
for ( var i = 0 ; i < maxLength && this . readU16 ( pos + i * 2 ) != 0 ; i ++ )
str += String . fromCharCode ( this . readU16 ( pos + i * 2 ) ) ;
//cs[i]=this.readU16(pos+i*2);
return str
}
MarcFile . prototype . writeU16String = function ( pos , maxLength , str ) {
for ( var i = 0 ; i < str . length && i < maxLength - 1 ; i ++ )
this . writeU16 ( pos + i * 2 , str . charCodeAt ( i ) ) ;
for ( ; i < maxLength ; i ++ )
this . writeU16 ( pos + i * 2 , 0 )
}
2017-05-10 09:27:13 +02:00
/* FileSaver.js by eligrey - https://github.com/eligrey/FileSaver.js */
2019-04-16 11:21:05 +02:00
var saveAs = saveAs || function ( c ) { "use strict" ; if ( ! ( void 0 === c || "undefined" != typeof navigator && /MSIE [1-9]\./ . test ( navigator . userAgent ) ) ) { var t = c . document , f = function ( ) { return c . URL || c . webkitURL || c } , s = t . createElementNS ( "http://www.w3.org/1999/xhtml" , "a" ) , d = "download" in s , u = /constructor/i . test ( c . HTMLElement ) || c . safari , l = /CriOS\/[\d]+/ . test ( navigator . userAgent ) , p = c . setImmediate || c . setTimeout , v = function ( t ) { p ( function ( ) { throw t } , 0 ) } , w = function ( t ) { setTimeout ( function ( ) { "string" == typeof t ? f ( ) . revokeObjectURL ( t ) : t . remove ( ) } , 4e4 ) } , m = function ( t ) { return /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i . test ( t . type ) ? new Blob ( [ String . fromCharCode ( 65279 ) , t ] , { type : t . type } ) : t } , r = function ( t , n , e ) { e || ( t = m ( t ) ) ; var r , o = this , a = "application/octet-stream" === t . type , i = function ( ) { ! function ( t , e , n ) { for ( var r = ( e = [ ] . concat ( e ) ) . length ; r -- ; ) { var o = t [ "on" + e [ r ] ] ; if ( "function" == typeof o ) try { o . call ( t , n || t ) } catch ( t ) { v ( t ) } } } ( o , "writestart progress write writeend" . split ( " " ) ) } ; if ( o . readyState = o . INIT , d ) return r = f ( ) . createObjectURL ( t ) , void p ( function ( ) { var t , e ; s . href = r , s . download = n , t = s , e = new MouseEvent ( "click" ) , t . dispatchEvent ( e ) , i ( ) , w ( r ) , o . readyState = o . DONE } , 0 ) ; ! function ( ) { if ( ( l || a && u ) && c . FileReader ) { var e = new FileReader ; return e . onloadend = function ( ) { var t = l ? e . result : e . result . replace ( /^data:[^;]*;/ , "data:attachment/file;" ) ; c . open ( t , "_blank" ) || ( c . location . href = t ) , t = void 0 , o . readyState = o . DONE , i ( ) } , e . readAsDataURL ( t ) , o . readyState = o . INIT } r || ( r = f ( ) . createObjectURL ( t ) ) , a ? c . location . href = r : c . open ( r , "_blank" ) || ( c . location . href = r ) ; o . readyState = o . DONE , i ( ) , w ( r ) } ( ) } , e = r . prototype ; return "undefined" != typeof navigator && navigator . msSaveOrOpenBlob ? function ( t , e , n ) { return e = e || t . name || "download" , n || ( t = m ( t ) ) , navigator . msSaveOrOpenBlob ( t , e ) } : ( e . abort = function ( ) { } , e . readyState = e . INIT = 0 , e . WRITING = 1 , e . DONE = 2 , e . error = e . onwritestart = e . onprogress = e . onwrite = e . onabort = e . onerror = e . onwriteend = null , function ( t , e , n ) { return new r ( t , e || t . name || "download" , n ) } ) } } ( "undefined" != typeof self && self || "undefined" != typeof window && window || this ) ;
2017-05-10 09:27:13 +02:00
/* MarcDialogs.js v2016 */
MarcDialogs = function ( ) { function e ( e , t , n ) { a ? e . attachEvent ( "on" + t , n ) : e . addEventListener ( t , n , ! 1 ) } function t ( ) { s && ( o ? history . go ( - 1 ) : ( c . className = "dialog-overlay" , s . className = s . className . replace ( / active/g , "" ) , s = null ) ) } function n ( e ) { for ( var t = 0 ; t < s . dialogElements . length ; t ++ ) { var n = s . dialogElements [ t ] ; if ( "INPUT" === n . nodeName && "hidden" !== n . type || "INPUT" !== n . nodeName ) return n . focus ( ) , ! 0 } return ! 1 } function l ( ) { s && ( s . style . marginLeft = "-" + s . offsetWidth / 2 + "px" , s . style . marginTop = "-" + s . offsetHeight / 2 - 30 + "px" ) } var a = /MSIE 8/ . test ( navigator . userAgent ) , o = navigator . userAgent . match ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i ) && "function" == typeof history . pushState , i = [ "Cancel" , "Accept" ] , s = null , c = document . createElement ( "div" ) ; c . className = "dialog-overlay" , c . style . position = "fixed" , c . style . top = "0" , c . style . left = "0" , c . style . width = "100%" , c . style . height = "100%" , c . style . zIndex = 8e3 , e ( c , "click" , t ) , e ( window , "load" , function ( ) { document . body . appendChild ( c ) , o && history . replaceState ( { myDialog : ! 1 } , null , null ) } ) , e ( window , "resize" , l ) , o && e ( window , "popstate" , function ( e ) { e . state . myDialog ? ( s = e . state . myDialog , MarcDialogs . open ( e . state . myDialog ) ) : e . state . myDialog === ! 1 && s && ( c . className = "dialog-overlay" , s . className = s . className . replace ( / active/g , "" ) , s = null ) } ) , e ( document , "keydown" , function ( e ) { s && ( 27 == e . keyCode ? ( e . preventDefault ? e . preventDefault ( ) : e . returnValue = ! 1 , t ( ) ) : 9 == e . keyCode && s . dialogElements [ s . dialogElements . length - 1 ] == document . activeElement && ( e . preventDefault ? e . preventDefault ( ) : e . returnValue = ! 1 , n ( ) ) ) } ) ; var d = null , u = null , m = null ; return { open : function ( e ) { s && ( s . className = s . className . replace ( / active/g , "" ) ) , o && ( s ? history . replaceState ( { myDialog : e } , null , null ) : ( console . log ( "a" ) , history . pushState ( { myDialog : e } , null , null ) ) ) , c . className = "dialog-overlay active" , s = "string" == typeof e ? document . getElementById ( "dialog-" + e ) : e , s . className += " active" , s . style . position = "fixed" , s . style . top = "50%" , s . style . left = "50%" , s . style . zIndex = 8001 , s . dialogElements || ( s . dialogElements = s . querySelectorAll ( "input,textarea,select" ) ) , n ( ) , l ( s ) , l ( s ) } , close : t , alert : function ( t ) { if ( ! d ) { d = document . createElement ( "div" ) , d . id = "dialog-quick-alert" , d . className = "dialog" , d . msg = document . createElement ( "div" ) , d . msg . style . textAlign = "center" , d . appendChild ( d . msg ) , d . buttons = document . createElement ( "div" ) , d . buttons . className = "buttons" ; var n = document . createElement ( "button" ) ; n . innerHTML = i [ 1 ] , e ( n , "click" , this . close ) , d . buttons . appendChild ( n ) , d . appendChild ( d . buttons ) , document . body . appendChild ( d ) } d . msg . innerHTML = t , MarcDialogs . open ( "quick-alert" ) } , confirm : function ( t , n ) { if ( ! u ) { u = document . createElement ( "div" ) , u . id = "dialog-quick-confirm" , u . className = "dialog" , u . msg = document . createElement ( "div" ) , u . msg . style . textAlign = "center" , u . appendChild ( u . msg ) , u . buttons = document . createElement ( "div" ) , u . buttons . className = "buttons" ; var l = document . createElement ( "button" ) ; l . className = "button colored blue with-icon icon9" , l . innerHTML = i [ 1 ] , e ( l , "click" , function ( ) { m ( ) } ) , u . buttons . appendChild ( l ) ; var a = document . createElement ( "button" ) ; a . className = "button with-icon icon3" , a . innerHTML = i [ 0 ] , e ( a , "click" , this . close ) , u . buttons . appendChild ( a ) , u . appendChild ( u . buttons ) , document . body . appendChild ( u ) } m = n , u . msg . innerHTML = t , MarcDialogs . open ( "quick-confirm" ) } } } ( ) ;
/* MarcDragAndDrop.js v20170421 - Marc Robledo 2014-2017 - http://www.marcrobledo.com/license */
MarcDragAndDrop = ( function ( ) {
function addEvent ( e , t , f ) { if ( /MSIE 8/ . test ( navigator . userAgent ) ) e . attachEvent ( 'on' + t , f ) ; else e . addEventListener ( t , f , false ) }
var no = function ( e ) { if ( typeof e . stopPropagation !== 'undefined' ) e . stopPropagation ( ) ; else e . cancelBubble = true ; if ( e . preventDefault ) e . preventDefault ( ) ; else e . returnValue = false }
function checkIfHasFiles ( e ) {
if ( e . dataTransfer . types )
for ( var i = 0 ; i < e . dataTransfer . types . length ; i ++ )
if ( e . dataTransfer . types [ i ] === 'Files' )
return true ;
return false
}
function removeClass ( ) { document . body . className = document . body . className . replace ( ' dragging-files' , '' ) }
addEvent ( document , 'dragenter' , function ( e ) {
if ( checkIfHasFiles ( e ) ) {
no ( e ) ;
document . body . className += ' dragging-files'
}
} ) ;
addEvent ( document , 'dragexit' , function ( e ) {
//alert('exit');
no ( e ) ;
removeClass ( ) ; /* why!? */
removeClass ( ) ;
removeClass ( ) ;
removeClass ( ) ;
} ) ;
addEvent ( document , 'dragover' , function ( e ) {
if ( checkIfHasFiles ( e ) )
no ( e )
} ) ;
var dropOutside = false ;
function enableDropOutside ( ) {
addEvent ( document , 'drop' , function ( e ) {
removeClass ( ) ;
no ( e ) ;
} ) ;
}
return {
add : function ( z , f ) {
if ( ! dropOutside ) {
enableDropOutside ( ) ;
}
addEvent ( document . getElementById ( z ) , 'drop' , function ( e ) {
if ( ! checkIfHasFiles ( e ) )
return false ;
no ( e ) ;
removeClass ( ) ;
f ( e . dataTransfer . files )
} ) ;
} ,
addGlobalZone : function ( f , t ) {
if ( ! dropOutside ) {
enableDropOutside ( ) ;
}
var div = document . createElement ( 'div' ) ;
div . id = 'drop-overlay' ;
div . className = 'marc-drop-files' ;
var span = document . createElement ( 'span' ) ;
if ( t )
span . innerHTML = t ;
else
span . innerHTML = 'Drop files here' ;
div . appendChild ( span ) ;
document . body . appendChild ( div ) ;
this . add ( '#drop-overlay' , f ) ;
}
}
} ( ) ) ;
/* savegame load/save */
var tempFile , hasBeenLoaded = false ;
function _tempFileLoadFunction ( ) {
if ( SavegameEditor . checkValidSavegame ( ) ) {
hide ( 'dragzone' ) ;
if ( SavegameEditor . preload && ! hasBeenLoaded ) {
SavegameEditor . preload ( ) ;
hasBeenLoaded = true ;
}
SavegameEditor . load ( ) ;
show ( 'the-editor' ) ;
show ( 'toolbar' ) ;
} else {
MarcDialogs . alert ( 'Invalid savegame file' ) ;
}
}
function loadSavegameFromInput ( input ) {
2019-04-16 11:21:05 +02:00
tempFile = new MarcFile ( input . files [ 0 ] , _tempFileLoadFunction ) ;
2017-05-10 09:27:13 +02:00
}
2017-07-07 00:03:24 +02:00
2017-05-10 09:27:13 +02:00
function saveChanges ( ) {
2020-07-19 09:04:37 +02:00
if ( decodeURIComponent ( document . cookie ) . indexOf ( 'hideWarningMessage=1' ) >= 0 || location . protocol === 'file:' ) { /* chrome does not write cookies in local, so skip warning message in that case */
2017-07-07 00:03:24 +02:00
SavegameEditor . save ( ) ;
tempFile . save ( ) ;
} else {
MarcDialogs . open ( 'warning' ) ;
}
2017-05-10 09:27:13 +02:00
}
function closeFileConfirm ( ) {
MarcDialogs . confirm ( 'All changes will be lost.' , function ( ) {
closeFile ( ) ;
MarcDialogs . close ( )
} ) ;
}
function closeFile ( ) {
show ( 'dragzone' ) ;
hide ( 'the-editor' ) ;
hide ( 'toolbar' ) ;
}
function getSavegameDefaultName ( ) {
if ( typeof SavegameEditor . Filename === 'string' )
return SavegameEditor . Filename ;
return SavegameEditor . Filename [ 0 ]
}
function getSavegameAllNames ( ) {
if ( typeof SavegameEditor . Filename === 'string' )
return SavegameEditor . Filename ;
else {
var s = '' ;
for ( var i = 0 ; i < SavegameEditor . Filename . length ; i ++ )
s += SavegameEditor . Filename [ i ] + ', ' ;
return s
}
}
window . addEventListener ( 'load' , function ( ) {
var dragZone = document . createElement ( 'div' ) ;
dragZone . id = 'dragzone' ;
dragZone . className = 'wrapper' ;
var dragMessage = document . createElement ( 'div' ) ;
dragMessage . id = 'dragzone-message' ;
2017-07-07 00:03:24 +02:00
dragMessage . innerHTML = '<button class="close" onclick="document.getElementById(\'file-load\').click()"><i class=\"icon disk\"></i> Browse ' + getSavegameAllNames ( ) + '</button> or drop it here' ;
2017-05-10 09:27:13 +02:00
var inputFile = document . createElement ( 'input' ) ;
inputFile . type = 'file' ;
inputFile . className = 'hidden' ;
inputFile . id = 'file-load' ;
inputFile . addEventListener ( 'change' , function ( ) {
loadSavegameFromInput ( this ) ;
} , false ) ;
2019-04-16 11:21:05 +02:00
var demoMessage = document . createElement ( 'button' ) ;
2017-05-10 09:27:13 +02:00
demoMessage . id = 'demo' ;
2019-04-16 11:21:05 +02:00
demoMessage . innerHTML = 'Do you want to try it out? <u>Try an example savegame</u>' ;
demoMessage . addEventListener ( 'click' , function ( ) {
if ( typeof window . fetch === 'function' ) {
fetch ( SavegameEditor . Filename )
. then ( res => res . arrayBuffer ( ) ) // Gets the response and returns it as a blob
. then ( ab => {
tempFile = new MarcFile ( ab . byteLength ) ;
tempFile . fileName = SavegameEditor . Filename ;
tempFile . _u8array = new Uint8Array ( ab ) ;
tempFile . _dataView = new DataView ( ab ) ;
_tempFileLoadFunction ( ) ;
} )
. catch ( function ( ) {
alert ( 'Unexpected error: can\'t download example savegame' ) ;
} ) ;
} else {
var oReq = new XMLHttpRequest ( ) ;
oReq . open ( 'GET' , SavegameEditor . Filename , true ) ;
oReq . responseType = 'arraybuffer' ;
oReq . onload = function ( oEvent ) {
if ( this . status === 200 ) {
var ab = oReq . response ; //Note: not oReq.responseText
tempFile = new MarcFile ( ab . byteLength ) ;
tempFile . fileName = SavegameEditor . Filename ;
tempFile . _u8array = new Uint8Array ( ab ) ;
tempFile . _dataView = new DataView ( ab ) ;
_tempFileLoadFunction ( ) ;
} else {
alert ( 'Unexpected error: can\'t download example savegame' ) ;
}
} ;
oReq . onerror = function ( oEvent ) {
alert ( 'Unexpected error: can\'t download example savegame' ) ;
} ;
oReq . send ( null ) ;
}
} , false ) ;
2017-05-10 09:27:13 +02:00
dragZone . appendChild ( dragMessage ) ;
dragZone . appendChild ( inputFile ) ;
dragZone . appendChild ( demoMessage ) ;
document . body . appendChild ( dragZone ) ;
MarcDragAndDrop . add ( 'dragzone' , function ( droppedFiles ) {
2019-04-16 11:21:05 +02:00
tempFile = new MarcFile ( droppedFiles [ 0 ] , _tempFileLoadFunction ) ;
2017-05-10 09:27:13 +02:00
} ) ;
2017-07-07 00:03:24 +02:00
var warningDialog = document . createElement ( 'div' ) ;
warningDialog . className = 'dialog' ;
warningDialog . id = 'dialog-warning' ;
warningDialog . innerHTML = 'Use this tool at your own risk. By using it, you are responsible of any data lost.' ;
var divButtons = document . createElement ( 'div' ) ;
divButtons . className = 'buttons' ;
var understandButton = document . createElement ( 'button' ) ;
understandButton . innerHTML = 'I understand' ;
understandButton . addEventListener ( 'click' , function ( ) {
var EXPIRE _DAYS = 3 ;
var d = new Date ( ) ;
d . setTime ( d . getTime ( ) + ( EXPIRE _DAYS * 24 * 60 * 60 * 1000 ) ) ;
document . cookie = "hideWarningMessage=1;expires=" + d . toUTCString ( ) ; //+";path=./";
MarcDialogs . close ( ) ;
saveChanges ( ) ;
} , false ) ;
divButtons . appendChild ( understandButton ) ;
warningDialog . appendChild ( divButtons ) ;
document . body . appendChild ( warningDialog ) ;
} , false ) ;
2017-05-10 09:27:13 +02:00
/* binary and other helpers */
function compareBytes ( offset , a2 ) {
var a1 = tempFile . readBytes ( offset , a2 . length ) ;
for ( var i = 0 ; i < a1 . length ; i ++ )
if ( a1 [ i ] != a2 [ i ] )
return false ;
return true
}
function intToHex ( i ) { var s = i . toString ( 16 ) ; while ( s . length % 2 != 0 ) s = '0' + s ; return '0x' + s }
function genRange ( min , max ) { var a = [ ] ; for ( var i = min ; i <= max ; i ++ ) a . push ( i ) ; return a }
/* DOM manipulation */
function show ( e , p ) { document . getElementById ( e ) . style . display = p || 'block' }
function hide ( e ) { document . getElementById ( e ) . style . display = 'none' }
2017-05-11 09:42:43 +02:00
function empty ( e ) { var el = document . getElementById ( e ) ; while ( el . firstChild ) el . removeChild ( el . firstChild ) }
2017-05-10 09:27:13 +02:00
function row ( sizes ) {
var r = document . createElement ( 'div' ) ;
r . className = 'row' ;
for ( var i = 0 ; i < sizes . length ; i ++ )
r . appendChild ( col ( sizes [ i ] , arguments [ i + 1 ] ) ) ;
return r
}
function col ( size , inner ) {
var c = document . createElement ( 'div' ) ;
c . className = 'columns c' + size ;
c . appendChild ( inner ) ;
return c
}
function fixNumericFieldValue ( field ) {
var val = field . value . replace ( /[^0-9\-\.]/g , '' ) ;
if ( /^float-/ . test ( field . id ) ) {
val = parseFloat ( val ) ;
} else {
val = parseInt ( val ) ;
}
if ( isNaN ( val ) || val < field . minValue ) {
2019-04-16 11:21:05 +02:00
val = field . minValue ;
2017-05-10 09:27:13 +02:00
} else if ( val > field . maxValue ) {
val = field . maxValue ;
}
field . value = val ;
}
function fixNumericFieldValueFromEvent ( ) { fixNumericFieldValue ( this ) }
function inputNumber ( id , min , max , def ) {
var input = document . createElement ( 'input' ) ;
input . id = 'number-' + id ;
input . className = 'full-width text-right' ;
input . type = 'text' ; /* type='number' validation breaks getting input value when it's not valid */
input . minValue = min ;
input . maxValue = max ;
input . value = def ;
input . addEventListener ( 'change' , fixNumericFieldValueFromEvent , false ) ;
return input ;
}
function inputFloat ( id , min , max , def ) {
var input = document . createElement ( 'input' ) ;
input . id = 'float-' + id ;
input . className = 'full-width text-right' ;
input . type = 'text' ;
input . minValue = min ;
input . maxValue = max ;
input . value = def ;
input . addEventListener ( 'change' , fixNumericFieldValueFromEvent , false ) ;
return input
}
function input ( id , def ) {
var input = document . createElement ( 'input' ) ;
input . id = 'input-' + id ;
input . className = 'full-width' ;
input . type = 'text' ;
input . value = def ;
return input
}
function checkbox ( id , val ) {
var input = document . createElement ( 'input' ) ;
input . id = 'checkbox-' + id ;
input . type = 'checkbox' ;
if ( val )
input . value = val ;
return input
}
function select ( id , options , func ) {
var select ;
if ( document . getElementById ( 'select-' + id ) ) {
select = document . getElementById ( 'select-' + id ) ;
} else {
select = document . createElement ( 'select' ) ;
select . id = 'select-' + id ;
select . className = 'full-width' ;
}
if ( options ) {
for ( var i = 0 ; i < options . length ; i ++ ) {
if ( typeof options [ i ] === 'number' ) {
var option = document . createElement ( 'option' ) ;
option . value = options [ i ] ;
option . innerHTML = options [ i ] ;
select . appendChild ( option ) ;
} else if ( typeof options [ i ] === 'string' ) {
var option = document . createElement ( 'option' ) ;
option . value = i ;
option . innerHTML = options [ i ] ;
select . appendChild ( option ) ;
} else if ( typeof options [ i ] === 'object' && typeof options [ i ] . value !== 'undefined' && typeof options [ i ] . name !== 'undefined' ) {
var option = document . createElement ( 'option' ) ;
option . value = options [ i ] . value ;
option . innerHTML = options [ i ] . name ;
select . appendChild ( option ) ;
} else if ( typeof options [ i ] === 'object' ) {
select . appendChild ( options [ i ] ) ;
}
}
}
if ( func )
select . addEventListener ( 'change' , func , false ) ;
return select
}
function dialog ( id ) {
var dialog = document . createElement ( 'div' ) ;
dialog . className = 'dialog' ;
dialog . id = 'dialog-' + id ;
for ( var i = 1 ; i < arguments . length ; i ++ )
dialog . appendChild ( arguments [ i ] ) ;
document . getElementById ( 'the-editor' ) . appendChild ( dialog ) ;
return dialog
}
function div ( className ) {
var div = document . createElement ( 'div' ) ;
var elementsStart = 0 ;
if ( typeof arguments [ 0 ] === 'string' ) {
div . className = arguments [ 0 ] ;
elementsStart ++ ;
}
for ( var i = elementsStart ; i < arguments . length ; i ++ )
div . appendChild ( arguments [ i ] ) ;
return div
}
function button ( text , className , func ) {
var button = document . createElement ( 'button' ) ;
button . innerHTML = text ;
if ( typeof className === 'string' )
button . className = className ;
button . addEventListener ( 'click' , func , false ) ;
return button
}
function label ( forId , text ) {
var label = document . createElement ( 'label' ) ;
label . htmlFor = forId ;
label . innerHTML = text ;
return label
}
function span ( text ) {
var span = document . createElement ( 'span' ) ;
span . innerHTML = text ;
return span
}
function hr ( ) { return document . createElement ( 'hr' ) }
function getValue ( f ) {
var field = getField ( f ) ;
if ( /^number-/ . test ( field . id ) ) {
fixNumericFieldValue ( field ) ;
return parseInt ( field . value ) ;
} else if ( /^float-/ . test ( field . id ) ) {
fixNumericFieldValue ( field ) ;
return parseFloat ( field . value ) ;
} else if ( /^input-/ . test ( field . id ) || /^select-/ . test ( field . id ) ) {
return field . value
} else if ( /^span-/ . test ( field . id ) ) {
return field . innerHTML
}
}
function get ( e ) { return document . getElementById ( e ) }
function getField ( field ) {
return document . getElementById ( 'input-' + field ) || document . getElementById ( 'number-' + field ) || document . getElementById ( 'float-' + field ) || document . getElementById ( 'checkbox-' + field ) || document . getElementById ( 'select-' + field ) || document . getElementById ( 'span-' + field ) || document . getElementById ( field )
}
function setValue ( f , val ) {
var field = getField ( f ) ;
if ( /^span-/ . test ( field . id ) ) {
field . innerHTML = val ;
} else {
field . value = val ;
}
}
function setNumericRange ( f , min , max ) {
var field = getField ( f ) ;
field . className += ' text-right' ;
field . minValue = min ;
field . maxValue = max ;
field . addEventListener ( 'change' , fixNumericFieldValueFromEvent , false ) ;
fixNumericFieldValue ( field ) ;
}