Inserting html or "templates" with quill.js - javascript

I'd like to create a html snippet or template for quill.js which will enable me to create a 3 column 1 row grid. ie:
<div class="row">
<div class="col col-4">
column 1
</div>
<div class="col col-4">
column 2
</div>
<div class="col col-4">
column 3
</div>
</div>
I tried to add <div> tags as shown below however it doesn't work and prints the tags out as text.
quill.setContents([
{ insert: '<div>' },
{ insert: 'World!', attributes: { bold: true } },
{ insert: '</div>\n' }
]);
I also read somewhere that quill.js strips out various html tags but I can't find how to allow them in the docs.
Any help on this would be appreciated.
Cheers :)

Note if you attempt to use the list component as an extension you will run in a number of Quill.js issues-- it doesn't actually support blocks within blocks so you will not be able to nest div's and still use features like headings, only inline elements will be possible, and you will not be able to use <br/> tags because they are wrapped in <p></p> blocks (no blocks within blocks) or use the backspace or enter keys-- this solution is severely limited and virtually impossible to extend, nobody has discovered a good workaround, you can't tell that from the issues board because issues related to architecture are systematically deleted... you will find that your delta saving will be off, make sure any extensions you make can actually save using the native format. I find the answer to modify the list element quite misleading as it's so clearly different to the requirements stated here... if you hit return within one of it's container blocks, it'll splice into a new block.... also the embed functionality is not the same anymore, so you will have trouble with that workaround.
My advice is to try another framework like slate.js or prosemirror, they are newer and have their own issues but don't suffer from the same architectural flaws and have nesting with first class data models. You will definitely have better luck with support.

Quill does not let you make arbitrary HTML modifications, as they are error prone and earned the previous generation of rich text editors their notoriety. Parchment is Quill's abstraction that that allows for deep customization and a good resource is: Cloning Medium with Parchment.
You may be able to use dangerouslyPasteHTML for some use cases but that passes through Quill's matchers so the pasted content's HTML may be different from what you pass in.

Related

Clientside HTML Minification

Is there a way to this kind of minification with javascript and update the DOM (clientSide)
Input:
<div class="parentDiv">
<div class="childDiv">Some text</div>
<div class="childDiv">Some text</div>
</div>
Output:
<div class="parentDiv"><div class="childDiv">Some text</div><div class="childDiv">Some text</div></div>
I know its useless doing the minification after downloading all the content.
The point here is to stop the identation to create gaps between my divs. I know that if I put a comment between the tags the gap won't appear but it gets difficult to understand the code with so many comments between my div tags.
See this [post] and you'll understand what I mean.
I managed to achieve what I wanted and even created a jQuery plugin to it.
jQuery.fn.clearWhiteSpace = function () {
var htmlClone = this.html().replace(/\n[ ]*/g,"");
this.html(htmlClone);
return this;
}
$(".parentDiv").clearWhiteSpace();
there is an example I wrote in jsfiddle
But thanks for all your effort. :)
If it's a minification the DOM won't update. Also there's nothing client-side minification accomplishes: it's not faster to download and it's not obfuscated from the client.
For what you wrote, you can replace '\n' with '' I guess.
Try this javascript minification script -- http://prettydiff.com/lib/jspretty.js
You need to be careful when parsing documents, especially with special characters in attributes. You can write your own DOM parser, but, why re-invent the wheel?
Here is a great parser, written in JavaScript: https://www.npmjs.com/package/html-minifier
Instructions are documented.
The above method is to "minify" production code; however, if it's a visual spacing issue, then see below:
Update:
"White-space" is mostly ignored when it comes to block-elements.
To ensure that your inline-block elements are not separated by "white-space" you can arrange your (blocks)-code underneath each other, indicating that it is not a "space" that separates them; other than that, here's what really matters:
Proper CSS & HTML
make sure all your HTML tags are "paired" correctly -that each open-tag has a close-tag. This does not count for "void-tags" like <img /> or <input /> as these are "self closing".
if you need blocks placed next to each other, use <div> tags styled with CSS to be display:inline-block. You can also make use of "table-cells" -which do NOT have to be <td> tags as you can achieve this also with CSS to be styled as: display:table-cell.
You can also have elements be wrapped and packed tightly together (as mentioned above) by specifying their style as: float:left (or "right").
It is good practice to place your styles in CSS style-sheets -not in-line as the latter makes your code unmanageable; however, some style-sheets are persistent (see below) and the only way to override such styles is by using inline style.
If you're coding in someone else's code-base and none of the above works, you can make some style-sheets of your own that overrides the others with the word: !important after each property. You can use this to override any property but in this case it would typically be margin or border-...
Lastly, make sure there are no no-braking-spaces between your elements if they are not needed; these look like this:
If you need more info on how to write the modern HTML5 markup and CSS3 style-sheet language, the "Mozilla Developer Network" is a great reference: https://developer.mozilla.org
So let's attempt to solve this issue: "The point here is to stop the indentation to create gaps between my divs." What I can deduce from that sentence + the [post] page + its linked answer page is that client-side HTML minification, isn't the correct solution for this problem.
Have you looked into using inline-block or CSS resets first, before attempting to minify the HTML code or munge it by adding blank comments between the HTML tags?
The linked answer page discusses using inline-block to eliminate the spacing, which is occurring between your HTML elements. Those two pages also discuss resetting the font styles to fix the spacing issues.
CSS Resets can be used to fix gaps between elements. There is a list of the most popular CSS Resets at http://cssreset.com If needed, it should be easy to extend them to override any font settings, thus normalizing how the fonts are treating the white-space characters.
So empty comments shouldn't need to be injected between HTML tags, to fix spacing issues with whitespace characters. If CSS is used to fix the styles, then the HTML will be readable. If the HTML is minified, it will be harder to read & debug. I'd suggest not minifying your HTML using JavaScript. Rather try fixing the spacing issues with CSS.
(As for how minification works under it's hood... see my answer at this SO question.)
Minify HTML in the browser with vanilla JS.
const minify_html = (dom_node) => {
dom_node.childNodes.forEach(node => {
const isTextNode = node.nodeType === 3;
const isEmpty = node.nodeValue.trim().length === 0;
if (isTextNode && isEmpty){
dom_node.removeChild(node);
}
});
};
I created an example with 1,000 elements, and my computer can minify the html in less than 15ms, but it may be slower or faster depending on the device running the code.
https://jsfiddle.net/shwajyxr/

The best way to target DOM

I'm a front-end developer, and I'm worried about the best way to target my DOM.
Let's imagine a tiny form to create a new zombie :
<h1>Add a new zombie</h1>
<form id="create-zombie">
<input id="zombie" type="text" name="zombie" />
<input id="lvl" type="text" name="lvl" />
<button type="submit">Add</button>
</form>
...and if I want to get the values of zombie and lvl, I will code something like this:
class Zombie_Add extends Controller
# Dom References
el:
'form': '#create-zombie'
'zombie': '#zombie'
'lvl': '#lvl'
run: ->
#on 'submit', #el.form, #validate
validate: (e) =>
e.preventDefault()
zombie = $(#el.zombie).val()
lvl = $(#el.lvl).val()
module.exports = Zombie_Add
That's "ok" and it does the job, but I have some problems with that "structure" :
If somebody touches the DOM and removes an ID, I'm just fucked, it breaks my code (Captain Obvious spotted !)
For more complicated selectors, it's just a mess (I'm thinking about some stuff like that [name^="dummy-"] input:first). I guess it's easy to imagine how shitty the names of el are.
Anyway, what I want to learn today is what's the best way to target the DOM from JS. Is it better to use IDs, class values or, data-* attributes? How we can prettify a selector with plain English, etc...
If somebody touches the DOM and removes an ID, I'm just ****ed, it
breaks my code (Captain Obvious spotted !)
The best way to target a single, unique element in the DOM is with an ID like you are doing with zombie and lvl. It is both fast to execute and simple to code.
It is a given that if someone messes with the id values in your HTML, that will break your Javascript. That's just the way it is. Anyone messing with your HTML has to be smart enough to know that an ID value is there for a reason so if they want to change that or remove it, then it is their responsibility to find someone who can make corresponding changes in the Javascript. That's just the way it is.
For more complicated selectors, it's just a mess (I'm thinking about
some stuff like that [name^="dummy-"] input:first). I guess it's easy
to imagine how ****ty the names of el are.
The same goes for more complicated selectors. Like it or not, a modern web page is a melding of server-side stuff, presentation HTML and Javascript. The three have to work together to deliver the final solution. While you strive to avoid unnecessary dependencies with good design techniques and practices, you cannot avoid all dependencies, nor would even trying to avoid all possible dependencies be an efficient way to develop.
Example
There are coding practices that can make your code less sensitive to edits to the HTML and I consider those to be desirable practices. For example, consider this HTML snippet:
<div class="header">
<div class="headerBorder">
<div class="actions>
Hide
</div>
<div class="contentContainer">
<div class="content">
... content here
</div>
</div>
</div>
</div>
<div class="header">
... more of these repeated
</div>
And you want to have code that, when you click on the Hide link, it will hide the content.
If you code that like this:
$(".header .actions .hide").click(function() {
$(this).parent().next().children().first().hide();
});
Then, you have embedded in your Javascript some extremely detailed knowledge of the HTML structure in the area of your button and content and pretty much any structural change to that HTML (even just adding one more level of div to help with some layout) will break the Javascript. This is bad.
Instead, you could write this:
$(".header .actions .hide").click(function() {
$(this).closest(".header").find(".content").hide();
});
This depends only upon one HTML structural concept - that the .content that corresponds to the .hide button is somewhere in the common .header parent element. The entire structure within that .header parent can be changed and this code will not break. This is robust code that tries to be as independent of the details of the HTML structure as possible.
Anyway, what I want to learn today is what's the best way to target
the DOM from JS. Is it better to use IDs, class values or, data-*
attributes? How we can prettify a selector with plain English, etc...
It's best to use IDs to target elements for which there is only one unique element in the page.
It's best to use class names to target elements for which there can be more than one element in the page and you can combine that with other parts of a selector if you want to target only a specific item with a class name.
data attributes can be used in selectors, but that isn't really their primary purpose. I can't think of any reason why it would be better to use a data attribute instead of a class name. I use data attributes for storing actual data on an object that will be used by scripts. This tends to allow the code to be more generic and let the content describe itself.
When you talk about classes getting removed to change the state of the element, that is a legitimate use of a class, but it would just be a bad design decision to use the same class for selecting an element as for add/removing state. Use different class names for those two purposes. For example, you could have a class name called "selected" that indicates a selection state, but you would only use that in a selector if you wanted just the selected objects. If you wanted all line items in a table, you wouldn't use ".selected", you'd create a more descriptive class name for that object such as "lineitem". Remember, you can have multiple class names on an object so you can use different class names on the same object for different purposes.
You seem to be searching for some magic bullet here that prevents changes in the HTML from affecting Javascript in any way. That simply does not exist. Selecting a DOM element or finding a DOM element relative to something that was clicked will rely on some inherent knowledge of how the HTML is structured or tagged. What is important is that you minimize that dependence to only what is required and that anyone messing with the HTML has an understanding of how to best change things and not break the Javascript or discusses changes with someone who knows the Javascript. If you're using different skills/people on different portions of the project, they have to coordinate their efforts in order to not break things or be aware of what dependencies there are with the other parts of the system. That's just the way it is. There is no magic answer here that removes all dependencies between HTML and Javascript. Smart designs have smaller and more obvious dependencies. Poor designs have large and often hidden depedencies.
Your question about "plain English" isn't particularly clear to me. It seems obvious to use descriptive ID names, class names or attribute names that make it as obvious to the reader what that particular name is being used for. I'm not sure what you were looking for beyond that.

VS Extension to manipulate HTML / CSS

I am looking to enhance my programming experience and I believe I can do that by creating a Visual Studio (2012) extension. I have started to dig into the documentation on MSDN, but it's dense and I am working through it.
I had a few questions:
Is an extension the correct approach for the scenario described
below?
If so, any idea which namespace I should start digging into?
Any sage wisdom/links RE: "pitfalls" or "gotcha"?
The Setup
I have a block of HTML and it has some inline CSS on certain elements. I'd like to right-click on the element and apply the inline code to a new or existing stylesheet (CSS).
The Code
<div>
<div class="ui-bar-d ui-bar" >
<span class="WBHeaderDetail" style="margin-left: 5px; margin-right: 5px;">
Name: <em class="WBHeaderDetailValue" style="text-decoration: underline;">#ViewBag.JobName</em>
</span>
<span class="WBHeaderDetail" style="margin-left: 5px; margin-right: 5px;">
Status: <em class="WBHeaderDetailValue" style="text-decoration: underline;">#ViewBag.Status</em>
</span>
<a data-role="button" data-theme="b" data-icon="check" data-inline="true" data-mini="true" >Save</a>
</div>
</div>
Arguably, the operation that extension would expose could grab a reference to a given element and inspect for inline CSS (style tag), remove it from the element, and then append that CSS to a new or existing stylesheet in the project/solution. Whether or not the element already has a value for the 'class' attribute could impact the vendor selected for this project.
UPDATE
Saw this on: http://www.asp.net/vnext/overview/aspnet/whats-new
Smart Tasks
In Design view, complex properties of server controls often have associated dialog boxes and wizards to make it easy to set them. For example, you can use a special dialog box to add a data source to a Repeater control or add columns to a GridView control.
However, this type of UI help for complex properties has not been available in Source view. Therefore, Visual Studio 11 introduces Smart Tasks for Source view. Smart Tasks are context-aware shortcuts for commonly used features in the C# and Visual Basic editors.
For ASP.NET Web Forms controls, Smart Tasks appear on server tags as a small glyph when the insertion point is inside the element:
Can I get my code into that dialog?
THANKS!
I made a small VS extension last year for class that turned out pretty well. It had to do with sorting, formatting and re-organizing C++ code files. It's a little different than what you want to do, but I can suggest that you take a look at CodeMaid. It has a surprising number of features, and since it's open source, the source code really helped me out when I was working on my extension.
Unfortunately, you're working with HTML and Visual Studio only provides the code model (basic AST) for C# and a small bit of C++. You're unlikely to get any help from visual studio with HTML editing.
So I would do 2 things. First, look at these tutorials. They'll help you create the base for your extension and get you familiar with the API. (You'll likely have to look for others to augment your knowledge, as MS tutorials aren't the greatest.) Second, polish up on your regular expressions. The best way to complete what you want is probably to parse the file yourself and locate all instances of inline style tags. Then add a right-click menu item and locate the appropriate tag when you need to.
But again, I would start with the basic tutorials. The VS extension API is a bit odd, so you'll probably want to get used to it by doing simple stuff first.
Good luck, you'll need it. :p
EDIT: I know this doesn't answer your question directly, just offering a bit of advice.
Yes a VSIX is the way to go.
You can take a look at some of the code from Web Essentials. Web essentials does something similar to what you want to do.
The following is a link to the CSS sorter on github: https://github.com/madskristensen/CssSorter
And this one is a link to the HTML ZenCoding feature:
https://github.com/madskristensen/zencoding
Since both of them involve dealing with HTML, CSS you could get a lot of information looking at the code. The only difference with your project is that you're actually targeting both at the same time and are looking into accessing multiple files. Unofrtunately, for HTML and CSS I don't know wether there's a built-in parser available.
There are a few packages availble on NuGet though, so you could try these out:
ExCSS Stylesheet Parser: http://nuget.org/packages/ExCSS/
HtmlAgilityPack: http://nuget.org/packages/HtmlAgilityPack/
I haven't worked with these packages directly, but I guess you'll have to try them out and see if it fits.
As for the smarttasks: this is normally a part of the control designer and I don't think it's appropriate for what you want to do. I would just add your extension to the context menu

Advantages Of Putting HTML in Javascript

I am wondering if it is better to put your html in javascript or in your html files.
For example having my js file have this
$('<div>').addClass('test').append(
$('<p>').text('test1'),
$('<span>').text('test2'),
$('<span>').text('test3')
).insertAfter( $('#test1') );
VS
My html file looking like this
<div id="#test1"></div>
<div class="test">
<p>test1</p>
<span>test2</span>
<span>test3</span>
</div>
and the js file have:
$('.test').show();
Highly subjective and depends on contexts of course.
In a web page, most of the content is already known. No reason not to just put the content in the HTML and use CSS (and maybe Javascript when really needed) to style in.
In a web application, however, things are not so well known. The document is much more dynamic and using Javascript to add/remove elements is required.
BTW, your two pieces of code do two different things. In the first example you give it a class of test and in the second you are giving it an ID of #test1. This is an invalid ID and should be test1. The selector for that ID would be #test1 which may be causing some of the confusion.
This is probably okay for just straight-up webpages, but for web applications you should really look into a templating system such as mustache.js(https://github.com/janl/mustache.js) or Handlebars.js(http://handlebarsjs.com/).
That way, you can keep your HTML in external template files and use Javascript objects and arrays to fill them with data. For example, a mustache template might look like:
<div id="{{id}}"></div>
<div class="{{class}}">
<p>{{name}}</p>
<span>{{prop1}}</span>
<span>{{prop2}}</span>
</div>
And you would have an object that looks like this to fill it:
var obj = {
id: "myID",
class: "some classes",
name: "Martin Brennan",
prop1: "whatever",
prop2: 22
}
And you would use the template with the object like this (after loading the template into a variable):
Mustache.render(template, obj)
Like Jeremy J Starcher said though, this is highly subjective, and I would suggested that you give templating systems a try to see if you can see the value in using them in your project(s).
Of course the second option is much better and faster.
If you use
$('<div>').addClass('test').append(
$('<p>').text('test1'),
$('<span>').text('test2'),
$('<span>').text('test3')
).insertAfter( $('#test1') );
browser must parse JavaScript. And each time you use $() you are creating an object which has a lot of properties and methods which you don't use (useless!). And of course the browser must parse the HTML too.
But if you use
<div id="#test1"></div>
<div class="test">
<p>test1</p>
<span>test2</span>
<span>test3</span>
</div>
browser only has to parse HTML and it's much faster.
One of the largest benefits of using the 2nd, hard-coded HTML method is that it'll still show up for people with JavaScript disabled. It's hard to verify exactly how many users don't have JS enabled (because most trackers use JS..) but last guesstimate I heard was somewhere around 5% of internet users.
Moral of the story - make your site work without JavaScript. Then and only then add JavaScript to make it look prettier/ add additional (non essential) features.
The simple answer is that static content should be created using normal markup, while Javascript should be used for dynamic content.
Also, in many cases you can use both. You can have static HTML markup with style="display:none", and then use Javascript to change the style to make it appear and disappear as needed.

How many element id's can browsers safely handle before performance degredation?

Using element id's is the fastest way for javascript to 'get' an element. Is there a rule of thumb or best practices guideline on how many of these id's should be used before one can expect browser performance to start degrading?
An ID, in and of itself, is just an attribute value. The only 'performance' issue is extra bits and bytes the browser has to download. From a JavaScript POV, the more elements in the DOM, the longer it can take to traverse it, but that's not directly related to the number of IDs you may be using.
EDIT:
To clarify if your JS is this:
document.getElementById("myID")
it doesn't matter if your HTML looks like this:
<div id="div1">
<div id="div2">
...
<div id="div999">
<div id="myDiv">
or this:
<div>
<div>
...
<div>
<div id="myDiv">
The JS should run the same for both of those examples.
A complex page means more bytes to download and it also means slower DOM access in JavaScript. It makes a difference if you loop through 500 or 5000 DOM elements on the page when you want to add an event handler for example.
A high number of DOM elements can be a symptom that there's something that should be improved with the markup of the page without necessarily removing content. Are you using nested tables for layout purposes? Are you throwing in more s only to fix layout issues? Maybe there's a better and more semantically correct way to do your markup.
A great help with layouts are the YUI CSS utilities: grids.css can help you with the overall layout, fonts.css and reset.css can help you strip away the browser's defaults formatting. This is a chance to start fresh and think about your markup, for example use s only when it makes sense semantically, and not because it renders a new line.
The number of DOM elements is easy to test, just type in Firebug's console:
document.getElementsByTagName('*').length
We've got a form with over 1,000 fields (don't ask), using jQuery Validate for client-side validation. This includes validating which fields are required, checking the data type of each field, showing/hiding groups of fields based on certain criteria and running calculations across multiple fields as data is entered.
Only MSIE slows down at this scale. Firefox and Chrome run the validation "instantly". MSIE eventually shows the "long running script" dialog. I was notified last night that additional fields are now required.

Categories