zwwcn

Just another WordPress.com site

Monthly Archives: August 2015

debug JQuery script loaded by getscript function

When loading js function with JQuery getScript function, we can’t debug it becuase it’s not in DOM. The following js function add the loaded js function into DOM and solve the problem.

var loadScript = function (path) {
    var result = $.Deferred(),
        script = document.createElement("script");
    script.async = "async";
    script.type = "text/javascript";
    script.src = path;
    script.onload = script.onreadystatechange = function(_, isAbort) {
        if (!script.readyState || /loaded|complete/.test(script.readyState)) {
            if (isAbort)
                result.reject();
            else
                result.resolve();
        }
    };
    script.onerror = function () { result.reject(); };
    $("head")[0].appendChild(script);
    return result.promise();
};

ref from :http://balpha.de/2011/10/jquery-script-insertion-and-its-consequences-for-debugging/

simulate signature in selenium

the following code simulate signature on canvas:

Actions builder = new Actions(getDriver());
WebElement canvasElement = getDriver().findElement(By.id("cordova.signature-view:pad"));
Action drawAction = builder.moveToElement(canvasElement, 20, 20)
	.clickAndHold()
	.moveByOffset(80, 80)
	.moveByOffset(50, 20)
	.release()
	.build();
drawAction.perform();

Multiple Canvas only draw the last one

I have five canvas on the page, The following code is supposed to read the image data from hidden input field and draw image to the correspoding canvas. but it only draw the last one.

$('.signatureField').each(function() {					   
	if($(this).children("input").val()!=""){
		canvas = $(this).children('canvas').get(0);
		ctx = canvas.getContext('2d');
		testImage = new Image();

		testImage.onload=function(){				
			ctx.drawImage(testImage,0,0,testImage.width,testImage.height,0,0,canvas.width,canvas.height);
		}
						
		testImage.src="data:image/png;base64,"+$(this).children("input").val();
	}						
})

Adding “var” to ctx solves the problem.What that does is to declare ctx as local variable in each loop, so they don’t share the same convas context.

$('.signatureField').each(function() {					   
	if($(this).children("input").val()!=""){
		var canvas = $(this).children('canvas').get(0);
		var ctx = canvas.getContext('2d');
		var testImage = new Image();

		testImage.onload=function(){				
			ctx.drawImage(testImage,0,0,testImage.width,testImage.height,0,0,canvas.width,canvas.height);
		}
						
		testImage.src="data:image/png;base64,"+$(this).children("input").val();
	}
})

Then I have the following code in CoffeeScript, unfortunately, it only draw the last canvas. Here I use apostrophe to declare canvas context as local variable. Also added an empty return at the end of the function to avoid CoffeeScript implicit return.

checklist.loadExistingSignature = (fields) ->
    for field in fields
        if field.type='signature' and field.value.length>0
            `var fieldCanvas = $('#' + field.id).get(0)`
            `var canvastx = fieldCanvas.getContext('2d')`
            `var testImage = new Image()`
            
            testImage.onload = ->
            	canvastx.drawImage(testImage,0,0,testImage.width,testImage.height,0,0,fieldCanvas.width,fieldCanvas.height);
            	return
            testImage.src = "data:image/png;base64," + field.value;
    return

To solve this problem, we need to add a javascript closure. In CoffeeScript , it’s the do function

checklist.loadExistingSignature = (fields) ->
    for field in fields
        if field.type='signature' and field.value.length>0
            `var fieldCanvas = $('#' + field.id).get(0)`
            `var canvastx = fieldCanvas.getContext('2d')`
            `var testImage = new Image()`
            do (canvastx, testImage) ->
            	testImage.onload = ->
            		canvastx.drawImage(testImage,0,0,testImage.width,testImage.height,0,0,fieldCanvas.width,fieldCanvas.height);
            		return
            	return
            testImage.src = "data:image/png;base64," + field.value;
    return

And the javascript version:

for (var i = 1; i < 5; i++) {
    var ctx = document.getElementById('canvas-' + i).getContext('2d'),
        image = new Image();
    (function(ctx, image) {
        image.onload = function() {
            ctx.drawImage(image, 0, 0);
        }
        image.src = images[(i - 1)];
    })(ctx, image);
}

ref for javascript closure in loop: http://www.mennovanslooten.nl/blog/post/62

Cordova not loading plugin js file

I installed signature plugin under cordova,but when testing it’s not loading the js file. Checking the cordova_plugins.js, the signature module is missing in the module.exports list. To fix the problem, you need to edit the plugin.xml file under plugins/nl.codeyellow.signature and add the jsmodule:

<js-module src=”www/signature-view.js” name=”Signature”>

<clobbers target=”nl.codeyellow.signature”/>

</js-module>