#1410: Category Management within FCKeditor
-------------------------------------------+--------------------------------
 Reporter:  davidwilliambarker             |       Owner:  Deimon  
     Type:  New Feature                    |      Status:  assigned
 Priority:  Normal                         |   Milestone:          
Component:  Project : MediaWiki+FCKeditor  |     Version:          
 Keywords:  Confirmed                      |  
-------------------------------------------+--------------------------------
Changes (by Deimon):

  * owner:  => Deimon
  * status:  new => assigned


Comment:

 I have created such functionality.

 Add this functions in extensions\FCKeditor\FCKeditorSajax.body.php
 {{{
 function wfSajaxSearchCategoryFCKeditor()
 {
         global $wgContLang, $wgOut;
         $ns = NS_CATEGORY;
         $m_sql="SELECT tmpSelectCat1.cl_to AS title
 FROM wiki_categorylinks AS tmpSelectCat1
 LEFT JOIN wiki_page AS tmpSelectCatPage ON ( tmpSelectCat1.cl_to =
 tmpSelectCatPage.page_title
 AND tmpSelectCatPage.page_namespace =14 )
 LEFT JOIN wiki_categorylinks AS tmpSelectCat2 ON tmpSelectCatPage.page_id
 = tmpSelectCat2.cl_from
 WHERE tmpSelectCat2.cl_from IS NULL
 GROUP BY tmpSelectCat1.cl_to";

         $db =& wfGetDB( DB_SLAVE );

         $res = $db->query($m_sql,__METHOD__ );

         $ret = "";
         $i=0;
         while ( ( $row = $db->fetchObject( $res ) ) ) {
                 $ret .= $row->title ."\n";
 //$ret.=wfSajaxSearchCategoryChildrenFCKeditor($row->title);
                 $sub =
 explode("\n",wfSajaxSearchCategoryChildrenFCKeditor($row->title));
                 foreach($sub as $subrow)if(strlen($subrow)>0)$ret.="
 ".$subrow."\n";
         }

         return $ret;
 }

 function wfSajaxSearchCategoryChildrenFCKeditor($m_root)
 {
         global $wgContLang, $wgOut;
         $limit = 50;
         $ns = NS_CATEGORY;
     $m_root = str_replace("'","\'",$m_root);
     $m_sql = "      SELECT tmpSelectCatPage.page_title AS title
                         FROM wiki_categorylinks AS tmpSelectCat
                         LEFT JOIN wiki_page AS tmpSelectCatPage ON
 tmpSelectCat.cl_from = tmpSelectCatPage.page_id
                         WHERE tmpSelectCat.cl_to LIKE '$m_root' AND
 tmpSelectCatPage.page_namespace = 14";

         $db =& wfGetDB( DB_SLAVE );

         $res = $db->query($m_sql,__METHOD__ );

         $ret = "";
         $i=0;
         while ( ( $row = $db->fetchObject( $res ) ) ) {
                 $ret .= $row->title ."\n";
 //$ret.=wfSajaxSearchCategoryChildrenFCKeditor($row->title);
                 $sub =
 explode("\n",wfSajaxSearchCategoryChildrenFCKeditor($row->title));
                 foreach($sub as $subrow)if(strlen($subrow)>0)$ret.="
 ".$subrow."\n";

         }

         return $ret;
 }
 }}}

 Add this in file extensions\FCKeditor\FCKeditor.php

 {{{
 $wgAjaxExportList[] = 'wfSajaxSearchCategoryFCKeditor';
 }}}

 Create file extensions\FCKeditor\plugins\mediawiki\dialogs\category.html
 as this

 {{{
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <!--
   * Link dialog window.
 -->
 <html>
 <head>
         <title>Link Properties</title>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8"
 />
         <meta name="robots" content="noindex, nofollow" />
         <script type="text/javascript">

 var oEditor             = window.parent.InnerDialogLoaded() ;
 var FCK                 = oEditor.FCK ;
 var FCKLang             = oEditor.FCKLang ;
 var FCKConfig   = oEditor.FCKConfig ;
 var FCKRegexLib = oEditor.FCKRegexLib ;
 var FCKTools    = oEditor.FCKTools ;
 var FCKBrowserInfo      = oEditor.FCKBrowserInfo ;
 var EditorDocument = oEditor.FCK.EditorDocument ;

 document.write( '<script src="' + FCKConfig.BasePath +
 'dialog/common/fck_dialog_common.js" type="text/javascript"><\/script>' )
 ;

         </script>
         <script type="text/javascript">

 // oLink: The actual selected link in the editor.

 window.onload = function()
 {
         // Translate the dialog box texts.
         oEditor.FCKLanguageManager.TranslatePage(document) ;

         // Load the selected link information (if any).
         InitSelected() ;
         SetSearchMessage( 'loading categories...' ) ;
         oEditor.window.parent.sajax_request_type = 'GET' ;
         oEditor.window.parent.sajax_do_call(
 'wfSajaxSearchCategoryFCKeditor', [], InitCategoryTree ) ;

         // Activate the "OK" button.
         window.parent.SetOkButton( true ) ;
         window.parent.SetAutoSize( true ) ;
 }

 var selectedCats;

 function InitSelected()
 {
         selectedCats=new Array();
         var node=EditorDocument;
     while(node){
                 if(node.nodeType==1 && node.tagName.toLowerCase() == 'a'){
                         // Get the actual Link href.
                         var sHRef = node.getAttribute( '_fcksavedurl' ) ;
                         if ( sHRef == null )sHRef = node.getAttribute(
 'href' , 2 ) || '' ;
                         if(sHRef.StartsWith('Category:')){
                                 var select = GetE('xCategories' ) ;
                                 var cat=sHRef.slice(9);
                                 SelectCategory(cat,-1);
                         }
                 }
         node=FCKTools.GetNextNode(node,EditorDocument);
     }


         // Make an Ajax search for the pages.
 }

 function SelectCategory(cat,catTreeRow)
 {
         var row=parseInt(catTreeRow);
         if(row>=0){
                 var select = GetE('xWikiResults' );
                 cat=select.options[row].text;
                 var lvl=0;
                 while(cat.charAt(lvl)==placeholder)lvl++;
                 cat=cat.slice(lvl);
                 if(cat.charAt(0)=='[' &&
 cat.charAt(cat.length-1)==']')cat=cat.substring(1,cat.length-1);
         }

         if(selectedCats[cat])delete selectedCats[cat];
         else selectedCats[cat]=cat;
         var select = GetE( 'xCategories' ) ;
         while (select.options.length > 0 )select.remove( 0 );
         for(var cat in selectedCats) FCKTools.AddSelectOption( select,
 cat, cat) ;
 }


 var catTree;

 function InitCategoryTree( result )
 {
         SetSearchMessage( '' ) ;

         catTree=new Object();
         var levelsHead=new Array('root');
         var levelsBody=new Array('');

         var results = result.responseText.Trim().split( '\n' ) ;
         var previousLvl=-1;
                 for ( var i = 0 ; i < results.length ; i++ ){
                         var lvl=0;
                         while(results[i].charAt(lvl)==' ')lvl++;
                         var t=results[i].slice(lvl);
                         for(var j=previousLvl;j>lvl-1;j--){

 if(levelsBody[j+1]!='')catTree[levelsHead[j+1]]=levelsBody[j+1];
                                 delete levelsHead[j+1];
                                 delete levelsBody[j+1];
                         }
                         if(lvl>previousLvl)levelsBody[lvl]=t;
                         else levelsBody[lvl]=levelsBody[lvl]+' '+t;
                         levelsHead[lvl+1]=t;
                         levelsBody[lvl+1]='';
                         previousLvl=lvl;
                 }
                 for(var j=previousLvl;j>=-1;j--){
 if(levelsBody[j+1]!='')catTree[levelsHead[j+1]]=levelsBody[j+1];
                 delete levelsHead[j+1];
                 delete levelsBody[j+1];
         }

         ShowCategoriesSubTree(-1);
 }

 var placeholder='.';

 //draw category subtree
 function ShowCategoriesSubTree(rowInTree){
         var row=parseInt(rowInTree);
         var select = GetE('xWikiResults' ) ;
         var root='root';
         var lvl=-1;
         var prefix='';
         if(row>=0){
                 root=select.options[row].text;
                 lvl=0;
                 while(root.charAt(lvl)==placeholder)lvl++;
                 root=root.slice(lvl);
                 if(root.charAt(0)=='[' && root.charAt(root.length-1)==']')
                         root=root.substring(1,root.length-1);
                 prefix=new Array(lvl+1+3).join(placeholder);
         }
         if(!catTree[root])return;

         var itCount=select.options.length;
         var itSkip=row+1;
         var opts=new Array();
         for(var i=row+1;i<itCount;i++){
                 var t=select.options[i].text;
                 var sublvl=0;
                 while(t.charAt(sublvl)==placeholder)sublvl++;
                 if(sublvl>lvl)itSkip=i+1;
                 else break;
         }
         for(var i=itCount-1;i>row;i--){
                 var t=select.options[i].text;
                 //if(t==fullroot)break;
                 if(i>=itSkip)opts.push(t);
                 select.remove(i);
         }
         //while ( select.options.length > 0 )
         //      select.remove( 0 )
                 if(itSkip==row+1){
                         var cats = catTree[root].split(' ') ;

                         for(var k in cats){
                                 var p=cats[k];
                                 if(catTree[cats[k]])p='['+p+']';
                                 var e=FCKTools.AddSelectOption( select,
 prefix+p, ++row) ;
                                 if(catTree[cats[k]])e.style.color='#00f';

                         }
                 }
                 for(var i=opts.length-1;i>=0;i--){
                         var e=FCKTools.AddSelectOption( select, opts[i],
 ++row) ;
                         if(opts[i].indexOf('[')>=0)e.style.color='#00f';
         }

 }

 //draw filtered
 function ShowFilteredCategories(filter){
         var select = GetE('xWikiResults' ) ;
         while (select.options.length > 0 )select.remove( 0 );
         //alert(filter);
         var found=new Object();
         if(filter.length==0){
                 ShowCategoriesSubTree(-1);
                 return;
         }
         filter=filter.toLowerCase();
         var row=-1;
         for(var folder in catTree){
                 var cats = catTree[folder].split(' ') ;
                 for(var k in cats){
                         var p=cats[k].toLowerCase();
                         if(p.indexOf(filter)>=0){
                                 if(found[cats[k]]);
                                 else{
                                         found[cats[k]]=cats[k];
                                         FCKTools.AddSelectOption( select,
 cats[k], ++row ) ;
                                 }
                         }
                 }
         }
 }

 function AddNew(){
         var select = GetE('txtUrl' );
         SelectCategory(select.value,-1)

 }


 //#### The OK button was hit.
 function Ok()
 {
         var nodes=new Array();
     var node=EditorDocument;
         var nodeNext;
         var s='';
         var i=0;
     while(node){
         nodeNext=FCKTools.GetNextNode(node,EditorDocument);
                 if(node.nodeType==1 && node.tagName.toLowerCase() == 'a'){
                         // Get the actual Link href.
                         var sHRef = node.getAttribute( '_fcksavedurl' ) ;
                         if ( sHRef == null )sHRef = node.getAttribute(
 'href' , 2 ) || '' ;
                         if(sHRef.StartsWith('Category:'))nodes[i++]=node;
                 }
                 node=nodeNext;
     }
         for(var
 i=0;i<nodes.length;i++)nodes[i].parentNode.removeChild(nodes[i]);

         for(var cat in selectedCats)AddCategoryLink(cat);
         return true;

 }


 function AddCategoryLink(cat){
         var sUri = 'Category:'+cat;
         var sInnerHtml ;

         // If no link is selected, create a new one (it may result in more
 than one link creation - #220).
         var aLinks = oEditor.FCK.CreateLink( sUri ) ;

         // If no selection, no links are created, so use the uri as the
 link text (by dom, 2006-05-26)
         var aHasSelection = ( aLinks.length > 0 ) ;
         if ( !aHasSelection )
         {
                 sInnerHtml = sUri;

                 var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$")
 ;
                 var asLinkPath = oLinkPathRegEx.exec( sUri ) ;
                 if (asLinkPath != null)
                         sInnerHtml = asLinkPath[1];  // use matched path

                 // Create a new (empty) anchor.
                 aLinks = [ oEditor.FCK.InsertElement( 'a' ) ] ;
         }

         oEditor.FCKUndo.SaveUndoStep() ;

         for ( var i = 0 ; i < aLinks.length ; i++ )
         {
                 oLink = aLinks[i] ;

                 if ( aHasSelection )
                         sInnerHtml = oLink.innerHTML ;          // Save
 the innerHTML (IE changes it if it is like an URL).

                 oLink.href = sUri ;
                 SetAttribute( oLink, '_fcksavedurl', sUri ) ;

                 oLink.innerHTML = sInnerHtml ;          // Set (or
 restore) the innerHTML

         }

         // Select the (first) link.
         //oEditor.FCKSelection.SelectNode( aLinks[0] );

         return true ;

 }

 //////////////////////
 var searchTimer ;

 //#### Called while the user types the URL.
 function OnUrlChange()
 {
         var link =GetE('txtUrl').value.Trim();
 ShowFilteredCategories(link);
 return;
         if ( searchTimer )
                 window.clearTimeout( searchTimer ) ;

         if ( link.StartsWith( '#' ) )
         {
                 SetSearchMessage( 'anchor link... no search for it' ) ;
                 return ;
         }

         if ( link.StartsWith( 'mailto:' ) )
         {
                 SetSearchMessage( 'e-mail link... no search for it' ) ;
                 return ;
         }

         if( /^\w+:\/\//.test( link ) )
         {
                 SetSearchMessage( 'external link... no search for it' ) ;
                 return ;
         }

         /*if ( link.length < 3  )
         {
                 ClearSearch() ;

                 if ( link.length == 0 )
                         SetSearchMessage( 'start typing in the above
 field' ) ;
                 else
                         SetSearchMessage( 'too short... type more' ) ;
                 return ;
         }
         */
         SetSearchMessage( 'stop typing to search' ) ;
         //searchTimer = window.setTimeout( StartSearch, 500 ) ;
 }

 function SetSearchMessage( message )
 {
         GetE('xWikiSearchStatus').innerHTML = message ;
 }







         </script>
 </head>
 <body scroll="no" style="overflow: hidden">
         <div id="divInfo">
                 <div id="divLinkTypeUrl">
                         <span>Selected categories</span><br />
                         <select id="xCategories" size="10" style="width:
 100%; height:70px"  ondblclick="SelectCategory( this.value,-1);">
                         </select><br />
                         Search category<br />
                         <input id="txtUrl" style="width: 80%" type="text"
 onkeyup="OnUrlChange();" />
                         <input id="btnNew" style="width: 18%"
 type="button" onclick="AddNew();" value="Add new"/>
                         <br />
                         Category tree (<span id="xWikiSearchStatus">start
 typing in the above field</span>)<br />
                         <select id="xWikiResults" size="10" style="width:
 100%; height:300px" onclick="ShowCategoriesSubTree( this.value );"
 ondblclick="SelectCategory('', this.value );">
                         </select>
                 </div>
         </div>
 </body>
 </html>

 }}}

 Also you need to enable this new command. One way to do it is to add

 {{{
 tbButton = new FCKToolbarButton( 'Category', 'Categories', 'Insert/Edit
 categories' ) ;
 tbButton.IconPath = FCKConfig.PluginsPath +
 'mediawiki/images/tb_icon_category.gif' ;
 FCKToolbarItems.RegisterItem( 'Category', tbButton ) ;
 }}}
 after

 {{{
 tbButton = new FCKToolbarButton( 'MW_Special', 'Special Tag', 'Insert/Edit
 Special Tag' ) ;
 tbButton.IconPath = FCKConfig.PluginsPath +
 'mediawiki/images/tb_icon_special.gif' ;
 FCKToolbarItems.RegisterItem( 'MW_Special', tbButton ) ;
 }}}
 and add

 {{{
 FCKCommands.RegisterCommand( 'Category', new FCKDialogCommand( 'Category',
 'Категории', FCKConfig.PluginsPath + 'mediawiki/dialogs/category.html',
 400, 500 ) ) ;
 }}}


 after
 {{{
 FCKCommands.RegisterCommand( 'Link', new FCKDialogCommand( 'Link',
 FCKLang.DlgLnkWindowTitle, FCKConfig.PluginsPath +
 'mediawiki/dialogs/link.html', 400, 250 ) ) ;
 }}}

 in extensions\FCKeditor\plugins\mediawiki\fckplugin.js

 Also you need to create tb_icon_special.gif.

 I'm new here. It's my first patch. Please correct the code above if it is
 not fit to coding standarts.

-- 
Ticket URL: <http://dev.fckeditor.net/ticket/1410#comment:5>
FCKeditor <http://www.fckeditor.net/>
The text editor for Internet
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
FCKeditor-Trac mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fckeditor-trac

Reply via email to