New edit toolbar for bold, italic, links, headlines, math, images, media,
authorErik Moeller <erik@users.mediawiki.org>
Sun, 11 Jan 2004 04:11:43 +0000 (04:11 +0000)
committerErik Moeller <erik@users.mediawiki.org>
Sun, 11 Jan 2004 04:11:43 +0000 (04:11 +0000)
sigs, horizontal lines (more can be added easily). Select text and click
to apply, or just click to see an example. Mouseover should show speedtips.

Also, access keys for the edit window (ALT+P=Preview, ALT+S=Save) -> Moz+IE

includes/EditPage.php
includes/Skin.php
languages/Language.php
stylesheets/wikibits.js
stylesheets/wikistandard.css

index efe60d4..72be476 100644 (file)
@@ -116,10 +116,10 @@ class EditPage {
                                return;
                        }
                        # If article is new, insert it.
-                       
-                       $aid = $this->mTitle->getArticleID();                   
+
+                       $aid = $this->mTitle->getArticleID();
                        if ( 0 == $aid ) {
-                               # we need to strip Windoze linebreaks because some browsers 
+                               # we need to strip Windoze linebreaks because some browsers
                                # append them and the string comparison fails
                                if ( ( "" == $wpTextbox1 ) ||
                                  ( wfMsg( "newarticletext" ) == rtrim( preg_replace("/\r/","",$wpTextbox1) ) ) ) {
@@ -134,8 +134,8 @@ class EditPage {
                        # Don't check for conflict when appending a comment - this should always work
 
                        $this->mArticle->clear(); # Force reload of dates, etc.
-                       if ( $section!="new" && ( $this->mArticle->getTimestamp() != $wpEdittime ) ) { 
-                               $isConflict = true;             
+                       if ( $section!="new" && ( $this->mArticle->getTimestamp() != $wpEdittime ) ) {
+                               $isConflict = true;
                        }
                        $u = $wgUser->getID();
 
@@ -180,7 +180,7 @@ class EditPage {
                } else {
                        $s = wfMsg( "editing", $this->mTitle->getPrefixedText() );
 
-                       if($section!="") { 
+                       if($section!="") {
                                if($section=="new") {
                                        $s.=wfMsg("commentedit");
                                } else {
@@ -206,11 +206,11 @@ class EditPage {
 
                $kblength = (int)(strlen( $wpTextbox1 ) / 1024);
                if( $kblength > 29 ) {
-                       $wgOut->addHTML( "<strong>" . 
+                       $wgOut->addHTML( "<strong>" .
                                wfMsg( "longpagewarning", $kblength )
                                . "</strong>" );
                }
-               
+
                $rows = $wgUser->getOption( "rows" );
                $cols = $wgUser->getOption( "cols" );
 
@@ -222,7 +222,7 @@ class EditPage {
                if ( "no" == $redirect ) { $q .= "&redirect=no"; }
                $action = wfEscapeHTML( wfLocalUrl( $this->mTitle->getPrefixedURL(), $q ) );
 
-               $summary = wfMsg( "summary" );          
+               $summary = wfMsg( "summary" );
                $subject = wfMsg("subject");
                $minor = wfMsg( "minoredit" );
                $watchthis = wfMsg ("watchthis");
@@ -239,38 +239,44 @@ class EditPage {
                $wpTextbox1 = wfEscapeHTML( $wpTextbox1 );
                $wpTextbox2 = wfEscapeHTML( $wpTextbox2 );
                $wpSummary = wfEscapeHTML( $wpSummary );
-               
+
+
+               if($wgUser->getOption("showtoolbar")) {
+                       // prepare toolbar for edit buttons
+                       $toolbar=$sk->getEditToolbar();
+               }
+
                // activate checkboxes if user wants them to be always active
                if (!$wpPreview && $wgUser->getOption("watchdefault")) $wpWatchthis=1;
-               if (!$wpPreview && $wgUser->getOption("minordefault")) $wpMinoredit=1;          
-               
+               if (!$wpPreview && $wgUser->getOption("minordefault")) $wpMinoredit=1;
+
                // activate checkbox also if user is already watching the page,
                // require wpWatchthis to be unset so that second condition is not
                // checked unnecessarily
                if (!$wpWatchthis && !$wpPreview && $this->mTitle->userIsWatching()) $wpWatchthis=1;
-               
+
                if ( 0 != $wgUser->getID() ) {
                        $checkboxhtml=
                        "<input tabindex=3 type=checkbox value=1 name='wpMinoredit'".($wpMinoredit?" checked":"")." id='wpMinoredit'>".
                        "<label for='wpMinoredit'>{$minor}</label>".
                        "<input tabindex=4 type=checkbox name='wpWatchthis'".($wpWatchthis?" checked":"")." id='wpWatchthis'>".
                        "<label for='wpWatchthis'>{$watchthis}</label><br>";
-                       
+
                } else {
                        $checkboxhtml="";
                }
 
 
                if ( "preview" == $formtype) {
-               
-                       $previewhead="<h2>" . wfMsg( "preview" ) . "</h2>\n<p><large><center><font color=\"#cc0000\">" . 
+
+                       $previewhead="<h2>" . wfMsg( "preview" ) . "</h2>\n<p><large><center><font color=\"#cc0000\">" .
                        wfMsg( "note" ) . wfMsg( "previewnote" ) . "</font></center></large><P>\n";
                        if ( $isConflict ) {
                                $previewhead.="<h2>" . wfMsg( "previewconflict" ) .
                                  "</h2>\n";
                        }
                        $previewtext = wfUnescapeHTML( $wpTextbox1 );
-                       
+
                        if($wgUser->getOption("previewontop")) {
                                $wgOut->addHTML($previewhead);
                                $wgOut->addWikiText( $this->mArticle->preSaveTransform( $previewtext ) ."\n\n");
@@ -293,6 +299,7 @@ class EditPage {
                        $wgOut->setOnloadHandler( "document.editform.wpTextbox1.focus()" );
                }
                $wgOut->addHTML( "
+{$toolbar}
 <form id=\"editform\" name=\"editform\" method=\"post\" action=\"$action\"
 enctype=\"application/x-www-form-urlencoded\">
 {$commentsubject}
@@ -303,8 +310,8 @@ $wgLang->recodeForEdit( $wpTextbox1 ) .
 </textarea>
 <br>{$editsummary}
 {$checkboxhtml}
-<input tabindex=5 type=submit value=\"{$save}\" name=\"wpSave\">
-<input tabindex=6 type=submit value=\"{$prev}\" name=\"wpPreview\">
+<input tabindex=5 type=submit value=\"{$save}\" name=\"wpSave\" accesskey=\"s\">
+<input tabindex=6 type=submit value=\"{$prev}\" name=\"wpPreview\" accesskey=\"p\">
 <em>{$cancel}</em> | <em>{$edithelp}</em>
 <br><br>{$copywarn}
 <input type=hidden value=\"{$section}\" name=\"wpSection\">
index e5638f7..7af2d63 100644 (file)
@@ -1923,6 +1923,98 @@ class Skin {
                return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
 
        }
+
+       // This function is called by EditPage.php and shows a bulletin board style
+       // toolbar for common editing functions. It can be disabled in the user preferences.
+       // The necsesary JavaScript code can be found in style/wikibits.js.
+       function getEditToolbar() {
+
+               global $wgUploadPath;
+
+               // toolarray an array of arrays which each include the filename of
+               // the button image (without path), the opening tag, the closing tag,
+               // and optionally a sample text that is inserted between the two when no
+               // selection is highlighted.
+               // The tip text is shown when the user moves the mouse over the button.
+               $toolarray=array(
+                       array(  "image"=>"button_bold.gif",
+                               "open"=>"\\'\\'\\'",
+                               "close"=>"\\'\\'\\'",
+                               "sample"=>wfMsg("bold_sample"),
+                               "tip"=>wfMsg("bold_tip")),
+                       array(  "image"=>"button_italic.gif",
+                               "open"=>"\\'\\'",
+                               "close"=>"\\'\\'",
+                               "sample"=>wfMsg("italic_sample"),
+                               "tip"=>wfMsg("italic_tip")),
+                       array(  "image"=>"button_link.gif",
+                               "open"=>"[[",
+                               "close"=>"]]",
+                               "sample"=>wfMsg("link_sample"),
+                               "tip"=>wfMsg("link_tip")),
+                       array(  "image"=>"button_extlink.gif",
+                               "open"=>"[",
+                               "close"=>"]",
+                               "sample"=>wfMsg("extlink_sample"),
+                               "tip"=>wfMsg("extlink_tip")),
+                       array(  "image"=>"button_headline.gif",
+                               "open"=>"\\n== ",
+                               "close"=>" ==\\n",
+                               "sample"=>wfMsg("headline_sample"),
+                               "tip"=>wfMsg("headline_tip")),
+                       array(  "image"=>"button_math.gif",
+                               "open"=>"\\<math\\>",
+                               "close"=>"\\</math\\>",
+                               "sample"=>wfMsg("math_sample"),
+                               "tip"=>wfMsg("math_tip")),
+                       array(  "image"=>"button_image.gif",
+                               "open"=>"[[Image:",
+                               "close"=>"]]",
+                               "sample"=>wfMsg("image_sample"),
+                               "tip"=>wfMsg("image_tip")),
+                       array(  "image"=>"button_media.gif",
+                               "open"=>"[[Media:",
+                               "close"=>"]]",
+                               "sample"=>wfMsg("media_sample"),
+                               "tip"=>wfMsg("media_tip")),
+                       array(  "image"=>"button_sig.gif",
+                               "open"=>"--~~~~",
+                               "close"=>"",
+                               "sample"=>"",
+                               "tip"=>wfMsg("sig_tip")),
+                       array(  "image"=>"button_hr.gif",
+                               "open"=>"\\n----\\n",
+                               "close"=>"",
+                               "sample"=>"",
+                               "tip"=>wfMsg("hr_tip"))
+               );
+               $toolbar.="
+               <div id=\"toolbar\">";
+               foreach($toolarray as $tool) {
+
+                       $image=$tool["image"];
+                       $open=$tool["open"];
+                       $close=$tool["close"];
+                       $sample=$tool["sample"];
+
+                       // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
+                       // Older browsers show a "speedtip" type message only for ALT.
+                       // Ideally these should be different, realistically they
+                       // probably don't need to be.
+                       $tip=$tool["tip"];
+
+                       $toolbar.=
+                       "<a href=\"#\"".
+                       "onclick=\"javascript:insertTags('$open','$close','$sample');\">".
+                       "<img src=\"$wgUploadPath/$image\" border=\"0\" ALT=\"$tip\" TITLE=\"$tip\">".
+                       "</a>";
+
+               }
+
+               $toolbar.="</div>";
+               return $toolbar;
+
+       }
 }
 
 include_once( "SkinStandard.php" );
index 328e867..37b6f4e 100644 (file)
@@ -61,6 +61,7 @@ if($wgMetaNamespace === FALSE)
        "skin" => 0, "math" => 1, "rcdays" => 7, "rclimit" => 50,
        "highlightbroken" => 1, "stubthreshold" => 0,
        "previewontop" => 1, "editsection"=>1,"editsectiononrightclick"=>0, "showtoc"=>1,
+       "showtoolbar"=>1,
        "date" => 0
 );
 
@@ -97,6 +98,7 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
        "hideminor" => "Hide minor edits in recent changes",
        "usenewrc" => "Enhanced recent changes (not for all browsers)",
        "numberheadings" => "Auto-number headings",
+       "showtoolbar"=>"Show edit box toolbar",
        "editondblclick" => "Edit pages on double click (JavaScript)",
        "editsection"=>"Enable section editing via [edit] links",
        "editsectiononrightclick"=>"Enable section editing by right clicking<br> on section titles (JavaScript)",
@@ -289,7 +291,7 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
     MAG_START                => array( 0,    "__START__"              ),
     MAG_CURRENTMONTH         => array( 1,    "{{CURRENTMONTH}}"       ),
     MAG_CURRENTMONTHNAME     => array( 1,    "{{CURRENTMONTHNAME}}"   ),
-    MAG_CURRENTDAY           => array( 1,    "{{CURRENTDAY}}"         ),   
+    MAG_CURRENTDAY           => array( 1,    "{{CURRENTDAY}}"         ),
     MAG_CURRENTDAYNAME       => array( 1,    "{{CURRENTDAYNAME}}"     ),
     MAG_CURRENTYEAR          => array( 1,    "{{CURRENTYEAR}}"        ),
     MAG_CURRENTTIME          => array( 1,    "{{CURRENTTIME}}"        ),
@@ -300,7 +302,7 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
     MAG_MSGNW                => array( 0,    "{{MSGNW:$1}}"           ),
        MAG_END                  => array( 0,    "__END__"                )
 );
-       
+
 # All special pages have to be listed here: a description of ""
 # will make them not show up on the "Special Pages" page, which
 # is the right thing for some of them (such as the "targeted" ones).
@@ -357,7 +359,7 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
 #-------------------------------------------------------------------
 # Default messages
 #-------------------------------------------------------------------
-# Allowed characters in keys are: A-Z, a-z, 0-9, underscore (_) and 
+# Allowed characters in keys are: A-Z, a-z, 0-9, underscore (_) and
 # hyphen (-). If you need more characters, you may be able to change
 # the regex in MagicWord::initRegex
 
@@ -582,6 +584,26 @@ You should log in and change your password now.",
 registered for \"$1\".
 Please log in again after you receive it.",
 
+# Edit page toolbar
+"bold_sample"=>"Bold text",
+"bold_tip"=>"Bold text",
+"italic_sample"=>"Italic text",
+"italic_tip"=>"Italic text",
+"link_sample"=>"Link title",
+"link_tip"=>"Internal link",
+"extlink_sample"=>"http://www.example.com link title",
+"extlink_tip"=>"External link (remember http:// prefix)",
+"headline_sample"=>"Headline text",
+"headline_tip"=>"Level 2 headline",
+"math_sample"=>"Insert formula here",
+"math_tip"=>"Mathematical formula (LaTeX)",
+"image_sample"=>"Example.jpg",
+"image_tip"=>"Embedded image",
+"media_sample"=>"Example.mp3",
+"media_tip"=>"Media file link",
+"sig_tip"=>"Your signature with timestamp",
+"hr_tip"=>"Horizontal line (use sparingly)",
+
 # Edit pages
 #
 "summary"              => "Summary",
@@ -594,14 +616,14 @@ Please log in again after you receive it.",
 "blockedtitle" => "User is blocked",
 "blockedtext"  => "Your user name or IP address has been blocked by $1.
 The reason given is this:<br>''$2''<p>You may contact $1 or one of the other
-[[$wgMetaNamespace:Administrators|administrators]] to discuss the block. 
+[[$wgMetaNamespace:Administrators|administrators]] to discuss the block.
 
-Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]]. 
+Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]].
 
 Your IP address is $3. Please include this address in any queries you make.
 
 ==Note to AOL users==
-Due to continuing acts of vandalism by one particular AOL user, Wikipedia often blocks AOL proxies. Unfortunately, a single proxy server may be used by a large number of AOL users, and hence innocent AOL users are often inadvertently blocked. We apologise for any inconvenience caused. 
+Due to continuing acts of vandalism by one particular AOL user, Wikipedia often blocks AOL proxies. Unfortunately, a single proxy server may be used by a large number of AOL users, and hence innocent AOL users are often inadvertently blocked. We apologise for any inconvenience caused.
 
 If this happens to you, please email an administrator, using an AOL email address. Be sure to include the IP address given above.
 ",
index ba8ce1d..21c679a 100644 (file)
@@ -1,5 +1,15 @@
 // Wikipedia JavaScript support functions
 
+var clientVer = parseInt(navigator.appVersion); // Get browser version
+var clientPC = navigator.userAgent.toLowerCase(); // Get client info
+var is_ie = ((clientPC.indexOf("msie") != -1) && (clientPC.indexOf("opera") == -1));
+var is_nav = ((clientPC.indexOf('mozilla')!=-1) && (clientPC.indexOf('spoofer')==-1)
+                && (clientPC.indexOf('compatible') == -1) && (clientPC.indexOf('opera')==-1)
+                && (clientPC.indexOf('webtv')==-1) && (clientPC.indexOf('hotjava')==-1));
+var is_moz = 0;
+var is_win = ((clientPC.indexOf("win")!=-1) || (clientPC.indexOf("16bit") != -1));
+var is_mac = (clientPC.indexOf("mac")!=-1);
+
 // for enhanced RecentChanges
 function toggleVisibility( _levelId, _otherId, _linkId) {
        var thisLevel = document.getElementById( _levelId );
@@ -51,7 +61,7 @@ function showTocToggle(show,hide) {
        if(document.getElementById) {
                document.writeln('<small>[<a href="javascript:toggleToc()" class="internal">' +
                '<span id="showlink" style="display:none;">' + show + '</span>' +
-               '<span id="hidelink">' + hide + '</span>' 
+               '<span id="hidelink">' + hide + '</span>'
                + '</a>]</small>');
        }
 }
@@ -61,7 +71,7 @@ function toggleToc() {
        var showlink=document.getElementById('showlink');
        var hidelink=document.getElementById('hidelink');
        if(toc.style.display == 'none') {
-               toc.style.display = tocWas;             
+               toc.style.display = tocWas;
                hidelink.style.display='';
                showlink.style.display='none';
 
@@ -74,3 +84,55 @@ function toggleToc() {
        }
 }
 
+// apply tagOpen/tagClose to selection in textarea,
+// use sampleText instead of selection if there is none
+// copied and adapted from phpBB
+function insertTags(tagOpen, tagClose, sampleText) {
+
+       var txtarea = document.editform.wpTextbox1;
+       if ((clientVer >= 4) && is_ie && is_win) {
+               theSelection = document.selection.createRange().text;
+               if (!theSelection) {
+                       txtarea.value += tagOpen + sampleText + tagClose;
+                       txtarea.focus();
+                       return;
+               }
+               document.selection.createRange().text = tagOpen + theSelection + tagClose;
+               txtarea.focus();
+               return;
+       }
+       else if (txtarea.selectionEnd && (txtarea.selectionEnd - txtarea.selectionStart > 0))
+       {
+               mozWrap(txtarea, tagOpen, tagClose, sampleText);
+               return;
+       }
+       else
+       {
+               txtarea.value += tagOpen + sampleText + tagClose;
+               txtarea.focus();
+       }
+       storeCaret(txtarea);
+}
+
+// From http://www.massless.org/mozedit/
+function mozWrap(txtarea, open, close)
+{
+       var txtarea = document.editform.wpTextbox1;
+       var selLength = txtarea.textLength;
+       var selStart = txtarea.selectionStart;
+       var selEnd = txtarea.selectionEnd;
+       if (selEnd == 1 || selEnd == 2)
+               selEnd = selLength;
+
+       var s1 = (txtarea.value).substring(0,selStart);
+       var s2 = (txtarea.value).substring(selStart, selEnd)
+       var s3 = (txtarea.value).substring(selEnd, selLength);
+       txtarea.value = s1 + open + s2 + close + s3;
+       return;
+}
+
+// Insert at Claret position. Code from
+// http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130
+function storeCaret(textEl) {
+       if (textEl.createTextRange) textEl.caretPos = document.selection.createRange().duplicate();
+}
index 1f33328..d4e20a7 100644 (file)
@@ -8,6 +8,7 @@
 #quickbar { width: 140px; padding: 4px; visibility: visible; z-index:99;font-size:95%;}
 #topbar { padding: 4px;font-size:95%; }
 #toc { border:1px solid #8888aa; background-color:#f7f8ff;padding:5px;font-size:95%; }
+#toolbar { border-width:2px;border-style:groove;border-color:black;padding:0px;width:230px;}
 .bodytext { }
 a.interwiki, a.external { color: #3366BB; }
 a.printable { text-decoration: underline; }