How can i use javascript with actionscript? - javascript

I'am having a flex web project and i need to use some java script functions (e.g,geolocation) so can anyone help me to understand the way of relating them to each others.

The ExternalInterface class is used for communication between swf's and the javascripts located on the same page.
By using the ExternalInterface.call("functionName", functionParams...) function in as3 you can call any function in javascript within your webpage.
To register functions to be called in flex from javascript use ExternalInterface.addCallback("functionName", functionReference).
Usage:
package {
import flash.display.MovieClip;
import flash.external.ExternalInterface;
public class EITest extends MovieClip {
public function EITest() {
registerWithJavascript();
makeCall();
}
public function registerWithJavascript():void {
// To register a function with javascript
var isAvailable:Boolean = ExternalInterface.available;
if(isAvailable)
ExternalInterface.addCallback("callbackName", actualCallback);
}
public function actualCallback():void {
// Do something
}
public function makeCall():void {
// To call a javascript function
var isAvailable:Boolean = ExternalInterface.available;
var someParamToSend:int = 13;
if(isAvailable)
ExternalInterface.call("someFunction", someParamToSend);
}
}
}

Related

Blazor, how to constantly get currentWindow width?

I want to do something like this in a razor page:
#if (currentwidth<x)
{
le code
}
else
{
le other code
}
I have added javascript file and connected it to a utility service which works when I get the static width (which I tested).
js:
export function getCurrentWidth() {
return window.addEventListener("resize", () => {
window.innerWidth;
});
}
UtilityService method:
public async Task<double> GetCurrentWidth()
{
var m = await GetModule();
var result = await m.InvokeAsync<double>("getCurrentWidth");
return result;
}
Razor file:
double width;
protected async override Task OnInitializedAsync()
{
width = await utilityService.GetCurrentWidth();
}
Thus the problem is I can't call it from OnInitailzedAsync since this function only fired once, so I need a function that constantly checks the GetCurrentWIdth() method to check for resize.
Is there another way of doing this in blazor or what method could I use/ Thank you in advance.
First of all I'd like to point out that you may not have to solve your problem with javascript/C# code. If it's something in the html that you want to manipulate, you may just be better of using css. But I'll leave that up to you.
If however you truly need the window width like you mentioned above, then I would recommend registering a listener to the window (as you've already done) and have that listener call a dotnet function. Doing this with static methods is quite easy, but for instance component this can be a bit trickier as you have to pass an object reference of the current object.
The [JsInvokable] indicates that this method can be called from javascript, which allows communication from the javascript event listener to dotnet.
CSharpFromJs.razor.cs
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Threading.Tasks;
public partial class CSharpFromJS
{
private DotNetObjectReference<CSharpFromJS> _objectReference;
public int WindowWidth { get; set; }
[Inject]
public IJSRuntime JSRuntime { get; set; }
protected override void OnInitialized()
{
_objectReference = DotNetObjectReference.Create(this);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await InitWindowWidthListener();
}
}
[JSInvokable]
public void UpdateWindowWidth(int windowWidth)
{
WindowWidth = windowWidth;
StateHasChanged();
}
private async Task InitWindowWidthListener()
{
await JSRuntime.InvokeVoidAsync("AddWindowWidthListener", _objectReference);
}
public async ValueTask DisposeAsync()
{
await JSRuntime.InvokeVoidAsync("RemoveWindowWidthListener", _objectReference);
_objectReference?.Dispose();
}
}
CSharpFromJs.razor
#implements IAsyncDisposable
<h1>Window width: #WindowWidth</h1>
Javascript
// Manages the registered event listeners so they can be disposed later
let windowEventListeners = {};
function AddWindowWidthListener(objReference) {
let eventListener = () => UpdateWindowWidth(objReference);
window.addEventListener("resize", eventListener);
windowEventListeners[objReference] = eventListener;
}
function RemoveWindowWidthListener(objReference) {
window.removeEventListener("resize", windowEventListeners[objReference]);
}
function UpdateWindowWidth(objReference) {
objReference.invokeMethodAsync("UpdateWindowWidth", window.innerWidth);
}
The only thing you should be careful with is when a component is disposd. You should remove the registered handlers in the DisposeAsync function to ensure that they're not still registered to prevent memory leaks.
This link might provide some better instructions on how to use this, but they don't explain the part about disposing handlers.
Note: This only works in .net5 and later, as IAsyncDisposable was not yet implemented for component before that. If for some reason you're working with an earlier version, you could call it using IDisposable. But this could potentially cause deadlocks, so I would not recommend it.
For me works the NuGet package BlazorPro.BlazorSize
Implement the method:
async void WindowResized(object _, BrowserWindowSize window){}
and all necessary Dependencies (see description).

Calling Javascript functions from C# Unit Tests

I am working on a small project that will primarily be a C# library. I also want to create a JavaScript counterpart that is functionally equivalent. I would like to be able to test both from the same unit tests.
To be clear I am NOT going to be using this in a production environment where C# calls JS, or vice versa. I only want to blend C# and JavaScript in the context of the unit tests so I can verify and maintain cross-platform compatibility. Most examples I find show that this is possible within Blazor using JSRuntime, but I don't want to do this within a web application.
Below is an example of what I am trying to accomplish.
C# Method:
public class CsharpLibrary
{
public static bool CheckLength(string str) {
if (str.Length > 10)
return false;
return true;
}
}
JavaScript Function:
function CheckLength(str) {
if (str.length > 10)
return false;
return true;
}
Unit Test
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CsharpJavascriptUnitTesting
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void CheckLength_TooLong()
{
var str = "1234567890123456789";
var isValid = CsharpLibrary.CheckLength(str);
Assert.IsFalse(isValid);
// TODO: is it possible to load the local Javascript file?
// TODO: call JavaScript CheckLength(str);
// TODO: assert that the value returned is also false
}
}
}
Thanks to the recommendation in the comment above from Collen I was able to accomplish this with the Jurassic library.
[TestMethod]
public void CheckLength_TooLong()
{
var str = "1234567890123456789";
var isValid = CsharpLibrary.CheckLength(str);
Assert.IsFalse(isValid);
var engine = new Jurassic.ScriptEngine();
engine.ExecuteFile(#"..\..\JsLibrary.js");
isValid = engine.CallGlobalFunction<bool>("CheckLength", str);
Assert.IsFalse(isValid);
}

Haxe Macros - replace "function" with "async function"

I want that when converting haxe to JavaScript, asynchronous is added to its methods.
I have Haxe code:
#:expose
class Main implements IAsync {
static function main() {
trace("test");
}
static function testAwait() {
return 1;
}
}
And this code is converted to such a code:
. . .
Main.testAwait = function() {
return Main.test();
};
. . .
I wanted to be able replace function to async function in this code.
For example:
Main.testAwait = async function() {
return Main.test();
};
But I can only change the name of the method for example code macros:
package haxe_test;
import haxe.macro.Expr;
import haxe.macro.Context;
using haxe.macro.Tools;
using haxe_test.AsyncBuilder;
class BuildHub {
macro static public function build():Array<Field> {
var fields = Context.getBuildFields();
var testFunc:Function = {
expr: macro return $v{1},
ret: null,
params: [],
args: []
};
fields.push({
name: "testAwait",
access: [Access.AStatic],
kind: FieldType.FFun(testFunc),
pos: Context.currentPos(),
});
return fields;
}
How replace function to async function?
UPD: I simplified code. Maybe is anythings options compilers or JSGenApi can help me)?
Not sure if you considered something more simple but in Haxe 4 you can do something like this:
class Test {
static function main() {
var value = await( async(testAsync) );
trace(value);
}
static function testAsync() return 1;
static inline function await<T>(fn:Void->Void):T {
return js.Syntax.code("await {0}()", fn);
}
static inline function async<T>(fn:Void->Void):T {
return js.Syntax.code("async () => {0}()", fn);
}
}
or do both at same time:
class Test {
static function main() {
var value = asyncAwait( testAsync );
trace(value);
}
static function testAsync() return 1;
static inline function asyncAwait<T>(fn:Void->Void):T {
return js.Syntax.code("(async () => { await {0}() })()", fn);
}
}
I think your general options would be:
Collect information about async types/fields in build macros, then use that in haxe.macro.Context.onAfterGenerate to modify the output file. Since Haxe code is consistently indented, you can get away with a couple regular expressions (I once made a macro that'd split the output file into multiple by-package files this way).
Make a slightly modified copy of haxe.macro.ExampleJSGenerator to prepend async before method declarations of interest. Since you do not need any changes to expression printing, this is also pretty easy.

How to inherit from WebElement in WebdriverIO

I looking for a way to inherit from WebElement object that webdriverio returns, without monkey-patching and with TS types support (autocompletion is a must). Is there a way to do something like this?
class Checkbox extends WebdriverIOWebElement {
constructor() {
super($('div'))
}
// overriding base method
isDisplayed(): boolean {
// blabla some new logic here
}
check() {
if(!this.isChecked()) {
this.click()
}
}
uncheck() {
if(this.isChecked()) {
this.click()
}
}
}
Lets take an example , When we have a New Tag (my-app) in HTML and we have to build a case to Login using webdriverIO ,
Assume this is the HTML :
What we would do is using the component object pattern , component object pattern attempts to reduce that repetition and move the component's api into an object of its own. We know that in order to interact with an element's shadow DOM, we first need the host element. Using a base class for your component objects makes this pretty straightforward.
Here's a bare-bones component base class that takes the host element in its constructor and unrolls that element's queries up to the browser object, so it can be reused in many page objects (or other component objects), without having to know anything about the page itself.
class Component {
constructor(host) {
const selectors = [];
// Crawl back to the browser object, and cache all selectors
while (host.elementId && host.parent) {
selectors.push(host.selector);
host = host.parent;
}
selectors.reverse();
this.selectors_ = selectors;
}
get host() {
// Beginning with the browser object, reselect each element
return this.selectors_.reduce((element, selector) => element.$(selector), browser);
}
}
module.exports = Component;
then what we would do is , We will write a subclass for our app-login component:
const Component = require('./component');
class Login extends Component {
get usernameInput() {
return this.host.shadow$('input #username');
}
get passwordInput() {
return this.host.shadow$('input[type=password]');
}
get submitButton() {
return this.login.shadow$('button[type=submit]');
}
login(username, password) {
this.usernameInput.setValue(username);
this.passwordInput.setValue(password);
this.submitButton.click();
}
}
module.exports = Login;
Finally, we can use the component object inside our login page object:
const Login = require('./components/login');
class LoginPage {
open() {
browser.url('/login');
}
get app() {
return browser.$('my-app');
}
get loginComponent() {
// return a new instance of our login component object
return new Login(this.app.$('app-login'));
}
}
Now this component object can now be used in tests for any page or section of your app that uses an app-login web component, without having to know about how that component is structured. If you later decide to change the internal structure of the web component, you only need to update the component object.
Now we apply the same approach with the Check Box Component by using Shadow Dom Support :
public class CheckBox extends Component {
public CheckBox(element) {
this.element = element;
}
get checkBoxSelector() {
return this.host.shadow$(element);
}
get void toggle() {
checkBoxSelector().click();
}
get void check() {
if (!isChecked()) {
toggle();
}
}
get void uncheck() {
if (isChecked()) {
toggle();
}
}
get boolean isChecked() {
return checkBoxSelector().isSelected();
}
}
Then We can write a Check Box Controller component that can get the instance of check box using id and verify what every is necessary.
const CheckBox= require('./components/CheckBox');
class CheckBoxController{
open() {
browser.url('/login');
}
get checkboxComponent() {
// Using this we can verify whether the Specific Check Box has been Selected or Not
let element = browser.$('[id="lpagecheckbox"]');
return new CheckBox(element);
}
}
Note :
Please bear this is not the actual code , This is just a part of the template which can help us to move towards the solution of the Problem .
Source Contends :
https://webdriver.io/docs/api/element/isSelected.html
https://webdriver.io/blog/2019/02/22/shadow-dom-support.html
https://webdriver.io/blog/2019/04/03/react-selectors.html
https://webdriver.io/docs/pageobjects.html
Moreover if we are using Selenium Webdriver , This can help us to Achieve it
Here we have an interface which actually combines all the webdriver interfaces , then we create a Specific implementation by inheriting the Element Class , finally Lets assume of any component you need we should be inheriting and using it with its own implementation , In this case lets assume the Check box that should be inherited from then Element Implementation Class and finally a Cranky way of using it by instantiating the object. CheckBox cb = new CheckBox(element);cb.uncheck();
Step 1:
Create an Interface that combines all of the WebDriver interfaces:
public interface Element extends WebElement, WrapsElement, Locatable {}
Step 2:
Element Implementation Inheriting the element class:
public class ElementImpl implements Element {
private final WebElement element;
public ElementImpl(final WebElement element) {
this.element = element;
}
#Override
public void click() {
element.click();
}
#Override
public void sendKeys(CharSequence... keysToSend) {
element.sendKeys(keysToSend);
}
// And so on, delegates all the way down...
}
Step 3:
Consider any component you use , Lets assume Check Box in this case
public class CheckBox extends ElementImpl {
public CheckBox(WebElement element) {
super(element);
}
public void toggle() {
getWrappedElement().click();
}
public void check() {
if (!isChecked()) {
toggle();
}
}
public void uncheck() {
if (isChecked()) {
toggle();
}
}
public boolean isChecked() {
return getWrappedElement().isSelected();
}
}
Way of Using It :
CheckBox cb = new CheckBox(element);
cb.uncheck();
If you want More Clear way of Implementing Something Like this : refer the third Link
public class Part2ExampleTest {
private final WebDriver driver;
#FindBy(id = "checkbox")
CheckBox checkBox;
protected Part2ExampleTest(WebDriver driver) {
this.driver = driver;
}
protected static Part2ExampleTest initialize(WebDriver driver) {
return ElementFactory.initElements(driver, Part2ExampleTest.class);
}
#Test
public void simple() {
WebDriver driver = new FirefoxDriver();
Part2ExampleTest page = initialize(driver);
PageLoader.get(driver, "forms.html");
Assert.assertFalse(page.checkBox.isChecked());
page.checkBox.check();
Assert.assertTrue(page.checkBox.isChecked());
driver.close();
}
}
Sources :
Extend Selenium WebDriver WebElement?
http://elisarver.com/2012/12/09/wrapping-webelement-1/
http://elisarver.com/2012/12/10/wrapping-webelement-2
IWebElement is an interface that you can just implement inside your driver class.

Calling of typescript code from javascript doesn't work in ionic

I am trying to call typescript method from Javascript method in IONIC. But typescript method is not getting called.
I have created a Cordova plugin in IONIC that will return the result in Javascript success or failure method. From the success method, I would like to call typescript method to navigate to another page in ionic. Please let me know how to call typescript from Javascript.
Code snippet:
var success= function(){
alert("JS method called");. // alert displayed
typescriptMethod();. // Defined in class of typescript
}
Class MainClass
{
constructor()
{
success();. // JS method called
}
typescriptmethod()
{
alert("typescript method called");. // alert not displayed
}
}
Thanks,
You must understand that TypeScript is not a stand-alone programming language. It comes on-top of JavaScript, as a superset ( which means that once a TypeScript program is written and compiled, it is essentially a JavaScript program ). You could easily try writing the equivalent JavaScript code, if you want to do the trick. If you go to the TypeScript Playground you could really fast transpile your TS code into JS code ( if not too complex of course ) .
Anyway , here is a bit of a refresher how can you achieve what you asked :
var success = function () {
alert("JS method called");
typescriptMethod();
};
var MainClass = /** #class */ (function () {
function MainClass() {
success();
}
MainClass.prototype.typescriptmethod = function () {
alert("typescript method called");
};
return MainClass;
}());
This will give an error that typescripmethod() is not deifned , so you could make it static ( JS code) :
var MainClass = /** #class */ (function () {
function MainClass() {
success(); // JS method called
}
MainClass.typescriptMethod = function () {
alert("typescript method called");
};
return MainClass;
}());
var success = function () {
alert("JS method called"); // alert displayed
MainClass.typescriptMethod(); // Defined in class of typescript
};
success();
Or use a class instance ( JS code ) :
var MainClass = /** #class */ (function () {
function MainClass() {
success(this); // JS method called
}
MainClass.prototype.typescriptMethod = function () {
alert("typescript method called");
};
return MainClass;
}());
var success = function (instance) {
alert("JS method called"); // alert displayed
instance.typescriptMethod(); // Defined in class of typescript
};
success(new MainClass());
Hope this will do the trick for you .
you cannor call typescript code from javascript code.
typescript code is compiled into javascript. You can call equivalent javascript code of your typescript code.

Categories

Resources