Opened 12 years ago

Closed 9 years ago

#30 closed New Feature (duplicate)

Passing arrays to configuration without custom js file

Reported by: Alfonso Martínez de Lizarrondo Owned by:
Priority: Normal Milestone:
Component: General Version:
Keywords: Confirmed Cc:

Description

I plan to study this set of patches: https://sourceforge.net/tracker/index.php?func=detail&aid=1605345&group_id=75348&atid=543655
https://sourceforge.net/tracker/index.php?func=detail&aid=1504513&group_id=75348&atid=543655
https://sourceforge.net/tracker/index.php?func=detail&aid=1026583&group_id=75348&atid=543655
https://sourceforge.net/tracker/index.php?func=detail&aid=1026582&group_id=75348&atid=543655

so it's possible and documented how to define a custom toolbar without using a customconfig.js file but instead just specifying its contents at the moment the editor is created. This should allow also other kind of customizations in the future.

I'll work in a new branch were I'll apply other patches, I'll try to open tickets for each one .

This might be a fix to this bug: https://sourceforge.net/tracker/index.php?func=detail&aid=1613963&group_id=75348&atid=543653

Change History (19)

comment:1 Changed 12 years ago by Frederico Caldeira Knabben

A similar feature is something I've been thinking about for a long time. I was planning to have this one done "until" the 3.0.

I've thought about creating a string which can simply be evaluated (eval()) in the browser. Similar to JSON (http://www.json.org/), but without defining a single object, and making it possible to call functions.

For compatibility, we could also "mark" the new model, making it start with "#". And to make it more compact, we could (optionally) replace all entries of "FCKConfig." with "$.".

So, for example, the following custom settings:

FCKConfig.DefaultLanguage = 'fr' ;
FCKConfig.ContextMenu = ['Generic','Link','Anchor'] ;
FCKConfig.Plugins.Add( 'autogrow' ) ;
FCKConfig.AutoGrowMax = 400 ;
FCKConfig.FullPage = true ;

Could be sent from the user in the hidden config field as:

#$.DefaultLanguage='fr';$.ContextMenu=['Generic','Link','Anchor'];$.Plugins.Add('autogrow');$.AutoGrowMax=400;$.FullPage=true;

So, in the editor we simply execute the following and the job is done:

eval( hiddenValue.replace( /$\./g, 'FCKConfig.' ) ) ;

Actually the server side implementation would be able to do any kind of job using it, not only set FCKConfig entries. In this way, it will be up to the server implementation to make it more or less flexible to the end user to define the configurations.

comment:2 in reply to:  1 Changed 12 years ago by Alfonso Martínez de Lizarrondo

Replying to FredCK:

I've thought about creating a string which can simply be evaluated (eval()) in the browser. Similar to JSON (http://www.json.org/), but without defining a single object, and making it possible to call functions.

That's what I was thinking about, but I forgot about functions, although it's very interesting to also have the ability to load a plugin this way (I don't see right now other functions that could be called).

I think that that would require to create a special object to set the configuration so it has a fake .Plugins.Add() function that instead of executing the code it does add some code that will be later serializad to the same call.

Actually the server side implementation would be able to do any kind of job using it, not only set FCKConfig entries. In this way, it will be up to the server implementation to make it more or less flexible to the end user to define the configurations.

The problem is how to set up the server code so it does generate the proper string that later will be evaluated. Due to that I don't think that the server will have full control about what it can do, but it will be limited to just the set of elements that have been predefined that can be converted to a js string (maybe add also another way to directly pass js code as a string?)

I need to study all the code related to the config as I almost haven't touched it so far and I'm not sure about all the details, when I study it and check the proposed changes in those patches I'll have a better overview about what can be done.

comment:3 Changed 12 years ago by Frederico Caldeira Knabben

During the last weeks, I've been thinking about many aspects of the project. One of them was the current config system. I strongly believe we can improve it.

Do we want to work on a radical change of it for version 2.5? Are you interested on being the maintainer of it Alfonso?

If we decide to make this move, we can create a component in the components page called "Core: Config" and trace the specifications of it. I would trace a draft for the first specifications and then we could discuss over it.

Does it sound reasonable?

comment:4 Changed 12 years ago by Frederico Caldeira Knabben

Just a tip for the wiki formatting...

You don't need to do a [[BR]] at the end of each paragraph. Just place a blank line between then and you will have it in different <p>s.

Use [[BR]] only if you want to place text attached to a paragraph, right after it. It is useful when making references to URLs, like this sample:
http://tools.assembla.com/fckeditor/wiki/WikiFormatting

Actually, just use the method you fell more comfortable with ;)

comment:5 Changed 12 years ago by Alfonso Martínez de Lizarrondo

If the current system needs to be redone then I think that instead of working on improving this one we can start drafting the requirements and specifications about how it should work, and then if the changes are really that importat setup its own specific branch for it, and merge it when it's done and not sooner.

comment:7 Changed 12 years ago by Frederico Caldeira Knabben

Keywords: Config added
Milestone: FCKeditor 3.0
Summary: passing arrays to configuration without custom js filePassing arrays to configuration without custom js file

Ok... I've finally completed the first draft of the specifications:

wiki:Components/Configuration?

Improvements are welcome.

comment:8 Changed 12 years ago by Alfonso Martínez de Lizarrondo

#305 has been marked as dup of this bug.

comment:9 Changed 12 years ago by Thomas Tallyce

I am really glad this is being looked at, as configuration and upgrades will be much easier when the js config file need not be touched when instantiating via PHP.

Can I *strongly* request that the wiki:Components/Configuration? makes quite explicit in the specification that *all* settings should be possible to set via server-side calling, so that the js config need not be touched?

comment:10 Changed 12 years ago by Thomas Tallyce

Is there any scope for getting the connector config also set outside the FCKeditor tree as part of these changes? At present, one must drive through about 5 directories deep and make a change to a config file there, rather than setting via any server-side call.

I realise the connectors are effectively separate, but perhaps some way of adding a routing mechanism that passes things off to the connector, but with the requests going via the central point, might be one way to handle this perhaps?

comment:11 in reply to:  10 Changed 12 years ago by Alfonso Martínez de Lizarrondo

Replying to tallyce:

Is there any scope for getting the connector config also set outside the FCKeditor tree as part of these changes? At present, one must drive through about 5 directories deep and make a change to a config file there, rather than setting via any server-side call.

If I do the changes I'll focus just on the configuration of the editor, not the filebrowser as that is a different element.

comment:12 Changed 12 years ago by Frederico Caldeira Knabben

Keywords: Config removed

Check #304 when implementing it.

comment:14 Changed 12 years ago by Alfonso Martínez de Lizarrondo

The code from https://sourceforge.net/tracker/index.php?func=detail&aid=1026581&group_id=75348&atid=543655

On line 18 of your 'fck_startup.js' file, replace the second half of that line with the code below starting from the term "FCKConfig.LoadHiddenField = function()" to the end.

FCKConfig.LoadHiddenField = function()
{ 
	var oConfigField = window.parent.document.getElementById( FCK.Name + '___Config' ) ;
	if ( ! oConfigField ) return ; 

	var aCouples = oConfigField.value.split('&') ; 
	var gToolbar = ""; 
	var gToolrow = ""; 
	for ( var i = 0 ; i < aCouples.length ; i++ )
	{
		var aConfig = aCouples[i].split('=') ;
		var sConfigName = aConfig[0] ;
		var sConfigValue = aConfig[1] ;
		var gConfig = sConfigName.split('[') ;
		var gConfigName = gConfig[0] ;
		if ( gConfigName == "ToolbarSets" )
		{ 
		var gConfigTool = gConfig [1].substring( 0, ( gConfig [1].length - 1 ) ) ;
		var gConfigVal1 = gConfig [2].substring( 0, ( gConfig [2].length - 1 ) ) ;
		var gConfigVal2 = gConfig [3].substring( 0, ( gConfig [3].length - 1 ) ) ;
		if ( gToolbar == "" )
			gToolbar = "FCKConfig.ToolbarSets[\"" + gConfigTool + "\"] = ["; if ( gToolrow == "" )gToolbar += "[";
		else
			if ( gToolrow != gConfigVal1 )
				gToolbar += "],[";

		if ( gConfigVal2 == '0' )
			gToolbar += "'" + sConfigValue + "'";
		else 
			gToolbar += ",'" + sConfigValue + "'";

		gToolrow = gConfigVal1;
		}
		else 
			if ( sConfigValue == "true" )
				FCKConfig[sConfigName] = true ; 
			else 
				if ( sConfigValue == "false" )
					FCKConfig[sConfigName] = false ; 
				else 
					if ( ! isNaN(sConfigValue) )
						FCKConfig[sConfigName] = parseInt( sConfigValue ) ; 
					else 
						FCKConfig[sConfigName] = sConfigValue ;
	}
	if ( gToolbar != "" )
	{ 
		gToolbar += "]];"; 
		eval( gToolbar );
	}
}

fckeditor.php

<?php

class FCKeditor
{
################################
##  VARS
################################
	var $InstanceName   = 'defaultFCKeditor';
	var $Width          = '100%';
	var $Height         = '200';
	var $ToolbarSet     = 'Default';
	var $Value          = '' ;
	var $BasePath		= '/fckeditor/' ;
	var $CheckBrowser	= true ;
	var $Config ;
################################
##  CONSTRUCTOR
################################
	function FCKeditor ()
	{
				
	}
################################
##  METHODS
################################	
	function CreateFCKeditor( $instanceName = false, $width = false, $height = false )
	{
		echo $this->ReturnFCKeditor( $instanceName, $width, $height );
	}
	
	function ReturnFCKeditor( $instanceName = false, $width = false, $height = false )
	{
		$fck_value    = htmlspecialchars( $this->Value ) ;
		$fck_instance = ( $instanceName ) ? $instanceName : $this->InstanceName ;
		$fck_width    = ( $width ) ? $width : $this->Width ;
		$fck_height   = ( $height ) ? $height : $this->Height ;
		if ( !$this->CheckBrowser || $this->IsCompatible() )
		{
			$fck_basepath = $this->BasePath ;
			$fck_toolbar  = ( $this->ToolbarSet != '' ) ? $this->ToolbarSet : 'Default' ;
			$fck_config   = ( is_array( $this->Config ) ) ? $this->http_build_query( $this->Config ) : '' ;
			$fck_editor   = "<div class=\"fckeditor\">
	<input type=\"hidden\" id=\"$fck_instance\" name=\"$fck_instance\" value=\"$fck_value\">
	<input type=\"hidden\" id=\"{$fck_instance}___Config\" value=\"$fck_config\">
	<iframe id=\"{$fck_instance}___Frame\" src=\"{$fck_basepath}editor/fckeditor.html?InstanceName=$fck_instance&Toolbar=$fck_toolbar\" width=\"$fck_width\" height=\"$fck_height\" frameborder=\"no\" scrolling=\"no\"></iframe>
</div>\n";
		}
		else
		{
			if ( strpos( $fck_width, '%' ) != ( strlen( $fck_width ) - 1 ) )
				$fck_width = $fck_width.'px';
			if ( strpos( $fck_height, '%' ) != ( strlen( $fck_height ) - 1 ) )
				$fck_height = $fck_height.'px';
			$fck_editor   = "<div class=\"fckeditor\">
	<textarea name=\"$fck_instance\" rows=\"4\" cols=\"40\" style=\"width: $fck_width; height: $fck_height\" wrap=\"virtual\">$fck_value</textarea>
</div>\n";
		}
		
		return $fck_editor ;
	}
	
	function IsCompatible()
	{
		$sAgent = $_SERVER['HTTP_USER_AGENT'] ;
		if ( is_integer( strpos($sAgent, 'MSIE') ) && is_integer( strpos($sAgent, 'Windows') ) && !is_integer( strpos($sAgent, 'Opera') ) )
		{
			$iVersion = floatval( substr( $sAgent, strpos( $sAgent, 'MSIE' ) + 5, 3) ) ;
			return ( $iVersion >= floatval( 5.5 ) ) ;
		}
		elseif ( is_integer( strpos($sAgent, 'Gecko/') ) )
		{
			$iVersion = intval( substr( $sAgent, strpos( $sAgent, 'Gecko/' ) + 6, 8) ) ;
			return ( $iVersion >= intval( 20030210 ) ) ;
		}
		else
			return false;
	}
	
	function Config( $sent_config, $sent_value )
	{
		$this->Config[$sent_config] = $sent_value;
	}
	
	function http_build_query( &$a, $pref = '', $f = '', $idx = '')
	{//Altered code from a help article at http://us3.php.net/function.http-build-query
		$ret = '';
		foreach ( $a as $i => $j )
		{
			if ( $idx != '' )
				$i = $idx."[$i]";
			if ( is_array( $j ) )
				$ret .= $this->http_build_query( $j, '', $f, $i );
			else
			{
				$j = urlencode( $j );
				if ( is_int( $i ) )
					$ret .= "$f$pref$i=$j";
				else
					$ret .= "$f$i=$j";
			}
			$f = '&';
		}
		return $ret;
	}

}
?>

comment:15 Changed 11 years ago by Thomas Tallyce

For the sake of others wondering whether this issue is resolved in the major version 2.5 release:

  • Confirmed that setting of arrays in PHP is *not* fixed for 2.5
  • Confirmed that setting of a tab in PHP using $instance->FormatIndentator is *not* fixed for 2.5 (see #304)

comment:16 Changed 11 years ago by Alfonso Martínez de Lizarrondo

Owner: Alfonso Martínez de Lizarrondo deleted

comment:17 Changed 11 years ago by Wojciech Olchawa

Keywords: Confirmed added

comment:18 Changed 10 years ago by Frederico Caldeira Knabben

Milestone: CKEditor 3.0CKEditor 3.x

comment:19 Changed 9 years ago by Alfonso Martínez de Lizarrondo

Milestone: CKEditor 3.x
Resolution: duplicate
Status: newclosed

This feature already exists in the CKEditor 3 and can be tested with the PHP samples.

Dup of #2872

Note: See TracTickets for help on using tickets.
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy