r72458 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r72457‎ | r72458 | r72459 >
Date:21:37, 5 September 2010
Author:janpaul123
Status:deferred (Comments)
Tags:
Comment:
InlineEditor extension and sub-extensions, first version (0.1.0). Will provide documentation on mediawiki.org and a mail to wikitech-l.
Modified paths:
  • /trunk/extensions/InlineEditor (added) (history)
  • /trunk/extensions/InlineEditor/EditForm.css (added) (history)
  • /trunk/extensions/InlineEditor/ExtendedEditPage.class.php (added) (history)
  • /trunk/extensions/InlineEditor/FullEditor (added) (history)
  • /trunk/extensions/InlineEditor/FullEditor/FullEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/FullEditor/FullEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/FullEditor/FullEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/HideEditSection.css (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditor.css (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditorPiece.class.php (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditorPreviousMarking.class.php (added) (history)
  • /trunk/extensions/InlineEditor/InlineEditorText.class.php (added) (history)
  • /trunk/extensions/InlineEditor/ListEditor (added) (history)
  • /trunk/extensions/InlineEditor/ListEditor/ListEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/ListEditor/ListEditor.css (added) (history)
  • /trunk/extensions/InlineEditor/ListEditor/ListEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/ListEditor/ListEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/ListEditor/jquery.inlineEditor.editors.listEditor.js (added) (history)
  • /trunk/extensions/InlineEditor/MediaEditor (added) (history)
  • /trunk/extensions/InlineEditor/MediaEditor/MediaEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/MediaEditor/MediaEditor.css (added) (history)
  • /trunk/extensions/InlineEditor/MediaEditor/MediaEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/MediaEditor/MediaEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/MediaEditor/jquery.inlineEditor.editors.mediaEditor.js (added) (history)
  • /trunk/extensions/InlineEditor/ReferenceEditor (added) (history)
  • /trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.css (added) (history)
  • /trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/ReferenceEditor/jquery.inlineEditor.editors.referenceEditor.js (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection/ISentenceDetection.class.php (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection/SentenceDetectionBasic.class.php (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.css (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/jquery.elastic.js (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/jquery.inlineEditor.editors.sentenceEditor.js (added) (history)
  • /trunk/extensions/InlineEditor/SentenceEditor/jquery.textWidth.js (added) (history)
  • /trunk/extensions/InlineEditor/TemplateEditor (added) (history)
  • /trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.class.php (added) (history)
  • /trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.css (added) (history)
  • /trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.i18n.php (added) (history)
  • /trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.php (added) (history)
  • /trunk/extensions/InlineEditor/TemplateEditor/jquery.inlineEditor.editors.templateEditor.js (added) (history)
  • /trunk/extensions/InlineEditor/ajax-loader.gif (added) (history)
  • /trunk/extensions/InlineEditor/jquery-ui-effects-1.8.4.min.js (added) (history)
  • /trunk/extensions/InlineEditor/jquery.inlineEditor.basicEditor.js (added) (history)
  • /trunk/extensions/InlineEditor/jquery.inlineEditor.js (added) (history)

Diff [purge]

Index: trunk/extensions/InlineEditor/InlineEditor.class.php
@@ -0,0 +1,401 @@
 2+<?php
 3+/**
 4+ * InlineEditor base class, contains all the basic logic of the editor.
 5+ * It handles hooks through static functions, and they can spawn an InlineEditor object using
 6+ * an article object, and then render like a normal page, or as JSON. Reason for this is to be
 7+ * able to pass this object to different hook functions.
 8+ */
 9+class InlineEditor {
 10+ private static $fallbackReason; ///< reason for not using the editor, used for showing a message
 11+ const REASON_BROWSER = 1; ///< reason is an incompatible browser
 12+ const REASON_ADVANCED = 2; ///< reason is editing an 'advanced' page, whatever that may be
 13+
 14+ private $article; ///< Article object to edit
 15+ private $editModes; ///< array of different edit modes, see addEditMode()
 16+ private $extendedEditPage; ///< ExtendedEditPage object we're using to handle editor logic
 17+
 18+ /**
 19+ * Main entry point, hooks into MediaWikiPerformAction.
 20+ * Checks whether or not to spawn the editor, and does so if nessicary.
 21+ */
 22+ public static function mediaWikiPerformAction( $output, $article, $title, $user, $request, $wiki ) {
 23+ global $wgHooks;
 24+
 25+ // the action of the page, i.e. 'view' or 'edit'
 26+ $action = $wiki->getVal( 'Action' );
 27+
 28+ // check if the editor could be used on this page, and if so, hide the [edit] links
 29+ if ( self::isValidBrowser() && !self::isAdvancedPage( $article, $title ) ) {
 30+ self::hideEditSection( $output );
 31+ }
 32+
 33+ // return if the action is not 'edit' or if it's disabled
 34+ if( $action != 'edit' || in_array( $action, $wiki->getVal( 'DisabledActions', array() ) ) )
 35+ {
 36+ return true;
 37+ }
 38+
 39+ // check if the 'fulleditor' parameter is set either in GET or POST
 40+ if ( $request->getCheck( 'fulleditor' ) ) {
 41+ // hook into the edit page to inject the hidden 'fulleditor' input field again
 42+ $wgHooks['EditPage::showEditForm:fields'][] = 'InlineEditor::showEditFormFields';
 43+ return true;
 44+ }
 45+
 46+ // terminate if the browser is not supported
 47+ if( !self::isValidBrowser() ) {
 48+ self::$fallbackReason = self::REASON_BROWSER;
 49+ return true;
 50+ }
 51+
 52+ // terminate if we consider this page 'advanced'
 53+ if( self::isAdvancedPage( $article, $title ) ) {
 54+ self::$fallbackReason = self::REASON_ADVANCED;
 55+ return true;
 56+ }
 57+
 58+ // start the session if needed
 59+ if( session_id() == '' ) {
 60+ wfSetupSession();
 61+ }
 62+
 63+ // try to spawn the editor and render the page
 64+ $editor = new InlineEditor( $article );
 65+ if( $editor->render( $output ) ) {
 66+ return false;
 67+ }
 68+ else {
 69+ // if rendering fails for some reason, terminate and show the advanced page notice
 70+ self::$fallbackReason = self::REASON_ADVANCED;
 71+ return true;
 72+ }
 73+ }
 74+
 75+ /**
 76+ * Hooks into EditPage::showEditForm:initial. Shows a message if there is a fallback reason set.
 77+ * @param $editPage EditPage
 78+ */
 79+ public static function showEditForm( &$editPage ) {
 80+ global $wgExtensionAssetsPath, $wgOut, $wgRequest;
 81+
 82+ // check for a fallback reason
 83+ if( isset( self::$fallbackReason ) ) {
 84+ // add the style for fallback message
 85+ $wgOut->addExtensionStyle( $wgExtensionAssetsPath . "/InlineEditor/EditForm.css?0" );
 86+
 87+ // show the appropriate message at the top of the page
 88+ switch( self::$fallbackReason ) {
 89+ case self::REASON_BROWSER:
 90+ self::prependFallbackMessage( wfMsgExt( 'inline-editor-redirect-browser', 'parseinline' ) );
 91+ break;
 92+ case self::REASON_ADVANCED:
 93+ self::prependFallbackMessage( wfMsgExt( 'inline-editor-redirect-advanced', 'parseinline' ) );
 94+ break;
 95+ }
 96+ }
 97+
 98+ return true;
 99+ }
 100+
 101+ /**
 102+ * Prepends a fallback message at the top of the page.
 103+ * @param $html String with correct HTML
 104+ */
 105+ private static function prependFallbackMessage( $html ) {
 106+ global $wgOut;
 107+ $wgOut->prependHTML( '<div class="inlineEditorMessage">' . $html . '</div>');
 108+ }
 109+
 110+ /**
 111+ * Checks if the browser is supported.
 112+ * This function is borrowed from EditPage::checkUnicodeCompliantBrowser().
 113+ */
 114+ private static function isValidBrowser() {
 115+ global $wgInlineEditorBrowserBlacklist;
 116+ if ( empty( $_SERVER["HTTP_USER_AGENT"] ) ) {
 117+ // No User-Agent header sent? Trust it by default...
 118+ return true;
 119+ }
 120+ $currentbrowser = $_SERVER["HTTP_USER_AGENT"];
 121+ foreach ( $wgInlineEditorBrowserBlacklist as $browser ) {
 122+ if ( preg_match($browser, $currentbrowser) ) {
 123+ return false;
 124+ }
 125+ }
 126+ return true;
 127+ }
 128+
 129+ /**
 130+ * Check if the page is 'advanced'. For now, that means it has to be in an allowed namespace.
 131+ * @param $article Article
 132+ * @param $title Title
 133+ * @return boolean
 134+ */
 135+ private static function isAdvancedPage( &$article, &$title ) {
 136+ global $wgInlineEditorAllowedNamespaces;
 137+ if( !empty( $wgInlineEditorAllowedNamespaces )
 138+ && !in_array( $title->getNamespace(), $wgInlineEditorAllowedNamespaces ) ) {
 139+ return true;
 140+ }
 141+ return false;
 142+ }
 143+
 144+ /**
 145+ * Entry point for the 'Preview' function through Ajax.
 146+ * No real point in securing this, as nothing is actually saved.
 147+ * @param $json String JSON object from the client
 148+ * @param $pageName String The page we're editing
 149+ * @return String HTML
 150+ */
 151+ public static function ajaxPreview( $json, $pageName ) {
 152+ $title = Title::newFromText( $pageName );
 153+ $article = Article::newFromId( $title->getArticleId() );
 154+
 155+ $editor = new InlineEditor( $article );
 156+ return $editor->preview( $json );
 157+ }
 158+
 159+ /**
 160+ * Hide the [edit] links on the page by enabling a piece of CSS (instead of screwing with the parser cache).
 161+ * @param $output OutputPage
 162+ */
 163+ public static function hideEditSection( &$output ) {
 164+ global $wgExtensionAssetsPath;
 165+ $output->addExtensionStyle( $wgExtensionAssetsPath . "/InlineEditor/HideEditSection.css?0" );
 166+ }
 167+
 168+ /**
 169+ * Add a 'fulleditor' hidden input field to the normal edit page
 170+ * @param $editpage EditPage
 171+ * @param $output OutputPage
 172+ */
 173+ public static function showEditFormFields( &$editpage, &$output ) {
 174+ $output->addHTML(
 175+ HTML::rawElement( 'input', array( 'name' => 'fulleditor', 'type' => 'hidden', 'value' => '1' ))
 176+ );
 177+ return true;
 178+ }
 179+
 180+ /**
 181+ * Constructor which takes only an Article object
 182+ * @param $article Article
 183+ */
 184+ public function __construct( $article ) {
 185+ $this->article = $article;
 186+ $editmodes = array();
 187+ }
 188+
 189+ /**
 190+ * Render the editor.
 191+ * Spawns an ExtendedEditPage which is an EditPage with some specific logic for this editor.
 192+ * This is supplied with wikitext generated using InlineEditorText, from the posted JSON.
 193+ * If the page is being saved, the ExtendedEditPage will terminate the script itself, else
 194+ * the editing interface will show as usual.
 195+ * @param $output OutputPage
 196+ */
 197+ public function render( &$output ) {
 198+ global $wgParser, $wgHooks, $wgRequest, $wgExtensionAssetsPath;
 199+
 200+ // create an InlineEditorText object which generates the HTML and JSON for the editor
 201+ $text = new InlineEditorText( $this->article );
 202+
 203+ // if the page is being saved, retrieve the wikitext from the JSON
 204+ if( $wgRequest->wasPosted() ) {
 205+ $text->loadFromJson( $wgRequest->getVal( 'json' ) );
 206+ $wgRequest->setVal( 'wpTextbox1', $text->getWikiOriginal() );
 207+ }
 208+
 209+ // try to init, or else return false, which will spawn an 'advanced page' notice
 210+ $this->extendedEditPage = new ExtendedEditPage( $this->article );
 211+ if( $this->extendedEditPage->initInlineEditor() ) {
 212+ // IMPORTANT: if the page was being saved, the script has been terminated by now!!
 213+
 214+ // include the required JS and CSS files
 215+ $output->includeJQuery();
 216+ $output->addScriptFile( $wgExtensionAssetsPath . "/InlineEditor/jquery.inlineEditor.js?0" );
 217+ $output->addScriptFile( $wgExtensionAssetsPath . "/InlineEditor/jquery.inlineEditor.basicEditor.js?0" );
 218+ $output->addScriptFile( $wgExtensionAssetsPath . "/InlineEditor/jquery-ui-effects-1.8.4.min.js?0" );
 219+ $output->addExtensionStyle( $wgExtensionAssetsPath . "/InlineEditor/InlineEditor.css?0" );
 220+
 221+ // have the different kind of editors register themselves
 222+ wfRunHooks( 'InlineEditorDefineEditors', array( &$this, &$output ) );
 223+
 224+ // load the wikitext into the InlineEditorText object
 225+ $text->loadFromWikiText( $this->extendedEditPage->getWikiText() );
 226+
 227+ // add a large <div> around the marked wikitext to denote the editing position
 228+ $parserOutput = $text->getParserOutputMarked();
 229+ $parserOutput->setText( '<div id="editContent">' . $parserOutput->getText() . '</div>' );
 230+
 231+ // put the marked output into the page
 232+ $output->addParserOutput( $parserOutput );
 233+
 234+ // add the different edit modes and initial JSON state in Javascript, and finally init the editor
 235+ $output->addInlineScript(
 236+ 'jQuery( document ).ready( function() {
 237+ jQuery.inlineEditor.editModes = ["' . implode( '","', array_keys( $this->editModes ) ) . '"];
 238+ jQuery.inlineEditor.currentMode = "' . reset( $this->editModes ) . '";
 239+ jQuery.inlineEditor.addInitialState( ' . $text->getWikiJson() . ' );
 240+ jQuery.inlineEditor.init();
 241+ } );'
 242+ );
 243+
 244+ // hook into SiteNoticeBefore to display the two boxes above the title
 245+ // @todo: fix this in core, make sure that anything can be inserted above the title, outside #siteNotice
 246+ $wgHooks['SiteNoticeBefore'][] = array( $this, 'siteNoticeBefore' );
 247+ return true;
 248+ }
 249+ else {
 250+ return false;
 251+ }
 252+ }
 253+
 254+ /**
 255+ * Get the Article being edited
 256+ * @return Article
 257+ */
 258+ public function getArticle() {
 259+ return $this->article;
 260+ }
 261+
 262+ /**
 263+ * Pass JSON into an InlineEditorText object and return combined JSON (HTML + sentence representation)
 264+ * @param $json String
 265+ * @return String
 266+ */
 267+ public function preview ( $json ) {
 268+ $text = new InlineEditorText( $this->article );
 269+ $text->loadFromJson( $json );
 270+ return $text->getCombinedJson();
 271+ }
 272+
 273+ /**
 274+ * Hooks into SiteNoticeBefore. Renders the edit interface above the title of the page.
 275+ * @param $siteNotice String
 276+ */
 277+ public function siteNoticeBefore( &$siteNotice ) {
 278+ $siteNotice = $this->renderEditBox() . $this->renderEditModes();
 279+ return false;
 280+ }
 281+
 282+ /**
 283+ * Add an edit mode to the list.
 284+ * @param $name String Name to be used in id-fields
 285+ * @param $caption String Name to be displayed
 286+ * @param $description String Description to be displayed when the mode is selected (*escaped* HTML only!)
 287+ */
 288+ public function addEditMode($name, $caption, $description) {
 289+ $this->editModes[$name] = array(
 290+ 'radioid' => 'radio-' . $name,
 291+ 'descriptionid' => 'description-' . $name,
 292+ 'caption' => $caption,
 293+ 'description' => $description
 294+ );
 295+ }
 296+
 297+ /**
 298+ * Generates "Edit box" (the first one)
 299+ * This looks like this:
 300+ * <div class="editbox">
 301+ * inline-editor-editbox-top
 302+ * <hr/>
 303+ *
 304+ * inline-editor-editbox-changes-question
 305+ * <input class="summary" name="summary" />
 306+ * <div class="example">inline-editor-editbox-changes-example</div>
 307+ * <hr/>
 308+ *
 309+ * <div class="side">
 310+ * inline-editor-editbox-publish-notice
 311+ * <div class="terms">inline-editor-editbox-publish-terms</div>
 312+ * </div>
 313+ * <a id="publish">inline-editor-editbox-publish-caption</a></div>
 314+ * @return string HTML
 315+ */
 316+ private function renderEditBox() {
 317+ $top = wfMsgExt( 'inline-editor-editbox-top', 'parseinline' );
 318+ $top .= '<hr/>';
 319+
 320+ $summary = wfMsgExt( 'inline-editor-editbox-changes-question', 'parseinline' );
 321+ $summary .= Html::input( 'wpSummary', $this->extendedEditPage->getSummary(),
 322+ 'text', array( 'class' => 'summary', 'maxlength' => 250 ) );
 323+ $summary .= Html::rawElement( 'div', array( 'class' => 'example' ),
 324+ wfMsgExt( 'inline-editor-editbox-changes-example', 'parseinline' ) );
 325+ $summary .= '<hr/>';
 326+
 327+ $terms = Html::rawElement( 'div', array( 'class' => 'terms' ),
 328+ wfMsgExt( 'inline-editor-editbox-publish-terms', 'parseinline', '[[' . wfMsgForContent( 'copyrightpage' ) . ']]' ) );
 329+ $publish = Html::rawElement( 'div', array( 'class' => 'side' ),
 330+ wfMsgExt( 'inline-editor-editbox-publish-notice', 'parseinline' ) . $terms );
 331+ $publish .= Html::rawElement( 'a', array( 'id' => 'publish', 'href' => '#' ),
 332+ wfMsgExt( 'inline-editor-editbox-publish-caption', 'parseinline' ) );
 333+ $publish .= HTML::rawElement( 'input', array( 'id' => 'json', 'name' => 'json', 'type' => 'hidden' ));
 334+
 335+ $form = Html::rawElement( 'form', array(
 336+ 'id' => 'editForm',
 337+ 'method' => 'POST',
 338+ 'action' => $this->extendedEditPage->getSubmitUrl() ), $top . $summary . $publish );
 339+
 340+
 341+ return Html::rawElement( 'div', array( 'class' => 'editbox' ), $form );
 342+ }
 343+
 344+ /**
 345+ * Generates "Edit mode" box (the second one)
 346+ * This looks like this:
 347+ * <div class="editmode">
 348+ * <div class="header">
 349+ * <div class="radio title">Edit mode: <!-- inline-editor-editmodes-caption --></div>
 350+ * <div class="radio"><!-- radio button + label --></div>
 351+ * <div class="radio"><!-- radio button + label --></div>
 352+ * <!-- for every edit mode one button -->
 353+ * <!-- and finally undo and redo buttons (with class 'button') -->
 354+ * </div>
 355+ * <div class="descriptionOuter">
 356+ * <div class="descriptionInner" id="description-text">
 357+ * <!-- for every edit mode a description -->
 358+ * </div>
 359+ * </div>
 360+ * @return string HTML
 361+ */
 362+ private function renderEditModes() {
 363+ if (!isset($this->editModes)) return '';
 364+
 365+ $header = Html::rawElement( 'div', array( 'class' => 'radio title' ),
 366+ wfMsgExt( 'inline-editor-editmodes-caption', 'parseinline' ) );
 367+
 368+ $descriptions = '';
 369+ $first = true;
 370+ foreach( $this->editModes as $editmode ) {
 371+ $inputOptions = array( 'id' => $editmode['radioid'], 'class' => 'optionMode' );
 372+ if ($first) {
 373+ $inputOptions['checked'] = 'checked';
 374+ $first = false;
 375+ }
 376+ $input = Html::input( 'optionMode', '', 'radio', $inputOptions );
 377+ $label = Html::rawElement('label', array( 'for' => $editmode['radioid'] ), $editmode['caption'] );
 378+
 379+ $header .= Html::rawElement( 'div', array( 'class' => 'radio' ), $input . $label );
 380+
 381+ $descriptions .= Html::rawElement('div', array( 'class' => 'descriptionInner', 'id' => $editmode['descriptionid']),
 382+ $editmode['description'] );
 383+ }
 384+
 385+ $header .= Html::rawElement( 'div', array( 'class' => 'button' ),
 386+ Html::rawElement( 'a', array( 'id' => 'redo', 'href' => '#' ),
 387+ wfMsgExt( 'inline-editor-editmodes-redo', 'parseinline' ) )
 388+ );
 389+ $header .= Html::rawElement( 'div', array( 'class' => 'button' ),
 390+ Html::rawElement( 'a', array( 'id' => 'undo', 'href' => '#' ),
 391+ wfMsgExt( 'inline-editor-editmodes-undo', 'parseinline' ) )
 392+ );
 393+ $header .= Html::rawElement( 'div', array( 'class' => 'button' ),
 394+ Html::rawElement( 'div', array( 'id' => 'editCounter', 'href' => '#' ), '#0' )
 395+ );
 396+
 397+ return Html::rawElement( 'div', array( 'class' => 'editmode' ),
 398+ Html::rawElement( 'div', array( 'class' => 'header' ), $header )
 399+ . Html::rawElement( 'div', array( 'class' => 'descriptionOuter' ), $descriptions )
 400+ );
 401+ }
 402+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditor.class.php
___________________________________________________________________
Added: svn:eol-style
1403 + native
Index: trunk/extensions/InlineEditor/ListEditor/ListEditor.i18n.php
@@ -0,0 +1,43 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension ListEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'list-editor-desc' => 'Adds the "Lists" edit mode for the InlineEditor',
 17+
 18+ 'list-editor-editmode-caption' => "Lists",
 19+ 'list-editor-editmode-description' => "
 20+Lists work like shown below.
 21+You can also make a new list by going in any other mode, like the '''Text''' mode,
 22+and add a list like the one below.
 23+
 24+{| width=\"100%\" style=\"background-color: inherit\"
 25+! Code
 26+! Output
 27+|-
 28+|
 29+<code><nowiki>* Lists are easy to do:</nowiki></code><br/>
 30+<code><nowiki>** start every line</nowiki></code><br/>
 31+<code><nowiki>* with a star</nowiki></code><br/>
 32+<code><nowiki>** more stars mean</nowiki></code><br/>
 33+<code><nowiki>*** deeper levels</nowiki></code><br/>
 34+|
 35+* Lists are easy to do:
 36+** start every line
 37+* with a star
 38+** more stars mean
 39+*** deeper levels
 40+|}
 41+
 42+[http://meta.wikimedia.org/wiki/Help:List More information]
 43+ ",
 44+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ListEditor/ListEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
145 + native
Index: trunk/extensions/InlineEditor/ListEditor/jquery.inlineEditor.editors.listEditor.js
@@ -0,0 +1,40 @@
 2+/**
 3+ * Client side part of the ListEditor.
 4+ */
 5+( function( $ ) { $.inlineEditor.editors.listEditor = {
 6+
 7+click: function(event) {
 8+ // prevent clicks from reaching other elements
 9+ event.stopPropagation();
 10+ event.preventDefault();
 11+
 12+ // find the element and retrieve the corresponding wikitext
 13+ var $field = $(this);
 14+ var wiki = $.inlineEditor.getTextById( $field.attr( 'id' ) );
 15+
 16+ $newField = $.inlineEditor.basicEditor.newField( $field, $.inlineEditor.editors.listEditor.click );
 17+ $.inlineEditor.basicEditor.addEditBar( $newField, 500, wiki );
 18+},
 19+
 20+enable: function() {
 21+ // do what we also do when reloading the page
 22+ $.inlineEditor.editors.listEditor.reload();
 23+
 24+ // add the identifying class to #editContent
 25+ $( '#editContent' ).addClass( 'listEditor' );
 26+},
 27+
 28+reload: function() {
 29+ // make lists clickable
 30+ $( '.listEditorElement' ).click( $.inlineEditor.editors.listEditor.click );
 31+},
 32+
 33+disable: function() {
 34+ // remove the click event from the lists
 35+ $( '.listEditorElement' ).unbind( 'click' );
 36+
 37+ // remove the identifying class from #editContent
 38+ $( '#editContent' ).removeClass( 'listEditor' );
 39+}
 40+
 41+}; } ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ListEditor/jquery.inlineEditor.editors.listEditor.js
___________________________________________________________________
Added: svn:eol-style
142 + native
Index: trunk/extensions/InlineEditor/ListEditor/ListEditor.php
@@ -0,0 +1,41 @@
 2+<?php
 3+/**
 4+ * ListEditor extension for the InlineEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the ListEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor/ListEditor/ListEditor.php" );
 13+ *
 14+ * @author Jan Paul Posma <jp.posma@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.0.0
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) die();
 20+
 21+// credits
 22+$wgExtensionCredits['other'][] = array(
 23+ 'path' => __FILE__,
 24+ 'name' => 'ListEditor',
 25+ 'author' => array( 'Jan Paul Posma' ),
 26+ 'version' => '0.1.0',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor#ListEditor',
 28+ 'descriptionmsg' => 'list-editor-desc',
 29+);
 30+
 31+// current directory including trailing slash
 32+$dir = dirname( __FILE__ ) . '/';
 33+
 34+// add autoload classes
 35+$wgAutoloadClasses['ListEditor'] = $dir . 'ListEditor.class.php';
 36+
 37+// register hooks
 38+$wgHooks['InlineEditorMark'][] = 'ListEditor::mark';
 39+$wgHooks['InlineEditorDefineEditors'][] = 'ListEditor::defineEditors';
 40+
 41+// i18n messages
 42+$wgExtensionMessagesFiles['ListEditor'] = $dir . 'ListEditor.i18n.php';
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ListEditor/ListEditor.php
___________________________________________________________________
Added: svn:eol-style
143 + native
Index: trunk/extensions/InlineEditor/ListEditor/ListEditor.css
@@ -0,0 +1,32 @@
 2+.listEditor .listEditorElement {
 3+ /* soft-blue background color to highlight editable lists */
 4+ background-color: #E4F0F9;
 5+
 6+ /* create a hand cursor, cross-browser hack: http://www.quirksmode.org/css/cursor.html */
 7+ cursor: pointer;
 8+ cursor: hand;
 9+}
 10+
 11+.listEditor .listEditorElement:hover {
 12+ /* indicate the list to be edited with a darker color */
 13+ background-color: #a7d7f9;
 14+}
 15+
 16+.listEditor .editing {
 17+ /* keeping the custom padding and margin breaks in Webkit browsers */
 18+ padding: 0px;
 19+ margin: 0px;
 20+
 21+ /* reset the cursor when editing */
 22+ cursor: auto;
 23+}
 24+
 25+.listEditor .edited {
 26+ /* have a yellow color to highlight edited elements, basically the orange color with the hue shifted */
 27+ background-color: #F9F2A7;
 28+}
 29+
 30+.listEditor .lastEdit {
 31+ /* have an orange color, the exact complement of the hover color, for highlighting on preview/cancel */
 32+ background-color: #f9c9a7;
 33+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ListEditor/ListEditor.css
___________________________________________________________________
Added: svn:eol-style
134 + native
Index: trunk/extensions/InlineEditor/ListEditor/ListEditor.class.php
@@ -0,0 +1,50 @@
 2+<?php
 3+/**
 4+ * Simple editor for lists.
 5+ */
 6+class ListEditor {
 7+
 8+ /**
 9+ * This function hooks into InlineEditorMark and marks the media.
 10+ * @param $inlineEditorText InlineEditorText
 11+ */
 12+ public static function mark( &$inlineEditorText ) {
 13+ // get the original wikitext
 14+ $text = $inlineEditorText->getWikiOriginal();
 15+
 16+ $matches = array();
 17+ preg_match_all( '/(\n|^)(([*#;:].*(\n|$))+)/', $text, $matches, PREG_OFFSET_CAPTURE );
 18+
 19+ foreach( $matches[2] as $match ) {
 20+ $start = $match[1];
 21+ $end = $start + strlen( $match[0] );
 22+
 23+ // do not include the trailing newline
 24+ if( substr( $match[0], -1) == "\n" ) $end--;
 25+
 26+ $inlineEditorText->addPiece( new InlineEditorPiece( $start, $end, 'listEditorElement', false ) );
 27+ }
 28+
 29+ return true;
 30+ }
 31+
 32+ /**
 33+ * Hooks into InlineEditorDefineEditors. Adds the option to to the list and adds CSS and JS files
 34+ * @param $editor InlineEditor
 35+ * @param $output OutputPage
 36+ */
 37+ public static function defineEditors( &$editor, &$output ) {
 38+ global $wgExtensionAssetsPath;
 39+
 40+ $editor->addEditMode(
 41+ 'listEditor',
 42+ wfMsgExt( 'list-editor-editmode-caption', 'parseinline' ),
 43+ wfMsgExt( 'list-editor-editmode-description','parseinline' )
 44+ );
 45+
 46+ $output->addExtensionStyle( "$wgExtensionAssetsPath/InlineEditor/ListEditor/ListEditor.css?0");
 47+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/ListEditor/jquery.inlineEditor.editors.listEditor.js?0" );
 48+
 49+ return true;
 50+ }
 51+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ListEditor/ListEditor.class.php
___________________________________________________________________
Added: svn:eol-style
152 + native
Index: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.i18n.php
@@ -0,0 +1,25 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension TemplateEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'template-editor-desc' => 'Adds the "Template" edit mode for the InlineEditor',
 17+
 18+ 'template-editor-editmode-caption' => "Templates",
 19+ 'template-editor-editmode-description' => "
 20+Templates are used to show the same thing on multiple pages.
 21+To fully understand templates, you should read documentation
 22+found online.
 23+
 24+[http://www.mediawiki.org/wiki/Help:Templates More information]
 25+",
 26+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
127 + native
Index: trunk/extensions/InlineEditor/TemplateEditor/jquery.inlineEditor.editors.templateEditor.js
@@ -0,0 +1,41 @@
 2+/**
 3+ * Client side part of the TemplateEditor.
 4+ */
 5+( function( $ ) { $.inlineEditor.editors.templateEditor = {
 6+
 7+click: function(event) {
 8+ // prevent clicks from reaching other elements
 9+ event.stopPropagation();
 10+ event.preventDefault();
 11+
 12+ // find the element and retrieve the corresponding wikitext
 13+ var $field = $(this);
 14+ var wiki = $.inlineEditor.getTextById( $field.attr( 'id' ) );
 15+
 16+ $newField = $.inlineEditor.basicEditor.newField( $field, $.inlineEditor.editors.templateEditor.click );
 17+ $newField.removeClass( 'templateEditorElementNotEditing' );
 18+ $.inlineEditor.basicEditor.addEditBar( $newField, 700, wiki );
 19+},
 20+
 21+enable: function() {
 22+ // do what we also do when reloading the page
 23+ $.inlineEditor.editors.templateEditor.reload();
 24+
 25+ // add the identifying class to #editContent
 26+ $( '#editContent' ).addClass( 'templateEditor' );
 27+},
 28+
 29+reload: function() {
 30+ // make templates clickable
 31+ $( '.templateEditorElement' ).click( $.inlineEditor.editors.templateEditor.click );
 32+},
 33+
 34+disable: function() {
 35+ // remove the click event from the templates
 36+ $( '.templateEditorElement' ).unbind( 'click' );
 37+
 38+ // remove the identifying class from #editContent
 39+ $( '#editContent' ).removeClass( 'templateEditor' );
 40+}
 41+
 42+}; } ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/TemplateEditor/jquery.inlineEditor.editors.templateEditor.js
___________________________________________________________________
Added: svn:eol-style
143 + native
Index: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.php
@@ -0,0 +1,41 @@
 2+<?php
 3+/**
 4+ * TemplateEditor extension for the InlineEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the TemplateEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor/TemplateEditor/TemplateEditor.php" );
 13+ *
 14+ * @author Jan Paul Posma <jp.posma@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.0.0
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) die();
 20+
 21+// credits
 22+$wgExtensionCredits['other'][] = array(
 23+ 'path' => __FILE__,
 24+ 'name' => 'TemplateEditor',
 25+ 'author' => array( 'Jan Paul Posma' ),
 26+ 'version' => '0.1.0',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor#TemplateEditor',
 28+ 'descriptionmsg' => 'template-editor-desc',
 29+);
 30+
 31+// current directory including trailing slash
 32+$dir = dirname( __FILE__ ) . '/';
 33+
 34+// add autoload classes
 35+$wgAutoloadClasses['TemplateEditor'] = $dir . 'TemplateEditor.class.php';
 36+
 37+// register hooks
 38+$wgHooks['InlineEditorMark'][] = 'TemplateEditor::mark';
 39+$wgHooks['InlineEditorDefineEditors'][] = 'TemplateEditor::defineEditors';
 40+
 41+// i18n messages
 42+$wgExtensionMessagesFiles['TemplateEditor'] = $dir . 'TemplateEditor.i18n.php';
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.php
___________________________________________________________________
Added: svn:eol-style
143 + native
Index: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.css
@@ -0,0 +1,37 @@
 2+.templateEditor .templateEditorElement {
 3+ /* soft-blue background color to highlight editable templates */
 4+ background-color: #E4F0F9;
 5+
 6+ /* create a hand cursor, cross-browser hack: http://www.quirksmode.org/css/cursor.html */
 7+ cursor: pointer;
 8+ cursor: hand;
 9+}
 10+
 11+.templateEditor .templateEditorElement:hover {
 12+ /* indicate the template to be edited with a darker color */
 13+ background-color: #a7d7f9;
 14+}
 15+
 16+.templateEditor .templateEditorElementNotEditing * {
 17+ /* make sure all the child elements inherit the background color */
 18+ background-color: inherit !important;
 19+}
 20+
 21+.templateEditor .editing {
 22+ /* keeping the custom padding and margin breaks in Webkit browsers */
 23+ padding: 0px;
 24+ margin: 0px;
 25+
 26+ /* reset the cursor when editing */
 27+ cursor: auto;
 28+}
 29+
 30+.templateEditor .edited {
 31+ /* have a yellow color to highlight edited elements, basically the orange color with the hue shifted */
 32+ background-color: #F9F2A7;
 33+}
 34+
 35+.templateEditor .lastEdit {
 36+ /* have an orange color, the exact complement of the hover color, for highlighting on preview/cancel */
 37+ background-color: #f9c9a7;
 38+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.css
___________________________________________________________________
Added: svn:eol-style
139 + native
Index: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.class.php
@@ -0,0 +1,46 @@
 2+<?php
 3+/**
 4+ * Simple editor for templates.
 5+ */
 6+class TemplateEditor {
 7+
 8+ /**
 9+ * This function hooks into InlineEditorMark and marks the media.
 10+ * @param $inlineEditorText InlineEditorText
 11+ */
 12+ public static function mark( &$inlineEditorText ) {
 13+ // get the original wikitext
 14+ $text = $inlineEditorText->getWikiOriginal();
 15+
 16+ $matches = array();
 17+ preg_match_all('/^(\{\{.*?\}\})/ms', $text, $matches, PREG_OFFSET_CAPTURE);
 18+
 19+ foreach( $matches[0] as $match ) {
 20+ $start = $match[1];
 21+ $end = $start + strlen( $match[0] );
 22+ $inlineEditorText->addPiece( new InlineEditorPiece( $start, $end, 'templateEditorElement templateEditorElementNotEditing', false ) );
 23+ }
 24+
 25+ return true;
 26+ }
 27+
 28+ /**
 29+ * Hooks into InlineEditorDefineEditors. Adds the option to to the list and adds CSS and JS files
 30+ * @param $editor InlineEditor
 31+ * @param $output OutputPage
 32+ */
 33+ public static function defineEditors( &$editor, &$output ) {
 34+ global $wgExtensionAssetsPath;
 35+
 36+ $editor->addEditMode(
 37+ 'templateEditor',
 38+ wfMsgExt( 'template-editor-editmode-caption', 'parseinline' ),
 39+ wfMsgExt( 'template-editor-editmode-description','parseinline' )
 40+ );
 41+
 42+ $output->addExtensionStyle( "$wgExtensionAssetsPath/InlineEditor/TemplateEditor/TemplateEditor.css?0");
 43+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/TemplateEditor/jquery.inlineEditor.editors.templateEditor.js?0" );
 44+
 45+ return true;
 46+ }
 47+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/TemplateEditor/TemplateEditor.class.php
___________________________________________________________________
Added: svn:eol-style
148 + native
Index: trunk/extensions/InlineEditor/InlineEditorText.class.php
@@ -0,0 +1,343 @@
 2+<?php
 3+
 4+/**
 5+ * Stores wikitext, pieces and previous markings, and generates HTML and JSON from them.
 6+ * Can import wikitext and previous markings from JSON and from an original article.
 7+ *
 8+ * Computation path is as follows:
 9+ *
 10+ * First time editing the page:
 11+ * wikitext from article => adding of new pieces => generating HTML (using parser) and JSON array
 12+ *
 13+ * Previewing the page:
 14+ * JSON array with pieces + last edit diff => adding of new pieces
 15+ * => computing overlap of pieces with previous markings => generating HTML (using parser) and JSON array
 16+ * => generating combined JSON array
 17+ *
 18+ * Saving the page:
 19+ * JSON array with pieces => new wikitext
 20+ *
 21+ */
 22+class InlineEditorText {
 23+ private $wikiOriginal;
 24+ private $parserOutputMarked;
 25+ private $wikiJsonArray;
 26+ private $wikiJsonText;
 27+ private $combinedJson;
 28+ private $article;
 29+ private $pieces;
 30+ private $previousMarkings;
 31+
 32+ /**
 33+ * @param $article Article The article to work with.
 34+ */
 35+ function __construct( $article ) {
 36+ $this->article = $article;
 37+ $this->pieces = array();
 38+ $this->previousMarkings = array();
 39+ }
 40+
 41+ /**
 42+ * Load the original wikitext from $wikiText.
 43+ * @param $wikiText String
 44+ */
 45+ public function loadFromWikiText( $wikiText ) {
 46+ $this->reset();
 47+ $this->wikiOriginal = $wikiText;
 48+ }
 49+
 50+ /**
 51+ * Get the original wikitext.
 52+ * @return String Original wikitext
 53+ */
 54+ public function getWikiOriginal() {
 55+ return $this->wikiOriginal;
 56+ }
 57+
 58+ /**
 59+ * Get the HTML with <span> and <div> markings.
 60+ * @return String HTML
 61+ */
 62+ public function getParserOutputMarked() {
 63+ if( !isset( $this->parserOutputMarked ) ) $this->process();
 64+ return $this->parserOutputMarked;
 65+ }
 66+
 67+ /**
 68+ * Get JSON representation of the wikitext and markings.
 69+ * @return String JSON
 70+ */
 71+ public function getWikiJson() {
 72+ if( !isset( $this->wikiJsonText ) ) $this->toJsonText();
 73+ return $this->wikiJsonText;
 74+ }
 75+
 76+ /**
 77+ * Get a combined JSON representation of the wikitext with markings, and marked HTML.
 78+ * @return String JSON with HTML in it
 79+ */
 80+ public function getCombinedJson() {
 81+ if( !isset( $this->combinedJson ) ) $this->toCombinedJson();
 82+ return $this->combinedJson;
 83+ }
 84+
 85+ /**
 86+ * Add a marking piece to the list of pieces. To be called by the different edit modes.
 87+ * @param $piece InlineEditorPiece
 88+ */
 89+ public function addPiece( InlineEditorPiece $piece ) {
 90+ if( isset( $this->pieces[$piece->getStart()] ) ) return;
 91+ if( !$piece->isValid() ) return;
 92+
 93+ $this->pieces[$piece->getStart()] = $piece;
 94+ }
 95+
 96+ /**
 97+ * Reset the object.
 98+ */
 99+ public function reset() {
 100+ unset( $this->wikiOriginal );
 101+ unset( $this->parserOutputMarked );
 102+ unset( $this->wikiJsonArray );
 103+ unset( $this->wikiJsonText );
 104+ unset( $this->combinedJson );
 105+ $this->pieces = array();
 106+ $this->previousMarkings = array();
 107+ }
 108+
 109+ /**
 110+ * Load original wikitext and previous markings from JSON
 111+ * @param $json String JSON string from the client side editor
 112+ */
 113+ public function loadFromJson( $json ) {
 114+ // first of all, reset the object
 115+ $this->reset();
 116+
 117+ // decode the JSON to an associative array
 118+ $input = FormatJson::decode( $json, true );
 119+
 120+ // if the 'lastEdit' attribute is set, this contains the edit the user made
 121+ // the original text is kept intact, but we don't need it, so just overwrite it with the new text
 122+ if( isset($input['lastEdit']) ) {
 123+ $input['originalWiki']['locations'][$input['lastEdit']['id']]['text'] = $input['lastEdit']['text'];
 124+ }
 125+
 126+ // convert the 'locations' array (by id) to the $pieces array (by position)
 127+ $pieces = array();
 128+ foreach( $input['originalWiki']['locations'] as $id => $piece ) {
 129+ $piece['id'] = $id;
 130+ $pieces[$piece['pos']] = $piece;
 131+ }
 132+
 133+ // sort the $pieces array by position
 134+ ksort($pieces);
 135+
 136+ // init loop variables
 137+ $text = ''; // reconstructed wikitext
 138+ $lastPos = 0; // position in the text of the previous piece
 139+ $offset = 0; // total amount of wikitext *inside* pieces so far
 140+
 141+ // iterate on all pieces
 142+ foreach( $pieces as $pos => $piece) {
 143+ // calculate the length of the piece
 144+ $length = strlen( $piece['text'] );
 145+
 146+ // add the wikitext between the previous piece and this piece
 147+ $text .= substr( $input['originalWiki']['text'], $lastPos, $pos - $lastPos );
 148+
 149+ // add the wikitext of the piece itself
 150+ $text .= $piece['text'];
 151+
 152+ // if this piece was last edited or marked before, add it to previousMarkings
 153+ if( ( isset( $input['lastEdit'] ) && $input['lastEdit']['id'] == $piece['id'] )
 154+ || $piece['edited'] )
 155+ {
 156+ // because these positions are within the text *with* the pieces included,
 157+ // the position has to be offsetted by exactly the total length of pieces so far
 158+ $previousStart = $pos + $offset;
 159+ $previousMarking = new InlineEditorPreviousMarking( $previousStart, $previousStart + $length );
 160+ $previousMarking->setEdited( true );
 161+
 162+ if( isset( $input['lastEdit'] ) && $input['lastEdit']['id'] == $piece['id'] ) {
 163+ $previousMarking->setLastEdit( true );
 164+ }
 165+
 166+ // last sanity check before adding the marking
 167+ if( $previousMarking->isValid() ) {
 168+ $this->previousMarkings[$previousStart] = $previousMarking;
 169+ }
 170+ }
 171+
 172+ // set variables for next round
 173+ $lastPos = $pos;
 174+ $offset += $length;
 175+ }
 176+
 177+ // add the text after the last piece
 178+ $text .= substr( $input['originalWiki']['text'], $lastPos );
 179+
 180+ // store it as the original wikitext
 181+ $this->wikiOriginal = $text;
 182+ }
 183+
 184+ /**
 185+ * Encodes the wikiJsonArray to a JSON string and stores it.
 186+ */
 187+ private function toJsonText() {
 188+ if ( !isset( $this->wikiJsonArray ) ) $this->process();
 189+ $this->wikiJsonText = FormatJson::encode( $this->wikiJsonArray );
 190+ }
 191+
 192+ /**
 193+ * Encodes both the wikiJsonArray and the parserOutputMarked to a JSON string and stores it.
 194+ */
 195+ private function toCombinedJson() {
 196+ if ( !isset( $this->wikiJsonArray ) || !isset( $this->parserOutputMarked ) ) $this->process();
 197+
 198+ $combined = array('html' => $this->parserOutputMarked->getText(), 'wiki' => $this->wikiJsonArray);
 199+ $this->combinedJson = FormatJson::encode( $combined );
 200+ }
 201+
 202+ /**
 203+ * Calls the InlineEditorMark hook to have pieces added, and calculates the JSON and marked HTML.
 204+ */
 205+ private function process() {
 206+ global $wgParser;
 207+
 208+ // make sure the pieces are added by the edit modes
 209+ wfRunHooks( 'InlineEditorMark', array( &$this ) );
 210+
 211+ // init the basic variables
 212+ $last = 0; // end position of the last piece in the original wikitext
 213+ $offset = 0; // total amount of wikitext *inside* pieces so far
 214+ $wikiMarked = ''; // marked wikitext to run through the parser
 215+ $jsonText = ''; // wikitext in JSON, which has the pieces *removed*
 216+ $jsonLocations = array(); // pieces with positions where to insert them in $jsonText
 217+
 218+ // sort the pieces by start position
 219+ ksort( $this->pieces );
 220+
 221+ // make sure the 'edited' and 'lastEdit' properties on pieces are correctly set
 222+ $this->applyPreviousMarkings();
 223+
 224+ // iterate on all pieces
 225+ foreach( $this->pieces as $start => $piece ) {
 226+ // do not allow overlap of pieces, so only take those with the lowest
 227+ // starting position
 228+ if ( $start < $last ) {
 229+ unset( $this->pieces[$start] );
 230+ }
 231+ else {
 232+ // get the end and calculate the length of the current piece
 233+ $end = $piece->getEnd();
 234+ $length = $end-$start;
 235+
 236+ // get the text between last piece and this piece
 237+ $prePieceText = substr($this->wikiOriginal, $last, $start-$last);
 238+
 239+ // get the text of the piece itself
 240+ $pieceText = substr($this->wikiOriginal, $start, $length);
 241+
 242+ // add the text between last piece and this piece, followed by
 243+ // the text of the piece surrounded by markings
 244+ $wikiMarked .= $prePieceText
 245+ . $piece->renderStartMarking()
 246+ . $pieceText
 247+ . $piece->renderEndMarking();
 248+
 249+ // only add the text between pieces to the JSON text
 250+ $jsonText .= $prePieceText;
 251+
 252+ // add the piece and position in $jsonText to the list of locations
 253+ // note that because we're taking out exactly the length of text within pieces,
 254+ // we can subtract this number from the start position of the piece, to obtain
 255+ // the position within $jsonText
 256+ $jsonLocations[$piece->getId()] = array(
 257+ 'text' => $pieceText,
 258+ 'pos' => $start - $offset,
 259+ 'edited' => ($piece->getEdited() ? '1' : '0')
 260+ );
 261+
 262+ // set variables for the next round
 263+ $offset += $length;
 264+ $last = $end;
 265+ }
 266+ }
 267+
 268+ // get the text after the last piece and add it to both variables
 269+ $postPieceText = substr($this->wikiOriginal, $last);
 270+ $wikiMarked .= $postPieceText;
 271+ $jsonText .= $postPieceText;
 272+
 273+ // store the JSON text and locations
 274+ $this->wikiJsonArray = array( 'text' => $jsonText, 'locations' => $jsonLocations );
 275+
 276+ // get the same parser options as usual, but remove [edit] links
 277+ $parserOptions = clone $this->article->getParserOptions();
 278+ $parserOptions->setEditSection( false );
 279+
 280+ // run $wikiMarked through the parser and store the result
 281+ $this->parserOutputMarked = $wgParser->parse( $wikiMarked, $this->article->getTitle(),
 282+ $parserOptions, true, true, $this->article->getRevIdFetched() );
 283+ }
 284+
 285+ /**
 286+ * Checks if pieces have overlap with previous markings and marks them again with
 287+ * 'edited' or 'lastEdit'.
 288+ *
 289+ * A piece can have overlap with multiple previous markings, but not with many. To
 290+ * avoid checking all pieces against all markings, a smarter algorithm is employed.
 291+ *
 292+ * When both the pieces are sorted (*precondition*) and the previous markings are
 293+ * sorted (which is done in the function), both arrays can be walked. For the array of
 294+ * previous markings we define a $firstId and $lastId. The end of the first previous marking
 295+ * has to be at least on or past the start of the current piece. The start of the last
 296+ * previous marking has to be at least past the end of the current piece. This way we can
 297+ * increment $firstId and $lastId until this is true, and we have a smaller window to
 298+ * check.
 299+ *
 300+ * @return unknown_type
 301+ */
 302+ private function applyPreviousMarkings() {
 303+ // if there are no previous markings there is no point in checking
 304+ if( empty( $this->previousMarkings ) ) return;
 305+
 306+ // start both at the beginning
 307+ $firstId = 0;
 308+ $lastId = 0;
 309+
 310+ // sort based on start position
 311+ ksort( $this->previousMarkings );
 312+
 313+ // use an array with as keys 0, 1, 2, etc.
 314+ $previous = array_values( $this->previousMarkings );
 315+
 316+ // interate over all pieces
 317+ foreach( $this->pieces as $start => $piece ) {
 318+ $end = $piece->getEnd();
 319+
 320+ // move the pointer of the first previous marking so it overlaps with the piece
 321+ while( isset( $previous[$firstId] ) && $previous[$firstId]->getEnd() < $start ) {
 322+ $firstId++;
 323+ }
 324+
 325+ // if the pointer to the first previous marking has gone too far, there is nothing
 326+ // to check for anymore: we're done
 327+ if( !isset( $previous[$firstId] ) ) return;
 328+
 329+ // move the pointer of the last previous marking so it just doesn't overlap
 330+ while( isset( $previous[$lastId] ) && $previous[$lastId]->getStart() <= $end ) {
 331+ $lastId++;
 332+ }
 333+
 334+ // check the (small) window of previous markings for overlap
 335+ for( $i = $firstId; $i < $lastId; $i++ ) {
 336+ // this should always be true, but check anyway!
 337+ if( $previous[$i]->inMarking( $piece ) ) {
 338+ if( $previous[$i]->getEdited() ) $piece->setEdited( true );
 339+ if( $previous[$i]->getLastEdit() ) $piece->setLastEdit( true );
 340+ }
 341+ }
 342+ }
 343+ }
 344+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditorText.class.php
___________________________________________________________________
Added: svn:eol-style
1345 + native
Index: trunk/extensions/InlineEditor/InlineEditorPiece.class.php
@@ -0,0 +1,102 @@
 2+<?php
 3+
 4+/**
 5+ * Denotes the start and end of an editiable piece in the wikitext, along with some properties.
 6+ */
 7+class InlineEditorPiece {
 8+ private static $lastId = 0; ///< counter which is used to generate unique ids
 9+
 10+ private $start; ///< start position of the piece in the wikitext
 11+ private $end; ///< end position of the piece in the wikitext
 12+ private $class; ///< class(es) attached to the piece, usually identifies the edit mode
 13+ private $inline; ///< whether or not the piece is inline (span) or not (div)
 14+ private $id; ///< unique id of this piece
 15+ private $edited; ///< boolean whether or not (part of) the piece has been edited before
 16+ private $lastEdit; ///< boolean whether or not (part of) the piece was in the last edit
 17+
 18+ // getter functions for most private variables
 19+ public function getStart() { return $this->start; }
 20+ public function getEnd() { return $this->end; }
 21+ public function getClass() { return $this->class; }
 22+ public function getId() { return $this->id; }
 23+ public function getEdited() { return $this->edited; }
 24+ public function getLastEdit() { return $this->lastEdit; }
 25+
 26+ // setter functions for edited and lastEdit, as these are not set by the different editors,
 27+ // but by InlineEditorText
 28+ public function setEdited( $val ) { $this->edited = $val; }
 29+ public function setLastEdit( $val ) { $this->lastEdit = $val; }
 30+
 31+ /**
 32+ * @param $start Integer Start of the piece, offset in number of characters from the begin of the wikitext
 33+ * @param $end Integer End of the piece, offset in number of characters from the begin of the wikitext
 34+ * @param $class String Class(es) the piece should be labeled with
 35+ * @param $inline Boolean Whether the piece is inline (span) or not (div), a div also adds newlines
 36+ */
 37+ function __construct($start, $end, $class, $inline) {
 38+ $this->start = $start;
 39+ $this->end = $end;
 40+ $this->class = $class;
 41+ $this->inline = $inline;
 42+ $this->id = self::uniqueId();
 43+ $this->edited = false;
 44+ $this->lastEdit = false;
 45+ }
 46+
 47+ /**
 48+ * Render the open tag, depending on $this->inline this is a <span> or a <div>.
 49+ * @return String HTML
 50+ */
 51+ public function renderStartMarking() {
 52+ $attribs = array( 'class' => $this->getFullClass(), 'id' => $this->id );
 53+ return HTML::openElement( $this->getElement(), $attribs ) . $this->getNewline();
 54+ }
 55+
 56+ /**
 57+ * Render the close tag.
 58+ * @return String HTML
 59+ */
 60+ public function renderEndMarking() {
 61+ return $this->getNewline() . '</' . $this->getElement() . '>';
 62+ }
 63+
 64+ /**
 65+ * Simple check to prevent invalid values.
 66+ * @return boolean
 67+ */
 68+ public function isValid() {
 69+ return $this->end > $this->start;
 70+ }
 71+
 72+ /**
 73+ * Get the class that should be rendered, this may include 'edited' and 'lastEdit' for highlighting.
 74+ * @return String All the classes
 75+ */
 76+ private function getFullClass() {
 77+ return $this->class . ($this->edited ? ' edited' : '') . ($this->lastEdit ? ' lastEdit' : '');
 78+ }
 79+
 80+ /**
 81+ * Get the element name based on $this->inline.
 82+ * @return String Element name
 83+ */
 84+ private function getElement() {
 85+ return $this->inline ? 'span' : 'div';
 86+ }
 87+
 88+ /**
 89+ * Get a newline or not based on $this->inline.
 90+ * @return String Empty string or single newline character
 91+ */
 92+ private function getNewline() {
 93+ return $this->inline ? '' : "\n";
 94+ }
 95+
 96+ /**
 97+ * Get a unique id by using self::$lastId and incrementing it.
 98+ * @return String
 99+ */
 100+ private static function uniqueId() {
 101+ return 'inline-editor-' . self::$lastId++;
 102+ }
 103+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditorPiece.class.php
___________________________________________________________________
Added: svn:eol-style
1104 + native
Index: trunk/extensions/InlineEditor/InlineEditorPreviousMarking.class.php
@@ -0,0 +1,47 @@
 2+<?php
 3+
 4+/**
 5+ * Denotes the start and end of previously edited pieces in the wikitext.
 6+ */
 7+class InlineEditorPreviousMarking {
 8+ private $start; ///< start position of the piece in the wikitext
 9+ private $end; ///< end position of the piece in the wikitext
 10+ private $edited; ///< boolean whether or not (part of) the piece has been edited before
 11+ private $lastEdit; ///< boolean whether or not (part of) the piece was in the last edit
 12+
 13+ // getters and setters for the private variables
 14+ public function getStart() { return $this->start; }
 15+ public function getEnd() { return $this->end; }
 16+ public function getEdited() { return $this->edited; }
 17+ public function getLastEdit() { return $this->lastEdit; }
 18+ public function setEdited( $val ) { $this->edited = $val; }
 19+ public function setLastEdit( $val ) { $this->lastEdit = $val; }
 20+
 21+ /**
 22+ * @param $start Integer Start of the piece, offset in number of characters from the begin of the wikitext
 23+ * @param $end Integer End of the piece, offset in number of characters from the begin of the wikitext
 24+ */
 25+ function __construct($start, $end) {
 26+ $this->start = $start;
 27+ $this->end = $end;
 28+ }
 29+
 30+ /**
 31+ * Checks if an InlineEditorPiece overlaps *or touches* with this marking.
 32+ * @param $piece InlineEditorPiece
 33+ * @return Boolean
 34+ */
 35+ public function inMarking( InlineEditorPiece $piece ) {
 36+ $start = $piece->getStart();
 37+ $end = $piece->getEnd();
 38+ return ($start >= $this->start && $start <= $this->end) || ($end >= $this->start && $end <= $this->end);
 39+ }
 40+
 41+ /**
 42+ * Simple check to prevent invalid values.
 43+ * @return boolean
 44+ */
 45+ public function isValid() {
 46+ return $this->end > $this->start;
 47+ }
 48+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditorPreviousMarking.class.php
___________________________________________________________________
Added: svn:eol-style
149 + native
Index: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.class.php
@@ -0,0 +1,60 @@
 2+<?php
 3+/**
 4+ * Simple editor for media (images, video, sound).
 5+ */
 6+class MediaEditor {
 7+
 8+ /**
 9+ * This function hooks into InlineEditorMark and marks the media.
 10+ * @param $inlineEditorText InlineEditorText
 11+ */
 12+ public static function mark( &$inlineEditorText ) {
 13+ // get the original wikitext
 14+ $text = $inlineEditorText->getWikiOriginal();
 15+
 16+ $matches = array();
 17+ preg_match_all( '/^\s*(\[\[(.*:.*)\]\])\s*$/m', $text, $matches, PREG_OFFSET_CAPTURE );
 18+
 19+ foreach( $matches[1] as $id => $match ) {
 20+ $link = $matches[2][$id][0];
 21+ $firstPipe = strpos($link, '|');
 22+ if( $firstPipe !== false ) {
 23+ $url = substr( $link, 0, $firstPipe );
 24+ }
 25+ else {
 26+ $url = $link;
 27+ }
 28+
 29+ $title = Title::newFromText( $url );
 30+ $namespace = $title->getNamespace();
 31+
 32+ if( $namespace == NS_FILE ) {
 33+ $start = $match[1];
 34+ $end = $start + strlen( $match[0] );
 35+ $inlineEditorText->addPiece( new InlineEditorPiece( $start, $end, 'mediaEditorElement', false ) );
 36+ }
 37+ }
 38+
 39+ return true;
 40+ }
 41+
 42+ /**
 43+ * Hooks into InlineEditorDefineEditors. Adds the option to to the list and adds CSS and JS files
 44+ * @param $editor InlineEditor
 45+ * @param $output OutputPage
 46+ */
 47+ public static function defineEditors( &$editor, &$output ) {
 48+ global $wgExtensionAssetsPath;
 49+
 50+ $editor->addEditMode(
 51+ 'mediaEditor',
 52+ wfMsgExt( 'media-editor-editmode-caption', 'parseinline' ),
 53+ wfMsgExt( 'media-editor-editmode-description','parseinline' )
 54+ );
 55+
 56+ $output->addExtensionStyle( "$wgExtensionAssetsPath/InlineEditor/MediaEditor/MediaEditor.css?0");
 57+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/MediaEditor/jquery.inlineEditor.editors.mediaEditor.js?0" );
 58+
 59+ return true;
 60+ }
 61+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.class.php
___________________________________________________________________
Added: svn:eol-style
162 + native
Index: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.i18n.php
@@ -0,0 +1,26 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension MediaEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'media-editor-desc' => 'Adds the "Media" edit mode for the InlineEditor',
 17+
 18+ 'media-editor-editmode-caption' => "Media",
 19+ 'media-editor-editmode-description' => "
 20+You can edit media like images, video and sound using this mode.
 21+Sometimes templates are used to display images, in which case you have to use the '''Template''' mode.
 22+
 23+:<code><nowiki>[[File:Example.jpg|thumb|An example file]]</nowiki></code>
 24+
 25+[http://en.wikipedia.org/wiki/Help:Files More information]
 26+",
 27+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
128 + native
Index: trunk/extensions/InlineEditor/MediaEditor/jquery.inlineEditor.editors.mediaEditor.js
@@ -0,0 +1,40 @@
 2+/**
 3+ * Client side part of the MediaEditor.
 4+ */
 5+( function( $ ) { $.inlineEditor.editors.mediaEditor = {
 6+
 7+click: function(event) {
 8+ // prevent clicks from reaching other elements
 9+ event.stopPropagation();
 10+ event.preventDefault();
 11+
 12+ // find the element and retrieve the corresponding wikitext
 13+ var $field = $(this);
 14+ var wiki = $.inlineEditor.getTextById( $field.attr( 'id' ) );
 15+
 16+ $newField = $.inlineEditor.basicEditor.newField( $field, $.inlineEditor.editors.mediaEditor.click );
 17+ $.inlineEditor.basicEditor.addEditBar( $newField, 700, wiki );
 18+},
 19+
 20+enable: function() {
 21+ // do what we also do when reloading the page
 22+ $.inlineEditor.editors.mediaEditor.reload();
 23+
 24+ // add the identifying class to #editContent
 25+ $( '#editContent' ).addClass( 'mediaEditor' );
 26+},
 27+
 28+reload: function() {
 29+ // make media clickable
 30+ $( '.mediaEditorElement' ).click( $.inlineEditor.editors.mediaEditor.click );
 31+},
 32+
 33+disable: function() {
 34+ // remove the click event from the media
 35+ $( '.mediaEditorElement' ).unbind( 'click' );
 36+
 37+ // remove the identifying class from #editContent
 38+ $( '#editContent' ).removeClass( 'mediaEditor' );
 39+}
 40+
 41+}; } ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/MediaEditor/jquery.inlineEditor.editors.mediaEditor.js
___________________________________________________________________
Added: svn:eol-style
142 + native
Index: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.php
@@ -0,0 +1,41 @@
 2+<?php
 3+/**
 4+ * MediaEditor extension for the InlineEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the MediaEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor/MediaEditor/MediaEditor.php" );
 13+ *
 14+ * @author Jan Paul Posma <jp.posma@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.0.0
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) die();
 20+
 21+// credits
 22+$wgExtensionCredits['other'][] = array(
 23+ 'path' => __FILE__,
 24+ 'name' => 'MediaEditor',
 25+ 'author' => array( 'Jan Paul Posma' ),
 26+ 'version' => '0.1.0',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor#MediaEditor',
 28+ 'descriptionmsg' => 'media-editor-desc',
 29+);
 30+
 31+// current directory including trailing slash
 32+$dir = dirname( __FILE__ ) . '/';
 33+
 34+// add autoload classes
 35+$wgAutoloadClasses['MediaEditor'] = $dir . 'MediaEditor.class.php';
 36+
 37+// register hooks
 38+$wgHooks['InlineEditorMark'][] = 'MediaEditor::mark';
 39+$wgHooks['InlineEditorDefineEditors'][] = 'MediaEditor::defineEditors';
 40+
 41+// i18n messages
 42+$wgExtensionMessagesFiles['MediaEditor'] = $dir . 'MediaEditor.i18n.php';
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.php
___________________________________________________________________
Added: svn:eol-style
143 + native
Index: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.css
@@ -0,0 +1,37 @@
 2+.mediaEditor .mediaEditorElement {
 3+ /* soft-blue background color to highlight editable media */
 4+ background-color: #E4F0F9;
 5+
 6+ /* create a hand cursor, cross-browser hack: http://www.quirksmode.org/css/cursor.html */
 7+ cursor: pointer;
 8+ cursor: hand;
 9+}
 10+
 11+.mediaEditor .mediaEditorElement:hover {
 12+ /* indicate the media to be edited with a darker color */
 13+ background-color: #a7d7f9;
 14+}
 15+
 16+.mediaEditor .editing {
 17+ /* keeping the custom padding and margin breaks in Webkit browsers */
 18+ padding: 0px;
 19+ margin: 0px;
 20+
 21+ /* reset the cursor when editing */
 22+ cursor: auto;
 23+}
 24+
 25+.mediaEditor .edited {
 26+ /* have a yellow color to highlight edited elements, basically the orange color with the hue shifted */
 27+ background-color: #F9F2A7;
 28+}
 29+
 30+.mediaEditor .lastEdit {
 31+ /* have an orange color, the exact complement of the hover color, for highlighting on preview/cancel */
 32+ background-color: #f9c9a7;
 33+}
 34+
 35+.mediaEditor .thumb,
 36+.mediaEditor .thumbinner {
 37+ background-color: inherit !important;
 38+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/MediaEditor/MediaEditor.css
___________________________________________________________________
Added: svn:eol-style
139 + native
Index: trunk/extensions/InlineEditor/InlineEditor.i18n.php
@@ -0,0 +1,29 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension InlineScripts.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'inline-editor-desc' => 'Provides an alternative editor which is easier to use',
 17+
 18+ 'inline-editor-editbox-top' => "'''Awesome, you're editing {{SITENAME}}!'''<br/>You can edit the article below, by clicking on <span class=\"highlightExample\">blue elements</span> in the article.",
 19+ 'inline-editor-editbox-changes-question' => "Can you briefly describe the changes you're making?",
 20+ 'inline-editor-editbox-changes-example' => 'For example: "Fixed spelling mistake", "Corrected facts", "Wrote a new paragraph", etc.',
 21+ 'inline-editor-editbox-publish-notice' => "When you're done, don't forget to publish the page!",
 22+ //'inline-editor-editbox-publish-terms' => 'When you click "Publish", you agree to the [http://wikimediafoundation.org/wiki/Terms_of_Use Terms of Use]. This means that you agree to share your contributions under a free license.',
 23+ 'inline-editor-editbox-publish-terms' => 'When you click "Publish", you agree with our copyright policy. See $1 for more information.',
 24+ 'inline-editor-editbox-publish-caption' => 'Publish',
 25+ 'inline-editor-editmodes-caption' => 'Edit mode:',
 26+ 'inline-editor-redirect-browser' => 'The new editing interface is not supported by your browser.',
 27+ 'inline-editor-redirect-advanced' => "Editing this page is considered '''advanced''' use of Wikipedia. You can only use the '''full editor''' for this page.",
 28+ 'inline-editor-editmodes-undo' => 'Undo',
 29+ 'inline-editor-editmodes-redo' => 'Redo',
 30+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
131 + native
Index: trunk/extensions/InlineEditor/ajax-loader.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/InlineEditor/ajax-loader.gif
___________________________________________________________________
Added: svn:mime-type
232 + application/octet-stream
Index: trunk/extensions/InlineEditor/HideEditSection.css
@@ -0,0 +1,4 @@
 2+.editsection {
 3+ /* hide the edit section from the page using CSS as opposed to hacking the parser options (and thus, cache) */
 4+ display: none !important;
 5+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/HideEditSection.css
___________________________________________________________________
Added: svn:eol-style
16 + native
Index: trunk/extensions/InlineEditor/ExtendedEditPage.class.php
@@ -0,0 +1,132 @@
 2+<?php
 3+/**
 4+ * This is basically an EditPage with some specific functions for the InlineEditor. This
 5+ * allows retrieval of wikitext, summary and a submit URL, and handles when to fall back
 6+ * to the full/traditional editor.
 7+ */
 8+class ExtendedEditPage extends EditPage {
 9+
 10+ /**
 11+ * Inits the edit page for the InlineEditor.
 12+ * This is largely a copy-paste from EditPage::edit(), with some specific changes.
 13+ */
 14+ public function initInlineEditor() {
 15+ global $wgRequest, $wgOut;
 16+ $this->importFormData( $wgRequest );
 17+
 18+ if( !empty( $this->section ) ) return false;
 19+
 20+ // @todo: refactor this piece in EditPage.php to (a) different function(s)
 21+ // so that this is not an ugly copy-paste
 22+
 23+ if ( wfReadOnly() && $this->save ) {
 24+ // Force preview
 25+ $this->save = false;
 26+ $this->preview = true;
 27+ }
 28+
 29+ $permErrors = $this->getEditPermissionErrors();
 30+ if ( $permErrors ) {
 31+ wfDebug( __METHOD__ . ": User can't edit\n" );
 32+ $this->readOnlyPage( $this->getContent( false ), true, $permErrors, 'edit' );
 33+ wfProfileOut( __METHOD__ );
 34+ return false;
 35+ } else {
 36+ if ( $this->save ) {
 37+ $this->formtype = 'save';
 38+ } else if ( $this->preview ) {
 39+ $this->formtype = 'preview';
 40+ } else if ( $this->diff ) {
 41+ $this->formtype = 'diff';
 42+ } else { # First time through
 43+ $this->firsttime = true;
 44+ if ( $this->previewOnOpen() ) {
 45+ $this->formtype = 'preview';
 46+ } else {
 47+ $this->formtype = 'initial';
 48+ }
 49+ }
 50+ }
 51+
 52+ // If they used redlink=1 and the page exists, redirect to the main article
 53+ if ( $wgRequest->getBool( 'redlink' ) && $this->mTitle->exists() ) {
 54+ $wgOut->redirect( $this->mTitle->getFullURL() );
 55+ }
 56+
 57+ $this->isConflict = false;
 58+ // css / js subpages of user pages get a special treatment
 59+ $this->isCssJsSubpage = $this->mTitle->isCssJsSubpage();
 60+ $this->isCssSubpage = $this->mTitle->isCssSubpage();
 61+ $this->isJsSubpage = $this->mTitle->isJsSubpage();
 62+ $this->isValidCssJsSubpage = $this->mTitle->isValidCssJsSubpage();
 63+
 64+ // catch the HTML that the intro throws
 65+ // if anything is thrown, fall back to the normal editor
 66+ $wgOut->clearHTML();
 67+ if ( $this->formtype == 'initial' || $this->firsttime ) {
 68+ $this->showIntro();
 69+ if( $wgOut->getHTML() != '' ) {
 70+ $wgOut->clearHTML();
 71+ return false;
 72+ }
 73+ }
 74+
 75+ if ( 'initial' == $this->formtype || 'preview' == $this->formtype || $this->firsttime ) {
 76+ if ( $this->initialiseForm() !== false ) {
 77+ return true;
 78+ }
 79+ else {
 80+ return false;
 81+ }
 82+ }
 83+ elseif ( 'save' == $this->formtype ) {
 84+ // attemptSave does a redirect *itself* when it's succesful!
 85+ $this->attemptSave();
 86+ if( $this->isConflict ) {
 87+ return false;
 88+ }
 89+ else {
 90+ return true;
 91+ }
 92+ }
 93+ else {
 94+ return false;
 95+ }
 96+ }
 97+
 98+ /**
 99+ * Get the wikitext to render the page from
 100+ * @return String
 101+ */
 102+ public function getWikiText() {
 103+ return $this->textbox1;
 104+ }
 105+
 106+ /**
 107+ * Get the summary to show in the input field
 108+ * @return String
 109+ */
 110+ public function getSummary() {
 111+ return $this->summary;
 112+ }
 113+
 114+ /**
 115+ * Get the URL to submit to, with some options in the URL that are usually hidden fields
 116+ * @return String
 117+ */
 118+ public function getSubmitUrl() {
 119+ global $wgUser;
 120+ $options = array(
 121+ 'action' => 'edit',
 122+ 'wpEditToken' => $wgUser->editToken(),
 123+ 'wpEdittime' => $this->edittime,
 124+ 'wpStarttime' => $this->starttime
 125+ );
 126+
 127+ if( $this->scrolltop ) $options['wpScrolltop'] = 1;
 128+ if( $this->minoredit ) $options['wpMinorEdit'] = 1;
 129+ if( $this->watchthis ) $options['wpWatchthis'] = 1;
 130+
 131+ return $this->mTitle->getLocalURL( $options );
 132+ }
 133+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ExtendedEditPage.class.php
___________________________________________________________________
Added: svn:eol-style
1134 + native
Index: trunk/extensions/InlineEditor/EditForm.css
@@ -0,0 +1,13 @@
 2+/* style for message on top of the full/original editor, put there by the InlineEditor */
 3+
 4+.inlineEditorMessage {
 5+ /* box on top of the page, colors are the same as the surrounding colors */
 6+ /* it scales with the display size */
 7+ font-size: 1.0em;
 8+ background-color: #eaf3f8;
 9+ border: 1px solid #A7D7F9;
 10+ margin-bottom: 10px;
 11+ padding: 10px 10px 5px;
 12+ max-width: 700px;
 13+ position: relative;
 14+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/EditForm.css
___________________________________________________________________
Added: svn:eol-style
115 + native
Index: trunk/extensions/InlineEditor/jquery.inlineEditor.basicEditor.js
@@ -0,0 +1,122 @@
 2+/**
 3+ * Provides a basic editor with preview and cancel functionality.
 4+ */
 5+( function( $ ) { $.inlineEditor.basicEditor = {
 6+
 7+/**
 8+ * Creates a new field which stores the original field inside.
 9+ * The original click event is required to bind with the original field.
 10+ */
 11+newField: function( $field, originalClickEvent ) {
 12+ // store the original field in a hidden field
 13+ var $orig = $( '<' + $field.get(0).nodeName + '/>' );
 14+ $orig.html( $field.html() );
 15+ $orig.attr( 'id', $field.attr( 'id' ) );
 16+ $orig.addClass( $field.attr( 'class' ) );
 17+ $orig.addClass( 'orig' );
 18+ $orig.click( originalClickEvent );
 19+
 20+ // create a new field and add the original text
 21+ var $newField = $( '<' + $field.get(0).nodeName + '/>' );
 22+ $newField.addClass( $field.attr('class' ) );
 23+ $newField.addClass( 'editing' );
 24+ $newField.append( $orig );
 25+
 26+ // add the new field after the current one, and remove the current one
 27+ // editing the current field is buggy in Webkit browsers
 28+ $field.after( $newField );
 29+ $field.remove();
 30+
 31+ return $newField;
 32+},
 33+
 34+/**
 35+ * Adds an edit bar to the field with preview and cancel functionality.
 36+ */
 37+addEditBar: function( $newSpan, width, wiki ) {
 38+ // build the input field
 39+ var $input = $( '<textarea style="width: ' + (width-60-60-10) + 'px;"></textarea>' );
 40+ $input.text( wiki );
 41+
 42+ // build preview and cancel buttons and add click events
 43+ var $preview = $( '<input type="button" value="Preview" style="width: 60px; margin-left: ' + (3) + 'px;" class="preview"/>' );
 44+ var $cancel = $( '<input type="button" value="Cancel" style="width: 60px; margin-left: ' + (60+3+3) + 'px;" class="cancel"/>' );
 45+ $preview.click( $.inlineEditor.basicEditor.preview );
 46+ $cancel.click( $.inlineEditor.basicEditor.cancel );
 47+
 48+ // build the edit bar from the input field and buttons
 49+ var $editBar = $( '<span class="editbar" style="width: ' + width + 'px"></span>' );
 50+ $editBar.append( $input );
 51+ $editBar.append( $preview );
 52+ $editBar.append( $cancel );
 53+
 54+ // append the edit bar to the new span
 55+ $newSpan.append( $editBar );
 56+
 57+ // automatically resize the textarea using the Elastic plugin
 58+ $input.elastic();
 59+
 60+ // focus on the input so you can start typing immediately
 61+ $input.focus();
 62+
 63+ return $editBar;
 64+},
 65+
 66+/**
 67+ * Cancels the current edit operation.
 68+ */
 69+cancel: function( event ) {
 70+ // prevent clicks from reaching other elements
 71+ event.stopPropagation();
 72+ event.preventDefault();
 73+
 74+ // find the outer span, two parents above the buttons
 75+ var $span = $(this).parent().parent();
 76+
 77+ // find the span with the original value
 78+ var $orig = $span.children('.orig');
 79+
 80+ // convert the span to it's original state
 81+ $orig.removeClass( 'orig' );
 82+
 83+ // place the original span after the current span and remove the current span
 84+ // editing the current span is buggy in Webkit browsers
 85+ $span.after( $orig );
 86+ $span.remove();
 87+
 88+ // highlight the text orange and have it fade to blue again
 89+ // this is a visual indicator to where the element is now
 90+ $orig.addClass( 'lastEdit' );
 91+ $orig.removeClass( 'lastEdit', 'slow' );
 92+},
 93+
 94+/**
 95+ * Previews the current edit operation.
 96+ */
 97+preview: function( event ) {
 98+ // prevent clicks from reaching other elements
 99+ event.stopPropagation();
 100+ event.preventDefault();
 101+
 102+ // find the span with class 'editbar', one parent above the buttons
 103+ var $editbar = $(this).parent();
 104+
 105+ // the element is one level above the editbar
 106+ var $element = $editbar.parent();
 107+
 108+ // add a visual indicator to show the preview is loading
 109+ $element.addClass( 'saving' );
 110+ var $overlay = $( '<div class="overlay"><div class="alpha"></div><img class="spinner" src="' + wgScriptPath + '/extensions/InlineEditor/ajax-loader.gif"/></div>' );
 111+ $editbar.append( $overlay );
 112+
 113+ // get the edited text and the id to save it to
 114+ text = $editbar.children( 'textarea' ).val();
 115+ id = $element.children( '.orig' ).attr( 'id' );
 116+
 117+ // let the inlineEditor framework handle the preview
 118+ $.inlineEditor.previewTextById( text, id );
 119+}
 120+
 121+}; } ) ( jQuery );
 122+
 123+
Property changes on: trunk/extensions/InlineEditor/jquery.inlineEditor.basicEditor.js
___________________________________________________________________
Added: svn:eol-style
1124 + native
Index: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.class.php
@@ -0,0 +1,46 @@
 2+<?php
 3+/**
 4+ * Simple editor for references.
 5+ */
 6+class ReferenceEditor {
 7+
 8+ /**
 9+ * This function hooks into InlineEditorMark and marks the references.
 10+ * @param $inlineEditorText InlineEditorText
 11+ */
 12+ public static function mark( &$inlineEditorText ) {
 13+ // get the original wikitext
 14+ $text = $inlineEditorText->getWikiOriginal();
 15+
 16+ $matches = array();
 17+ preg_match_all( '/<ref[^\/]*?>.*?<\/ref>|<ref.*?\/>/is', $text, $matches, PREG_OFFSET_CAPTURE );
 18+
 19+ foreach( $matches[0] as $match ) {
 20+ $start = $match[1];
 21+ $end = $start + strlen( $match[0] );
 22+ $inlineEditorText->addPiece( new InlineEditorPiece( $start, $end, 'referenceEditorElement', true ) );
 23+ }
 24+
 25+ return true;
 26+ }
 27+
 28+ /**
 29+ * Hooks into InlineEditorDefineEditors. Adds the option to to the list and adds CSS and JS files
 30+ * @param $editor InlineEditor
 31+ * @param $output OutputPage
 32+ */
 33+ public static function defineEditors( &$editor, &$output ) {
 34+ global $wgExtensionAssetsPath;
 35+
 36+ $editor->addEditMode(
 37+ 'referenceEditor',
 38+ wfMsgExt( 'reference-editor-editmode-caption', 'parseinline' ),
 39+ wfMsgExt( 'reference-editor-editmode-description','parseinline' )
 40+ );
 41+
 42+ $output->addExtensionStyle( "$wgExtensionAssetsPath/InlineEditor/ReferenceEditor/ReferenceEditor.css?0");
 43+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/ReferenceEditor/jquery.inlineEditor.editors.referenceEditor.js?0" );
 44+
 45+ return true;
 46+ }
 47+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.class.php
___________________________________________________________________
Added: svn:eol-style
148 + native
Index: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.i18n.php
@@ -0,0 +1,26 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension ReferenceEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'reference-editor-desc' => 'Adds the "References" edit mode for the InlineEditor',
 17+
 18+ 'reference-editor-editmode-caption' => "References",
 19+ 'reference-editor-editmode-description' => "
 20+References are placed after a piece of text.
 21+You can edit them in this mode, and add new references in the '''Text''' mode.
 22+
 23+:<code><nowiki>According to scientists, the Sun is pretty big. <ref>E. Miller, The Sun, (New York: Academic Press, 2005), 23-5.</ref></nowiki></code>
 24+
 25+[http://www.mediawiki.org/wiki/Extension:Cite/Cite.php More information]
 26+",
 27+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
128 + native
Index: trunk/extensions/InlineEditor/ReferenceEditor/jquery.inlineEditor.editors.referenceEditor.js
@@ -0,0 +1,40 @@
 2+/**
 3+ * Client side part of the ReferenceEditor. Defines $.inlineEditor.editors.referenceEditor.
 4+ */
 5+( function( $ ) { $.inlineEditor.editors.referenceEditor = {
 6+
 7+click: function(event) {
 8+ // prevent clicks from reaching other elements
 9+ event.stopPropagation();
 10+ event.preventDefault();
 11+
 12+ // find the element and retrieve the corresponding wikitext
 13+ var $field = $(this);
 14+ var wiki = $.inlineEditor.getTextById( $field.attr( 'id' ) );
 15+
 16+ $newField = $.inlineEditor.basicEditor.newField( $field, $.inlineEditor.editors.referenceEditor.click );
 17+ $.inlineEditor.basicEditor.addEditBar( $newField, 500, wiki );
 18+},
 19+
 20+enable: function() {
 21+ // do what we also do when reloading the page
 22+ $.inlineEditor.editors.referenceEditor.reload();
 23+
 24+ // add the identifying class to #editContent
 25+ $( '#editContent' ).addClass( 'referenceEditor' );
 26+},
 27+
 28+reload: function() {
 29+ // make references clickable
 30+ $( '.referenceEditorElement' ).click( $.inlineEditor.editors.referenceEditor.click );
 31+},
 32+
 33+disable: function() {
 34+ // remove the click event from the references
 35+ $( '.referenceEditorElement' ).unbind( 'click' );
 36+
 37+ // remove the identifying class from #editContent
 38+ $( '#editContent' ).removeClass( 'referenceEditor' );
 39+}
 40+
 41+}; } ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ReferenceEditor/jquery.inlineEditor.editors.referenceEditor.js
___________________________________________________________________
Added: svn:eol-style
142 + native
Index: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.php
@@ -0,0 +1,41 @@
 2+<?php
 3+/**
 4+ * ReferenceEditor extension for the InlineEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the ReferenceEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.php" );
 13+ *
 14+ * @author Jan Paul Posma <jp.posma@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.0.0
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) die();
 20+
 21+// credits
 22+$wgExtensionCredits['other'][] = array(
 23+ 'path' => __FILE__,
 24+ 'name' => 'ReferenceEditor',
 25+ 'author' => array( 'Jan Paul Posma' ),
 26+ 'version' => '0.1.0',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor#ReferenceEditor',
 28+ 'descriptionmsg' => 'reference-editor-desc',
 29+);
 30+
 31+// current directory including trailing slash
 32+$dir = dirname( __FILE__ ) . '/';
 33+
 34+// add autoload classes
 35+$wgAutoloadClasses['ReferenceEditor'] = $dir . 'ReferenceEditor.class.php';
 36+
 37+// register hooks
 38+$wgHooks['InlineEditorMark'][] = 'ReferenceEditor::mark';
 39+$wgHooks['InlineEditorDefineEditors'][] = 'ReferenceEditor::defineEditors';
 40+
 41+// i18n messages
 42+$wgExtensionMessagesFiles['ReferenceEditor'] = $dir . 'ReferenceEditor.i18n.php';
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.php
___________________________________________________________________
Added: svn:eol-style
143 + native
Index: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.css
@@ -0,0 +1,35 @@
 2+.referenceEditor .referenceEditorElement {
 3+ /* soft-blue background color to highlight editable references */
 4+ background-color: #E4F0F9;
 5+
 6+ /* create a hand cursor, cross-browser hack: http://www.quirksmode.org/css/cursor.html */
 7+ cursor: pointer;
 8+ cursor: hand;
 9+
 10+ /* add a lot of padding to make them stand out */
 11+ padding: 0.5em;
 12+}
 13+
 14+.referenceEditor .referenceEditorElement:hover {
 15+ /* indicate the reference to be edited with a darker color */
 16+ background-color: #a7d7f9;
 17+}
 18+
 19+.referenceEditor .editing {
 20+ /* keeping the custom padding and margin breaks in Webkit browsers */
 21+ padding: 0px;
 22+ margin: 0px;
 23+
 24+ /* reset the cursor when editing */
 25+ cursor: auto;
 26+}
 27+
 28+.referenceEditor .edited {
 29+ /* have a yellow color to highlight edited elements, basically the orange color with the hue shifted */
 30+ background-color: #F9F2A7;
 31+}
 32+
 33+.referenceEditor .lastEdit {
 34+ /* have an orange color, the exact complement of the hover color, for highlighting on preview/cancel */
 35+ background-color: #f9c9a7;
 36+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.css
___________________________________________________________________
Added: svn:eol-style
137 + native
Index: trunk/extensions/InlineEditor/FullEditor/FullEditor.php
@@ -0,0 +1,40 @@
 2+<?php
 3+/**
 4+ * FullEditor extension for the InlineEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the FullEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor/FullEditor/FullEditor.php" );
 13+ *
 14+ * @author Jan Paul Posma <jp.posma@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.0.0
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) die();
 20+
 21+// credits
 22+$wgExtensionCredits['other'][] = array(
 23+ 'path' => __FILE__,
 24+ 'name' => 'FullEditor',
 25+ 'author' => array( 'Jan Paul Posma' ),
 26+ 'version' => '0.1.0',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor#FullEditor',
 28+ 'descriptionmsg' => 'fulleditor-desc',
 29+);
 30+
 31+// current directory including trailing slash
 32+$dir = dirname( __FILE__ ) . '/';
 33+
 34+// add autoload classes
 35+$wgAutoloadClasses['FullEditor'] = $dir . 'FullEditor.class.php';
 36+
 37+// register hooks
 38+$wgHooks['InlineEditorDefineEditors'][] = 'FullEditor::defineEditors';
 39+
 40+// i18n messages
 41+$wgExtensionMessagesFiles['FullEditor'] = $dir . 'FullEditor.i18n.php';
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/FullEditor/FullEditor.php
___________________________________________________________________
Added: svn:eol-style
142 + native
Index: trunk/extensions/InlineEditor/FullEditor/FullEditor.class.php
@@ -0,0 +1,17 @@
 2+<?php
 3+/**
 4+ * This 'editor' just shows some description with a link to the full/traditional editor.
 5+ */
 6+class FullEditor {
 7+ public static function defineEditors( &$editor, &$output ) {
 8+ $editor->addEditMode(
 9+ 'FullEditor',
 10+ wfMsgExt( 'fulleditor-editmode-caption', 'parseinline' ),
 11+ wfMsgExt( 'fulleditor-editmode-description', 'parseinline' )
 12+ . '<br/><a class="fulleditor" href="' . $editor->getArticle()->getTitle()->getLocalURL( 'action=edit&fulleditor=1' ) . '">'
 13+ . wfMsgExt( 'fulleditor-editmode-description-link', 'parseinline' )
 14+ . '</a>'
 15+ );
 16+ return true;
 17+ }
 18+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/FullEditor/FullEditor.class.php
___________________________________________________________________
Added: svn:eol-style
119 + native
Index: trunk/extensions/InlineEditor/FullEditor/FullEditor.i18n.php
@@ -0,0 +1,23 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension FullEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'fulleditor-desc' => 'Provides a link to the full editor for the InlineEditor',
 17+
 18+ 'fulleditor-editmode-caption' => 'Full editor',
 19+ 'fulleditor-editmode-description' => "
 20+If you want full control over the page, you can use the full editor.
 21+With this editor you can edit the [http://en.wikipedia.org/wiki/Help:Wiki_markup Wiki markup] directly.
 22+The editor is also more complex to use, but to have full control of editing Wikipedia, that's worth it!",
 23+ 'fulleditor-editmode-description-link' => 'Use the full editor &raquo;',
 24+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/FullEditor/FullEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
125 + native
Index: trunk/extensions/InlineEditor/jquery-ui-effects-1.8.4.min.js
@@ -0,0 +1,31 @@
 2+/*
 3+ * jQuery UI Effects 1.8.4
 4+ *
 5+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 6+ * Dual licensed under the MIT or GPL Version 2 licenses.
 7+ * http://jquery.org/license
 8+ *
 9+ * http://docs.jquery.com/UI/Effects/
 10+ */
 11+jQuery.effects||function(f,j){function l(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
 12+16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return m.transparent;return m[f.trim(c).toLowerCase()]}function r(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return l(b)}function n(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
 13+a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function o(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in s||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function t(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
 14+a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:f.fx.speeds[b]||f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=r(b.elem,a);b.end=l(b.end);b.colorInit=
 15+true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var m={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,
 16+183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,
 17+165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},p=["add","remove","toggle"],s={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,d){if(f.isFunction(b)){d=b;b=null}return this.each(function(){var e=f(this),g=e.attr("style")||" ",h=o(n.call(this)),q,u=e.attr("className");f.each(p,function(v,
 18+i){c[i]&&e[i+"Class"](c[i])});q=o(n.call(this));e.attr("className",u);e.animate(t(h,q),a,b,function(){f.each(p,function(v,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)})})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?
 19+f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.4",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==
 20+null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();
 21+var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});
 22+c.css({position:"relative",top:0,left:0})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments);a={options:a[1],duration:a[2],callback:a[3]};var b=f.effects[c];return b&&!f.fx.off?b.call(this,a):this},_show:f.fn.show,show:function(c){if(!c||
 23+typeof c=="number"||f.fx.speeds[c])return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(!c||typeof c=="number"||f.fx.speeds[c])return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(!c||typeof c=="number"||f.fx.speeds[c]||typeof c=="boolean"||f.isFunction(c))return this.__toggle.apply(this,
 24+arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,
 25+a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+
 26+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,
 27+10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*
 28+a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,
 29+a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,
 30+a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+
 31+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
 32+;
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/jquery-ui-effects-1.8.4.min.js
___________________________________________________________________
Added: svn:eol-style
133 + native
Added: svn:executable
234 + *
Index: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.i18n.php
@@ -0,0 +1,42 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension SentenceEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Jan Paul Posma
 14+ */
 15+$messages['en'] = array(
 16+ 'sentence-editor-desc' => 'Adds the "Text" edit mode for the InlineEditor',
 17+
 18+ 'sentence-editor-editmode-caption' => "Text",
 19+/*
 20+ 'sentence-editor-editmode-description' => "
 21+There are a few [http://en.wikipedia.org/wiki/Wikipedia:Simplified_ruleset guidelines] for editing an article:<br/>
 22+* Write what you think is best for the article, or as we say here: [http://en.wikipedia.org/wiki/Wikipedia:Be_bold be bold when updating pages]! If you feel that a rule prevents you from improving Wikipedia, [http://en.wikipedia.org/wiki/Wikipedia:Ignore_all_rules ignore it].
 23+* [http://en.wikipedia.org/wiki/Wikipedia:What_Wikipedia_is_not Wikipedia is an encyclopedia.] Someone else should be able to [http://en.wikipedia.org/wiki/Wikipedia:Verifiability verify] what you've written, for example in books or online.
 24+* Write from a [http://en.wikipedia.org/wiki/Wikipedia:Neutral_point_of_view neutral point of view], and use your [http://en.wikipedia.org/wiki/Wikipedia:Copyrights own words].
 25+ ",
 26+*/
 27+ 'sentence-editor-editmode-description' => "
 28+Edit sentences by clicking on them. You can use wiki syntax to format the text. Some examples:
 29+{| width=\"100%\" style=\"background-color: inherit\"
 30+! Code
 31+! Output
 32+|-
 33+| <code><nowiki>Here's a link to the [[Main Page]].</nowiki></code>
 34+| Here's a link to the [[Main Page]].
 35+|-
 36+| <code><nowiki>This is ''italic text'' and this is '''bold text'''.</nowiki></code>
 37+| This is ''italic text'' and this is '''bold text'''.
 38+|-
 39+| <code><nowiki>[http://meta.wikimedia.org/wiki/Help:Editing More information]</nowiki></code>
 40+| [http://meta.wikimedia.org/wiki/Help:Editing More information]
 41+|}
 42+ ",
 43+);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.i18n.php
___________________________________________________________________
Added: svn:eol-style
144 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/jquery.inlineEditor.editors.sentenceEditor.js
@@ -0,0 +1,46 @@
 2+/**
 3+ * Client side part of the SentenceEditor. Defines $.inlineEditor.editors.sentenceEditor,
 4+ * and uses $.elastic and $.textWidth.
 5+ */
 6+( function( $ ) { $.inlineEditor.editors.sentenceEditor = {
 7+
 8+click: function(event) {
 9+ // prevent clicks from reaching other elements
 10+ event.stopPropagation();
 11+ event.preventDefault();
 12+
 13+ // find the <span> element and retrieve the corresponding wikitext
 14+ var $span = $(this);
 15+ var wiki = $.inlineEditor.getTextById( $span.attr( 'id' ) );
 16+
 17+ // calculate width based on the text width witin the page flow
 18+ // this means that this width will never exeed the original width when it's a multiline sentence
 19+ var width = $span.textWidth() - 5;
 20+ if( width < 300 ) width = 300;
 21+
 22+ $newField = $.inlineEditor.basicEditor.newField( $span, $.inlineEditor.editors.sentenceEditor.click );
 23+ $.inlineEditor.basicEditor.addEditBar( $newField, width, wiki );
 24+},
 25+
 26+enable: function() {
 27+ // do what we also do when reloading the page
 28+ $.inlineEditor.editors.sentenceEditor.reload();
 29+
 30+ // add the identifying class to #editContent
 31+ $( '#editContent' ).addClass( 'sentenceEditor' );
 32+},
 33+
 34+reload: function() {
 35+ // make sentences clickable
 36+ $( '.sentenceEditorElement' ).click( $.inlineEditor.editors.sentenceEditor.click );
 37+},
 38+
 39+disable: function() {
 40+ // remove the click event from the sentences
 41+ $( '.sentenceEditorElement' ).unbind( 'click' );
 42+
 43+ // remove the identifying class from #editContent
 44+ $( '#editContent' ).removeClass( 'sentenceEditor' );
 45+}
 46+
 47+}; } ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/jquery.inlineEditor.editors.sentenceEditor.js
___________________________________________________________________
Added: svn:eol-style
148 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.php
@@ -0,0 +1,46 @@
 2+<?php
 3+/**
 4+ * SentenceEditor extension for the InlineEditor.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the SentenceEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor/SentenceEditor/SentenceEditor.php" );
 13+ *
 14+ * @author Jan Paul Posma <jp.posma@gmail.com>
 15+ * @license GPL v2 or later
 16+ * @version 0.0.0
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) die();
 20+
 21+// credits
 22+$wgExtensionCredits['other'][] = array(
 23+ 'path' => __FILE__,
 24+ 'name' => 'SentenceEditor',
 25+ 'author' => array( 'Jan Paul Posma' ),
 26+ 'version' => '0.1.0',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor#SentenceEditor',
 28+ 'descriptionmsg' => 'sentence-editor-desc',
 29+);
 30+
 31+// current directory including trailing slash
 32+$dir = dirname( __FILE__ ) . '/';
 33+
 34+// add autoload classes
 35+$wgAutoloadClasses['SentenceEditor'] = $dir . 'SentenceEditor.class.php';
 36+$wgAutoloadClasses['ISentenceDetection'] = $dir . 'SentenceDetection/ISentenceDetection.class.php';
 37+$wgAutoloadClasses['SentenceDetectionBasic'] = $dir . 'SentenceDetection/SentenceDetectionBasic.class.php';
 38+
 39+// register hooks
 40+$wgHooks['InlineEditorMark'][] = 'SentenceEditor::mark';
 41+$wgHooks['InlineEditorDefineEditors'][] = 'SentenceEditor::defineEditors';
 42+
 43+// i18n messages
 44+$wgExtensionMessagesFiles['SentenceEditor'] = $dir . 'SentenceEditor.i18n.php';
 45+
 46+// default settings
 47+$wgSentenceEditorDetectionDefault = 'SentenceDetectionBasic';
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.php
___________________________________________________________________
Added: svn:eol-style
148 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.css
@@ -0,0 +1,36 @@
 2+.sentenceEditor .sentenceEditorElement {
 3+ /* soft-blue background color to highlight editable sentences */
 4+ background-color: #E4F0F9;
 5+
 6+ /* create a hand cursor, cross-browser hack: http://www.quirksmode.org/css/cursor.html */
 7+ cursor: pointer;
 8+ cursor: hand;
 9+
 10+ /* have the background color extend just a bit around the text border, looks better */
 11+ margin: -1px;
 12+ padding: 1px;
 13+}
 14+
 15+.sentenceEditor .sentenceEditorElement:hover {
 16+ /* indicate the sentence to be edited with a darker color */
 17+ background-color: #a7d7f9;
 18+}
 19+
 20+.sentenceEditor .editing {
 21+ /* keeping the custom padding and margin breaks in Webkit browsers */
 22+ padding: 0px;
 23+ margin: 0px;
 24+
 25+ /* reset the cursor when editing */
 26+ cursor: auto;
 27+}
 28+
 29+.sentenceEditor .edited {
 30+ /* have a yellow color to highlight edited elements, basically the orange color with the hue shifted */
 31+ background-color: #F9F2A7;
 32+}
 33+
 34+.sentenceEditor .lastEdit {
 35+ /* have an orange color, the exact complement of the hover color, for highlighting on preview/cancel */
 36+ background-color: #f9c9a7;
 37+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.css
___________________________________________________________________
Added: svn:eol-style
138 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection/SentenceDetectionBasic.class.php
@@ -0,0 +1,36 @@
 2+<?php
 3+/**
 4+ * Basic implementation of sentence splitting. Not recommended for actual use, but does the job
 5+ * for a simple demo.
 6+ */
 7+class SentenceDetectionBasic implements ISentenceDetection {
 8+ private $wikiTexts;
 9+
 10+ function __construct() {
 11+ $this->wikiTexts = array();
 12+ }
 13+
 14+ public function addWikiText( $text, $offset ) {
 15+ $this->wikiTexts[] = array( 'text' => $text, 'offset' => $offset );
 16+ }
 17+
 18+ public function addPiecesToText( InlineEditorText &$inlineEditorText, $class, $inline ) {
 19+ $pieces = array();
 20+ foreach( $this->wikiTexts as $wikiText ) {
 21+ $sentences = preg_split( "/(?<!\..|\...|\....)([\?\!\.]+)\s(?!.\.|..\.|...\.)/u", $wikiText['text'], -1,
 22+ PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_DELIM_CAPTURE );
 23+
 24+ foreach( $sentences as $index => $sentence ) {
 25+ if( $index % 2 == 0 ) {
 26+ if( isset( $sentences[$index+1] ) ) {
 27+ $sentence[0] .= $sentences[$index+1][0];
 28+ }
 29+ $start = $wikiText['offset'] + $sentence[1];
 30+ $end = $start + strlen( $sentence[0] );
 31+ $inlineEditorText->addPiece( new InlineEditorPiece( $start, $end, $class, $inline ) );
 32+ }
 33+ }
 34+ }
 35+ return $pieces;
 36+ }
 37+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection/SentenceDetectionBasic.class.php
___________________________________________________________________
Added: svn:eol-style
138 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection/ISentenceDetection.class.php
@@ -0,0 +1,23 @@
 2+<?php
 3+/**
 4+ * This interface defines what a sentence detector should be able to do, which is
 5+ * adding portions of wikitext and adding the detected sentences as pieces to an
 6+ * InlineEditorText object.
 7+ */
 8+interface ISentenceDetection {
 9+ /**
 10+ * Add a bit of wikitext to the object. The wikitext has to be split in sentences while
 11+ * remembering the position of each sentence.
 12+ * @param $text String
 13+ * @param $position Integer
 14+ */
 15+ public function addWikiText( $text, $position );
 16+
 17+ /**
 18+ * All the sentences and their offsets have to be added as pieces to $inlineEditorText.
 19+ * @param $inlineEditorText InlineEditorText Object the pieces should be added to
 20+ * @param $class String Class name of the piece
 21+ * @param $inline Boolean whether the pieces are inline or not
 22+ */
 23+ public function addPiecesToText( InlineEditorText &$inlineEditorText, $class, $inline );
 24+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/SentenceDetection/ISentenceDetection.class.php
___________________________________________________________________
Added: svn:eol-style
125 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.class.php
@@ -0,0 +1,127 @@
 2+<?php
 3+/**
 4+ * This editor allows for editing individual sentences. It strips the wikitext from
 5+ * things that are too hard to edit, and leaves the splitting of sentences to a
 6+ * class that implements the interface ISentenceDetection.
 7+ *
 8+ * It's very much possible to create an extension that inherits from this class to
 9+ * do the detection another way, i.e. without the preprocessing and splitting.
 10+ */
 11+class SentenceEditor {
 12+
 13+ /**
 14+ * This function hooks into InlineEditorMark and marks the sentences.
 15+ * @param $inlineEditorText InlineEditorText
 16+ */
 17+ public static function mark( &$inlineEditorText ) {
 18+ global $wgSentenceEditorDetectionDefault;
 19+
 20+ // get the original wikitext
 21+ $text = $inlineEditorText->getWikiOriginal();
 22+
 23+ // preprocess the text by replacing everything difficult by spaces
 24+ $text = self::preprocess( $text );
 25+
 26+ // split what's left into sensible blocks of text
 27+ $split = self::split( $text );
 28+
 29+ // get the default detection class and make it able for extensions to alter it
 30+ $detectionClass = $wgSentenceEditorDetectionDefault;
 31+ wfRunHooks( 'SentenceEditorDetectionClass', array( &$detectionClass ) );
 32+
 33+ // spawn the detection class and add the texts and position
 34+ $detection = new $detectionClass();
 35+ foreach( $split as $wikiText ) {
 36+ // $wikiText[0] is the text, $wikiText[1] is the position of that text
 37+ $detection->addWikiText( $wikiText[0], $wikiText[1] );
 38+ }
 39+
 40+ // have the detection class add the pieces to the InlineEditorText object,
 41+ // class 'sentenceEditorElement', inline elements
 42+ $detection->addPiecesToText( $inlineEditorText, 'sentenceEditorElement', true );
 43+
 44+ return true;
 45+ }
 46+
 47+ /**
 48+ * Hooks into InlineEditorDefineEditors. Adds the option to to the list and adds CSS and JS files
 49+ * @param $editor InlineEditor
 50+ * @param $output OutputPage
 51+ */
 52+ public static function defineEditors( &$editor, &$output ) {
 53+ global $wgExtensionAssetsPath;
 54+
 55+ $editor->addEditMode(
 56+ 'sentenceEditor',
 57+ wfMsgExt( 'sentence-editor-editmode-caption', 'parseinline' ),
 58+ wfMsgExt( 'sentence-editor-editmode-description','parseinline' )
 59+ );
 60+
 61+ $output->addExtensionStyle( "$wgExtensionAssetsPath/InlineEditor/SentenceEditor/SentenceEditor.css?0");
 62+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/SentenceEditor/jquery.inlineEditor.editors.sentenceEditor.js?0" );
 63+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/SentenceEditor/jquery.textWidth.js?0" );
 64+ $output->addScriptFile( "$wgExtensionAssetsPath/InlineEditor/SentenceEditor/jquery.elastic.js?0" );
 65+
 66+ return true;
 67+ }
 68+
 69+ /**
 70+ * Replaces all occurences of unsupported wikitext by spaces. This is to make sure the
 71+ * positions of what's left are still the same as those in the original wikitext
 72+ * @param $wikitext String
 73+ * @return String
 74+ */
 75+ protected static function preprocess( $wikitext ) {
 76+ $patterns = array();
 77+
 78+ // remove references
 79+ $patterns[] = '/(<ref[^>\/]*>.*?<\/ref>)/is';
 80+
 81+ // remove references like <ref/>
 82+ $patterns[] = '/(<ref.*?\/>)/i';
 83+
 84+ // remove templates starting at the beginning of a line (or with whitespace)
 85+ $patterns[] = '/^\s*(\{\{.*?\}\})/ms';
 86+
 87+ // remove tables
 88+ $patterns[] = '/(\{\|.*?\|\})/';
 89+
 90+ // remove links with : in it
 91+ $patterns[] = '/(\[\[[^:\[\]]*:[^:\[\]]*\]\])/';
 92+
 93+ // remove headings
 94+ $patterns[] = '/^(=+[^=]*=+)\s*$/m';
 95+
 96+ // remove lists, indents, things like that
 97+ $patterns[] = '/^[\*#:;](.*)$/m';
 98+
 99+ return preg_replace_callback( $patterns, 'SentenceEditor::makeSpaces', $wikitext );
 100+ }
 101+
 102+ /**
 103+ * Function used by preprocess() to replace matches with spaces
 104+ * @param $matches array
 105+ * @return String
 106+ */
 107+ protected static function makeSpaces ( $matches ) {
 108+ return str_repeat( ' ', strlen($matches[0]) );
 109+ }
 110+
 111+ /**
 112+ * Splits the wikitext into pieces of actual text. A split is forced where there are
 113+ * two spaces or a newline. This way, it's possible to have the users define the sentences.
 114+ * @param $wikitext String
 115+ * @return array
 116+ */
 117+ protected static function split( $wikitext ) {
 118+ // split where there are at least two spaces, or a newline, or the beginning of the text
 119+ $splits = preg_split( '/\s\s+|\n\s*|^/', $wikitext, -1, PREG_SPLIT_OFFSET_CAPTURE );
 120+
 121+ // remove small occurences
 122+ foreach( $splits as $index => $split ) {
 123+ if( strlen( $split[0] ) < 2 ) unset( $splits[$index] );
 124+ }
 125+
 126+ return $splits;
 127+ }
 128+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/SentenceEditor.class.php
___________________________________________________________________
Added: svn:eol-style
1129 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/jquery.elastic.js
@@ -0,0 +1,6 @@
 2+(function(jQuery){jQuery.fn.extend({elastic:function(){var mimics=['paddingTop','paddingRight','paddingBottom','paddingLeft','fontSize','lineHeight','fontFamily','width','fontWeight'];return this.each(function(){if(this.type!='textarea'){return false;}
 3+var $textarea=jQuery(this),$twin=jQuery('<div />').css({'position':'absolute','display':'none','word-wrap':'break-word'}),lineHeight=parseInt($textarea.css('line-height'),10)||parseInt($textarea.css('font-size'),'10'),minheight=parseInt($textarea.css('height'),10)||lineHeight*3,maxheight=parseInt($textarea.css('max-height'),10)||Number.MAX_VALUE,goalheight=0,i=0;if(maxheight<0){maxheight=Number.MAX_VALUE;}
 4+$twin.appendTo($textarea.parent());var i=mimics.length;while(i--){$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()));}
 5+function setHeightAndOverflow(height,overflow){curratedHeight=Math.floor(parseInt(height,10));if($textarea.height()!=curratedHeight){$textarea.css({'height':curratedHeight+'px','overflow':overflow});}}
 6+function update(){var textareaContent=$textarea.val().replace(/&/g,'&amp;').replace(/ /g,'&nbsp;').replace(/<|>/g,'&gt;').replace(/\n/g,'<br />');var twinContent=$twin.html();if(textareaContent+'&nbsp;'!=twinContent){$twin.html(textareaContent+'&nbsp;');if(Math.abs($twin.height()+lineHeight-$textarea.height())>3){var goalheight=$twin.height()+lineHeight;if(goalheight>=maxheight){setHeightAndOverflow(maxheight,'auto');}else if(goalheight<=minheight){setHeightAndOverflow(minheight,'hidden');}else{setHeightAndOverflow(goalheight,'hidden');}}}}
 7+$textarea.css({'overflow':'hidden'});$textarea.keyup(function(){update();});$textarea.live('input paste',function(e){setTimeout(update,250);});update();});}});})(jQuery);
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/jquery.elastic.js
___________________________________________________________________
Added: svn:eol-style
18 + native
Index: trunk/extensions/InlineEditor/SentenceEditor/jquery.textWidth.js
@@ -0,0 +1,33 @@
 2+/**
 3+ * Function to determine the actual usable width of a span.
 4+ * This means that the span has to start at the left of the containing element,
 5+ * and the text inside the span may wrap if it gets too long.
 6+ */
 7+( function( $ ) {
 8+ $.fn.textWidth = function(){
 9+ var element = $j(this);
 10+
 11+ // build an outer element that stretches to the maximum width, so the span will
 12+ // be located to the leftmost position
 13+ var outer = $('<div style="width: 100%"></div>');
 14+
 15+ // build a span inside the outer div
 16+ var inner = $('<span></span>');
 17+ inner.html(element.html());
 18+ outer.append(inner);
 19+
 20+ // place the outer div after the original element and hide the original element so it'll
 21+ // be in exactly the same place
 22+ element.after(outer);
 23+ element.hide();
 24+
 25+ // calculate the div of the span (which will wrap when it meets the maximum width)
 26+ var width = inner.width();
 27+
 28+ // remove the test elements and show the original element again
 29+ outer.remove();
 30+ element.show();
 31+
 32+ return width;
 33+ };
 34+} ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/SentenceEditor/jquery.textWidth.js
___________________________________________________________________
Added: svn:eol-style
135 + native
Index: trunk/extensions/InlineEditor/InlineEditor.php
@@ -0,0 +1,61 @@
 2+<?php
 3+/**
 4+ * InlineEditor extension.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ *
 9+ * This is the include file for the InlineEditor.
 10+ *
 11+ * Usage: Include the following line in your LocalSettings.php
 12+ * require_once( "$IP/extensions/InlineEditor.php" );
 13+ *
 14+ * To enable all provided editors, add this in your LocalSettings.php:
 15+ * require_once( "$IP/extensions/InlineEditor/InlineEditor.php" );
 16+ * require_once( "$IP/extensions/InlineEditor/SentenceEditor/SentenceEditor.php" );
 17+ * require_once( "$IP/extensions/InlineEditor/ListEditor/ListEditor.php" );
 18+ * require_once( "$IP/extensions/InlineEditor/ReferenceEditor/ReferenceEditor.php" );
 19+ * require_once( "$IP/extensions/InlineEditor/MediaEditor/MediaEditor.php" );
 20+ * require_once( "$IP/extensions/InlineEditor/TemplateEditor/TemplateEditor.php" );
 21+ * require_once( "$IP/extensions/InlineEditor/FullEditor/FullEditor.php" );
 22+ *
 23+ * @author Jan Paul Posma <jp.posma@gmail.com>
 24+ * @license GPL v2 or later
 25+ * @version 0.0.0
 26+ */
 27+
 28+if ( !defined( 'MEDIAWIKI' ) ) die();
 29+
 30+// credits
 31+$wgExtensionCredits['other'][] = array(
 32+ 'path' => __FILE__,
 33+ 'name' => 'InlineEditor',
 34+ 'author' => array( 'Jan Paul Posma' ),
 35+ 'version' => '0.1.0',
 36+ 'url' => 'http://www.mediawiki.org/wiki/Extension:InlineEditor',
 37+ 'descriptionmsg' => 'inline-editor-desc',
 38+);
 39+
 40+// current directory including trailing slash
 41+$dir = dirname(__FILE__) . '/';
 42+
 43+// add autoload classes
 44+$wgAutoloadClasses['InlineEditor'] = $dir . 'InlineEditor.class.php';
 45+$wgAutoloadClasses['InlineEditorText'] = $dir . 'InlineEditorText.class.php';
 46+$wgAutoloadClasses['InlineEditorPiece'] = $dir . 'InlineEditorPiece.class.php';
 47+$wgAutoloadClasses['InlineEditorPreviousMarking'] = $dir . 'InlineEditorPreviousMarking.class.php';
 48+$wgAutoloadClasses['ExtendedEditPage'] = $dir . 'ExtendedEditPage.class.php';
 49+
 50+// register hooks
 51+$wgHooks['MediaWikiPerformAction'][] = 'InlineEditor::mediaWikiPerformAction';
 52+$wgHooks['EditPage::showEditForm:initial'][] = 'InlineEditor::showEditForm';
 53+
 54+// i18n messages
 55+$wgExtensionMessagesFiles['InlineEditor'] = $dir . 'InlineEditor.i18n.php';
 56+
 57+// ajax functions
 58+$wgAjaxExportList[] = 'InlineEditor::ajaxPreview';
 59+
 60+// default options
 61+$wgInlineEditorBrowserBlacklist = $wgBrowserBlackList;
 62+$wgInlineEditorAllowedNamespaces = array( NS_MAIN, NS_TALK, NS_USER, NS_USER_TALK );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditor.php
___________________________________________________________________
Added: svn:eol-style
163 + native
Index: trunk/extensions/InlineEditor/InlineEditor.css
@@ -0,0 +1,258 @@
 2+/*
 3+ * Right now everything has #siteNotice in front as there's no better way, really, to include the
 4+ * top boxes to the page.
 5+ */
 6+
 7+#siteNotice {
 8+ text-align: inherit;
 9+ font-size: inherit;
 10+}
 11+
 12+#siteNotice div,
 13+#siteNotice p {
 14+ /* make these elements behave normal again */
 15+ margin: 0px;
 16+ padding: 0px;
 17+}
 18+
 19+#siteNotice div.editbox {
 20+ /* box on top of the page, colors are the same as the surrounding colors */
 21+ /* it scales with the display size */
 22+ font-size: 1.0em;
 23+ background-color: #eaf3f8;
 24+ border: 1px solid #A7D7F9;
 25+ margin-bottom: 10px;
 26+ padding: 10px 10px 5px;
 27+ max-width: 700px;
 28+ position: relative;
 29+}
 30+
 31+#siteNotice div.editbox .highlightExample {
 32+ /* example in the text to show how the highlights look like */
 33+ background-color: #a7d7f9;
 34+ padding: 1px 3px;
 35+}
 36+
 37+#siteNotice div.editbox input.summary {
 38+ /* summary box, scales with the editbox to a certain point */
 39+ display: block;
 40+ width: 500px;
 41+ max-width: 98%;
 42+ padding: 2px;
 43+ margin: 2px 0px;
 44+ font-size: 0.8em;
 45+}
 46+
 47+#siteNotice div.editbox .example, .editbox .terms {
 48+ /* smaller font and lighter color for less important items */
 49+ font-size: 0.8em;
 50+ color: #555;
 51+}
 52+
 53+#siteNotice div.editbox .side {
 54+ /* text besides the publish button */
 55+ margin-right: 150px;
 56+}
 57+
 58+/*#siteNotice div.editbox*/ #publish {
 59+ /* style the publish button to be eye-catching using a bright green color */
 60+ background-color: #008C00;
 61+ color: #fff;
 62+ font-size: 1.5em;
 63+ padding: 8px 16px 6px;
 64+ line-height: 1em;
 65+ position: absolute;
 66+ bottom: 10px;
 67+ right: 10px;
 68+ border: 1px solid green;
 69+
 70+ /* cross (modern) browser rounded corners */
 71+ border-radius: 10px;
 72+ -moz-border-radius: 10px;
 73+ -webkit-border-radius: 10px;
 74+}
 75+
 76+#siteNotice div.editmode {
 77+ /* style the mode selection box essentially in the same way as the box above */
 78+ border: 1px solid #A7D7F9;
 79+ padding: 0px;
 80+ max-width: 720px;
 81+ margin-bottom: 10px;
 82+}
 83+
 84+#siteNotice div.editmode .header {
 85+ /* only the header has a blue background color */
 86+ background-color: #eaf3f8;
 87+ margin: 0px;
 88+ padding: 0px;
 89+
 90+ /* make sure the header resizes due to the floated elements */
 91+ overflow: auto;
 92+
 93+ /* make the bottom borders of the buttons collapse */
 94+ margin-bottom: -1px;
 95+}
 96+
 97+#siteNotice div.editmode .header .radio, #siteNotice div.editmode .header .button {
 98+ /* margin fix for old IE versions, see http://www.positioniseverything.net/explorer/doubled-margin.html */
 99+ display: inline;
 100+ float: left;
 101+
 102+ /* have the borders here, not in the header div, to make sure it looks good on smaller displays! */
 103+ border-top: 1px solid #A7D7F9;
 104+ border-right: 1px solid #A7D7F9;
 105+ border-bottom: 1px solid #A7D7F9;
 106+ padding: 2px 6px;
 107+ height: 22px;
 108+
 109+ /* collapse the top border */
 110+ margin-top: -1px;
 111+}
 112+
 113+#siteNotice div.editmode .header .button {
 114+ /* undo and redo buttons on the right, as well as the counter */
 115+ float: right;
 116+ border-left: 1px solid #A7D7F9;
 117+ border-right: none;
 118+}
 119+
 120+#siteNotice div.editmode .header .button a {
 121+ font-size: 0.9em;
 122+}
 123+
 124+/*#siteNotice div.editmode .header .button */ #editCounter {
 125+ font-size: 0.9em;
 126+ color: #555;
 127+}
 128+
 129+/*#siteNotice div.editmode .header .button */ #editCounter.changeHighlight {
 130+ color: #eaf3f8;
 131+}
 132+
 133+#siteNotice div.editmode .header .radio input {
 134+ /* use only the padding of .radio div, and the label margin */
 135+ margin: 0px;
 136+}
 137+
 138+#siteNotice div.editmode .header .title {
 139+ /* bold title on the left side of the header */
 140+ font-size: 0.9em;
 141+ font-weight: bold;
 142+}
 143+
 144+#siteNotice div.editmode .header .radio label {
 145+ /* only have a small margin on the left side */
 146+ font-size: 0.9em;
 147+ margin: 0px 0px 0px 5px;
 148+
 149+ /* create a hand cursor, cross-browser hack: http://www.quirksmode.org/css/cursor.html */
 150+ cursor: pointer;
 151+ cursor: hand;
 152+}
 153+
 154+#siteNotice div.editmode .header .radio label:hover {
 155+ /* make the labels recognizable as clickable */
 156+ text-decoration: underline;
 157+}
 158+
 159+#siteNotice div.editmode .descriptionOuter {
 160+ /* have a top border which collapses with the label borders */
 161+ border-top: 1px solid #A7D7F9;
 162+
 163+ /* use padding and margin only in the inner div */
 164+ padding: 0px;
 165+ margin: 0px;
 166+
 167+
 168+ /* make sure the box works correctly for the nice animation */
 169+ background-color: #f8f8f8;
 170+ position: relative;
 171+ overflow: hidden;
 172+}
 173+
 174+#siteNotice div.editmode .descriptionInner {
 175+ /* have the same padding as the box above */
 176+ padding: 10px 10px 5px;
 177+ margin: 0px;
 178+
 179+ /* position all the inner descriptions at the same place for the nice animation */
 180+ position: absolute;
 181+ top: 0px;
 182+ left: 0px;
 183+}
 184+
 185+#editContent a, #editContent a:hover, #editContent a:visited, #editContent a:active {
 186+ /* remove the link underline because that way it looks they're clickable */
 187+ text-decoration: none;
 188+}
 189+
 190+#editContent .orig {
 191+ /* hide the original element */
 192+ display: none;
 193+}
 194+
 195+#editContent .editbar {
 196+ /* use an inline-block to support no-wrap and width; this makes sure everything is on one line
 197+ the inline-block is cross-browser supported because a span is inline by default,
 198+ see http://www.quirksmode.org/css/display.html */
 199+ display: inline-block;
 200+ white-space: no-wrap;
 201+
 202+ /* this is used for vertical alignment */
 203+ position: relative;
 204+ vertical-align: middle;
 205+
 206+ margin: 2px;
 207+}
 208+
 209+#editContent .editbar input {
 210+ /* vertically align the inputs */
 211+ position: absolute;
 212+ top: 50%;
 213+ height: 22px;
 214+ margin-top: -11px;
 215+}
 216+
 217+#editContent .editbar textarea {
 218+ /* style the textarea font, as this differs heavily from browser to browser */
 219+ font-family: sans-serif;
 220+ font-size: 1.0em;
 221+ line-height: 1.3em;
 222+ margin: 0px;
 223+ padding: 0px;
 224+ height: 50px;
 225+
 226+ /* disable resizing for browsers like Chrome, as we do this ourselves */
 227+ resize: none;
 228+}
 229+
 230+#editContent .editbar .overlay {
 231+ /* position the overly to cover the entire editbar */
 232+ height: 100%;
 233+ left: 0;
 234+ position: absolute;
 235+ text-align: center;
 236+ top: 0;
 237+ width: 100%;
 238+}
 239+
 240+#editContent .editbar .overlay img.spinner {
 241+ /* position the spinner exactly in the middle */
 242+ left: 50%;
 243+ margin-left: -8px;
 244+ margin-top: -8px;
 245+ position: absolute;
 246+ top: 50%;
 247+ width: 16px;
 248+ height: 16px;
 249+}
 250+
 251+#editContent .editbar .overlay .alpha {
 252+ /* have a cross-browser alpha overlay, see http://www.quirksmode.org/css/opacity.html */
 253+ width: 100%;
 254+ height: 100%;
 255+ background-color: #333;
 256+ opacity: 0.7;
 257+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
 258+ filter: alpha(opacity=70);
 259+}
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/InlineEditor.css
___________________________________________________________________
Added: svn:eol-style
1260 + native
Index: trunk/extensions/InlineEditor/jquery.inlineEditor.js
@@ -0,0 +1,229 @@
 2+/**
 3+ * Client side framework of the InlineEditor. Facilitates publishing, previewing,
 4+ * switching edit modes and undo/redo operations.
 5+ */
 6+( function( $ ) { $.inlineEditor = {
 7+editors: {},
 8+
 9+editModes: [],
 10+currentMode: '',
 11+
 12+states: [],
 13+currentState: 0,
 14+lastState: 0,
 15+
 16+/**
 17+ * Adds the initial state from the current HTML and a wiki string.
 18+ */
 19+addInitialState: function( stateWiki ) {
 20+ $.inlineEditor.states[0] = {
 21+ wiki: stateWiki,
 22+ html: $('#editContent').html()
 23+ };
 24+ $.inlineEditor.currentState = 0;
 25+},
 26+
 27+/**
 28+ * Returns wikitext in the current state given an ID.
 29+ */
 30+getTextById: function( id ) {
 31+ return $.inlineEditor.states[$.inlineEditor.currentState].wiki.locations[id].text;
 32+},
 33+
 34+/**
 35+ * Previews given a new text for a given field by ID.
 36+ */
 37+previewTextById: function( text, id ) {
 38+ // send out an AJAX request which will be handled by addNewState()
 39+ var data = {
 40+ 'originalWiki': $.inlineEditor.states[$.inlineEditor.currentState].wiki,
 41+ 'lastEdit': { 'id': id, 'text': text }
 42+ };
 43+
 44+ var args = [ JSON.stringify( data ), wgPageName ];
 45+ sajax_request_type = 'POST';
 46+ sajax_do_call( 'InlineEditor::ajaxPreview', args, $.inlineEditor.addNewState );
 47+},
 48+
 49+/**
 50+ * Adds a new state from an AJAX request.
 51+ */
 52+addNewState: function( request ) {
 53+ // save the state and show it on the screen
 54+ state = JSON.parse( request.responseText );
 55+ $('#editContent').html( state.html );
 56+ $.inlineEditor.currentState += 1;
 57+ $.inlineEditor.states[$.inlineEditor.currentState] = state;
 58+
 59+ // clear out all states after the current state, because undo/redo would be broken
 60+ var i = $.inlineEditor.currentState + 1;
 61+ while( i <= $.inlineEditor.lastState ) {
 62+ delete $.inlineEditor.states[i];
 63+ i += 1;
 64+ }
 65+ $.inlineEditor.lastState = $.inlineEditor.currentState;
 66+
 67+ // reload the current editor and update the edit counter
 68+ $.inlineEditor.reload();
 69+ $.inlineEditor.updateEditCounter();
 70+},
 71+
 72+/**
 73+ * Reloads the current editor and finish some things in the HTML.
 74+ */
 75+reload: function() {
 76+ // reload the current editor
 77+ $.inlineEditor.editors[$.inlineEditor.currentMode].reload();
 78+
 79+ // fade out all lastEdit elements
 80+ $('.lastEdit').removeClass('lastEdit', 200);
 81+
 82+ // make the links in the article unusable
 83+ $('#editContent a').click(function(event) { event.preventDefault(); });
 84+},
 85+
 86+/**
 87+ * Moves back one state.
 88+ */
 89+undo: function( event ) {
 90+ event.stopPropagation();
 91+ event.preventDefault();
 92+
 93+ // check if we can move backward one state and do it
 94+ if( $.inlineEditor.currentState > 0 ) {
 95+ $.inlineEditor.currentState -= 1;
 96+ $('#editContent').html( $.inlineEditor.states[$.inlineEditor.currentState].html );
 97+ $.inlineEditor.reload();
 98+ }
 99+
 100+ // refresh the edit counter regardless of actually switching, this confirms
 101+ // that the button works, even if there is nothing to switch to
 102+ $.inlineEditor.updateEditCounter();
 103+},
 104+
 105+/**
 106+ * Moves forward one state.
 107+ */
 108+redo: function( event ) {
 109+ event.stopPropagation();
 110+ event.preventDefault();
 111+
 112+ // check if we can move forward one state and do it
 113+ if( $.inlineEditor.currentState < $.inlineEditor.lastState ) {
 114+ $.inlineEditor.currentState += 1;
 115+ $('#editContent').html( $.inlineEditor.states[$.inlineEditor.currentState].html );
 116+ $.inlineEditor.reload();
 117+ }
 118+
 119+ // refresh the edit counter regardless of actually switching, this confirms
 120+ // that the button works, even if there is nothing to switch to
 121+ $.inlineEditor.updateEditCounter();
 122+},
 123+
 124+/**
 125+ * Updates the edit counter and makes it flash.
 126+ */
 127+updateEditCounter: function() {
 128+ // update the value of the edit counter
 129+ var $editCounter = $( '#editCounter' );
 130+ $editCounter.text( '#' + $.inlineEditor.currentState );
 131+
 132+ // remove everything from the editcounter, and have it fade again
 133+ $editCounter.removeClass( 'changeHighlight' );
 134+ $editCounter.attr( 'style', '' );
 135+ $editCounter.addClass( 'changeHighlight' );
 136+ $editCounter.removeClass( 'changeHighlight', 200 );
 137+},
 138+
 139+/**
 140+ * Checks if the mode radio button has changed and selects the new editor and description.
 141+ */
 142+changeMode: function( event ) {
 143+ // set the currently visible descriptions in the foreground to have them
 144+ // fade away nicely
 145+ $( '.editmode .descriptionInner' ).css( 'z-index', 2 );
 146+ $( '.editmode .descriptionInner' ).fadeOut(300);
 147+
 148+ // check for all options if they are selected
 149+ for( var optionNr in $.inlineEditor.editModes ) {
 150+ if( $.inlineEditor.editModes[optionNr] ) {
 151+ var option = $.inlineEditor.editModes[optionNr];
 152+
 153+ // if a certain option is selected, show the description
 154+ // and set the edit mode in #content, then exit this function as only
 155+ // one mode can be selected
 156+ if( $( '#radio-' + option ).attr( 'checked' ) ) {
 157+ // get the description, put it behind the currently visible description,
 158+ // and show it instantly
 159+ $description = $( '#description-' + option );
 160+ $description.show();
 161+ $description.css( 'z-index', 1 );
 162+
 163+ // resize the outer box to match the description height, also take in
 164+ // account the padding of the description box
 165+ $( '.editmode .descriptionOuter' ).animate( {
 166+ height: $description.height() + 15
 167+ }, 600);
 168+
 169+ // if we've actually switched, disable the previous editor and enable
 170+ // the new one
 171+ if( $.inlineEditor.currentMode != option ) {
 172+ if( $.inlineEditor.editors[$.inlineEditor.currentMode] ) {
 173+ $.inlineEditor.editors[$.inlineEditor.currentMode].disable();
 174+ }
 175+
 176+ $.inlineEditor.currentMode = option;
 177+
 178+ if( $.inlineEditor.editors[$.inlineEditor.currentMode] ) {
 179+ $.inlineEditor.editors[$.inlineEditor.currentMode].enable();
 180+ }
 181+ }
 182+
 183+ // we've found the option to switch to, nothing to be done anymore
 184+ return;
 185+ }
 186+ }
 187+ }
 188+},
 189+
 190+/**
 191+ * Publishes the document in its current state.
 192+ */
 193+publish: function( event ) {
 194+ event.stopPropagation();
 195+ event.preventDefault();
 196+
 197+ // get the wikitext from the state as it's currently on the screen
 198+ var data = { 'originalWiki': $.inlineEditor.states[$.inlineEditor.currentState].wiki };
 199+ var json = JSON.stringify( data );
 200+
 201+ // set and send the form
 202+ $( '#json' ).val( json );
 203+ $( '#editForm' ).submit();
 204+},
 205+
 206+/**
 207+ * Initializes the editor.
 208+ */
 209+init : function() {
 210+ // make the edit mode radiobuttons clickable
 211+ $( '.optionMode' ).change( $.inlineEditor.changeMode );
 212+
 213+ $( '#publish' ).click( $.inlineEditor.publish );
 214+ $( '#undo' ).click( $.inlineEditor.undo );
 215+ $( '#redo' ).click( $.inlineEditor.redo );
 216+
 217+ // initially hide the descriptions, else things look messy because of the animation
 218+ $( '.editmode .descriptionInner' ).hide();
 219+
 220+ // open all our links in a new window except for switching to the full editor
 221+ $( '#siteNotice a[class!=fulleditor]' ).attr( 'target', '_blank' );
 222+
 223+ // check the current selected edit mode
 224+ $.inlineEditor.changeMode();
 225+
 226+ // reload the current editor
 227+ $.inlineEditor.reload();
 228+}
 229+
 230+}; } ) ( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/InlineEditor/jquery.inlineEditor.js
___________________________________________________________________
Added: svn:eol-style
1231 + native

Comments

#Comment by Raymond (talk | contribs)   15:13, 6 September 2010

A very short i18n review from translatewiki sight:

I suggest to prefix all messages with the name of the extension: 'inline-editor-' to avoid key conflicts with other extensions. I.e. 'template-editor-desc' cries for such a conflict. May not today but in the future.

#Comment by JanPaul123 (talk | contribs)   15:19, 6 September 2010

Makes sense, I'll do that!

Status & tagging log