Firebreath Object in AngularJS - javascript

I have tried to include a FireBreath plugin object in an AngularJS view, however when I try to render the view I get this error:
TypeError: Cannot read property 'nodeName' of undefined
I am able to successfully include the object in the view with $compile like this:
$("body").append($compile('<object id="plugin" type="application/x-firebreathplugin" width="0" height="0></object>')($scope));
However, after including the object like this I cannot get my plugin to fire an event in the JS.
Doing something like this:
plugin = document.getElementById('plugin');
console.log(plugin);
Returns
TypeError
In the Chrome console. But I can still do:
plugin.callFunction();
And have a FireBreath method execute. The issue is when I try to get an event to fire in the JS. No matter what I try, I cannot get the event to fire. So this code will never execute:
var addEvent = function(obj, name, func) {
obj.addEventListener(name, func, false);
}
addEvent(document.getElementById('plugin'), 'firebreathEvent', function(data) {
console.log('data ' + data);
});
var plugin = document.getElementById('plugin');
plugin.functionThatTriggersFireBreathEvent();
Does anybody know if it has something to do with accessing the object after calling $compile? I noticed that in regular HTML (before using AngularJS) logging the plugin in the console returns this :
<JSAPI-Auto Javascript Object>
So I am thinking that whatever I am getting with document.getElementById after using $compile is not the same.
What would be easier is is if I could just include the <object> tag in the view.html file and have it display in <body class='ng-view'> but I get the top TypeError, so if anyone has any ideas for that, that would be preferred.
Any help is appreciated. Thanks.

If anyone is interested, because I could not get the event to fire, I followed along to this link:
http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/
(which I think is your blog #taxilian) to get the data back to the JS.
Plugin Code: Great example in the link.
JS Code:
//attach FireBreath Object to AngularJS View
$("body").append($compile('<object id="plugin" type="application/x-firebreathplugin" width="1" height="1"><param name="onload" value="pluginLoaded"/></object>')($scope));
var callback = function(data) {
//data is an object
console.log(data.resultFromFireBreath);
}
plugin = document.getElementById("plugin");
plugin.getData(callback);
This will have to work for now until someone can figure out how to attach an event to the plugin object after $compile.

I ran into the same problem and was able to make the problem go away by creating a read-only nodeName property in my plugin object. I asked about this in a firebreath forum post and taxilian suggested adding this to JSAPIAuto.cpp, which also worked, so I submitted a pull request with the change.

I once spent about 6 hours trying to make FireBreath plugins work with jquery; it was really educational, but ultimately I determined that it wasn't worth the work.
Long story short is that it's not worth it; particularly since even if you could make it work, it would break on IE9 where FireBreath doesn't support addEventListener (IE never gives it the even info, so it's a little hard to support) and you would need to use attachEvent anyway.

Related

TypeError: this._url is undefined at Dojo FilteringSelect onChange callback

I keep getting following error: TypeError: this._url is undefined at the callback of a Dojo FilteringSelect.
I simplified my code to this:
var testFeatures = [
{ "id": 1, "Adresa": "Pyšvejcova 6, Kotěhůlky"},
...
];
var filteringSelect = new FilteringSelect({
id: "testSelect",
autoComplete: false,
searchAttr: "Adresa",
store: new Memory({ data: testFeatures }),
onChange: this.onSelected
}, "testSelect");
filteringSelect.startup();
//end of the function, still in the same define callback
onSelected: function () {
//custom processing
var queryTask = new esri.tasks.QueryTask(this.serviceUrl);
var query = new esri.tasks.Query();
query.outFields = ["OBJECTID"];
query.where = "Adresa=" + dojo.byId("testSelect").value;
query.returnGeometry = true;
queryTask.execute(query, this.zoomToSelected);
}
zoomToSelected: function (featureSet) {
//custom map processing
}
and HTML:
<input id="testSelect" data-dojo-attach-point="testSelect" />
I have no idea where's the problem, Google found no case similar to mine. FireBug says the error occurs in init.js. Console says line 199, but the code in question (...nction(){},onExecuteForCountComplete:function(){},onExecuteForExtentComplete:fun...) is on line 256.
One possible cause of problems might be ArcGIS JavaScript API or Web AppBuilder - this seems not to be one of the "ArcGIS-heavy" parts of the code, but I don't know for sure. It's ArcGIS JS API 3.15 (Dojo 1.10) and Web AppBuilder for developers version 1.4.
EDIT: with help of #KenFranqueiro and this post I made some progress. I can't say that I fully understand the onChange callbacks, but I learnt to omit the parentheses while calling a named function. The onSelected still wasn't called, but modifying the input data to include id solved this. But it didn't solve the main problem...
Now the old good TypeError: this._url is undefined occurs at queryTask.execute, or between it and start of zoomToSelected method. The exact place where the error occurs changed to line 256, column 351, with following referenced code:
...e:function(a,b,c,d,f){var m=f.assembly;a=this._encode(n.mixin({},this._url.query...
There is a pointer at the = after "a", so the error seems to be to the right of it, trying to mixin something non-existent to something else. I have no idea what the this in the init.js should mean. Unfortunately, dojo core code is almost undebuggable without some de-obfuscation. Is this my only option, or does anybody know how to solve it?
So debugging the init.js wasn't so hard, it takes QueryTask as this. As far as I know, this shouldn't have a _url attribute. So I must have some mistake in the queryTask as well.
Obsolete part of the question, archived:
I wonder whether the problem might be caused by the onChange callback's argument, which I don't really understand. I've read several examples of Dojo FilteringSelect with onChange event set, like the official one. Usually it has some argument, but I don't know what does it mean and where it gets from. In the official example it corresponds to the div id and nothing else. However, how is the id translated to a variable and even whether my assumption that it's the id is correct. The detailed documentation is not much helpful in this case.
Older EDIT: testSelect is an object. Seems it was created implicitly with the dom - it's a childnode of this.domNode. So now I understand where it comes from, but not how to prepare another function to be called on change and why the correct syntax is what it is.
Also, I don't know where exactly is the problematic undefined this._url supposed to exist. In my example, this refers to the dijit, but I have no idea what is the scope of the part of init.js where the problem occurs.
I'm not sure how much related are the two subquestions (confusion in the onChange callback and identification of this in init.js), I only suppose they are symptoms of the same issue since the error is thrown at the onChange event in my code.
The problem at the query was caused by this.serviceUrl either missing as a part of wrong coontext, or being an object instead of a URL string. So the final step was to make sure the correct context is used (by lang/hitch) and then setting this.serviceUrl to be what I originally thought, one of the attributes of the object referenced as serviceUrl before.

Parse.View.extend - "cannot read property 'extend' of undefined"

Currently using the Parse JavaScript SDK for a web app, but I'm also new to Backbone, and since this particular problem is in functionality that Parse copied over from Backbone, I'm not sure exactly where I'm making my mistake.
I have index.html, with this basic structure & script template tag (to be used by _underscore):
<div id="my-app">
</div>
<script type="text/template" id="album-header-template">
<div id="some-id">
Some Content
</div>
</script>
At the end of <body>, the following script tags, to take care of Parse dependencies, load Parse, & use my own JS file:
<script src="libraries/node_modules/jquery/dist/jquery.min.js"></script>
<script src="libraries/node_modules/underscore/underscore-min.js"></script>
<script src="libraries/node_modules/parse/dist/parse-latest.min.js"></script>
<script src="app/ParseApp.js"></script>
Then in ParseApp.js, where I am trying to get off the ground by creating simple objects and views, I have the following:
$(function () {
var Album = Parse.Object.extend("Album",{
// Default attributes for the album
defaults: {
name: "Album Title"
},
// Ensure that each album created has a title
initialize: function() {
if (!this.get("name")) {
this.set({"name": this.defaults.content});
}
},
});
var HomeView = Parse.View.extend({
el: $("#my-app"),
initialize: function() {
console.log("new instance of HomeView");
this.render();
},
render: function() {
this.$el.html(_.template($("#album-header-template").html()));
}
});
new HomeView;
});
When I run index.html in the browser, I get the following error in console: Uncaught TypeError: Cannot read property 'extend' of undefined (occurring at the var Home View = Parse.View.extend line).
Originally, I had thought this might be because Parse wasn't initiated in time for ParseApp.js to use it, based on my scripts loading. However, I ran the recommended "Test the SDK" script from Parse, and it's indeed initialized (in addition, adding an object with var Album works fine). So I'm really stuck on what's causing either HomeView or Parse.View to be "undefined".
Likely a straightforward answer that I'm overlooking, but any help would be greatly appreciated, and I could provide full files if need be.
Not a very satisfying answer, but thanks to the help from #Yura & #Daniel Blank, discovered that the error was resulting because the most recent versions of the Parse SDK (everything after 1.6.0) no longer include full Backbone functionality. This includes the version I had been using locally from npm.
The best explanation of the Parse SDK direction is in the link given above, and there seem to be three options, for those hoping to continue using Parse and/or Backbone:
Use an old version (1.5.0 being the most recent that includes Backbone functionality) in order to maintain your Backbone functions, such as Parse.Collection or Parse.Router.
Try going Parse SDK-agnostic, while continuing to use Backbone. Can use the basic Parse REST API, or try one of the GitHub projects attempting to do that linking for you.
Give up on Backbone going forward, and use Parse with VanillaJS, or perhaps switch over to React (which is obviously the direction Facebook would want Parse to head)
I'm too inexperienced to recommend one of the three, although #1 seems the easiest, while #3 seems far and away the most maintainable. Still trying to make my own decision, but that's outside the scope of my original question. Thanks for the help, everyone.
2 things jump out at me:
I don't see where you initialize Parse... typically that
produces a different error, but still might be an issue
You are referencing your own local library for Parse... maybe try targeting the officially deployed version.
script src="http://www.parsecdn.com/js/parse-1.2.13.min.js"

how to obtain a reference to the lite plugin object for ckeditor

Beginning web developer here, bear with me, I realize this question is simplistic.
I am trying to use the LITE plugin for ckeditor. In the documentation (http://www.loopindex.com/lite/docs/) they say that in order to get a reference to the lite plugin object I need to
"To interact with the lite plugin, you need to obtain a reference to the actual plugin object which is unique for each instance of CKEditor. The safest way to do this is by listening to the event LITE.Events.INIT fired by the editor instance. The data member of the event will contain a property called lite which references the lite plugin instance, initialized and ready for action."
How do I do this?
Is it something like:
LITE.Events.INIT(data) {
//desired functionality here
}
or is it:
LITE.Events.INIT.addEventListener (function (data) {//desired functionality here})
Thanks in advance.
Hard to say without having access to the plugin, but according to the documentation this should work:
editor.on( LITE.Events.INIT, function( evt ) {
// The instance should be somewhere in:
evt.data;
} );
Note that LITE.Events.INIT is a constant which keeps the name of Lite's event name. It's not a name of the event.

Receive EntryChangedEvent on folder

Currently i'm experementing with the the chrome.fileSystem-Api and i was curious about the new EntryChangedEvent that was added in Version 38. But im writing because i do not really know how to receive this event in my app. I tried it like this, what obviously didn't worked :
chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(folder) {
if (!folder) {
output.textContent = 'No Folder selected.';
return;
}
folder.on("entrychangedevent",function(v){
console.log(v);
});
});
How do i have to change my code so that i really can use receive EntryChangedEvents?
Thanks!
Link to documentation:
https://developer.chrome.com/apps/fileSystem#type-EntryChangedEvent
I actually think that this feature is not implemented yet. I don't know why it is in the documentation, but if you look at the chromium source there is a function called chrome.fileSystem.observeDirectory (which has a callback that should get these events) but when looking at the implementation it just says:
bool FileSystemObserveDirectoryFunction::RunSync() {
NOTIMPLEMENTED();
error_ = kUnknownIdError;
return false;
}
I found this document which is a request for the API:
https://docs.google.com/document/d/1aW-37JOBZgoD2CIPvoBEgw6bog8gFSowpfqtDEKt5Vo/edit#heading=h.w8inspeo32bj
Anyways, great feature and will probably be available soon.
Three issues here:
It's not clear from the documentation what object this listener should be attached to. In your example, you have attached it to the DirectoryEntry representing a directory. While I don't know the answer, that sounds like it's probably wrong, as a DirectoryEntry is only a means for accessing a directory, and is not itself a directory.
The documentation says that this event is fired for only certain filesystems, and I guess neither of us knows whether it is even effective for whatever file systems we're testing with.
In your example, even if the code were right and the event were enabled, you don't have any changes to the directory, so the event wouldn't fire.

How can I use jQuery 1.5.2+ on a Firefox addon?

At first I made a function that received a parameter and returned jQuery such as:
function getjQuery(window)
{
/*jquery code*/(window);
return window.jQuery;
}
But then I got an email form the review and they told me I have to use jQuery file with the original file name and completely unmodified.
I started to search for an alternative and found this solution, but there is no way it work.
jQuery object is created, but I can't find any elements. $("#id").length is always 0. With the previous method it was always found.
My current code (which doesn't work)
AddonNameSpace.jQueryAux = jQuery;
AddonNameSpace.$ = function(selector,context) {
return // correct window
new AddonNameSpace.jQueryAux.fn.init(selector,context||contentWindow);
};
AddonNameSpace.$.fn =
AddonNameSpace.$.prototype = AddonNameSpace.jQueryAux.fn;
AddonNameSpace.jQuery = AddonNameSpace.$;
The jQuery file is loading on my browser.xul overlay:
<script type="text/javascript" src="chrome://addon/content/bin/jquery-1.5.2.min.js" />
Am I loading in the right place?
How can I use jQuery to modify the content on a page (HTML) with the original jQuery file, is it even possible?
You need pass the e.originalTarget.defaultView on the second parameter on jquery..
If you don't jquery will use window.document, which is the window.document from the xul.
Use
gBrowser.addEventListener("DOMContentLoaded", function (e) {
$("#id", e.originalTarget.defaultView).length
}, true);
instead of
$("#id").length;
And, for avoid conflicts with other extensions don't use script in the xul page, use MozIJSSubScriptLoader.
Components.classes["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript("chrome://youraddon/content/jquery-1.5.2.min.js");
If you use this method, you load jquery only when you need, avoiding memory leak.
The preferred way to load it is with mozIJSSubScriptLoader so you don't collide with other's extensions. I'm not sure why you're having problems, I can use jQuery in my addon like $("#id").hide() with no additional code (although from the sidebar, now browser.xul).
Either way, this blog post provides a pretty good guide and even has an example xpi to download.

Categories