mPDF CSS class for text color of <i> nested in <li> overridden by parent's color - mpdf

relevant HTML looks like:
<li class="lineEntry t1" title="Right-Click for Options" style="">
<span id="job_111095">
<i class="ic-p-appr"></i> 111095
</span> Foo/Bar, Some Text </span>
</li>
... and the relevant CSS looks like ( file = icomoon's foo.css ) ...
/* this is an icomoon icon, that should be green */
.ic-p-appr:before {
content: "\e905";
color: #0f8040 !important;
}
... and ( file = bar.css ) ...
.t1{color:#B92426;}
/* .line-entry never defines a color */
I have added !important AND loaded the foo.css After the bar.css in an effort to make the icon green (#0f8040), but the icon nested within the .t1 class always inherits that parent's font color ONLY when mpfd converts the HTML to a pdf doc. (the nested icon in HTML works as expect)
When I look at the mPDF documentation for supported CSS, I see nothing there or in SO that suggests why this occurs. My mPDF is 7, and here is the configuration:
$mpdf = new \Mpdf\Mpdf([
'fontDir' => array_merge($fontDirs, [
'../vendor/resources/fonts',
]),
'fontdata' => $fontData + [
'icomoon' => [
'R' => 'icomoon.ttf',
],
],
'format' => 'A4-L',
'orientation' => 'L',
'debug' => true,
]);
see:
enter image description here
Help with this issue is appreciated.

Fixed: I discovered that because mPDF ver7 does not support CSS pseudo class :before, it was necessary to declare the font-color independently with the class name. So for my HTML output, this worked, .ic-p-appr:before { color: #0f8040 !important; } but I had to declare it again, minus the ':before' to register that style in the PDF document.
Summary: mPDF7 ignores CSS style attributes declared under a pseudo-class.

Related

Use HTMLPurifier to append a class name to CSS styles written in CKEditor

In CKEditor, I'm writing custom CSS like:
a {
color: #ff0000;
}
but I don't want it to overwrite my css written for other global components of my project. Is there a way to use HTMLPurifier to add a class to all my css written in CKEditor. Something like:
.my-ckeditor-class a {
color: #ff0000;
}
In my purifier.php file I have this rule set up but I'm not sure how to go about prefixing a class to all CSS written in my CKEditor
'ckeditor' => [
'HTML.Allowed' => 'b,i,u,a[href|title|target|style],ul,li,br,ol,p,em,strong,img[alt|src|style|width|height],table,td,th,tr,iframe[src|width|height|frameborder]',
'Attr.AllowedFrameTargets' => [ '_blank', '_top', '_self', '_parent' ],
'CSS.Trusted' => true,
'CSS.AllowedProperties' => 'display,font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,padding-right,padding-top,padding-bottom,padding,margin,margin-left,margin-right,margin-top,margin-bottom,color,background-color,text-align,vertical-align,background-image,background-position,max-width,width,height,max-height',
'HTML.MaxImgLength' => NULL,
'CSS.MaxImgLength' => NULL,
'CSS.AllowTricky' => true,
'CSS.AllowImportant' => true,
"HTML.SafeIframe" => 'true',
"URI.SafeIframeRegexp" => "%^(.*)%",
'CSS.[something-to-prefix-class]' => [
'class' => '.my-ckeditor-class',
]
],
```
I believe you're looking for Filter.ExtractStyleBlocks.Scope:
If you would like users to be able to define external stylesheets, but
only allow them to specify CSS declarations for a specific node and
prevent them from fiddling with other elements, use this directive. It
accepts any valid CSS selector, and will prepend this to any CSS
declaration extracted from the document. For example, if this
directive is set to #user-content and a user uses the selector
a:hover, the final selector will be #user-content a:hover.
The comma shorthand may be used; consider the above example, with
#user-content, #user-content2, the final selector will be #user-content a:hover, #user-content2 a:hover.
But keep this warning in mind (although I don't know if this is still relevant, this is a pretty old warning at this point):
Warning: It is possible for users to bypass this measure using a
naughty + selector. This is a bug in CSS Tidy 1.3, not HTML Purifier,
and I am working to get it fixed. Until then, HTML Purifier performs a
basic check to prevent this.
If you want to use this directive, check out the other Filter.ExtractStyleBlocks directives in the configuration documentation, they're meant to be used together (or at least assessed together).

Adding classes to slotted elements (?)

I've run into an awkward scenario while working on a lit-element component library.
The component I'm currently working on is an "alert". Within it's render template it has two named slots: "title" and "text".
<div class="alert-item-content">
<i class="alert-item-icon"></i>
<slot name="title"></slot>
<slot name="text"></slot>
</div>
The elements assigned to those slots will potentially be any valid text tag (h1, h2, h3, etc.). I need to target the slots' assigned element to A) remove/reset global styles that affect them and B) add specific styles that are fundamental to UI requirements.
So, in other words, a person might provide an 'h5' because it is semantically correct but, as an alert title, it should always appear the same.
Example:
<mult-alert>
<mult-alert-item>
<h5 slot="title">Notice Me</h5>
<p slot="text">
This is something you should probably
pay attention to
</p>
</mult-alert-item>
</mult-alert>
The only solution I could come up with so far is to query the assigned elements in shadowRoot and add a class to them. It does work but feels gross. This is the relevant code from the component for that:
addClassesToSlottedNodes() {
[{
slotName: 'title',
className: 'alert-item-title'
}, {
slotName: 'text',
className: 'alert-item-text'
}].forEach(n => {
const slotNodes = this.shadowRoot
.querySelector(`slot[name="${n.slotName}"]`)
.assignedNodes();
if (slotNodes && slotNodes.length) {
slotNodes[0].classList.add(n.className);
}
})
}
Is there a better way to target these slotted elements without adding classes this way? Or, is there a cleaner way to add the class in the component template?
Inside the Custom Element template for the Shadow DOM, you could use the ::slotted() CSS function to set the CSS style of the slotted elements:
<style>
slot[name=title]::slotted(*) {
font-size: 20pt ;
font-weight: bold ;
color: red ;
}
slot[name=text]::slotted(*) {
font-family: Arial ;
}
</style>
<div class="alert-item-content">
<i class="alert-item-icon"></i>
<slot name="title"></slot>
<slot name="text"></slot>
</div>

How do you allow <style> tags in redactor v9.2.1?

I'm using Redactor v9.2.1. I'm trying to allow my customers to use style tags in their CMS, but redactor strips them from the content.
When I add the following:
<style type="text/css">
.red{color:red;}
</style>
redactor strips it to:
<p>
.red{color:red;}
</p>
I've made sure that deniedTags is not including 'style' in my settings object and I'm not using the allowedTags attribute since it conflicts with deniedTags.
Here is my settings object that I'm passing to the redactor init:
var settings = {
deniedTags:[
'html', 'head','link', 'body', 'meta', 'applet'
],
observeLinks: true,
iframe: true,
convertVideoLinks: true
};
Any help is appreciated.
http://imperavi.com/redactor/docs/settings/clean/#setting-deniedTags
Top-level HTML tags ('html', 'head', 'link', 'body', 'meta', 'style',
'script', 'applet') will always be removed regardless of this setting,
unless wrapped in 'pre' tag (formatting option 'Code')
Edit
So you can't add a style tag inside the editor, as I read in the docs. Seems like you have these options:
Style individual tags outside the editor: You add the parent selector .redactor-editor and then the tag name. See http://imperavi.com/redactor/examples/typography/
Add several formattingAdd options to let users pick up custom styles from the formatting dropdown:
$('#redactor').redactor({
formattingAdd: [
{
tag: 'p',
title: 'Red Block',
class: 'red-style'
}
]
});
/**
* The above would create a new formatting entry,
* which you define with 2 css selectors:
* one for the class of the entry, another for the dropdown entry
*
* .red-style, .redactor-dropdown .redactor-formatting-red-style {
* color: red;
* }
*/
Notice css selector rule for the dropdown, which is .redactor-dropdown .redactor-formatting-YOUR_CSS_CLASSNAME. This also is important:
formattingAdd can only be applied to p, pre, blockquote and header
tags.
So you can't apply it to <div>. If you need block element, use <p>. Also, if you need inline, you CAN use <span>... it works, see fiddle: http://jsfiddle.net/a4df10vj/1/

ExtJS 4 - Styling the button of a filefield xtype

Good day, I am building a web application and the user is allowed to upload a photo using a fileField. I am trying to style the button, however, nothing I try seems to work. At first I tried using the element inspector to look for the proper class type but that did not give the results I wanted. Next, I assigned a class to the fileField and created a css for that style but it did not work either. Here is my code:
my filefield
{
xtype: 'filefield',
x: 200,
y: 910,
cls: 'fileBtnClass',
width: 200,
fieldLabel: 'LABEL',
hideLabel: true,
labelStyle: 'text-align: center; color: white',
labelWidth: 140,
buttonOnly: true,
buttonText: 'Browse'
}
my css:
.fileBtnClass {
font-size: 40px !important;
font-family: 'Arial' !important;
font-weight: normal !important;
color: black !important;
background-color: white !important;
border-radius: 15px !important;
text-align: center;
}
What happens is that the button size gets larger to accommodate the text. However, the text itself does not get larger in any way.
Can anyone help me with my situation? Styling certain fields in ExtJS proves to be a pinch at times. Any help is very much appreciated. Thank you.
A Ext.form.field.File has a buttonConfig property which expect a Ext.button.Button configuration. If you filter for Cls within the button API you get at least 10 Cls properties that can all be used to style the button.
arrowCls : String
The className used for the inner arrow element if the button has a menu. ...
baseCls : String
The base CSS class to add to all buttons. ...
cls : String
A CSS class string to apply to the button's main element.
componentCls : String
CSS Class to be added to a components root level element to give distinction to it via styling.
disabledCls : String
CSS class to add when the Component is disabled. ...
focusCls : String
The CSS class to add to a button when it is in the focussed state. ...
iconCls : String
A css class which sets a background image to be used as the icon for this button. ...
menuActiveCls : String
The CSS class to add to a button when it's menu is active. ...
overCls : String
The CSS class to add to a button when it is in the over (hovered) state. ...
pressedCls : String
The CSS class to add to a button when it is in the pressed state. ...
Additional Info
cls -> the additional one
This class is added to the inner element of the button
baseCls -> the one who change it all
// following the template that is used to render a button
'<span id="{id}-btnWrap" role="presentation" class="{baseCls}-wrap',
'<tpl if="splitCls"> {splitCls}</tpl>',
'{childElCls}" unselectable="on">',
'<span id="{id}-btnEl" class="{baseCls}-button" role="presentation">',
'<span id="{id}-btnInnerEl" class="{baseCls}-inner {innerCls}',
'{childElCls}" unselectable="on">',
'{text}',
'</span>',
'<span role="presentation" id="{id}-btnIconEl" class="{baseCls}-icon-el {iconCls}',
'{childElCls} {glyphCls}" unselectable="on" style="',
'<tpl if="iconUrl">background-image:url({iconUrl});</tpl>',
'<tpl if="glyph && glyphFontFamily">font-family:{glyphFontFamily};</tpl>">',
'<tpl if="glyph">&#{glyph};</tpl><tpl if="iconCls || iconUrl"> </tpl>',
'</span>',
'</span>',
'</span>',
// if "closable" (tab) add a close element icon
'<tpl if="closable">',
'<span id="{id}-closeEl" role="presentation"',
' class="{baseCls}-close-btn"',
'<tpl if="closeText">',
' title="{closeText}" aria-label="{closeText}"',
'</tpl>',
'>',
'</span>',
'</tpl>'
The classes that are directly affected by baseCls:
// applied in the template
{baseCls}-wrap
{baseCls}-button
{baseCls}-inner
{baseCls}-close-btn
// just a view that are (may be) applied in code
{glyphCls}
{innerCls}

How to add a custom paragraph format in CKEditor

In my project I have a requirement to remove the paragraph format like "Address" and "Formatted" from the drop down and to add a new custom format called "Links" which would be Arial, 14px, bold, red. Is it possible to add custom paragraph format in CKEditor?
Use CKEDITOR.config.formatTags to specify some new formatting:
CKEDITOR.replace( 'editor1', {
format_tags: 'p;h2;h3;pre;links', // entries is displayed in "Paragraph format"
format_links: {
name: 'Links',
element: 'span',
styles: {
color: 'red',
'font-family': 'arial',
'font-weight': 'bold'
}
}
} );
To know more about styles see how CKEDITOR.styleSet works. Also note that since CKEditor 4.1, removing styles from "Paragraph format" has an impact on Advanced Content Filter.
Since you're working with Drupal, ckeditor.styles.js is the file you're looking for, this will allow you to add/edit/remove entries in the Styles menu.
Comment out any entries you don't want, and use something like this to add a new paragraph format:
{ name : 'Links', element : 'p', attributes : { 'class' : 'links' } },
This will add the CSS class links to whatever paragraph you want, and you can define the class in your theme stylesheet. Make sure to define the class in ckeditor.css if you don't see the changes applied in the CKEditor instance.
Alternatively, you could also apply the inline styles directly:
{ name : 'Links', element : 'p', attributes : { 'style' : 'font: bold 14px Arial, sans-serif; color: red;' } },
But the first method is clearly more flexible/clean.
Make sure to clear your Drupal and/or browser cache if you don't see your changes show up immediately.

Resources