how can you use oncanplaythrough after a setimeout? - settimeout

i assume this doesn't work because canplaythrough is fired too early?
function splasher() {
showDelay = setTimeout(vidCheck, 6000);
};
function vidCheck() {
vid.addEventListener("canplaythrough", showPage);
};

Related

Why doesn't the callback function runs in this code?

I've been trying to run the following code but only the second function runs and the first one does not execute. Can anyone please let me know what's wrong.
function first() {
setTimeout(function(){
console.log(1);
}, 500 );
};
function second(first) {
console.log(2);
};
second();
What I'm expecting is that the program first displays 1 after 500ms and then 2.
What you expect :
function first() {
setTimeout(function(){
console.log(1);
second();
}, 500 );
};
function second() {
console.log(2);
};
first();
Your 'first' parameter in the second function does nothing. Instead you can do this too :
function first(callback) {
setTimeout(function(){
console.log(1);
callback();
}, 500 );
};
function second() {
console.log(2);
};
first(second);
I think this is the effect you're trying to achieve. first accepts a callback function as a parameter. It then needs to be called somewhere inside of the first function.
function first(callback) {
setTimeout(function() {
console.log(1);
callback(); // Calling the passed function
}, 500);
};
function second() {
console.log(2);
};
first(second); // Passing the 'second' function as a callback
you just called second. you most call first for callback funtion for you expectation your code shoould be like this
function second() {
setTimeout(function(){
console.log(2);
}, 500 );
};
function first() {
console.log(1);
second();
};
first();

With Chrome FileSystem, let the user choose a Directory, load files inside. And save files in that directory without prompting again

I could not found any examples with this scenario so here we go:
I want the user choose a directory, load all files inside it, change them, and save this file overriding it or saving a new file in that same directory without asking where he want to save.
I don't know how to list the files of the directory
I don't know how to save a file in a directory without prompting the filechooser window
I believe it is possible because I see something similar here (last paragraph):
http://www.developer.com/lang/using-the-file-api-outside-the-sandbox-in-chrome-packaged-apps.html
Any answer will be appreciated, Thank you
EDIT: Thanks to Chris Johnsen for giving me this great answer:
var fileHandler = function() {
var _entry = null;
this.open = function(cb) {
chrome.fileSystem.chooseEntry({
type: 'openDirectory'
}, function(dirEntry) {
if (!dirEntry || !dirEntry.isDirectory) {
cb && cb(null);
return;
}
_entry = dirEntry;
listDir(_entry, cb);
});
};
this.save = function(filename, source) {
chrome.fileSystem.getWritableEntry(_entry, function(entry) {
entry.getFile(filename, {
create: true
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(new Blob([source], {
type: 'text/javascript'
}));
});
});
});
};
this.saveAs = function(filename, source) {
chrome.fileSystem.chooseEntry({
type: 'openDirectory'
}, function(entry) {
chrome.fileSystem.getWritableEntry(entry, function(entry) {
entry.getFile(filename, {
create: true
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(new Blob([source], {
type: 'text/javascript'
}));
});
});
});
});
};
var listDir = function(dirent, cb, listing) {
if (listing === undefined) {
listing = [];
}
var reader = dirent.createReader();
var read_some = reader.readEntries.bind(reader, function(ents) {
if (ents.length === 0) {
return cb && cb(listing);
}
var process_some = function(ents, i) {
for (; i < ents.length; i++) {
listing.push(ents[i]);
if (ents[i].isDirectory) {
return listDir(ents[i], process_some.bind(null, ents, i + 1), listing);
}
}
read_some();
};
process_some(ents, 0);
}, function() {
console.error('error reading directory');
});
read_some();
};
};
Your save method should work fine (mostly, see below) for your second requirement (write to a code-chosen filename without another user prompt), but there are a couple of bugs in open (at least as presented in the question):
Inside the chooseEntry callback, this !== fileHandler because the callback is invoked with a different this (probably the background page’s window object).
You can work around this in several ways:
Use fileHandler instead of this (if you are not using it as any kind of prototype).
Use .bind(this) to bind each of your callback functions to the same context.
Use var self = this; at the top of open and use self.entry (et cetera) in the callbacks.
You may want to call cb for the success case. Maybe you have another way of postponing calls to (e.g.) fileHandler.save (clicking on some element to trigger the save?), but adding something like
⋮
cb && cb(self.entry);
⋮
after self.entry = dirEntry makes it easy to (e.g.) chain open and save:
fileHandler.open(function(ent) {
fileHandler.save('newfile','This is the text\nto save in the (possibly) new file.');
});
There is a latent bug in save: if you ever overwrite an existing file, then you will want to call writer.truncate() (unless you always write more bytes than the file originally held).
⋮
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(…);
⋮
It looks like you have a good start on the file listing part. If you want to reference the list of files later, then you might want to save them in your object instead of just logging them; this can get a bit hairy if you want to recurse into subdirectories (and also not assume that readEntries returns everything for its first call).
function list_dir(dirent, cb, listing) {
if (listing === undefined) listing = [];
var reader = dirent.createReader();
var read_some = reader.readEntries.bind(reader, function(ents) {
if (ents.length === 0)
return cb && cb(listing);
process_some(ents, 0);
function process_some(ents, i) {
for(; i < ents.length; i++) {
listing.push(ents[i]);
if (ents[i].isDirectory)
return list_dir(ents[i], process_some.bind(null, ents, i + 1), listing);
}
read_some();
}
}, function() {
console.error('error reading directory');
});
read_some();
}
You could use it in the open callback (assuming you add its success callback) like this:
fileHandler.open(function(ent) {
ent && list_dir(ent, function(listing) {
fileHandler.listing = listing;
console.log('listing', fileHandler.listing.map(function(ent){return ent.fullPath}).join('\n'));
fileHandler.save('a_dir/somefile','This is some data.');
});
});

Mootools class: call a class method from an event handler

is it possible to call a class method from within an event handler?
I mean, something like this:
initialize: function(options) {
/* initial options */
this.setOptions(options);
this.area = (this.options.status == 'out') ? $(this.options.loggedoutArea) : $(this.options.loggedinArea);
this.button = $(this.options.buttonArea);
this.button.addEvent('click', function(){
this.showHideBanner();
});
},
showHideBanner: function() {
this.area.setStyle('display', 'none');
},
see full example here http://jsfiddle.net/dvzj6/
I managed to find a solution using this code:
initialize: function(options) {
/* initial options */
this.setOptions(options);
this.area = (this.options.status == 'out') ? $(this.options.loggedoutArea) : $(this.options.loggedinArea);
this.button = $(this.options.buttonArea);
this.button.addEvent('click', function(){
this.showHideBanner();
}.bind(this));
},
see also: http://jsfiddle.net/uA3Ak/

for loop not waiting for function to end

I have 5 links on a page and i have to check if all are links are working or not. Here is the code
// iterate through each link and check if ti works.
for(var i=0; i < 5; i++) {
var ifLinkWorks = verifyLinkWorks(links[i]);
if(ifLinkWorks){ OK }
else{ error }
}
This is verifyLinkWorks function. It opens a link. After it get opened, it checks if the page is loaded properly
function verifyLinkWorks(link) {
return winjs.Promise(function(complete) {
link.click();
// wait for page to load
return winjs.promise.timeout(4000).then(function () {
// check if page is loaded
var islinkOK = IsPageLoaded();
complete(islinkOK); // i want verifyLinkWorks to return this value
});
});
}
After reaching link.click(), it is not waiting for page to load. Instead it jumps to the if condtion in outer for loop (which makes linkWorks = undefined therefore,gives Error). How to make it wait in the verfifyLinkWorks function.
Thanks in advance...
You'll need to wait for the results of each promise, either all at once, or individually. As the actions are all async in nature, the code can't wait, but it can call a function when it completes all of the work.
Here, I've created an array which will hold each Promise instance. Once the loop has completed, the code waits for all to complete, and then using the array that is passed, checking the result at each index.
// iterate through each link and check if it works.
var verifyPromises = [];
for(var i=0; i < 5; i++) {
verifyPromises.push(verifyLinkWorks(links[i]));
}
WinJS.Promise.join(verifyPromise).done(function(results) {
for(var i=0; i < 5; i++) {
var ifLinkWorks = results[i];
if (ifLinkWorks) { /* OK */ }
else { /* error */ }
}
});
In case the link.click() call fails, I've wrapped it in a try/catch block:
function verifyLinkWorks(link) {
return WinJS.Promise(function(complete, error) {
try {
link.click();
} catch (e) {
complete(false); // or call the error callback ...
}
// wait for page to load, just wait .. no need to return anything
WinJS.Promise.timeout(4000).then(function () {
// check if page is loaded
var islinkOK = IsPageLoaded();
// finally, call the outer promise callback, complete
complete(islinkOK);
});
});
}
If you want to check the validity of a URL, I'd suggest you consider using WinJS.xhr method to perform a HEAD request instead (rfc). With each link variable, you can use a timeout to validate that there's a reasonable response at the URL, without downloading the full page (or switch to a GET and check the response body).
WinJS.Promise.timeout(4000,
WinJS.xhr({
type: 'HEAD',
url: link
}).then(function complete(result) {
var headers = result.getAllResponseHeaders();
}, function error(err) {
if (err['name'] === 'Canceled') {
}
if (err.statusText) {
}
})
);
Ok heres the link to the msdn code sample for win js promise object.
Promise winjs
now going through the code
<button id="start">StartAsync</button>
<div id="result" style="background-color: blue"></div>
<script type="text/javascript">
WinJS.Application.onready = function (ev) {
document.getElementById("start").addEventListener("click", onClicked, false);
};
function onClicked() {
addAsync(3, 4).then(
function complete(res) {
document.getElementById("result").textContent = "Complete";
},
function error(res) {
document.getElementById("result").textContent = "Error";
},
function progress(res) {
document.getElementById("result").textContent = "Progress";
})
}
function addAsync(l, r) {
return new WinJS.Promise(function (comp, err, prog) {
setTimeout(function () {
try {
var sum = l + r;
var i;
for (i = 1; i < 100; i++) {
prog(i);
}
comp(sum);
}
catch (e) {
err(e);
}
}, 1000);
});
}
</script>
you will see the addAsync(3,4).then() function. So all the code is to be kept inside that function in order to have a delayed response . Sorry m using a tab so cannot write it properly.
Also go through link then for winjs promise

Passing stored selector to function - efficiency

I'm storing selectors in two variables. If I create them globally and use in function, duration of operation is about 0.2s
window.$my = {
nameEdit : $('#nameEdit'),
nameError : $('#nameError')
};
function Validation() {
console.profile();
var result = true;
if ($my.nameEdit.val() == '') {
$my.nameEdit.addClass('error');
$my.nameError.css({ 'display': 'block' });
}
else {
$my.nameEdit.removeClass('error');
$my.nameError.css({'display':'none'});
}
console.profileEnd();
}
If I'm binding another function in Validaton() and try to use them i this function, it takes too long (about 0.6s):
window.$my = {
nameEdit : $('#nameEdit'),
nameError : $('#nameError')
};
function Validation() {
$my.nameEdit.blur(function (evt) { ValidateName(evt); });
}
function ValidateName(evt) {
console.profile();
if ($my.nameEdit.val() == '') {
$my.nameEdit.addClass('error');
$my.nameError.css({ 'display': 'block' });
}
else {
$my.nameEdit.removeClass('error');
$my.nameError.css({'display':'none'});
}
console.profileEnd();
}