Merge pull request #6352 from opf/feature/wysiwyg/tables

Allow wysiwyg tables to exist with and without header

[ci skip]
pull/6332/head
Oliver Günther 7 years ago committed by GitHub
commit e246a0bdef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/assets/javascripts/vendor/ckeditor/ckeditor.js
  2. 6
      app/views/wiki/edit.html.erb
  3. 8
      app/views/wiki/new.html.erb
  4. 5
      lib/open_project/text_formatting/formatters/markdown/helper.rb
  5. 146
      spec/features/wysiwyg/tables_spec.rb
  6. 40
      spec/support/components/wysiwyg/wysiwyg_editor.rb

File diff suppressed because one or more lines are too long

@ -33,7 +33,11 @@ See docs/COPYRIGHT.rdoc for more details.
<%= error_messages_for 'content' %>
<div class="attributes-group">
<%= f.text_area :text, cols: 100, rows: 25, class: 'wiki-edit op-auto-complete', accesskey: accesskey(:edit) %>
<%= f.text_area :text,
cols: 100,
rows: 25,
class: 'wiki-edit op-auto-complete',
accesskey: accesskey(:edit) %>
<%= wikitoolbar_for 'content_text' %>
</div>

@ -61,7 +61,12 @@ See docs/COPYRIGHT.rdoc for more details.
<h3 class="attributes-group--header-text"><%= WikiPage.human_attribute_name(:text) %></h3>
</div>
</div>
<%= f.text_area :text, :cols => 100, :rows => 25, :class => 'wiki-edit op-auto-complete', :accesskey => accesskey(:edit) %>
<%= f.text_area :text,
cols: 100,
rows: 25,
class: 'wiki-edit op-auto-complete',
accesskey: accesskey(:edit) %>
<%= wikitoolbar_for 'content_text' %>
</div>
<div class="form--field">
@ -74,7 +79,6 @@ See docs/COPYRIGHT.rdoc for more details.
<%= f.button t(:button_save), class: 'button -highlight -with-icon icon-checkmark' %>
<%= preview_link preview_project_wiki_index_path(@project), 'wiki_form-preview' %>
<%= wikitoolbar_for 'content_text' %>
<% end %>
<div id="preview"></div>

@ -64,6 +64,11 @@ module OpenProject::TextFormatting::Formatters
private
def wysiwyg_for(field_id)
# Hide the original textarea
view_context.content_for(:additional_js_dom_ready) do
"document.getElementById('#{field_id}').style.display = 'none';".html_safe
end
view_context.content_tag 'op-ckeditor-form', '', 'textarea-selector': "##{field_id}"
end

@ -0,0 +1,146 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2017 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe 'Wysiwyg tables',
with_settings: { text_formatting: 'markdown', use_wysiwyg?: true },
type: :feature, js: true do
let(:user) { FactoryBot.create :admin }
let(:project) { FactoryBot.create(:project, enabled_module_names: %w[wiki]) }
let(:editor) { ::Components::WysiwygEditor.new }
before do
login_as(user)
end
describe 'in wikis' do
describe 'creating a wiki page' do
before do
visit project_wiki_path(project, :wiki)
end
it 'can add tables without headers' do
editor.in_editor do |container, editable|
# strangely, we need visible: :all here
container.find('.ck-button', visible: :all, text: 'Insert table').click
# Edit table
tds = editable.all('table.ck-widget td')
values = %w(h1 h2 c1 c2)
expect(tds.length).to eq(4)
tds.each_with_index do |td, i|
td.click
td.send_keys values[i]
sleep 0.5
end
end
# Save wiki page
click_on 'Save'
expect(page).to have_selector('.flash.notice')
within('#content') do
expect(page).to have_selector('table td', text: 'h1')
expect(page).to have_selector('table td', text: 'h2')
expect(page).to have_selector('table td', text: 'c1')
expect(page).to have_selector('table td', text: 'c2')
end
end
end
describe 'editing a wiki page with tables' do
let(:wiki_page) {
page = FactoryBot.build :wiki_page_with_content,
title: 'Wiki page with titles'
page.content.text = <<~EOS
## This is markdown!
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<td> c1 </td>
<td> c2 </td>
</tr>
<tr>
<td> c3 </td>
<td> c4 </td>
</tr>
</tbody>
</table>
EOS
page
}
before do
project.wiki.pages << wiki_page
project.wiki.save!
visit project_wiki_path(project, wiki_page.slug)
end
it 'can show the table with header' do
within('#content') do
expect(page).to have_selector('h2', text: 'This is markdown')
expect(page).to have_selector('table thead th', text: 'A')
expect(page).to have_selector('table thead th', text: 'B')
expect(page).to have_selector('table td', text: 'c1')
expect(page).to have_selector('table td', text: 'c2')
expect(page).to have_selector('table td', text: 'c3')
expect(page).to have_selector('table td', text: 'c4')
end
# Edit the table
click_on 'Edit'
# Expect wysiwyg to render table
editor.in_editor do |_, editable|
expect(editable).to have_selector('h2', text: 'This is markdown')
expect(editable).to have_selector('table thead th', text: 'A')
expect(editable).to have_selector('table thead th', text: 'B')
expect(editable).to have_selector('table td', text: 'c1')
expect(editable).to have_selector('table td', text: 'c2')
expect(editable).to have_selector('table td', text: 'c3')
expect(editable).to have_selector('table td', text: 'c4')
end
end
end
end
end

@ -0,0 +1,40 @@
module Components
class WysiwygEditor
include Capybara::DSL
attr_reader :context_selector
def initialize(context = '#content')
@context_selector = context
end
def container
page.find("#{context_selector} .op-ckeditor--wrapper")
end
def editor_element
page.find "#{context_selector} #{input_selector}"
end
def in_editor
yield container, editor_element
end
def input_selector
'div.ck-content'
end
def expect_value(value)
expect(input_element.text).to eq(value)
end
def click_and_type_slowly(text)
sleep 0.5
input_element.click
sleep 0.5
input_element.send_keys text
sleep 0.5
end
end
end
Loading…
Cancel
Save