{"id":166,"date":"2019-06-10T12:34:04","date_gmt":"2019-06-10T11:34:04","guid":{"rendered":"https:\/\/blog.inplico.uk\/?p=166"},"modified":"2019-06-10T18:38:43","modified_gmt":"2019-06-10T17:38:43","slug":"javascript-in-c","status":"publish","type":"post","link":"https:\/\/blog.inplico.uk\/?p=166","title":{"rendered":"Javascript in c++"},"content":{"rendered":"<p>The problem that I had with laying down javascript functions in c++ was very similar in nature to the problem one of html; i.e. having escape characters all over the place or producing virtually unreadable code.\u00a0 Thankfully the problem was much easier to solve with a class of less than 100 lines of code; And while it is fairly dumb, it will suffice for what I need to do with it.<\/p>\n<pre class=\"lang:c++ decode:true  \">#include \"jsfunction.h\"\r\n#include \"ic_core.h\"\r\n\r\nusing std::string;\r\n\r\njsfunction::jsfunction(string fcnDeclaration)\r\n    :\r\n      m_fcnDeclaration(fcnDeclaration) {\r\n}\r\n\r\nvoid jsfunction::add_line(std::string lineString) { m_fcnLines.push_back(lineString);}\r\nvoid jsfunction::add_line_break() { m_fcnLines.push_back(\"\");}\r\n\r\n\r\nstring jsfunction::js_function(int indent, bool appendNewLine) {\r\n\r\n    string jFcn(\"\\n\");\r\n\r\n    int tabstops = 0;\r\n    if(indent)\r\n        jFcn.append(indent, '\\t');\r\n\r\n    jFcn.append(\"function \" + m_fcnDeclaration + \" {\\n\\n\");\r\n\r\n    for(string &amp;it : m_fcnLines) {\r\n\r\n        it = cleanstring(it);\r\n\r\n        \/\/SORT OUT INDENTATION\r\n        if((it.back() == '}') &amp;&amp; (it.front() != '{')) --tabstops;\r\n\r\n        if(indent) {\r\n            jFcn.append(indent + tabstops +1, '\\t');\r\n            jFcn.append(it + \"\\n\");\r\n        }\r\n        else {\r\n            jFcn.append(\"\\t\" +it + \"\\n\");\r\n        }\r\n\r\n        if(it.back() == '{') ++tabstops;\r\n    }\r\n\r\n\r\n    jFcn.append(\"\\n\");\r\n\r\n    if(indent)\r\n        jFcn.append(indent, '\\t');\r\n\r\n    jFcn.append(\"}\");\r\n\r\n    if(appendNewLine)\r\n        jFcn.append(\"\\n\\n\");\r\n\r\n    return(jFcn);\r\n}\r\n\r\n\r\n<\/pre>\n<p>This is quite literally it, and to use it you simply create an instance with a javascript function name, add lines with the <strong>add_line()<\/strong> method and add line brakes using the <strong>add_line_break()<\/strong> method.\u00a0 When you are done you call <strong>js_function()<\/strong> with the desired number of indents and you have a string that you can put in a node of your formatted <strong>html_tree<\/strong>.<\/p>\n<p>The add_line() method adds each line literally, this class purely handles the formatting so<\/p>\n<pre class=\"lang:c++ decode:true\">jsfunction nav(\"nav(name, value, url)\");\r\n        nav.add_line(\"var form = document.createElement(\\\"form\\\");\");\r\n        nav.add_line(\"form.setAttribute(\\\"method\\\", \\\"post\\\");\");\r\n        nav.add_line(\"form.setAttribute(\\\"action\\\", url);\");\r\n        nav.add_line_break();\r\n        nav.add_line(\"var jobId = document.createElement(\\\"input\\\");\");\r\n        nav.add_line_break();\r\n        nav.add_line(\"jobId.setAttribute(\\\"type\\\", \\\"hidden\\\");\");\r\n        nav.add_line(\"jobId.setAttribute(\\\"name\\\", name);\");\r\n        nav.add_line(\"jobId.setAttribute(\\\"value\\\", value);\");\r\n        nav.add_line_break();\r\n        nav.add_line(\"form.appendChild(jobId);\");\r\n        nav.add_line(\"document.body.appendChild(form);\");\r\n        nav.add_line(\"form.submit();\");\r\n\r\nnav.jsfunction();<\/pre>\n<p>will create a function that will look like:<\/p>\n<pre class=\"lang:c++ decode:true\">function nav(name, value, url) {\r\n    var form = document.createElement(\"form\");\r\n    form.setAttribute(\"method\", \"post\");\r\n    form.setAttribute(\"action\", url);\r\n\t\t\t\t\r\n    var jobId = document.createElement(\"input\");\r\n\t\t\t\t\r\n    jobId.setAttribute(\"type\", \"hidden\");\r\n    jobId.setAttribute(\"name\", name);\r\n    jobId.setAttribute(\"value\", value);\r\n\t\t\t\t\r\n    form.appendChild(jobId);\r\n    document.body.appendChild(form);\r\n    form.submit();\r\n\r\n}<\/pre>\n<p>The class can easily handle more complex function with brackets &#8220;{&#8221; and &#8220;}&#8221; and will indent your code in a reasonable manner. without the need for spacing.<\/p>\n<pre class=\"lang:c++ decode:true \">jsfunction cbState(\"resolved_state()\");\r\ncbState.add_line(\"var resolved = \\\"\"+ std::to_string(faults::PENDING) + \"\\\";\");\r\ncbState.add_line(\"if(document.getElementById(\\\"faultstat\\\").checked) {\");\r\ncbState.add_line(\"resolved = \\\"\" + std::to_string(faults::RESOLVED_EXT) + \"\\\";\");\r\ncbState.add_line(\"}\");\r\ncbState.add_line_break();\r\ncbState.add_line(\"return(resolved);\");<\/pre>\n<p>will produce<\/p>\n<pre class=\"lang:c++ decode:true \">function resolved_state() {\r\n    var resolved = \"pending\";\r\n    if(document.getElementById(\\\"faultstat\\\").checked) {\r\n        resolved = resolved;\r\n    }\r\n    return(resolved);\r\n}<\/pre>\n<p>It is not idea, but then again, I don&#8217;t suppose writing javascript functions in c++ could ever be ideal and it is a little better than the alternatives of raw strings containing c++ variables, or strings littered with escape characters.<\/p>\n<p>&nbsp;<\/p>\n<p>Event Listeners:<\/p>\n<p>This is a function that was thrown together that has not been exhaustively tested.\u00a0 it is not part of the jsfunction class although it does rely on it.\u00a0 jsevent takes a number of arguments in order to create an event listener.<\/p>\n<pre class=\"lang:c++ decode:true\">    string jsevent::jsevent(\r\n            std::string element,\r\n            std::string event,\r\n            jsfunction &amp;function,\r\n            bool useCapture,\r\n            unsigned indent\r\n        ) {\r\n    string strEvent(element + \".addEventListener(\\n\");\r\n\r\n    strEvent.append(indent + 1, '\\t');\r\n    strEvent.append(\"'\" + event + \"',\\n\");\r\n    strEvent.append(function.js_function(indent +1, false) + \",\\n\");\r\n    strEvent.append(indent + 1, '\\t');\r\n    strEvent.append(useCapture ? \"true\\n\" : \"false\\n\");\r\n    strEvent.append(indent, '\\t');\r\n    strEvent.append(\");\\n\\n\");\r\n\r\n    return(strEvent);\r\n\r\n}<\/pre>\n<p>In order to create an event, first you need to create the event function using the jsfunction class eg.<\/p>\n<pre class=\"lang:c++ decode:true\">    jsfunction e(\"(event)\");\r\n    e.add_line(\"if (event.target.id.toLowerCase() !== 'faulttext') {\");\r\n    e.add_line(\"return;\");\r\n    e.add_line(\"}\");\r\n    e.add_line(\"autoExpand(event.target);\");<\/pre>\n<p>Then all you need to do is call jsevent in order to grab the event string<\/p>\n<pre class=\"lang:c++ decode:true\">    string onInput = jsevent::jsevent(\r\n                \"document\",\r\n                \"input\",\r\n                e,\r\n                false,\r\n                2\r\n                );<\/pre>\n<p>Will create an event listener like<\/p>\n<pre class=\"lang:js decode:true \">document.addEventListener(\r\n    'input',\r\n    function (event) {\r\n        if (event.target.id.toLowerCase() !== 'faulttext') {\r\n            return;\r\n        }\r\n        autoExpand(event.target);\r\n    },\r\n    false\r\n);<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The problem that I had with laying down javascript functions in c++ was very similar in nature to the problem one of html; i.e. having escape characters all over the place or producing virtually unreadable code.\u00a0 Thankfully the problem was much easier to solve with a class of less than 100 lines of code; And [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-166","post","type-post","status-publish","format-standard","hentry","category-cgi"],"_links":{"self":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=166"}],"version-history":[{"count":4,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":170,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions\/170"}],"wp:attachment":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}