Partially skip sections with Google Closure Compiler - google-closure-compiler

I'm generating a javascript on the server like and would like to run Google Clousure Compiler to be ran on the php source code of the script.
var jsvar = <?=$var ? true : false ?>;
Just wandering if there is any way in telling the compiler to skip optimazation of ? Like a regexp skip:
/<\?=.*?\?>/
Best regards,
Niclas

I have found that my code is much easier to maintain when I separate my client-side JavaScript from my server-side logic. Now I write my scripts such that my server-side processing emits initialization variables.
Example - Server Side:
<?php echo 'var mynamespace = {}; mynamespace.jsvar = "' . $var . '";'; ?>
And in my client-side javascript:
var mynamespace = window['mynamespace'] || {};
function MyFunction() {
alert(mynamespace['jsvar']);
}
MyFunction();
Using this style, my client-side javascript compiles easily with Closure-compiler.

You can do this:
var jsvar = eval("<?=$var ? true : false ?>");
The compiler won't touch the contents of the string.

Related

Suitescript 1.0 & handlebars js

I'm starting to review some requirements for processing a few HTML templates from within a suitelet using suitescript 1.0
I haven't been able to find any information on handlebars JS from within netsuite but I'm curious as to whether there is any requirements to configuring a suitelet that does the server side generation as I would prefer to use it compared to using the client side implementation
If anyone can share anything useful on how to get a suitelet prepared to make use of handlebars that would be greatly appreciated
Below is a sample from one of the Suitelets I use handlebars in. You setup the suitelet like any other by creating a form object and a html field to hold the rendered handlebar template.
var screenTitle = 'Form Title';
var form = nlapiCreateForm(screenTitle);
var pageTemplate = nlapiLoadFile('SuiteBundles/Bundle '+sitBundleId+'/src/sit_html_templates/template.html').getValue();
var hbTemplate = Handlebars.compile(pageTemplate);
Handlebars.registerHelper('if_eq',function(a,b,opts) { if(a == b) { return opts.fn(this); } else { return opts.inverse(this); } });
Handlebars.registerHelper('json', function(context) { return JSON.stringify(context); });
var data = {
"account_id":nlapiGetContext().getCompany(),
"bundle_id":sitBundleId,
"other_data":{}
};
var htmlValue = hbTemplate(data);
var templateField = form.addField('template_section','inlinehtml','',null,'main_group');
templateField.setDefaultValue(htmlValue);
response.writePage(form);
Thats the basics. Of course the Handlebar library must be added to the library sublist on the NetSuite Suitelet record.

Manually use precompiled handlebars templates

How to manually use the precompiled handlebars.js templates?
Let's say, we have
source = "<p>Hello, my name is {{name}}</p>"
data = { name: "Joe" }
Currently, I have
template = Handlebars.compile(source)
render: -> template(data)
The source is coming from the database, and in order to cut down on the compilation time, I want to use a compilation step, precompiling the template server side with Handlebars.precompile(source) and then using something like:
template = precompiled_template
render: -> precompiled_template(data)
The precompiled_template is a string with function definition, so that doesn't work.
Also, I've found that Hanlebars.compile(source)() == Handlebars.precompile(source), but after browsing the source codes of handlebars, it's compilers and runtime, I'm still not sure how to achieve this.
if you did not find the right question till now, the answer is pretty simple.
Handlebars comes with a C pre-compiler on the command line, if you can access your shell you can simple just compile your templates each separated or merge them together into one file.
you can install Handlebars via npm / or build it on your system.
on the shell you can access the help file
$> Handlebars [ENTER]
You will see a help file like >
- f --output Output File etc etc ..
- m --min Minimize Output
$> Handlebars mysupertemplate.handlebars -f compiled.js -m ("-m" if
you want to minify the js file)
To run Handlebars.compile in the browser is a huge loss in performance, so it's worth a try to precompile on the server before sending the file to the browser.
To register Handlebars templates in your browser you have to load them like this:
var obj = {"foo":"bar"}
var template = require("./mytemplate-file.js") // require.js example
template = template(Handlebars) // Pass Handlebars Only if the template goes mad asking for his Father
var html = Handlebars.templates[template-name](obj)
For example if you have more then one template registered in the "templates-file" you will be able to access after the require call all templates by name using
var html = Handlebars.templates["templateName"]({"foo":"bar"});
You can go even further by register all the know helper within the file and / or making custom helpers for partials like so..
*// This will be the helper in you app.js file*
Handlebars.registerHelper("mypartials", function(partialName, data) {
var partial = Handlebars.registerPartial(partialName) || data.fn
Handlebars.partials[partialName] = partial
})
And in your template file you can put this...
{{#mypartial "divPartial"}}
<div id="block"><h2>{{foo}}</h2><p>{{bar}}</p></div>
{{/mypartial}}
{{#mypartial "formPartial"}}
<form id="foo"><input type="text" value="{{foo}}" name="{{bar}}"></form>
{{/mypartial}}
Now you can access this files by calling
var html = Handlebars.partials["divPartial"]({"foo":"bar","bar":"foo"})
var formHtml = Handlebars.partials["formPartial"]({"bar":"bar","foo":"foo"})
Hope this helped a bit ..
This speed test http://jsperf.com/handlebars-compile-vs-precompile/3 gave the answer.
Apparently, one solution is to eval() that resulting string and it will work.
The code is
var data = { name: "Greg" };
var source = "<p>Howdy, {{ name }}</p>";
eval("var templateFunction = " + Handlebars.precompile(source));
var template = Handlebars.template(templateFunction);
template(data);
=> "<p>Howdy, Greg</p>"
Of course one needs to be careful with eval and probably a better solution exists.

"eval is not a function" when using iframe and Greasemonkey/Scriptish

Is there any way I can get this piece of code to work inside Greasemonkey/Scriptish, or would I have to inject it into the webpage itself?
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementsById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
This code does work when using source:
<script type="text/javascript" src="test.js"></script>
But not when using in a Greasemonkey script, I have observed there's some kind of security barrier I'm not quite familiar with and attempted to use unsafeWindow to bypass XPCNativeWrapper.
Please shed some light on this.
Several things:
The code has an error; getElementsById is not a function.
That code otherwise does work in Greasemonkey 1.0 or later, if the #grant none directive applies. More on this below.
For Scriptish, all other browsers, and Greasemonkey scenarios where #grant none is not possible; you will have to "inject" the code. More on this below.
As Jeremy J Starcher says, eval() should be avoided as much as possible. eval() makes performance, maintenance, debugging, and security much harder.
For Greasemonkey 1.0, and later:
In some scenarios, Greasemonkey no longer uses the XPCNativeWrapper. See the doc for the #grant directive.
So this means that (1) If your script uses no GM_ functions and (2) the script specifies #grant none, then your code will run as-is (excepting the getElementsById typo).
Note that no other scripting engine does this. (For darn good reasons. Greasemonkey's new behavior concerning #grant, and the sandbox, is controversial at best.)
If you wish to use GM_ functions, then you must inject the iframe code. See the next section.
For Scriptish, Privileged Greasemonkey, Chrome, etc.:
Scriptish, Sandboxed Greasemonkey, Chrome, etc. all do not handle iframes well from within their respective sandboxes. (See these Q's, for example.)
The only reliable way to run this kind of code from a GM/userscript is to inject it. Like so:
function gmMain () {
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
}
addJS_Node (null, null, gmMain);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}

Is there a (free) way to unpack .zip files without the use of a .DLL in ASP Classic

I would like to be able to unpack a .zip file using ASP classic.
I have had a bit of a poke around on google for something that will allow me to do this, and there seems to be a fair amount libraries out there. However all of these as far as I can tell require me to install a third party DLL.
The server that this script will be deployed on (or more accurately the IT department that control said server) will not allow me to use these to extend ASP's functionality and do what I have been asked to do (totally paradoxical!).
Is there any class library's out there that I might just be able to throw in as an include?
thanks for your time
Not sure is you can make it work with ASP, but in this project you will find a way to unZip in VB using a DLL, but you don't need to register the DLL, just put it somewhere where the class can find it.
I've used it in a VB 6 compiled app, but maybe you can adapt it to ASP. Not sure.
This is the code you will need: UnZip.cls
Hope it helps.
I have solved my problem... it's pretty messy, far from ideal, and dependant on server set up, but for the sake of anyone that has a similar problem and server in future here is how I solved it.
Basically I used PHP's ZIP library which seems to be installed on the server that I'm working on and made an unzip.php file:
<?PHP
$infile = $_REQUEST['infile'];
$outfile = $_REQUEST['outfile'];
$input_folder = "uploads";
$output_folder = "templates";
echo "false";
$zip = zip_open($input_folder."/".$infile);
if ($zip) {
while ($zip_entry = zip_read($zip)) {
$fp = fopen($output_folder."/".$outfile."/".zip_entry_name($zip_entry), "w");
if (zip_entry_open($zip, $zip_entry, "r")) {
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
fwrite($fp,"$buf");
zip_entry_close($zip_entry);
fclose($fp);
} else {
echo "false";
exit;
}
}
echo "true";
zip_close($zip);
} else {
echo "false";
exit;
}
?>
Then where I wanted to call this in my ASP script I HTTPXML'd to the PHP file location on same server with my variables as part of the querystring.
Response.Buffer = True
Dim objXMLHTTP, xml
Set xml = Server.CreateObject("Microsoft.XMLHTTP")
xml.Open "GET", "http://" & strdomain & "/unzip.php?infile="& filename &"&outfile=" & out_foldername, False
xml.Send
if xml.responseText = "true" then
SaveFiles = SaveFiles & "(unzip successful!)"
else
SaveFiles = SaveFiles & "(unzip failed!)"
end if
Set xml = Nothing
next
where
filename = The name of the file that you want to unzip
out_folder = The name of the folder that you want put your unzipped files into
strdomain = Request.ServerVariables("HTTP_HOST")
SaveFiles = my return variable.
I'm sure there must be a better way of doing this, but for the time being in my situation this seems to work ok (and hopefully no one will ever know!).

ASP.Net Custom Client-Side Validation

I have a custom validation function in JavaScript in a user control on a .Net 2.0 web site which checks to see that the fee paid is not in excess of the fee amount due.
I've placed the validator code in the ascx file, and I have also tried using Page.ClientScript.RegisterClientScriptBlock() and in both cases the validation fires, but cannot find the JavaScript function.
The output in Firefox's error console is "feeAmountCheck is not defined". Here is the function (this was taken directly from firefox->view source)
<script type="text/javascript">
function feeAmountCheck(source, arguments)
{
var amountDue = document.getElementById('ctl00_footerContentHolder_Fees1_FeeDue');
var amountPaid = document.getElementById('ctl00_footerContentHolder_Fees1_FeePaid');
if (amountDue.value > 0 && amountDue >= amountPaid)
{
arguments.IsValid = true;
}
else
{
arguments.IsValid = false;
}
return arguments;
}
</script>
Any ideas as to why the function isn't being found? How can I remedy this without having to add the function to my master page or consuming page?
Try changing the argument names to sender and args. And, after you have it working, switch the call over to ScriptManager.RegisterClientScriptBlock, regardless of AJAX use.
When you're using .Net 2.0 and Ajax - you should use:
ScriptManager.RegisterClientScriptBlock
It will work better in Ajax environments then the old Page.ClientScript version
Also you could use:
var amountDue = document.getElementById('<%=YourControlName.ClientID%>');
That will automatically resolve the client id for the element without you having to figure out that it's called 'ctl00_footerContentHolder_Fees1_FeeDue'.
While I would still like an answer to why my javascript wasn't being recognized, the solution I found in the meantime (and should have done in the first place) is to use an Asp:CompareValidator instead of an Asp:CustomValidator.

Resources