How to load a file from a user selection?
In later flex versions is available the method FileReference.load(). But in flex 2 there isn't.
I want to do something like this:
var fileRef:FileReference= new FileReference();
button.addEventListener(MouseEvent.CLICK, onButtonClick);
function onButtonClick(e:MouseEvent):void {
fileRef.browse([new FileFilter("Images", "*.jpg;*.gif;*.png")]);
fileRef.addEventListener(Event.SELECT, onFileSelected);
}
function onFileSelected(e:Event):void {
fileRef.addEventListener(Event.COMPLETE, onFileLoaded);
fileRef.load();
}
function onFileLoaded(e:Event):void {
var loader:Loader = new Loader();
loader.loadBytes(e.target.data);
}
Related
I found some classes in defpackage directory but it not list out with below code:
log("load script")
Java.perform(function() {
log("load java")
var clzlst = []
Java.enumerateLoadedClasses({
onMatch: function(clzname) {
clzlst.push(clzname)
},
onComplete: function(e) {
console.log("<<<<onComplete");
}
});
log(clzlst.length)
clzlst.forEach(function (clzname) {
if (clzname.includes("abcd")) {
log("found clz:" + clzname) // this line not been hitted.
}
});
var hook = Java.use("abcd");
var methods = hook.class.getDeclaredMethods();
hook.$dispose();
methods.forEach(function (method) {
var name = method.toString();
log(name) // this line hitted
});
});
function log(msg) {
console.log(msg)
}
The loaded list classes not include target class (e.g. abcd), but if I call Java.use("abcd"), I can access that class successfully.
I guess that class maybe still not being loaded! how can I list all classes even if it's not been loaded?
I've implemented repository pattern with two entity managers,
mainManager is for read only and delete, and updateManager is used for edit and add new entities. I use createEmptyCopy() to create updateManager.
Before i update an entity i export the entity from mainManager and import into the updateManager, after the change i call to updateManager.saveChanges() method.
I've noticed that i get back the updated entities in the promise response. i wonder what is the best practice to import those entities back into the mainManager?
here is my code:
function ($q, $http, entityManagerFactory) {
var self = this;
self.mainManager = entityManagerFactory.newManager();
self.updateManager = entityManagerFactory.newManager();
self.saveChanges = function () {
return self.updateManager.saveChanges();
};
self.rejectChanges = function() {
self.updateManager.rejectChanges();
};
self.getDomains = function () {
self.mainManager.clear();
var query = new breeze.EntityQuery()
.from('Domains')
.orderBy('name');
return self.mainManager.executeQuery(query);
};
self.createEmptyDomain = function () {
var domain = self.updateManager.createEntity('Domain');
return domain;
};
self.editDomain = function(domain) {
var exported = self.mainManager.exportEntities([domain]);
return self.updateManager.importEntities(exported).entities[0];
}
self.addDomain = function (domain) {
self.updateManager.addEntity(domain);
return self.updateManager.saveChanges();
};
self.deleteDomain = function (domain) {
domain.entityAspect.setDeleted();
var deferred = $q.defer();
self.mainManager.saveChanges().then(
function(data) {
deferred.resolve(data);
},
function (reason) {
console.log(reason);
self.mainManager.rejectChanges();
deferred.reject(reason);
});
return deferred.promise;
};
}
Right now i'm calling mainManager.clear() and get the data again from the server as you can see above in getDomains function.
But i think this is too expansive, why call the server if i already have the updated entities from the saveChanges promise?
i've also tried to import those entities back to mainManager using:
mainManager.importEntities(data.entities, { mergeStrategy: breeze.MergeStrategy.OverwriteChanges });
but i get an internal null breeze exception:
TypeError: Cannot read property 'forEach' of undefined
at EntityManager.proto.importEntities (breeze.debug.js:13081)
at self.importEntities (domain-list.service.js:22)
at domain-list.controller.js:70
at processQueue (angular.js:13170)
at angular.js:13186
at Scope.promises.$get.Scope.$eval (angular.js:14383)
at Scope.promises.$get.Scope.$digest (angular.js:14199)
at Scope.promises.$get.Scope.$apply (angular.js:14488)
at done (angular.js:9646)
at completeRequest (angular.js:9836)
the error is from this line breeze.debug.js:13081
13080: var tempKeyMap = {};
13081: json.tempKeys.forEach(function (k) {
13082: var oldKey = EntityKey.fromJSON(k, that.metadataStore);
13083: // try to use oldKey if not already used in this keyGenerator. 13084: tempKeyMap[oldKey.toString()] = new EntityKey(oldKey.entityType,
13085: that.keyGenerator.generateTempKeyValue(oldKey.entityType, oldKey.values[0]));
13086: });
var exportData = updateManager.exportEntities(data.entities, false);
mainManager.importEntities(exportData,
{ mergeStrategy: breeze.MergeStrategy.OverwriteChanges });
I need to create an about: page, to display addon options. I have seen ti done before, but there seems to be no option in the SDK that allows you to do that.
Is there another way I could let users type about:pagename and get to my page?
I would prefer not to redirect all tabs with a URL of about:pagename to another options page.
Thanks in advance
This is the index.js file for a restartless add-on developed using jpm:
const { Cc, Ci, Cr, Cu, Cm, components } = require("chrome");
Cm.QueryInterface(Ci.nsIComponentRegistrar);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
// globals
var factory;
const aboutPage_description = 'This is my custom about page';
const aboutPage_id = '6c098a80-9e13-11e5-a837-0800200c9a66'; // make sure you generate a unique id from https://www.famkruithof.net/uuid/uuidgen
const aboutPage_word = 'foobar';
const aboutPage_page = Services.io.newChannel('data:text/html,hi this is the page that is shown when navigate to about:foobar', null, null);
function AboutCustom() {};
AboutCustom.prototype = Object.freeze({
classDescription: aboutPage_description,
contractID: '#mozilla.org/network/protocol/about;1?what=' + aboutPage_word,
classID: components.ID('{' + aboutPage_id + '}'),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
getURIFlags: function(aURI) {
return Ci.nsIAboutModule.ALLOW_SCRIPT;
},
newChannel: function(aURI) {
let channel = aboutPage_page;
channel.originalURI = aURI;
return channel;
}
});
function Factory(component) {
this.createInstance = function(outer, iid) {
if (outer) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return new component();
};
this.register = function() {
Cm.registerFactory(component.prototype.classID, component.prototype.classDescription, component.prototype.contractID, this);
};
this.unregister = function() {
Cm.unregisterFactory(component.prototype.classID, this);
}
Object.freeze(this);
this.register();
}
exports.main = function() {
factory = new Factory(AboutCustom);
};
exports.onUnload = function(reason) {
factory.unregister();
};
Basically it registers a custom about page that will be loaded when you access about:foobar. The loaded page is just a line of text.
This is how it looks like:
You can see a working example here: https://github.com/matagus/about-foobar-addon
I think this is a better solution if you are using the addons-sdk:
Credit goes here:
https://stackoverflow.com/a/9196046/1038866
var pageMod = require("page-mod");
pageMod.PageMod({
include: data.url("options.html"),
...
});
var tabs = require("tabs");
tabs.open(data.url("options.html"));
But there are other ways. You could take a look at the Scroll to Top addon which implements this: https://addons.mozilla.org/firefox/addon/402816
I'm dealing with a huge javascript codebase that I'm trying to reorganize. I'm not really an expert and I just started studying good javascript coding practices. So, one thing I'm trying to do is to divide all the code in modules. In this particular case I'm trying to create a module that would help me to optimize video embeds. I would like to pass the module an id and receive some html code or an image out of it.
I'm not putting the whole code here, but it's enough for the example:
var videoIframe = (function($) {
'use strict';
var id,
setVideoId = function(videoId) {
id = videoId;
console.log(id);
},
getVideoThumbnail = function(videoId) {
setVideoId(videoId);
},
test = function() {
console.log(id)
},
getVideoEmbedCode = function() {
};
return {
test: test,
getVideoThumbnail: getVideoThumbnail
};
})(jQuery);
In another module I assign it to two variables:
var video1 = videoIframe;
var video2 = videoIframe;
video1.getVideoThumbnail(123);
video2.getVideoThumbnail(456);
video1.test();
video2.test();
And, of course, I'm not getting what I expected. After the second getVideoThumbnail call, it always prints 456.
Doing some research I understood that I'm creating a singleton, a single instance, and I'm only changing values inside that instance. I think I need a constructor for my module, but I'm not sure how to create it in combination with the IIFE pattern. And is it the right approach?
And is it the right approach?
No. IIFEs are for things you want to do exactly once.
If you want to do something multiple times, then use a regular function and call it multiple times.
var videoIframe = (function($) {
function videoIframe() {
'use strict';
var id,
setVideoId = function(videoId) {
id = videoId;
console.log(id);
},
getVideoThumbnail = function(videoId) {
setVideoId(videoId);
},
test = function() {
console.log(id)
},
getVideoEmbedCode = function() {
};
return {
test: test,
getVideoThumbnail: getVideoThumbnail
};
}
return videoIframe;
})(jQuery);
var video1 = videoIframe();
var video2 = videoIframe();
video1.getVideoThumbnail(123);
video2.getVideoThumbnail(456);
video1.test();
video2.test();
The problem is that you are initializing object when assigning to videoIframe variable:
var videoIframe = (function($) {
// ...
})(jQuery);
You can try with:
var videoIframe = (function($) {
// ...
});
var video1 = videoIframe(jQuery);
var video2 = videoIframe(jQuery);
Just keep videoIframe as a function that returns your IIFE, instead of reusing the singleton. I kept the IIFE so the id and the inner functions keep being encapsulated and hence, not reachable if they're not in the returned interface object. If you are planning to create alot of these, it might be more efficient to just use a constructor and a prototype, so the inner functions don't get recreated for every instance.
var videoIframe = function() {
'use strict';
return (function() {
var id,
setVideoId = function(videoId) {
id = videoId;
console.log(id);
},
getVideoThumbnail = function(videoId) {
setVideoId(videoId);
},
test = function() {
console.log(id)
},
getVideoEmbedCode = function() {
};
return {
test: test,
getVideoThumbnail: getVideoThumbnail
};
}());
};
I did some minor modification. Hope it will be helpful
var videoIframe = (function($) {
'use strict';
var id;
function _setVideoId(videoId) {
id = videoId;
alert(id);
};
function _getVideoThumbnail(videoId) {
_setVideoId(videoId);
};
function _test(){
console.log(id)
}
function _getVideoEmbedCode() {
};
return {
test: _test,
getVideoThumbnail: _getVideoThumbnail
};
})(jQuery);
Now you can call like this
videoIframe.getVideoThumbnail(123);
videoIframe.getVideoThumbnail(561);
jsfiddle
I am trying using code
// This is an active module of the goelvivek (8) Add-on
exports.main = function() {
var httpRequestObserver =
{
observe: function(subject, topic, data)
{
if (topic == "http-on-examine-response") {
if(console)
console.log(data);
}
}
};
var {Cc, Ci, Cr} = require("chrome");
var observer = require("observer-service");
observerService = Components.classes["#mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
observerService.addObserver(httpRequestObserver, "http-on-examine-response", false);
};
but line console.log(data); is not printing any thing in console log. why ?
In addition to the issue noted by Nickolay, an observer needs to implement a QueryInterface() function (typically by means of XPCOMUtils.generateQI()). Here is how one would do it with the Add-on SDK:
var {Cc, Ci, Cr, Cu} = require("chrome");
var {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var httpRequestObserver =
{
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
...
};
However, since you already require observer-service package, it would be easier to use it:
var observer = require("observer-service");
observer.add("http-on-examine-response", onHttpRequest);
function onHttpRequest(subject, data)
{
...
}
The downside of this approach is that observer-service is an internal package and its API might change in future Add-on SDK versions.
Is it the real snippet? You should see an error about Components being undefined in the Error Console. Either get it from require('chrome') or use the object from require("observer-service").