Fixed bug #5994: IRRE - RTEhtmlarea is not show in child records if parent has no RTE
authorOliver Hader <oliver.hader@typo3.org>
Sun, 6 Jan 2008 10:46:27 +0000 (10:46 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Sun, 6 Jan 2008 10:46:27 +0000 (10:46 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@2866 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_tceforms_inline.php
t3lib/jsfunc.inline.js
typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php

index 68d0f47..3fe2f40 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2007-01-06  Oliver Hader  <oh@inpublica.de>
+
+       * Fixed bug #5994: IRRE - RTEhtmlarea is not show in child records if parent has no RTE
+
 2008-01-06  Stanislas Rolland  <stanislas.rolland@fructifor.ca>
 
        * Feature/Cleanup: Acronym plugin of htmlArea RTE using new plugin API and enabled in IE7
index 932b449..75574dd 100755 (executable)
@@ -87,6 +87,9 @@
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
+
+require_once(PATH_t3lib.'class.t3lib_parsehtml.php');
+
 class t3lib_TCEforms_inline {
 
        /**
@@ -923,7 +926,11 @@ class t3lib_TCEforms_inline {
                        );
                }
 
-                       // add the JavaScript data that would have been added at the bottom of a regular TCEforms calls
+                       // Add data that would have been added at the top of a regular TCEforms call:
+               if ($headTags = $this->getHeadTags()) {
+                       $jsonArray['headData'] = $headTags;
+               }
+                       // Add the JavaScript data that would have been added at the bottom of a regular TCEforms call:
                $jsonArray['scriptCall'][] = $this->fObj->JSbottom($this->fObj->formName, true);
                        // if script.aculo.us Sortable is used, update the Observer to know the the record
                if ($config['appearance']['useSortable'])
@@ -1828,6 +1835,41 @@ class t3lib_TCEforms_inline {
                $margin = ($this->inlineStyles['margin-right']+1)*2;
                return $margin;
        }
+
+       /**
+        * Parses the HTML tags that would have been inserted to the <head> of a HTML document and returns the found tags as multidimensional array.
+        *
+        * @return      array           The parsed tags with their attributes and innerHTML parts
+        */
+       protected function getHeadTags() {
+               $headTags = array();
+               $headDataRaw = $this->fObj->JStop();
+
+               if ($headDataRaw) {
+                               // Create instance of the HTML parser:
+                       $parseObj = t3lib_div::makeInstance('t3lib_parsehtml');
+                               // Removes script wraps:
+                       $headDataRaw = str_replace(array('/*<![CDATA[*/', '/*]]>*/'), '', $headDataRaw);
+                               // Removes leading spaces of a multiline string:
+                       $headDataRaw = trim(preg_replace('/(^|\r|\n)( |\t)+/', '$1', $headDataRaw));
+                               // Get script and link tags:
+                       $tags = array_merge(
+                               $parseObj->getAllParts($parseObj->splitTags('link', $headDataRaw)),
+                               $parseObj->getAllParts($parseObj->splitIntoBlock('script', $headDataRaw))
+                       );
+
+                       foreach ($tags as $tagData) {
+                               $tagAttributes = $parseObj->get_tag_attributes($parseObj->getFirstTag($tagData), true);
+                               $headTags[] = array(
+                                       'name' => $parseObj->getFirstTagName($tagData),
+                                       'attributes' => $tagAttributes[0],
+                                       'innerHTML'     => $parseObj->removeFirstAndLastTag($tagData),
+                               );
+                       }
+               }
+
+               return $headTags;
+       }
 }
 
 
index 4c6942f..31637b1 100755 (executable)
@@ -33,6 +33,7 @@ var inline = {
        prependFormFieldNames: 'data',
        noTitleString: '[No title]',
        lockedAjaxMethod: {},
+       sourcesLoaded: {},
        data: {},
 
        addToDataArray: function(object) {
@@ -149,10 +150,81 @@ var inline = {
                inline.lockedAjaxMethod[method] = false;
        },
 
-       processAjaxResponse: function(method, xhr) {
-               inline.unlockAjaxMethod(method);
-               var json = eval('('+xhr.responseText+')');
-               for (var i in json.scriptCall) eval(json.scriptCall[i]);
+       processAjaxResponse: function(method, xhr, json) {
+               var addTag=null, restart=false, processedCount=0, element=null, errorCatch=[], sourcesWaiting=[];
+               if (!json && xhr) {
+                       json = eval('('+xhr.responseText+')');
+               }
+                       // If there are elements the should be added to the <HEAD> tag (e.g. for RTEhtmlarea):
+               if (json.headData) {
+                       var head = inline.getDomHeadTag();
+                       var headTags = inline.getDomHeadChildren(head);
+                       $A(json.headData).each(function(addTag) {
+                               if (!restart) {
+                                       if (addTag && (addTag.innerHTML || !inline.searchInDomTags(headTags, addTag))) {
+                                               if (addTag.name=='SCRIPT' && addTag.innerHTML && processedCount) {
+                                                       restart = true;
+                                                       return false;
+                                               } else {
+                                                       if (addTag.name=='SCRIPT' && addTag.innerHTML) {
+                                                               try {
+                                                                       eval(addTag.innerHTML);
+                                                               } catch(e) {
+                                                                       errorCatch.push(e);
+                                                               }
+                                                       } else {
+                                                               element = inline.createNewDomElement(addTag);
+                                                                       // Set onload handler for external JS scripts:
+                                                               if (addTag.name=='SCRIPT' && element.src) {
+                                                                       element.onload = inline.sourceLoadedHandler(element);
+                                                                       sourcesWaiting.push(element.src);
+                                                               }
+                                                               head.appendChild(element);
+                                                               processedCount++;
+                                                       }
+                                                       json.headData.shift();
+                                               }
+                                       }
+                               }
+                       });
+               }
+               if (restart || processedCount) {
+                       window.setTimeout(function() { inline.reprocessAjaxResponse(method, json, sourcesWaiting); }, 40);
+               } else {
+                       if (method) {
+                               inline.unlockAjaxMethod(method);
+                       }
+                       if (json.scriptCall && json.scriptCall.length) {
+                               $A(json.scriptCall).each(function(value) { eval(value); });
+                       }
+               }
+       },
+
+               // Check if dynamically added scripts are loaded and restart inline.processAjaxResponse():
+       reprocessAjaxResponse: function (method, json, sourcesWaiting) {
+               var sourcesLoaded = true;
+               if (sourcesWaiting && sourcesWaiting.length) {
+                       $A(sourcesWaiting).each(function(source) {
+                               if (!inline.sourcesLoaded[source]) {
+                                       sourcesLoaded = false;
+                                       return false;
+                               }
+                       });
+               }
+               if (sourcesLoaded) {
+                       $A(sourcesWaiting).each(function(source) {
+                               delete(inline.sourcesLoaded[source]);
+                       });
+                       window.setTimeout(function() { inline.processAjaxResponse(method, null, json); }, 80);
+               } else {
+                       window.setTimeout(function() { inline.reprocessAjaxResponse(method, json, sourcesWaiting); }, 40);
+               }
+       },
+
+       sourceLoadedHandler: function(element) {
+               if (element && element.src) {
+                       inline.sourcesLoaded[element.src] = true;
+               }
        },
 
        showAjaxFailure: function(method, xhr) {
@@ -273,6 +345,57 @@ var inline = {
                }
        },
 
+               // Get script and link elements from head tag:
+       getDomHeadChildren: function(head) {
+               var headTags=[];
+               $$('head script', 'head link').each(function(tag) { headTags.push(tag); });
+               return headTags;
+       },
+
+       getDomHeadTag: function() {
+               if (document && document.head) {
+                       return document.head;
+               } else {
+                       var head = $$('head');
+                       if (head.length) {
+                               return head[0];
+                       }
+               }
+               return false;
+       },
+
+               // Search whether elements exist in a given haystack:
+       searchInDomTags: function(haystack, needle) {
+               var result = false;
+               $A(haystack).each(function(element) {
+                       if (element.nodeName.toUpperCase()==needle.name) {
+                               var attributesCount = $H(needle.attributes).keys().length;
+                               var attributesFound = 0;
+                               $H(needle.attributes).each(function(attribute) {
+                                       if (element.getAttribute && element.getAttribute(attribute.key)==attribute.value) {
+                                               attributesFound++;
+                                       }
+                               });
+                               if (attributesFound==attributesCount) {
+                                       result = true;
+                                       return true;
+                               }
+                       }
+               });
+               return result;
+       },
+
+               // Create a new DOM element:
+       createNewDomElement: function(addTag) {
+               var element = document.createElement(addTag.name);
+               if (addTag.attributes) {
+                       $H(addTag.attributes).each(function(attribute) {
+                               element[attribute.key] = attribute.value;
+                       });
+               }
+               return element;
+       },
+
        changeSorting: function(objectId, direction) {
                var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 2);
                var objectPrefix = this.parseFormElementName('full', objectId, 0, 1);
index a1e89c1..aa2b5f1 100644 (file)
@@ -546,8 +546,10 @@ class tx_rtehtmlarea_base extends t3lib_rteapi {
                        }
                        
                                // Loading JavaScript files and code
-                       $this->TCEform->additionalCode_pre['loadJSfiles'] = $this->loadJSfiles($this->TCEform->RTEcounter);
-                       $this->TCEform->additionalJS_pre['loadJScode'] = $this->loadJScode($this->TCEform->RTEcounter);
+                       if ($this->TCEform->RTEcounter == 1) {
+                               $this->TCEform->additionalCode_pre['loadJSfiles'] = $this->loadJSfiles($this->TCEform->RTEcounter);
+                               $this->TCEform->additionalJS_pre['loadJScode'] = $this->loadJScode($this->TCEform->RTEcounter);
+                       }
 
                        /* =======================================
                         * DRAW THE EDITOR
@@ -854,13 +856,13 @@ class tx_rtehtmlarea_base extends t3lib_rteapi {
                $loadJavascriptCode = '
                <script type="text/javascript">
                /*<![CDATA[*/
-                       var i=1;
+                       i=1;
                        while (document.getElementById("pleasewait" + i)) {
                                document.getElementById("pleasewait" + i).style.display = "block";
                                document.getElementById("editorWrap" + i).style.visibility = "hidden";
                                i++;
                        };
-                       var RTEarea = new Array();
+                       RTEarea = new Array();
                        RTEarea[0] = new Object();
                        RTEarea[0]["version"] = "' . $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . '";
                        RTEarea[0]["popupwin"] = "' . $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/popupwin.js', "popupwin") . '";'
@@ -868,20 +870,20 @@ class tx_rtehtmlarea_base extends t3lib_rteapi {
                        RTEarea[0]["htmlarea-ie"] = "' . $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-ie.js', "htmlarea-ie") . '";')
                        : ('
                        RTEarea[0]["htmlarea-gecko"] = "' . $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-gecko.js', "htmlarea-gecko") . '";')) . '
-                       var _editor_url = "' . $this->extHttpPath . 'htmlarea";
-                       var _editor_lang = "' . $this->language . '";
-                       var _editor_CSS = "' . $this->editorCSS . '";
-                       var _editor_skin = "' . dirname($this->editorCSS) . '";
-                       var _editor_edited_content_CSS = "' .  $this->editedContentCSS  . '";
-                       var _typo3_host_url = "' . $this->hostURL . '";
-                       var _editor_debug_mode = ' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? 'true' : 'false') . ';
-                       var _editor_compressed_scripts = ' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? 'true' : 'false') . ';'
+                       _editor_url = "' . $this->extHttpPath . 'htmlarea";
+                       _editor_lang = "' . $this->language . '";
+                       _editor_CSS = "' . $this->editorCSS . '";
+                       _editor_skin = "' . dirname($this->editorCSS) . '";
+                       _editor_edited_content_CSS = "' .  $this->editedContentCSS  . '";
+                       _typo3_host_url = "' . $this->hostURL . '";
+                       _editor_debug_mode = ' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? 'true' : 'false') . ';
+                       _editor_compressed_scripts = ' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? 'true' : 'false') . ';'
                        . (($this->client['BROWSER'] == 'gecko') ? ('
-                       var _editor_mozAllowClipboard_url = "' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['mozAllowClipboardURL'] ? $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['mozAllowClipboardURL'] : '') . '";')
+                       _editor_mozAllowClipboard_url = "' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['mozAllowClipboardURL'] ? $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['mozAllowClipboardURL'] : '') . '";')
                        : '') . '
-                       var _spellChecker_lang = "' . $this->spellCheckerLanguage . '";
-                       var _spellChecker_charset = "' . $this->spellCheckerCharset . '";
-                       var _spellChecker_mode = "' . $this->spellCheckerMode . '";
+                       _spellChecker_lang = "' . $this->spellCheckerLanguage . '";
+                       _spellChecker_charset = "' . $this->spellCheckerCharset . '";
+                       _spellChecker_mode = "' . $this->spellCheckerMode . '";
                /*]]>*/
                </script>';
                $loadJavascriptCode .= '