FriendsOfTYPO3 / frontend_editing

TYPO3 CMS Frontend Editing
https://friendsoftypo3.github.io/frontend_editing/
102 stars 39 forks source link

Selecting exisiting image file results in JavaScript error (v2) #457

Closed mabolek closed 1 year ago

mabolek commented 3 years ago

If creating a Text & Image content element, you can upload an image directly, but if you want to select an existing image, it doesn't work.

image

TypeError: undefined is not an object (evaluating 'window.parent.document.list_frame.parent.document')

MattiasNilsson commented 3 years ago

The reason is because of the fact that window.parent.document.list_frame.parent can´t be found. Where list_frame is the actual iframe.

timhorstmann commented 3 years ago

I can reproduce this issue with TYPO3 v9.5.28 / frontend_editing v2.0.4 and TYPO3 v10.4.19 / frontend_editing v2.0.6. I open the edit overlay with the inline-editing icons. I can remove an image. if i want to add an image, a second overlay with the FAL tree appears. when selecting an image, nothing happens. error in console is

ElementBrowser.js?bust=1630047118:13 Uncaught TypeError: Cannot read property 'document' of undefined

The corresponding source code in ElementBrowser is

  ElementBrowser.getParent = function() {
    var opener = null;
    if (
      typeof window.parent !== 'undefined' &&
      typeof window.parent.document.list_frame !== 'undefined' &&
      window.parent.document.list_frame.parent.document.querySelector('.t3js-modal-iframe') !== null
    ) {
      opener = window.parent.document.list_frame;
    } else if (
      typeof window.parent !== 'undefined' &&
      typeof window.parent.frames.list_frame !== 'undefined' &&
      window.parent.frames.list_frame.parent.document.querySelector('.t3js-modal-iframe') !== null
    ) {
      opener = window.parent.frames.list_frame;
    } else if (
      typeof window.frames !== 'undefined' &&
      typeof window.frames.frameElement !== 'undefined' &&
      window.frames.frameElement !== null &&
      window.frames.frameElement.classList.contains('t3js-modal-iframe')
    ) {
      opener = window.frames.frameElement.contentWindow.parent;
    } else if (window.opener) {
      opener = window.opener;
    }
    return opener;
  };

Error happens in line 6 of my code excerpt.

NairCoder commented 2 years ago

The issue @timhorstmann raised is still existing in TYPO3 v9.5.31, frontend_editing v2.0.9.

MattiasNilsson commented 2 years ago

@NairCoder We are aware of this bug, it is just really hard to extend the JS file as we are using the built in modals. Any help are welcome :)

tomleiter commented 2 years ago

There is probably no solution here yet?

MattiasNilsson commented 2 years ago

There is probably no solution here yet?

No not yet @tomleiter. Hope to be able to focus on it in the near future. All help is welcome!

rbtwt commented 2 years ago

When will it be fixed? This makes the extension unusable for TYPO3 11.

mabolek commented 2 years ago

When will it be fixed? This makes the extension unusable for TYPO3 11.

Please, let's keep to the facts here: Except from this use case, the extension is still usable. 😄

As my colleague @MattiasNilsson mentioned, this is no easy bug to fix. We would be very thankful for help to solve this.

kryslin commented 1 year ago

The reason is because we have in html two iframes with name list_frame and window.parent.document.list_frame returns HTMLCollection. I wrote patch to fix it. Patch overrides two functions from core javascript:

FormEngineLinkBrowserAdapter.getParent()
ElementBrowser.getParent()
diff --git a/Resources/Public/JavaScript/ParentWindow.js b/Resources/Public/JavaScript/ParentWindow.js
new file mode 100644
--- /dev/null   (date 1679499080086)
+++ b/Resources/Public/JavaScript/ParentWindow.js   (date 1679499080086)
@@ -0,0 +1,26 @@
+define([
+  'TYPO3/CMS/Backend/FormEngineLinkBrowserAdapter',
+  'TYPO3/CMS/Recordlist/ElementBrowser'
+], function(FormEngineLinkBrowserAdapter, ElementBrowser) {
+  const FormEngineLinkBrowserAdapterParentFunction = FormEngineLinkBrowserAdapter.getParent
+  const getParent = () => {
+    if (
+      typeof window.parent !== 'undefined' &&
+      typeof window.parent.document.list_frame !== 'undefined' &&
+      window.parent.document.list_frame.length > 0 &&
+      window.parent.document.list_frame[window.parent.document.list_frame.length - 1].contentWindow.parent.document.querySelector('.t3js-modal-iframe') !== null
+    ) {
+      return window.parent.document.list_frame[window.parent.document.list_frame.length - 1].contentWindow
+    }
+    return null
+  }
+
+  FormEngineLinkBrowserAdapter.getParent = () => {
+    return getParent() || FormEngineLinkBrowserAdapterParentFunction()
+  }
+
+  ElementBrowser.getParent = () => {
+    ElementBrowser.opener = FormEngineLinkBrowserAdapter.getParent()
+    return ElementBrowser.opener;
+  }
+});
diff --git a/ext_localconf.php b/ext_localconf.php
--- a/ext_localconf.php (revision b9efab199cd25b7dc8d0c721ab1396b6449d7352)
+++ b/ext_localconf.php (date 1679499008835)
@@ -2,6 +2,11 @@

 defined('TYPO3') or die();

+if (TYPO3_MODE === "BE" )   {
+    $pageRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Page\PageRenderer::class);
+    $pageRenderer->loadRequireJsModule('TYPO3/CMS/FrontendEditing/ParentWindow');
+}
+
 // Extend the <core:contentEditable> viewhelper by the one from EXT:frontend_editing
 $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['core'][] = 'TYPO3\\CMS\\FrontendEditing\\ViewHelpers';

ParentWindow.patch

MattiasNilsson commented 1 year ago

@kryslin Thanks for the patch. A new release is now out that solves the issue: https://github.com/FriendsOfTYPO3/frontend_editing/releases/tag/3.0.33

mattnraines commented 1 year ago

Version 3.0.33 seems to break with a different error in Chrome / Edge because contentWindow is undefined. This patch appears to fix it.

@@ -4,13 +4,18 @@
   ], function(FormEngineLinkBrowserAdapter, ElementBrowser) {
     const FormEngineLinkBrowserAdapterParentFunction = FormEngineLinkBrowserAdapter.getParent;
     const getParent = () => {
+      // Accessing the frame using .contentWindow does not
+      // work in Chrome or Edge.
       if (
         typeof window.parent !== 'undefined' &&
         typeof window.parent.document.list_frame !== 'undefined' &&
-        window.parent.document.list_frame.length > 0 &&
-        window.parent.document.list_frame[window.parent.document.list_frame.length - 1].contentWindow.parent.document.querySelector('.t3js-modal-iframe') !== null
+        window.parent.document.list_frame.length > 0
       ) {
-        return window.parent.document.list_frame[window.parent.document.list_frame.length - 1].contentWindow;
+        var frame = window.parent.document.list_frame[window.parent.document.list_frame.length - 1];
+        frame = frame.contentWindow || frame;
+        if (frame.parent.document.querySelector('.t3js-modal-iframe') !== null) {
+            return frame;
+        }
       }
       return null;
     }
MattiasNilsson commented 1 year ago

@mattnraines A new release is out.

https://github.com/FriendsOfTYPO3/frontend_editing/releases/tag/3.0.34