Readability - how do I keep parts of content that get omitted? - javascript

I'm working with Readability library from Mozilla to show simplified content of articles and blogposts. But I would like to keep certain content based either on HTML tag or class, for example <time> elements.
How can I do that?

After looking into the code, it seems there isn't any user-exposed functionality for this, but you can do it quite easily if you don't mind editing the source code. There's an array PHRASING_ELEMS in Readability.js (line 159 at the time of writing) that determines which element tag names to preserve.
You'll need to modify that array yourself to achieve what you want, either by editing your local copy of Readability or by making a fork of the source code with your custom array and then using that in place of the original (or even better, fork and change it so that users can define their own included/excluded element arrays in the constructor options to solve the root problem here).

Related

Setting (ARIA) role for HTML custom elements without explicit attribute?

I have a web app that displays and passes around user-editable semantic markup. For a variety of reasons, including security, the markup consists entirely of custom elements (plus the i, b, and u tags). For regular rendering, I simply have styles for all the tags and stick them straight in the DOM. This looks and works great.
Now I'm doing screen-reader testing, and things aren't great. I have a bunch of graphical symbols I want to add labels for. I've got divs that I want to make into landmarks. I've got custom input fields and buttons.
It would be easy enough to just add role= to all the different tag instances. But part of the reason for the custom markup is to eliminate all the redundant information from the strings that get passed around (note: they're also compressed). My <ns-math> tag should always have role="math", and adding 11 bytes to what might be tags around a single character is an actual problem when multiplied out over a whole article. I know this because the app started with a bunch of <span class="... type elements instead of custom.
For the fields and buttons, I've used a shadow DOM approach. This was necessary anyway to get focus/keyboard semantics correct without polluting the semantic markup with a bunch of redundant attributes, so it's easy to also slap the ARIA stuff on the shadow elements. Especially since the inputs are all leaf nodes. But most of my custom tags amount to fancy spans, and are mostly not leaf nodes, so I don't really want to shadow them all when they're working so well in the light DOM.
After a bunch of searching, it seems like the internals.role property from "4.13.7.4 Accessibility semantics" of the HTML standard is maybe what I want. I may well be using it incorrectly (I'm a novice at front-end), but I can't seem to get this to work in recent versions of Firefox or Chrome. I don't get an error, but it seems to have no effect on the accessibility tree. My elements are not form-associated, but my reading is that the ARIAMixin should be functional anyway. This is maybe a working draft? If this is supposed to work in current browsers, does anybody have a code snippet or example?
Is there some other straight-forward way to achieve my goal of accessibility-annotating my custom elements without adding a bunch of explicit attributes to the element instances?
So you want the benefit of adding a role or an aria-attribute without actually adding those attributes? The concept of an "accessibility object model" (AOM) has been bantering around a bit that would let you access and modify the accessibility tree directly but it's still in the works. Here's an article from a couple years ago that talks about it. Nothing official. Just one person's thoughts.
Further research shows that, as of this time, the abstracted accessibility options I'm asking for are not yet implemented.
For the time being: eliminating a number of page-owned enclosing divs from the accessibility hierarchy via role="presentation" significantly improved my overall tree. With those out of the way, the majority of my custom tags seem to be simply semantically ignored. This is mostly fine as the majority of my content is plain text.
Since I already mark up the vast majority of even single-character symbols, I've simply added all my symbols to the markup generator. Since everything is already in custom tags, I then use a shadow DOM span with role="img" and a character-specific aria-label to present the symbolic character.
My solution is still incomplete. I wish that I could convey the full richness of the semantic content I have available.

How to modify a large number of elements in DOM without sacrificing usability?

I have a list with quite a few elements (each of them is a nested div). Each element has a custom onclick handler.
JS updates the list several times per second, this may result in:
adding or removing some elements
changing text in some elements
changing styles in some elements
changing height of some elements
etc.
Most of the time the update makes small changes to the majority of the elements.
To minimize reflows I should remove the list from DOM, make the changes and append it back. The problem I have with this approach is that when user selects some text, the next update will reset the selection. (And the next update comes within a second) If user clicks a button his click may fail to register if there was an update between mose_down and mouse_up.
I understand when the selection resets on text that have been changed. It makes sense. But with such approach any selection in this list will reset.
Is there any better way to do this? How would you implement such list?
This list is fully generated by JS. If I'm removing it from DOM anyway, is there any benefit to modifying it instead of recreating it from scratch? Creating it anew each time would require less code.
This sounds like 2 way data binding, there are a couple of good custom solutions to data-binding answers on here: Handy stack link. Alternatively backbone.js and knockout.js have good techniques amongst quite a few other frameworks (angular ect).
Additionally, if you want to have a pop at it yourself (which I highly recommend to get a better understanding) you could use the proposed 'Object Observe' function. There's some handy documentation with some examples on how this works over at Mozilla. as well as The trusty HTML5 Rocks, which is a nice simple tutorial on using the new Object.Observe functionality, well worth a read.
Hope this helps!

Remove JavaScript styles, allowing CSS to take control

Preamble: Possible duplicate to my question can be found found here, although for me, this question was not sufficiently answered. A work-around is given, but a definitive answer to the question of whether or not it is possible, is not provided.
The question:
On my website, when a user clicks a button (or area of screen), I want that area to "flash" a couple of times before returning to its original state. (I think this gives the user a reassuring feel of something having been activated, as in some circumstances, they may have short delay before the feedback is given.)
Anyway, I've managed to get this working using a bit of JavaScript and jQuery, and you can see the results here >>.
As you may notice, the problem is that after the flashing is done, the element doesn't return to its original state. Rather, it keeps its last "flash" state, and overrides the underlying CSS styling which originally styles the object when the page loads.
I style the element with the following jQuery:
$jq_obj.css('background-color',flash_fg_color_).css('color',flash_bg_color_);
And I 'attempt' to un-style it with:
$jq_obj.removeAttr('background-color').removeAttr('color');
I've also tried:;
$jq_obj.css('background-color','').css('color','');
Despite the documentation saying that this should remove styling, it doesn't.
Is there a solution, or do I have to revert to the work-around solution referred to in my preamble? The nice thing about the JavaScript option is that it becomes a lot more versatile when you want to play around with the animations a bit.
Thanks,
===EDIT 2014-06-28===
As a demonstration of why the class solution is untidy, please see this fiddle: http://jsfiddle.net/Y9L4x/ (inspired by #BiffMaGriff 's proposed solutin here: http://jsfiddle.net/rte3G/)
The problem is that the elements being flashed could already be CSS-ed up to the hilt with multiple classes.
I recognise that I can remove styling classes first, before applying the "flash" classes, complicate the JavaScript and/or the CSS rules, etc. etc.
But the whole point of looking for a non-class-solution is that this option becomes extremely verbose in a real world situation, and you tend to have to program each flashing object individually, rather than the tidy one-JavaScript-function-fits-all that I'm searching for.
You are going to want to do your styles as classes.
.activated{
background-color: red; //or whatever else
}
and then with your jquery you can just toggle them a few times with the delays I assume you already have in your javascript.
$jq_obj.toggleClass('activated');
Try this:
$jq_obj.attr('style','');
The direct answer to the question appears to be a simple "No".
You cannot tell JavaScript to style an object, and then at a later stage, ask JavaScript to give styling responsibility back to CSS.
However, another messy work-around is to re-draw the HTML inside the element which contains your flashing-object.
$jq_flashing_obj.parent().html(original_html_);
This has the slight overhead of having to wrap your flashing object inside a div or span element, to ensure that the parent element contains nothing but your flashing element.
<div class="multiple-children">
link 1
<span class="wrapper">Click me to watch me flash</span>
link 3
</div>
You then, of course, have to capture the outerHTML of your flashing-object before the flashing starts.
original_html_ = $jq_obj[0].outerHTML;
The resulting JavaScript is a little bit verbose, as you see here: http://jsfiddle.net/CgsLs/ . However, it does have the following benefits:
Reusable on all clickable elements regardles of CSS :hover and other messy styling
Can optionally define the flash-color of the element inside the JS
Independent of CSS, meaning that the code is in one file, and therefore more maintainable
There are down-sides too
Requires the use of JQuery on() function (as opposed to simple click event handler)
Anyhoo... it may not be a solution for everyone. In some cases (maybe even most cases) the class option might be simpler.
But this is one other possible method of tackling this inherent shortcoming in JavaScript/Browser technology.

Adding DOM Elements, what is the Right Way?

This question might be stupid, or basic.
Can someone explain which is the best method in adding DOM elements. We have these two ways of adding DOM elements.
Scenario: Need to add <strong>Hi</strong> inside an existing <div id="theEl"></div>.
By editing the HTML inside them.
document.getElementById("theEl").innerHTML = '<strong>Hi</strong>';
By using document.createElement().
var hi = document.createTextNode("Hi"),
strong = document.createElement("strong");
strong.appendChild(hi);
mydiv = document.getElementById("theEl");
document.body.insertBefore(strong, mydiv);
Questions
What is the best way to do? One is a single line, another is about five lines.
What is the performance aspect?
What is the right way or best practise?
Is there any difference between the codes as a whole?
If at all this question is not making sense, please let me know, I will be glad to close this or even remove this. Thanks.
For the close voter, this is not going to be a duplicate of that question. One thing I just noted is, using createElement() preserves the event handlers attached to the element. Even though that's a good point, any kind of basic web page, too has jQuery in them, which provides delegation and such stuff that allow me to have the event attached to the element even after change in HTML.
There is no "best" or "best practice". They are two different methods of adding content that have different characteristics. Which one you select depends upon your particular circumstance.
For creating lots and lots of elements, setting a block of HTML all at once has generally shown to be faster than creating and inserting lots of individual elements. Though if you really cared about this aspect of performance, you would need to test your particular circumstance in a tool like jsperf.
For creating elements with lots of fine control, setting classes from variables, setting content from variables, etc..., it is generally much easier to do this via createElement() where you have direct access to the properties of each element without having to construct a string.
If you really don't know the difference between the two methods and don't see any obvious reason to use one over the other in a particular circumstance, then use the one that's simpler and less code. That's what I do.
In answer to your specific questions:
There is no "best" way. Select the method that works best for your circumstance.
You will need to test the performance of your specific circumstance. Large amounts of HTML have been shown in some cases to be faster by setting one large string with .innerHTML rather than individually created an inserting all the objects.
There is no "right way" or "best practice. See answer #1.
There need be no difference in the end result created by the two methods if they are coded to create the same end result.
I actually like a combination of both: createElement for the outer element so you won't be removing any event handlers, and innerHTML for the content of that element, for convenience and performance. For example:
var strong = document.createElement('strong');
strong.innerHTML = 'Hi';
document.getElementById('theEl').appendChild(strong);
Of course, this technique is more useful when the content of the thing you're adding is more complex; then you can use innerHTML normally (with the exception of the outer element) but you're not removing any event listeners.
1. What is the best way to do? One is a single line, another is about five lines.
It depends on context. You probably want to use innerHTML sparingly as a rule of thumb.
2. What is the performance aspect?
DOM manipulation significantly outperforms innerHTML, but browsers seem to keep improving innerHTML performance.
3. What is the right way or best practise?
See #1.
4. Is there any difference between the codes as a whole?
Yes. The innerHTML example will replace the contents of the existing element, while the DOM example will put the new element next to the old one. You probably meant to write mydiv.appendChild(strong), but this is still different. The existing element's child nodes are appended to rather than replaced.
What did you mean by best? In just one DOM operation everything is good and shows the same performance. But when you need multiple DOM insertion, things go diferently.
Background
Every time you insert DOM node, the browser render new image of the page. So if you insert multiple child inside a DOM node, the browser renders it multiple times. That operation is the slowest that you will see.
The solution
So, we need to append most child at once. Use a empty dom node. The built in is createDocumentFragment();
var holder = createDocumentFragment();
// append everything in the holder
// append holder to the main dom tree
The real answer
If in the case is that you described, I would prefer the shortest solution. Because there is no performance penalty in one dom operation

Is loose coupling possible for a web app?

I understand that content, presentation, and behavior are supposed to be separated by using HTML, CSS, and JS to implement them independently. Is there a best practice for binding these elements concretely while maintaining loose coupling in a dynamic web app? Is it even possible? Optimally without depending on jQuery?
To clarify what I'm talking about: HTML has no mechanism for the definition of new tags, so when your JavaScript model needs to generate content, the tags and structure for its presentation are necessarily defined in JS or somehow made accessible to it, tightly coupling behavior to content.
Before someone calls over-OOP, the reason I want to keep tags and CSS classes out of JS is that I don't even want to commit to HTML as a front end. There are at least five different representations of my underlying model that I'll eventually want, and tightly coupling the model to HTML rules out at least two of them.
Is there some way to late bind the model to the target representation without sacrificing dynamics or loose coupling? Like an XML document corresponding model elements to template HTML snippets?
UPDATE
Though it seems backward to provide concrete details of a question about factoring and OO best practice, I want to provide a much fresher example of the entanglement of form & function inherent to HTML. The entanglement of content & behavior between HTML and JS is the problem, though, not the example, and I want an answer that doesn't break when I change the details. It's from a very different project than the one I was working when I first asked this question, but the gist is the same:
I have some HTML for a UI widget. It is a view that represents a model object - a selection of palettes - to the user. Palettes themselves are part of the app's task, so they're not view, they're model.
I want to use this widget in at least 2 different dialogs (and any I might want in the future). In one, I need a changed selection to cause immediate action, the recoloring of a set of images in canvas elements that are part of the same dialog. In another, I just need to have two different sets to select from - one selection in each set.
I do not want to copy and paste this widget's HTML form or JS behavior because I want maintenance and revision to propagate from one base thing to all of its instances. Thus, only one instance of the widget, whatever its form may be, may exist in my source.
I do not want to have my JS rendering HTML tags directly because doing so will forfeit my IDE's error checking and content assistance on the HTML. Further, if there are problems with the HTML output, their source in my JS will be less clear because the process of generating the HTML doesn't look like HTML or necessarily reflect its structure. Finally, I want to test the effects of changes to the widget's CSS and HTML independently of my JS.
I do not want to involve additional dependencies e.g. separate templating & parameterization languages in my source because changes to various standards or evolving needs may break their compatibility, or they may themselves become unmaintained, in the future, leaving me with a massive quantity of useless source. Depending on jQuery is okay because it does more for normalizing between browsers (not to mention for convenience) than it is likely to ever break given its ubiquity, but other libraries will be regarded with extreme suspicion.
I want to specify the details of altering and retrieving the widget's state (what colors compose the palettes, how the user chooses among them) in JS that references only the widget and its component parts, since it's going to be a part of multiple dialogs that use its information in different ways.
Simultaneously, other JS code (the dialog's behavior) needs to be able to observe and initialize the widget's state - but without including any specific references to the widget's internal structure, which may some day change to accommodate new features, fix bugs, etc.
For simply making multiple copies of the widget's HTML, I can settle on calling jquery.clone on a template node that exists in an HTML file, and inserting the contents where I need them, from the function that sets up the dialog. HTML makes things difficult when any of the cloned elements have id or name attributes, but careful handling during cloning can make unique identifiers, point their corresponding label elements and href attributes at the new identifiers, and keep the old ones accessible in data attributes. So all is well and good for structure & content, and obviously the CSS presentation propagates to the clone just fine.
The rub comes when I try to implement the widget's interface with its dialog's controller. What is the most future-proof way to expose the widget's state's abstraction? I.e. I don't want to use widgetJquery.find('input:checked').val() to get the selected color from code that doesn't absolutely have to commit to a selection being based on a checked input element whose value attribute is a set of serialized colors.
I hope that makes it more clear what I'm looking for without muddling the question with details.
You can always have different XSLTs parse an XML.
But, it seems you try to abstract tooo much.
use the MVC, use different views to parse.
The methodology you write about is common in old systems, I worked with more than 10 years ago, there is probably a good reason evolution killed it.
Loose coupling is best achieved archtecturally using design patterns. A great example of how to achieve loose coupling is found in the Mediator Pattern. However, there are several patterns to use.
I suggest reading Addy Osmani's 'Essential JavaScript design Patterns' for comprehensive coverage of a range of patterns.
Enjoy!

Categories

Resources