r63547 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r63546‎ | r63547 | r63548 >
Date:12:49, 10 March 2010
Author:jojo
Status:resolved (Comments)
Tags:
Comment:
implemented add/remove-via-popup w/ jQuery
Modified paths:
  • /trunk/extensions/Collection/Collection.hooks.php (modified) (history)
  • /trunk/extensions/Collection/Collection.php (modified) (history)
  • /trunk/extensions/Collection/CollectionCore.i18n.php (modified) (history)
  • /trunk/extensions/Collection/js/bookcreator.js (modified) (history)

Diff [purge]

Index: trunk/extensions/Collection/Collection.php
@@ -279,6 +279,24 @@
280280
281281 $wgAjaxExportList[] = 'wfAjaxCollectionClear';
282282
 283+function wfAjaxCollectionGetPopupData( $title ) {
 284+ wfLoadExtensionMessages( 'CollectionCore' );
 285+ $json = new Services_JSON();
 286+ $result = array();
 287+ if ( CollectionSession::findArticle( $title ) == -1 ) {
 288+ $result['action'] = 'add';
 289+ $result['text'] = wfMsg( 'coll-add_linked_article', $title );
 290+ } else {
 291+ $result['action'] = 'remove';
 292+ $result['text'] = wfMsg( 'coll-remove_linked_article', $title );
 293+ }
 294+ $r = new AjaxResponse( $json->encode( $result ) );
 295+ $r->setContentType( 'application/json' );
 296+ return $r;
 297+}
 298+
 299+$wgAjaxExportList[] = 'wfAjaxCollectionGetPopupData';
 300+
283301 /**
284302 * Backend of several following SAJAX function handlers...
285303 * @param String $action provided by the specific handlers internally
Index: trunk/extensions/Collection/Collection.hooks.php
@@ -240,6 +240,7 @@
241241 global $wgCollectionStyleVersion;
242242 global $wgCollectionVersion;
243243 global $wgJsMimeType;
 244+ global $wgOut;
244245 global $wgScriptPath;
245246 global $wgTitle;
246247 global $wgUser;
@@ -259,8 +260,21 @@
260261 $oldid = 0;
261262 }
262263 }
 264+
263265 $html = '';
264266
 267+ if ( false && method_exists( $wgOut, 'includeJQuery' ) ) {
 268+ $wgOut->includeJQuery();
 269+ } else {
 270+ $html .= Xml::element( 'script',
 271+ array(
 272+ 'type' => $wgJsMimeType,
 273+ 'src' => "$jsPath/jquery.js?$wgCollectionStyleVersion",
 274+ ),
 275+ '', false
 276+ );
 277+ }
 278+
265279 $html .= Xml::element( 'script',
266280 array(
267281 'type' => $wgJsMimeType,
@@ -268,6 +282,20 @@
269283 ),
270284 '', false
271285 );
 286+ $html .= Xml::element( 'style',
 287+ array( 'type' => 'text/css' ),
 288+ <<<EOS
 289+#collectionpopup {
 290+ position: absolute;
 291+ padding: 4px;
 292+ border: 1px solid #000;
 293+ background-color: #fea;
 294+ z-index: 9999;
 295+ display: inline;
 296+}
 297+EOS
 298+ , false
 299+ );
272300
273301 $addRemoveState = $mode;
274302
Index: trunk/extensions/Collection/CollectionCore.i18n.php
@@ -36,6 +36,8 @@
3737 'coll-disable' => 'disable',
3838 'coll-book_creator_disable' => 'Disable book creator',
3939 'coll-book_creator_disable_tooltip' => 'Stop using the book creator',
 40+ 'coll-add_linked_article' => 'Add page $1 to your book',
 41+ 'coll-remove_linked_article' => 'Remove page $1 from your book',
4042 'coll-add_category' => 'Add this category to your book',
4143 'coll-add_category_tooltip' => 'Add all wiki pages in this category to your book',
4244 'coll-add_this_page' => 'Add this page to your book',
Index: trunk/extensions/Collection/js/bookcreator.js
@@ -24,20 +24,14 @@
2525 function refreshBookCreatorBox(hint, oldid) {
2626 sajax_request_type = 'GET';
2727 sajax_do_call('wfAjaxCollectionGetBookCreatorBoxContent', [hint, oldid], function(xhr) {
28 - document.getElementById('coll-book_creator_box').innerHTML = xhr.responseText;
29 - if (hint && typeof wgCollectionAddRemoveState != 'undefined') {
30 - wgCollectionAddRemoveState = hint;
31 - }
32 - if (typeof refreshCollectionArticleList == 'function') {
33 - refreshCollectionArticleList();
34 - }
 28+ $('#coll-book_creator_box').html(xhr.responseText);
3529 });
3630 }
3731
3832 function collectionCall(func, args) {
3933 var hint = args.shift();
4034 sajax_request_type = 'POST';
41 - sajax_do_call('wfAjaxCollection' + func, args, function(xhr) {
 35+ sajax_do_call('wfAjaxCollection' + func, args, function() {
4236 var oldid = null;
4337 if (args.length == 3) {
4438 oldid = args[2];
@@ -48,4 +42,123 @@
4943
5044 window.collectionCall = collectionCall; // public
5145
 46+
 47+var mouse_pos = {};
 48+var popup_div = null;
 49+var addremove_link = null;
 50+var visible = false;
 51+var show_soon_timeout = null;
 52+var get_data_xhr = null;
 53+var script_url = wgServer + ((wgScript == null) ? (wgScriptPath + "/index.php") : wgScript);
 54+
 55+function createDiv() {
 56+ addremove_link = $('<a href="javascript:void(0)" />');
 57+ popup_div = $('<div id="collectionpopup" />');
 58+ popup_div.append(addremove_link)
 59+ $('body').append(popup_div);
 60+ popup_div.hide();
 61+}
 62+
 63+function addremove_article(action, title) {
 64+ $.post(script_url, {
 65+ 'action': 'ajax',
 66+ 'rs': 'wfAjaxCollection' + action.charAt(0).toUpperCase() + action.slice(1) + 'Article',
 67+ 'rsargs[]': [0, title, '']
 68+ }, function() {
 69+ hide();
 70+ refreshBookCreatorBox(null, null);
 71+ });
 72+}
 73+
 74+function show(link) {
 75+ if (visible) {
 76+ return;
 77+ }
 78+ var title = link.attr('title');
 79+ show_soon_timeout = setTimeout(function() {
 80+ get_data_xhr = $.post(script_url, {
 81+ 'action': 'ajax',
 82+ 'rs': 'wfAjaxCollectionGetPopupData',
 83+ 'rsargs[]': [title]
 84+ }, function(result) {
 85+ visible = true;
 86+ addremove_link
 87+ .text(result.text)
 88+ .unbind('click')
 89+ .click(function(e) { addremove_article(result.action, title); });
 90+ popup_div
 91+ .css({left: mouse_pos.x + 2 + 'px',
 92+ top: mouse_pos.y + 2 + 'px'})
 93+ .show();
 94+ }, 'json');
 95+ }, 300);
 96+}
 97+
 98+function cancel_asyncs() {
 99+ if (show_soon_timeout) {
 100+ clearTimeout(show_soon_timeout);
 101+ show_soon_timeout = null;
 102+ }
 103+ if (get_data_xhr) {
 104+ get_data_xhr.abort();
 105+ get_data_xhr = null;
 106+ }
 107+}
 108+
 109+function hide() {
 110+ cancel_asyncs();
 111+ if (!visible) {
 112+ return;
 113+ }
 114+ visible = false;
 115+ popup_div.hide();
 116+}
 117+
 118+function is_inside(x, y, left, top, width, height) {
 119+ var fuzz = 5;
 120+ return x + fuzz >= left && x - fuzz <= left + width
 121+ && y + fuzz >= top && y - fuzz <= top + height;
 122+}
 123+
 124+function check_popup_hide() {
 125+ if (!visible) {
 126+ return;
 127+ }
 128+ var pos = popup_div.offset();
 129+ if (!is_inside(mouse_pos.x, mouse_pos.y,
 130+ pos.left, pos.top, popup_div.width(), popup_div.height())) {
 131+ hide();
 132+ }
 133+}
 134+
 135+$(function() {
 136+ $(document).mousemove(function(e) {
 137+ mouse_pos.x = e.pageX;
 138+ mouse_pos.y = e.pageY;
 139+ });
 140+ setInterval(check_popup_hide, 300);
 141+ createDiv();
 142+ var prefix = wgArticlePath.replace(/\$1/, '');
 143+ $('#bodyContent '
 144+ + 'a[href^=' + prefix + ']' // URL starts with prefix of wgArticlePath
 145+ + ':not(a[href~=index.php])' // URL doesn't contain index.php (simplification!)
 146+ + '[title!=]' // title attribute is not empty
 147+ + ':not([title~=:])' // title doesn't contain a ':' (simplification!)
 148+ + '[rel!=nofollow]'
 149+ + ':not(.external)'
 150+ + ':not(.sortheader)'
 151+ + ':not([accesskey])'
 152+ + ':not(.nopopup)'
 153+ ).each(function(i, link) {
 154+ if (this.onmousedown) {
 155+ return;
 156+ }
 157+ var $this = $(this);
 158+ if ($this.parents('.nopopups').length) {
 159+ return;
 160+ }
 161+ $this.hover(function() { show($this); }, cancel_asyncs);
 162+ });
 163+});
 164+
52165 })();

Comments

#Comment by Tim Starling (talk | contribs)   19:24, 10 March 2010
+		if ( false && method_exists( $wgOut, 'includeJQuery' ) ) {

Debugging code left in?

+		+ ':not(a[href~=index.php])' // URL doesn't contain index.php (simplification!)

Article paths can contain index.php. It would be good to have something a bit less simple and more robust here.

#Comment by Jbeigel (talk | contribs)   11:23, 11 March 2010

Yes, that's currently a big simplification (as the comment says :). But it should work for the majority of article links on MediaWikis with "pretty URLs".

(The other over-simplification is to skip all links with a ":" in their title. This solution has been chosen to get this done quickly, without having to implement all the prefix-checking code (using mappings for each language) which was contained in the Navpopup code.)

I'll look into both issues later, but for now I'd say it's good enough to provide the functionality that's needed, especially on the WMF wikis.

#Comment by Jbeigel (talk | contribs)   11:25, 11 March 2010

And regarding the debugging code ... D'oh!

Removed it in r63593.

Status & tagging log