var obju = require( "./object.js" ); var _newStackItem = function( t ) { var o = { "name": t, "attrs": "", "cont": "" }; o[ "fd" ] = ( x ) => o.cont += x; return o; }; module.exports = { encodeHtml: function ( str, br ) { str = ( str + "" ).replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'") ; if( br ) str = str.replace( /\n/g, "
" ); return str; } , http_str: function( str ) { if( str.match( "^https?://" ) ) { return str; } return "http://" + str; } , walk_tags: function( str, handler, _OP, _ED, _fineHandlers ) { _fineHandlers ||= {}; var l = str && str.length; var strOut = ""; var tokenStack = new (obju.LStack)(); var _fd_strOut = ( x ) => strOut += x; var _fd = _fd_strOut; var exitCurrentTag = () => { tokenStack.pop(); _fd = tokenStack.empty() ? _fd_strOut : tokenStack.curr().fd; }; var ctx = { "exitCurrentTag": exitCurrentTag , "stack": tokenStack , "fd": ( x ) => ( tokenStack.empty() ? _fd_strOut : tokenStack.curr().fd )( x ) }; for( let i = 0; i < l; i ++ ) { let c = str[i]; let t = "", _a, _n; if( c === _OP ) { let closeTag = ( str[ i + 1 ] === "/" ); if( closeTag ) { t = str[ ++i ]; } for( _a = str[ ++i ], _n = _a.charCodeAt(0); // check alpha numeric ( 65 <= _n && _n <= 90 ) || ( 97 <= _n && _n <= 122 ) || ( 48 <= _n && _n <= 57 ); i ++, _a = str[i], _n = _a.charCodeAt(0) ) t += _a; if( t === "" || t === "/" ) { // Hits "<#" where # is not a valid tag name _fd( _OP + t + _a ); continue; } if( _a === _ED ) { // Hits "" if( closeTag ) { // Hits "..." with no corresponding open tag if( tokenStack.empty() ) { if( _fineHandlers.UnmatchedCloseTag ) { _fineHandlers.UnmatchedCloseTag( ctx, t.substr( 1 ) ); } else { throw new Error( `Syntax Error: Unexpected closing ${_OP}${t}${_ED}` ); } } // Hits "..." else if( t.substr( 1 ) === tokenStack.curr().name ) { let st = tokenStack.pop(); _fd = tokenStack.empty() ? _fd_strOut : tokenStack.curr().fd; _fd( handler( st.name, st.attrs, st.cont ) ); continue; } // Hits "..." else { if( _fineHandlers.UnmatchedCloseTag ) { _fineHandlers.UnmatchedCloseTag( ctx, t.substr( 1 ) ); } else { throw new Error( `Syntax error: Unexpected closing ${_OP}${t}${_ED} after opened ${_OP}${tokenStack.curr().name}${_ED}` ); } } } // Hits "" else { tokenStack.add( _newStackItem( t ) ); _fd = tokenStack.curr().fd; _fineHandlers.TagOpen && _fineHandlers.TagOpen( ctx ); continue; } } else { // Hits "" or opening "<" tokenStack.add( _newStackItem( t ) ); t = _a; for( _a = str[ ++i ]; !( _a.startsWith( _OP ) || _a.startsWith( _ED ) ); i ++, _a = str[i] ) t += _a; // Hits "" else { // Write #... into abcd's attrs tokenStack.curr().attrs = t; _fd = tokenStack.curr().fd; _fineHandlers.TagOpen && _fineHandlers.TagOpen( ctx ); continue; } } } else { _fd( c ); } } _fineHandlers.WalkEnd && _fineHandlers.WalkEnd( ctx ); return strOut; } }