r83222 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r83221‎ | r83222 | r83223 >
Date:17:06, 4 March 2011
Author:janpaul123
Status:deferred
Tags:
Comment:
This should fix bug 27167, but testing is needed to verify all messages are handled properly. Also some cleanup and restructuring.
Modified paths:
  • /trunk/extensions/InlineEditor/ExtendedEditPage.class.php (modified) (history)
  • /trunk/extensions/InlineEditor/FullEditor (deleted) (history)
  • /trunk/extensions/InlineEditor/InlineEditor.class.php (modified) (history)
  • /trunk/extensions/InlineEditor/InlineEditor.i18n.php (modified) (history)
  • /trunk/extensions/InlineEditor/InlineEditorMarking.class.php (modified) (history)
  • /trunk/extensions/InlineEditor/InlineEditorNode.class.php (modified) (history)
  • /trunk/extensions/InlineEditor/InlineEditorRecommended.php (modified) (history)
  • /trunk/extensions/InlineEditor/InlineEditorRoot.class.php (modified) (history)
  • /trunk/extensions/InlineEditor/InlineEditorText.class.php (modified) (history)
  • /trunk/extensions/InlineEditor/jquery.inlineEditor.api.js (added) (history)
  • /trunk/extensions/InlineEditor/jquery.inlineEditor.css (modified) (history)
  • /trunk/extensions/InlineEditor/jquery.inlineEditor.editors.basic.js (modified) (history)
  • /trunk/extensions/InlineEditor/jquery.inlineEditor.js (modified) (history)

Diff [purge]

Index: trunk/extensions/InlineEditor/InlineEditor.class.php
@@ -15,6 +15,7 @@
1616 private $editWarning; /// < boolean that shows if the editWarning message of the Vector Extension is enabled
1717 private $article; /// < Article object to edit
1818 private $extendedEditPage; /// < ExtendedEditPage object we're using to handle editor logic
 19+ private $intro; /// < Intro message(s) that should be displayed on top
1920
2021 /**
2122 * Main entry point, hooks into MediaWikiPerformAction.
@@ -163,7 +164,7 @@
164165 */
165166 public static function ajaxPreview( $json, $pageName ) {
166167 $title = Title::newFromText( $pageName );
167 - $article = Article::newFromId( $title->getArticleId() );
 168+ $article = new Article( $title );
168169
169170 $editor = new InlineEditor( $article );
170171 return $editor->preview( $json );
@@ -213,7 +214,7 @@
214215
215216 // try to initialise, or else return false, which will spawn an 'advanced page' notice
216217 $this->extendedEditPage = new ExtendedEditPage( $this->article );
217 - if ( $this->extendedEditPage->initInlineEditor() ) {
 218+ if ( $this->extendedEditPage->initInlineEditor( $this ) ) {
218219 // IMPORTANT: if the page was being saved, the script has been terminated by now!!
219220
220221 // have the different kind of editors register themselves
@@ -235,6 +236,7 @@
236237 $this->renderInitialState( $output, $text );
237238 $this->renderScroll( $output, $parserOutput );
238239 $this->renderEditWarning( $output );
 240+ $this->renderOpenFullEditor( $output );
239241
240242 // hook into SiteNoticeBefore to display the two boxes above the title
241243 // @todo: fix this in core, make sure that anything can be inserted above the title, outside #siteNotice
@@ -271,6 +273,14 @@
272274 }
273275
274276 /**
 277+ * Set the intro message(s) that should be displayed on top of the page.
 278+ * @param $intro String
 279+ */
 280+ public function setIntro( $intro ) {
 281+ $this->intro = $intro;
 282+ }
 283+
 284+ /**
275285 * Add the preference in the user preferences
276286 * @param $user
277287 * @param $preferences
@@ -290,7 +300,7 @@
291301 *
292302 * @param $output OutputPage
293303 */
294 - private function renderScripts( $output ) {
 304+ private function renderScripts( OutputPage $output ) {
295305 // include the required JS and CSS files
296306 $output->addModules( array( 'jquery.inlineEditor', 'jquery.inlineEditor.editors.basic' ) );
297307
@@ -313,7 +323,7 @@
314324 * @param $output OutputPage
315325 * @param $text InlineEditorText Use this text object to generate the initial state
316326 */
317 - private function renderInitialState( $output, $text ) {
 327+ private function renderInitialState( OutputPage $output, InlineEditorText $text ) {
318328 // convert the text object into an initial state to send
319329 $initial = InlineEditorText::initialState( $text );
320330
@@ -333,7 +343,7 @@
334344 * @param $output OutputPage
335345 * @param $parserOutput ParserOutput
336346 */
337 - private function renderScroll( $output, $parserOutput ) {
 347+ private function renderScroll( OutputPage $output, ParserOutput $parserOutput ) {
338348 $scrollAnchor = $this->getScrollAnchor( $parserOutput );
339349 if( $scrollAnchor !== null ) {
340350 $output->addInlineScript(
@@ -350,7 +360,7 @@
351361 * @param $output OutputPage
352362 * @param $parserOutput ParserOutput
353363 */
354 - private function renderEditWarning( $output ) {
 364+ private function renderEditWarning( OutputPage $output ) {
355365 if ( $this->editWarning ) {
356366 $output->addInlineScript(
357367 'jQuery( document ).ready( function() {
@@ -361,6 +371,19 @@
362372 }
363373
364374 /**
 375+ * On new pages, open the editor right away.
 376+ */
 377+ private function renderOpenFullEditor( OutputPage $output ) {
 378+ if ( !$this->article->exists() ) {
 379+ $output->addInlineScript(
 380+ 'jQuery( document ).ready( function() {
 381+ jQuery.inlineEditor.show( "inline-editor-root" );
 382+ } );'
 383+ );
 384+ }
 385+ }
 386+
 387+ /**
365388 * Get an anchor to scroll to, or null
366389 * @param $parserOutput ParserOutput
367390 * @return string or null
@@ -405,7 +428,7 @@
406429 * @param $siteNotice string
407430 */
408431 public function siteNoticeBefore( &$siteNotice ) {
409 - $siteNotice = $this->renderEditBox();
 432+ $siteNotice = $this->renderIntroBox() . $this->renderEditBox();
410433 return false;
411434 }
412435
@@ -431,7 +454,12 @@
432455 * @return string HTML
433456 */
434457 private function renderEditBox() {
435 - $top = wfMsgExt( 'inline-editor-editbox-top', 'parseinline' );
 458+ if( $this->article->exists() ) {
 459+ $top = wfMsgExt( 'inline-editor-editbox-top', 'parseinline' );
 460+ }
 461+ else {
 462+ $top = wfMsgExt( 'inline-editor-editbox-top-new', 'parseinline' );
 463+ }
436464 $top .= '<hr/>';
437465
438466 $summary = wfMsgExt( 'inline-editor-editbox-changes-question', 'parseinline' );
@@ -459,4 +487,10 @@
460488
461489 return Html::rawElement( 'div', array( 'class' => 'editbox' ), $form );
462490 }
 491+
 492+ private function renderIntroBox() {
 493+ if( strlen( $this->intro ) <= 0 ) return '';
 494+
 495+ return Html::rawElement( 'div', array( 'class' => 'introbox' ), $this->intro );
 496+ }
463497 }
Index: trunk/extensions/InlineEditor/InlineEditorRoot.class.php
@@ -1,197 +1,10 @@
22 <?php
33 /**
4 - * This class provides a rootnode for a tree which provides a good structure for markings.
5 - * It is closely connected to the wikitext, and should be recreated whenever a marking or
6 - * wikitext changes. InlineEditorNode inherits from this class.
 4+ * This is a special marking that spans all wikitext.
75 */
8 -class InlineEditorRoot extends InlineEditorPiece {
9 - protected $wiki; /// < reference to the original wikitext
10 - protected $children; /// < array of children (InlineEditorNode)
11 - protected $isSorted; /// < bool whether or not the children are sorted
12 - protected $lastEnd; /// < largest endposition of children, to verify during adding the children are sortd
13 -
14 - /**
15 - * @param $wiki String Reference to the original wikitext
16 - */
17 - public function __construct( &$wiki ) {
18 - $this->wiki = &$wiki;
19 - $this->children = array();
20 - $this->lastEnd = 0;
21 - $this->isSorted = true;
 6+class InlineEditorRoot extends InlineEditorMarking {
 7+ function __construct( &$wiki ) {
 8+ parent::__construct( 0, strlen( $wiki ), 'rootElement inlineEditorBasic', true, true, 0, false );
 9+ $this->id = 'inline-editor-root';
2210 }
23 -
24 - /**
25 - * Always span the entire text.
26 - * @return int
27 - */
28 - public function getStart() {
29 - return 0;
30 - }
31 -
32 - /**
33 - * Always span the entire text.
34 - * @return int
35 - */
36 - public function getEnd() {
37 - return strlen( $this->wiki );
38 - }
39 -
40 - /**
41 - * Always returns 'inline-editor-root', the outermost div.
42 - * @return string
43 - */
44 - public function getId() {
45 - return 'inline-editor-root';
46 - }
47 -
48 - /**
49 - * Get an array of children of type InlineEditorNode.
50 - * @return array
51 - */
52 - public function getChildren() {
53 - return $this->children;
54 - }
55 -
56 - /**
57 - * Add a node to the list of children.
58 - *
59 - * Checks whether or not the child can be added. Returns false if it cannot add the
60 - * child, and true when it can. The calling class is responsible to add the node to
61 - * the innermost node, this will not be done by the function.
62 - *
63 - * It is recommended to add nodes from left to right, as this gives the best performance.
64 - *
65 - * @param $child InlineEditorNode
66 - * @return bool
67 - */
68 - public function addChild( InlineEditorNode $child ) {
69 - // if we cannot contain the child, we cannot add it
70 - if( !$this->canContain( $child ) ) return false;
71 -
72 - // if the start is before the largest endpoint, check all children for overlap
73 - if( $child->getStart() < $this->lastEnd) {
74 - foreach( $this->children as $otherChild ) {
75 - if( $child->hasOverlap( $otherChild ) ) return false;
76 - }
77 -
78 - // if there is no overlap, we're sure that the list isn't sorted anymore
79 - $this->isSorted = false;
80 - }
81 -
82 - // add the child and set the parent of the child to $this
83 - $this->children[$child->getStart()] = $child;
84 - $child->parent = $this;
85 -
86 - // move $this->lastEnd if needed
87 - if( $child->getEnd() > $this->lastEnd ) $this->lastEnd = $child->getEnd();
88 -
89 - return true;
90 - }
91 -
92 - /**
93 - * Find the node (or root) with the smallest length still able to contain $piece.
94 - * @param $piece InlineEditorPiece
95 - * @return InlineEditorPiece
96 - */
97 - public function findBestParent( InlineEditorPiece $piece ) {
98 - // if we cannot contain the piece, return false
99 - if( !$this->canContain( $piece ) ) return false;
100 -
101 - // sorted children is a precondition for the algoritm
102 - $this->sort();
103 -
104 - foreach( $this->children as $start => $child ) {
105 - // if we've move past the end of the piece, stop
106 - if( $piece->getEnd() < $start ) break;
107 -
108 - // try to fit the piece to this child
109 - if( $piece->getStart() >= $start ) {
110 - $fit = $child->findBestParent( $piece );
111 - // if we found a child that fits the piece, return it
112 - if( $fit !== false ) {
113 - return $fit;
114 - }
115 - }
116 - }
117 -
118 - // if we cannot find a suitable child, but we can contain it in this piece, return $this
119 - return $this;
120 - }
121 -
122 - /**
123 - * Find the highest level of children that can be fit into a certain piece.
124 - * This will return an array of nodes that are best fit.
125 - * @param $piece InlineEditorPiece
126 - * @return array
127 - */
128 - public function findBestChildren( InlineEditorPiece $piece ) {
129 - // try to find a parent that fits $piece (which can very well be $this!)
130 - $parent = $this->findBestParent( $piece );
131 -
132 - // if we cannot find a parent, return false
133 - if( !$parent ) return false;
134 -
135 - // if the piece can contain the entire parent piece, just return that piece
136 - if( $piece->canContain( $parent ) ) return array( $parent );
137 -
138 - // sorting is a precondition of the algoritm
139 - $this->sort();
140 -
141 - $children = array();
142 - foreach( $parent->children as $start => $child ) {
143 - // if we've moved past the end of the piece, stop
144 - if( $start > $piece->getEnd() ) break;
145 -
146 - // add the child to the list if it can be contained in the piece
147 - if( $piece->canContain( $child ) ) {
148 - $children[] = $child;
149 - }
150 - }
151 - return $children;
152 - }
153 -
154 - /**
155 - * Render the start tag, in this case always a div with id="inline-editor-root".
156 - * @return string HTML
157 - */
158 - protected function renderStartTag() {
159 - return '<div id="inline-editor-root">' . "\n";
160 - }
161 -
162 - /**
163 - * Render the end tag, in this case always a closing div.
164 - * @return string HTML
165 - */
166 - protected function renderEndTag() {
167 - return "\n</div>";
168 - }
169 -
170 - /**
171 - * Render the entire tag, with recursion on the children.
172 - * @return string HTML
173 - */
174 - public function render() {
175 - $this->sort();
176 - $lastPos = $this->getStart();
177 - $output = $this->renderStartTag();
178 - foreach( $this->children as $child ) {
179 - $output .= substr( $this->wiki, $lastPos, $child->getStart() - $lastPos );
180 - $output .= $child->render();
181 - $lastPos = $child->getEnd();
182 - }
183 -
184 - $output .= substr( $this->wiki, $lastPos, $this->getEnd() - $lastPos );
185 - $output .= $this->renderEndTag();
186 -
187 - return $output;
188 - }
189 -
190 - /**
191 - * Sort the children by start position (key).
192 - */
193 - protected function sort() {
194 - if( $this->isSorted ) return;
195 - ksort( $this->children );
196 - $this->isSorted = true;
197 - }
198 -}
\ No newline at end of file
 11+}
Index: trunk/extensions/InlineEditor/InlineEditorText.class.php
@@ -27,6 +27,7 @@
2828 */
2929 public function __construct( Article $article ) {
3030 $this->article = $article;
 31+ $this->wikiOriginal = '';
3132 }
3233
3334 /**
@@ -57,7 +58,7 @@
5859 public function getPartialParserOutput() {
5960 $this->process();
6061
61 - if( $this->changedNode != $this->root ) {
 62+ if( isset( $this->previous ) && $this->changedNode != $this->root ) {
6263 $markedWiki = $this->changedNode->render();
6364 if( wfRunHooks( 'InlineEditorPartialBeforeParse', array( &$markedWiki ) ) ) {
6465 $output = $this->parse( $markedWiki );
@@ -67,7 +68,7 @@
6869 }
6970 }
7071
71 - return array( 'id' => $this->root->getId(), 'html' => $this->parse( $this->root->render() )->getText() );
 72+ return array( 'id' => $this->root->getId(), 'html' => $this->parseRoot()->getText() );
7273 }
7374
7475 /**
@@ -80,7 +81,7 @@
8182 */
8283 public function getFullParserOutput() {
8384 $this->process();
84 - return $this->parse( $this->root->render() );
 85+ return $this->parseRoot();
8586 }
8687
8788 /**
@@ -90,10 +91,13 @@
9192 public function getTexts() {
9293 $this->process();
9394
94 - $texts = array();
95 - foreach( $this->markings as $marking ) {
96 - $texts[$marking->getId()] = substr( $this->wikiOriginal, $marking->getStart(), $marking->getLength() );
 95+ foreach( $this->markings as $id => $marking ) {
 96+ $texts[$id] = substr( $this->wikiOriginal, $marking->getStart(), $marking->getLength() );
 97+
 98+ // force an empty string, as substr returns 'false'
 99+ if( !$texts[$id] ) $texts[$id] = '';
97100 }
 101+
98102 return $texts;
99103 }
100104
@@ -129,7 +133,7 @@
130134 if( $offset != 0) {
131135 foreach( $this->markings as $id => $marking ) {
132136 // if the marking is strictly after the edited marking, shift both start and end positions
133 - if( $marking->getStart() >= $end ) {
 137+ if( $marking->getStart() > $end ) {
134138 $marking->setStart( $marking->getStart() + $offset );
135139 $marking->setEnd( $marking->getEnd() + $offset );
136140 }
@@ -163,6 +167,16 @@
164168 }
165169
166170 /**
 171+ * Give special treatment to parsing the root. Add the root divs only after parsing
 172+ * to make sure they survive the parsing.
 173+ */
 174+ protected function parseRoot() {
 175+ $output = $this->parse( $this->root->renderInside() );
 176+ $output->setText( $this->root->renderStartTag() . $output->getText() . $this->root->renderEndTag() );
 177+ return $output;
 178+ }
 179+
 180+ /**
167181 * Have the wikitext marked by different extensions by calling the 'InlineEditorMark' hook.
168182 * After that, tries to match previous markings against the new markings, and tries to preserve
169183 * the previous markings, while growing $this->editedPiece if needed.
@@ -176,7 +190,7 @@
177191 wfRunHooks( 'InlineEditorMark', array( &$this ) );
178192
179193 // sort the markings while preserving the keys (ids)
180 - uasort( $this->markings, 'InlineEditorText::sortByStartAndLength' );
 194+ uasort( $this->markings, 'InlineEditorText::sortByStartLengthLevel' );
181195
182196 // collapse markings
183197 $this->collapseMarkings();
@@ -193,7 +207,14 @@
194208 if( isset( $this->root ) ) return;
195209
196210 $this->mark();
197 - $this->root = $this->buildTree( $this->markings );
 211+
 212+ // add the root marking to the list after building the tree,
 213+ // so it will get in the list of markings, but isn't duplicated in the
 214+ // tree
 215+ $rootMarking = new InlineEditorRoot( $this->wikiOriginal );
 216+ $this->root = $this->buildTree( $this->markings, $rootMarking );
 217+ $this->markings[$rootMarking->getId()] = $rootMarking;
 218+
198219 $this->changedNode = $this->findChangedNode();
199220 $this->applyLastEditHighlight();
200221 }
@@ -249,11 +270,14 @@
250271 */
251272 protected function matchPreviousMarkings() {
252273 // abort if there is nothing to match
253 - if( empty( $this->previous ) ) return;
 274+ if( !isset( $this->previous ) ) return;
254275
 276+ // don't use the root of the previous markings
 277+ unset( $this->previous['inline-editor-root'] );
 278+
255279 // sort the previous markings, while *re-keying* to natural numbers (0, 1, 2, ...)
256280 // this is necessary to be able to run through the array using an integer pointer
257 - usort( $this->previous, 'InlineEditorText::sortByStartAndLength' );
 281+ usort( $this->previous, 'InlineEditorText::sortByStartLengthLevel' );
258282
259283 // point to the start of the previous markings list
260284 $indexPrevious = 0;
@@ -267,7 +291,7 @@
268292 while( isset( $this->previous[$indexPrevious] ) ) {
269293 $previous = $this->previous[$indexPrevious];
270294
271 - switch( self::sortByStartAndLength( $previous, $marking ) ) {
 295+ switch( self::sortByStartLengthLevel( $previous, $marking ) ) {
272296 case 1:
273297 // if we've moved past the current marking, break, mismatch, and go to the next current marking
274298 break(2);
@@ -304,11 +328,12 @@
305329 * Build a tree from an array of sorted (!) markings.
306330 *
307331 * @param $markingsSorted array A sorted array of InlineEditorMarking objects.
308 - * @return InlineEditorRoot
 332+ * @param $rootMarking InlineEditorRoot A root marking, not included in the list of sorted markings
 333+ * @return InlineEditorNode
309334 */
310 - protected function buildTree( array $markingsSorted ) {
 335+ protected function buildTree( array $markingsSorted, InlineEditorRoot $rootMarking ) {
311336 // create the root
312 - $root = new InlineEditorRoot( $this->wikiOriginal );
 337+ $root = new InlineEditorNode( $this->wikiOriginal, $rootMarking );
313338
314339 // $workingNode is the node we're trying to add children to
315340 // initialise it to the root node
@@ -373,10 +398,7 @@
374399 // find the markings contained in $this->editedPiece and mark them
375400 $children = $this->root->findBestChildren( $this->editedPiece );
376401 foreach( $children as $child ) {
377 - // don't mark if somehow root appears, as it has no marking attached
378 - if( $child != $this->root ) {
379 - $child->getMarking()->addClasses( 'lastEdit edited' );
380 - }
 402+ $child->getMarking()->addClasses( 'lastEdit edited' );
381403 }
382404 }
383405
@@ -389,7 +411,7 @@
390412 * @param $b InlineEditorMarking
391413 * @return int
392414 */
393 - private static function sortByStartAndLength( $a, $b ) {
 415+ private static function sortByStartLengthLevel( $a, $b ) {
394416 if( $a->getStart() == $b->getStart() ) {
395417 if( $a->getLength() == $b->getLength() ) {
396418 if( $a->getLevel() == $b->getLevel() ) {
Index: trunk/extensions/InlineEditor/InlineEditorNode.class.php
@@ -1,18 +1,26 @@
22 <?php
33 /**
44 * This class wraps an InlineEditorMarking to be a part of a tree spanning the
5 - * wikitext. Inherits from InlineEditorRoot, where most of the logic is.
 5+ * wikitext. It is closely connected to the wikitext, and should be recreated whenever a
 6+ * marking or wikitext changes.
67 */
7 -class InlineEditorNode extends InlineEditorRoot {
 8+class InlineEditorNode extends InlineEditorPiece {
 9+ protected $wiki; /// < reference to the original wikitext
 10+ protected $children; /// < array of children (InlineEditorNode)
 11+ protected $isSorted; /// < bool whether or not the children are sorted
 12+ protected $lastEnd; /// < largest endposition of children, to verify during adding the children are sortd
813 protected $marking; /// < marking this nodes wraps
9 - protected $parent; /// < parent node, either an InlineEditorNode or InlineEditorRoot
 14+ protected $parent; /// < parent node (InlineEditorNode)
1015
1116 /**
1217 * @param $wiki String Reference to the original wikitext
1318 * @param $marking InlineEditorMarking Marking to wrap in the tree
1419 */
1520 public function __construct( &$wiki, InlineEditorMarking $marking ) {
16 - parent::__construct( $wiki );
 21+ $this->wiki =& $wiki;
 22+ $this->children = array();
 23+ $this->lastEnd = 0;
 24+ $this->isSorted = true;
1725 $this->marking = $marking;
1826 }
1927
@@ -41,6 +49,14 @@
4250 }
4351
4452 /**
 53+ * Get an array of children of type InlineEditorNode.
 54+ * @return array
 55+ */
 56+ public function getChildren() {
 57+ return $this->children;
 58+ }
 59+
 60+ /**
4561 * Get the corresponding marking.
4662 * @return InlineEditorMarking
4763 */
@@ -49,8 +65,8 @@
5066 }
5167
5268 /**
53 - * Get the parent node or root.
54 - * @return InlineEditorPiece
 69+ * Get the parent node.
 70+ * @return InlineEditorNode
5571 */
5672 public function getParent() {
5773 return $this->parent;
@@ -71,4 +87,136 @@
7288 public function renderEndTag() {
7389 return $this->marking->renderEndTag();
7490 }
 91+
 92+ /**
 93+ * Add a node to the list of children.
 94+ *
 95+ * Checks whether or not the child can be added. Returns false if it cannot add the
 96+ * child, and true when it can. The calling class is responsible to add the node to
 97+ * the innermost node, this will not be done by the function.
 98+ *
 99+ * It is recommended to add nodes from left to right, as this gives the best performance.
 100+ *
 101+ * @param $child InlineEditorNode
 102+ * @return bool
 103+ */
 104+ public function addChild( InlineEditorNode $child ) {
 105+ // if we cannot contain the child, we cannot add it
 106+ if( !$this->canContain( $child ) ) return false;
 107+
 108+ // if the start is before the largest endpoint, check all children for overlap
 109+ if( $child->getStart() < $this->lastEnd) {
 110+ foreach( $this->children as $otherChild ) {
 111+ if( $child->hasOverlap( $otherChild ) ) return false;
 112+ }
 113+
 114+ // if there is no overlap, we're sure that the list isn't sorted anymore
 115+ $this->isSorted = false;
 116+ }
 117+
 118+ // add the child and set the parent of the child to $this
 119+ $this->children[$child->getStart()] = $child;
 120+ $child->parent = $this;
 121+
 122+ // move $this->lastEnd if needed
 123+ if( $child->getEnd() > $this->lastEnd ) $this->lastEnd = $child->getEnd();
 124+
 125+ return true;
 126+ }
 127+
 128+ /**
 129+ * Find the node with the smallest length still able to contain $piece.
 130+ * @param $piece InlineEditorPiece
 131+ * @return InlineEditorNode
 132+ */
 133+ public function findBestParent( InlineEditorPiece $piece ) {
 134+ // if we cannot contain the piece, return false
 135+ if( !$this->canContain( $piece ) ) return false;
 136+
 137+ // sorted children is a precondition for the algoritm
 138+ $this->sort();
 139+
 140+ foreach( $this->children as $start => $child ) {
 141+ // if we've move past the end of the piece, stop
 142+ if( $piece->getEnd() < $start ) break;
 143+
 144+ // try to fit the piece to this child
 145+ if( $piece->getStart() >= $start ) {
 146+ $fit = $child->findBestParent( $piece );
 147+ // if we found a child that fits the piece, return it
 148+ if( $fit !== false ) {
 149+ return $fit;
 150+ }
 151+ }
 152+ }
 153+
 154+ // if we cannot find a suitable child, but we can contain it in this piece, return $this
 155+ return $this;
 156+ }
 157+
 158+ /**
 159+ * Find the highest level of children that can be fit into a certain piece.
 160+ * This will return an array of nodes that are best fit.
 161+ * @param $piece InlineEditorPiece
 162+ * @return array
 163+ */
 164+ public function findBestChildren( InlineEditorPiece $piece ) {
 165+ // try to find a parent that fits $piece (which can very well be $this!)
 166+ $parent = $this->findBestParent( $piece );
 167+
 168+ // if we cannot find a parent, return false
 169+ if( !$parent ) return false;
 170+
 171+ // if the piece can contain the entire parent piece, just return that piece
 172+ if( $piece->canContain( $parent ) ) return array( $parent );
 173+
 174+ // sorting is a precondition of the algoritm
 175+ $this->sort();
 176+
 177+ $children = array();
 178+ foreach( $parent->children as $start => $child ) {
 179+ // if we've moved past the end of the piece, stop
 180+ if( $start > $piece->getEnd() ) break;
 181+
 182+ // add the child to the list if it can be contained in the piece
 183+ if( $piece->canContain( $child ) ) {
 184+ $children[] = $child;
 185+ }
 186+ }
 187+ return $children;
 188+ }
 189+
 190+ /**
 191+ * Render the entire tag, with recursion on the children.
 192+ * @return string HTML
 193+ */
 194+ public function render() {
 195+ return $this->renderStartTag() . $this->renderInside() . $this->renderEndTag();
 196+ }
 197+
 198+ /**
 199+ * Render the inside of the tag.
 200+ */
 201+ public function renderInside() {
 202+ $this->sort();
 203+ $lastPos = $this->getStart();
 204+ $output = '';
 205+ foreach( $this->children as $child ) {
 206+ $output .= substr( $this->wiki, $lastPos, $child->getStart() - $lastPos );
 207+ $output .= $child->render();
 208+ $lastPos = $child->getEnd();
 209+ }
 210+
 211+ $output .= substr( $this->wiki, $lastPos, $this->getEnd() - $lastPos );
 212+ return $output;
 213+ }
 214+
 215+ /**
 216+ * Sort the children by start position (key).
 217+ */
 218+ protected function sort() {
 219+ if( $this->isSorted ) return;
 220+ ksort( $this->children );
 221+ $this->isSorted = true;
 222+ }
75223 }
\ No newline at end of file
Index: trunk/extensions/InlineEditor/jquery.inlineEditor.api.js
@@ -0,0 +1,22 @@
 2+/**
 3+ * Useful calls for other plugins (extensions, browser apps, etc.)
 4+ */
 5+( function( $ ) { $.inlineEditor.api = {
 6+ getFullText: function() {
 7+ return $.inlineEditor.getTextById( 'inline-editor-root' );
 8+ },
 9+
 10+ previewFullText: function( text ) {
 11+ $.inlineEditor.cancel();
 12+ $.inlineEditor.previewTextById( text, 'inline-editor-root' );
 13+ },
 14+
 15+ openFullEditor: function() {
 16+ $.inlineEditor.show( 'inline-editor-root' );
 17+ },
 18+
 19+ getFullEditorTextarea: function() {
 20+ $.inlineEditor.api.openFullEditor();
 21+ return $( '#inline-editor-root textarea' );
 22+ }
 23+}; } ) ( jQuery );
Property changes on: trunk/extensions/InlineEditor/jquery.inlineEditor.api.js
___________________________________________________________________
Added: svn:eol-style
124 + native
Index: trunk/extensions/InlineEditor/InlineEditorMarking.class.php
@@ -41,8 +41,7 @@
4242 $this->id = self::uniqueId();
4343
4444 $this->classes = array();
45 - $this->addClasses( $classes );
46 -
 45+ $this->addClasses( $classes );
4746 }
4847
4948 /**
Index: trunk/extensions/InlineEditor/InlineEditor.i18n.php
@@ -14,7 +14,8 @@
1515 $messages['en'] = array(
1616 'inline-editor-desc' => 'Provides an alternative editor which is easier to use',
1717
18 - 'inline-editor-editbox-top' => "'''Awesome, you are editing {{SITENAME}}!'''<br />You can edit the article below, by clicking on <span class=\"highlightExample\">blue elements</span> in the page.",
 18+ 'inline-editor-editbox-top' => "'''Awesome, you are editing {{SITENAME}}!'''<br />You can edit the page below, by clicking on <span class=\"highlightExample\">blue elements</span> in the page.",
 19+ 'inline-editor-editbox-top-new' => "'''Cool, you are creating a new page on {{SITENAME}}!'''<br />You can start typing in the <span class=\"highlightExample\">textbox</span> below.",
1920 'inline-editor-editbox-changes-question' => 'Can you briefly describe the changes you are making?',
2021 'inline-editor-editbox-changes-example' => 'For example: "Fixed spelling mistake", "Corrected facts", "Wrote a new paragraph", etc.',
2122 'inline-editor-editbox-publish-notice' => "When you are done, do not forget to publish the page!",
@@ -37,6 +38,7 @@
3839 */
3940 $messages['qqq'] = array(
4041 'inline-editor-editbox-top' => 'The "edit box" should be as small as possible. It should present the most essential information, and nothing more. It should ask for nothing more but the bare minimum. I chose to include a few basic guidelines, starting with some positive reinforcement: "Awesome, you\'re editing Wikipedia!". This invites novice users to actually edit the article. After all, what they are doing is "awesome"!',
 42+ 'inline-editor-editbox-top-new' => 'The welcoming message when creating a new page is similar, but slightly different than the usual message. First, you can use another encouraging word, in this case "Cool", and then tell the user to start typing in the textbox. The word textbox is given a blue highlight, as the textbox below also looks blue on the borders.',
4143 'inline-editor-editbox-changes-question' => "The line above the edit summary is chosen very carefully: \"Can you briefly describe the changes you're making?\"
4244 Asking for \"changes you ''have'' made\" looks strange when first encountering this page.
4345 Asking for \"changes you ''will be'' making\" looks strange when
@@ -63,4 +65,3 @@
6466 unambiguous: it will be shown to the world. On the other hand, using the word "Publish" may have legal
6567 consequences in some countries, which should be looked into.',
6668 );
67 -
Index: trunk/extensions/InlineEditor/jquery.inlineEditor.css
@@ -72,111 +72,10 @@
7373 -webkit-border-radius: 10px;
7474 }
7575
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;
 76+#siteNotice div.introbox {
 77+ background-color: #f3f3f3;
 78+ border: 1px solid #aaa;
8179 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;
 80+ padding: 10px 10px 5px;
17081 position: relative;
171 - overflow: hidden;
17282 }
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 -}
Index: trunk/extensions/InlineEditor/ExtendedEditPage.class.php
@@ -10,7 +10,7 @@
1111 * Inits the edit page for the InlineEditor.
1212 * This is largely a copy-paste from EditPage::edit(), with some specific changes.
1313 */
14 - public function initInlineEditor() {
 14+ public function initInlineEditor( $inlineEditor ) {
1515 global $wgRequest, $wgOut;
1616 $this->importFormData( $wgRequest );
1717
@@ -65,10 +65,8 @@
6666 $wgOut->clearHTML();
6767 if ( $this->formtype == 'initial' || $this->firsttime ) {
6868 $this->showIntro();
69 - if ( $wgOut->getHTML() != '' ) {
70 - $wgOut->clearHTML();
71 - return false;
72 - }
 69+ $inlineEditor->setIntro( $wgOut->getHTML() );
 70+ $wgOut->clearHTML();
7371 }
7472
7573 if ( 'initial' == $this->formtype || 'preview' == $this->formtype || $this->firsttime ) {
Index: trunk/extensions/InlineEditor/jquery.inlineEditor.editors.basic.js
@@ -66,7 +66,7 @@
6767 },
6868
6969 /**
70 - * Default click handler for simple editors. Recommended to override.
 70+ * Default click handler for simple editors.
7171 */
7272 click: function( event ) {
7373 var $field = $(this);
@@ -75,31 +75,45 @@
7676 // prevent clicks from reaching other elements
7777 event.stopPropagation();
7878 event.preventDefault();
79 -
 79+
8080 // disable the existing editing field if necessary
8181 $.inlineEditor.editors.basic.cancel();
8282
83 - // find the element and retrieve the corresponding wikitext
84 - var wiki = $.inlineEditor.getTextById( $field.attr( 'id' ) );
 83+ $.inlineEditor.editors.basic.show( $field.attr( 'id' ) );
 84+ }
 85+ },
 86+
 87+ /**
 88+ * Actually handles showing the editing interface. Recommended to override.
 89+ * @return Boolean Whether or not showing the interface was successful.
 90+ */
 91+ show: function( id ) {
 92+ $field = $( '#' + id );
 93+
 94+ // if the class is incorrect, terminate
 95+ if( !$field.hasClass( 'inlineEditorBasic' ) ) return false;
 96+
 97+ // find the element and retrieve the corresponding wikitext
 98+ var wiki = $.inlineEditor.getTextById( $field.attr( 'id' ) );
 99+
 100+ // create the edit field and build the edit bar
 101+ var $newField = $.inlineEditor.editors.basic.newField( $field, $.inlineEditor.editors.basic.click );
 102+ $.inlineEditor.editors.basic.addEditBar( $newField, wiki );
 103+
 104+ // add the wikiEditor toolbar
 105+ if( $.fn.wikiEditor ) {
 106+ $textarea = $newField.find( 'textarea' );
85107
86 - // create the edit field and build the edit bar
87 - var $newField = $.inlineEditor.editors.basic.newField( $field, $.inlineEditor.editors.basic.click );
88 - $.inlineEditor.editors.basic.addEditBar( $newField, wiki );
 108+ if( $.wikiEditor.modules.toolbar && $.wikiEditor.modules.toolbar.config && $.wikiEditor.isSupported( $.wikiEditor.modules.toolbar ) ) {
 109+ $textarea.wikiEditor( 'addModule', $.wikiEditor.modules.toolbar.config.getDefaultConfig() );
 110+ }
89111
90 - // add the wikiEditor toolbar
91 - if( $.fn.wikiEditor ) {
92 - $textarea = $newField.find( 'textarea' );
93 -
94 - if( $.wikiEditor.modules.toolbar && $.wikiEditor.modules.toolbar.config && $.wikiEditor.isSupported( $.wikiEditor.modules.toolbar ) ) {
95 - $textarea.wikiEditor( 'addModule', $.wikiEditor.modules.toolbar.config.getDefaultConfig() );
96 - }
97 -
98 - if( $.wikiEditor.modules.dialogs && $.wikiEditor.modules.dialogs.config && $.wikiEditor.isSupported( $.wikiEditor.modules.dialogs ) ) {
99 - $.wikiEditor.modules.dialogs.config.replaceIcons( $textarea );
100 - $textarea.wikiEditor( 'addModule', $.wikiEditor.modules.dialogs.config.getDefaultConfig() );
101 - }
 112+ if( $.wikiEditor.modules.dialogs && $.wikiEditor.modules.dialogs.config && $.wikiEditor.isSupported( $.wikiEditor.modules.dialogs ) ) {
 113+ $.wikiEditor.modules.dialogs.config.replaceIcons( $textarea );
 114+ $textarea.wikiEditor( 'addModule', $.wikiEditor.modules.dialogs.config.getDefaultConfig() );
102115 }
103116 }
 117+ return true;
104118 },
105119
106120 /**
Index: trunk/extensions/InlineEditor/InlineEditorRecommended.php
@@ -23,4 +23,3 @@
2424 require_once( dirname(__FILE__) . "/TemplateEditor/TemplateEditor.php" );
2525 require_once( dirname(__FILE__) . "/ParagraphEditor/ParagraphEditor.php" );
2626 require_once( dirname(__FILE__) . "/SectionEditor/SectionEditor.php" );
27 -require_once( dirname(__FILE__) . "/FullEditor/FullEditor.php" );
Index: trunk/extensions/InlineEditor/jquery.inlineEditor.js
@@ -159,6 +159,21 @@
160160 },
161161
162162 /**
 163+ * Show the interface for a particular element.
 164+ * @return Boolean Whether or not showing the interface was successful.
 165+ */
 166+ show: function( id ) {
 167+ // disable the existing editing field if necessary
 168+ $.inlineEditor.editors.basic.cancel();
 169+
 170+ // try the show function of all editors
 171+ for( var optionNr in $.inlineEditor.editors ) {
 172+ if( $.inlineEditor.editors[optionNr].show( id ) ) return true;
 173+ }
 174+ return false;
 175+ },
 176+
 177+ /**
163178 * Submit event, adds the json to the hidden field
164179 */
165180 submit: function( event ) {

Follow-up revisions

RevisionCommit summaryAuthorDate
r83338Fixes a few things:...janpaul12323:30, 5 March 2011

Status & tagging log