r95349 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r95348‎ | r95349 | r95350 >
Date:23:13, 23 August 2011
Author:wikinaut
Status:deferred
Tags:
Comment:
creating a new project 'viaf' under mediawiki/trunk/tools - a greasemonkey script with a few submodules and jquery which adds further deep links to viaf resources to a page when it found viaf numbers in text and links
Modified paths:
  • /trunk/tools/viaf (added) (history)
  • /trunk/tools/viaf/README (added) (history)
  • /trunk/tools/viaf/jquery.ba-replacetext.js (added) (history)
  • /trunk/tools/viaf/jquery.cookie.js (added) (history)
  • /trunk/tools/viaf/viaf.user.js (added) (history)

Diff [purge]

Index: trunk/tools/viaf/jquery.cookie.js
@@ -0,0 +1,86 @@
 2+/**
 3+ * jQuery Cookie plugin
 4+ * http://plugins.jquery.com/project/Cookie
 5+ *
 6+ * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
 7+ * Dual licensed under the MIT and GPL licenses:
 8+ * http://www.opensource.org/licenses/mit-license.php
 9+ * http://www.gnu.org/licenses/gpl.html
 10+ *
 11+ */
 12+
 13+/**
 14+ * Create a cookie with the given key and value and other optional parameters.
 15+ *
 16+ * @example $.cookie('the_cookie', 'the_value');
 17+ * @desc Set the value of a cookie.
 18+ * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 19+ * @desc Create a cookie with all available options.
 20+ * @example $.cookie('the_cookie', 'the_value');
 21+ * @desc Create a session cookie.
 22+ * @example $.cookie('the_cookie', null);
 23+ * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 24+ * used when the cookie was set.
 25+ *
 26+ * @param String key The key of the cookie.
 27+ * @param String value The value of the cookie.
 28+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 29+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 30+ * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 31+ * If set to null or omitted, the cookie will be a session cookie and will not be retained
 32+ * when the the browser exits.
 33+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 34+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 35+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 36+ * require a secure protocol (like HTTPS).
 37+ * @type undefined
 38+ *
 39+ * @name $.cookie
 40+ * @cat Plugins/Cookie
 41+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
 42+ */
 43+
 44+/**
 45+ * Get the value of a cookie with the given key.
 46+ *
 47+ * @example $.cookie('the_cookie');
 48+ * @desc Get the value of a cookie.
 49+ *
 50+ * @param String key The key of the cookie.
 51+ * @return The value of the cookie.
 52+ * @type String
 53+ *
 54+ * @name $.cookie
 55+ * @cat Plugins/Cookie
 56+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
 57+ */
 58+jQuery.cookie = function (key, value, options) {
 59+
 60+ // key and value given, set cookie...
 61+ if (arguments.length > 1 && (value === null || typeof value !== "object")) {
 62+ options = jQuery.extend({}, options);
 63+
 64+ if (value === null) {
 65+ options.expires = -1;
 66+ }
 67+
 68+ if (typeof options.expires === 'number') {
 69+ var days = options.expires, t = options.expires = new Date();
 70+ t.setDate(t.getDate() + days);
 71+ }
 72+
 73+ return (document.cookie = [
 74+ encodeURIComponent(key), '=',
 75+ options.raw ? String(value) : encodeURIComponent(String(value)),
 76+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
 77+ options.path ? '; path=' + options.path : '',
 78+ options.domain ? '; domain=' + options.domain : '',
 79+ options.secure ? '; secure' : ''
 80+ ].join(''));
 81+ }
 82+
 83+ // key and possibly options given, get cookie...
 84+ options = value || {};
 85+ var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
 86+ return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
 87+};
Index: trunk/tools/viaf/jquery.ba-replacetext.js
@@ -0,0 +1,129 @@
 2+/*!
 3+ * jQuery replaceText - v1.1 - 11/21/2009
 4+ * http://benalman.com/projects/jquery-replacetext-plugin/
 5+ *
 6+ * Copyright (c) 2009 "Cowboy" Ben Alman
 7+ * Dual licensed under the MIT and GPL licenses.
 8+ * http://benalman.com/about/license/
 9+ */
 10+
 11+// Script: jQuery replaceText: String replace for your jQueries!
 12+//
 13+// *Version: 1.1, Last updated: 11/21/2009*
 14+//
 15+// Project Home - http://benalman.com/projects/jquery-replacetext-plugin/
 16+// GitHub - http://github.com/cowboy/jquery-replacetext/
 17+// Source - http://github.com/cowboy/jquery-replacetext/raw/master/jquery.ba-replacetext.js
 18+// (Minified) - http://github.com/cowboy/jquery-replacetext/raw/master/jquery.ba-replacetext.min.js (0.5kb)
 19+//
 20+// About: License
 21+//
 22+// Copyright (c) 2009 "Cowboy" Ben Alman,
 23+// Dual licensed under the MIT and GPL licenses.
 24+// http://benalman.com/about/license/
 25+//
 26+// About: Examples
 27+//
 28+// This working example, complete with fully commented code, illustrates one way
 29+// in which this plugin can be used.
 30+//
 31+// replaceText - http://benalman.com/code/projects/jquery-replacetext/examples/replacetext/
 32+//
 33+// About: Support and Testing
 34+//
 35+// Information about what version or versions of jQuery this plugin has been
 36+// tested with, and what browsers it has been tested in.
 37+//
 38+// jQuery Versions - 1.3.2, 1.4.1
 39+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome, Opera 9.6-10.1.
 40+//
 41+// About: Release History
 42+//
 43+// 1.1 - (11/21/2009) Simplified the code and API substantially.
 44+// 1.0 - (11/21/2009) Initial release
 45+
 46+(function($){
 47+ '$:nomunge'; // Used by YUI compressor.
 48+
 49+ // Method: jQuery.fn.replaceText
 50+ //
 51+ // Replace text in specified elements. Note that only text content will be
 52+ // modified, leaving all tags and attributes untouched. The new text can be
 53+ // either text or HTML.
 54+ //
 55+ // Uses the String prototype replace method, full documentation on that method
 56+ // can be found here:
 57+ //
 58+ // https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/String/Replace
 59+ //
 60+ // Usage:
 61+ //
 62+ // > jQuery('selector').replaceText( search, replace [, text_only ] );
 63+ //
 64+ // Arguments:
 65+ //
 66+ // search - (RegExp|String) A RegExp object or substring to be replaced.
 67+ // Because the String prototype replace method is used internally, this
 68+ // argument should be specified accordingly.
 69+ // replace - (String|Function) The String that replaces the substring received
 70+ // from the search argument, or a function to be invoked to create the new
 71+ // substring. Because the String prototype replace method is used internally,
 72+ // this argument should be specified accordingly.
 73+ // text_only - (Boolean) If true, any HTML will be rendered as text. Defaults
 74+ // to false.
 75+ //
 76+ // Returns:
 77+ //
 78+ // (jQuery) The initial jQuery collection of elements.
 79+
 80+ $.fn.replaceText = function( search, replace, text_only ) {
 81+ return this.each(function(){
 82+ var node = this.firstChild,
 83+ val,
 84+ new_val,
 85+
 86+ // Elements to be removed at the end.
 87+ remove = [];
 88+
 89+ // Only continue if firstChild exists.
 90+ if ( node ) {
 91+
 92+ // Loop over all childNodes.
 93+ do {
 94+
 95+ // Only process text nodes.
 96+ if ( node.nodeType === 3 ) {
 97+
 98+ // The original node value.
 99+ val = node.nodeValue;
 100+
 101+ // The new value.
 102+ new_val = val.replace( search, replace );
 103+
 104+ // Only replace text if the new value is actually different!
 105+ if ( new_val !== val ) {
 106+
 107+ if ( !text_only && /</.test( new_val ) ) {
 108+ // The new value contains HTML, set it in a slower but far more
 109+ // robust way.
 110+ $(node).before( new_val );
 111+
 112+ // Don't remove the node yet, or the loop will lose its place.
 113+ remove.push( node );
 114+ } else {
 115+ // The new value contains no HTML, so it can be set in this
 116+ // very fast, simple way.
 117+ node.nodeValue = new_val;
 118+ }
 119+ }
 120+ }
 121+
 122+ } while ( node = node.nextSibling );
 123+ }
 124+
 125+ // Time to remove those elements!
 126+ remove.length && $(remove).remove();
 127+ });
 128+ };
 129+
 130+})(jQuery);
Index: trunk/tools/viaf/README
@@ -0,0 +1,33 @@
 2+viaf.user.js, a Greasemonkey script
 3+which detects VIAF numbers on web pages and creates related links
 4+
 5+*** detailed information page will follow ***
 6+
 7+Version: see viaf.user.js
 8+
 9+The viaf.user.js script tries to generously detect VIAF numbers as part of a web
 10+page's text, and also as part of links (urls).
 11+
 12+Detected numbers are indicated with bright cyan colour to attract the
 13+user's attention.
 14+
 15+While detecting the numbers, the script adds new links to additional servers.
 16+
 17+Such new links come in yellow and have the detected VIAF number as part of the
 18+url, i.e. are deep links (single-click solution).
 19+
 20+Those VIAF numbers which are only part of a url (i.e not in the text) are not
 21+apparent without this script. Numbers as part of urls are treated in the same
 22+way as numbers in the text. The script adds a dotted red underline to urls which
 23+contain a VIAF which is detected by matching a magic regular expression
 24+(see program code for details).
 25+
 26+A summary box (6) lists all distinct VIAF numbers to facilitate cut & paste of
 27+the extracted numbers; this can be disabled in the program code.
 28+
 29+The set of further server urls can be adapted in the program code.
 30+It relies on jQuery and two further javascripts, which are fetched automatically
 31+and has an integrated update checker (currently disabled) which looks for newer
 32+versions of it and prompts the user in such case.
 33+
 34+It does not automatically install a newer version.
Index: trunk/tools/viaf/viaf.user.js
@@ -0,0 +1,188 @@
 2+// ==UserScript==
 3+// @name viaf
 4+// @namespace viaf
 5+// @require https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
 6+// @require http://$$$yourhost$$$/js/jquery.cookie.js
 7+// @require http://$$$yourhost$$$/js/jquery.ba-replacetext.js
 8+// @description locate VIAF numbers in texts and urls on web pages. (c) T.Gries Version 0.198 201108230150
 9+// @include *
 10+// ==/UserScript==
 11+
 12+/***
 13+ * Copyright (c) 2011 T. Gries
 14+ *
 15+ * Dual licensed under the MIT and GPL licenses:
 16+ * http://www.opensource.org/licenses/mit-license.php
 17+ * http://www.gnu.org/licenses/gpl.html
 18+ *
 19+ * 20110806 Initial version; detecting VIAF in texts
 20+ * 20110811 color marking of VIAF number; detecting VIAF in Urls
 21+ * creation of three additional links with VIAF numbers as arguments
 22+ * 20110813 summary: an alert box shows detected distinct and sorted VIAF numbers
 23+ * 20110814 more language specific urls; use jquery 1.6.2 from google
 24+ * alert box shows up to maxVIAFNumbers
 25+ * 20110816 wrapped into a closure
 26+ * 20110817 disabled the built-in update checker; it has set 1-day cookie
 27+ * "update" for every page by mistake.
 28+ * 20110823 changed viaf.org link composition
 29+ *
 30+ ***/
 31+
 32+// wrapper see http://www.mediawiki.org/wiki/JQuery
 33+// to avoid possible conflicts with other scripts on the current page
 34+( function ( $ ) {
 35+
 36+var markUrlDetectedItems = true; // if detected items in Urls will be marked
 37+var markUrlDetectedItemsCSS = { "borderBottom" : "1px orangered dotted" };
 38+
 39+// maximum of VIAF numbers which are shown in the summary box
 40+var maxVIAFNumbers = 30;
 41+
 42+// Script update checker source: http://a32.me/2009/11/greasemonkey/
 43+var VERSION = "0.198";
 44+var SCRIPT_NAME = "viaf"
 45+var SCRIPT_URL = "http://$$$yourhost$$$/"+SCRIPT_NAME+".user.js"
 46+
 47+function updateCheck2() {
 48+ updateCheck(1);
 49+}
 50+
 51+function updateCheck(verbose) {
 52+
 53+ try {
 54+ GM_xmlhttpRequest({
 55+ method: 'GET',
 56+ url: SCRIPT_URL + "?rnd="+Math.random(),
 57+ onload: function(result) {
 58+ if (result.status != 200) throw "status="+result.status;
 59+
 60+ var tmp = /VERSION[\s=]+"(.*?)"/.exec(result.responseText);
 61+ if (tmp == null) throw "parse error";
 62+
 63+ if (VERSION < tmp[1]) {
 64+ if ( ($.cookie("updatecheck", {path:'/'} ) == null) || ( $("#updateinfo").length == 0) ) if (window.confirm("A newer version of the Greasemonkey script "+SCRIPT_NAME+" is available. You currently have version "+VERSION+".\n\nDo you want to update to version "+tmp[1]+" from "+SCRIPT_URL+" now ?\n\nPress Ctrl+F5 after the installation has finished to clear your browser chache.")) location.href = SCRIPT_URL;
 65+
 66+ $("#updateinfo")
 67+ .css("background","yellow")
 68+ .text(" New version of Greasemonkey script "+SCRIPT_NAME+" available.")
 69+ .attr("title","Click here to update to "+SCRIPT_NAME+" version "+tmp[1]+". Your current version is "+VERSION)
 70+ .mouseover( function(){ $(this).css("cursor","pointer") } )
 71+ .click( function() { $(this).fadeOut(2000); location.href=SCRIPT_URL } );
 72+
 73+ } else {
 74+ if (verbose) alert("There is no newer version of the Greasemonkey script "+SCRIPT_NAME+" available. Feel lucky, because you already have the latest version "+VERSION+".") ;
 75+ }
 76+
 77+ $.cookie("updatecheck", "1", {expires:1, path:'/'} );
 78+
 79+ }
 80+ });
 81+ } catch (error) {
 82+ alert('Error updating: '+error);
 83+ }
 84+}
 85+
 86+var out = new Array();
 87+
 88+function doAnyOtherBusiness( viaf ) {
 89+ // add the element only if it does not exist in list
 90+ if ( out.indexOf(viaf) == -1 ) {
 91+ out.push(viaf);
 92+ }
 93+}
 94+
 95+
 96+// update checker (disabled)
 97+// GM_registerMenuCommand("Check for update of "+SCRIPT_NAME, updateCheck2);
 98+// updateCheck(0);
 99+
 100+
 101+// PASS 1
 102+// try to retrieve as much viaf numbers from text as possible
 103+// but don't look in an active textareas like mediawiki input textarea
 104+
 105+$("body *:not(textarea)")
 106+ .replaceText( /(viaf)(:|\/|%3A|%2F|\s|ID:|=|%3D)*([0-9]+)/gi, "$1$2<span class='viaf' viaf='$3'>$3</span" );
 107+
 108+
 109+// PASS 2
 110+// try to retrieve viaf numbers in urls
 111+
 112+$("a").each(function(){
 113+ var $this = $(this);
 114+ if ( $this.find(".viaf").length != 0 ) return; // in PASS 2, skip all entries which have this attribute from PASS 1
 115+ var url = $this.attr("href");
 116+
 117+ var magicUrlRegExp = new RegExp( /(http:\/\/viaf.org\/(viaf\/)?(\d+)|http:\/\/www.librarything.de\/commonknowledge\/search.php?f=13&exact=1&q=VIAF%3A(\d)+)/gi );
 118+
 119+ if ( typeof url != "undefined" && url.match( magicUrlRegExp ) ) {
 120+ if ( markUrlDetectedItems ) $this.css( markUrlDetectedItemsCSS );
 121+ var viaf = RegExp.$1.replace( /[\D]*/g, '' );
 122+ $this.after( $("<span class='viaf' viaf='"+viaf+"'>&nbsp;"+viaf+"</span>") );
 123+ }
 124+
 125+})
 126+
 127+// PASS 3
 128+// add additional predefined target links
 129+// after the place where VIAF numbers were detected
 130+
 131+$(".viaf").each(function(){
 132+ var $this = $(this);
 133+ var viaf = $this.attr( "viaf" );
 134+
 135+ var newLink = new Array();
 136+ newLink.unshift( $( "<span> <a href='http://viaf.org/viaf/"+viaf+"/' class='addedlink viaf' viaf='"+viaf+"'>VIAF</a></span>" ) );
 137+ newLink.unshift( $( "<span> <a href='http://www.librarything.de/commonknowledge/search.php?f=13&exact=1&q=VIAF%3A"+viaf+"' class='addedlink viaf' viaf='"+viaf+"'>LT de</a></span>" ) );
 138+ newLink.unshift( $( "<span> <a href='http://www.librarything.com/commonknowledge/search.php?f=13&exact=1&q=VIAF%3A"+viaf+"' class='addedlink viaf' viaf='"+viaf+"'>en</a></span>" ) );
 139+ newLink.unshift( $( "<span> <a href='http://ru.librarything.com/commonknowledge/search.php?f=13&exact=1&q=VIAF%3A"+viaf+"' class='addedlink viaf' viaf='"+viaf+"'>ru</a></span>" ) );
 140+ newLink.unshift( $( "<span> <a href='http://yi.librarything.com/commonknowledge/search.php?f=13&exact=1&q=VIAF%3A"+viaf+"' class='addedlink viaf' viaf='"+viaf+"'>yi</a></span>" ) );
 141+ newLink.unshift( $( "<span> <a href='http://toolserver.org/%7Eapper/pd/person/viaf/"+viaf+"' class='addedlink viaf' viaf='"+viaf+"'>TS</a></span>" ) );
 142+ // newLink.unshift( $( "<label class='show-summary'><input type='checkbox' class='show-summary-checkbox' checked='checked'><span id='show-summary-text'></span></label>" ) );
 143+
 144+ // add a space as the last character after the last added links
 145+ newLink.unshift( $("<span> </span>") );
 146+
 147+ for ( i in newLink ) {
 148+ $this.after( newLink[i] )
 149+ }
 150+ doAnyOtherBusiness( viaf );
 151+})
 152+
 153+// style all checkboxes
 154+$( ".show-summary-checkbox" )
 155+ .click(function(e){
 156+ $this=$(this);
 157+ if ( $this.attr("checked")=='checked' ) {
 158+ $( ".show-summary-checkbox" ).attr("checked", true);
 159+ } else {
 160+ $( ".show-summary-checkbox" ).removeAttr("checked");
 161+ }
 162+ });
 163+
 164+// style all detected numbers
 165+$( ".viaf" ).css( { "background":"cyan", "color":"black" } );
 166+
 167+// style all added links
 168+$( ".addedlink" ).css( { "background":"yellow" , "color":"black" } );
 169+
 170+function numSort( a, b ) { return a-b }
 171+
 172+
 173+// show a summary of the collected numbers
 174+if ( out.length > 0 ) {
 175+
 176+ out.sort( numSort );
 177+ var x = "";
 178+ for ( var i=0; i < Math.min( out.length, maxVIAFNumbers ) ; i++ ) {
 179+ x += out[i]+"\n";
 180+ }
 181+
 182+ if ( out.length > maxVIAFNumbers ) x += "...\n("+maxVIAFNumbers+" of "+out.length+" distinct numbers are shown.)";
 183+ var pluralS = ( out.length > 1 ) ? "s" : "";
 184+
 185+ // comment the following line if you don't want to see the summary (alert) box
 186+ alert( "The present page contains "+out.length+" distinct VIAF number"+pluralS+" in text or links.\nModify the script if you want to remove the alert box permanently.\n\n"+x );
 187+}
 188+
 189+}) ( jQuery );

Status & tagging log