I want to use an external crypto library in my GWT project (client side). (particularly, Stanford Javascript Crypto Library, http://crypto.stanford.edu/sjcl/
I have added these lines in my project's gwt configuration file (MyProj.gwt.xml)
<script src="libs/sjcl/sjcl.js" />
<script src="libs/sjcl/core/sha256.js" />
And have created a new method in my security class:
public static native String sha256(String ptext)
/*-{
return sjcl.hash.sha256.hash(ptext);
}-*/;
But when I call it
String result = Security.sha256("password");
I get an error ("sjcl is not defined")
If someone who knows these issues and javasript could read the library and tell me the right way, I will be saving much time and effort - no digging in monstrous JavaScript.
UPD:
First thing I figured out, external library must be in /war directory
Second, I couldn't make GWT import the *.js files if I added the following just to gwt.xml files
<script src="libs/sjcl/sjcl.js"></script>
<script src="libs/sjcl/core/sha256.js"></script>
I had to add similar lines to Entry point's html source
<script src="/sjcl/sjcl.js"></script>
<script src="/sjcl/core/sha256.js"></script>
This way import works, I could check it with Chrome Inspector
I tried to use another library, not so complicated as sjcl, and it worked fine.
So, obviously, I'm not using sjcl right.
Another library is simpler, just pure methods, sjcl uses classes and stuff, but as I don't know JS at all, I can't figure out how to call such things properly without digging into JS syntax. I really would like to skip this part.
Can anybody look into the sjcl code and tell me how to call the method properly? The source is really small and JS pro can figure it out at a glance, I think.
UPD 2:
It turned out that adding the following code to gwt.xml is enough, just put library in /war and pay attention to the preceding "/" in the path. If you don't put it there, GWT will be seeking for you lib in module directory
UPD 3:
And don't forget to clear browser's cache or "not found" error won't go away
Make sure that when you talk about objects in the global context that you prefix them with $wnd, meaning the main window instance that the app is running in. This is documented in the JSNI docs, see https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsJSNI#writing.
public static native String sha256(String ptext)
/*-{
return $wnd.sjcl.hash.sha256.hash(ptext);
}-*/;
"sjcl is not defined" means that you didn't import the sjcl file correctly.
Check the file path and make sure the browser can access the file.
Related
I'm programming a project using HTML and JavaScript. I access my js code with the following script tags:
<script src="js/monthChanger.js"></script>
However, when running my program in Edge & Google Chrame, I keep getting
this error.
Why is this happening? Looking at my file directories there doesn't seem to be anything wrong with the way I declared the function.
check out this article on absolute and relative paths
you probably want this:
<script src="./js/monthChanger.js"></script>
The ./ makes it relative to the current folder.
Alright, so it turns out my issue had nothing to do with HTML.
I didn't specify this in the OP, but I was also using a Django's framework in my project. I had mistakenly assumed that static fields such as css, js, and images would be called the same way they are called in normal html files. However, after reading django's documentation on managing static files, I realize that this is not the case. I follow django's instructions and was able to get my code working.
I am using ASP.NET MVC to build a web application, and I have fallen in love with the library Q.js, available here:
Q.js
Right now, I am using version 1.0, I load it up in the way that is most natural to me as an ASP.NET MVC developer. I have a place in my BundleConfig that just loads the script with my other scripts.
BundleConfig.cs
public static class BundleConfig {
public static void RegisterBundles(BundleCollection bundles){
bundles.Add(new ScriptBundle("~/bundles/scripts")
.Include("~/content/scripts/jquery.js")
// lots of other includes
.Include("~/content/scripts/q.js"));
}
}
So then in my view _Layout.cshtml, it's the normal simple process...
_Layout.cshtml
<head>
#Scripts.Render("~/bundles/scripts")
</head>
Easy enough, right? Yes, it works fine. But I notice that Q.js has another branch labelled v2.
Now, from what I can immediately tell, they are not that much different, but I do not believe the creator would have made a version 2 if they were not doing it to improve the product. I'd like to try it out, but this is where my experience fails me.
version 2 seems fundamentally different than version 1. Here is a link to it for quicker reference; Qv2
The q.js file starts out with this at line 43.
require("collections/shim");
var WeakMap = require("collections/weak-map");
var Iterator = require("collections/iterator");
var asap = require("asap");
I am accustomed to the require function being a part of requirejs, but I don't believe that is the purpose being served here. I in fact think this is intended to be consumed/run/used by node.js.
Now, since I am using ASP.NET MVC, I won't be using node.js. I've attempted to just put the expected folders and files in the right place so that they would be path relative to q.js, but that does not seem to satisfy it.
The Actual Question
Is there a way I can 'compile' Q.js 2.0 into a .js file that will not require node.js, and can be loaded normally within my ASP.NET MVC project? Can I use node.js to actually create an output .js file that has everything I need?
browserify is a tool for Node that takes all of the require()d dependencies, resolves them, and packages them into a single JavaScript file servable to the browser.
I actually have a js code that i want to protect, and so i use the dean edward's packer php from Nicolas Martin : http://joliclic.free.fr/php/javascript-packer/en/index.php
It correctly minify my code, but it doesn't rename var & function name (so it not obfuscate it).
For exemple, a web minifier return this :
(function(e){var t="#step1";var n="#step2";})
and the php packer return this (if i set Encoding:None, i tried with all other option, no change)
(function($){var step1="#step1";var step2="#step2";
I appreciate this php packer because it's just one short php file that i can push on all of my server or local projects (on Wamp).
Closure compiler no work very well on local projects (and if you want rename, it rename ALL, and so it seems you can't use this with library, like jQuery), and other need to use Java or Python/Ruby. I would like to use only php, if it's possible.
Anyone knows how to upgrade this php packer to do what i want ? i tried hard, and i failed hard.
I've found a solution :
I backed to the Closure Compiler, and i found a PHP *version* of it here : https://code.google.com/p/php-closure/
that work with on both local machine and server.
It's called like that in the html. You call the php process and give it js filename that you want to crypt, here jquery-wa-custom-object. You can give other js file adding &otherjsname&othertwojsname
<!-- Load protected javascript -->
<script src="js/protected/?jquery-wa-custom-object"></script>
and return a text string that contains all your crypted js.
In the php-closure.php, i edited it to have renamed variables (but not function name, because it use in others js files)
Finally, it will give you a fully minified/obfuscated js that can't be understand by anyone (even if you "beautify" it) because all var are not understandable.
With so much excellent code already freely provided to build on, are you sure people will be that interested in 'stealing' yours?
How much of your code is built on what you've learnt from others? So pay it forward
Even obfuscated code is fairly easy to deobfuscate. Just tracing the logic and renaming vars as you go is fairly quick and a good IDE that understands javascript scope can probably automate some of it.
Currently, I've been trying to put Cassette into our Sitecore project and it's just fallen flat on it's face. I've had dotLess in the project already, but would like a more solid solution for cache-busting while bundling.
I can use Cassette in a normal .Net4 project, but just can't get it to work in our Sitecore project. (Ed) We were unable to get it to actually build any sort of bundles (checked /_cassette) and it wasn't outputting anything to the page. For us, the project isn't built but is instead using CodeFile and I'm not sure if that was part of the problem. In general, we kept getting the No bundle with path 'xxx' exception no matter what we tried. It's a bummer to because I would really wouldn't mind having CoffeeScript weaved into the solution.
Is there a solution that compresses/minifies javascript and can render dotLess files with Sitecore?
The empty response streams from Cassette when working in any of the Sitecore client interfaces are being caused by the rewriteHtml functionality that it implements.
By default Cassette will buffer and rewrite page HTML output. This allows partial views to insert <link> tags referencing stylesheets after the <head> tag has been rendered. The rewrite functionality gets invoked as a PostRequestHandlerExecute event handler.
The empty response streams that you are seeing are as a result of the output stream that has been rewritten not being flushed. A fix for this issue is to flush the output stream when Close is called on the Cassette.AspNet.PlaceholderReplacingResponseFilter class, this is shown below:
void WriteUncompressedOutput()
{
var output = GetOutputWithPlaceholdersReplaced(bufferStream);
var outputBytes = outputEncoding.GetBytes(output);
if (outputBytes.Length > 0)
{
outputStream.Write(outputBytes, 0, outputBytes.Length);
outputStream.Flush();
}
}
If you do not require the rewriting functionality a workaround is available now. Just disable the Cassette HTML rewriting feature, either in the web.config:
<configuration>
<configSections>
....
<section name="cassette" type="Cassette.CassetteConfigurationSection, Cassette"/>
</configSections>
<cassette rewriteHtml="false"/>
or in code:
public class CassetteSettingsConfiguration : IConfiguration<CassetteSettings>
{
public void Configure(CassetteSettings configurable)
{
configurable.IsHtmlRewritingEnabled = false;
}
}
This information is included in my blog post about using Cassette with Sitecore.
We ended up getting SquishIt to work rather easily and without much hassle besides getting the JavaScript files to play nicely together.
Using VS2008 and ASP.NET 3.5 (or VS 2010 / .NET 4.0?), how can I include a bit of dynamic ASP.NET server-side code in mostly-static JavaScript and CSS files?
I want to do this to avoid cloning entire JS or CSS files to vary just a small part of them multi-tenant sites. Later, I want to extend the solution to handle localization inside javascript/CSS, dynamic debugging/tracing support, and other cool things you can get by injecting stuff dynamically into JavaScript and CSS.
The hard part is that I don't want to lose all the cool things you get with static files, for example:
JS/CSS code coloring and intellisense
CSS-class "go to definition" support in the IDE
automatic HTTP caching headers based on date of underlying file
automatic compression by IIS
The server-side goodness of static files (e.g. headers/compression) can be faked via an HttpHandler, but retaining IDE goodness (intellisense/coloring/etc) has me stumped.
An ideal solution would meet the following requirements:
VS IDE provides JS/CSS intellisense and code coloring. Giving up server-code intellisense is OK since server code is usually simple in these files.
"go to defintion" still works for CSS classes (just like in static CSS files)
send HTTP caching headers, varying by modified date of the underlying file.
support HTTP compression like other static files
support <%= %> and <script runat=server> code blocks
URL paths (at least the ones that HTTP clients see) end with .JS or .CSS (not .ASPX). Optionally, I can use querystring or PathInfo to parameterize (e.g. choosing a locale), although in most cases I'll use vdirs for this. Caching should vary for different querystrings.
So far the best (hacky) solution I've come up with is this:
Switch the underlying CSS or JS files to be .ASPX files (e.g. foo.css.aspx or foo.js.aspx). Embed the underlying static content in a STYLE element (for CSS) or a SCRIPT element (for JS). This enables JS/CSS intellisense as well as allowing inline or runat=server code blocks.
Write an HttpHandler which:
looks at the URL and adds .aspx to know the right underlying ASPX to call
uses System.Net.HttpWebRequest to call that URL
strips out the containing STYLE or SCRIPT tags, leaving only the CSS or JS
adds the appropriate headers (caching, content type, etc.)
compresses the response if the client suports compression
Map *.CSS and *.JS to my handler.
(if IIS6) Ensure .JS and .CSS file extensions are mapped to ASP.NET
I'm already using a modified version of Darick_c's HttpCompression Module which handles almost all of above for me, so modifying it to support the solution above won't be too hard.
But my solution is hacky. I was wondering if anyone has a more lightweight approach for this problem which doesn't lose Visual Studio's static-file goodness.
I know I can also hack up a client-side-only solution where I split all JS and CSS into "vary" and "won't vary" files, but there's a performance and maintenance overhead to this kind of solution that I'd like to avoid. I really want a server-side solution here so I can maintain one file on the server, not N+1 files.
I've not tried VS10/.NET 4.0 yet, but I'm open to a Dev10/.net4 solution if that's the best way to make this scenario work.
Thanks!
I have handled a similar problem by having a master page output a dynamic generated JSON object in the footer of each page.
I needed to have my js popup login dialog box support localization. So using JSON.NET for serialization, I created a public key/value collection property of the master page that pages could access in order place key/values into such as phrase key/localized phrase pairs. The master page then renders a dynamic JSON object that holds these values so that static js files could reference these dynamic values.
For the js login box I have the masterpage set the localized values. This made sense because the masterpage also includes the login.js file.
I do commend you on your concern over the number of http requests being made from the client and the payload being returned. Too many people I know and work with overlook those easy optimizations. However, any time I run into the same issue you're having (which is actually quite often), I have found I've usually either taken a wrong turn somewhere or am trying to solve the problem the wrong way.
As far as your JS question goes, I think Frank Schwieterman in the comments above is correct. I'd be looking at ways to expose the dynamic parts of your JS through setters. A really basic example would be if you have want to display a customized welcome message to users on login. In your JS file, you can have a setMessage(message) method exposed. That method would then be called by the page including the script. As a result, you'd have something like:
<body onLoad="setMessage('Welcome' + <%= user.FirstName %>);">
This can obviously be expanded by passing objects or methods into the static JS file to allow you the functionality you desire.
In response to the CSS question, I think you can gain a lot from the approach Shawn Steward from the comments makes a good point. You can define certain static parts of your CSS in the base file and then redefine the parts you want to change in other files. As a result, you can then dictate the look of your website by which files you're including. Also, since you don't want to take the hit for extra http requests (keep in mind, if you set those files to be cached for a week, month, etc. it's a one time request), you can do something like combining the CSS files into a single file at compilation or runtime.
Something like the following links may be helpful in pointing you in the right direction:
http://geekswithblogs.net/rashid/archive/2007/07/25/Combine-Multiple-JavaScript-and-CSS-Files-and-Remove-Overheads.aspx
http://www.asp.net/learn/3.5-SP1/video-296.aspx?wwwaspnetrdirset=1
http://dimebrain.com/2008/04/resourceful-asp.html
By utilizing the combining at run or compile time you can gain the best of both world by allowing you to logically separate CSS and JS files, yet also gaining the reduction of payload and requests that comes with compressing and combining files.