Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
lazaronixon committed Jan 15, 2020
0 parents commit f51cc67
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Trix Extensions

A package of resources to make Trix more integrated with ActionText and provide more features like colors, dividers and headings.

![TrixExt Logo](https://nixo-etc.s3-sa-east-1.amazonaws.com/trixext.gif)
170 changes: 170 additions & 0 deletions app/javascript/richtext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import Trix from "trix"

addHeadingAttributes()
addForegroundColorAttributes()
addBackgroundColorAttributes()

addEventListener("trix-initialize", function (event) {
new RichText(event.target)
})

addEventListener("trix-action-invoke", function (event) {
if (event.actionName == "x-horizontal-rule") insertHorizontalRule()

function insertHorizontalRule() {
event.target.editor.insertAttachment(buildHorizontalRule())
}

function buildHorizontalRule() {
return new Trix.Attachment({ content: "<hr>", contentType: "vnd.rubyonrails.horizontal-rule.html" })
}
})

class RichText {
constructor(element) {
this.element = element

this.insertHeadingElements()
this.insertDividerElements()
this.insertColorElements()
}

insertHeadingElements() {
this.removeOriginalHeadingButton()
this.insertNewHeadingButton()
this.insertHeadingDialog()
}

removeOriginalHeadingButton() {
this.buttonGroupBlockTools.removeChild(this.originalHeadingButton)
}

insertNewHeadingButton() {
this.buttonGroupBlockTools.insertAdjacentHTML("afterbegin", this.headingButtonTemplate)
}

insertHeadingDialog() {
this.dialogsElement.insertAdjacentHTML("beforeend", this.dialogHeadingTemplate)
}

insertDividerElements() {
this.quoteButton.insertAdjacentHTML("afterend", this.horizontalButtonTemplate)
}

insertColorElements() {
this.insertColorButton()
this.insertDialogColor()
}

insertColorButton() {
this.buttonGroupTextTools.insertAdjacentHTML("beforeend", this.colorButtonTemplate)
}

insertDialogColor() {
this.dialogsElement.insertAdjacentHTML("beforeend", this.dialogColorTemplate)
}

get buttonGroupBlockTools() {
return this.toolbarElement.querySelector("[data-trix-button-group=block-tools]")
}

get buttonGroupTextTools() {
return this.toolbarElement.querySelector("[data-trix-button-group=text-tools]")
}

get dialogsElement() {
return this.toolbarElement.querySelector("[data-trix-dialogs]")
}

get originalHeadingButton() {
return this.toolbarElement.querySelector("[data-trix-attribute=heading1]")
}

get quoteButton() {
return this.toolbarElement.querySelector("[data-trix-attribute=quote]")
}

get toolbarElement() {
return this.element.toolbarElement
}

get horizontalButtonTemplate() {
return '<button type="button" class="trix-button trix-button--icon trix-button--icon-horizontal-rule" data-trix-action="x-horizontal-rule" tabindex="-1" title="Divider">Divider</button>'
}

get headingButtonTemplate() {
return '<button type="button" class="trix-button trix-button--icon trix-button--icon-heading-1" data-trix-action="x-heading" title="Heading" tabindex="-1">Heading</button>'
}

get colorButtonTemplate() {
return '<button type="button" class="trix-button trix-button--icon trix-button--icon-color" data-trix-action="x-color" title="Color" tabindex="-1">Color</button>'
}

get dialogHeadingTemplate() {
return `
<div class="trix-dialog trix-dialog--heading" data-trix-dialog="x-heading" data-trix-dialog-attribute="x-heading">
<div class="trix-dialog__link-fields">
<input type="text" name="x-heading" class="trix-dialog-hidden__input" data-trix-input>
<div class="trix-button-group">
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="heading1">H1</button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="heading2">H2</button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="heading3">H3</button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="heading4">H4</button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="heading5">H5</button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="heading6">H6</button>
</div>
</div>
</div>
`
}

get dialogColorTemplate() {
return `
<div class="trix-dialog trix-dialog--color" data-trix-dialog="x-color" data-trix-dialog-attribute="x-color">
<div class="trix-dialog__link-fields">
<input type="text" name="x-color" class="trix-dialog-hidden__input" data-trix-input>
<div class="trix-button-group">
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor1" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor2" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor3" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor4" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor5" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor6" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor7" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor8" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="fgColor9" data-trix-method="hideDialog"></button>
</div>
<div class="trix-button-group">
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor1" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor2" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor3" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor4" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor5" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor6" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor7" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor8" data-trix-method="hideDialog"></button>
<button type="button" class="trix-button trix-button--dialog" data-trix-attribute="bgColor9" data-trix-method="hideDialog"></button>
</div>
</div>
</div>
`
}
}

function addHeadingAttributes() {
Array.from(["h1", "h2", "h3", "h4", "h5", "h6"]).forEach((tagName, i) => {
Trix.config.blockAttributes[`heading${(i + 1)}`] = { tagName: tagName, terminal: true, breakOnReturn: true, group: false }
})
}

function addForegroundColorAttributes() {
Array.from(["rgb(136, 118, 38)", "rgb(185, 94, 6)", "rgb(207, 0, 0)", "rgb(216, 28, 170)", "rgb(144, 19, 254)", "rgb(5, 98, 185)", "rgb(17, 138, 15)", "rgb(148, 82, 22)", "rgb(102, 102, 102)"]).forEach((color, i) => {
Trix.config.textAttributes[`fgColor${(i + 1)}`] = { style: { color: color }, inheritable: true, parser: e => e.style.color == color }
})
}

function addBackgroundColorAttributes() {
Array.from(["rgb(250, 247, 133)", "rgb(255, 240, 219)", "rgb(255, 229, 229)", "rgb(255, 228, 247)", "rgb(242, 237, 255)", "rgb(225, 239, 252)", "rgb(228, 248, 226)", "rgb(238, 226, 215)", "rgb(242, 242, 242)"]).forEach((color, i) => {
Trix.config.textAttributes[`bgColor${(i + 1)}`] = { style: { backgroundColor: color }, inheritable: true, parser: e => e.style.backgroundColor == color }
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<figure class="attachment attachment--content attachment--<%= content_attachment.name %>">
<%= render "action_text/attachables/content_attachments/#{content_attachment.name.underscore}" %>
</figure>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<hr>
1 change: 1 addition & 0 deletions assets/images/trix_color.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/images/trix_horizontal_rule.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 89 additions & 0 deletions assets/stylesheets/richtext.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
trix-toolbar {
.trix-button--icon-horizontal-rule::before { background-image: image-url("trix_horizontal_rule.svg"); }
.trix-button--icon-color::before { background-image: image-url("trix_color.svg"); }

.trix-dialog--heading { max-width: 180px; }

.trix-dialog--color {
max-width: 265px;

.trix-dialog__link-fields { flex-direction: column; }
.trix-button-group {
margin: 1px;

button {
width: 28px;
&:after { content: "Ab"; }
&.trix-active::after { content: ""; }
}

[data-trix-attribute=fgColor1] { color: rgb(136, 118, 38) }
[data-trix-attribute=fgColor2] { color: rgb(136, 118, 38) }
[data-trix-attribute=fgColor3] { color: rgb(207, 0, 0) }
[data-trix-attribute=fgColor4] { color: rgb(216, 28, 170) }
[data-trix-attribute=fgColor5] { color: rgb(144, 19, 254) }
[data-trix-attribute=fgColor6] { color: rgb(5, 98, 185) }
[data-trix-attribute=fgColor7] { color: rgb(17, 138, 15) }
[data-trix-attribute=fgColor8] { color: rgb(148, 82, 22) }
[data-trix-attribute=fgColor9] { color: rgb(102, 102, 102) }

[data-trix-attribute=bgColor1] { background-color: rgb(250, 247, 133) }
[data-trix-attribute=bgColor2] { background-color: rgb(255, 240, 219) }
[data-trix-attribute=bgColor3] { background-color: rgb(255, 229, 229) }
[data-trix-attribute=bgColor4] { background-color: rgb(255, 228, 247) }
[data-trix-attribute=bgColor5] { background-color: rgb(242, 237, 255) }
[data-trix-attribute=bgColor6] { background-color: rgb(225, 239, 252) }
[data-trix-attribute=bgColor7] { background-color: rgb(228, 248, 226) }
[data-trix-attribute=bgColor8] { background-color: rgb(238, 226, 215) }
[data-trix-attribute=bgColor9] { background-color: rgb(242, 242, 242) }
}
}

.trix-dialog {
padding: 5px;
.trix-dialog-hidden__input {
position: absolute;
z-index: -1;
opacity: 0;
}
}
}

trix-editor {
[data-trix-mutable] {
&.attachment {
&[data-trix-content-type~="vnd.rubyonrails.horizontal-rule.html"] {
box-shadow: 0 0 0 2px highlight;
}
}
}
}

.trix-content {
h1, h2, h3, h4, h5, h6 {
line-height: 1.2;
margin: 0;
}

h1 { font-size: 36px; }
h2 { font-size: 26px; }
h3 { font-size: 18px; }
h4 { font-size: 18px; }
h5 { font-size: 14px; }
h6 { font-size: 12px; }

.attachment { width: 100%; }

.attachment--content.attachment--horizontal-rule,
.attachment--content[data-trix-content-type~='vnd.rubyonrails.horizontal-rule.html'] {
padding: 1.5em 0 0.5em !important;
margin-bottom: 0.5em
}

.attachment--content.attachment--horizontal-rule hr,
.attachment--content[data-trix-content-type~='vnd.rubyonrails.horizontal-rule.html'] hr {
margin: 0;
width: 20%;
border-color: currentColor
}
}
3 changes: 3 additions & 0 deletions config/initializers/action_text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Rails.application.config.after_initialize do
ActionText::ContentHelper.allowed_attributes << 'style'
end

0 comments on commit f51cc67

Please sign in to comment.