Fix/update wysiwyg styles (#8844)
This is a refactoring of the CSS classes in the WYSIWYG editor. The classes now use proper BEM and are almost completely independent of other CSS. It also includes small style refactorings, like a reduction of heading size in attribute fields, and an increase in heading size in all other instances.
* Initial class definitions
* Added more classes
* Added Table of Contents basics
* CkEditor applying custom CSS classes to p, h1, h2, h3, h4, h5, h6, li and blockquote
* CKEditorInspector removed
* op css class for headings
* op css class for paragraphs
* op css class for code/code block
* adapt specs to altered markdown/html generation
* adapt grid/budget representers to altered signature
* op css class for lists
* op css class for toc
* op css class for links
* Start working on typography css
* op css class for tables
* Fixing more typography, trying out larger headers
* Applying custom classes to li, a, blockquote, figure, table, tr, td, th, image, codeblock, figcaption and macros
* adapt specs to altered link classes
* op css class for images
* apply user content container class throughout application
* CSS alignment custom classes applied to table
* op css class for task list checkbox
* Added task checkbox class
* amend list checkbox class in backend
* op css class for table thead element
* adapt specs on image html generation
* Updated table and typography styles
* Update typography and figure styles
* Figure overflow handling
* Table alignment styles + ckEditor styles removed
* rename wiki-anchor to op-uc-link_permalink
* wrap table in div as well as figure
* Updated code-block
* Update permalinks
* Fixed a lot about tables
* Removed Description header from work-packages page
* Fix frontend styles
* Add placeholder styling, fix toc
* Fixed figure print
* working with table aligns
* Custom class add to task lists
* Custom classes applied to theads
* op-uc-container custom class added to container
* Codeblocks inside pre elements
* Fix: single <code> and <a> tags
* explicitly require overwritten gem class
Apparently, the gem is not loaded yet when it is registered as a filter when in eager loading mode
* adapt spec expectation to altered toc rendering
* CkInspector removed
* Latest ckeditor changes
* remove highlight css class from wiki content
* allow html pipleline to handle macros with additional classes
* Fixed a lot of print css for tables
* Add general print css back in
* Update Table of Contents styling
* Custom classes on ul, ol, li and task-lists
* Revert "Custom classes on ul, ol, li and task-lists"
This reverts commit 0d27d28137
.
* Custom classes on ul, ol, li and task-lists
* Custom classes on column's th
* remove placeholder class when rendering
* WOrking on task lists
* Changing task-list classes, changed tests
* Updated list styles
* Remove unused todo list styles
* remove checked in binstubs
* Fix table of contents
* adapt todo list handing in backend pipeline
* adapt specs to altered css classes
* Add numbers to table of contents
* Better comments in table of contents
* Fix: wrap single <table> with a <figure>
* Fixes to todo list design
* Updated todo list scss to fix nested lists
* adapt selectors in table spec
* Update table styles
* Improve table borders more
* Custom classes specs
* Fix: no need to remove regular list classes when its type changes
* Add modifier for inline headings
* Update table editing styles
* Remove break-word tests
* wrap images just like tables
* Update figure content styles
* Fix: All tests passing (ul.op-uc-list_task-list)
* div.op-uc-figure--content wrapping tables
* Specs for figures wrappers div.op-uc-figure--content
* Fix: add custom classes to links and codes again
* Table wrapper div reverted + specs
* Fix inline palceholders
* Custom macro type classes
* Add basic macro placeholder changes
* Move heading permalink after text
* Fix word-break spec
* Sending figure styles to the backend (width)
* extend test to take ckeditor placeholder into account
* avoid adding bem classes multiple times
* attempt to fix flickering spec
* Removing image spinner when uploading finishes
* adapt spec expectations
Co-authored-by: Aleix Suau <info@macrofonoestudio.es>
Co-authored-by: ulferts <jens.ulferts@googlemail.com>
pull/8867/head
parent
8688e3a34d
commit
e848d44dea
@ -1,5 +1,5 @@ |
||||
<h3 class="widget-box--header"> |
||||
<div class="widget-box--header"> |
||||
<div class="widget-box--header-title title-container"> |
||||
<h2 class="editable-toolbar-title--fixed"><%= title %></h2> |
||||
</div> |
||||
</h3> |
||||
</div> |
||||
|
@ -1,5 +1,5 @@ |
||||
<%= render 'homescreen/blocks/header', title: Setting.welcome_title.presence || organization_name %> |
||||
|
||||
<div class="wiki"> |
||||
<div class="wiki op-uc-container"> |
||||
<%= format_text(Setting.welcome_text, headings: false) %> |
||||
</div> |
||||
|
@ -1,186 +0,0 @@ |
||||
//-- copyright |
||||
// OpenProject is an open source project management software. |
||||
// Copyright (C) 2012-2020 the OpenProject GmbH |
||||
// |
||||
// 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. |
||||
//++ |
||||
|
||||
div.wiki |
||||
// ------------------- FONT ------------------- |
||||
|
||||
font-size: var(--wiki-default-font-size) |
||||
|
||||
h1 |
||||
font-size: calc(var(--wiki-default-font-size) * 1.75) |
||||
h2 |
||||
font-size: calc(var(--wiki-default-font-size) * 1.75 * 0.8) |
||||
h3 |
||||
font-size: calc(var(--wiki-default-font-size) * 1.75 * 0.7) |
||||
h4 |
||||
font-size: calc(var(--wiki-default-font-size) * 1.75 * 0.6) |
||||
h5 |
||||
font-size: calc(var(--wiki-default-font-size) * 1.75 * 0.5) |
||||
|
||||
h1, h2, h3, h4, h5 |
||||
margin: 1em 0 |
||||
line-height: 1.5 |
||||
font-weight: bold |
||||
color: #555555 |
||||
text-transform: none |
||||
border-bottom: 1px dotted #bbbbbb |
||||
|
||||
h1, h2 |
||||
border-bottom-style: solid |
||||
|
||||
|
||||
// ------------------- TABLES ------------------- |
||||
table:not(.work-package-table) |
||||
border: 1px solid #bbb |
||||
border-collapse: collapse |
||||
margin-bottom: 1em |
||||
|
||||
td, th |
||||
border: 1px solid #bbb |
||||
text-align: left |
||||
|
||||
ul, ol |
||||
margin-bottom: 0 |
||||
|
||||
th |
||||
background: rgba(0, 0, 0, 0.05) |
||||
padding: 10px |
||||
|
||||
// ------------------- LISTINGS ------------------- |
||||
ul.toc |
||||
margin-bottom: 12px |
||||
margin-right: 12px |
||||
margin-left: 0 |
||||
display: table |
||||
font-size: var(--wiki-toc-ul-font-size) |
||||
|
||||
.section-nav |
||||
margin-bottom: 0 |
||||
margin-left: 12px |
||||
&.right |
||||
float: right |
||||
margin-left: 12px |
||||
margin-right: 0 |
||||
width: auto |
||||
&.left |
||||
float: left |
||||
margin-right: 12px |
||||
margin-left: 0 |
||||
width: auto |
||||
a |
||||
font-weight: normal |
||||
background-repeat: no-repeat |
||||
background-position: 0% 60% |
||||
&.icon-context:before |
||||
padding: 3px 3px 0 0 |
||||
li |
||||
list-style-type: none |
||||
|
||||
ul li |
||||
word-wrap: break-word |
||||
|
||||
|
||||
// ------------------- GENERAL ------------------- |
||||
.external.icon-context:before |
||||
padding: 4px 4px 0 0 |
||||
|
||||
fieldset.collapsible legend |
||||
font-weight: bold |
||||
font-size: var(--wiki-toc-header-font-size) |
||||
img |
||||
vertical-align: middle |
||||
|
||||
a.wiki-anchor |
||||
display: none |
||||
text-decoration: none |
||||
font-size: 16px |
||||
vertical-align: middle |
||||
padding-right: 2px |
||||
|
||||
&:hover |
||||
color: #aaa !important |
||||
text-decoration: none |
||||
|
||||
h1:hover, h2:hover, h3:hover |
||||
a.wiki-anchor |
||||
display: inline |
||||
color: #ddd |
||||
|
||||
.wiki |
||||
p |
||||
margin-bottom: 1em |
||||
font-size: var(--wiki_default-font-size) |
||||
|
||||
.quick_info .label |
||||
background: none |
||||
color: #000 |
||||
font-weight: bold |
||||
font-size: var(--wiki-default-font-size) |
||||
|
||||
.wiki-title |
||||
@include text-shortener |
||||
max-width: 100% |
||||
|
||||
.wiki.wiki-content |
||||
overflow: auto |
||||
overflow-wrap: break-word |
||||
word-wrap: break-word |
||||
@include styled-scroll-bar |
||||
|
||||
.wiki--content--attribute |
||||
.form--field-container, |
||||
.form--text-area-container |
||||
max-width: 100% |
||||
|
||||
#wiki_page_parent_id |
||||
overflow: auto |
||||
|
||||
.toolbar-container ~ .wiki-content |
||||
margin-top: 0 |
||||
|
||||
.wiki-version--details |
||||
.navigate-left |
||||
margin: 0 1.5rem 0 0 |
||||
.navigate-right |
||||
margin: 0 0 0 1.5rem |
||||
span |
||||
vertical-align: middle |
||||
|
||||
body.controller-wiki |
||||
|
||||
.ck-content |
||||
min-height: 25vh |
||||
|
||||
#breadcrumb ul.breadcrumb li.first-breadcrumb-element a |
||||
display: inline |
||||
width: auto |
||||
|
||||
|
||||
@include breakpoint(680px down) |
||||
.toolbar-container ~ .wiki-content |
||||
margin-top: 0 |
@ -1,58 +0,0 @@ |
||||
// Specific styles for displaying rendered markdown on all pages |
||||
// This is still selected by div.wiki since this is still used throughout the app. |
||||
|
||||
div.wiki, |
||||
div.ck-editor__preview |
||||
|
||||
// Style pre tags alone |
||||
pre |
||||
margin: 1em 1em 1em 1.6em |
||||
padding: 2px 2px 2px 0 |
||||
background-color: #fafafa |
||||
border: 1px solid #dadada |
||||
width: auto |
||||
overflow-x: auto |
||||
overflow-y: hidden |
||||
|
||||
// Avoid doubling borders in pre > code |
||||
pre > code |
||||
display: block |
||||
border: none |
||||
background: transparent |
||||
color: initial |
||||
|
||||
ul.task-list |
||||
list-style: none |
||||
|
||||
.task-list-item |
||||
* |
||||
vertical-align: top |
||||
input |
||||
height: 25px |
||||
position: absolute |
||||
margin-left: -25px |
||||
|
||||
// Style tables within figure.table |
||||
figure.table |
||||
// Copy the display style of CKEDitors table figures |
||||
// this prevents cutting of the figure if float is involved |
||||
display: table |
||||
|
||||
// If a figure is present, it might set the width and height |
||||
// so we want to have the table at full width and height |
||||
> table |
||||
height: 100% |
||||
width: 100% |
||||
|
||||
.task-list-item |
||||
input |
||||
position: relative |
||||
margin-right: 5px |
||||
|
||||
// Ensure we break apart words in table cells that |
||||
// are restricted in width (OP#33524) |
||||
td[style*=";width:"], |
||||
td[style^="width:"], |
||||
th[style*=";width:"], |
||||
th[style^="width:"] |
||||
word-break: break-all |
@ -0,0 +1,45 @@ |
||||
.op-uc-figure |
||||
margin: 0 |
||||
display: flex |
||||
flex-direction: column |
||||
align-items: center |
||||
align-self: stretch |
||||
width: 100% |
||||
max-width: 100% |
||||
position: relative |
||||
|
||||
@include styled-scroll-bar |
||||
|
||||
@at-root .op-uc-container_editing & |
||||
max-height: unset |
||||
|
||||
@media print |
||||
display: block |
||||
max-height: unset |
||||
|
||||
&_align-end |
||||
float: right |
||||
width: auto |
||||
&_align-start |
||||
float: left |
||||
width: auto |
||||
&_align-center |
||||
// This is the current default behaviour, as ckeditor has no "don't align" option |
||||
|
||||
&--content |
||||
flex-basis: auto |
||||
flex-grow: 0 |
||||
flex-shrink: 1 |
||||
width: 100% |
||||
display: flex |
||||
justify-content: center |
||||
&--description |
||||
flex-basis: auto |
||||
flex-grow: 1 |
||||
flex-shrink: 0 |
||||
padding: 0.75rem |
||||
width: 100% |
||||
text-align: center |
||||
|
||||
&.table |
||||
display: flex !important |
@ -0,0 +1,3 @@ |
||||
.op-uc-image |
||||
max-width: 100%; |
||||
max-height: 100%; |
@ -0,0 +1,30 @@ |
||||
@import 'mixins' |
||||
@import 'typography' |
||||
@import 'figure' |
||||
@import 'image' |
||||
@import 'table' |
||||
@import 'list' |
||||
@import 'toc' |
||||
@import 'macros' |
||||
@import 'placeholder' |
||||
|
||||
.op-uc-container |
||||
--op-uc-heading-base: 3.5rem |
||||
--op-uc-heading-falloff: 0.7 |
||||
display: block |
||||
overflow: hidden |
||||
font-size: var(--wiki-default-font-size) |
||||
z-index: 0; |
||||
padding-bottom: 1rem; |
||||
// TODO: This becomes obsolete once border-box is the default |
||||
box-sizing: border-box |
||||
|
||||
@include user-content-children |
||||
|
||||
&_reduced-headings |
||||
--op-uc-heading-base: 1.5rem |
||||
--op-uc-heading-falloff: 0.9 |
||||
|
||||
&_no-permalinks *:hover .op-uc-link_permalink |
||||
display: none |
||||
|
@ -0,0 +1,27 @@ |
||||
.op-uc-list |
||||
page-break-inside: avoid |
||||
margin-left: 2rem |
||||
|
||||
&_task-list |
||||
list-style: none |
||||
&--task-checkbox |
||||
width: 1rem |
||||
height: 1rem |
||||
margin-left: -1.5rem |
||||
margin-right: 0.25rem |
||||
position: relative |
||||
top: 0.1rem |
||||
|
||||
|
||||
// The selectors below are needed because the CKEditor currently |
||||
// renders more nested tags than needed and its own classes |
||||
// TODO: Make these obsolete |
||||
&_task-list &--item |
||||
> span, |
||||
> label |
||||
display: inline |
||||
font: inherit |
||||
|
||||
&--item |
||||
@at-root .op-uc-container_editing #{&} input[type="checkbox"] |
||||
margin-top: -0.1rem |
@ -0,0 +1,3 @@ |
||||
.op-uc-embedded-table |
||||
clear: both |
||||
|
@ -0,0 +1,16 @@ |
||||
@mixin user-content-children |
||||
> * + * |
||||
margin-top: 1.5rem |
||||
|
||||
> .op-uc-h1 + *, |
||||
> .op-uc-h2 + *, |
||||
> .op-uc-h3 + *, |
||||
> .op-uc-h4 + *, |
||||
> .op-uc-h5 + * |
||||
margin-top: 0 |
||||
|
||||
|
||||
.op-uc-figure |
||||
&_align-start, |
||||
&_align-end |
||||
margin-bottom: 1rem |
@ -0,0 +1,7 @@ |
||||
.op-uc-placeholder |
||||
display: block |
||||
text-align: center |
||||
color: #6f6f6f |
||||
padding: 1rem |
||||
background-color: #fafafa |
||||
border: 1px solid #dadada |
@ -0,0 +1,36 @@ |
||||
.op-uc-table |
||||
break-inside: avoid |
||||
border-collapse: collapse |
||||
border-spacing: 0 |
||||
width: 100% |
||||
|
||||
@at-root .op-uc-container_editing & |
||||
border: 1px solid rgba(0, 0, 0, 0.1) |
||||
|
||||
&--row |
||||
&:not(:last-child) |
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1) |
||||
|
||||
@at-root .op-uc-container:not(.op-uc-container_editing) &:hover |
||||
background: rgba(26, 103, 163, 0.05) |
||||
|
||||
&--cell |
||||
text-align: left |
||||
padding: 0.75rem |
||||
word-break: break-all |
||||
|
||||
&:not(:last-child):not([colspan]) |
||||
border-right: 1px solid rgba(0, 0, 0, 0.1) |
||||
|
||||
@include user-content-children |
||||
|
||||
@at-root .op-uc-container_editing &:hover |
||||
background: rgba(26, 103, 163, 0.05) |
||||
|
||||
&_head |
||||
background: rgb(242, 242, 242) |
||||
background-clip: padding-box |
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1) |
||||
|
||||
&.ck-editor__editable_selected |
||||
background: rgba(26, 103, 163, 0.1) |
@ -0,0 +1,26 @@ |
||||
.op-uc-toc |
||||
break-inside: avoid |
||||
font-size: var(--wiki-toc-ul-font-size) |
||||
background-color: #fafafa |
||||
border: 1px solid #dadada |
||||
float: left |
||||
margin: 1rem 2rem 1rem 0rem |
||||
padding: 1.5rem 1.5rem 1.5rem 0rem |
||||
|
||||
&--list |
||||
padding-left: 1rem |
||||
margin: 0; |
||||
list-style: none |
||||
|
||||
&--list-item |
||||
padding: 0.1em 0 |
||||
|
||||
&--item-link |
||||
display: flex |
||||
|
||||
&--list-item-number |
||||
margin-right: 0.3rem |
||||
color: var(--body-font-color) |
||||
|
||||
&--list-item-title |
||||
margin-right: 0.3rem |
@ -0,0 +1,85 @@ |
||||
.op-uc-h1, |
||||
.op-uc-h2, |
||||
.op-uc-h3, |
||||
.op-uc-h4, |
||||
.op-uc-h5, |
||||
.op-uc-h6, |
||||
--falloff: var(--op-uc-heading-falloff) |
||||
color: inherit |
||||
line-height: 1.6em |
||||
text-transform: none |
||||
font-weight: bold |
||||
border-bottom: 0 |
||||
margin: 0 |
||||
padding: 0 |
||||
break-before: auto |
||||
break-after: avoid |
||||
break-inside: avoid |
||||
|
||||
&:hover .op-uc-link_permalink |
||||
display: inline-flex |
||||
|
||||
.op-uc-h1 |
||||
font-size: var(--op-uc-heading-base) |
||||
.op-uc-h2 |
||||
font-size: calc(var(--op-uc-heading-base) * var(--falloff)) |
||||
.op-uc-h3 |
||||
font-size: calc(var(--op-uc-heading-base) * var(--falloff) * var(--falloff)) |
||||
.op-uc-h4 |
||||
font-size: calc(var(--op-uc-heading-base) * var(--falloff) * var(--falloff) * var(--falloff)) |
||||
.op-uc-h5 |
||||
font-size: calc(var(--op-uc-heading-base) * var(--falloff) * var(--falloff) * var(--falloff) * var(--falloff)) |
||||
|
||||
.op-uc-p |
||||
font: inherit; |
||||
margin: 0 |
||||
line-height: 1.6em |
||||
color: inherit |
||||
|
||||
.op-uc-blockquote |
||||
display: block |
||||
margin: 0; |
||||
border-left: 3px solid #e0e0e0 |
||||
padding: 0.8rem 1.2rem 0 1.2rem |
||||
overflow: hidden |
||||
color: #6f6f6f |
||||
|
||||
@include user-content-children |
||||
|
||||
.op-uc-code-block |
||||
break-inside: avoid |
||||
display: block |
||||
margin: 0 |
||||
padding: 1rem |
||||
background-color: #fafafa |
||||
border: 1px solid #dadada |
||||
|
||||
.op-uc-code |
||||
font-family: Consolas, "Liberation Mono", Courier, monospace |
||||
font-weight: normal |
||||
color: #333739 |
||||
background-color: #fafafa |
||||
border: 1px solid #dadada |
||||
padding: 0.125em 0.3125em |
||||
break-inside: avoid |
||||
|
||||
.op-uc-link |
||||
color: var(--content-link-color) |
||||
font-size: 1em |
||||
|
||||
&:hover |
||||
color: var(--content-link-hover-active-color) |
||||
|
||||
&_permalink |
||||
display: none |
||||
text-decoration: none |
||||
align-items: center |
||||
color: #ccc |
||||
margin-left: 0.5em |
||||
|
||||
&::before |
||||
font-size: 1em |
||||
|
||||
&:hover |
||||
color: #aaa |
||||
text-decoration: none |
@ -0,0 +1,3 @@ |
||||
# User Content |
||||
|
||||
## |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,94 @@ |
||||
#-- encoding: UTF-8 |
||||
|
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||
# |
||||
# 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. |
||||
#++ |
||||
|
||||
module OpenProject::TextFormatting |
||||
module Filters |
||||
class BemCssFilter < HTML::Pipeline::Filter |
||||
BEM_CLASSES = { |
||||
h1: 'op-uc-h1', |
||||
h2: 'op-uc-h2', |
||||
h3: 'op-uc-h3', |
||||
h4: 'op-uc-h4', |
||||
h5: 'op-uc-h5', |
||||
h6: 'op-uc-h6', |
||||
p: 'op-uc-p', |
||||
blockquote: 'op-uc-blockquote', |
||||
code: 'op-uc-code', |
||||
pre: 'op-uc-code-block', |
||||
li: 'op-uc-list--item', |
||||
ul: 'op-uc-list', |
||||
ol: 'op-uc-list', |
||||
a: 'op-uc-link', |
||||
figure: 'op-uc-figure', |
||||
img: 'op-uc-image', |
||||
figcaption: 'op-uc-figure--description', |
||||
table: 'op-uc-table', |
||||
thead: 'op-uc-table--head', |
||||
tr: 'op-uc-table--row', |
||||
td: 'op-uc-table--cell', |
||||
th: 'op-uc-table--cell op-uc-table--cell_head' |
||||
}.with_indifferent_access.freeze |
||||
|
||||
# Contains all elements with their classes which should not be modified |
||||
# as they already have the correct BEM class. |
||||
UNMODIFIED = { |
||||
h1: 'op-uc-toc--title', |
||||
li: 'op-uc-toc--list-item', |
||||
ul: 'op-uc-toc--list' |
||||
}.with_indifferent_access.freeze |
||||
|
||||
def call |
||||
doc.search(*BEM_CLASSES.keys.map(&:to_s)).each do |element| |
||||
add_css_class(element, BEM_CLASSES[element.name]) unless not_to_be_modified?(element) |
||||
end |
||||
|
||||
doc |
||||
end |
||||
|
||||
private |
||||
|
||||
def not_to_be_modified?(element) |
||||
element['class'].present? && |
||||
UNMODIFIED[element.name] && |
||||
element['class'].include?(UNMODIFIED[element.name]) |
||||
end |
||||
|
||||
def add_css_class(element, css_class) |
||||
if element['class'].present? |
||||
# Avoid using element['class'].include?(css_class) as css_class can be a substring |
||||
# of an existing class |
||||
element['class'] += " #{css_class}" unless element['class'].split.any? { |existing_class| existing_class == css_class } |
||||
else |
||||
element['class'] = css_class |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,87 @@ |
||||
#-- encoding: UTF-8 |
||||
|
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||
# |
||||
# 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. |
||||
#++ |
||||
|
||||
module OpenProject::TextFormatting |
||||
module Filters |
||||
class FigureWrappedFilter < HTML::Pipeline::Filter |
||||
include ActionView::Context |
||||
include ActionView::Helpers::TagHelper |
||||
|
||||
def call |
||||
doc.search('table', 'img').each do |element| |
||||
case element.name |
||||
when 'img', 'table' |
||||
wrap_element(element) |
||||
else |
||||
# nothing |
||||
end |
||||
end |
||||
|
||||
doc |
||||
end |
||||
|
||||
private |
||||
|
||||
# Wrap img elements like this |
||||
# <figure> |
||||
# <div class="op-uc-figure--content"> |
||||
# <img></img> |
||||
# </div> |
||||
# <figure> |
||||
# |
||||
# and |
||||
# |
||||
# <figure> |
||||
# <div class="op-uc-figure--content"> |
||||
# <table></table> |
||||
# </div> |
||||
# <figure> |
||||
|
||||
# The figure and img/table element later on get css classes applied to them so it does |
||||
# not have to happen here. |
||||
def wrap_element(element) |
||||
wrap_in_div(element) |
||||
wrap_in_figure(element.parent) |
||||
end |
||||
|
||||
def wrap_in_figure(element) |
||||
element.wrap('<figure>') unless element.parent&.name == 'figure' |
||||
end |
||||
|
||||
def wrap_in_div(element) |
||||
element.wrap('<div>') unless element.parent&.name == 'div' |
||||
|
||||
div = element.parent |
||||
|
||||
div['class'] = 'op-uc-figure--content' |
||||
end |
||||
end |
||||
end |
||||
end |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue