Ckeditor : stylesSet not working when i set a custom allowedContent - ckeditor

In my Ckeditor config i have a custom allowedContent. I don't use allowedContent:true because i don't want to allow the style attribute in the span tags
So this is my allowedContent
allowedContent : 'span[class]; a[!href](*); caption; div; em; h1; h2; h3; h4; h5; h6; hr; i; img; li; ol; p[*]{*}; pre; strong; sub; sup; table; thead; tbody; tfoot; td; th; tr; tt; u; ul; dl; dt; dd; iframe;'
With this configuration, the style attributes are not allowed anymore on the span tags
The problem is with my stylesSets :
stylesSet:
- { name: "style 1", element: ['div', 'p', 'a', 'span'], attributes: { class:"display_only_in_popup" } }
- { name: "style 2", element: ['div', 'p', 'a', 'span'], attributes: { class:"blockquote" } }
- { name: "style 3", element: ['div', 'p', 'a', 'span'], attributes: { class:"note" } }
- { name: "style 4", element: ['p', 'span'], attributes: { class:"highlight" } }
- { name: "style 5", element: 'span', attributes: { class:"visuallyhidden" } }
Before, when i had allowedContent:true, i was able to see and use all of my 5 stylesets, but now, for some reason, i only see the "style 5" in the Styles field
Is it possible to keep my 5 stylesets without using allowedContent:true?
Thanks a lot

It seems that your 5 stylesets all use the class attribute, but your allowedContent rule only allows the class attribute for the span elements.
I suggest changing the allowedContent rule to:
allowedContent : '*[class]; a[!href](*); caption; div; em; h1; h2; h3; h4; h5; h6; hr; i; img; li; ol; p[*]{*}; pre; strong; sub; sup; table; thead; tbody; tfoot; td; th; tr; tt; u; ul; dl; dt; dd; iframe;'
or if you want to be more explicit:
allowedContent : 'div[class]; p[class]; a[class]; span[class]; a[!href](*); caption; div; em; h1; h2; h3; h4; h5; h6; hr; i; img; li; ol; p[*]{*}; pre; strong; sub; sup; table; thead; tbody; tfoot; td; th; tr; tt; u; ul; dl; dt; dd; iframe;'
Please refer to the documentation here.
Note: I was not able to test this code, please let me know in the comments if it does the job.

Related

Set a NativeScript Label line height on iOS

I have a label with a large font size, and the default line-height is quite loose for my taste. I'd like to reduce it to less than the default.
Providing a line-height value larger than the font-size does increase the line spacing, but a smaller value (or negative value) does not reduce it to be smaller than the default on iOS.
From a GitHub issue, I got this snippet that I updated to work with the latest NS;
import { Label } from "#nativescript/core/ui/label";
export function setIOSLineHeight(label: Label, lineHeight: number){
const iosLabel = label.nativeView;
let attributedString;
if (iosLabel.attributedText) {
attributedString = iosLabel.attributedText;
} else {
attributedString = NSMutableAttributedString.alloc().initWithString(iosLabel.text);
}
let range = new NSRange({ location: 0, length: iosLabel.text.length });
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
paragraphStyle.lineSpacing = 0;
paragraphStyle.minimumLineHeight = lineHeight;
paragraphStyle.maximumLineHeight = lineHeight;
attributedString.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, range);
iosLabel.attributedText = attributedString;
}
However, calling this method in the mounted() lifecycle method does not have any effect for any value of lineHeight - even ones that do have an effect via the CSS property:
<template>
<Page ref="page">
<Label ref="topLine" text="Hello this is a text that flows onto multiple lines" textWrap="true" />
</Page>
</template>
<script>
import { isIOS } from 'tns-core-modules/platform';
import { setIOSLineHeight } from '../label-helper.ts';
export default {
mounted() {
if (isIOS) {
/* Has no effect, regardless of value */
setIOSLineHeight(this.$refs.topLine, 40);
}
}
}
</script>
<style lang="scss" scoped>
Label {
font-size: 60;
/* Does work */
line-height: 100;
/* Does not work */
line-height: 40;
}
</style>
How can I reduce the line height of my Label to a value smaller than the font size?
In NativeScript I have used the following code to handle both IOS and Android for Line Spacing
function labelLineHeight(nsLabel) {
if(isIOS){
var label= nsLabel.ios;
var attributedString;
if(label.atributedText){
attributedString = label.atributedText;
}
else{
attributedString=NSMutableAttributedString.alloc().initWithString(label.text);
}
var paragraphStyle = NSMutableParagraphStyle.alloc().init();
paragraphStyle.lineSpacing = 5;
var range= NSMakeRange(0, label.text.length);
attributedString.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, range);
label.attributedText = attributedString;
}
if(isAndroid){
var label = nsLabel.android;
//Default spacing is 20% of text size
//setLineSpacing(add,multiplyby);
label.setLineSpacing(12, 1);
}
}
Also follow this thread for more inputs on the line-spacing. You can see the pull request too for reference.

Adding QQuickItem pointers to an std::map makes them all "not accessible" pointers or items

This question involves Qt but could be pure C++ problem with my logic.
I am adding QQuickItems to an std::map store info about a list of QQuickItems & their respective parents.
The code:
std::array<std::string, 2> ObjectNamesArray = { "quickitemObj1", "quickitemObj2" };
std::map<QQuickItem*, QQuickItem*> items;
for(const auto& quickitem: ObjectNamesArray) {
QQuickItem * item = Qmlengine->rootObjects()[0]->findChild<QQuickItem*>(quickitem.c_str());
if (item != NULL)
items.insert(std::make_pair(item, item->parent());
// for a test, following works fine with the item pointer within this loop
qreal width ? item->width();
}
Debugging through above loop, the items map shows zero items with the tag not accessible.
Iterating over the map again like this.
std::map<QQuickItem*, QQuickItem*>::iterator it = items.begin();
while (it != items.end()) {
QQuickItem* item = it->first;
QQuickItem * itemParent = it->second; // crashes here as *item is null
it++;
}
Problem:
But, when I try to iterate through the map, there are no valid pointers to my QQuickItems. In fact looks like there are not items added to the map.
Question:
What is wrong with my logic? How should I add QQuickItems to an std::map so that I can safely retrieve them back.
First you have const string inside this method istead of QQuickItem name
findChild<QQuickItem*>("quickitem.c_str()");
So it gives you 0
You should add checking if item is NULL before adding to container.
Second thing is that you talking about searching items map, but here, you are appending to parents
parents.insert(std::make_pair(item, item->parent());
BTW: When you use Qt, I recommend you using Qt containers
EDIT:
This works for me, after some improvements and if i have appropriate objects in QML
CPP
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
std::array<std::string, 2> ObjectNamesArray = { "quickitemObj1", "quickitemObj2" };
std::map<QQuickItem*, QQuickItem*> items;
for(const auto& quickitem: ObjectNamesArray) {
QQuickItem * item = engine.rootObjects()[0]->findChild<QQuickItem*>(quickitem.c_str());
if (item != NULL)
items.insert(std::make_pair(item, (QQuickItem*)item->parent()));
}
std::cout << "Map: " << items.size() << std::endl; //it gives 2
std::map<QQuickItem*, QQuickItem*>::iterator it = items.begin();
while (it != items.end()) {
QQuickItem* item = it->first;
QQuickItem * itemParent = it->second; // no crash
it++;
}
QML
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Item
{
objectName: "quickitemObj1"
}
Item
{
objectName: "quickitemObj2"
}
}

How do I dynamically create CartoCSS for a choropleth with CartoDB

I am trying to create choropleth map with CartoDB using the JS library.
How can I dynamically create the cartoCSS on a layer?
It seems possible based on column?
For example using the built in wizard the following was generated. I want to somehow dynamically generate this using custom colors and column names on the frontend.
#mytable{
polygon-fill: #FFFFB2;
polygon-opacity: 0.8;
line-color: #FFF;
line-width: 0.5;
line-opacity: 1;
}
#mytable [ col_xyz <= 12505.969707] {
polygon-fill: #B10026;
}
#mytable [ col_xyz <= 3650.909837] {
polygon-fill: #E31A1C;
}
#mytable [ col_xyz <= 1656.60976] {
polygon-fill: #FC4E2A;
}
#mytable [ col_xyz <= 677.226857] {
polygon-fill: #FD8D3C;
}
#mytable [ col_xyz <= 333.140676] {
polygon-fill: #FEB24C;
}
#mytable [ col_xyz <= 170.576913] {
polygon-fill: #FED976;
}
#mytable [ col_xyz <= 51.090065] {
polygon-fill: #FFFFB2;
}
http://docs.cartodb.com/cartodb-platform/cartodb-js.html#sublayersetcartocsscss
Yes - you'll want to use the createLayer method, making each of the polygons its own sublayer...
cartodb.createLayer(map, {
user_name: 'mycartodbuser',
type: 'cartodb',
sublayers: [{
sql: "SELECT * FROM table_name",
cartocss: '#table_name {polygon-fill: #F0F0F0;}'
},
{
sql: "SELECT * FROM table_name",
cartocss: '#table_name {polygon-fill: #FFFFFF;}'
}]
})
.addTo(map)
.done(function(layer) {
//DO STUFF
});
Maybe there are better ways to do this, but it worked for me.
http://docs.cartodb.com/cartodb-platform/cartodb-js.html

Sass BEM: avoid modifier duplication when element is inside a modifier

Can I somehow refactor the following code snippet to get rid of double modifier declaration?
.block {
&__element {
rule: value;
}
&--modifier {
rule: value;
}
&--modifier & {
&__element {
rule: value;
}
}
}
Output wanted:
.block {
property: value;
}
.block--modifier {
property: value;
}
.block--modifier .block__element {
property: value;
}
Nesting elements inside modifiers is a known issue. There are a lot of workarounds.
Variable way
Store the block element in a variable.
And use it interpolated when creating a element inside a modifier.
.block {
$block: &;
&__element {
property: value;
}
&--modifier {
property: value;
#{$block}__element {
property: value;
}
}
}
See output below.
Function way
1. Create a function that returns the block element.
It'll get the parent selector and cut the word before -- (which is the block). Looks hacky, but it's the simplest way to go.
#function block() {
$selector: str-slice(inspect(&), 2, -2);
$index: str-index($selector, '--') - 1;
#return str-slice($selector, 0, $index);
}
2. Use the function interpolated.
Which will return the name of the block so you don't have to repeat it.
.block {
property: value;
&--modifier {
property: value;
#{block()}__element {
property: value;
}
}
}
See output below.
Both ways will output to:
.block {
property: value;
}
.block--modifier {
property: value;
}
.block--modifier .block__element {
property: value;
}
You can place the block within the &--modifier selector like this, using the class name of the block rather than & to target it.
.block {
&__element {
rule: value;
}
&--modifier {
rule: value;
.block {
&__element {
rule: value;
}
}
}
}
However, this is possibly not the best BEM solution, you should consider renaming the nested block as an element of the containing block, such as .block__another-element or creating a new block entirely.
You could add & alongside the modifier for a solution similar to Toni's.
.block {
&__element {
rule: value;
}
&--modifier & {
rule: value;
&__element {
rule: value;
}
}
}
This would however require .block to be a root selector and not nested inside any other selector.
Just another possible solution. For most situations though, I would still prefer Toni's solution.
if someone use less, this will help you!
#block:.parent;
#{block}{
backgroung:red;
&--modifier{
backgroung:blue;
}
&__child{
font-size:20px;
#{block}--modifier & {
font-size:40px;
}
}
}

Qt5 Syntax Highlighting in QML [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am working on a QtQuick 2.0 presentation and I would like to embed some code samples. is it possible easily to create a syntax highlighting QML element.
The objective in question is to apply syntax highlighting to a TextEdit or a TextArea. I know Qt has a QSyntaxHighlighter, but the documentation is not very clear on how exactly to apply it to a TextEdit or a TextArea.
Can you provide examples on how it's done?
Qt Quick's TextEdit item exposes a textDocument property, of type QQuickTextDocument. This is explicitly exposed so you can use QSyntaxHighlighter directly with the document.
QtQuick textEdit documentation for Qt 5.3
I have two answers:
a pure QML answer
a C++ answer involving QSyntaxHighlighter
For a pure QML answer, we can use a TextArea one can set TextArea::textFormat to textFormat: TextEdit.RichText for formatting. We can use TextArea::getText() to get the plain text and set TextArea::text with the rich text. Here's a mock example that:
color uppercase identifiers (e.g. Button) as purple
color lowercase identifiers (e.g. x y z) as red
color numbers (e.g. 123 456) as blue
but leave symbols (e.g. = + ;) as black
Here's the snippet:
TextArea {
id: output
property bool processing: false
text: "<p>x = 123;</p><p>y = 456;</p><p>z = x + y;</p>"
textFormat: TextEdit.RichText
selectByMouse: true
onTextChanged: {
if (!processing) {
processing = true;
let p = cursorPosition;
let markUp = getText(0, length).replace(
/([A-Z][A-Za-z]*|[a-z][A-Za-z]*|[0-9]+|[ \t\n]|['][^']*[']|[^A-Za-z0-9\t\n ])/g,
function (f) {
console.log("f: ", JSON.stringify(f));
if (f.match(/^[A-Z][A-Za-z]*$/))
return "<span style='color:#800080'>" + f + "</span>";
if (f.match(/^[a-z][A-Za-z]*$/))
return "<span style='color:#800000'>" + f + "</span>";
else if (f.match(/^[0-9]+$/))
return "<span style='color:#0000ff'>" + f + "</span>";
else if (f.match(/^[ ]/))
return " "
else if (f.match(/^[\t\n]/))
return f;
else if (f.match(/^[']/))
return "<span style='color:#008000'>" + f + "</span>";
else
return f;
}
);
text = markUp;
cursorPosition = p;
processing = false;
}
}
}
To use Qt's QSyntaxHighlighter, you need the following:
In QML, use TextEdit QML type in your application
In C++, define a QSyntaxHighlighter and connect TextEdit QML type to it via the TextEdit::textDocument property
In C++, implement QSyntaxHighlighter::highlightBlock( const QString& text ) in your derived class, calling QSyntaxHighlighter::setFormat() as often as needed to tokenize the text found.
To make things easier, I create a sample app https://github.com/stephenquan/QtSyntaxHighlighterApp which wraps QSyntaxHighlighter and QTextFormat as SyntaxHighlighter and TextFormat QML Types. That way, one can handle onHighlightBlock signal and put the business logic of the syntax highlighter in Javascript instead of C++:
TextEdit {
id: textEdit
selectByMouse: true
text: [
"import QtQuick 2.12",
"",
"Item {",
" Rectangle {",
" width: 50",
" height: 50",
" color: '#800000'",
" }",
"}",
].join("\n") + "\n"
font.pointSize: 12
}
SyntaxHighlighter {
id: syntaxHighlighter
textDocument: textEdit.textDocument
onHighlightBlock: {
let rx = /\/\/.*|[A-Za-z.]+(\s*:)?|\d+(.\d*)?|'[^']*?'|"[^"]*?"/g;
let m;
while ( ( m = rx.exec(text) ) !== null ) {
if (m[0].match(/^\/\/.*/)) {
setFormat(m.index, m[0].length, commentFormat);
continue;
}
if (m[0].match(/^[a-z][A-Za-z.]*\s*:/)) {
setFormat(m.index, m[0].match(/^[a-z][A-Za-z.]*/)[0].length, propertyFormat);
continue;
}
if (m[0].match(/^[a-z]/)) {
let keywords = [ 'import', 'function', 'bool', 'var',
'int', 'string', 'let', 'const', 'property',
'if', 'continue', 'for', 'break', 'while',
];
if (keywords.includes(m[0])) {
setFormat(m.index, m[0].length, keywordFormat);
continue;
}
continue;
}
if (m[0].match(/^[A-Z]/)) {
setFormat(m.index, m[0].length, componentFormat);
continue;
}
if (m[0].match(/^\d/)) {
setFormat(m.index, m[0].length, numberFormat);
continue;
}
if (m[0].match(/^'/)) {
setFormat(m.index, m[0].length, stringFormat);
continue;
}
if (m[0].match(/^"/)) {
setFormat(m.index, m[0].length, stringFormat);
continue;
}
}
}
}
TextCharFormat { id: keywordFormat; foreground: "#808000" }
TextCharFormat { id: componentFormat; foreground: "#aa00aa"; font.pointSize: 12; font.bold: true; font.italic: true }
TextCharFormat { id: numberFormat; foreground: "#0055af" }
TextCharFormat { id: propertyFormat; foreground: "#800000" }
TextCharFormat { id: stringFormat; foreground: "green" }
TextCharFormat { id: commentFormat; foreground: "green" }
There is no obvious way to achieve syntax highlighting in QML.
One could implement one's own declarative item, performing the actual highlighting with QSyntaxHighlighter but then one would have to define its own highlighting rules for language of the source code in question. I would't do that amount of coding for a presentation.
Instead I would display the code in a WebView item with the highlighting already applied as static HTML markup or with the help of a JavaScript highlighting library, for expample highlight.js.
Update 1
If the WebView item is indeed unusable, even the simple Text item with its rudimentary HTML support should be enough to handle the source code highlighting usecase if fed with static HTML.
in your app file:
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickTextDocument* doc = childObject<QQuickTextDocument*>(engine, "textEditor", "textDocument");
Q_ASSERT(doc != 0);
// QSyntaxHighlighter derrived class
MySyntaxHighlighter* parser = new MySyntaxHighlighter(doc->textDocument());
// use parser, see QSyntaxHighlighter doc...
int ret = app.exec();
delete parser;
return ret;
The template function to get child objects (returns the first occurence of objectName, so use unique names to identify objects in your qml files) :
template <class T> T childObject(QQmlApplicationEngine& engine,
const QString& objectName,
const QString& propertyName)
{
QList<QObject*> rootObjects = engine.rootObjects();
foreach (QObject* object, rootObjects)
{
QObject* child = object->findChild<QObject*>(objectName);
if (child != 0)
{
std::string s = propertyName.toStdString();
QObject* object = child->property(s.c_str()).value<QObject*>();
Q_ASSERT(object != 0);
T prop = dynamic_cast<T>(object);
Q_ASSERT(prop != 0);
return prop;
}
}
return (T) 0;
}
in your qml file use a TextEdit (inside a Flickable or whatever you want) with the objectName property correctly set:
....
TextEdit {
id: edit
objectName: "textEditor"
width: flick.width
height: flick.height
focus: true
font.family: "Courier New"
font.pointSize: 12
wrapMode: TextEdit.NoWrap
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
}
....
Take a look at QSyntaxHighlighter.
If you need a QML Item doing syntax highlighting, you can simply create your own by extending QDeclarativeItem and using the utility above.

Resources