jQuery each with SetTimeout - javascript

Can anyone tell me why this doesn't work?
jeMarkers is an array of Google Maps markers.
function toggleBounce() {
var bcounter = 0;
$(jeMarkers).each(function () {
setTimeout(function () {
if (this.getAnimation() != null) {
this.setAnimation(null);
} else {
this.setAnimation(google.maps.Animation.BOUNCE);
}
}, bcounter * 100);
bcounter++;
});
}
If I do the same without the setTimeout function it works but obviously does all the markers at once:
function toggleBounce() {
$.each(jeMarkers, function () {
if (this.getAnimation() != null) {
this.setAnimation(null);
} else {
this.setAnimation(google.maps.Animation.BOUNCE);
}
});

You have to cache the this object inside the function since the context of the setTimeout is not automatically set:
function toggleBounce() {
var bcounter = 0;
$(jeMarkers).each(function () {
var that = this; // <- Cache the item
setTimeout(function () {
if (that.getAnimation() != null) {
that.setAnimation(null); // <- Now we can call stuff on the item
} else {
that.setAnimation(google.maps.Animation.BOUNCE);
}
}, bcounter * 100);
bcounter++;
});
}

Related

JavaScript Returns from Functions. Functions calling functions

I am trying to get a better understanding on javacsript. And I am not sure why this code is not working. I am trying to create functions that will call another function. And return the results of the called function.
When I call the below, I get fully logged in and presented with the screen I desire. But jsDidLogin Always returns undefined. Is there a better way to implement my methods?
var jsDidLogin = beginLogin()
console.log(jsDidLogin)
function waitUntilElementFound(element, time, callFunction) //Wait for the element to be found on the page
{
if (document.querySelector(element) != null) {
return callFunction();
}
else {
if (!checkForFailedLogin()) {
setTimeout(function () {
waitUntilElementFound(element, time, callFunction);
}, time);
}
else {
return false;
}
}
}
function checkForFailedLogin() {
if (document.querySelector("div[class='modal-body ng-scope'] h1") != null) {
if(document.querySelector("div[class='modal-body ng-scope'] h1").innerHTML == "Login Error")
{
return true;
}
}
else {
return false;
}
}
function initialTabSelect() //Load the bank page once login is completed
{
document.querySelectorAll("li[class='Tab'] a")[0].click();
return "Fully Logged In";
}
function initialDoNotAsk() {
document.querySelectorAll("a[ng-click='modalCancel()']")[0].click();
return waitUntilElementFound("li[class='Tab'] a", 1000, initialTabSelect);
}
function initialLogin() {
var accountName = document.getElementById("username");
var accountPassword = document.getElementById("password");
var evt = document.createEvent("Events");
evt.initEvent("change", true, true);
accountName.value = "USERNAME";
accountPassword.value = "PASSWORD";
accountName.dispatchEvent(evt);
accountPassword.dispatchEvent(evt);
document.querySelectorAll("form[name='loginForm'] button.icon-login")[0].click();
return waitUntilElementFound("a[ng-click='modalCancel()']", 2000, initialDoNotAsk);
}
function beginLogin() {
return waitUntilElementFound("form[name='loginForm'] button.icon-login", 1000, initialLogin);
}
Changing to this alerts me when Fully Logged in, but if I change it to return status. I still get no returns.
My head is starting to hurt :(
function waitUntilElementFound(element, time, callFunction, callBack) //Wait for the element to be found on the page
{
if (document.querySelector(element) != null) {
callBack(callFunction());
}
else {
if (!checkForFailedLogin()) {
setTimeout(function () {
callBack(waitUntilElementFound(element, time, callFunction, function(status){alert(status);}));
}, time);
}
else {
return false;
}
}
}
function checkForFailedLogin() {
if (document.querySelector("div[class='modal-body ng-scope'] h1") != null) {
if(document.querySelector("div[class='modal-body ng-scope'] h1").innerHTML == "Login Error")
{
return true;
}
}
else {
return false;
}
}
function initialTabSelect() //Load the bank page once login is completed
{
document.querySelectorAll("li[class='Tab'] a")[0].click();
return "Fully Logged In";
}
function initialDoNotAsk() {
document.querySelectorAll("a[ng-click='modalCancel()']")[0].click();
return waitUntilElementFound("li[class='Tab'] a", 1000, initialTabSelect, function(status){alert(status)};);
}
function initialLogin() {
var accountName = document.getElementById("username");
var accountPassword = document.getElementById("password");
var evt = document.createEvent("Events");
evt.initEvent("change", true, true);
accountName.value = "USERNAME";
accountPassword.value = "PASSWORD";
accountName.dispatchEvent(evt);
accountPassword.dispatchEvent(evt);
document.querySelectorAll("form[name='loginForm'] button.icon-login")[0].click();
return waitUntilElementFound("a[ng-click='modalCancel()']", 2000, initialDoNotAsk, function(status){alert(status)};);
}
function beginLogin() {
return waitUntilElementFound("form[name='loginForm'] button.icon-login", 1000, initialLogin, function(status){alert(status)};);
}

How to bind multiple labels using leaflet.label?

I am using Leaflet and it works well. I am using leaflet.label as well and that works nicely as well. The problem is that I would like to display two labels to the right of the marker. If I call bindLabel twice, then the second overrides the first. How could I make sure that I have two labels, both to the right of the marker and the second label is above the first one?
This is how I tried:
newMarker.bindLabel(result, { noHide: true }).bindLabel("secondlabel", { noHide: true });
Thanks
EDIT:
I have managed to display the texts using a single call to bindLabel, like this:
newMarker.bindLabel(result + "<br>secondLabel", { noHide: true });
but this seems to be a too hacky solution.
Here they say it is not possible, but that was written in 2014. It might be possible since then.
I have managed to solve it. I am lazy to push it to their repo right now, but I will probably do it in the future. The logic of the solution is as follows:
this.label -> this.labels
this.labels is an array of LeafletLabels
apply the change for methods containing this.label
move this._labelNoHide = options.noHide into the if to prevent bugs
The labels will act similarly for the subset of options which is handled singularly / marker. Sorry, folks, singularizing noHide or opacity to label level instead of marker level is beyond the scope of this question. I might resolve those later though.
The code is as follows:
/*
Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
(c) 2012-2013, Jacob Toye, Smartrak
https://github.com/Leaflet/Leaflet.label
http://leafletjs.com
https://github.com/jacobtoye
*/
(function (factory, window) {
// define an AMD module that relies on 'leaflet'
if (typeof define === 'function' && define.amd) {
define(['leaflet'], factory);
// define a Common JS module that relies on 'leaflet'
} else if (typeof exports === 'object') {
module.exports = factory(require('leaflet'));
}
// attach your plugin to the global 'L' variable
if (typeof window !== 'undefined' && window.L) {
window.LeafletLabel = factory(L);
}
}(function (L) {
L.labelVersion = '0.2.4';
var LeafletLabel = L.Class.extend({
includes: L.Mixin.Events,
options: {
className: '',
clickable: false,
direction: 'right',
noHide: false,
offset: [12, -15], // 6 (width of the label triangle) + 6 (padding)
opacity: 1,
zoomAnimation: true
},
initialize: function (options, source) {
L.setOptions(this, options);
this._source = source;
this._animated = L.Browser.any3d && this.options.zoomAnimation;
this._isOpen = false;
},
onAdd: function (map) {
this._map = map;
this._pane = this.options.pane ? map._panes[this.options.pane] :
this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;
if (!this._container) {
this._initLayout();
}
this._pane.appendChild(this._container);
this._initInteraction();
this._update();
this.setOpacity(this.options.opacity);
map
.on('moveend', this._onMoveEnd, this)
.on('viewreset', this._onViewReset, this);
if (this._animated) {
map.on('zoomanim', this._zoomAnimation, this);
}
if (L.Browser.touch && !this.options.noHide) {
L.DomEvent.on(this._container, 'click', this.close, this);
map.on('click', this.close, this);
}
},
onRemove: function (map) {
this._pane.removeChild(this._container);
map.off({
zoomanim: this._zoomAnimation,
moveend: this._onMoveEnd,
viewreset: this._onViewReset
}, this);
this._removeInteraction();
this._map = null;
},
setLatLng: function (latlng) {
this._latlng = L.latLng(latlng);
if (this._map) {
this._updatePosition();
}
return this;
},
setContent: function (content) {
// Backup previous content and store new content
this._previousContent = this._content;
this._content = content;
this._updateContent();
return this;
},
close: function () {
var map = this._map;
if (map) {
if (L.Browser.touch && !this.options.noHide) {
L.DomEvent.off(this._container, 'click', this.close);
map.off('click', this.close, this);
}
map.removeLayer(this);
}
},
updateZIndex: function (zIndex) {
this._zIndex = zIndex;
if (this._container && this._zIndex) {
this._container.style.zIndex = zIndex;
}
},
setOpacity: function (opacity) {
this.options.opacity = opacity;
if (this._container) {
L.DomUtil.setOpacity(this._container, opacity);
}
},
_initLayout: function () {
this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated');
this.updateZIndex(this._zIndex);
},
_update: function () {
if (!this._map) { return; }
this._container.style.visibility = 'hidden';
this._updateContent();
this._updatePosition();
this._container.style.visibility = '';
},
_updateContent: function () {
if (!this._content || !this._map || this._prevContent === this._content) {
return;
}
if (typeof this._content === 'string') {
this._container.innerHTML = this._content;
this._prevContent = this._content;
this._labelWidth = this._container.offsetWidth;
}
},
_updatePosition: function () {
var pos = this._map.latLngToLayerPoint(this._latlng);
this._setPosition(pos);
},
_setPosition: function (pos) {
var map = this._map,
container = this._container,
centerPoint = map.latLngToContainerPoint(map.getCenter()),
labelPoint = map.layerPointToContainerPoint(pos),
direction = this.options.direction,
labelWidth = this._labelWidth,
offset = L.point(this.options.offset);
// position to the right (right or auto & needs to)
if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) {
L.DomUtil.addClass(container, 'leaflet-label-right');
L.DomUtil.removeClass(container, 'leaflet-label-left');
pos = pos.add(offset);
} else { // position to the left
L.DomUtil.addClass(container, 'leaflet-label-left');
L.DomUtil.removeClass(container, 'leaflet-label-right');
pos = pos.add(L.point(-offset.x - labelWidth, offset.y));
}
L.DomUtil.setPosition(container, pos);
},
_zoomAnimation: function (opt) {
var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
this._setPosition(pos);
},
_onMoveEnd: function () {
if (!this._animated || this.options.direction === 'auto') {
this._updatePosition();
}
},
_onViewReset: function (e) {
/* if map resets hard, we must update the label */
if (e && e.hard) {
this._update();
}
},
_initInteraction: function () {
if (!this.options.clickable) { return; }
var container = this._container,
events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
L.DomUtil.addClass(container, 'leaflet-clickable');
L.DomEvent.on(container, 'click', this._onMouseClick, this);
for (var i = 0; i < events.length; i++) {
L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
}
},
_removeInteraction: function () {
if (!this.options.clickable) { return; }
var container = this._container,
events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
L.DomUtil.removeClass(container, 'leaflet-clickable');
L.DomEvent.off(container, 'click', this._onMouseClick, this);
for (var i = 0; i < events.length; i++) {
L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
}
},
_onMouseClick: function (e) {
if (this.hasEventListeners(e.type)) {
L.DomEvent.stopPropagation(e);
}
this.fire(e.type, {
originalEvent: e
});
},
_fireMouseEvent: function (e) {
this.fire(e.type, {
originalEvent: e
});
// TODO proper custom event propagation
// this line will always be called if marker is in a FeatureGroup
if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
L.DomEvent.preventDefault(e);
}
if (e.type !== 'mousedown') {
L.DomEvent.stopPropagation(e);
} else {
L.DomEvent.preventDefault(e);
}
}
});
/*global LeafletLabel */
// This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
L.BaseMarkerMethods = {
showLabel: function () {
if (this.labels && this._map) {
for (var labelIndex in this.labels) {
this.labels[labelIndex].setLatLng(this._latlng);
this._map.showLabel(this.labels[labelIndex]);
}
}
return this;
},
hideLabel: function () {
if (this.labels) {
for (var labelIndex in this.labels) {
this.labels[labelIndex].close();
}
}
return this;
},
setLabelNoHide: function (noHide) {
if (this._labelNoHide === noHide) {
return;
}
this._labelNoHide = noHide;
if (noHide) {
this._removeLabelRevealHandlers();
this.showLabel();
} else {
this._addLabelRevealHandlers();
this.hideLabel();
}
},
bindLabel: function (content, options) {
var labelAnchor = this.options.icon ? this.options.icon.options.labelAnchor : this.options.labelAnchor,
anchor = L.point(labelAnchor) || L.point(0, 0);
anchor = anchor.add(LeafletLabel.prototype.options.offset);
if (options && options.offset) {
anchor = anchor.add(options.offset);
}
options = L.Util.extend({ offset: anchor }, options);
if (!this.labels) {
this._labelNoHide = options.noHide;
this.labels = [];
if (!this._labelNoHide) {
this._addLabelRevealHandlers();
}
this
.on('remove', this.hideLabel, this)
.on('move', this._moveLabel, this)
.on('add', this._onMarkerAdd, this);
this._hasLabelHandlers = true;
}
this.labels.push(new LeafletLabel(options, this).setContent(content));
return this;
},
unbindLabel: function () {
if (this.labels) {
this.hideLabel();
this.labels = null;
if (this._hasLabelHandlers) {
if (!this._labelNoHide) {
this._removeLabelRevealHandlers();
}
this
.off('remove', this.hideLabel, this)
.off('move', this._moveLabel, this)
.off('add', this._onMarkerAdd, this);
}
this._hasLabelHandlers = false;
}
return this;
},
updateLabelContent: function (content, index) {
if ((this.labels) && (index < this.labels.length)) {
this.labels[index].setContent(content);
}
},
getLabels: function () {
return this.labels;
},
_onMarkerAdd: function () {
if (this._labelNoHide) {
this.showLabel();
}
},
_addLabelRevealHandlers: function () {
this
.on('mouseover', this.showLabel, this)
.on('mouseout', this.hideLabel, this);
if (L.Browser.touch) {
this.on('click', this.showLabel, this);
}
},
_removeLabelRevealHandlers: function () {
this
.off('mouseover', this.showLabel, this)
.off('mouseout', this.hideLabel, this);
if (L.Browser.touch) {
this.off('click', this.showLabel, this);
}
},
_moveLabel: function (e) {
this.label.setLatLng(e.latlng);
}
};
// Add in an option to icon that is used to set where the label anchor is
L.Icon.Default.mergeOptions({
labelAnchor: new L.Point(9, -20)
});
// Have to do this since Leaflet is loaded before this plugin and initializes
// L.Marker.options.icon therefore missing our mixin above.
L.Marker.mergeOptions({
icon: new L.Icon.Default()
});
L.Marker.include(L.BaseMarkerMethods);
L.Marker.include({
_originalUpdateZIndex: L.Marker.prototype._updateZIndex,
_updateZIndex: function (offset) {
var zIndex = this._zIndex + offset;
this._originalUpdateZIndex(offset);
if (this.labels) {
for (var labelIndex in this.labels) {
this.labels[labelIndex].updateZIndex(zIndex);
}
}
},
_originalSetOpacity: L.Marker.prototype.setOpacity,
setOpacity: function (opacity, labelHasSemiTransparency) {
this.options.labelHasSemiTransparency = labelHasSemiTransparency;
this._originalSetOpacity(opacity);
},
_originalUpdateOpacity: L.Marker.prototype._updateOpacity,
_updateOpacity: function () {
var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;
this._originalUpdateOpacity();
if (this.labels) {
for (var labelIndex in labels) {
this.labels[labelIndex].setOpacity(this.options.labelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
}
}
},
_originalSetLatLng: L.Marker.prototype.setLatLng,
setLatLng: function (latlng) {
if (this.labels && !this._labelNoHide) {
this.hideLabel();
}
return this._originalSetLatLng(latlng);
}
});
// Add in an option to icon that is used to set where the label anchor is
L.CircleMarker.mergeOptions({
labelAnchor: new L.Point(0, 0)
});
L.CircleMarker.include(L.BaseMarkerMethods);
/*global LeafletLabel */
L.Path.include({
bindLabel: function (content, options) {
if (!this.label || this.label.options !== options) {
this.label = new LeafletLabel(options, this);
}
this.label.setContent(content);
if (!this._showLabelAdded) {
this
.on('mouseover', this._showLabel, this)
.on('mousemove', this._moveLabel, this)
.on('mouseout remove', this._hideLabel, this);
if (L.Browser.touch) {
this.on('click', this._showLabel, this);
}
this._showLabelAdded = true;
}
return this;
},
unbindLabel: function () {
if (this.label) {
this._hideLabel();
this.label = null;
this._showLabelAdded = false;
this
.off('mouseover', this._showLabel, this)
.off('mousemove', this._moveLabel, this)
.off('mouseout remove', this._hideLabel, this);
}
return this;
},
updateLabelContent: function (content) {
if (this.label) {
this.label.setContent(content);
}
},
_showLabel: function (e) {
this.label.setLatLng(e.latlng);
this._map.showLabel(this.label);
},
_moveLabel: function (e) {
this.label.setLatLng(e.latlng);
},
_hideLabel: function () {
this.label.close();
}
});
L.Map.include({
showLabel: function (label) {
return this.addLayer(label);
}
});
L.FeatureGroup.include({
// TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
clearLayers: function () {
this.unbindLabel();
this.eachLayer(this.removeLayer, this);
return this;
},
bindLabel: function (content, options) {
return this.invoke('bindLabel', content, options);
},
unbindLabel: function () {
return this.invoke('unbindLabel');
},
updateLabelContent: function (content) {
this.invoke('updateLabelContent', content);
}
});
return LeafletLabel;
}, window));

How can I include a function (and its parameter) within an event handler, without the function being called on page load?

I am refactoring this code
$("#one").on("click", function() {
if(operator === undefined) {
firstArray.push("1");
}
else {
secondArray.push("1");
}
});
$("#two").on("click", function() {
if(operator === undefined) {
firstArray.push("2");
}
else {
secondArray.push("2");
}
});
$("#three").on("click", function() {
if(operator === undefined) {
firstArray.push("3");
}
else {
secondArray.push("3");
}
});
$("#four").on("click", function() {
console.log("4");
if(operator === undefined) {
firstArray.push("4");
}
else {
secondArray.push("4");
}
});
$("#five").on("click", function() {
console.log("5");
if(operator === undefined) {
firstArray.push("5");
}
else {
secondArray.push("5");
}
});
$("#six").on("click", function() {
console.log("6");
if(operator === undefined) {
firstArray.push("6");
}
else {
secondArray.push("6");
}
});
$("#seven").on("click", function() {
console.log("7");
if(operator === undefined) {
firstArray.push("7");
}
else {
secondArray.push("7");
}
});
$("#eight").on("click", function() {
console.log("8");
if(operator === undefined) {
firstArray.push("8");
}
else {
secondArray.push("8");
}
});
$("#nine").on("click", function() {
console.log("9");
if(operator === undefined) {
firstArray.push("9");
}
else {
secondArray.push("9");
}
});
$("#zero").on("click", function() {
console.log("0");
if(operator === undefined) {
firstArray.push("0");
}
else {
secondArray.push("0");
}
});
into this
function pushNumber(numberToPush) {
if(operator === undefined) {
firstArray.push(numberToPush);
}
else {
secondArray.push(numberToPush);
}
}
$("#one").on("click", pushNumber("1"));
$("#two").on("click", pushNumber("2"));
$("#three").on("click", pushNumber("3"));
$("#four").on("click", pushNumber("4"));
$("#five").on("click", pushNumber("5"));
$("#six").on("click", pushNumber("6"));
$("#seven").on("click", pushNumber("7"));
$("#eight").on("click", pushNumber("8"));
$("#nine").on("click", pushNumber("9"));
$("#zero").on("click", pushNumber("0"));
When I try the above code, the pushNumber function is being called on page load. I understand that this is happening because I have put parentheses, thereby calling the function. But I do not know how I can pass a parameter to the function without doing it this way.
I'd appreciate some help, thanks.
What you want to do is "curry" a function, or generate a new function that already has some arguments added into it.
First, we'll make a function to generate a new function for each click handler:
function generateHandler(argument) {
return function() {
pushNumber(argument);
};
}
Then, you can use it like this:
$("#one").on("click", generateHandler("1"));
What you want is something called partial application or currying. You can do it manually for your case with a higher-order function, like this:
function pushNumber(numberToPush)
return function() {
if(operator === undefined) {
firstArray.push(numberToPush);
} else {
secondArray.push(numberToPush);
}
};
}
But many utiility libraries also offer a curry or partial function that you might be able to use to wrap your function.

Need to modify this onlinejs code (internet detection script) to fire manually, not on a timer

I am using the excellent onlinejs (https://github.com/PixelsCommander/OnlineJS) library for checking that my app has a live internet connection. However, I don't need it to fire regularly, but rather upon the manual calling of the main function.
I would like to modify this code so that it is not firing on a timer, and know the name of the function to call for manual firing, which assume is just getterSetter.
My previous attempts to modify the code below have broken the script as I'm no expert at JavaScript. I appreciate any help in adapting this very useful code.
function getterSetter(variableParent, variableName, getterFunction, setterFunction) {
if (Object.defineProperty) {
Object.defineProperty(variableParent, variableName, {
get: getterFunction,
set: setterFunction
});
}
else if (document.__defineGetter__) {
variableParent.__defineGetter__(variableName, getterFunction);
variableParent.__defineSetter__(variableName, setterFunction);
}
}
(function (w) {
w.onlinejs = w.onlinejs || {};
//Checks interval can be changed in runtime
w.onLineCheckTimeout = 5000;
//Use window.onLineURL incapsulated variable
w.onlinejs._onLineURL = "http://lascelles.us/wavestream/online.php";
w.onlinejs.setOnLineURL = function (newURL) {
w.onlinejs._onLineURL = newURL;
w.onlinejs.getStatusFromNavigatorOnLine();
}
w.onlinejs.getOnLineURL = function () {
return w.onlinejs._onLineURL;
}
getterSetter(w, 'onLineURL', w.onlinejs.getOnLineURL, w.onlinejs.setOnLineURL);
//Verification logic
w.onlinejs.setStatus = function (newStatus) {
w.onlinejs.fireHandlerDependOnStatus(newStatus);
w.onLine = newStatus;
}
w.onlinejs.fireHandlerDependOnStatus = function (newStatus) {
if (newStatus === true && w.onLineHandler !== undefined && (w.onLine !== true || w.onlinejs.handlerFired === false)) {
w.onLineHandler();
}
if (newStatus === false && w.offLineHandler !== undefined && (w.onLine !== false || w.onlinejs.handlerFired === false)) {
w.offLineHandler();
}
w.onlinejs.handlerFired = true;
};
w.onlinejs.startCheck = function () {
setInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
w.onlinejs.stopCheck = function () {
clearInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
w.checkOnLine = function () {
w.onlinejs.logic.checkConnectionWithRequest(false);
}
w.onlinejs.getOnLineCheckURL = function () {
return w.onlinejs._onLineURL + '?' + Date.now();
}
w.onlinejs.getStatusFromNavigatorOnLine = function () {
if (w.navigator.onLine !== undefined) {
w.onlinejs.setStatus(w.navigator.onLine);
} else {
w.onlinejs.setStatus(true);
}
}
//Network transport layer
var xmlhttp = new XMLHttpRequest();
w.onlinejs.isXMLHttp = function () {
return "withCredentials" in xmlhttp;
}
w.onlinejs.isXDomain = function () {
return typeof XDomainRequest != "undefined";
}
//For IE we use XDomainRequest and sometimes it uses a bit different logic, so adding decorator for this
w.onlinejs.XDomainLogic = {
init: function () {
xmlhttp = new XDomainRequest();
xmlhttp.onerror = function () {
xmlhttp.status = 404;
w.onlinejs.processXmlhttpStatus();
}
xmlhttp.ontimeout = function () {
xmlhttp.status = 404;
w.onlinejs.processXmlhttpStatus();
}
},
onInternetAsyncStatus: function () {
try {
xmlhttp.status = 200;
w.onlinejs.processXmlhttpStatus();
} catch (err) {
w.onlinejs.setStatus(false);
}
},
checkConnectionWithRequest: function (async) {
xmlhttp.onload = w.onlinejs.logic.onInternetAsyncStatus;
var url = w.onlinejs.getOnLineCheckURL();
xmlhttp.open("GET", url);
w.onlinejs.tryToSend(xmlhttp);
}
}
//Another case for decoration is XMLHttpRequest
w.onlinejs.XMLHttpLogic = {
init: function () {
},
onInternetAsyncStatus: function () {
if (xmlhttp.readyState === 4) {
try {
w.onlinejs.processXmlhttpStatus();
} catch (err) {
w.onlinejs.setStatus(false);
}
}
},
checkConnectionWithRequest: function (async) {
if (async) {
xmlhttp.onreadystatechange = w.onlinejs.logic.onInternetAsyncStatus;
} else {
xmlhttp.onreadystatechange = undefined;
}
var url = w.onlinejs.getOnLineCheckURL();
xmlhttp.open("HEAD", url, async);
w.onlinejs.tryToSend(xmlhttp);
if (async === false) {
w.onlinejs.processXmlhttpStatus();
return w.onLine;
}
}
}
if (w.onlinejs.isXDomain()) {
w.onlinejs.logic = w.onlinejs.XDomainLogic;
} else {
w.onlinejs.logic = w.onlinejs.XMLHttpLogic;
}
w.onlinejs.processXmlhttpStatus = function () {
var tempOnLine = w.onlinejs.verifyStatus(xmlhttp.status);
w.onlinejs.setStatus(tempOnLine);
}
w.onlinejs.verifyStatus = function (status) {
return status === 200;
}
w.onlinejs.tryToSend = function (xmlhttprequest) {
try {
xmlhttprequest.send();
} catch(e) {
w.onlinejs.setStatus(false);
}
}
//Events handling
w.onlinejs.addEvent = function (obj, type, callback) {
if (window.attachEvent) {
obj.attachEvent('on' + type, callback);
} else {
obj.addEventListener(type, callback);
}
}
w.onlinejs.addEvent(w, 'load', function () {
w.onlinejs.fireHandlerDependOnStatus(w.onLine);
});
w.onlinejs.addEvent(w, 'online', function () {
window.onlinejs.logic.checkConnectionWithRequest(true);
})
w.onlinejs.addEvent(w, 'offline', function () {
window.onlinejs.logic.checkConnectionWithRequest(true);
})
w.onlinejs.getStatusFromNavigatorOnLine();
w.onlinejs.logic.init();
w.checkOnLine();
w.onlinejs.startCheck();
w.onlinejs.handlerFired = false;
})(window);
Looking at the source, I believe you can simply call onlinejs.logic.checkConnectionWithRequest(false) to get the status synchronously. This function will return either true or false.
PS: I am sure there are better libraries for this task out there, I really do not like the way it's written and clearly, the author doesn't know JS very well. E.g., the following code taken from the library makes no sense at all.
w.onlinejs.stopCheck = function () {
clearInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}

PDF.js pages does not get painted. Only white pages are displayed

I am trying to render a pdf in chrome using PDFJS
This is the function I am calling:
open: function pdfViewOpen(url, scale, password) {
var parameters = {password: password};
if (typeof url === 'string') { // URL
this.setTitleUsingUrl(url);
parameters.url = url;
} else if (url && 'byteLength' in url) { // ArrayBuffer
parameters.data = url;
}
if (!PDFView.loadingBar) {
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
}
this.pdfDocument = null;
var self = this;
self.loading = true;
getDocument(parameters).then(
function getDocumentCallback(pdfDocument) {
self.load(pdfDocument, scale);
self.loading = false;
},
function getDocumentError(message, exception) {
if (exception && exception.name === 'PasswordException') {
if (exception.code === 'needpassword') {
var promptString = mozL10n.get('request_password', null,
'PDF is protected by a password:');
password = prompt(promptString);
if (password && password.length > 0) {
return PDFView.open(url, scale, password);
}
}
}
var loadingErrorMessage = mozL10n.get('loading_error', null,
'An error occurred while loading the PDF.');
if (exception && exception.name === 'InvalidPDFException') {
// change error message also for other builds
var loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.');
//#if B2G
// window.alert(loadingErrorMessage);
// return window.close();
//#endif
}
var loadingIndicator = document.getElementById('loading');
loadingIndicator.textContent = mozL10n.get('loading_error_indicator',
null, 'Error');
var moreInfo = {
message: message
};
self.error(loadingErrorMessage, moreInfo);
self.loading = false;
},
function getDocumentProgress(progressData) {
self.progress(progressData.loaded / progressData.total);
}
);
}
This is the call:
PDFView.open('/MyPDFs/Pdf2.pdf', 'auto', null);
All I get is this:
If you notice, even the page number is retrieved but the content is not painted in the pages. CanĀ“t find why.. Is the any other function I should call next to PDFView.open?
Found the solution...!
This is the code that does the work.
$(document).ready(function () {
PDFView.initialize();
var params = PDFView.parseQueryString(document.location.search.substring(1));
//#if !(FIREFOX || MOZCENTRAL)
var file = params.file || DEFAULT_URL;
//#else
//var file = window.location.toString()
//#endif
//#if !(FIREFOX || MOZCENTRAL)
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
document.getElementById('openFile').setAttribute('hidden', 'true');
} else {
document.getElementById('fileInput').value = null;
}
//#else
//document.getElementById('openFile').setAttribute('hidden', 'true');
//#endif
// Special debugging flags in the hash section of the URL.
var hash = document.location.hash.substring(1);
var hashParams = PDFView.parseQueryString(hash);
if ('disableWorker' in hashParams)
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
//#if !(FIREFOX || MOZCENTRAL)
var locale = navigator.language;
if ('locale' in hashParams)
locale = hashParams['locale'];
mozL10n.setLanguage(locale);
//#endif
if ('textLayer' in hashParams) {
switch (hashParams['textLayer']) {
case 'off':
PDFJS.disableTextLayer = true;
break;
case 'visible':
case 'shadow':
case 'hover':
var viewer = document.getElementById('viewer');
viewer.classList.add('textLayer-' + hashParams['textLayer']);
break;
}
}
//#if !(FIREFOX || MOZCENTRAL)
if ('pdfBug' in hashParams) {
//#else
//if ('pdfBug' in hashParams && FirefoxCom.requestSync('pdfBugEnabled')) {
//#endif
PDFJS.pdfBug = true;
var pdfBug = hashParams['pdfBug'];
var enabled = pdfBug.split(',');
PDFBug.enable(enabled);
PDFBug.init();
}
if (!PDFView.supportsPrinting) {
document.getElementById('print').classList.add('hidden');
}
if (!PDFView.supportsFullscreen) {
document.getElementById('fullscreen').classList.add('hidden');
}
if (PDFView.supportsIntegratedFind) {
document.querySelector('#viewFind').classList.add('hidden');
}
// Listen for warnings to trigger the fallback UI. Errors should be caught
// and call PDFView.error() so we don't need to listen for those.
PDFJS.LogManager.addLogger({
warn: function () {
PDFView.fallback();
}
});
var mainContainer = document.getElementById('mainContainer');
var outerContainer = document.getElementById('outerContainer');
mainContainer.addEventListener('transitionend', function (e) {
if (e.target == mainContainer) {
var event = document.createEvent('UIEvents');
event.initUIEvent('resize', false, false, window, 0);
window.dispatchEvent(event);
outerContainer.classList.remove('sidebarMoving');
}
}, true);
document.getElementById('sidebarToggle').addEventListener('click',
function () {
this.classList.toggle('toggled');
outerContainer.classList.add('sidebarMoving');
outerContainer.classList.toggle('sidebarOpen');
PDFView.sidebarOpen = outerContainer.classList.contains('sidebarOpen');
PDFView.renderHighestPriority();
});
document.getElementById('viewThumbnail').addEventListener('click',
function () {
PDFView.switchSidebarView('thumbs');
});
document.getElementById('viewOutline').addEventListener('click',
function () {
PDFView.switchSidebarView('outline');
});
document.getElementById('previous').addEventListener('click',
function () {
PDFView.page--;
});
document.getElementById('next').addEventListener('click',
function () {
PDFView.page++;
});
document.querySelector('.zoomIn').addEventListener('click',
function () {
PDFView.zoomIn();
});
document.querySelector('.zoomOut').addEventListener('click',
function () {
PDFView.zoomOut();
});
document.getElementById('fullscreen').addEventListener('click',
function () {
PDFView.fullscreen();
});
document.getElementById('openFile').addEventListener('click',
function () {
document.getElementById('fileInput').click();
});
document.getElementById('print').addEventListener('click',
function () {
window.print();
});
document.getElementById('download').addEventListener('click',
function () {
PDFView.download();
});
document.getElementById('pageNumber').addEventListener('change',
function () {
PDFView.page = this.value;
});
document.getElementById('scaleSelect').addEventListener('change',
function () {
PDFView.parseScale(this.value);
});
document.getElementById('first_page').addEventListener('click',
function () {
PDFView.page = 1;
});
document.getElementById('last_page').addEventListener('click',
function () {
PDFView.page = PDFView.pdfDocument.numPages;
});
document.getElementById('page_rotate_ccw').addEventListener('click',
function () {
PDFView.rotatePages(-90);
});
document.getElementById('page_rotate_cw').addEventListener('click',
function () {
PDFView.rotatePages(90);
});
//#if (FIREFOX || MOZCENTRAL)
//if (FirefoxCom.requestSync('getLoadingType') == 'passive') {
// PDFView.setTitleUsingUrl(file);
// PDFView.initPassiveLoading();
// return;
//}
//#endif
//#if !B2G
PDFView.open(file, 0);
//#endif
});
The system must be initialized first before PDFView.open call!
Thanks

Categories