r63790 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r63789‎ | r63790 | r63791 >
Date:00:13, 16 March 2010
Author:jeroendedauw
Status:resolved (Comments)
Tags:
Comment:
* Restuctures css and js
* Restructured Story special page and added html for edit action
* Added comments to JS functions
Modified paths:
  • /trunk/extensions/Storyboard/specials/Story/Story_body.php (modified) (history)
  • /trunk/extensions/Storyboard/specials/StoryReview/StoryReview_body.php (modified) (history)
  • /trunk/extensions/Storyboard/specials/StoryReview/storyreview.js (deleted) (history)
  • /trunk/extensions/Storyboard/story.css (deleted) (history)
  • /trunk/extensions/Storyboard/storyboard.css (added) (history)
  • /trunk/extensions/Storyboard/storyboard.js (added) (history)
  • /trunk/extensions/Storyboard/tags/Storyboard/Storyboard_body.php (modified) (history)
  • /trunk/extensions/Storyboard/tags/Storyboard/storyboard.css (deleted) (history)
  • /trunk/extensions/Storyboard/tags/Storysubmission/Storysubmission_body.php (modified) (history)
  • /trunk/extensions/Storyboard/tags/Storysubmission/storysubmission.css (deleted) (history)
  • /trunk/extensions/Storyboard/tags/Storysubmission/storysubmission.js (deleted) (history)

Diff [purge]

Index: trunk/extensions/Storyboard/story.css
@@ -1,35 +0,0 @@
2 -/**
3 - * Css for stories, used at variouse places in the Storyboard extension.
4 - *
5 - * @file story.css
6 - * @ingroup Storyboard
7 - *
8 - * @author Jeroen De Dauw
9 - */
10 -
11 -.story {
12 - margin-left: 15px;
13 - margin-top: 5px;
14 - float: left;
15 - overflow: hidden;
16 -}
17 -.story-title {
18 - font: 16px "Lucida Sans", Verdana;
19 - font-weight: bold;
20 - float: left;
21 - overflow: hidden;
22 -}
23 -.story-image {
24 - margin: 5px 15px 0px 15px;
25 - float: right;
26 -}
27 -
28 -.story-sharing {
29 - height: 30px;
30 - width: 110px;
31 - float: right;
32 -}
33 -.story-sharing-item {
34 - float: left;
35 - padding-right: 5px;
36 -}
\ No newline at end of file
Index: trunk/extensions/Storyboard/storyboard.css
@@ -0,0 +1,68 @@
 2+/**
 3+ * Css for the Storyboard extension.
 4+ *
 5+ * @file storyboard.css
 6+ * @ingroup Storyboard
 7+ *
 8+ * @author Jeroen De Dauw
 9+ */
 10+
 11+/**
 12+ * Css for stories
 13+ */
 14+.story {
 15+ margin-left: 15px;
 16+ margin-top: 5px;
 17+ float: left;
 18+ overflow: hidden;
 19+}
 20+.story-title {
 21+ font: 16px "Lucida Sans", Verdana;
 22+ font-weight: bold;
 23+ float: left;
 24+ overflow: hidden;
 25+}
 26+.story-image {
 27+ margin: 5px 15px 0px 15px;
 28+ float: right;
 29+}
 30+
 31+.story-sharing {
 32+ height: 30px;
 33+ width: 110px;
 34+ float: right;
 35+}
 36+.story-sharing-item {
 37+ float: left;
 38+ padding-right: 5px;
 39+}
 40+
 41+/**
 42+ * Css for story submission/editting
 43+ */
 44+.storysubmission-charcount {
 45+ display: inline;
 46+ float: right;
 47+}
 48+
 49+/**
 50+ * Css for <storyboard> tags
 51+ */
 52+.storyboard {
 53+border: 1px solid #ddd;
 54+}
 55+.storyboard .storyboard-batch {
 56+ margin: 0;
 57+ padding: 0;
 58+}
 59+.storyboard .storyboard-box {
 60+ display: inline-block;
 61+ border: 1px solid #eee;
 62+ width: 99%;
 63+ min-height: 100px;
 64+ margin: 5px;
 65+}
 66+.storyboard .storyboard-empty .storyboard-box {
 67+ border: 1px solid #ddd;
 68+ background: #FCFCFC url(images/storyboard-loader.gif) no-repeat scroll center center;
 69+}
\ No newline at end of file
Property changes on: trunk/extensions/Storyboard/storyboard.css
___________________________________________________________________
Name: svn:eol-style
170 + native
Index: trunk/extensions/Storyboard/tags/Storyboard/storyboard.css
@@ -1,27 +0,0 @@
2 -/**
3 - * Css for <storyboard> tags of the Storyboard extension.
4 - *
5 - * @file storyboard.css
6 - * @ingroup Storyboard
7 - *
8 - * @author Jeroen De Dauw
9 - */
10 -
11 -.storyboard {
12 -border: 1px solid #ddd;
13 -}
14 -.storyboard .storyboard-batch {
15 - margin: 0;
16 - padding: 0;
17 -}
18 -.storyboard .storyboard-box {
19 - display: inline-block;
20 - border: 1px solid #eee;
21 - width: 99%;
22 - min-height: 100px;
23 - margin: 5px;
24 -}
25 -.storyboard .storyboard-empty .storyboard-box {
26 - border: 1px solid #ddd;
27 - background: #FCFCFC url(../../images/storyboard-loader.gif) no-repeat scroll center center;
28 -}
\ No newline at end of file
Index: trunk/extensions/Storyboard/tags/Storyboard/Storyboard_body.php
@@ -19,8 +19,7 @@
2020 public static function render( $input, $args, $parser, $frame ) {
2121 global $wgOut, $wgJsMimeType, $wgScriptPath, $egStoryboardScriptPath, $egStoryboardWidth, $egStoryboardHeight;
2222
23 - $wgOut->addStyle( $egStoryboardScriptPath . '/story.css' );
24 - $wgOut->addStyle( $egStoryboardScriptPath . '/tags/Storyboard/storyboard.css' );
 23+ $wgOut->addStyle( $egStoryboardScriptPath . '/storyboard.css' );
2524 $wgOut->includeJQuery();
2625 // TODO: Combine+minfiy JS files, add switch to use combined+minified version
2726 $wgOut->addScriptFile( $egStoryboardScriptPath . '/tags/Storyboard/jquery.ajaxscroll.js' );
Index: trunk/extensions/Storyboard/tags/Storysubmission/storysubmission.css
@@ -1,13 +0,0 @@
2 -/**
3 - * Css for <storysubmission> tags of the Storyboard extension.
4 - *
5 - * @file Storysubmission.css
6 - * @ingroup Storyboard
7 - *
8 - * @author Jeroen De Dauw
9 - */
10 -
11 -.storysubmission-charcount {
12 - display: inline;
13 - float: right;
14 -}
\ No newline at end of file
Index: trunk/extensions/Storyboard/tags/Storysubmission/storysubmission.js
@@ -1,40 +0,0 @@
2 -/**
3 - * JavaScript for <storysubmission> tags.
4 - *
5 - * @author Jeroen De Dauw
6 - * @ingroup Storyboard
7 - */
8 -
9 -function stbValidateStory( textarea, lowerLimit, upperLimit, infodiv, submissionButton ) {
10 - var button = document.getElementById( submissionButton );
11 - button.disabled = !stbLimitChars( textarea, lowerLimit, upperLimit, infodiv );
12 -}
13 -
14 -function stbLimitChars(textarea, lowerLimit, upperLimit, infodiv) {
15 - var text = textarea.value;
16 - var textlength = text.length;
17 - var info = document.getElementById( infodiv );
18 -
19 - if(textlength > upperLimit) {
20 - info.innerHTML = -( upperLimit - textlength ) + ' characters to many!'; // TODO: i18n
21 - return false;
22 - } else if (textlength < lowerLimit) {
23 - info.innerHTML = '('+ ( lowerLimit - textlength ) + ' more characters needed)'; // TODO: i18n
24 - return false;
25 - } else {
26 - info.innerHTML = '(' + ( upperLimit - textlength ) + ' characters left)'; // TODO: i18n
27 - return true;
28 - }
29 -}
30 -
31 -function stbValidateSubmission( termsCheckbox ) {
32 - var agreementValid = document.getElementById( termsCheckbox ).checked;
33 - if (!agreementValid) {
34 - alert( 'You need to agree to the publication of your story to submit it.' ); // TODO: i18n
35 - }
36 - return agreementValid;
37 -}
38 -
39 -addOnloadHook( function() {
40 - document.getElementById( 'storysubmission-button' ).disabled = true;
41 -} );
\ No newline at end of file
Index: trunk/extensions/Storyboard/tags/Storysubmission/Storysubmission_body.php
@@ -46,14 +46,24 @@
4747 private static function getFrom( $parser, array $args ) {
4848 global $wgOut, $wgUser, $wgJsMimeType, $egStoryboardScriptPath, $egStorysubmissionWidth, $egStoryboardMaxStoryLen, $egStoryboardMinStoryLen;
4949
50 - $wgOut->addStyle( $egStoryboardScriptPath . '/tags/Storysubmission/storysubmission.css' );
51 - $wgOut->addScriptFile( $egStoryboardScriptPath . '/tags/Storysubmission/storysubmission.js' );
 50+ $wgOut->addStyle( $egStoryboardScriptPath . '/storyboard.css' );
 51+ $wgOut->addScriptFile( $egStoryboardScriptPath . '/storyboard.js' );
 52+ // Loading a seperate JS file would be overkill for just these 3 lines, and be bad for performance.
 53+ $wgOut->addScript(
 54+ <<<EOT
 55+ <script type="$wgJsMimeType"> /*<![CDATA[*/
 56+ addOnloadHook( function() {
 57+ document.getElementById( 'storysubmission-button' ).disabled = true;
 58+ } );
 59+ /*]]>*/ </script>
 60+EOT
 61+ );
5262
5363 $fieldSize = 50;
5464
5565 $width = StoryboardUtils::getDimension( $args, 'width', $egStorysubmissionWidth );
56 - $maxLen = array_key_exists( 'maxlength', $args ) && is_numeric( $args['maxlength'] ) ? $args['maxlength'] : $egStoryboardMaxStoryLen;
57 - $minLen = array_key_exists( 'minlength', $args ) && is_numeric( $args['minlength'] ) ? $args['minlength'] : $egStoryboardMinStoryLen;
 66+ $maxLen = array_key_exists( 'maxlength', $args ) && is_int( $args['maxlength'] ) ? $args['maxlength'] : $egStoryboardMaxStoryLen;
 67+ $minLen = array_key_exists( 'minlength', $args ) && is_int( $args['minlength'] ) ? $args['minlength'] : $egStoryboardMinStoryLen;
5868
5969 $submissionUrl = $parser->getTitle()->getLocalURL( 'action=purge' );
6070
Index: trunk/extensions/Storyboard/specials/Story/Story_body.php
@@ -22,25 +22,40 @@
2323 public function execute( $title ) {
2424 wfProfileIn( __METHOD__ );
2525
26 - $dbr = wfGetDB( DB_SLAVE );
 26+ global $wgOut, $wgRequest;
2727
28 - if ( trim( $identifier ) != '' ) {
 28+ $action = $wgRequest->getVal( 'action' );
 29+
 30+ if ( $action == 'save' ) {
 31+ $this->saveStoryAndShowResult();
 32+ } else if ( trim( $title ) != '' || $wgRequest->getIntOrNull( 'id' ) ) {
 33+ $this->queryAndShowStory( $title, $action );
 34+ } else {
 35+ $wgOut->addWikiMsg( 'storyboard-nostorytitle' );
 36+ }
 37+
 38+ wfProfileOut( __METHOD__ );
 39+ }
 40+
 41+ /**
 42+ * Queries for the requested story and shows it in either display or edit mode when it's found.
 43+ */
 44+ private function queryAndShowStory( $title, $action ) {
 45+ global $wgOut, $wgRequest;
 46+
 47+ if ( trim( $title ) != '' ) {
2948 $conds = array(
3049 'story_title' => str_replace( '_', ' ', $title )
3150 );
3251 } else {
3352 $id = $wgRequest->getIntOrNull( 'id' );
34 - if ( $id ) {
35 - $conds = array(
36 - 'story_id' => $id
37 - );
38 - } else {
39 - global $wgOut;
40 - $wgOut->addWikiMsg( 'storyboard-nostorytitle' );
41 - return;
42 - }
 53+ $conds = array(
 54+ 'story_id' => $id
 55+ );
4356 }
4457
 58+ $dbr = wfGetDB( DB_SLAVE );
 59+
4560 $story = $dbr->selectRow(
4661 'storyboard',
4762 array(
@@ -55,24 +70,146 @@
5671 );
5772
5873 if ( $story ) {
59 - if ( $story->story_is_published == 1 ) {
60 - $this->showStory( $story );
 74+ if ( $action == 'edit' ) {
 75+ $this->showStoryForm( $story );
 76+ } else {
 77+ if ( $story->story_is_published == 1 ) {
 78+ $this->showStory( $story );
 79+ }
 80+ else {
 81+ $wgOut->addWikiMsg( 'storyboard-unpublished' );
 82+ }
6183 }
62 - else {
63 - $wgOut->addHTML( wfMsg( 'storyboard-unpublished' ) );
64 - }
6584 }
6685 else {
67 - global $wgOut;
68 - $wgOut->addHTML( wfMsg( 'storyboard-nosuchstory' ) );
 86+ $wgOut->addWikiMsg( 'storyboard-nosuchstory' );
 87+ }
 88+ }
 89+
 90+ /**
 91+ * Ouputs the story in regular display mode.
 92+ *
 93+ * @param $story
 94+ */
 95+ private function showStory( $story ) {
 96+ global $wgOut;
 97+
 98+
 99+
 100+ $wgOut->addHTML( '' ); // TODO: add output
 101+ }
 102+
 103+ /**
 104+ * Outputs a form to edit the story with. Code based on <storysubmission>.
 105+ *
 106+ * @param $story
 107+ */
 108+ private function showStoryForm( $story ) {
 109+ global $wgOut, $wgRequest, $wgUser, $wgJsMimeType, $egStoryboardScriptPath, $egStorysubmissionWidth, $egStoryboardMaxStoryLen, $egStoryboardMinStoryLen;
 110+
 111+ $wgOut->addStyle( $egStoryboardScriptPath . '/storyboard.css' );
 112+ $wgOut->addScriptFile( $egStoryboardScriptPath . '/storyboard.js' );
 113+
 114+ $fieldSize = 50;
 115+
 116+ $width = $egStorysubmissionWidth;
 117+
 118+ $maxLen = $wgRequest->getVal( 'maxlength' );
 119+ if ( !is_int( $maxLen ) ) $maxLen = $egStoryboardMaxStoryLen;
 120+
 121+ $minLen = $wgRequest->getVal( 'minlength' );
 122+ if ( !is_int( $minLen ) ) $minLen = $egStoryboardMinStoryLen;
 123+
 124+ //$submissionUrl = $wgParser->getTitle()->getLocalURL( 'action=save' );
 125+ $submissionUrl = ''; // TODO: get title
 126+
 127+ $formBody = "<table width='$width'>";
 128+
 129+ $defaultName = '';
 130+ if ( $wgUser->isLoggedIn() ) {
 131+ $defaultName = $wgUser->getRealName() !== '' ? $wgUser->getRealName() : $wgUser->getName();
69132 }
 133+ $formBody .= '<tr>' .
 134+ Html::element( 'td', array( 'width' => '100%' ), wfMsg( 'storyboard-yourname' ) ) .
 135+ '<td>' .
 136+ Html::input( 'name', $defaultName, 'text', array( 'size' => $fieldSize )
 137+ ) . '</td></tr>';
70138
71 - wfProfileOut( __METHOD__ );
 139+ $formBody .= '<tr>' .
 140+ Html::element( 'td', array( 'width' => '100%' ), wfMsg( 'storyboard-location' ) ) .
 141+ '<td>' . Html::input( 'location', '', 'text', array( 'size' => $fieldSize )
 142+ ) . '</td></tr>';
 143+
 144+ $formBody .= '<tr>' .
 145+ Html::element( 'td', array( 'width' => '100%' ), wfMsg( 'storyboard-occupation' ) ) .
 146+ '<td>' . Html::input( 'occupation', '', 'text', array( 'size' => $fieldSize )
 147+ ) . '</td></tr>';
 148+
 149+ $formBody .= '<tr>' .
 150+ Html::element( 'td', array( 'width' => '100%' ), wfMsg( 'storyboard-contact' ) ) .
 151+ '<td>' . Html::input( 'contact', '', 'text', array( 'size' => $fieldSize )
 152+ ) . '</td></tr>';
 153+
 154+ $formBody .= '<tr>' .
 155+ Html::element( 'td', array( 'width' => '100%' ), wfMsg( 'storyboard-storytitle' ) ) .
 156+ '<td>' . Html::input( 'storytitle', '', 'text', array( 'size' => $fieldSize )
 157+ ) . '</td></tr>';
 158+
 159+ $formBody .= '<tr><td colspan="2">' .
 160+ wfMsg( 'storyboard-story' ) .
 161+ Html::element(
 162+ 'div',
 163+ array( 'class' => 'storysubmission-charcount', 'id' => 'storysubmission-charlimitinfo' ),
 164+ wfMsgExt( 'storyboard-charsneeded', 'parsemag', $minLen )
 165+ ) .
 166+ '<br />' .
 167+ Html::element(
 168+ 'textarea',
 169+ array(
 170+ 'id' => 'storytext',
 171+ 'name' => 'storytext',
 172+ 'rows' => 7,
 173+ 'onkeyup' => "stbValidateStory( this, $minLen, $maxLen, 'storysubmission-charlimitinfo', 'storysubmission-button' )",
 174+ ),
 175+ null
 176+ ) .
 177+ '</td></tr>';
 178+
 179+ $formBody .= '<tr><td colspan="2"><input type="checkbox" id="storyboard-agreement" />&nbsp;' .
 180+ htmlspecialchars( wfMsg( 'storyboard-agreement' ) ) .
 181+ '</td></tr>';
 182+
 183+ $formBody .= '<tr><td colspan="2">' .
 184+ Html::input( '', wfMsg( 'htmlform-submit' ), 'submit', array( 'id' => 'storysubmission-button' ) ) .
 185+ '</td></tr>';
 186+
 187+ $formBody .= '</table>';
 188+
 189+ $formBody .= Html::hidden( 'wpEditToken', $wgUser->editToken() );
 190+
 191+ $formBody = Html::rawElement(
 192+ 'form',
 193+ array(
 194+ 'id' => 'storyform',
 195+ 'name' => 'storyform',
 196+ 'method' => 'post',
 197+ 'action' => $submissionUrl,
 198+ 'onsubmit' => 'return stbValidateSubmission( "storyboard-agreement" );'
 199+ ),
 200+ $formBody
 201+ );
 202+
 203+ $wgOut->addHTML( $formBody );
72204 }
73205
74 - private function showStory( $story ) {
 206+ /**
 207+ * Saves the story after a story edit form has been submitted and shows a result.
 208+ */
 209+ private function saveStoryAndShowResult() {
75210 global $wgOut;
76211
 212+ // TODO: save story
 213+
77214 $wgOut->addHTML( '' ); // TODO: add output
78215 }
79216 }
\ No newline at end of file
Index: trunk/extensions/Storyboard/specials/StoryReview/storyreview.js
@@ -1,33 +0,0 @@
2 -function doStoryAction( sender, storyid, action ) {
3 - sender.disabled = true;
4 -
5 - jQuery.getJSON( wgScriptPath + '/api.php',
6 - {
7 - 'action': 'storyreview',
8 - 'format': 'json',
9 - 'storyid': storyid,
10 - 'storyaction': action
11 - },
12 - function( data ) {
13 - if ( data.result ) {
14 - switch( data.result.action ) {
15 - case 'publish' : case 'unpublish' : case 'hide' :
16 - jQuery( '#story_' + data.result.id ).slideUp( 'slow', function () {
17 - jQuery( this ).remove();
18 - } );
19 - // TODO: would be neat to update the other list when doing an (un)publish here
20 - break;
21 - // TODO: add handling for the other actions
22 - }
23 - } else {
24 - alert( 'An error occured:\n' + data.error.info ); // TODO: i18n
25 - }
26 - }
27 - );
28 -}
29 -
30 -function deleteStoryImage( sender, storyid ) {
31 - if ( confirm( 'Are you sure you want to permanently delete this stories image?' ) ) { // TODO: i18n
32 - doStoryAction( sender, storyid, 'deleteimage' );
33 - }
34 -}
\ No newline at end of file
Index: trunk/extensions/Storyboard/specials/StoryReview/StoryReview_body.php
@@ -39,9 +39,9 @@
4040
4141 $wgOut->setPageTitle( wfMsg( 'storyboard-storyreview' ) );
4242
43 - $wgOut->addStyle( $egStoryboardScriptPath . '/story.css' );
 43+ $wgOut->addStyle( $egStoryboardScriptPath . '/storyboard.css' );
4444 $wgOut->includeJQuery();
45 - $wgOut->addScriptFile( $egStoryboardScriptPath . '/specials/StoryReview/storyreview.js' );
 45+ $wgOut->addScriptFile( $egStoryboardScriptPath . '/storyboard.js' );
4646
4747 // Get a slave db object to do read operations against.
4848 $dbr = wfGetDB( DB_SLAVE );
@@ -127,11 +127,11 @@
128128 </tr>
129129 <tr>
130130 <td align="center" height="35">
131 - <button type="button" onclick="doStoryAction( this, $story->story_id, '$publishAction' )">$publishMsg</button>&nbsp;&nbsp;&nbsp;
 131+ <button type="button" onclick="stbDoStoryAction( this, $story->story_id, '$publishAction' )">$publishMsg</button>&nbsp;&nbsp;&nbsp;
132132 <button type="button" onclick="">$editMsg</button>&nbsp;&nbsp;&nbsp;
133 - <button type="button" onclick="doStoryAction( this, $story->story_id, 'hide' )">$hideMsg</button>&nbsp;&nbsp;&nbsp;
134 - <button type="button" onclick="doStoryAction( this, $story->story_id, '$imageAction' )">$imageMsg</button>&nbsp;&nbsp;&nbsp;
135 - <button type="button" onclick="deleteStoryImage( this, $story->story_id )">$deleteImageMsg</button>
 133+ <button type="button" onclick="stbDoStoryAction( this, $story->story_id, 'hide' )">$hideMsg</button>&nbsp;&nbsp;&nbsp;
 134+ <button type="button" onclick="stbDoStoryAction( this, $story->story_id, '$imageAction' )">$imageMsg</button>&nbsp;&nbsp;&nbsp;
 135+ <button type="button" onclick="stbDeleteStoryImage( this, $story->story_id )">$deleteImageMsg</button>
136136 </td>
137137 </tr>
138138 </table>
Index: trunk/extensions/Storyboard/storyboard.js
@@ -0,0 +1,128 @@
 2+/**
 3+ * JavaScript for the Storyboard extension.
 4+ *
 5+ * @file storyboard.js
 6+ * @ingroup Storyboard
 7+ *
 8+ * @author Jeroen De Dauw
 9+ */
 10+
 11+
 12+/**
 13+ * Story submission/editting functions
 14+ */
 15+
 16+/**
 17+ * Validates a story, and will update the provided UI elements depending on the result.
 18+ *
 19+ * @param textarea Textarea object in which the story resides.
 20+ * @param lowerLimit Min numbers of chars a story can be.
 21+ * @param upperLimit Max numbers of chars a story can be.
 22+ * @param infodiv Id of a div to put info about the characters amount in.
 23+ * @param submissionButton Id of the button that will submit the story.
 24+ */
 25+function stbValidateStory( textarea, lowerLimit, upperLimit, infodiv, submissionButton ) {
 26+ var button = document.getElementById( submissionButton );
 27+ button.disabled = !stbLimitChars( textarea, lowerLimit, upperLimit, infodiv );
 28+}
 29+
 30+/**
 31+ * Validates the amount of characters of a story and outputs the result in an infodiv.
 32+ *
 33+ * @param textarea Textarea object in which the story resides.
 34+ * @param lowerLimit Min numbers of chars a story can be.
 35+ * @param upperLimit Max numbers of chars a story can be.
 36+ * @param infodiv Id of a div to put info about the characters amount in.
 37+ *
 38+ * @return Boolean indicating whether the story is valid.
 39+ */
 40+function stbLimitChars( textarea, lowerLimit, upperLimit, infodiv ) {
 41+ var text = textarea.value;
 42+ var textlength = text.length;
 43+ var info = document.getElementById( infodiv );
 44+
 45+ if(textlength > upperLimit) {
 46+ info.innerHTML = -( upperLimit - textlength ) + ' characters to many!'; // TODO: i18n
 47+ return false;
 48+ } else if (textlength < lowerLimit) {
 49+ info.innerHTML = '('+ ( lowerLimit - textlength ) + ' more characters needed)'; // TODO: i18n
 50+ return false;
 51+ } else {
 52+ info.innerHTML = '(' + ( upperLimit - textlength ) + ' characters left)'; // TODO: i18n
 53+ return true;
 54+ }
 55+}
 56+
 57+/**
 58+ * Checks if the story can actually be submitted, and shows and error when this is not the case.
 59+ *
 60+ * @param termsCheckbox Id of a terms of service checkbox that needs to be checked.
 61+ *
 62+ * @return Boolean indicating whether the submission is valid.
 63+ */
 64+function stbValidateSubmission( termsCheckbox ) {
 65+ var agreementValid = document.getElementById( termsCheckbox ).checked;
 66+ if (!agreementValid) {
 67+ alert( 'You need to agree to the publication of your story to submit it.' ); // TODO: i18n
 68+ }
 69+ return agreementValid;
 70+}
 71+
 72+
 73+
 74+/**
 75+ * Story review functions
 76+ */
 77+
 78+/**
 79+ * Calls the StoryReview API module to do actions on a story and handles updating of the page in the callback.
 80+ *
 81+ * @param sender The UI element invocing the action, typically a button.
 82+ * @param storyid Id identifying the story.
 83+ * @param action The action that needs to be performed on the story.
 84+ *
 85+ * TODO: support multiple actions at once
 86+ */
 87+function stbDoStoryAction( sender, storyid, action ) {
 88+ sender.disabled = true;
 89+
 90+ jQuery.getJSON( wgScriptPath + '/api.php',
 91+ {
 92+ 'action': 'storyreview',
 93+ 'format': 'json',
 94+ 'storyid': storyid,
 95+ 'storyaction': action
 96+ },
 97+ function( data ) {
 98+ if ( data.storyreview ) {
 99+ switch( data.storyreview.action ) {
 100+ case 'publish' : case 'unpublish' : case 'hide' :
 101+ jQuery( '#story_' + data.storyreview.id ).slideUp( 'slow', function () {
 102+ jQuery( this ).remove();
 103+ } );
 104+ // TODO: would be neat to update the other list when doing an (un)publish here
 105+ break;
 106+ // TODO: add handling for the other actions
 107+ }
 108+ } else {
 109+ alert( 'An error occured:\n' + data.error.info ); // TODO: i18n
 110+ }
 111+ }
 112+ );
 113+}
 114+
 115+/**
 116+ * Asks the user to confirm the deletion of an image, and if confirmed, calls stbDoStoryAction with action=delete.
 117+ *
 118+ * @param sender The UI element invocing the action, typically a button.
 119+ * @param storyid Id identifying the story.
 120+ *
 121+ * @return Boolean indicating whether the deletion was confirmed.
 122+ */
 123+function stbDeleteStoryImage( sender, storyid ) {
 124+ var confirmed = confirm( 'Are you sure you want to permanently delete this stories image?' ); // TODO: i18n
 125+ if ( confirmed ) {
 126+ doStoryAction( sender, storyid, 'deleteimage' );
 127+ }
 128+ return confirmed;
 129+}
\ No newline at end of file
Property changes on: trunk/extensions/Storyboard/storyboard.js
___________________________________________________________________
Name: svn:eol-style
1130 + native

Comments

#Comment by Pdhanda (talk | contribs)   23:26, 31 March 2010

Hi Jeroen,

I was looking at the submission code of the Storyboard and I have a few comments. You may already have planned for this but I just wanted it documented so that we don't forget about it

- The storyboard table has a unique index on title, however storytitle is not a required field in the submission form. I notice if i try to submit multiple stories without a title I get sql key violation errors. We should probably do some kind of enforcing/unification of title.

- The test for whether a user has posted a story is currently done in TagStorysubmission's render. Since this is cached by the parser once you post a story it every subsequent page request keeps displaying the success message and no form unless we do an action=purge. We may want to do the check for submission outside the tag?

Thanks -p

#Comment by Jeroen De Dauw (talk | contribs)   00:01, 1 April 2010

I indeed still have to add some form of validation to the title in the submission form, as well as some other fields. Is there any preferred way of doing this? I'm guessing either validating a field when it loses focus or the whole form before it's submitted. Also, should I have additional server side validation, for people who have JS disabled, or a hacky browser? I don't see any security issues there, but it might be preferred not to display SQL errors in any situation? Both points also go for editing stories on Special:Story of course.

I didn't think of the cache issue with putting the message in the tag. I'm not quite sure how to best check outside it though - any recommendations?

#Comment by Jeroen De Dauw (talk | contribs)   19:32, 10 April 2010

Both issues have been fixed - this can be marked as fixed.

Status & tagging log