From ead16f1f100224e7b6c629636f98b2f63ecc6d0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 23 Apr 2020 16:37:03 +0200
Subject: [PATCH] assets: use assets views instead of ckeditor browser (#40249)

---
 .../combo/manager_assets_browse.html          | 72 +++++++++++++++++++
 .../combo/manager_assets_fragment.html        |  8 ++-
 combo/apps/assets/views.py                    | 16 ++++-
 combo/manager/static/js/combo.manager.js      | 23 ++++--
 combo/manager/urls.py                         |  3 +-
 tests/test_manager.py                         | 44 ++++++++++++
 6 files changed, 157 insertions(+), 9 deletions(-)
 create mode 100644 combo/apps/assets/templates/combo/manager_assets_browse.html

diff --git a/combo/apps/assets/templates/combo/manager_assets_browse.html b/combo/apps/assets/templates/combo/manager_assets_browse.html
new file mode 100644
index 0000000..6a8746d
--- /dev/null
+++ b/combo/apps/assets/templates/combo/manager_assets_browse.html
@@ -0,0 +1,72 @@
+{% extends "gadjo/base.html" %}
+{% load staticfiles i18n %}
+
+{% block css %}
+<link rel="stylesheet" type="text/css" media="all" href="{{ STATIC_URL }}css/combo.manager.css"/>
+{% endblock %}
+
+{% block extrascripts %}
+<script src="{% static "js/combo.manager.js" %}"></script>
+{% endblock %}
+
+{% block user-links %}{% endblock %}
+{% block sidepage %}{% endblock %}
+{% block site-header %}{% endblock %}
+{% block footer %}{% endblock %}
+
+{% block appbar %}
+<h2>{% trans "Browse for the file you want, then click 'Embed File' to continue..." %}</h2>
+{% endblock %}
+
+{% block content %}
+
+{% if not object_list and not query %}
+<div class="big-msg-info">
+  {% trans "No files found. Upload files using the 'Image Button' or 'Link Button' dialog's 'Upload' tab." %}
+</div>
+
+{% else %}
+
+<form>
+  {% for k, v in request.GET.items %}
+    {% if k != 'q' %}<input type="hidden" name="{{ k }}" value="{{ v }}" />{% endif %}
+  {% endfor %}
+  <p><input name="q" type="search" value="{{query}}"> <button>{% trans 'Search' %}</button>
+  <span class="help_text">{% trans "(case insensitive search over filenames)" %}</span>
+  </p>
+</form>
+
+<div id="assets-browser" class="assets-ckeditor">
+  <div id="assets-listing">
+    {% with asset_for_ckeditor=True %}
+    {% include "combo/manager_assets_fragment.html" %}
+    {% endwith %}
+  </div>
+  <div id="asset-preview"></div>
+</div>
+<input href="" id="asset-ckeditor-embed" type="submit" name="_embed" value="{% trans "Embed File" %}" disabled />
+
+{% include "gadjo/pagination.html" %}
+
+{% endif %}
+<script type="text/javascript">
+    // helper functions
+    function getUrlParam(paramName) {
+        var reParam = new RegExp('(?:[\?&]|&amp;)' + paramName + '=([^&]+)', 'i') ;
+        var match = window.location.search.match(reParam) ;
+
+        return (match && match.length > 1) ? match[1] : '' ;
+    }
+
+    // embedder
+    $(document).on('click', '#asset-ckeditor-embed', function() {
+        var funcNum = getUrlParam('CKEditorFuncNum');
+        var fileUrl = $(this).attr('href');
+        console.log(funcNum)
+        console.log(fileUrl)
+        window.opener.CKEDITOR.tools.callFunction(funcNum, fileUrl);
+        window.close();
+    });
+    console.log(window.opener.CKEDITOR)
+</script>
+{% endblock %}
diff --git a/combo/apps/assets/templates/combo/manager_assets_fragment.html b/combo/apps/assets/templates/combo/manager_assets_fragment.html
index ccb9661..7485e3c 100644
--- a/combo/apps/assets/templates/combo/manager_assets_fragment.html
+++ b/combo/apps/assets/templates/combo/manager_assets_fragment.html
@@ -5,15 +5,18 @@
       <th>{% trans "Name" %}</th>
       <th>{% trans "Size" %}</th>
       <th></th>
+      {% if not asset_for_ckeditor %}
       <th></th>
+      {% endif %}
     </tr>
   </thead>
   <tbody>
     {% for asset in object_list %}
-    <tr class="{{ asset.css_classes }}">
-      <td><a href="{{ asset.src }}">{{ asset.name }}</a></td>
+    <tr class="{{ asset.css_classes }}" data-href="{{ asset.src }}">
+      <td>{% if not asset_for_ckeditor %}<a href="{{ asset.src }}">{{ asset.name }}</a>{% else %}{{ asset.name }}{% endif %}</td>
       <td>{% if asset.size %}{{ asset.size|filesizeformat }}{% else %}-{% endif %}</td>
       <td class="image">{% if asset.is_image %}<img data-href="{{ asset.src }}" src="{{ asset.thumb }}"/>{% endif %}</td>
+      {% if not asset_for_ckeditor %}
       <td class="actions">
         {% if asset.key %}{# theme asset #}
         <a href="{% url 'combo-manager-slot-asset-upload' key=asset.key %}{% if cell_reference %}?cell_reference={{ cell_reference }}{% endif %}"
@@ -29,6 +32,7 @@
            class="delete" rel="popup">{% trans 'Delete' %}</a>
         {% endif %}
       </td>
+      {% endif %}
     </tr>
     {% endfor %}
   </tbody>
diff --git a/combo/apps/assets/views.py b/combo/apps/assets/views.py
index 7e036a7..ced6fa6 100644
--- a/combo/apps/assets/views.py
+++ b/combo/apps/assets/views.py
@@ -119,8 +119,11 @@ class Assets(ListView):
     template_name = 'combo/manager_assets.html'
     paginate_by = 10
 
+    def get_files(self):
+        return list(SlotAsset.get_assets()) + CkEditorAsset.get_assets(self.request)
+
     def get_queryset(self):
-        files = list(SlotAsset.get_assets()) + CkEditorAsset.get_assets(self.request)
+        files = self.get_files()
         q = self.request.GET.get('q')
         if q:
             files = [x for x in files if q.lower() in x.name.lower()]
@@ -142,9 +145,20 @@ class Assets(ListView):
             return url + '?page=%s' % ((i // self.paginate_by) + 1)
         return url
 
+
 assets = Assets.as_view()
 
 
+class AssetsBrowse(Assets):
+    template_name = 'combo/manager_assets_browse.html'
+
+    def get_files(self):
+        return CkEditorAsset.get_assets(self.request)
+
+
+browse = AssetsBrowse.as_view()
+
+
 class AssetUpload(FormView):
     form_class = AssetUploadForm
     template_name = 'combo/manager_asset_upload.html'
diff --git a/combo/manager/static/js/combo.manager.js b/combo/manager/static/js/combo.manager.js
index 9f60305..7dfd86f 100644
--- a/combo/manager/static/js/combo.manager.js
+++ b/combo/manager/static/js/combo.manager.js
@@ -284,17 +284,30 @@ $(function() {
       $(this).addClass('untoggled');
     }
   });
-  $('#assets-browser table tr').on('hover mouseenter', function() {
-    var $img = $(this).find('img');
+
+  function show_asset($elem) {
+    var $img = $elem.find('img');
     if ($img.data('href')) {
       $('#asset-preview').empty().append($('<img src="' + $img.data('href') + '"/>'));
     } else {
       $('#asset-preview').empty();
     }
     return true;
-  }).on('mouseleave', function() {
-    $('#asset-preview').empty();
-  });
+  }
+  if ($('#assets-browser.assets-ckeditor').length) {
+    $('#assets-browser table tr').on('click', function() {
+      $('#assets-browser table tr').removeClass('active');
+      $(this).addClass('active');
+      show_asset($(this));
+      $('#asset-ckeditor-embed').attr('href', $(this).data('href')).prop('disabled', false);
+    });
+  } else {
+    $('#assets-browser table tr').on('hover mouseenter', function() {
+      show_asset($(this));
+    }).on('mouseleave', function() {
+      $('#asset-preview').empty();
+    });
+  }
   $('.manager-add-new-cell a').on('click', function() {
     $(this).next().toggle();
     return false;
diff --git a/combo/manager/urls.py b/combo/manager/urls.py
index 9170658..efbb241 100644
--- a/combo/manager/urls.py
+++ b/combo/manager/urls.py
@@ -20,6 +20,7 @@ from django.views.decorators.cache import never_cache
 
 import ckeditor.views as ckeditor_views
 
+from combo.apps.assets import views as assets_views
 from .. import plugins
 from . import views
 
@@ -94,7 +95,7 @@ urlpatterns = [
             name='combo-manager-page-order'),
         url(r'^ckeditor/upload/', staff_member_required(ckeditor_views.upload),
             name='ckeditor_upload'),
-        url(r'^ckeditor/browse/', never_cache(staff_member_required(ckeditor_views.browse)),
+        url(r'^ckeditor/browse/', never_cache(staff_member_required(assets_views.browse)),
             name='ckeditor_browse'),
 ]
 
diff --git a/tests/test_manager.py b/tests/test_manager.py
index cf3a27d..25f98e1 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -1041,6 +1041,7 @@ def test_logout(app, admin_user):
     app.get('/logout/')
     assert app.get('/manage/', status=302).location.endswith('/login/?next=/manage/')
 
+
 def test_asset_management(app, admin_user):
     app = login(app)
     resp = app.get('/manage/assets/')
@@ -1099,6 +1100,7 @@ def test_asset_management(app, admin_user):
     resp = resp.form.submit().follow()
     assert 'have any asset yet.' in resp.text
 
+
 def test_asset_management_anchor(app, admin_user):
     app = login(app)
     resp = app.get('/manage/assets/')
@@ -1134,6 +1136,7 @@ def test_asset_management_anchor(app, admin_user):
     resp = resp.follow()
     assert 'test.png' not in resp.text
 
+
 def test_asset_management_search(app, admin_user):
     app = login(app)
 
@@ -1156,6 +1159,47 @@ def test_asset_management_search(app, admin_user):
     assert resp.text.count('<tr class="asset') == 2
 
 
+def test_assets_browse(app, admin_user):
+    app = login(app)
+
+    resp = app.get('/manage/ckeditor/browse/?CKEditor=foo&CKEditorFuncNum=0')
+    assert 'No files found' in resp.text
+
+    filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'aa.png')
+    pix = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
+    default_storage.save(filepath, BytesIO(base64.decodebytes(pix)))
+    filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'bb.pdf')
+    pix = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
+    default_storage.save(filepath, BytesIO(base64.decodebytes(pix)))
+    filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'cc.png')
+    pix = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
+    default_storage.save(filepath, BytesIO(base64.decodebytes(pix)))
+
+    resp = app.get('/manage/ckeditor/browse/?CKEditor=foo&CKEditorFuncNum=0')
+    assert 'No files found' not in resp.text
+
+    resp.form['q'] = 'test'
+    resp = resp.form.submit()
+    assert 'CKEditor=foo' in resp.request.url
+    assert 'CKEditorFuncNum=0' in resp.request.url
+    assert resp.text.count('<tr class="asset') == 0
+
+    resp.form['q'] = 'png'
+    resp = resp.form.submit()
+    assert 'CKEditor=foo' in resp.request.url
+    assert 'CKEditorFuncNum=0' in resp.request.url
+    assert resp.text.count('<tr class="asset') == 2
+
+    for i in range(25):
+        filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'cc.png')
+        pix = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
+        default_storage.save(filepath, BytesIO(base64.decodebytes(pix)))
+    resp = app.get('/manage/ckeditor/browse/?CKEditor=foo&CKEditorFuncNum=0')
+    resp = resp.click(href='.*page=2.*')
+    assert 'CKEditor=foo' in resp.request.url
+    assert 'CKEditorFuncNum=0' in resp.request.url
+
+
 def test_asset_slots_management(app, admin_user):
     app = login(app)
     assert Asset.objects.count() == 0
-- 
2.20.1

