jquery function not working properly in safari - html

I am working on the following code. This function creates a "typed" effect. This function works well in chrome but not in safari. Is there an issue with jquery for safari?
var Typed = (function() {
var typed = '.typed',
$typed = $(typed);
function init($this) {
var el = '#' + $this.attr('id'),
strings = $this.data('type-this'),
strings = strings.split(',');
var options = {
strings: strings,
typeSpeed: 100,
backSpeed: 70,
loop: true
};
var animation = new Typed(el, options);
inView(el).on('enter', function() {
animation.start();
}).on('exit', function() {
animation.stop();
});
}
if ($typed.length) {
$typed.each(function() {
init($(this));
});
}
})();
<span class="typed" id="type-example-1" data-type-this="text1., text2., text3., text4."></span>

Related

canvas is throw error of tainted after LoadFromJson

I am using fabric js version 1.7.22
when image set in a repetitive manner in a rectangle of fabric js, at
the first time it will be loaded and saved into JSON using toJSON()
and save an image using todataUrl() method, but when cal canvas a loadFromJson method at that time, this canvas not savable, because it throws tainted canvas error.
Please help me,
I already set crossOrigin in a pattern but it not working. and not
added in canvas JSON.
I have made one Fiddle For Generate Issue :
[http://jsfiddle.net/Mark_1998/kt387vLc/1/][1]
Steps to generate issue :
click on 'set pattern'
then click on 'save canvas'
then click on 'reload canvas' // load canvas from JSON
then click on 'save canvas' // cause issue of tainted canvas
This issue is fixed in new version of fabricjs already. If you are still using 1.7.20 the override fabric.Pattern.prototype.toObject and fabric.Pattern.prototype.initialize, find code in snippet.
var canvas = new fabric.Canvas('canvas', {
height: 500,
width: 500,
});
canvas.backgroundColor = '#ff0000';
canvas.renderAll();
var canvasJSON = {};
document.getElementById('setPat').addEventListener('click', function() {
fabric.util.loadImage('https://cdn.dribbble.com/assets/icon-backtotop-1b04df73090f6b0f3192a3b71874ca3b3cc19dff16adc6cf365cd0c75897f6c0.png', function(image) {
var pattern = new fabric.Pattern({
source: image,
repeat: 'repeat',
crossOrigin: 'Anonymous'
});
var patternObject = new fabric.Rect({
left: 0,
top: 0,
height: canvas.height,
width: canvas.width,
angle: 0,
fill: pattern,
objectCaching: false
})
canvas.add(patternObject);
}, null, {
crossOrigin: 'Anonymous'
});
})
document.getElementById('saveCanvas').addEventListener('click', function() {
console.log('save canvas');
canvasJSON = canvas.toJSON();
var image = canvas.toDataURL("image/png", {
crossOrigin: 'Anonymous'
}); // don't remove this, i need it as thumbnail.
//console.log('canvas.Json', canvasJSON);
//console.log('image', image);
canvas.clear();
canvas.backgroundColor = '#ff0000';
canvas.renderAll();
});
document.getElementById('reloadCanvas').addEventListener('click', function() {
console.log('save canvas');
canvas.loadFromJSON(canvasJSON, function() {
canvas.set({
crossOrigin: 'Anonymous'
})
});
console.log('canvas.Json', canvasJSON);
});
//cross origin was not added in toObject JSON
fabric.Pattern.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
crossOrigin: this.crossOrigin,
patternTransform: this.patternTransform ? this.patternTransform.concat() : null
});
};
})(fabric.Pattern.prototype.toObject);
//cross origin was not added while creating image
fabric.Pattern.prototype.initialize = function(options, callback) {
options || (options = {});
this.id = fabric.Object.__uid++;
this.setOptions(options);
if (!options.source || (options.source && typeof options.source !== 'string')) {
callback && callback(this);
return;
}
// function string
if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {
this.source = new Function(fabric.util.getFunctionBody(options.source));
callback && callback(this);
} else {
// img src string
var _this = this;
this.source = fabric.util.createImage();
fabric.util.loadImage(options.source, function(img) {
_this.source = img;
callback && callback(_this);
}, null, this.crossOrigin);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.js"></script>
<button id="setPat">
Set pattern
</button>
<button id="saveCanvas">
Save canvas
</button>
<button id="reloadCanvas">
Reload CAnvas
</button>
<canvas id="canvas"></canvas>

How to add Google Drive Picker in Google web app

what I'm trying to do is to show the Google Picker in my Google Web app. I already tried many ways to accomplish that, but nothing works.
At the moment my code looks like this:
WebApp.html
<!-- rest of the code -->
<button type="button" id="pick">Pick File</button>
</div>
<script>
function initPicker() {
var picker = new FilePicker({
apiKey: "####################",
clientId: "##########-##########################",
buttonEl: document.getElementById('pick'),
onSelect: function(file) {
alert('Selected ' + file.title);
} // onSelect
}); // var picker
} // function initPicker()
</script>
<!-- rest of the code -->
WebAppJS.html
/* rest of the code */
var FilePicker = window.FilePicker = function(options) {
this.apiKey = options.apiKey;
this.clientId = options.clientId;
this.buttonEl = options.buttonEl;
this.onSelect = options.onSelect;
this.buttonEl.addEventListener('click', this.open.bind(this));
this.buttonEl.disabled = true;
gapi.client.setApiKey(this.apiKey);
gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this));
google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) });
}
FilePicker.prototype = {
open: function() {
var token = gapi.auth.getToken();
if (token) {
this._showPicker();
} else {
this._doAuth(false, function() { this._showPicker(); }.bind(this));
}
},
_showPicker: function() {
var accessToken = gapi.auth.getToken().access_token;
this.picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.DOCUMENTS).
setAppId(this.clientId).
setOAuthToken(accessToken).
setCallback(this._pickerCallback.bind(this)).
build().
setVisible(true);
},
_pickerCallback: function(data) {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var file = data[google.picker.Response.DOCUMENTS][0],
id = file[google.picker.Document.ID],
request = gapi.client.drive.files.get({ fileId: id });
request.execute(this._fileGetCallback.bind(this));
}
},
_fileGetCallback: function(file) {
if (this.onSelect) {
this.onSelect(file);
}
},
_pickerApiLoaded: function() {
this.buttonEl.disabled = false;
},
_driveApiLoaded: function() {
this._doAuth(true);
},
_doAuth: function(immediate1, callback) {
gapi.auth.authorize({
client_id: this.clientId + '.apps.googleusercontent.com',
scope: 'https://www.googleapis.com/auth/drive.readonly',
immediate: immediate1
}, callback);
}
}; // FilePicker.prototype
/* rest of the code */
For now, what this code does is showing kind of a popup, but empty. Code is based on Daniel15's code.
What I already tried is:
relocating chunks of code, to server-side and client-side,
using htmlOutput, htmlTemplate - non of those works,
many other things, that i can't exactly remember.
What I would like to get is answer to the question: Why this code doesn't show Google Picker.
Thanks in advance.
Try adding a call origin and developer key
_showPicker: function() {
var accessToken = gapi.auth.getToken().access_token;
this.picker = new google.picker.PickerBuilder()
.addView(google.picker.ViewId.DOCUMENTS)
.setAppId(this.clientId)
.setOAuthToken(accessToken)
.setCallback(this._pickerCallback.bind(this))
.setOrigin('https://script.google.com') //
.setDeveloperKey(BROWSERKEYCREATEDINAPICONSOLE) //
.build()
.setVisible(true);
},

Backbone using external js

Hi all I have a site developed in cakephp and I would to integrate backbone on it.
For my scope I would to use external js for backbone to reuse the code.
I have write some lines but I can't append results on my element.
I have tried to print the "el" in this modes:
console.log($(this.el));
console.log(this.el);
console.log(this.$el);
But nothing I can't enter into el to make a simple append!
The container #search-results already exist
This is my main view:
<script type="text/javascript">
var search = {};
search.product = {};
search.product.template = "#results-product-template";
search.product.container = "#search-results";
search.product.defaults = {
id:0,
type:"product",
};
$(function(){
var ProductList = new Search.Collections.Products();
var ProductView = new Search.Views.Product({
// new Search.Collections.Products();
collection:ProductList
,el:$("#search-results")
});
function parseResults () {
var json = {
//my data
}
for (var i = json.products.length - 1; i >= 0; i--) {
ProductList.add([new Search.Models.Product(json.products[i])]);
};
updateResults();
}
function updateResults () {
console.log('updateResults: Ritorno il risultato quando hunter riceve una risposta dal server');
if ($('#search-results').length == 0) {
$('div.main > section:first-child').before('<section id="search-results"> <ul id="product-results"> <li>Contenuto</li> </ul> </section>');
}
ProductView.render();
}
// search
$('#search-results .close').on('click', function () {
$('#search-results').animate({height:0}, 500, function () {
$(this).remove();
})
});
});
</script>
And this is my external js with backbone
var Search = {
Models: {},
Collections: {},
Views: {},
Templates:{}
}
Search.Models.Product = Backbone.Model.extend({
defaults: search.product.defaults || {},
toUrl:function (url) {
return url.replace(" ", "-").toLowerCase();
},
initialize:function () {
console.log("initialize Search.Models.Product");
this.on("change", function (){
console.log("chiamato evento change del Model Search.Models.Product");
});
this.on("change:text", function () {
console.log("chiamato evento change:text del Model Search.Models.Product");
});
}
});
Search.Collections.Products = Backbone.Collection.extend({
model: Search.Models.Product,
initialize:function () {
console.log("initialize Search.Collections.Products");
console.log(this);
console.log(this.length);
console.log(this.models);
}
});
Search.Views.Product = Backbone.View.extend({
initialize:function () {
console.log("initialize Search.Views.Product");
console.log($(search.product.template).html());
},
template:function (data) {
if (data == null) {
data = this.collection.toJSON();
}
var template = Handlebars.compile($(search.product.template).html());
template(data);
},
render:function () {
console.log($(this.el));
$(this.el.append("TEST"));
//HERE IS THE PROBLEM
// I have tried this.$el.append("TEST");
return this;
}
});
Does this change anything?
var ProductView = new Search.Views.Product({
// new Search.Collections.Products();
collection:ProductList,
el:$("#search-results")[0]
});
I think backbone can accept both jQuery wrapped or not wrapped object and be fine, but I don't know what Backbone version you are using, see if this works
EDIT: From backbone 1.0 sources, it seems backbone can indeed take either a jQuery wrapped object or a regular dom element, it should still work
this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
Do you have something online (JSFiddle?) I will be happy to take a look, but this.$el should work and be equal to $("#search-results") from your code in a quick glance.
Have you tried using ProductView.setElement($("#search-results")) instead? it should be the same, but worth a try as well.

html color to alternative rows of dynamic table

I have a Dynamic table that I want to give color to on alternative rows. How can I achieve this with css? I need the code to work in IE7+
Look into using even/odd rules in CSS3.
Reference: https://developer.mozilla.org/en/CSS/:nth-child
For instance,
tr:nth-child(odd) will represent the CSS for every 2n + 1 child, whereas tr:nth-child(even) will represent the CSS for every 2n child.
i came across this same problem Friday, i used the jquery solution of
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
a stack overflow solution .js posted here
Detect changes in the DOM
so essentially you add the .js script in the head and fire the jquery rules on dom change.
My finished .js looked like this
<script type="text/javascript">
(function (window) {
var last = +new Date();
var delay = 100; // default delay
// Manage event queue
var stack = [];
function callback() {
var now = +new Date();
if (now - last > delay) {
for (var i = 0; i < stack.length; i++) {
stack[i]();
}
last = now;
}
}
// Public interface
var onDomChange = function (fn, newdelay) {
if (newdelay)
delay = newdelay;
stack.push(fn);
};
// Naive approach for compatibility
function naive() {
var last = document.getElementsByTagName('*');
var lastlen = last.length;
var timer = setTimeout(function check() {
// get current state of the document
var current = document.getElementsByTagName('*');
var len = current.length;
// if the length is different
// it's fairly obvious
if (len != lastlen) {
// just make sure the loop finishes early
last = [];
}
// go check every element in order
for (var i = 0; i < len; i++) {
if (current[i] !== last[i]) {
callback();
last = current;
lastlen = len;
break;
}
}
// over, and over, and over again
setTimeout(check, delay);
}, delay);
}
//
// Check for mutation events support
//
var support = {};
var el = document.documentElement;
var remain = 3;
// callback for the tests
function decide() {
if (support.DOMNodeInserted) {
window.addEventListener("DOMContentLoaded", function () {
if (support.DOMSubtreeModified) { // for FF 3+, Chrome
el.addEventListener('DOMSubtreeModified', callback, false);
} else { // for FF 2, Safari, Opera 9.6+
el.addEventListener('DOMNodeInserted', callback, false);
el.addEventListener('DOMNodeRemoved', callback, false);
}
}, false);
} else if (document.onpropertychange) { // for IE 5.5+
document.onpropertychange = callback;
} else { // fallback
naive();
}
}
// checks a particular event
function test(event) {
el.addEventListener(event, function fn() {
support[event] = true;
el.removeEventListener(event, fn, false);
if (--remain === 0) decide();
}, false);
}
// attach test events
if (window.addEventListener) {
test('DOMSubtreeModified');
test('DOMNodeInserted');
test('DOMNodeRemoved');
} else {
decide();
}
// do the dummy test
var dummy = document.createElement("div");
el.appendChild(dummy);
el.removeChild(dummy);
// expose
window.onDomChange = onDomChange;
})(window);
$(document).ready(function () {
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
onDomChange(function () {
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
});
});
</script>
I would like to caveat this answer that this probably is not the greatest solution but worked for what i needed it to do. :-)
CSS3 nth-child selector:
tr:nth-child(odd) {
background: red /* or whatever */;
}
You can use a CSS3 selector:
tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}
or jQuery:
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
or do it on the server side.

Display image with requestFileSystem and toUrl() function

I made an application who use requestFileSystem. Everything works fine.
Add a new image and store it in an persistent local file system.
Does anybody know how to display an image with toUrl() ?
...
window.requestFileSystem(window.PERSISTENT, 5*1024*1024, function(fs){
fs.root.getDirectory(itemId, {create: false}, function(dirEntry) {
var dirReader = dirEntry.createReader();
var entries = [];
var readEntries = function() {
dirReader.readEntries (function(results) {
if (!results.length) {
listResults(entries.sort(), itemId);
} else {
entries = entries.concat(fsdatas.dir.toArray(results));
readEntries();
}
}, errorHandler);
};
readEntries();
});
}, errorHandler);
...
And
function listResults(entries, itemId) {
document.querySelector('#listRecordFiles-'+itemId).innerHTML = '';
var fragment = document.createDocumentFragment();
var i = 0;
entries.forEach(function(entry, i) {
i++;
var img = document.createElement('img');
img.src = entry.toURL();
fragment.appendChild(img);
});
document.querySelector('#listRecordFiles-'+itemId).appendChild(fragment);
}
The output is :
<img src="filesystem:http://domain.tld/persistent/1/image-test.jpg">
But nothing is displayed on browser.
The example below is a snippet of code responsible for reading the images saved in the application's root directory, and show in the document body.
Remember, in this case, I used navigator.camera.DestinationType.DATA_URL to open the PHOTOLIBRARY, and saved the image content using atob (ascii to binary), so carry the image with btoa (binary to ascii)
function myLoadFile(filename) {
var myDocument = document.querySelector("body");
filesystem.root.getFile(filename, {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement('img');
// if you save the file with atob (ascii to binary), then:
img.src = "data:image/jpeg;base64,"+btoa(this.result);
// if you don't save the file without atob, then:
// img.src = "data:image/jpeg;base64,"+this.result;
myDocument.appendChild(img)
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}