Issue with Google Gears and jQuery creating a managedStore - javascript

I'm trying to create a managedStore to cache all the js, img, swf and css from a web app I'm developing.
Here is the code:
$(document).ready(function() {
var manifestName = 'cache_manifest.json';
var storeName = 'cache';
var localServer;
var localStore;
if (window.google && google.gears) {
localRequest = google.gears.factory.create('beta.httprequest');
localServer = google.gears.factory.create('beta.localserver');
localStore = localServer.openManagedStore(storeName);
isServerAvailable();
$("#separator").text(' | ');
if (!localStore) {
localStore = localServer.createManagedStore(storeName);
localStore.manifestUrl = manifestName;
localStore.onerror = $('#offline').text('Error con el cache');
localStore.oncomplete = $('#offline').text('Cache activado');
localStore.onprogress = $('#offline').text(Math.ceil(((event.filesComplete / event.filesTotal) * 100)) + "%");
localStore.checkForUpdate();
}
else {
$('#offline').text('Cache activado');
}
}
});
However, localStore.onerror always get's triggered.
I have to questions:
Any ideas what's going wrong?
How can I see what's the actual error ( alert(localStore.onerror) won't work)
Regards,

try
if (!localStore) {
localStore = localServer.createManagedStore(storeName);
localStore.manifestUrl = manifestName;
localStore.onerror = function(){$('#offline').text('Error con el cache');}
localStore.oncomplete = function(){$('#offline').text('Cache activado');}
localStore.onprogress = function(){$('#offline').text(Math.ceil(((event.filesComplete / event.filesTotal) * 100)) + "%");}
localStore.checkForUpdate();
}
you have to assign references to functions, that should be called on defined events. What you did was calling these functions, and on the end the onerror, oncomplete and onprogress properties held jQuery instances returned by $('#offline').text('...')

Related

Call variable value in another .js file

I have 2 soy.js and lib-dialogs.js files.
I need to make lib-dialogs pass the value of the lineCount variable to soy.js.
I was able to do this with localStorage but because it saves in a cookie it does not update the values correctly.
In lib-dialogs there is a function called BlocklyDialogs.congratulations that calls the necessary data.
FIle:lib-dialogs.js
BlocklyDialogs.congratulations = function() {
// Add the user's code.
if (BlocklyGames.workspace) {
var linesText = document.getElementById('dialogLinesText');
linesText.textContent = '';
// Line produces warning when compiling Puzzle since there is no JavaScript
// generator. But this function is never called in Puzzle, so no matter.
var code = Blockly.JavaScript.workspaceToCode(BlocklyGames.workspace);
code = BlocklyInterface.stripCode(code);
var noComments = code.replace(/\/\/[^\n]*/g, ''); // Inline comments.
noComments = noComments.replace(/\/\*.*\*\//g, ''); /* Block comments. */
noComments = noComments.replace(/[ \t]+\n/g, '\n'); // Trailing spaces.
noComments = noComments.replace(/\n+/g, '\n'); // Blank lines.
noComments = noComments.trim();
var lineCount = noComments.split('\n').length;
var pre = document.getElementById('containerCode');
pre.textContent = code;
if (typeof prettyPrintOne == 'function') {
code = pre.innerHTML;
code = prettyPrintOne(code, 'js');
pre.innerHTML = code;
}
if (lineCount == 1) {
var text = BlocklyGames.getMsg('Games_linesOfCode1');
} else {
var text = BlocklyGames.getMsg('Games_linesOfCode2')
.replace('%1', String(lineCount));
}
linesText.appendChild(document.createTextNode(text));
}
FIle:soy.js
example "var count = BlocklyDialogs.congratulations(lineCount);"
In soy.js I need to receive the values of lineCount. I've already managed to do this using localStorage but I needed to do something more direct.
In testing I verified that the problem is in the lineCount variable because it is not passing a value to any variable even within the file itself.
I created a variable outside the blocklyDialogs.congratulations function and entered a value of 5.
I called the variable in the soy.js file and got it normally.
I need to make the lineCount pass its value.
You can use event driven programming, pub-sub model.
class EventManager {
constructor(...listeners) {
this.listeners = listeners;
}
register(fn) {
const id = this.listeners.push(fn);
return () => {
this.listeners.splice(id - 1, 1);
};
}
emit(data) {
this.listeners.forEach(fn => fn(data));
}
}
const pushEvents = new EventManager();
// JS 1
const unsubscribe1 = pushEvents.register(x => {
console.log("event:", x);
});
pushEvents.register(x => {
console.log("event:", x);
});
// JS 2
pushEvents.emit("Tets data");
//Output
// event: Tets data
// event: Tets data
unsubscribe1();
pushEvents.emit("Tets data2");
//Output
// event: Tets data2
.as-console-row {color: red!important}

Javascript listening for data changes & trigger reload

I have a server sent event in PHP that displays inventory information client side and updates in real time. That part works great. The challenge is that I want to trigger a reload when the inventory = 0. Note: I'm using jQuery Mobile 1.4.5
Here's my code:
var source = new EventSource('listener.php');
source.onmessage = function(msg) {
document.getElementById('inv').innerHTML = msg.data;
};
source.addEventListener('msg', onMessageHandler,false);
function onMessageHandler(msg) {
var inventory = msg.data;
};
// Trying to Fire Something like this //
//if (inventory = 0) {
//setTimeout(function() {
//location.reload(true)
//},5000);
Thanks for any suggestions : )
Watch the scoping:
var source = new EventSource('listener.php');
source.onmessage = function(msg) {
document.getElementById('inv').innerHTML = msg.data;
};
source.addEventListener('msg', onMessageHandler,false);
function onMessageHandler(msg) {
var inventory = msg.data;
if (inventory === 0) {
setTimeout(function() {
location.reload(true);
}, 5000);
}
};
Thank you for the suggestions. Both helped tremendously. This is what worked for me in the event any others ever have a similar challenge:
var source = new EventSource('listener.php');
source.onmessage = function(msg) {
document.getElementById('inv').innerHTML = msg.data;
console.log(msg.data);
var x = msg.data;
if (x == 0) {
setTimeout(function() {
window.location.reload(true);
// Or any of the 1000's of other ways to reload
}, 1000);
}
};
source.addEventListener('msg', onMessageHandler,false);
function onMessageHandler(msg) {
var inventory = msg.data;
};

javascript function move to webworker

I have function:
function addModel() {
var values = new Array();
var $input = $('input[type=\'text\']');
var error = 0;
$input.each(function() {
$(this).removeClass('double-error');
var that = this;
if (that.value!='') {
values[that.value] = 0;
$('input[type=\'text\']').each(function() {
if (this.value == that.value) {
values[that.value]++;
}
});
}
});
$input.each(function(key) {
if (values[this.value]>1) {
//error++;
var name = this.value;
var product_model = $(this).parent().parent().find('.product-model').text();
var m = product_model.toLowerCase().areplace(search,replace);
$(this).parent().find('input[type=\'text\']').val(name + '-' + m);
}
});
return error <= 0; //return error > 0 ? false : true;
}
where are a lot of inputs to recheck... up to 50000. Usually are about 5000 to 20000 inputs. Of course browsers are freezing... How to move this function to web-worker and call it to get data back and fill form type="text"
thank you in advance.
Web workers don't have direct access to the DOM. So to do this, you'd need to gather the values of all 5-50k inputs into an array or similar, and then send that to the web worker (via postMessage) for processing, and have the web worker do the relevant processing and post the result back, and then use that result to update the inputs. See any web worker tutorial for the details of launching the worker and passing messages back and forth (and/or see my answer here).
Even just gathering up the values of the inputs and posting them to the web worker is going to take significant time on the main UI thread, though, as is accepting the result from the worker and updating the inputs; even 5k inputs is just far, far too many for a web page.
If maintaining browser responsiveness is the issue, then releasing the main thread periodically will allow the browser to process user input and DOM events. The key to this approach is to find ways to process the inputs in smaller batches. For example:
var INTERVAL = 10; // ms
var intervalId = setInterval((function () {
var values = [];
var $input = $('input[type=\'text\']');
var index;
return function () {
var $i = $input[index];
var el = $i.get();
$i.removeClass('double-error');
if (el.value != '') {
values[el.value] = 0;
$input.each(function() {
if (this.value == el.value) {
values[el.value]++;
}
});
}
if (index++ > $input.length) {
clearInterval(intervalId);
index = 0;
// Now set elements
intervalId = setInterval(function () {
var $i = $input[index];
var el = $i.get();
if (values[el.value] > 1) {
var name = el.value;
var product_model = $i.parent().parent().find('.product-model').text();
var m = product_model.toLowerCase().areplace(search,replace);
$i.parent().find('input[type=\'text\']').val(name + '-' + m);
}
if (index++ > $input.length) {
clearInterval(intervalId);
}
}, INTERVAL);
}
};
}()), INTERVAL);
Here, we do just a little bit of work, then use setInterval to release the main thread so that other work can be performed. After INTERVAL we will do some more work, until we finish and call clearInterval

LocalStorage Save Javascript

My localstorage save and load won't work
I can't load or save. Can you please help me out?
I don't know whether it is the variables or functions that has been put up incorrectly
The functions are being called by HTML buttons that goes "onclick" and has ID's
var faze = 0;
function fazeClick(number){
faze = faze + number;
document.getElementById('faze').innerHTML = faze;
}
var mntDew = 0;
function buyDew(){
var mntDewCost = Math.floor(10 * Math.pow(1.1,mntDew));
if(faze >= mntDewCost){
mntDew = mntDew +1;
faze = faze - mntDewCost;
document.getElementById('mntDew').innerHTML = mntDew;
document.getElementById('faze').innerHTML = faze;
};
var nextCost = Math.floor(10 * Math.pow(1.2,mntDew));
document.getElementById('mntDewCost').innerHTML = nextCost;
};
window.setInterval(function(){
fazeClick(mntDew);
}, 1000);
function save(){
localstorage.setItem.faze;
};
function load(){
document.getElementById("faze").innerHTML = localstorage.getItem.faze;
};
document.write(faze);
// <button type="button" onClick="buyDew()">Buy Mountain Dew</button> #buyCursor
//Mountain Dew: <span id="mntDew">0</span><br/> #cursors
//cost: <span id="mntDewCost">10</span> #cursorCost
You got one letter wrong, it is spelled localStorage:
http://diveintohtml5.info/storage.html
var foo = localStorage.getItem("bar");
// ...
localStorage.setItem("bar", foo);
I would mostly advise to wrap your storage in a class, so that you would create a bridge pattern. And separate place of storage from your code logic, it will be easyer to change it so other type of storage in the future.
Check out the syntax for loading/saving values in localStorage
http://www.w3schools.com/html/html5_webstorage.asp
You can either use:
localStorage.setItem('faze', newFazeValue); // save
var newFazeValue = localStorage.getItem('faze'); // load
or
localStorage.faze = newFazeValue; // save
var newFazeValue = localStorage.faze; // load

How to check table for new content, and then update browser tab title?

I am working on a way to flash a browser tab when a new message appears in a table. I have the flashing of the tab part working, my only problem is that I can't seem to get it to flash when a message is received (which is the whole point of my exercise :) )
The newMessage() function is working fine, I just can't seem to get the notification() function to work.
My code is as follows:
function newMessage()
{
var oldTitle = "Your Page";
var msg = "New Message";
var timeout = setInterval(function()
{
document.title = document.title == msg ? '' : msg;
}, 1000);
window.onmousemove = function() {
clearInterval(timeout);
document.title = oldTitle;
window.onmousemove = null;
};
}
function notification()
{
var index = 2;
var content = document.getElementById('refreshMessages').childNodes[index];
var content = document.getElementById('refreshMessages').getElementByTagName("tr")[1];
var knownContent = content.toString();
updater.start();
updater2.start();
var newContent = document.getElementById('refreshMessages').childNodes[index];
var newContent = document.getElementById('refreshMessages').getElementByTagName("tr")[1];
if(knownContent != newContent.toString())
{
newMessage();
knownContent = newContent;
}
else if(knownContent = newContent.toString())
{
alert("No need to flash title.");
}
}
notification();
In the notification() function, I am trying to call the newMessage() function by comparing the strings at the appropiate cell in the table.
I put the alert() into the else if just to see if it would be called, but it does not happen. update.start() and update2.start() are carried out however, as I can see the messages appearing in the table.
I would be happier to use JavaScript but I am open to jQuery also.
My JavaScript is very very rusty so excuse me if I have made any silly mistakes!
Thanks,
Chuck
You have several mistakes in function notification(), see my comments:
function notification()
{
var index = 2;
//Why are you assigning value to "content" for twice?
var content = document.getElementById('refreshMessages').childNodes[index];
/*
* function getElementByTagName is undefined, should be getElementsByTagName,
* 's' is missing. And [1] means the second one not the first one, make sure
* that's exactly what you want.
*/
var content = document.getElementById('refreshMessages').getElementByTagName("tr")[1];
/*
* content is a tr dom object, content.toString() is something like "[object]".
* If you want to get content inside a cell, you should use cell.innerHTML.
* e.g. A table:
* <table id="refreshMessages">
* <tr><td>Hello world</td></tr>
* </table>
* var table = document.getElementById('refreshMessages');
* var firstTr = table.getElementsByTagName("tr")[0];
* var firstTd = firstTr.getElementsByTagName("td")[0];
* alert(firstTd.innerHTML); //alerts "Hello world"
*/
var knownContent = content.toString();
//I doubt these functions really get invoked cuz there's javascript error above.
updater.start();
updater2.start();
//assigning twice, "getElementByTagName" is missing "s"
var newContent = document.getElementById('refreshMessages').childNodes[index];
var newContent = document.getElementById('refreshMessages').getElementByTagName("tr")[1];
//Remove toString(), use innerHTML i metioned above.
if(knownContent != newContent.toString())
{
newMessage();
knownContent = newContent;
}
//You miss an "=" here, to judge a equals b, you should use "=="
else if(knownContent = newContent.toString())
{
alert("No need to flash title.");
}
}

Categories