Haskell Webviewhs textfields and returns to Haskell - javascript

I've discovered webviewhs and tried it recently. It just works and I think it can do what I need it to do. Samples are abundant, but I would need some pointers of Haskell experts.
{-# LANGUAGE
OverloadedStrings
, QuasiQuotes
#-}
import Data.Text
import Language.Javascript.JMacro
import qualified Graphics.UI.Webviewhs as WHS
main :: IO ()
main =
WHS.withWindowLoop
WHS.WindowParams
{ WHS.windowParamsTitle = "webviewhs - How do I run some JavaScript inside the window?"
-- This could be a localhost URL to your single-page application (SPA).
, WHS.windowParamsUri = ""
, WHS.windowParamsWidth = 800
, WHS.windowParamsHeight = 600
, WHS.windowParamsResizable = True
, WHS.windowParamsDebuggable = True
}
-- This is the callback JavaScript can execute.
(\ _window stringFromJavaScript -> print stringFromJavaScript) $
-- This function runs every window loop.
-- Return True to continue the loop or False to exit the loop.
\ window -> do
let string = "Hello from Haskell." :: Text
-- runJavaScript returns either True on success or False on failure.
WHS.runJavaScript
window
[jmacro|
alert ("Yahoo! Alert windows, but little too persistent!");
window.external.invoke("Hello from JavaScript.");
|]
If I use the code above, the alert-dialog (test) keeps popping up. I would love to have it gone after ok. I also tried several times to get information (document.getElementById) from a sites' input field. Cannot get that to work. For me webviewhs is the missing link in Haskell and I would really like to get it to work.

The problem is in WHS.withWindowLoop. Referring to the documentation:
Creates a window for you. Accepts a function that is called with each iteration of the window loop. If the accepted function returns False, the loop is exited and the window is destroyed. If the accepted function returns True, the loop is continued provided it can.
(my emphasis)
Note that the last parameter of withWindowLoop is invoked repeatedly until it returns False. However, you are always returning True, meaning that the dialog box is repeatedly opened without ever finishing the loop. I can see two ways out of this problem:
Use WHC.createWindow instead; this function simply creates a window and returns it, without looping. This is the approach used in the relevant example.
Keep on using withWindowLoop, but return False instead of True. This will stop the loop immediately after one iteration.
If you really want to use withWindowLoop, then you could declare an IORef which is True at first, then changed to False after one iteration. That approach isn't very idiomatic though. (Don't use this approach, it doesn't work, it actually launches the dialog box twice, and it's much more complicated than needed anyway)

Related

How to check if NOT using Javascript bitwise operators?

I have a function that checks whether a user is premium by checking its flags:
isUserPremium() {
return this.flags & Flags.PREMIUM; // returns true
}
Now let's say that I'd want another function, but this time to check whether the user is free, but using the same flag. I tried negating the returned value, but I'd like to know if there was a better way to do this.
isUserFree() {
return !(this.flags & Flags.PREMIUM); // returns false
}
There isn't a way of checking whether a flag is not set with a single operator. I can suggest using !isUserPremium() instead of isUserFree() later in the code - don't create functions that invert a value returned from another function. However, make sure that you don't rely on this for security. Everything that is executing in the browser can be easily manipulated.

Is there a way to change variable values while debugging JavaScript?

I have a breakpoint on this piece of code (using Firebug):
if (validator.formValidate([dom.forumid]))
How can I skip this validation part and get into the if clause even if my dom.forumid is not valid, i.e. the call to formValidate() returns false? So how can I make it return true?
I was thinking about modifying the JavaScript, but I don't know how that's done.
As of today (Chrome 67) you can just double-click any variable on the right hand side under the "Scope" section and edit it in real-time.
In Firebug I do this by entering an assignment into the watch input field
to assign a new value
to assign a new function that returns the value I expect
This also works in Chrome ~33 (just tested) execpt: one has to enter the assignment into the console (which actually works in Firefox too, but using the watch panel is faster :).
In Firebug, you have to edit and re-save the assignment typed into the input on each break.
Of course, replacing the function will prevent the code from functioning normally on further runs. To avoid this one might save the original value to window._savedFnX or so and then do the assingment again assigning the saved function/value. But I think this is a workaround from saving one stepping through the code again and again to reach the point of interest. I often realize that there's a bad condition and then I want to continue (while the code would not) to test the rest of the code.
Take a look at these screenshots:
Code background
In the screenshot photo is an instance with this code:
{
...
_loaded: false, // set to true on some condition
...
isLoaded: function(){
return this._loaded;
},
...
}
The method isLoaded() will be replaced in the example to always return true. :)
Firebug
(Applies to Firebug ~1.12)
Stop at breakpoint
Go to the console
Assign function that returns the value you want to the variable in scope (or being reachable) [ORANGE]
The [BLUE] box highlights the the value that would be returned by isLoaded() and the value that is being returned by the replaced function.
Chrome
(Applies to Chrome ~34.0)
Note: in Chrome you can also edit the source code and re-run the modified version.
Stop at breakpoint
Go to the console
Assign function that returns the value you want to the variable in scope (or being reachable) [ORANGE]
(Refresh to see the result) [GREEN]
The [BLUE] box highlights the the value that would be returned by isLoaded() and the value that is being returned by the replaced function.

How to set variables inside a mocha test

I am having trouble understanding how to set variables for use in my tests. For example I have a function called spark.isTriple() that takes a number and looks at an array called dice and returns true if the value occurs three or more times or false if it doesn't.
#In game.coffee
window.spark =
isTriple: (n)->
triples = _.filter dice, (i)->
n is i
if triples.length >= 3
true
else
false
And I have a test that looks like this.
# In game_spec.coffee
describe 'spark.isTriple', ->
it "Should return true if the given value is found 3 or more times in the dice roll", ->
dice = [1,2,2,2,4,5]
spark.isTriple(2).should.be.true
The problem is that 'dice' is also being set in an earlier test that is actually testing a rollDice() function. In that test dice is being set to a random array of values which is what it should be doing and testing. But for this particular test I want to be able to set 'dice' to a specific array in order to test my isTriple() function. I've tried placing the "dice = [1,2,2,2,3,4]" in a before() call and a beforeEach() call but it doesn't seem to make any difference.
If anyone can give me some help or pointers on this it would be much appreciated.
So mocha + coffeescript sometimes requires an explicit declare in the right scope if you want a variable that a whole suite of tests can use and can be manipulated during before/beforeEach/after/afterEach.
describe 'spark.isTriple', ->
dice = null #force coffeescript var declaration
it "should blah blah", ->
dice = [1,2,2,2,4,5]
I'm pretty sure something along those lines will fix your problem, but if you post a full file that demonstrates the issue I can be sure.
I'm gonna disagree with Peter here. I think depending on a variable across tests is a bad idea -- it sets you up for intermittent and weird failures in tests. Anything that's going to change as a result of the test should be contained only in that test. To that end, I'd write your re-write your code like so (from the coffee console):
window.spark = hasTriple: (dice, n) ->
ld.filter(dice, ((i) -> n is i)).length >= 3
{ hasTriple: [Function] }
coffee> window.spark.hasTriple([1,2,1,2,5,6], 2)
false
coffee> window.spark.hasTriple([1,2,2,2,5,6], 2)
true
I renamed _ to ld (aka Lodash) because _ has a special meaning in the console so I think it's a good practice to avoid using it.

Strange Javascript statement

if (1) {
google_conversion_value = 1;
}
What is the meaning of the above statement? I mean, this looks like it will always execute so why bother with the if statement?
updated: one reason might be remnants of scripting on the server side. Any other ideas?
updated2: could as easily change the value of the assignment without bothering with the if statement, no?
There are two likely explanations:
It's a leftover from debugging.
The file containing this code is generated dynamically and the original sourcecode contains something like if(<?php echo $some_stuff_enabled; ?>)
However, in the latter case it would have been cleaner to output that code block only if the condition is met - but maybe it's used in some crappy template engine that just allows replacements but no conditionals...
I've seen this before, and I've always assumed it was a remnant of some old condition that was no longer needed, but never removed. I can't see any actual reason to do something like that otherwise.
Potentially because the person writing the code wanted an easy way to turn it off and on again, this is especially useful if there is a lot of code inside the block (not the case here).
Another possibility is that the original programmer couldn't be bothered writing the logic or, more likely, it hadn't been specified so the "if" was left as a placeholder.
More than likely left in from a debug release or something similar. You're right, it will always execute. It could also have been done like this so that it can be easily enabled / disabled by setting the if to 0. Perhaps the developer intended to use it as a flag somewhere else in the code?
actually, this happens when the "if" condition is driven from server, so instead of doing the right thing and not produce the script when the condition is false, they do something like this:
if (<% if (my_server_condition) then Response.Write("1") else Response.Write("0") %>){
// code goes here
}
Perhaps the if statement used to check for a legitimate conditional, and then someone replaced it with a truthy value for testing/debugging/etc.
You're right, it will always execute because 1 is truthy. I would go through your source control history and investigate that line to see if it used to contain a real conditional. If the conditional was always 1, then it's likely a debugging statement. Otherwise someone might have meant for it to be a temporary change, and may not have meant to check that in (which could be bad).
I'm not sure where this code is from, but as you indicated it will always execute. As for why you'd do this, there are times where you want to see what the result of branch code would be, without having to setup an environment. In this case you can comment out the actual value and replace it with if(1) instead for testing:
// if( ... some hard to achieve condition )
if (1) {
// Now you can see what happens if this value is set quickly
google_conversion_value = 1;
}
Of course the problem with this is that it's sometimes easy to forget to remove the if(1) and uncomment the proper condition.
This is actually the javascript recommended by Google on http://support.google.com/adwords/bin/answer.py?hl=en&answer=1722054#nocomments (click on Step 2 for the sample HTML)

Is there a name for this pattern?

I am basically quite sure this pattern must exist and possess a name... for now I will call it "gate pattern"...
Here it is:
In my webpage's javascript, I have to trigger various asynchronous processes. Let's not discuss how trully async js is, but anyway I have to trigger 2 or 3 AJAX calls, must be sure, the UI build-up has finished, and so on.
Only then, when all these processes have finished, I want to do run a certain function. And precisely once.
Example
1: cropStore loaded()
2: resizeEvent()
3: productStore loaded()
The Pattern:
At the end of every (sucessful) Ajax-load-callback, the end of the GUI construction routine, etc... I set a respective flag from false to true and call gatedAction()
onEvent( 'load',
{
.... // whatever has to happen in response to cropStored, resized, etc...
// lastly:
f1 = true; //resp f2, f3, ...
gatedAction();
}
Gate will check the flags, return if any flag is still unset, only calling the target function, if all flags (or as I call them: gates) are open. If all my async pre-conditions call gatedAction() exactly once, I hope I can be sure, the actual targetFunction is called exactly once().
gatedAction ()
{
// Gate
if ( ! f1) return;
if ( ! f2) return;
if ( ! f3) return;
// actual Action ( <=> f1==f2==f3==true )
targetFunction();
}
In practice it works reliably. On a side-note: I think java-typical (not js-typical) synchronization/volatile concerns can be ignored, because javascript is not truly multithreading. Afaik a function is never stopped in the middle of it, just to grant another javascript function in the same document run-time...
So, anyone, is there a name for this? :-)
I need this pattern actually quite often, especially with complex backend UIs.. (and yes, I think, I will turn the above butt-ugly implementation into a more reusable javascript... With a gates array and a target function.)
It sounds like Balking pattern to me.
It is similar to the Rendezvous pattern, although that pattern is generally used in the context of multithreaded real-time systems.
I have no idea, if your pattern has a special name, but it seems equivalent to just using a counting semaphore, which blocks the thread, which started all those other actions, until they all made a V-invocation. Of course, there are no threads and semaphores in JavaScript, but instead of using many boolean variables you could use just one integer for counting.
In addition to the actual answer to your question, you might be interested in the Rx framework for Javascript. It's a port of the .NET version and allows you to compose events, so you don't have to work with tons of flag variables. It's meant for this sort of thing.
http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

Categories

Resources