I am creating a HTML5 SVG editor for Chrome. As a packaged app, I implemented a save dialog using this code:
function prepareExport(){
var svg = document.getElementById("canvas");
svgDoc = svg.children;
var exported = document.querySelector('#canvasWrap').innerHTML;
/*old stuff, does not work in packed apps. well for me anyway
var output = document.querySelector(".opt");
var outputTextarea = document.querySelector(".optText");
output.style.display = "block";
outputTextarea.style.display = "none";
var dlButton = document.querySelector(".dragout");
dlButton.setAttribute("href" ,"data:image/xml+svg;base64," + window.btoa(exported));
dlButton.setAttribute("data-downloadurl" ,dlButton.dataset['downloadurl'] + window.btoa(exported));
dlButton.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('DownloadURL', this.dataset.downloadurl);
}, false);
*/
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry, unused) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob([exported], {type: 'image/svg+xml'}));
}, errorHandler);
});
}
I ran this function using a button, Export SVG, and guess what? the dialog did not appear. I do not know why and this is my javascript console:
http://prntscr.com/1uklw7
This is probably a permission error. Have you added the write filesystem permission to your manifest? See http://developer.chrome.com/apps/fileSystem.html for details.
If that isn't the problem, you can get more details from chrome.lastError in your callback. See http://developer.chrome.com/apps/runtime.html#property-lastError for details of this.
Also you might want to check out the file system sample: https://github.com/GoogleChrome/chrome-app-samples/tree/master/filesystem-access.
Related
I have created a simple extension in autodesk forge.
The idea is that when I make a mouse-over event on a 3D object it has to show me the ID of the hovered object/sub-object my extension code runs like this.
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
Autodesk.ADN.Viewing.Extension.MouseEvent = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _self = this;
var _viewer = viewer;
var _selectedId = null;
//On Load of the exension function
_self.load = function () {
_viewer.addEventListener(
Autodesk.Viewing.MOUSE_OVER_EVENT,
_self.onMouseOver);
console.log("Autodesk.ADN.MouseEvent loaded");
return true;
};
//On unload of the exension function
_self.unload = function () {
_viewer.removeEventListener(
Autodesk.Viewing.MOUSE_OVER_EVENT,
_self.onMouseOver);
console.log("Autodesk.ADN.MouseEvent unloaded");
return true;
};
// Event function initialization
_self.onMouseOver = function (event) {
var dbId = event.dbIdArray[0];
if (typeof dbId !== 'undefined') {
_selectedId = dbId;
alert('ID: ' + _selectedId);
}
else _selectedId = null;
}
};
Autodesk.ADN.Viewing.Extension.MouseEvent.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.MouseEvent.prototype.constructor =
Autodesk.ADN.Viewing.Extension.MouseEvent;
Autodesk.Viewing.theExtensionManager.registerExtension(
'Autodesk.ADN.Viewing.Extension.MouseEvent',
Autodesk.ADN.Viewing.Extension.MouseEvent);
but the onMouseOver function is not working, can anyone please help me? thanks in advance.
PS: I have included the extensions in the script tags and the extension is loaded likewise.
oViewer.loadExtension('Autodesk.ADN.Viewing.Extension.MouseEvent');
I also get a confirmation from the console that the extension is loaded successfully.
There is no such event as Autodesk.Viewing.MOUSE_OVER_EVENT ... did you just made that up or you got it from some - apparently incorrect - source?
The way to handle that would be to use a viewer tool (see that post for details), then in handleMouseMove callback, do the following:
handleMouseMove (event) {
var hitTest = _self.viewer.clientToWorld(
event.canvasX,
event.canvasY,
true)
if (hitTest) {
console.log(hitTest)
}
}
Here is another post I wrote about viewer events, it is a bit old, so there are a couple more now but can give you a good starting point.
I am getting a TypeError: tracking.MyTracker is not a constructor error in the console while running the custom tracker example from the tracking.js website. What am I missing. I looked up but it doesn't seem to be a problem for anybody else. I am on chromium 51, via localhost. I have included the tracking-js.min.js file version 1.1.2
window.onload = function () {
var img = document.getElementById('img');
var MyTracker = function() {
MyTracker(this, 'constructor');
}
MyTracker = function() {
MyTracker.prototype.track = function(pixels, width, height) {
// Your code here
this.emit('track', {
// Your results here
});
}
}
tracking.inherits(MyTracker, tracking.Tracker);
var myTracker = new tracking.MyTracker();
myTracker.on('track', function(event) {
console.log(event);
});
tracking.track(img, myTracker);
}
What am I doing wrong? The error is on the var myTracker = new tracking.MyTracker(); line. Strangely, I have just copied it from the website's custom tracker example code.
Thanks.
I created a Firefox add-on, the point is that Youtube is built into the side and adds an extra button.
A key role is just enough to redirect to another page of youtube link.
The problem is that when changing the youtube video url does not change, but remains above the header change, but not the button.
You can, however, be updated properly when I update the page (F5).
What I mean is that the supply is not updated during its navigation on Youtube.
Here is the content of the file main.js which invite the executive file:
var pageMod = require("page-mod");
var self = require("self");
pageMod.PageMod({
include: "*.youtube.com",
contentScriptFile: self.data.url("youtube.js")
});
My question is, how should it be changed so that during navigation in the Youtube freshen the accessories as well?
Thanks in advance!
Best Regards
Davee
I copied my code currently looks like this, but unfortunately if there is for the code snippet does not work.
think so?
main.js:
var pageMod = require("page-mod");
var self = require("self");
pageMod.PageMod({
include: "*.youtube.com",
contentScriptFile: self.data.url("youtube.js")
});
var progListener = {
onLocationChange: function (aProgress, aRequest, aURI, aFlags) {
Cu.reportError('location changed!');
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
Cu.reportError('anchor clicked!');
} else {
return
}
var domWin = aProgress.DOMWindow;
var domDoc = domWin.document;
if(!domDoc) {
Cu.reportError('document not loaded yet');
return;
}
}
}
Services.wm.getMostRecentWindow('navigator:browser').gBrowser.addProgressListener(progListener);
you have to use onLocationChange
var progListener = {
onLocationChange: function (aProgress, aRequest, aURI, aFlags) {
Cu.reportError('location changed!');
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
Cu.reportError('anchor clicked!');
} else {
return
}
var domWin = aProgress.DOMWindow;
var domDoc = domWin.document;
if(!domDoc) {
Cu.reportError('document not loaded yet');
return;
}
}
}
browserDOMWindow.gBrowser.addProgressListener(progListener);
Hey #Davee I think i figured this out. Actually youtube is using pushtate stuff.
Did you ever figure it out? See this topic here: Chrome extension is not loading on browser navigation at YouTube
I had been able to do this up until Firefox 15 using:
netscape.security.privilegeManager.enablePrivilege("UniversalXPConnect")
and setting the signed.applets.codebase_principal_support option to true. Unfortunately as of FF 17 this functionality has been removed. From what I understand Chrome has been the same way for some time now.
Does anyone know if there has been a Firefox or Chrome extension created that allows for the use of enablePrivilege? If not, recommendations on where to start if building my own?
File API, the reason those have stopped working is because both have now implemented the html5 file api.
Here is a html5 demo of the api.
Here is the relevant script in case they remove the demo:
<script>
var holder = document.getElementById('holder'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
console.log(event.target);
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
console.log(file);
reader.readAsDataURL(file);
return false;
};
</script>
As a note: if you need to access a file on your local machine in chrome you need to run the program using this switch --allow-file-access-from-files (for using a file input without it actually loading to the server, otherwise you get a xhr cross-domain error).
I don't know of the equivalent in firefox.
We have an app that records audio, making use of the PhoneGap Media API and in iOS's case the File API.
When the user clicks the Accept & Upload button, the app moves that file to the server making use of PhoneGap's File.FileTransfer() method.
Works well with iOS, Android not so much.
When I connect my Android device to my computer and mount as a drive, I can see that the file is getting created at the root which is where it should be.
After the audio file has been created, I'm able to play the file on my device from the location stored in the global var fullRecordPath which = recording.wav
When I attempt to point File.FileTransfer() at that came path I'm getting Error Code = 1 which I understand is File Not Found
Code Handling the Accept & Upload tap event:
$('#btnAcceptUpload').live('tap',function () {
if(isIOS){
thisFileToUpload = fullRecordPath;
} else {
// thisFileToUpload = './'+fullRecordPath; //doesn't work
// thisFileToUpload = 'file:///'+fullRecordPath; //doesn't work
thisFileToUpload = fullRecordPath; //doesn't work
}
var options = new FileUploadOptions();
msg = '';
options.fileKey="file";
msg += "options.fileKey = "+options.fileKey+"\n";
options.fileName=thisFileToUpload.substr(thisFileToUpload.lastIndexOf('/')+1);
msg += "options.fileName = "+options.fileName+"\n";
options.mimeType='audio/wav';
options.chunkedMode = false;
msg += "options.mimeType = "+options.mimeType+"\n";
msg += "thisFileToUpload = "+thisFileToUpload;
alert(msg);
var ft = new FileTransfer();
ft.upload(thisFileToUpload, "http://10.0.17.121/~email/ttmovefiles.php", fileUploadSuccess, fileUploadFailure, options);
});
Success Callback:
function fileUploadSuccess(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
alert(r.response);
}
Failure Callback:
function fileUploadFailure(error){
alert("An error has occurred: Code = " + error.code);
}
Thanks for looking.
Alright, alright. I figured this one out. I promise I'll come back through and tighten this one down later, but wanted to get it documented so I might end helping another.
in iOS to create a new piece of media you have no choice, you gotta use the File api. This same fully qualified spot in the filesystem was moved in to the same global var which the Media.play() method played nicely with... in iOS.
Not sure why it works this way, but with Android, Media.play() doesn't like the fully qualified path passed in to it. It just wants the filename and it apparently searches from the root.
File.FileTransfer.upload() always wants the fully qualified path of the asset to upload, regardless iOS or Android.
To Make this work:
I used the File API to create the file that the audio Media then uses to move the recording in to. I set 2 global vars: one for playing the audio on the device fullRecordPath and the other for uploading fullUploadPath.
Here's the function the creates the file, invokes the media API and sets the global vars that Android wants:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
fileSystem.root.getFile(recordFileName, {
create: true,
exclusive: false
}, function(fileEntry){
alert("---------> Android File " + recordFileName + " created at " + fileEntry.fullPath);
fullRecordPath = recordFileName;
fullUploadPath = fileEntry.fullPath;
mediaVar = new Media(recordFileName, function(){
alert("Android media created successfully");
}, androidMediaCreateFailure, mediaStatusCallback); //of new Media
onMediaCreated();
}, androidMediaCreateFailure); //of getFile
}, androidMediaCreateFailure); //of requestFileSystem
Here's the code to play that media back
function playAudio() {
var my_media = new Media(fullRecordPath,
// success callback
function () {
console.log("playAudio():Audio Success");
},
// error callback
function (err) {
console.log("playAudio():Audio Error: " + err.code);
exposeObject(err);
});
my_media.play();
}
Here's the code to upload
$('#btnAcceptUpload').live('tap',function () {
if(isIOS){
thisfullUploadPath = fullRecordPath;
} else {
thisfullUploadPath = fullUploadPath;
}
var options = new FileUploadOptions();
msg = '';
options.fileKey="file";
msg += "options.fileKey = "+options.fileKey+"\n";
options.fileName=thisfullUploadPath.substr(thisfullUploadPath.lastIndexOf('/')+1);
msg += "options.fileName = "+options.fileName+"\n";
options.mimeType='audio/wav';
options.chunkedMode = false;
msg += "options.mimeType = "+options.mimeType+"\n";
msg += "thisfullUploadPath = "+thisfullUploadPath;
alert(msg);
var ft = new FileTransfer();
ft.upload(thisfullUploadPath, "http://10.0.17.121/~email/ttmovefiles.php", fileUploadSuccess, fileUploadFailure, options);
});
On android you need to resolveFileSystem
window.resolveLocalFileSystemURI(FILEURI, function(msg){
// success call msg.fullPath
}, function(){
// FAIL
});