Dispatching events from webkit for consumption in Adobe AIR - webkit

I have a webkit HTML component in my AIR application, and would like to be able to respond to events such as onclick and ondoubleclick generated from the HTML in the webkit component. Is there any way to accomplish this?

There is, although it took me a little while to find it.
This should serve as a pretty good starting off point: http://livedocs.adobe.com/flex/3/html/help.html?content=ProgrammingHTMLAndJavaScript_04.html
Here's the key code:
var html:HTMLLoader = new HTMLLoader();
var foo:String = "Hello from container SWF."
function helloFromJS(message:String):void {
trace("JavaScript says:", message);
}
var urlReq:URLRequest = new URLRequest("test.html");
html.addEventListener(Event.COMPLETE, loaded);
html.load(urlReq);
function loaded(e:Event):void{
html.window.foo = foo;
html.window.helloFromJS = helloFromJS;
}
The HTML content (in a file named test.html) loaded into the HTMLLoader object in the previous example can access the foo property and the helloFromJS() method defined in the parent SWF file:
<html>
<script>
function alertFoo() {
alert(foo);
}
</script>
<body>
<button onClick="alertFoo()">
What is foo?
</button>
<p><button onClick="helloFromJS('Hi.')">
Call helloFromJS() function.
</button></p>
</body>
</html>

Related

Call vue-html-to-paper print function on a new window

I have a Vue component I'd like to print. When the user presses a print button, a function is called which opens the component in a new window to isolate the HTML, and get the formatting right.
async openPrintDetailsDialogue() {
const prtHtml = document.getElementById('printable').innerHTML;
let stylesHtml = '';
for (const node of [...document.querySelectorAll('link[rel="stylesheet"], style')]) {
stylesHtml += node.outerHTML;
}
var newWindow = window.open('', '', 'left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0');
newWindow.document.write(`<!DOCTYPE html>
<html>
<head>
${stylesHtml}
</head>
<body id="printme">
${prtHtml}
</body>
</html>`);
newWindow.document.close();
newWindow.focus();
...
I then try to print using $htmlToPaper.
...
await this.$htmlToPaper('printme');
newWindow.close();
}
However, the main window alerts Element to print #printme not found!.
I add the plugin VueHtmlToPaper in my mounted() function:
mounted() {
Vue.use(VueHtmlToPaper);
}
I've already tried passing my existing styles.css to the $htmlToPaper() call options, which changed nothing. I also have some styles in my vue file's <style scoped>, which couldn't be included in the options parameter either.
How can I get VueHtmlToPaper to "point" to newWindow?
By opening a new window you have a new separate webpage, where is no Vue Js instance. It does not work so and you will not make it work this way. You should use a Modal, change the current page or make a new page with Vue instance for printing.

Unable to use Lazy load + Dynamic image manipulation Cloudinary

I am unable to use the feature Cloudinary Lazyload + Dynamic image manipulation both at the same time.
Is there any trick to use both the function at the same time?
I am using an HTML website.
My code is
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://unpkg.com/cloudinary-core#latest/cloudinary-core-shrinkwrap.js"></script>
<script type="text/javascript">
var cl = cloudinary.Cloudinary.new({cloud_name: "syg"});
// replace 'demo' with your cloud name in the line above
cl.responsive();
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const imageObserver = new IntersectionObserver((entries, imgObserver) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const lazyImage = entry.target
console.log("lazy loading ", lazyImage)
lazyImage.src = lazyImage.dataset.src
}
})
});
const arr = document.querySelectorAll('img.lzy_img')
arr.forEach((v) => {
imageObserver.observe(v);
})
})
</script>
<img class="cld-responsive lzy_img" data-src="https://res.cloudinary.com/syg/image/upload/w_auto,c_scale/sample.jpg" />
The responsive script will apply the relevant width value and replace w_auto in the URL based on the container size.
Since your code does not limit the <img> container, it applies the max width size of the screen.
For testing purposes, you can wrap your <img> element with <div style="width:50%;"></div> and you will see that the image URL adjusts the width transformation accordingly:
<div style="width:50%;">
<img class="cld-responsive lzy_img" data-src="https://res.cloudinary.com/syg/image/upload/w_auto,c_scale/v346346/sample.jpg"/>
</div>
In addition, you can take a look at the following broader implementation of LQIP+Lazy Loading+Responsive with Cloudinary for reference and ideas on how to implement these features within your site's pages.

How to define dojo module for reference by onClick in HTML?

I'm trying to follow the latest Dojo1.9 best AMD practices when defining a separate javascript module to be referenced by the JSP markup. I used to have a large javascript section in the same JSP file, MyJayEsspEe.jsp, where the javascript section defined functions that were called by various element onClick properties. Now I am separating the javascript into a new file called MyCallbacks.js using the Dojo define mechanism.
The format of the MyCallbacks.js looks like:
define(["dojo/dom", "dojo/dom-style", "dojo/has", "dijit/registry", "dojo/on"],
function (dom, domStyle, dojoHas, registry, on) {
...
function clickedOnButton1() {
console.log("Clicked on button1");
}
function clickedOnLinkTwo() {
console.log("Clicked on second link");
}
...
return {
clickedOnButton1: clickedOnButton1,
clickedOnLinkTwo: clickedOnLinkTwo
}
});
and in the MyJayEsspEe.jsp file I currently have working ugly markup that includes:
...
<button data-dojo-type="dijit/form/Button" type="button" onclick="require(['commonjs/MyCallbacks'], function(mycallbacks) {mycallbacks.clickedOnButton1();});">First Button</button>
<a id="testLinkId" href="#" onclick="require(['commonjs/MyCallbacks'], function(mycallbacks) {mycallbacks.clickedOnLinkTwo();});">Link Two</a>
...
but I'm hoping there's a way to define the module and require it such that in the markup I could have cleaner callbacks like so:
...
<button data-dojo-type="dijit/form/Button" type="button" onclick="mycallbacks.clickedOnButton1();">First Button</button>
<a id="testLinkId" href="#" onclick="mycallbacks.clickedOnLinkTwo();">Link Two</a>
...
I've been reviewing the Dojo reference documentation for defining modules and callbacks but so far haven't found a pointer to the clean solution that I'm looking for. Is there a cleaner solution than the one I've been using?
Thanks for your time,
Gregor
If you cannot create a full widget on the JS side and use the template to attach events,
using your current example you can write it like that:
<button data-dojo-type="dijit/form/Button" type="button" onclick="require('commonjs/MyCallbacks').clickedOnButton1();">First Button</button>
<a id="testLinkId" href="#" onclick="require('commonjs/MyCallbacks').clickedOnLinkTwo();">Link Two</a>
Your JS look a bit strange through, in how you return your functions. Usually it would be written like that:
define(["dojo/dom", "dojo/dom-style", "dojo/has", "dijit/registry", "dojo/on"],
function (dom, domStyle, dojoHas, registry, on) {
var MyCallbacks={};
MyCallbacks.clickedOnButton1 = function() {
console.log("Clicked on button1");
};
MyCallbacks.clickedOnLinkTwo = function() {
console.log("Clicked on second link");
};
...
return MyCallbacks;
});
As a best practice it is always advised to encapsulate the behaviour of a widget in itself. All callbacks that a widget is supposed to handle should be defined within the widget. Defining all the callbacks in a single module breaks the modularity and portability of your modules.
To answer your question:
<script>
require(['dojo/dom', 'dojo/on', 'commonjs/MyCallbacks'], function(dom, on, MyCallbacks) {
// register all event handlers here
on(dom.byId('testLinkId'), 'click', MyCallbacks.clickedOnLinkTwo);
});
</script>
<a id="testLinkId" href="#">Link Two</a>

Is there a way to disconnect an event added by dojoAttachEvent

I have a dojo widget which uses a a custom-library code having a link like this in its template.
Go Back
I need to find a way to disconnect this event from my widget. The only way i know how an event can be disconnected is, using a
dojo.disconnect(handle)
I could use this if I had the event connected using dojo,connect() which returns me the handle.
However with dojoAttachEvent i don't have the event handle hence no way to disconnect it.
Note :
Changing this html is not an option for me, since this an external library i am using.
Also, I am not looking for a solution to disconnect all events.
CODE:
otherWidget.js:
dojo.provide("otherWidget");
dojo.declare("otherWidget", [], {
templateString : dojo.cache("otherWidget","templates/otherWidget.html"),
_goBack: function(){
this.destroyWidgetAndRedirect();
},
destroyWidgetAndRedirect: function(){
//Code to destory and redirect.
},
});
otherWidget.html:
<div>
Go Back
<!-- Other Widget related code -->
...
</div>
myWidget.js:
dojo.provide("myWidget");
dojo.require("otherWidget");
dojo.declare("myWidget", [], {
templateString : dojo.cache("myWidget","templates/myWidget.html"),
this.otherWidget = new otherWidget({}, dojo.byId('otherWidgetContainer'));
});
myWidget.html:
<div>
<div id="otherWidgetContainer"></div>
<!-- My Widget related code -->
...
</div>
Any thoughts..
Thanks.
Extension points can be used directly on your html, or in javascript. Suppose the widget you are using is called 'my.custom.dojowidget', and that it has an onClick extension point. I will show here the declarative way, in your html. Try this :
<div data-dojo-type="my.custom.widget">
<script type="dojo/method" data-dojo-event="onClick" data-dojo-args"evt">
dojo.stopEvent(evt);
console.debug("did this work ?");
</script>
</div>
Now this depends on the existence of the extension point... if you can't still do what you want, please post the relevant parts of your widget's code.
So... based on the sample code you posted in your edit, I think you should do the following :
<div data-dojo-type="otherWidget">
<script type="dojo/method" data-dojo-event="destroyWidgetAndRedirect" data-dojo-args="evt">
dojo.stopEvent(evt);
// do whatever custom code you want here...
</script>
</div>

jCaptcha - Refresh only image not whole page

I'm using jCaptcha (http://jcaptcha.sourceforge.net/) on our website. The problem is sometimes it's very difficult to read the image. So, we are planning to provide a button named 'REFRESH' next to the jcaptcha image and upon clicking REFRESH button, it has to refresh only the jcaptcha image not the entire page/portlet. How can we do that?
This is how I solved it using JQuery, it will replace the image. The alert() is just there to show off the new filename and can of course be removed. The code is using the jquery plugin in grails but shows what to do in jquery to refresh the image.
<div>
<jcaptcha:jpeg name="captchaImage"/>
Refresh captcha
<jq:jquery>
$("#refreshCaptcha").click(function() {
$("#captchaImage").fadeOut(500, function() {
var captchaURL = $("#captchaImage").attr("src");
captchaURL = captchaURL.replace(captchaURL.substring(captchaURL.indexOf("=")+1, captchaURL.length), Math.floor(Math.random()*9999999999));
alert(captchaURL);
$("#captchaImage").attr("src", captchaURL);
});
$("#captchaImage").fadeIn(300);
});
</jq:jquery>
</div>
Make this changes in JSP :
<img src="jcaptcha" id="captcha_image"/> Refresh
Add the Javascript function like :
function reloadCaptcha(){
var d = new Date();
$("#captcha_image").attr("src", "jcaptcha?"+d.getTime());
}
You would have to load the image and the refresh button into . Than you should be able to refresh just the iframe. But the I don't know how you are performing your validation so.
Set an id for the img tag and let it call a javascript function:
<img src="jcaptcha.jpg" id="captchaImage"/>
javascript function:
<script type="text/javascript">
function refresh()
{
var captchaImage=document.getElementById("captchaImage");
captchaImage.src="jcaptcha.jpg";
}
</script>
this works fine because i implemented this one in my project just create one button on clicking that button it will come to below menctiond block of code like that you do
<script type="text/javascript">
function refresh()
{
var image=document.getElementById("kaptchaImage");
image.src="<%=request.getContextPath()%>/kaptcha.jpg?"+Math.floor(Math.random()*100)
}
</script>