I have a requirement as follows:
I wanted to initialize a user-defined class inheriting from FB::JSAPIAuto but I wanted to create it plugin independent..like
In JS, earlier i used to do this::
plugin().CreateJSAPIObject("someParameter");
//in order to initialize the c++ object with a value..It was successfully compiling..
What I want to do is to create a c++ object plugin independent
So in JS>>
UserDefinedJSAPIClassPtr obj=new UserDefinedJSAPIClass();
obj->SetMember1="This is Member 1";
//not necessarily using new keyword
plugin().DoSomethingWithObject(obj);
I came to know of boost::clipp library..and other numerous frameworks but am finding difficulty...as everything is strongly tied to the root JSAPI.
My doubt>>Is this possible?
My objective later on>>
P.S:: DoSomethingWithObject(FB::variant& object) will get the members of the JSAPI object (set in the JS side) and process them
EDIT after Taxilian's answer::
what in the case of this,
In JS side,
function AnotherJavascriptfunction(member1)
{
member1='2';
}
var UserClass=function(color,settings){}
var userObject=new UserClass('Red',AnotherJavascriptfunction);
plugin().DoTheChanges(userObject);
In FB side,
how do i access member1.?
which method should i Look for to get the member of settings
Regards,
Pratik
Definitely not possible to create a JSAPIPtr from javascript, but you can create a normal javascript object and pass it into a JSAPI method; it'll be a FB::JSObjectPtr type and you can then call methods/properties on it using Invoke, GetProperty, SetProperty, etc.
Related
I'm developing my project with Blazor Server-side.
While I develop, I used javascript code to implement things that hard to implement by C#.
However, I'm facing something weird situation. (I guess it is problem for javascript)
Suppose there are 2 users(A, B). When 'A' user do some action that call javascript code, if 'B' user into same page, 'A' users action affects to 'B' user.
I implemented web page that have 3d scene with threejs. As I explained above, when User 'A' move some object with mouse event(mousemove, mousedown..), if User 'B' accesses the same page, 3d objects of B are moved to the location where User 'A' moved.
Originally, when user access to web page I developed, 3d objects's position should be 0,0,0.
My Guess
I don't use prototype or class(use variable and functions globally. I'm new to javascript.. )
Javascript runs on server-side(share resources??, If then, how can I solve it)
I'm guessing the javascript would be problem, but if you have any other opinions, would you please share?
Edited
I've solved this problem using DotNetObjectReference.Create(this);
C#
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
//send created instance to javascript
var dotNetObjRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeVoidAsync("SetObjectRef", dotNetObjRef);
}
await base.OnAfterRenderAsync(firstRender);
}
[JSInvokable]
public async Task enableSomething(bool bEnable)
{
var something = bEnable;
}
//== before edit
//[JSInvokable]
//public static async Task enableSomethingStatic(bool bEnable)
//{
// var something = bEnable;
//}
Javascript
var objectRef;
function SetObjectRef(ref) {
objectRef = ref;
}
//call c# function
objectRef.invokeMethodAsync("enableSomething", true);
It was problem of 'static' method as I guessed.
If you declare C# method called from javascript as 'static' and this method changes something of UI variable, this method can affect another users.
So I create instance of current page and send it javascript and when I need to call C# methods from javascript, I call methods using created instance.
Is there any problem or issue, please share it.
Sorry for my bad English.
JavaScript runs client side only. I don't see how two windows, let alone two users, would share data.
Almost for sure, the problem is that you are injecting a singleton service-- which means the server will use one instance for all users.
If so, you have two choices:
(1) add logic to your singleton service to incorporate users. (For example, a dictionary with UserID/Property name for key, and a column for Value)
(2) go to Startup.cs and change the suspect singleton service to .AddScoped(), which will create a new instance for each user.
For right now, I think the latter solution will solve your problem immediately. However, don't underestimate the value of Singletons-- they'll be very useful for other things.
I have a C# file that pulls various config settings from different config files. A JavaScript application I'm writing needs some of those settings to run. I'm having trouble bringing the C# variables into the js file. Not sure what is the best approach. They need to end up as a JS object on the page. Would adding them to a JSon object in the C# file & calling that from the JS file work? Not even sure how to do that to be honest. Any help appreciated.
You can just declare a global variable in one of your root pages (say, _layout.cshtml):
<script>
var settings = {
foo: #(IsFoo ? "true", "false"),
bar: #SomeNumber,
baz: "#ImportantString"
}
</script>
Or, if you're writing a Web API, you can just add a /settings endpoint you can query like so (Assuming you're using jQuery):
$.get("/settings", response => {
// Store the `response` in a global variable.
});
If it's an independent javascript project and .net is more of an API, you need to make an API call which will send you those config settings.
If your javascript is part of .net MVC application, i.e., you are adding your javascript through an tag at then end of a .cshtml/.aspx file, you can easily pass it through a global variable, but even then the C# code need to pass those values through Modal to the .cshtml/aspx file.
what you can do is:
var pageConfig = pageConfig || {};
pageconfig.settings = #Html.Raw(Model.Settings); // This model object is part of the C# code and my assumption is that Settings will have array of configurations.
This can also be done globally, depending upon how the C# code is written.
Assuming that when you say 'various config settings' you're referring to .NET's ApplicationSettings (defined in Visual Studio's Properties > Settings), we've done something similar, in a generic manner, as follows:
public void WriteSettings(TextWriter writer)
{
// Declare the nameSpace for the DLL you want to pull settings from
var nameSpace = "foo.Bar"
ApplicationSettingsBase properties = (System.Configuration.ApplicationSettingsBase)Activator.CreateInstance(nameSpace, string.Format("{0}.Properties.Settings", nameSpace)).Unwrap();
foreach (SettingsProperty property in properties.Properties)
{
writer.Write(string.Format("{0}=\"{1}\", property.Name, properties[property.Name]);
}
}
I've ignored a few issues in your case:
I've not bothered trying to deal with non-strings; consider looking at property.PropertyType and casting your values appropriately
I've wrapped this in a function that accepts a TextWriter; you can pass this method Response.Output
Calling Javascript functions running inside Rhino from Java is easy enough - that after all is why Rhino was created. The thing I am having trouble establishing is this:
Context: I have a Phonegap CLI (v 6.3.3) Android project (API 19+) where I do a great deal of processing via loadable JavaScript running inside rhino
A Phonegap plugin - which I am creating at the same time as the actual Phonegap app - contains class called Storage which provides public, static, methods such as readFromFile(String fileName), writeToFile(String fileName,String data) etc.
What I want to be able to do is to call Storage.readFromFile etc from my loaded JavaScript code in Rhino.
Just how this should be done is not too clear to me. From the searches I have done thus far it involves using ScriptableObject.putProperty to pass the Java class in question, Storage in my case to JavaScript. However, how this should be done and then how it should be used at the JS end leaves me rather confused.
I would be most grateful to anyone here who might be able to point me in the right direction
Given that Rhino has less than 100 followers here it should perhaps come as little surprise that this question was not answered. In the mean time I have managed to find the solution myself and it turns out to be very simple. I share it below for the benefit of anyone else running into this thread.
My Storage class is very simple. It goes something like this
public class Storage
{
public static boolean haveFile(){}
public static boolean readFromFile(String fname){}
...
}
When I call Javascript from Java via Rhino I simply pass a new instance of the Storage class as the last of my function parameters
Context rhino = Context.enter();
Object[] functionParams = new Object[] {"Other parameters",new Storage()};
rhino.setOptimizationLevel(-1);
try
{
Scriptable scope = rhino.initStandardObjects();
String rhinoLog = "var log = Packages.io.vec.ScriptAPI.log;";
String code = /*Javascript code here* as shown separately below/;
rhino.evaluateString(scope, rhinoLog + code, "ScriptAPI", 1, null);
Function function = (Function) scope.get("jsFunction", scope);
Object jsResult = function.call(rhino,scope,scope,functionParams);
}
where the Javascript code is
function jsFunction(a,s)
{
//a - or a,b,c etc - here will be the "other" parameters
//s - will be the instance of the Java side Storage class passed above
//now you can do things like
s.writeToFile('fileName','fileData');
var fd = s.readFromFile('fileName');
s.dropFile('fileName');
...
}
What I would like to do is load javascript to create a library of methods in an object and wait until the object is used for the first time before it is actually defined or compiled. I would like to build references to this object before it is actually fully defined. When I call a method on this object for the first time before the methods on the object are ever defined (meaning the object doesn't actually have methods) I would like to define the object and then call the method. Is there a way to do this using standard syntax such as "MyLibrary.sayHello()" if "sayHello()" is not yet defined on the object.
I imagine it would look like this:
var independentVar = "noCommitments";
var MyLibrary = function(user_ini){
//MyLibrary.init looks like
// (function(ini){
// var a = ini;
// return function(){
// //Notice the method sayHello defines when called,
// // and does not return a reference
// return {
// b:a,c:"c",sayHello:function(z){return "Hello"+a+z}
// }
// }
// })(user_ini);
var d1 = myRequire("MyLibrary.init");
return {
**handleAll : function(){ this = d1(); this.("**calledMethod")}
}
};
var greeting = MyLibrary.sayHello();
alert(greeting);
This is only pseudo-code. If I add a method to cleanup I can then return that object to the uninitialized state of "{**handleAll:function(){/noContext/}}". My application/library has a stub and a link this way and can be used immediately from an undefined state, when building modules this can be useful in order to lower the number of references to a utility, say a post has a menu of functions and those functions are shared by by all posts, -- with a mechanism such as is described here only the "active post"/"post in focus" will reference the utility. It moreless give the ability to activate and de-activate modules. The special part is the modules are already warmed up, they are ready to call functions even though they do not reference them yet, it is similar to live binding but allows the whole user interface to already be defined with functions already stubbed out with the exact name they will have when they are usable. A control mechanism for defaults and debounce is easily found in this model for me.
My question is: Is this type of scripting possible natively or will I have to use some form of compilation like for TypeScript, CoffeeScript or others. I understand it is possible if I pass the method I would like to call as a parameter to a singleton factory. I ultimately would like whole applications that are able to gracefully degrade unused functionality without polluting the code.
What I mean by pollution:
var LibDef = (
function(){
return {
callUndefined:function(methodName){
var returnVal = {}
}
}
})()
var MySingltonLibrary = moduleSinglton.getLibrary("MyLibrary", Lib);
var greeting = MySingltonLibrary.callUndefined("sayHello");
//
// Please use your imagination to consider the complexity in the singlton
The best way that will allow you to tear down an object releasing any space its functions and members consume on the heap and maintain a single reference, that will allow the object to rebuild itself or just rebuild the function that is called is like this - (A very simple model, you may like to use arrays and gradually tear down nested objects internally):
var twentySecondObj(function(window,document){
var base_obj = undefined;
var externalAPI = undefined;
setTimeout(function(){
base_obj = undefined;
},20000);
return function(){
base_obj = (function(base_obj){
if(base_obj === undefined){
return {
property1:"This is property1",
property2:"This is property2"
}
}
})();
externalAPI = (function(){
if(externalAPI === undefined){
return {
property1:base_obj.property1,
property2:base_obj.property2
}
}
})();
return externalAPI;
}
})(window,document);
console.log(twentySecondObj().property1);
On an additional note, you can use getters and setters to observe access to properties and can internally present a facade of both functions and properties which reference a build method like the one above, this way it looks like you are accessing a legit member of the object. There are no options I can think of that will allow you to intercept when attempt to set a new property on an object like: myObj.fooProperty = "foo", and buildup that property into a custom object with a getter and setter, if you have a custom type that needs to be set, then you will have to know it's implimentation details to set it, or call a function passing in the property name and value, or use a method similar to what is shown above.
Here is a link to the proposal for adding weak references to javascript: https://ponyfoo.com/articles/weakref weak-references would alter how this looks, however would not address everything mentioned in this question. Remapping an object when a property is added via some type of deep observer will allow new property members to be enhanced at the time they are set, this would require that the observer ran synchrounously when the property was set, or once the set is complete, the very next statement must be a call to update the object. I will keep posted here for any advances I see that will make the "default handler function" available within javascript in the future.
WeakRef can absolutely be used for recording and handling object usage. I would really like to move object management into webworkers and service workers so they can be maintained through all web endpoints on the domain and do not require to reload across requests. Web frameworks would need to have modified handle to offload all dom changes and updates to worker, essentially a single hook that handles message passing for all hooks. Modload, now must include a message handle name and have task priority meta data so it is properly placed in the least busy or least active worker (slow worker and fast worker) this helps to create an api that can offload to cloud functions, this shpuld give us ability to do more AI, lookups and work offline that is currently handled for most apps in the cloud where more processing power is, and in this way we can gracefully augment local processing with cloud functions only when local resources, or completion times are degraded below acceptable speeds, or above acceptable power policy.
https://v8.dev/features/weak-references
server side background, getting deeper and deeper into client side.
I've got a site with a lot of legacy that I'm new to, and I'm just trying to get a handle on how things are working/what's available.
Is there a way to have jquery tell me(for a page/pages) all its current info and any plugins it can/is use/ing, similar to what phpinfo does?
Some proof of concept how you can get names for all plugins
var plugins = (function() {
var plugins = [];
for(var plugin in jQuery.fn) {
plugins.push(plugin)
}
return plugins;
}());
var filterValue = ['constructor', 'init', 'add', 'parents'] // // you must add all standard methods here
filterValue.forEach(function(value) {
var position = function(value) {
return plugins.indexOf(value);
}
while(position(value) >= 0) {
plugins.splice(position(value), 1)
}
})
console.log(plugins)
You can use the following for jQuery
console.log( jQuery.fn.jquery );
To answer your question directly, No jQuery does not have a mechanism that lists installed plug-ins.
jQuery does not keep such a registry of installed plugins. The jQuery plugin mechanism is to just add a method to the jQuery prototype (right along-side all the other jQuery methods). So, there's no separate list of which methods have been added by some outside agent (e.g. a plug-in). In addition, there's no one-to-one correspondence between methods and a particular plug-in as a single plug-in could add multiple methods.
It would be possible to create a master list (for any specific jQuery version) of what methods are there by default and then enumerate a jQuery object to find out which methods have been added since then, but you'd have to create that master list ahead of time and store it or create the master list immediately after jQuery was loaded before any plug-ins were loaded.
You can always test to see if any specific jQuery plug-in is loaded by just checking to see if any of its signature methods are available on a jQuery object.
So, if you really just wanted to know which of 10 plugins happen to be available in any given page, you could write a quick function that would test for each of the 10 plugins (by looking for the existence of known methods in those plugins) and would return a list of the ones installed, but this has to be done with specific knowledge of each plugin as there is no "generic plugin identification mechanism" since a plug-in is nothing more than a piece of code that adds methods to the jQuery prototype. It doesn't actually have any identity of its own.