I am having trouble updating threejs to the new es6 class version that they introduced because I am having trouble with babel.
I have the following code where I am extending Object3D
import {
Object3D,
} from "three";
type Props = {
myProp:string
};
export default class MyBox extends Object3D {
constructor(props: Props = {}) {
super();
console.log("HERE");
this.init(props);
console.log("Done");
}
init(props){
// Do stuff
}
Now this works in almost every case just fine, except when I am trying to load it in an ios webview. In that case I drilled down and saw that my code is transpiled to
function e() {
var e,
o = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
return e = n.call(this) || this, console.log("HERE"), e.init(o), console.log("DOne"), e
Which on the ios webview throws an error saying:
TypeError: Cannot call a class constructor without |new|
Which to me means since Object3D is a class it cannot be called like the transpiled version wants to.
{
"presets": ["#babel/preset-flow", ["#babel/preset-env",
{
"targets": ">1%"
}], "#babel/react"],
"plugins": [
"#babel/transform-runtime",
"#babel/plugin-syntax-flow",
"#babel/plugin-transform-flow-strip-types",
"#babel/plugin-proposal-class-properties"]
}
I have tried playing with the targets property and other packages, but have had no luck. My understanding is the threejs is not getting transpiled, whereas the rest of my code is.
Edit: I was wrong about the cause, it was actually due to Meteor build systems misdetecting whether this was a legacy case or not
Answer for me ended up being:
import { setMinimumBrowserVersions } from "meteor/modern-browsers";
setMinimumBrowserVersions(
{
"mobileSafariUI/WKWebView": 10,
},
"classes"
);
Related
I use Ionic 3 on one of my projects with an authentication system. I use native storage when the user wants to connect. It works on Android but on iOS, it redirects me to the login screen even using platform.ready (). I saw that several people were a similar problem but no answer, so I wanted to know if someone was facing the same problem and if he found a solution. Here is my code:
this.plt.ready().then(() => {
this.nativeStorage.setItem('userStorage', { stayConnected: (typeof this.stayConnected == "undefined" || this.stayConnected == false ? '' : 'stayConnected'), userId: (result as any).id, userLogin: (result as any).login })
.then(
() => {
this.loader.dismiss();
this.navCtrl.setRoot(HomePage);
},
error => {
this.loader.dismiss();
this.presentToast(this.languageLogin.error, 3000, "bottom");
}
)
},
error => {
this.loader.dismiss();
this.presentToast(this.languageLogin.error, 3000, "bottom");
});
thank you for your answers.
I would put 2 function storeUser() and getUser() into the same provider UserService like belows
Then add UserService to the constructor of any pages required.
It works for both IOS, Android and web
import {Storage} from '#ionic/storage';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class UserService {
constructor(private storage: Storage){}
public storeUser(userData): void {
this.storage.set('userData', userData);
}
public getUser(): Observable<any>
return Observable.fromPromise(this.storage.get('userData').then((val) => {
return !!val;
}));
}
Yes, I have faced issues while using ionic native storage plugins. So I turned to javascript Window localStorage Property and it's working completely fine.
Syntax for SAVING data to localStorage:
localStorage.setItem("key", "success");
Syntax for READING data from localStorage:
var lastname = localStorage.getItem("key");
Syntax for REMOVING data from localStorage:
localStorage.removeItem("key");
and now you can write your code with this property, like this -
if (lastname == "success"){
this.navCtrl.setRoot(HomePage);
} else{
alert("Not matched")
}
You are inside a platform.ready(), which is good. The storage package also has a .ready() that you may want to leverage, which specifically checks if storage itself is ready. If this runs at startup there is a decent chance storage is initializing.
Also, this starts to get into some crazy promise chaining messiness. I'd suggest diving into async/await. Something like the (untested) code below.
try{
await this.plt.ready();
await this.nativeStorage.ready();
let stayConnectedValue = (this.stayConnected) ? 'stayConnected' : '';
await this.nativeStorage.setItem('userStorage', { stayConnected: stayConnectedValue , userId: (result as any).id, userLogin: (result as any).login });
this.navCtrl.setRoot(HomePage);
}
catch(err){
this.presentToast(this.languageLogin.error, 3000, "bottom");
}
finally{
this.loader.dismiss();
}
I have written this piece of code to build a simple react native UI
'use strict';
var React = require('react-native');
var styles = React.StyleSheet.create({
text : {
color : 'black',
backgroundColor : 'white',
fontSize : 30,
margin : 80
}
});
class PropertyFinderApp extends React.Component() {
render() {
return React.createElement(React.text,{style : styles.text},"Hello World");
}
}
React.AppRegistry.registerComponent('PropertyFinder',function(){ return PropertyFinderApp});
I am getting error "Super expression must either be null or a function"
I have already tried installing the latest version of react but I am still unable to solve it!
What's causing your error is the React.Component() which should be without the parentheses React.Component. When you fix that you will get another error from the use of lowercase React.text which should be React.Text.
I'm trying to load a custom module in a restartless add-on, using the following:
chrome/content/modules/Test.jsm:
var EXPORTED_SYMBOLS = [ 'Test' ];
let Test = {};
chrome.manifest:
content test chrome/content/
bootstrap.js:
const Cu = Components.utils;
// Tried this first, but figured perhaps chrome directives aren't loaded here yet
// let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
function install() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function uninstall() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function startup() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function shutdown() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
However, I get the following types of WARN messages (this one was for shutdown(), but basically identical for all functions and in the earlier attempt in the global scope):
1409229174591 addons.xpi WARN Exception running bootstrap method
shutdown on test#extensions.codifier.nl: [Exception... "Component
returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE)
[nsIXPCComponents_Utils.import]" nsresult: "0x80070057
(NS_ERROR_ILLEGAL_VALUE)" location: "JS frame ::
resource://gre/modules/addons/XPIProvider.jsm ->
file:///test/bootstrap.js :: shutdown :: line 21" data: no] Stack
trace: shutdown()#resource://gre/modules/addons/XPIProvider.jsm ->
file:///test/bootstrap.js:21 <
XPI_callBootstrapMethod()#resource://gre/modules/addons/XPIProvider.jsm:4232
<
XPI_updateAddonDisabledState()#resource://gre/modules/addons/XPIProvider.jsm:4347
<
AddonWrapper_userDisabledSetter()#resource://gre/modules/addons/XPIProvider.jsm:6647
< uninstall()#extensions.xml:1541 < oncommand()#about:addons:1 <
Are chrome.manifest directives not yet available in bootstrap.js? Or is what I am attempting some kind of security violation, perhaps? Or am I simply doing something trivially wrong?
What I was hoping to achieve, is that I could do something like the following:
chrome/content/modules/Test.jsm:
var EXPORTED_SYMBOLS = [ 'Test' ];
let Test = {
install: function( data, reason ) {
},
/* etc */
bootstrap: function( context ) {
context.install = this.install;
context.uninstall = this.uninstall;
context.startup = this.startup;
context.shutdown = this.shutdown;
}
}
bootstrap.js:
const Cu = Components.utils;
Cu.import( 'chrome://test/modules/Test.jsm' );
Test.bootstrap( this );
Perhaps it's a bit over the top to begin with, but I just kind of like the idea of hiding implementations in modules and/or objects and keeping bootstrap.js super clean.
If you happen to have suggestions on how to achieve this by other means: I'm all ears.
Yes you can your path is wrong though.
Just do this:
let test = Cu.import( 'chrome://test/content/modules/Test.jsm', {} ).Test;
notice the /content/
You don't have to do the .Test unless you want the lower case test to hold it. You can just do:
Cu.import( 'chrome://test/content/modules/Test.jsm');
and use as Test.blah where blah is whatever is in the JSM module.
This code can go anywhere, it does not have to be in the install function.
Make sure to unload the custom JSM modules or else it can lead to zombie compartments which is bad for memory. Read here:
last paragraph here: https://developer.mozilla.org/en-US/docs/Extensions/Common_causes_of_memory_leaks_in_extensions
more reading but optional: https://developer.mozilla.org/en-US/docs/Zombie_compartments
Beyond #Noitidart's answer, you don't have to use chrome.manifest' and register a content package if your only concern is how to import your module.
function install(data, reason) {
Components.utils.import(data.resourceURI.spec + "relative/path/to/your/module.jsm");
}
I am using Cordova 2.9.0 with phonegap to build an iOS app.
With iOS 8, I am getting error messages of
Deprecated attempt to access property 'geolocation' on a non-Navigator object.
Deprecated attempt to access property 'userAgent' on a non-Navigator object
I tried EddyVerbruggen's solution
https://gist.github.com/EddyVerbruggen/cd02c73162180793513e
But, I am getting those error messages from Cordova
Also, when my application loads completely, I have no problem using
window.navigator.userAgent
Fist of all, it seems just a warning and the apps work fine.
They have been fixed this and I suposse it will be available soon, but for people using cordova 2.9.X, we have to change the replaceNavigator function to be like this on the cordova.js file (the whole else is new)
function replaceNavigator(origNavigator) {
var CordovaNavigator = function() {};
CordovaNavigator.prototype = origNavigator;
var newNavigator = new CordovaNavigator();
// This work-around really only applies to new APIs that are newer than Function.bind.
// Without it, APIs such as getGamepads() break.
if (CordovaNavigator.bind) {
for (var key in origNavigator) {
if (typeof origNavigator[key] == 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
} else {
(function(k) {
Object.defineProperty(newNavigator, k, {
get: function() {
return origNavigator[k];
},
configurable: true,
enumerable: true
});
})(key);
}
}
}
return newNavigator;
}
I have a bootstrapped extension for Firefox.
And now I want to implement nsIContentPolicy XPCOM component.
I wrote a component module code.
And now I want to register this component.
The reason I want to register component is that I want to add my component to nsICategoryManager.addCategoryEntry with "content-policy" category.
var {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
//console.error("Running interceptor");
function Interceptor()
}
Interceptor.prototype = {
classDescription: "DeferredTo HTTP requests Interceptor",
classID: "{B5B3D9A0-08FC-11E3-8253-5EF06188709B}",
contractID: "#deferredto.com/Interceptor;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]),
shouldLoad : function dt_shouldLoad(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) {
console.log("dt_shouldLoad");
if (contentLocation.scheme != "http" && contentLocation.scheme != "https")
return Ci.nsIContentPolicy.ACCEPT;
let result = Ci.nsIContentPolicy.ACCEPT;
// we should check for TYPE_SUBDOCUMENT as well if we want frames.
if ((Ci.nsIContentPolicy.TYPE_DOCUMENT == aContentType) &&
SOME_REGULAR_EXPRESSION.test(aContentLocation.spec)) {
// do stuff here, possibly changing result.
}
return result;
},
shouldProcess: function ILO_shouldProcess() Ci.nsIContentPolicy.ACCEPT,
_xpcom_categories: [
{ category: "content-policy", service: true }
],
classInfo: XPCOMUtils.generateCI(
{classID: Components.ID("{B5B3D9A0-08FC-11E3-8253-5EF06188709B}"),
contractID: "#deferredto.com/Interceptor;1",
classDescription: "Interceptor implements nsIContentPolicy to block images that are not yet at screen #DeferredTo",
interfaces: [
Ci.nsIContentPolicy,
],
flags: Ci.nsIClassInfo.SINGLETON})
}
var components = [Interceptor];
var NSGetFactory = XPCOMUtils.generateNSGetFactory([Interceptor]);
Questions:
Is it possible to register the component from bootstrapped extension?
Is it possible to register the component from restartless extension?
Is it possible to use nsICategoryManager.addCategoryEntry "content-policy" without
component?
How to register the component in bootstrapped extension or somehow add
new "content-policy" category entry?
I've added to harness-options.js
"requirements": {
"sdk/page-mod": "sdk/page-mod",
"sdk/self": "sdk/self",
"chrome": "chrome"},
That is how I try to import module:
var {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://deferredto/lib/interceptor.js");
I' ve tried many paths ))) But none works. resource entry in chrome.manifest file does not allowed for bootstrapped extensions. The path to component module file is:
resources/deferredto/lib/interceptor.js
Adblock Plus, which is restartless but not using the SDK, registers an nsIContentPolicy implementation at runtime, just like your SDK would. There are probably a few SDK add-ons registering components at run time, but I don't know any open source ones that I would recommend to look at off the top of my head.
A few points regarding that ABP implementation and what to change to make it work with the SDK:
The category manager is available via Cc["#mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).
The component registrar should be available by requiring also components from the chrome module and then components.manager.getService(Ci.nsIComponentRegistrar).
As Adblock Plus, you must unregister your component yourself on unload.
The unload part is unfortunely also a bit tricking, since you cannot synchronously unregister your component and the category entry, due to Bug 753687. Adblock Plus therefore does it async using Util.runAsync, which just dispatches a runnable (event, if you like) to the main thread. I don't think you can use any SDK stuff here, as the SDK will clean up before any async code gets a chance to run, so you'd need to use a low-level XPCOM runnable (or timer) yourself.
Your code will register your component at runtime. You won't touch harness-options or anything like that.
(I also implemented a generic component register function myself, but that again is not SDK code, and would need to be adapted to run in the SDK, just like the ABP one. It is also very similar to the ABP one.)
Now my nsIContentPolicy sdk-based component look like this. File interceptor.js:
'use strict';
var { Class } = require('sdk/core/heritage');
var xpcom = require('sdk/platform/xpcom');
var { Cc, Ci, Cu, Cm } = require('chrome');
var categoryManager = Cc["#mozilla.org/categorymanager;1"]
.getService(Ci.nsICategoryManager);
// nsIDOMNode
const TYPE_DOCUMENT_NODE = Ci.nsIDOMNode.DOCUMENT_NODE;
/// Interceptor
var contractId = "#deferredto.com/Interceptor;1";
var Interceptor = Class({
extends: xpcom.Unknown,
interfaces: [ 'nsIContentPolicy' ],
get wrappedJSObject() this,
shouldLoad : function dt_shouldLoad(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) {
let result = Ci.nsIContentPolicy.ACCEPT;
return result;
},
shouldProcess: function () Ci.nsIContentPolicy.ACCEPT
});
var factory = xpcom.Factory({
contract: contractId,
Component: Interceptor,
unregister: false // see https://bugzilla.mozilla.org/show_bug.cgi?id=753687
});
/// unload
var unload = require("sdk/system/unload");
unload.when(function() {
function trueUnregister() {
categoryManager.deleteCategoryEntry("content-policy", contractId, false);
try {
console.log("xpcom.isRegistered(factory)=" + xpcom.isRegistered(factory));
console.log("trueUnregister");
xpcom.unregister(factory);
console.log("xpcom.isRegistered(factory)=" + xpcom.isRegistered(factory));
} catch (ex) {
Cu.reportError(ex);
}
}
if ("dispatch" in Cu) {
console.log('"dispatch" in Cu');
Cu.dispatch(trueUnregister, trueUnregister);
} else {
console.log('"dispatch" not! in Cu');
Cu.import("resource://gre/modules/Services.jsm");
Services.tm.mainThread.dispatch(trueUnregister, 0);
}
});
//xpcom.register(factory);
var interceptor = Cc[contractId].createInstance(Ci.nsIContentPolicy);
categoryManager.deleteCategoryEntry("content-policy", contractId, false);
categoryManager.addCategoryEntry("content-policy", contractId, contractId, false, true);
And you can use it from sdk like this:
var interceptor = require("./interceptor");