Partage
  • Partager sur Facebook
  • Partager sur Twitter

Bookmarklet & JSONP

Marche ni sous IE ni sous Safari...

Sujet résolu
    26 avril 2009 à 15:43:43

    Hi all !

    N'ayant rien de spécial à faire aujourd'hui je me suis dis que j'allais faire un bookmarklet utile, j'ai donc pensé à un bookmark pour un tinyurl-like, je me suis pencher vers reque.st car je l'aime bien et qu'il possède une API simple, bref il existe déjà un bookmarklet qui fait intervenir deux prompt(); et je trouve ça dommage, quand je suis sur une page je veux juste raccourcir l'url de cette page, les autres je m'en fiche, bref je me suis pencher sur le bookmarklet d'origine surtout pour le JSONP que je ne connais que de nom (et grosso modo son fonctionnement), et il y a un truc dont je ne comprends pas bien dans la fonction getJSON :

    function getJSON(url, success) {
    		var uniqueId = 'json' + (Math.random() * 100).toString().replace(/\./g, '');
    
    		window[uniqueId] = function(i) { //<<<ce bloc je ne vois pas trop comment il fonctionne/ni son intérêt
    			success && success(i);
    		};
    
    		document.getElementsByTagName('body')[0].appendChild(
    			(function() {
    				var script = document.createElement('script');
    				script.type = 'text/javascript';
    				script.src = url.replace('callback=?', 'callback=' + uniqueId);
    
    				return script;
    			})()
    		);
    	}
    

    (fonction originale de James Padolsey)

    A la base ça n'est pas pour ça que je postais mais si quelqu'un peut m'expliquer brièvement, ça serait sympa :p

    Mon vrai problème (pê vient-il de getJSON()) est que le script que j'ai fait ne fonctionne ni sous IE ni sous Safari (et c'est ma faute je ne l'ai pas testé au cours du "développement" car je comptais faire un bookmark pour moi-même donc s'il ne marchait pas sous IE c'était pas grave, et puis je me suis dit par la suite que ça pourrait être sympa de le partager (donc il faut que ça fonctionne sous IE/Safari)).

    Quan dje dit "ne marche pas" comprenez rien ne s'affiche, donc je suppose qu'il ne se passe rien, il faudrait vérifier en regardant le code source généré sous IE et Safari mais je ne sais pas faire :s (qu'est-que j'aime mon panda roux ♥)

    Bref voila le script auquel je suis arrivé :

    javascript:
    (function() {
    
    	var url;
    
    	function getJSON(url, success) {
    		var uniqueId = 'json' + (Math.random() * 100).toString().replace(/\./g, '');
    
    		window[uniqueId] = function(i) {
    			success && success(i);
    		};
    
    		document.getElementsByTagName('body')[0].appendChild(
    			(function() {
    				var script = document.createElement('script');
    				script.type = 'text/javascript';
    				script.src = url.replace('callback=?', 'callback=' + uniqueId);
    
    				return script;
    			})()
    		);
    	}
    
    	if(location.href != 'about:blank') {
    		url = window.location.href;
    	}
    
    	if(url) {
    		getJSON('http://reque.st/create.api.php?json&callback=?&url=' + encodeURIComponent(url), function(data) {
    
    			var showResult = document.createElement('div'),
    				style = {
    					margin: '0',
    					padding: '15px',
    					position: 'fixed',
    					top: '0',
    					left: '0',
    					width: '100%',
    					backgroundColor: 'rgba(0,0,0,0.75)',
    					color: '#ffffff',
    					fontSize: '12px',
    					fontFamily: 'Helvetica, "Segoe UI", Calibri, Tahoma, Arial, serif',
    					textAlign: 'center',
    					borderBottom: '1px solid white'
    				};
    
    			showResult.id = 'showResult';
    
    			for(var i in style) {
    				showResult.style[i] = style[i];
    			}
    
    			if(data.url) {
    				showResult.appendChild(document.createTextNode('Here is the short URL :'));
    
    				showResult.appendChild(document.createElement('br'));
    				showResult.appendChild(document.createElement('br'));
    
    				var link = document.createElement('a'),
    					linkStyle = {
    						color: '#ffffff',
    						fontSize: '14px',
    						fontFamily: 'Helvetica, "Segoe UI", Calibri, Tahoma, Arial, serif',
    						fontWeight: 'bold',
    						textDecoration: 'none'
    					};
    
    				for(var j in linkStyle) {
    					link.style[j] = linkStyle[j];
    				}
    
    					link.href= data.url;
    					link.appendChild(document.createTextNode(data.url));
    
    				showResult.appendChild(link);
    			}
    
    			else {
    				showResult.appendChild(document.createTextNode('There is a error :'));
    				showResult.appendChild(document.createElement('br'));
    				showResult.appendChild(document.createElement('br'));
    
    				var error = document.createElement('span'),
    					errorStyle = {
    						fontWeight: 'bold',
    						fontSize: '14px'
    					};
    
    				for(var k in errorStyle) {
    					error.style[k] = errorStyle[k];
    				}
    
    				error.appendChild(document.createTextNode(data.error));
    
    				showResult.appendChild(error);
    				showResult.appendChild(document.createElement('br'));
    				showResult.appendChild(document.createElement('br'));
    				showResult.appendChild(document.createTextNode('Please retry.'));
    
    			}
    
    			document.getElementsByTagName('body')[0].appendChild(showResult);
    
    			showResult.ondblclick = function() {
    				document.getElementsByTagName('body')[0].removeChild(document.getElementById('showResult'));
    			};
    		});
    	}
    
    })();
    


    Et si vous voulez tester le bookmark, le voici !
    javascript:(function(){var%20url;function%20getJSON(url,success){var%20uniqueId='json'+(Math.random()*100).toString().replace(/\./g,'');window[uniqueId]=function(i){success&&success(i)};document.getElementsByTagName('body')[0].appendChild((function(){var%20script=document.createElement('script');script.type='text/javascript';script.src=url.replace('callback=?','callback='+uniqueId);return%20script})())}if(location.href!='about:blank'){url=window.location.href}if(url){getJSON('http://reque.st/create.api.php?json&callback=?&url='+encodeURIComponent(url),function(data){var%20showResult=document.createElement('div'),style={margin:'0',padding:'15px',position:'fixed',top:'0',left:'0',width:'100%',backgroundColor:'rgba(0,0,0,0.75)',color:'#ffffff',fontSize:'12px',fontFamily:'Helvetica,%20"Segoe%20UI",%20Calibri,%20Tahoma,%20Arial,%20serif',textAlign:'center',borderBottom:'1px%20solid%20white'};showResult.id='showResult';for(var%20i%20in%20style){showResult.style[i]=style[i]}if(data.url){showResult.appendChild(document.createTextNode('Here%20is%20the%20short%20URL%20:'));showResult.appendChild(document.createElement('br'));showResult.appendChild(document.createElement('br'));var%20link=document.createElement('a'),linkStyle={color:'#ffffff',fontSize:'14px',fontFamily:'Helvetica,%20"Segoe%20UI",%20Calibri,%20Tahoma,%20Arial,%20serif',fontWeight:'bold',textDecoration:'none'};for(var%20j%20in%20linkStyle){link.style[j]=linkStyle[j]}link.href=data.url;link.appendChild(document.createTextNode(data.url));showResult.appendChild(link)}else{showResult.appendChild(document.createTextNode('There%20is%20a%20error%20:'));showResult.appendChild(document.createElement('br'));showResult.appendChild(document.createElement('br'));var%20error=document.createElement('span'),errorStyle={fontWeight:'bold',fontSize:'14px'};for(var%20k%20in%20errorStyle){error.style[k]=errorStyle[k]}error.appendChild(document.createTextNode(data.error));showResult.appendChild(error);showResult.appendChild(document.createElement('br'));showResult.appendChild(document.createElement('br'));showResult.appendChild(document.createTextNode('Please%20retry.'))}document.getElementsByTagName('body')[0].appendChild(showResult);showResult.ondblclick=function(){document.getElementsByTagName('body')[0].removeChild(document.getElementById('showResult'))}})}})();
    


    Si vous avez deux trois pistes/idées pour m'aider je suis preneur :p Merci !

    PS : le code n'est pas commenté, si vous voulez je peux vous le commenter ;)
    • Partager sur Facebook
    • Partager sur Twitter
      26 avril 2009 à 15:48:29

      Pourquoi javascript: ? C'est dans un href ? Si oui, c'est pas bien... il faut y mettre dans le onclick sans javascript:
      Voir bonnes pratiques javascript dans les tutoriels...
      • Partager sur Facebook
      • Partager sur Twitter
        26 avril 2009 à 15:50:18

        C'est un bookmarklet hein...
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          26 avril 2009 à 16:02:24

          haha j'allais faire la même remarque mais j'ai eu le temps de réfléchir. Jamais rien compris aux bookmarklets.

          Pour ce qui est du premier bout de code c'est un peu tordu mais y'a pas 36 autres solutions.

          Tu crée une variable globale qui à pour nom un certain id. donc si tu as ton id unique qui est json1234567 alors la fonction globale json1234567 sera la fonction success que tu passes en deuxième paramètre de getJSON.

          Cet id unique est lui passé au script que tu appelle et qui manifestement inclu un appel à ta fonction success par le biais de json1234567. C'est une norme plus ou moins implicite pour que tu puisse avoir un évènement déclanché par le script distant que tu inclus (j'espère que t'as confiance :p) pour simuler un peu le comportement d'une requete ajax.

          Pas sur d'avoir bien été clair…

          Pour le reste je sais pô.
          • Partager sur Facebook
          • Partager sur Twitter
            26 avril 2009 à 16:10:04

            Citation

            Jamais rien compris aux bookmarklets.


            :o Rien compris ou jamais vu l'utilité ?

            Citation

            Pas sur d'avoir bien été clair…


            Bah plus ou moins en fait :p

            Parce que pour mois success && success(i) ça ressemble à une condition :/

            Citation

            (j'espère que t'as confiance :p)


            Oui je fais confiance ^^ (reque.st appartient à James Padolsey qui m'a l'air d'être quelqu'un de sérieux)

            Et puis si vous trouvez pas pour IE/Safari c'est pas dramatique non plus, à la base c'est pour un usage perso ^^
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              26 avril 2009 à 16:23:34

              Jamais pigé comment on utilisait ce truc. J'ai essayer une fois, marchais pas => hop aux oubliettes et vu que je cache ma barre de favoris tout le temps… Mais je viens de capter le truc là.

              Confiance, je parlais le domaine duquel tu inclus le script, pas le script qui fait le «sale travail». Il peuvent faire tout et n'importe quoi du fait que tu inclus leur script.

              Pour en revenir au code, c'est pas une condition, enfin si, mais pas seulement.

              success && success(i);
              


              Tu passes une fonction dans success.
              Le premier success renvoie une fonction, qui est évalué comme "true" dans une condition, on continue donc apprès le && et là : pouf on execute la fonction que l'on a.

              Maintenant tu ne passes pas de fonction, success est donc "undefined" qui est évalué comme "false" dans une condition donc on s'arrete avant le && et la fonction n'est pas executée.

              ( edit )
              Par exemple, pour vérifier la présence de la méthode print (héhé ;) )
              window.print && window.print();
              



              Ensuite pour l'histoire de callback.

              Pas de callback (success vide) le script renvoie (c'est possible que ça soit pas ça, faut voir):
              {"objet":"json normal"}
              


              tu passes un callback (success est une fonction):
              json1234567({"objet":"json normal"});
              



              Pour le reste ça donne quoi à coups de alert()?
              • Partager sur Facebook
              • Partager sur Twitter
                26 avril 2009 à 17:34:19

                (si ta barre de favori est masquée en effet ça sert pas à grand chose ^^)

                Citation

                Confiance, je parlais le domaine duquel tu inclus le script, pas le script qui fait le «sale travail». Il peuvent faire tout et n'importe quoi du fait que tu inclus leur script.


                Oui oui, mais j'ai confiance envers le type qui possède le domaine, donc j'ai confiance au domaine :p

                Ah ce coup-ci je crois que j'ai compris ;)

                Pour les alert() je teste et j'édite ;)

                Edit :

                C'est simple, IE ne me loggue rien du tout ! (Safari quant à lui marche je sais pas comment je me suis débrouillé tout à l'heure !)

                Le code avec les alert(), le compte-rendu est en haut.

                /*
                	Résultat des alert() & console.log() :
                	
                	FF:
                		http://www.google.fr/
                		[object HTMLScriptElement]
                		[object HTMLDivElement]
                		Here is the short URL :<br><br>
                		Here is the short URL :<br><br><a href="http://reque.st/6321" style="color: rgb(255, 255, 255); font-size: 14px; font-family: Helvetica,&quot;Segoe UI&quot;,Calibri,Tahoma,Arial,serif; font-weight: bold; text-decoration: none;">http://reque.st/6321</a>
                	
                	IE: (ne loggue rien)
                	
                	Safari: (Safari ok finalement, je comprends pas :/)
                		http://google.fr/
                		[object HTMLScriptElement]
                		[object HTMLDivElement]
                		Here is the short URL :<br><br>
                		Here is the short URL :<br><br><a href="http://reque.st/6321" style="color: rgb(255, 255, 255); font-size: 14px; font-family: Helvetica,&quot;Segoe UI&quot;,Calibri,Tahoma,Arial,serif; font-weight: bold; text-decoration: none;">http://reque.st/6321</a>
                */
                
                javascript:
                (function() {
                
                	var url;
                
                	function getJSON(url, success) {
                		var uniqueId = 'json' + (Math.random() * 100).toString().replace(/\./g, '');
                
                		window[uniqueId] = function(i) {
                			success && success(i);
                		};
                
                		document.getElementsByTagName('body')[0].appendChild(
                			(function() {
                				var script = document.createElement('script');
                				script.type = 'text/javascript';
                				script.src = url.replace('callback=?', 'callback=' + uniqueId);
                				
                				console.log(script);
                				alert(script);
                
                				return script;
                			})()
                		);
                	}
                
                	if(location.href != 'about:blank') {
                		url = window.location.href;
                	}
                	
                	alert(url);
                	console.log(url);
                
                	if(url) {
                		
                		getJSON('http://reque.st/create.api.php?json&callback=?&url=' + encodeURIComponent(url), function(data) {
                
                			var showResult = document.createElement('div'),
                				style = {
                					margin: '0',
                					padding: '15px',
                					position: 'fixed',
                					top: '0',
                					left: '0',
                					width: '100%',
                					backgroundColor: 'rgba(0,0,0,0.75)',
                					color: '#ffffff',
                					fontSize: '12px',
                					fontFamily: 'Helvetica, "Segoe UI", Calibri, Tahoma, Arial, serif',
                					textAlign: 'center',
                					borderBottom: '1px solid white'
                				};
                
                			showResult.id = 'showResult';
                			
                			console.log(showResult);
                			alert(showResult);
                
                			for(var i in style) {
                				showResult.style[i] = style[i];
                			}
                
                			if(data.url) {
                				showResult.appendChild(document.createTextNode('Here is the short URL :'));
                
                				showResult.appendChild(document.createElement('br'));
                				showResult.appendChild(document.createElement('br'));
                				
                				console.log(showResult.innerHTML);
                				alert(showResult.innerHTML);
                
                				var link = document.createElement('a'),
                					linkStyle = {
                						color: '#ffffff',
                						fontSize: '14px',
                						fontFamily: 'Helvetica, "Segoe UI", Calibri, Tahoma, Arial, serif',
                						fontWeight: 'bold',
                						textDecoration: 'none'
                					};
                
                				for(var j in linkStyle) {
                					link.style[j] = linkStyle[j];
                				}
                
                					link.href= data.url;
                					link.appendChild(document.createTextNode(data.url));
                
                				showResult.appendChild(link);
                				
                				console.log(showResult.innerHTML);
                				alert(showResult.innerHTML);
                			}
                
                			else {
                				showResult.appendChild(document.createTextNode('There is a error :'));
                				showResult.appendChild(document.createElement('br'));
                				showResult.appendChild(document.createElement('br'));
                				
                				console.log(showResult.innerHTML);
                				alert(showResult.innerHTML);				
                
                				var error = document.createElement('span'),
                					errorStyle = {
                						fontWeight: 'bold',
                						fontSize: '14px'
                					};
                
                				for(var k in errorStyle) {
                					error.style[k] = errorStyle[k];
                				}
                
                				error.appendChild(document.createTextNode(data.error));
                
                				showResult.appendChild(error);
                				showResult.appendChild(document.createElement('br'));
                				showResult.appendChild(document.createElement('br'));
                				showResult.appendChild(document.createTextNode('Please retry.'));
                				
                				console.log(showResult.innerHTML);
                				alert(showResult.innerHTML);
                
                			}
                
                			document.getElementsByTagName('body')[0].appendChild(showResult);
                
                			showResult.ondblclick = function() {
                				document.getElementsByTagName('body')[0].removeChild(document.getElementById('showResult'));
                			};
                		});
                	}
                
                })();
                
                • Partager sur Facebook
                • Partager sur Twitter
                  26 avril 2009 à 20:00:59

                  C'est quoi les bookmarklet ?
                  T'as appris où ?
                  Ca sert à quoi ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    26 avril 2009 à 23:10:07

                    haha excellent :)
                    xavier 0 – cerium 1

                    :p
                    • Partager sur Facebook
                    • Partager sur Twitter
                      26 avril 2009 à 23:20:43

                      En fait, c'est (plus ou moins) le concept que reproduit GreaseMonkey, c'est ça ?
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        26 avril 2009 à 23:27:18

                        ouais vaguement. Mais pour les pauvres :p
                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 avril 2009 à 10:03:05

                          J'utilise GreaseMonkey ;) mais dans ce cas particulier je trouve un bookmarklet plus adapté :)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 avril 2009 à 13:46:04

                            Tain je suis con... en plus on m'en avait parlé pour le truc des smileys perso...
                            Mais présenté comme ça j'ai pas capté que c'était des truc dans l'url...
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Anonyme
                              27 avril 2009 à 13:50:01

                              Pour en revenir au problème, quand tu teste sous IE faut que tu vires les console.log sinon ça fait tout planter sous IE6 et 7.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                27 avril 2009 à 17:27:00

                                Même une fois enlevés ça n'alert() rien ;)
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  28 avril 2009 à 18:18:32

                                  Bon j'ai tenté de recoder de 0, et il semble que le problème viennent de IE, je vous montre mon nouveau code :

                                  javascript:
                                  
                                  //some alias for common tasks
                                  
                                  function $(id) { //string
                                  	return document.getElementById(id);
                                  }
                                  
                                  function $$(tagName, context) { //string, HTMLElement
                                  	return context ? context.getElementsByTagName(tagName) : document.getElementsByTagName(tagName);
                                  }
                                  

                                  Ça s'est juste pour aller plus vite, rien de bien compliqué/intéressant.

                                  function createElement(tagName, text, attributes) { //string, string, object
                                  	var element = document.createElement(tagName);
                                  	
                                  	element.appendChild(document.createTextNode(text));
                                  	
                                  	for(var i in attributes) {
                                  		element[i] = attributes[i];
                                  		//element.setAttribute(i, attributes[i]);
                                  	}
                                  	
                                  	return element;
                                  }
                                  

                                  Ça (et a priori c'est là que ça m**** sous IE) c'est pour créer rapidement un élément Html, tout en lui attribuant un noeud de texte, et éventuellement des attributs (passé en paramètres sous forme d'objet).

                                  function css(element, style) { //HTMLElement, object
                                  	for(var i in style) {
                                  		element.style[i] = style[i];
                                  	}
                                  }
                                  

                                  Je le poste au cas où mais je ne pense pas que ça ait de rapport avec mon problème (je ne style pas les balises script ^^).

                                  function getJSON(url, callback) {
                                  	var id = 'jsonp' + (Math.random() * 100).toString().replace(/(\n|\r|\.)+/g, '');
                                  	
                                  	window[id] = function (data) {
                                  		if(callback) {
                                  			callback(data);
                                  		}
                                  	};
                                  	
                                  	$$('body')[0].appendChild(
                                  	//	createElement('script', '', {type: 'text/javascript', src: url.replace('callback=?', 'callback=' + id)})
                                  	/*	
                                  		(function() {
                                  			var script = document.createElement('script');
                                  			script.type = 'text/javascript';
                                  			script.src = url.replace('callback=?', 'callback=' + id);
                                  			
                                  			return script;
                                  		})()
                                  	*/
                                  	);
                                  }
                                  

                                  La "nouvelle" fonction getJSON, que je crois avoir bien compris désormais, elle est intéressante car on note deux choses :
                                  >Si je créer la balise script via createElement le script marche nickel sous ff, opera, safari, mais pas sous IE. (commentaire court)
                                  >Si je créer la balise script de manière "traditionnelle" (commentaire long) cela marche sous ff, opera, safari et IE.

                                  (function() {
                                  
                                  	var url;
                                  	
                                  	$('gbar').innerHTML = 'O_o';
                                  	
                                  	$$('a')[0].innerHTML = 'I\'m a link!';
                                  	
                                  	$$('body')[0].appendChild(createElement('a', 'I am a dynamic link !', {href: '#ieTest'}));
                                  	
                                  	css($('gbar'), {color: 'blue', fontWeight: 'bold'});
                                  	
                                  	getJSON('http://reque.st/create.api.php?json&callback=?&url=' + encodeURIComponent('http://google.fr'), function(data) { alert(data.url); });
                                  
                                  })();
                                  

                                  Code qui sert juste à tester que les fonctions fonctionnent bien (tester sur google.fr) et donc elles fonctionnent toutes bien (même sous IE) excepté getJSON, alors que createElement tout seul marche bien :s

                                  (le code est complet et posté dans l'ordre ;))

                                  Grosso modo mon problème est que je voudrais que le script marche en passant par createElement() parce que je suis têtu et que si j'ai créé la fonction (même si l'idée n'est pas de moi :p) c'est pour qu'elle serve !

                                  Merci à ceux qui se sont déjà penchés/se pencheront sur mon problème :) Si vous avez des questions, comme d'hab demandez :)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    29 avril 2009 à 12:46:31

                                    Bah essayes de nommer ta fonction autrement que createElement...
                                    Vu que ça existe déjà, certains navigateurs doivent pas aimer...
                                    Et vu qu'elle appelle justement createElement, vu que tu redéfinis cette fonction, ça doit faire une boucle infinie...
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      29 avril 2009 à 16:17:08

                                      Oups j'ai oublié d'éditer, le nom de la fonction ne gêne en rien car fonction != méthode je pense, bref j'ai résolu mon problème en vérifiant si les paramètres de la fonction exitaient avant de les créer (pas très clair).
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        29 avril 2009 à 16:19:51

                                        Ah oui... j'avais oulié ça :p
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Bookmarklet & JSONP

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                        • Editeur
                                        • Markdown