From 22579925bad75e30299e2e4f1fc3d2d5bc0c3eb5 Mon Sep 17 00:00:00 2001 From: renato <renato@rezo.net> Date: Tue, 15 May 2007 16:56:56 +0000 Subject: [PATCH] highlight in javascript; var_recherche is no more used --- .gitattributes | 1 + dist/javascript/SEhighlight.js | 223 +++++++++++++++++++++++++++++++++ ecrire/inc/surligne.php | 173 +++++++------------------ ecrire/public/assembler.php | 4 +- ecrire/public/balises.php | 22 +--- ecrire/public/stats.php | 3 +- 6 files changed, 272 insertions(+), 154 deletions(-) create mode 100644 dist/javascript/SEhighlight.js diff --git a/.gitattributes b/.gitattributes index 87cf7c0cf6..720f518dc8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -229,6 +229,7 @@ dist/inc-petition.html -text dist/inc-pied.html -text dist/inc-rss-item.html -text dist/inc-rubriques.html -text +dist/javascript/SEhighlight.js -text dist/javascript/ajaxCallback.js -text dist/javascript/articles_tous_edite.js -text dist/javascript/async_upload.js -text diff --git a/dist/javascript/SEhighlight.js b/dist/javascript/SEhighlight.js new file mode 100644 index 0000000000..e35590ce3b --- /dev/null +++ b/dist/javascript/SEhighlight.js @@ -0,0 +1,223 @@ +/** + * SEhighlight plugin for jQuery + * + * Thanks to Scott Yang <http://scott.yang.id.au/> + * for the original idea and some code + * + * @author Renato Formato <renatoformato@virgilio.it> + * + * @version 0.32 + * + * Options + * - exact (string, default:"exact") + * "exact" : find and highlight the exact words. + * "whole" : find partial matches but highlight whole words + * "partial": find and highlight partial matches + * + * - style_name (string, default:'hilite') + * The class given to the span wrapping the matched words. + * + * - style_name_suffix (boolean, default:true) + * If true a different number is added to style_name for every different matched word. + * + * - debug_referrer (string, default:null) + * Set a referrer for debugging purpose. + * + * - engines (array of regex, default:null) + * Add a new search engine regex to highlight searches coming from new search engines. + * The first element is the regex to match the domain. + * The second element is the regex to match the query string. + * Ex: [/^http:\/\/my\.site\.net/i,/search=([^&]+)/i] + * + * - startHighlightComment (string, default:null) + * The text of a comment that starts a block enabled for highlight. + * If null all the document is enabled for highlight. + * + * - stopHighlightComment (string, default:null) + * The text of a comment that ends a block enabled for highlight. + * If null all the document is enabled for highlight. + */ + +(function($){ + jQuery.fn.SEhighlight = function(options) { + var ref = options.debug_referrer || document.referrer; + if(!ref && options.keys==undefined) return this; + + SEhighlight.options = $.extend({exact:"exact",style_name:'hilite',style_name_suffix:true},options); + + if(options.engines) SEhighlight.engines.unshift(options.engines); + var q = (options.keys?options.keys.split(/[\s,\+\.]+/):false) || SEhighlight.decodeURL(ref,SEhighlight.engines); + if(q) { + SEhighlight.buildReplaceTools(q); + return this.each(function(){ + var el = this; + if(el==document) el = $("body")[0]; + SEhighlight.hiliteElement(el, q); + }) + } else return this; + } + + var SEhighlight = { + options: {}, + regex: [], + engines: [ + [/^http:\/\/(www\.)?google\./i, /q=([^&]+)/i], // Google + [/^http:\/\/(www\.)?search\.yahoo\./i, /p=([^&]+)/i], // Yahoo + [/^http:\/\/(www\.)?search\.msn\./i, /q=([^&]+)/i], // MSN + [/^http:\/\/(www\.)?search\.live\./i, /query=([^&]+)/i], // MSN Live + [/^http:\/\/(www\.)?search\.aol\./i, /userQuery=([^&]+)/i], // AOL + [/^http:\/\/(www\.)?ask\.com/i, /q=([^&]+)/i], // Ask.com + [/^http:\/\/(www\.)?altavista\./i, /q=([^&]+)/i], // AltaVista + [/^http:\/\/(www\.)?feedster\./i, /q=([^&]+)/i], // Feedster + [/^http:\/\/(www\.)?search\.lycos\./i, /q=([^&]+)/i], // Lycos + [/^http:\/\/(www\.)?alltheweb\./i, /q=([^&]+)/i], // AllTheWeb + [/^http:\/\/(www\.)?technorati\.com/i, /([^\?\/]+)(?:\?.*)$/i], // Technorati + ], + subs: {}, + decodeURL: function(URL,reg) { + URL = decodeURIComponent(URL); + var query = null; + $.each(reg,function(i,n){ + if(n[0].test(URL)) { + var match = URL.match(n[1]); + if(match) { + query = match[1]; + return false; + } + } + }) + + if (query) { + query = query.replace(/(\'|")/, '\$1'); + query = query.split(/[\s,\+\.]+/); + } + + return query; + }, + regexAccent : [ + [/[\xC0-\xC5]/ig,'a'], + [/[\xD2-\xD6\xD8]/ig,'o'], + [/[\xC8-\xCB]/ig,'e'], + [/\xC7/ig,'c'], + [/[\xCC-\xCF]/ig,'i'], + [/[\xD9-\xDC]/ig,'u'], + [/\xFF/ig,'y'], + [/\xD1/ig,'n'], + [/[\x91\x92\u2018\u2019]/ig,'\''] + ], + matchAccent : /[\x91\x92\u2018\u2019\xC0-\xC5\xC7-\xCF\xD1-\xD6\xD8-\xDC\xFF]/ig, + replaceAccent: function(q) { + SEhighlight.matchAccent.lastIndex = 0; + if(SEhighlight.matchAccent.test(q)) { + for(var i=0,l=SEhighlight.regexAccent.length;i<l;i++) + q = q.replace(SEhighlight.regexAccent[i][0],SEhighlight.regexAccent[i][1]); + } + return q; + }, + buildReplaceTools : function(query) { + re = new Array(); + for (var i = 0, l=query.length; i < l; i ++) { + query[i] = SEhighlight.replaceAccent(query[i].toLowerCase()); + re.push(query[i]); + } + + var regex = re.join("|"); + switch(SEhighlight.options.exact) { + case "exact": + regex = '\\b(?:'+regex+')\\b'; + break; + case "whole": + regex = '\\b\\w*('+regex+')\\w*\\b'; + break; + } + SEhighlight.regex = new RegExp(regex, "gi"); + + for (var i = 0, l = query.length; i < l; i ++) { + SEhighlight.subs[query[i]] = SEhighlight.options.style_name+ + (SEhighlight.options.style_name_suffix?i+1:''); + } + }, + nosearch: /s(?:cript|tyle)|textarea/i, + hiliteElement: function(el, query) { + var startIndex, endIndex, comment = false, opt = SEhighlight.options; + if(!opt.startHighlightComment || !opt.stopHighlightComment) + return SEhighlight.hiliteTree(0,el.childNodes.length,el,query); + if($.browser.msie) { + var item = el.firstChild, i = 0, parents = [], startComment = false; + while(item) { + if(item.nodeType==8) { + if($.trim(item.data)==opt.startHighlightComment) { + comment = startComment = true; + startIndex= i+1; + } else if($.trim(item.data)==opt.stopHighlightComment) { + endIndex = i; + SEhighlight.hiliteTree(startIndex,endIndex,item.parentNode,query); + startComment = false; + } + } + var next = item.nextSibling, back, child; + if(!startComment && (child = item.firstChild)) { + if(next) + parents.push([next,i+1]); + item = child; + i = 0; + } else { + if(!(item = next)) { + if(back = parents.pop()) { + item = back[0]; + i = back[1]; + } + } else i++; + } + } + } else { + var walker = document.createTreeWalker(el,NodeFilter.SHOW_COMMENT,null,false), currComment; + while(currComment = walker.nextNode()) { + if($.trim(currComment.data)==opt.startHighlightComment) { + comment = true; + el = currComment.parentNode; + startIndex = 0; + endIndex = el.childNodes.length; + while(el.childNodes[startIndex]!=currComment) startIndex++; + startIndex++; + } else if($.trim(currComment.data)==opt.stopHighlightComment) { + while(el.childNodes[endIndex-1]!=currComment) endIndex--; + SEhighlight.hiliteTree(startIndex,endIndex,el,query); + } + } + } + if(!comment) SEhighlight.hiliteTree(0,el.childNodes.length,el,query); + }, + hiliteTree : function(startIndex,endIndex,el,query) { + var matchIndex = SEhighlight.options.exact=="whole"?1:0; + for(;startIndex<endIndex;startIndex++) { + var item = el.childNodes[startIndex]; + if ( item.nodeType != 8 ) {//comment node + //text node + if(item.nodeType==3) { + var text = item.data, textNoAcc = SEhighlight.replaceAccent(text); + var newtext="",match,index=0; + SEhighlight.regex.lastIndex = 0; + while(match = SEhighlight.regex.exec(textNoAcc)) { + newtext += text.substr(index,match.index-index)+'<span class="'+ + SEhighlight.subs[match[matchIndex].toLowerCase()]+'">'+text.substr(match.index,match[0].length)+"</span>"; + index = match.index+match[0].length; + } + if(newtext) { + //add ther last part of the text + newtext += text.substring(index); + var repl = $.merge([],$("<span>"+newtext+"</span>")[0].childNodes); + endIndex += repl.length-1; + startIndex += repl.length-1; + $(item).before(repl).remove(); + } + } else { + if(item.nodeType==1 && item.nodeName.search(SEhighlight.nosearch)==-1) + SEhighlight.hiliteTree(0,item.childNodes.length,item,query); + } + } + } + } + + }; +})(jQuery) diff --git a/ecrire/inc/surligne.php b/ecrire/inc/surligne.php index 49fc8368e8..7197bfee26 100644 --- a/ecrire/inc/surligne.php +++ b/ecrire/inc/surligne.php @@ -17,136 +17,49 @@ if (!defined("_ECRIRE_INC_VERSION")) return; // Ces commentaires vont etre substitue's en mode recherche // voir les champs SURLIGNE dans inc-index-squel -define("MARQUEUR_SURLIGNE", '!-- debut_surligneconditionnel -->'); -define("MARQUEUR_FSURLIGNE", '!-- finde_surligneconditionnel -->'); - -// http://doc.spip.org/@surligner_sans_accents -function surligner_sans_accents ($mot) { - $accents = - /* A */ chr(192).chr(193).chr(194).chr(195).chr(196).chr(197). - /* a */ chr(224).chr(225).chr(226).chr(227).chr(228).chr(229). - /* O */ chr(210).chr(211).chr(212).chr(213).chr(214).chr(216). - /* o */ chr(242).chr(243).chr(244).chr(245).chr(246).chr(248). - /* E */ chr(200).chr(201).chr(202).chr(203). - /* e */ chr(232).chr(233).chr(234).chr(235). - /* Cc */ chr(199).chr(231). - /* I */ chr(204).chr(205).chr(206).chr(207). - /* i */ chr(236).chr(237).chr(238).chr(239). - /* U */ chr(217).chr(218).chr(219).chr(220). - /* u */ chr(249).chr(250).chr(251).chr(252). - /* yNn */ chr(255).chr(209).chr(241); - - if ($GLOBALS['meta']['charset'] == 'utf-8') { - include_spip('inc/charsets'); - $mot = unicode2charset(utf_8_to_unicode($mot), 'iso-8859-1'); - } - - return strtr($mot, $accents, "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn"); -} - -// tres sale -// http://doc.spip.org/@split_by_char -function split_by_char($str) { -$len = strlen($str); -$streturn = array(); -for ($i=0; $i<$len; $i++) { -$streturn[$i] = substr($str, $i, 1); -} -return $streturn; -} - -// http://doc.spip.org/@surligner_regexp_accents -function surligner_regexp_accents ($mot) { - $accents_regexp = array( - "a" => "[a".chr(224).chr(225).chr(226).chr(227).chr(228).chr(229). chr(192).chr(193).chr(194).chr(195).chr(196).chr(197)."]", - "o" => "[o".chr(242).chr(243).chr(244).chr(245).chr(246).chr(248). chr(210).chr(211).chr(212).chr(213).chr(214).chr(216)."]", - "e" => "[e".chr(232).chr(233).chr(234).chr(235). chr(200).chr(201).chr(202).chr(203)."]", - "c" => "[c".chr(199).chr(231)."]", - "i" => "[i".chr(236).chr(237).chr(238).chr(239). chr(204).chr(205).chr(206).chr(207)."]", - "u" => "[u".chr(249).chr(250).chr(251).chr(252). chr(217).chr(218).chr(219).chr(220)."]", - "y" => "[y".chr(255)."]", - "n" => "[n".chr(209).chr(241)."]" - ); - - $mot = surligner_sans_accents ($mot); - if ($GLOBALS['meta']['charset'] == 'utf-8') { - while(list($k,$s) = each ($accents_regexp)) { - $accents_regexp_utf8[$k] = "(".join("|", split_by_char(preg_replace(',[\]\[],','',$accents_regexp[$k]))).")"; - } - $mot = strtr(strtolower($mot), $accents_regexp_utf8); - $mot = importer_charset($mot, 'iso-8859-1'); - } else - $mot = strtr(strtolower($mot), $accents_regexp); - - return $mot; -} - - -// mettre en rouge les mots passes dans $var_recherche -// http://doc.spip.org/@surligner_mots -function surligner_mots($page, $mots) { - global $nombre_surligne; - include_spip('inc/texte'); // pour le reglage de $nombre_surligne - tester_variable('nombre_surligne', 4); - - // Remplacer les caracteres potentiellement accentues dans la chaine - // de recherche par les choix correspondants en syntaxe regexp (!) - $mots = preg_split(',\s+,ms', $mots); - - foreach ($mots as $mot) { - if (strlen($mot) >= 2) { - $mot = surligner_regexp_accents(preg_quote(str_replace('/', '', $mot))); - $mots_surligne[] = $mot; - } - } - - if (!$mots_surligne) return $page; - - $regexp = '/((^|>)([^<]*[^[:alnum:]_<\x80-\xFF])?)((' - . join('|', $mots_surligne) - . ')[[:alnum:]_\x80-\xFF]*?)/Uis'; - - // en cas de surlignement limite' (champs #SURLIGNE), - // le compilateur a inse're' les balises de surlignement - // sur toute la zone; reste a` raffiner. - // On boucle pour le cas ou` il y a plusieurs zones - - $p = strpos($page, MARQUEUR_SURLIGNE); - if ($p !== false) { - $debut = ''; - while ($p) { - $debut .= substr($page, 0, $p-1); - $page = substr($page, $p+strlen(MARQUEUR_SURLIGNE)); - if (!$q = strpos($page,MARQUEUR_FSURLIGNE)) - $q = 1+strlen($page); - $debut .= trouve_surligne(substr($page, 0, $q-1), $regexp); - $page = substr($page, $q+strlen(MARQUEUR_FSURLIGNE)); - $p = strpos($page,MARQUEUR_SURLIGNE); - } - return $debut . $page; - } else { - // pour toute la page: ignorer ce qui est avant </head> ou <body> - $re = '/<\/head>|<body[^>]*>/i'; - if (preg_match($re, $page, $exp)) { - $debut = substr($page, 0, strpos($page, $exp[0])+strlen($exp[0])); - $page = substr($page, strlen($debut)); - } else - $debut = ''; - return $debut . trouve_surligne($page, $regexp); - } -} - -// http://doc.spip.org/@trouve_surligne -function trouve_surligne($page, $regexp) { - // Remplacer une occurrence de mot maxi par espace inter-tag - // (max 1 par paragraphe, sauf italiques etc.) - // se limiter a 4 remplacements pour ne pas bouffer le CPU ; - // traiter <textarea...>....</textarea> comme un tag. - global $nombre_surligne; - $page = preg_replace('/(<textarea[^>]*>)([^<>]*)(<\/textarea>)/Uis', '\1<<SPIP\2>>\3', $page); - $page = preg_replace($regexp, '\1<span class="spip_surligne">\4</span>', $page, $nombre_surligne); - $page = preg_replace('/(<textarea[^>]*>)<<SPIP([^<>]*)>>(<\/textarea>)/Uis', '\1\2\3', $page); - return $page ; +define("MARQUEUR_SURLIGNE", 'debut_surligneconditionnel'); +define("MARQUEUR_FSURLIGNE", 'finde_surligneconditionnel'); + + +function surligner_mots($page) { + $surlignejs_engines = array( + array(",".str_replace(array("/","."),array("\/","\."),$GLOBALS['meta']['adresse_site']).",i", ",recherche=([^&]+),i"), //SPIP + array(",^http://(www\.)?google\.,i", ",q=([^&]+),i"), // Google + array(",^http://(www\.)?search\.yahoo\.,i", ",p=([^&]+),i"), // Yahoo + array(",^http://(www\.)?search\.msn\.,i", ",q=([^&]+),i"), // MSN + array(",^http://(www\.)?search\.live\.,i", ",query=([^&]+),i"), // MSN Live + array(",^http://(www\.)?search\.aol\.,i", ",userQuery=([^&]+),i"), // AOL + array(",^http://(www\.)?ask\.com,i", ",q=([^&]+),i"), // Ask.com + array(",^http://(www\.)?altavista\.,i", ",q=([^&]+),i"), // AltaVista + array(",^http://(www\.)?feedster\.,i", ",q=([^&]+),i"), // Feedster + array(",^http://(www\.)?search\.lycos\.,i", ",q=([^&]+),i"), // Lycos + array(",^http://(www\.)?alltheweb\.,i", ",q=([^&]+),i"), // AllTheWeb + array(",^http://(www\.)?technorati\.com,i", ",([^\?\/]+)(?:\?.*)$,i"), // Technorati + ); + + + $ref = $_SERVER['HTTP_REFERER']; + foreach($surlignejs_engines as $engine) + if(preg_match($engine[0],$ref)) + if(preg_match($engine[1],$ref,$match)) { + //good referrer found + $script = "<script src='".find_in_path("javascript/SEhighlight.js")."'></script> + <script type='text/javascript'> + jQuery(function(){ + jQuery(document).SEhighlight({ + style_name:'spip_surligne', + exact:'whole', + style_name_suffix:false, + engines:[/^".str_replace(array("/","."),array("\/","\."),$GLOBALS['meta']['adresse_site'])."/i,/recherche=([^&]+)/i], + startHighlightComment:'".MARQUEUR_SURLIGNE."', + stopHighlightComment:'".MARQUEUR_FSURLIGNE."' + }) + }); + </script>"; + $page = preg_replace(",</head>,",$script."\n</head>",$page); + break; + } + return $page; } ?> diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php index 7bb90bedb9..d90b5428cd 100644 --- a/ecrire/public/assembler.php +++ b/ecrire/public/assembler.php @@ -300,9 +300,9 @@ function inclure_balise_dynamique($texte, $echo=true, $ligne=0) { // Traiter var_recherche pour surligner les mots // http://doc.spip.org/@f_surligne function f_surligne ($texte) { - if (isset($_GET['var_recherche'])) { + if (isset($_SERVER['HTTP_REFERER'])) { include_spip('inc/surligne'); - $texte = surligner_mots($texte, $_GET['var_recherche']); + $texte = surligner_mots($texte); } return $texte; } diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php index c18f9a9edc..3089b1a84d 100644 --- a/ecrire/public/balises.php +++ b/ecrire/public/balises.php @@ -185,9 +185,6 @@ function balise_URL_ARTICLE_dist($p) { if (!$_id_article) $_id_article = champ_sql('id_article', $p); $p->code = "generer_url_article($_id_article)"; - - if ($p->boucles[$p->nom_boucle ? $p->nom_boucle : $p->id_boucle]->hash) - $p->code = "url_var_recherche(" . $p->code . ")"; } $p->interdire_scripts = false; @@ -201,9 +198,6 @@ function balise_URL_RUBRIQUE_dist($p) { $_id_rubrique = champ_sql('id_rubrique',$p); $p->code = "generer_url_rubrique($_id_rubrique)" ; - if ($p->boucles[$p->nom_boucle ? $p->nom_boucle : $p->id_boucle]->hash) - $p->code = "url_var_recherche(" . $p->code . ")"; - $p->interdire_scripts = false; return $p; } @@ -215,9 +209,6 @@ function balise_URL_BREVE_dist($p) { $_id_breve = champ_sql('id_breve',$p); $p->code = "generer_url_breve($_id_breve)"; - if ($p->boucles[$p->nom_boucle ? $p->nom_boucle : $p->id_boucle]->hash) - $p->code = "url_var_recherche(" . $p->code . ")"; - $p->interdire_scripts = false; return $p; } @@ -229,9 +220,6 @@ function balise_URL_MOT_dist($p) { $_id_mot = champ_sql('id_mot',$p); $p->code = "generer_url_mot($_id_mot)"; - if ($p->boucles[$p->nom_boucle ? $p->nom_boucle : $p->id_boucle]->hash) - $p->code = "url_var_recherche(" . $p->code . ")"; - $p->interdire_scripts = false; return $p; } @@ -263,9 +251,6 @@ function balise_URL_FORUM_dist($p) { $_id_forum = champ_sql('id_forum',$p); $p->code = "generer_url_forum($_id_forum)"; - if ($p->boucles[$p->nom_boucle ? $p->nom_boucle : $p->id_boucle]->hash) - $p->code = "url_var_recherche(" . $p->code . ")"; - $p->interdire_scripts = false; return $p; } @@ -288,9 +273,6 @@ function balise_URL_AUTEUR_dist($p) { $_id_auteur = champ_sql('id_auteur',$p); $p->code = "generer_url_auteur($_id_auteur)"; - if ($p->boucles[$p->nom_boucle ? $p->nom_boucle : $p->id_boucle]->hash) - $p->code = "url_var_recherche(" . $p->code . ")"; - $p->interdire_scripts = false; return $p; } @@ -480,13 +462,13 @@ function balise_EMBED_DOCUMENT_dist($p) { // http://doc.spip.org/@balise_DEBUT_SURLIGNE_dist function balise_DEBUT_SURLIGNE_dist($p) { include_spip('inc/surligne'); - $p->code = "'<" . MARQUEUR_SURLIGNE . "'"; + $p->code = "'<!-- " . MARQUEUR_SURLIGNE . " -->'"; return $p; } // http://doc.spip.org/@balise_FIN_SURLIGNE_dist function balise_FIN_SURLIGNE_dist($p) { include_spip('inc/surligne'); - $p->code = "'<" . MARQUEUR_FSURLIGNE . "'"; + $p->code = "'<!-- " . MARQUEUR_FSURLIGNE . "-->'"; return $p; } diff --git a/ecrire/public/stats.php b/ecrire/public/stats.php index 3ee8a7b5a1..105d09c340 100644 --- a/ecrire/public/stats.php +++ b/ecrire/public/stats.php @@ -41,9 +41,8 @@ function public_stats_dist() { url_de_base())); if (!(($url_site_spip<>'') AND strpos('-'.strtolower($_SERVER['HTTP_REFERER']), strtolower($url_site_spip)) - AND !isset($_GET['var_recherche']))) { + AND strpos("recherche=",$_SERVER['HTTP_REFERER'])===false) { $log_referer = $_SERVER['HTTP_REFERER']; - $referer_md5 = '0x'.substr(md5($log_referer), 0, 15); } } -- GitLab