r52214 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r52213‎ | r52214 | r52215 >
Date:21:54, 20 June 2009
Author:catrope
Status:deferred
Tags:
Comment:
Adding NavigableTOC extension which adds a TOC on top of the edit page; when a section in the TOC is clicked, the cursor in the textarea jumps to the associated section. Tested in Firefox 3 and IE 7; still has issues with section editing and preview (which causes two TOCs to appear), will fix those tomorrow.
Modified paths:
  • /trunk/extensions/UsabilityInitiative/NavigableTOC (added) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.hooks.php (added) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.i18n.php (added) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.php (added) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.i18n.php
@@ -0,0 +1,17 @@
 2+<?php
 3+/**
 4+ * Internationalisation for Usability Initiative NavigableTOC extension
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Roan Kattouw
 14+ */
 15+$messages['en'] = array(
 16+ 'navigabletoc' => 'Navigable table of contents',
 17+ 'navigabletoc-desc' => 'Adds a table of contents to the edit form that scrolls the text box when a section is clicked.',
 18+);
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.php
@@ -0,0 +1,44 @@
 2+<?php
 3+/**
 4+ * Usability Initiative NavigableTOC extension
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This file contains the include file for the NavigableTOC portion of the
 10+ * UsabilityInitiative extension of MediaWiki.
 11+ *
 12+ * Usage: This file is included automatically by ../UsabilityInitiative.php
 13+ *
 14+ * @author Roan Kattouw <roan.kattouw@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.1.1
 17+ */
 18+
 19+/* Configuration */
 20+
 21+// Bump the version number every time you change any of the .css/.js files
 22+$wgNavigableTOCStyleVersion = 0;
 23+
 24+/* Setup */
 25+
 26+// Credits
 27+$wgExtensionCredits['other'][] = array(
 28+ 'path' => __FILE__,
 29+ 'name' => 'NavigableTOC',
 30+ 'author' => 'Roan Kattouw',
 31+ 'version' => '0.1.1',
 32+ 'url' => 'http://www.mediawiki.org/wiki/Extension:UsabilityInitiative',
 33+ 'descriptionmsg' => 'navigabletoc-desc',
 34+);
 35+
 36+// Adds Autoload Classes
 37+$wgAutoloadClasses['NavigableTOCHooks'] =
 38+ dirname( __FILE__ ) . '/NavigableTOC.hooks.php';
 39+
 40+// Adds Internationalized Messages
 41+$wgExtensionMessagesFiles['NavigableTOC'] =
 42+ dirname( __FILE__ ) . '/NavigableTOC.i18n.php';
 43+
 44+// Registers Hooks
 45+$wgHooks['EditPage::showEditForm:initial'][] = 'NavigableTOCHooks::addTOC';
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.hooks.php
@@ -0,0 +1,56 @@
 2+<?php
 3+/**
 4+ * Hooks for Usability Initiative NavigableTOC extension
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+class NavigableTOCHooks {
 11+
 12+ /* Static Functions */
 13+
 14+ /**
 15+ * EditPage::showEditForm::initial hook
 16+ * Adds the TOC to the edit form
 17+ */
 18+ public static function addTOC(&$ep) {
 19+ global $wgNavigableTOCStyleVersion, $wgParser, $wgUser;
 20+ global $wgUseParserCache;
 21+
 22+ // Adds script to document
 23+ UsabilityInitiativeHooks::addScript(
 24+ 'NavigableTOC/NavigableTOC.js', $wgNavigableTOCStyleVersion
 25+ );
 26+
 27+ // Try the parser cache first
 28+ $pcache = ParserCache::singleton();
 29+ $articleObj = new Article( $ep->mTitle );
 30+ $p_result = $pcache->get( $articleObj, $wgUser );
 31+ if ( !$p_result )
 32+ {
 33+ $p_result = $wgParser->parse( $articleObj->getContent(), $ep->mTitle, new ParserOptions());
 34+ if( $wgUseParserCache )
 35+ $pcache->save( $p_result, $articleObj, $popts );
 36+ } else {
 37+ // The ParserOutput in cache could be too old to have
 38+ // byte offsets. In that case, reparse
 39+ $sections = $p_result->getSections();
 40+ if ( isset( $sections[0] ) && !isset( $sections[0]['byteoffset'] ) ) {
 41+ $p_result = $wgParser->parse( $articleObj->getContent(), $ep->mTitle, new ParserOptions());
 42+ if( $wgUseParserCache )
 43+ $pcache->save( $p_result, $articleObj, $popts );
 44+ }
 45+ }
 46+
 47+ $js = "\$.sectionOffsets = [";
 48+ foreach ( $p_result->getSections() as $section )
 49+ if ( !is_null( $section['byteoffset'] ) )
 50+ $js .= intval( $section['byteoffset'] ) . ',';
 51+ $js .= '];';
 52+ $jsTag = Xml::element( 'script', array(), $js );
 53+
 54+ $ep->editFormTextTop .= $p_result->getTOCHTML() . $jsTag;
 55+ return true;
 56+ }
 57+}
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.js
@@ -0,0 +1,116 @@
 2+/* JavaScript for NavigableTOC extension */
 3+
 4+/**
 5+ * Add a plugin that can scroll a textarea to a certain location
 6+ */
 7+(function($){
 8+ $.fn.extend({
 9+ /**
 10+ * Scroll a textarea to a certain offset
 11+ * @param pos Byte offset in the contents
 12+ */
 13+ scrollToPosition: function( pos ) {
 14+ return this.each(function() {
 15+ // The next three functions were copied from Wikia's
 16+ // LinkSuggest extension and modified slightly.
 17+ // https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest/LinkSuggest.js
 18+ function getLineLength(control) {
 19+ var width = control.scrollWidth;
 20+ return Math.floor(width/8);
 21+ }
 22+
 23+ function getCaret(control) {
 24+ var caretPos = 0;
 25+ // IE Support
 26+ if($.browser.msie) {
 27+ control.focus();
 28+ var sel = document.selection.createRange();
 29+ var sel2 = sel.duplicate();
 30+ sel2.moveToElementText(control);
 31+ var caretPos = -1;
 32+ while(sel2.inRange(sel)) {
 33+ sel2.moveStart('character');
 34+ caretPos++;
 35+ }
 36+ // Firefox support
 37+ } else if (control.selectionStart || control.selectionStart == '0') {
 38+ caretPos = control.selectionStart;
 39+ }
 40+ return caretPos;
 41+ }
 42+
 43+ function getCaretPosition(control) {
 44+ var text = control.value.replace(/\r/g, "");
 45+ var caret = getCaret(control);
 46+ var lineLength = getLineLength(control);
 47+
 48+ var row = 0;
 49+ var charInLine = 0;
 50+ var lastSpaceInLine = 0;
 51+
 52+ for(i = 0; i < caret; i++) {
 53+ charInLine++;
 54+ if(text.charAt(i) == " ") {
 55+ lastSpaceInLine = charInLine;
 56+ } else if(text.charAt(i) == "\n") {
 57+ lastSpaceInLine = 0;
 58+ charInLine = 0;
 59+ row++;
 60+ }
 61+ if(charInLine > lineLength) {
 62+ if(lastSpaceInLine > 0) {
 63+ charInLine = charInLine - lastSpaceInLine;
 64+
 65+ lastSpaceInLine = 0;
 66+ row++;
 67+ }
 68+ }
 69+ }
 70+
 71+ var nextSpace = 0;
 72+ for(j = caret; j < caret + lineLength; j++) {
 73+ if(text.charAt(j) == " " || text.charAt(j) == "\n" || caret == text.length) {
 74+ nextSpace = j;
 75+ break;
 76+ }
 77+ }
 78+
 79+ if(nextSpace > lineLength && caret <= lineLength) {
 80+ charInLine = caret - lastSpaceInLine;
 81+ row++;
 82+ }
 83+
 84+
 85+ return ($.os.name == 'mac' ? 13 : 16)*row;
 86+ }
 87+
 88+ // Put the cursor at the desired position
 89+ this.focus();
 90+ if ( this.selectionStart || this.selectionStart == '0' ) { // Mozilla
 91+ this.selectionStart = this.selectionEnd = pos;
 92+ } else if ( document.selection && document.selection.createRange ) { // IE/Opera
 93+ var range = document.selection.createRange();
 94+ range.moveToElementText( this );
 95+ range.collapse();
 96+ //range.moveStart( 'character', pos );
 97+ range.move( 'character', pos );
 98+ //alert(range.text);
 99+ range.select();
 100+ }
 101+ $(this).scrollTop( getCaretPosition( this ) );
 102+ });
 103+ }
 104+ });
 105+})(jQuery);
 106+
 107+$( document ).ready( function() {
 108+ for ( i = 1; i <= $.sectionOffsets.length; i++ )
 109+ $( '.tocsection-' + i ).children( 'a' ).data( 'offset', $.sectionOffsets[i - 1] );
 110+ $( '.toc * li a' ).click( function(e) {
 111+ if( typeof $(this).data( 'offset' ) != 'undefined' )
 112+ $( '#wpTextbox1' ).scrollToPosition( $(this).data( 'offset' ) );
 113+ e.preventDefault();
 114+ });
 115+
 116+});
 117+

Status & tagging log