Skip to content
This repository has been archived by the owner on Mar 22, 2019. It is now read-only.

Commit

Permalink
Ember 2.0 status update blog post
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed May 25, 2015
1 parent 57b9dfd commit 3bd5ef6
Show file tree
Hide file tree
Showing 5 changed files with 347 additions and 11 deletions.
110 changes: 106 additions & 4 deletions lib/highlighter.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require "redcarpet"
require "coderay"
require "nokogiri"

module Highlighter
class MissingLanguageError < StandardError; end
class << self
def registered(app)
app.helpers Helpers
Expand All @@ -11,18 +13,118 @@ def registered(app)

module Helpers
def _highlight(string, language, class_name=nil)
error_message = "Code blocks must be fenced with proper language designated. If you don't know what language to use, specify ```text.\n\n"
error_message << "Offending Code Block:\n\n#{string}"

language ||= 'text'
#raise MissingLanguageError, error_message if language.nil?

language, file_name, changes = _detect_language_filename_and_changes(language)

result = %Q{<div class="highlight #{language} #{class_name}">}
result += '<div class="ribbon"></div>'
result += '<div class="scroller">'
code = CodeRay.scan(string, language)
result += code.div css: :class,
line_numbers: :table,
line_number_anchors: false
result += _code_table(string, language, file_name, changes)
result += '</div>'
result += %Q{</div>}
result
end

def _detect_language_filename_and_changes(language)
file_name = nil
changes = []
changes_regex = /\{(.+)\}$/
bare_language_regex = /\A\w+\z/

if change_numbers = changes_regex.match(language)
language = language.sub(changes_regex, '')

changes = _parse_changes(change_numbers[1])
end

unless language =~ bare_language_regex
file_name = language

language = _determine_language(language)
end
[language, file_name, changes]
end

def _determine_language(language)
case /\.(\w+)$/.match(language)[1]
when 'hbs'
'handlebars'
when 'js'
'javascript'
when 'html'
'html'
when 'css'
'css'
when 'json'
'json'
end
end

def _parse_changes(change_numbers)
changes = change_numbers.split(',').map do |change|
state = case change.slice(0)
when '+'
'added'
when '-'
'removed'
else
nil
end

[change.to_i.abs, state]
end
end

def _code_table(string, language, file_name, changes)
code = CodeRay.scan(string, language)

table = code.div css: :class,
line_numbers: :table,
line_number_anchors: false

if file_name.present?

table = table.sub('<table class="CodeRay">', <<-HEADER)
<table class="CodeRay">
<thead>
<tr>
<td colspan="2">#{file_name}</td>
</tr>
</thead>
HEADER
end

_highlight_lines(table, changes)
end

def _highlight_lines(table, highlights)
return table if highlights.empty?

table_xml = Nokogiri.XML(table)

numbers_node = table_xml.at_xpath('//td[@class="line-numbers"]/pre')
code_node = table_xml.at_xpath('//td[@class="code"]/pre')

numbers_contents = numbers_node.inner_html.split("\n")
code_contents = code_node.inner_html.split("\n")

highlights.each do |line_number, state|
index = line_number - 1
numbers_contents[index] = "<span class=\"highlight-line #{state}\">#{numbers_contents[index]}</span>"
code_contents[index] = "<span class=\"highlight-line #{state}\">#{code_contents[index]}</span>"
end

numbers_node.inner_html = numbers_contents.join("\n")
code_node.inner_html = code_contents.join("\n")

table_xml.to_xml
end

def highlight(language, class_name, &block)
concat(_highlight(capture(&block), language, class_name))
end
Expand Down
2 changes: 1 addition & 1 deletion source/blog/2014-12-08-ember-1-9-0-released.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ change does not affect the template syntax or public API of Ember applications.
Projects using an Ember-CLI version less than 0.1.5 will require a bump
of the Handlebars dependency version:

```
```text
bower install --save handlebars#2.0.0
```

Expand Down
130 changes: 130 additions & 0 deletions source/blog/2015-05-24-another-two-oh-status-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
title: Another Ember 2.x Status Update
author: Yehuda Katz
tags: Recent Posts
---

We're just a few weeks away from the release of Ember 1.13 and Ember 2.0 beta, and while there's been a lot of focus on those releases, the trains will keep rolling on June 12. There will be a 2.1 release 6 weeks hence, and a 2.2 release 6 weeks later.

With all of the focus on Ember 2.0, it's easy to forget that 2.0 is just a six-week release, with the added ability to remove some built-up cruft. Because of the symbolic nature of 2.0, discussions about the future have had an artificial end date of June 12, which is now just three weeks away.

This post gives some more details about what cruft will be removed in Ember 2.0, but, since the first features in Ember 2.1 will land in Canary just three weeks hence, what we plan to do in the early releases of Ember 2.x.

It's important to note that we've talked a lot about an improved "Ember 2 programming model" over the past several months, significantly inspired by React. While much of the model will be in place in Ember 2.0, the early releases of Ember 2.x (especially 2.1 and 2.2), will finish up some important features. This blog post details the expected timeline.

Of course, the six-week release cycle means that we ship on a train cycle, so the precise versions of specific features may change before they land in a final release.

## Removals

While we've spent a lot of time talking about the new features that Ember is getting over the next few months, the 2.0 release itself is more about removals and de-cruft-ification.

Some notable examples:

* Context-shifting helpers (`#with item` becomes `#with item as |i|`,
`#each list` becomes `#each list as |item|`)
* Fake block params versions of helpers (`#with foo as bar` becomes
`#with foo as |bar|`, `#each item in list` becomes
`#each list as |item|`)
* The `ArrayPolyfills` and `EnumerableUtils` libraries are being
pulled out into a library; most apps should prefer lodash or other
utility libs.
* In `#each`, the options `itemController`, `itemViewClass`,
`itemView`; superseded by using a component inside the loop
* In `#with`, the `controller` option
* The `Ember.Handlebars` namespace and all of its properties
* `bind-attr`, superseded by just using attributes
* The legacy names `bindAttr` and `linkTo`
* The `{{collection}}` helper
* The `{{template}}` helper; superseded by `{{partial}}`
* The `{{render}}` helper; superseded in most cases by components
* Manually rendering a string into the buffer in a view
* `Ember.Deferred`; superseded by normal promises
* The globals resolver, which will be moved into an external library;
superseded in normal use by the ES6 module resolver

While top-level controllers will not be removed in 2.0 (see more below), we will remove all of the other uses of controllers from templates (such as `#with controller=`, `{{render}}`, `itemController` and others).

In all of these cases, we did significant work in the 1.x series, especially in 1.12 and 1.13, to make sure that the dominant use-cases for these features were addressed by existing or new features.

You can learn about all of the deprecations added in the 1.x era, along with the expected transition to the features that superseded them, in the [1.x deprecations guide][deprecation-guide].

[deprecation-guide]: http://emberjs.com/deprecations/v1.x/

## The Glimmer Engine

The Glimmer engine, with its improved performance and improved support for the "data down, actions up" model, landed in Ember 1.13 beta.

## Fast Re-Render

In Ember 1.12, calling rerender() on a component is an extremely expensive operation, and blows away all of the existing DOM (together with its internal state, such as selection, cursor, focus, scroll position and more).

**In Ember 1.13**, thanks to the Glimmer engine, you can safely invoke rerender() and it will only update the parts of the template that have actually changed.

This allows you to replace an entire data structure with a totally new POJO, rerender the component, and get highly performant updates that preserve the DOM.

## New Lifecycle Hooks

Because `rerender()` is now fast and reliable, any call to `component.set()` will trigger a re-render on the component. When a component re-renders, that may change the attributes of child components, which likewise are re-rendered.

As a result of the fact that `rerender()` is now such an important part of the programming model, **Ember 1.13 beta** got a bunch of new React-inspired lifecycle hooks:

* `didUpdateAttrs`, invoked when a component's attributes have changed
but before the component is rendered.
* `willUpdate`, invoked before a component will rerender, whether
the update was triggered by new attributes or by rerender.
* `didUpdate`, invoked after a component has been rerendered.
* `didReceiveAttrs`, invoked when a component gets attributes, either
initially or due to an update.
* `willRender`, invoked before a component will render, either
initially or due to an update, and regardless of how the rerender
was triggered.
* `didRender`, invoked after a component has been rendered, either
initially or due to an update.

These lifecycle hooks will fire on all components (but not views), regardless of invocation style (both curlies and angle bracket style).

## Angle Bracket Components

Angle bracket components (`<my-component>`) are a very important part of the Ember 2.x programming model. In addition to nicer syntax, they serve as an opt-in for component changes that we could not easily make compatibly, such as default one-way bindings.

We originally thought that angle-bracket components would land in time for Ember 1.13, and they have already landed on Canary, and were included in the first 1.13 beta release.

However, there were some late-breaking concerns, and we have decided to defer this feature so we can write an RFC and go through the regular process. We have already written an implementation of the RFC, which we will land on Canary and keep up to date with the RFC discussions.

Because we are so close to the Ember 2.0 branch point, **this feature is likely to land in Ember 2.1.**

## Routeable Components

The routeable components RFC was first published several months ago, and has been the subject of vigorous discussion. It is one of the most anticipated features of the Ember 2.x programming model.

---

(the following two paragraphs are a bit of insider baseball)

The primary reason to attempt to land this feature in Ember 2.0, despite the fact that its development is at a relatively early stage, was a desire to deprecate controllers for 2.0. In Ember, in order to deprecate a public API, we require an alternate path for all of the use-cases of the old feature. In order to remove a feature in 2.0, it would have needed to be deprecated in 1.13.

Together, that means that in order to remove controllers in 2.0, we needed to land routeable components, the transition from controllers, in 1.13. During the 1.13 canary cycle, it became obvious that removing controllers in 2.0 would be too aggressive, so the pressure to ship Routeable Components exactly in 2.0.0 is less.

---

The work on Routeable Components, as well as work to make it possible to move query parameters fully to routes, is ongoing.

There are less than three weeks left until the 2.0-beta branch point, and given that the feature has not yet landed in Canary (and the importance and magnitude of the feature), it will probably land in 2.1 at the earliest.

**It is extremely likely to land in 2.1, or 2.2 at the latest.**

The Routeable Component feature also includes a change that makes it possible to provide multiple asynchronous attributes to the component you are routing to, rather than just the `model` attribute. The `attrs` hook will run on every transition into the route, in contrast to the `model` hook, which doesn't run again in some cases.

## FastBoot

An early version of the FastBoot feature, suitable for SEO, is already available as an Ember addon that works with Ember 1.12. We expect the addon to work with the final release of 1.13.

Work on rehydrating FastBoot will begin very soon, and we hope to land it in Canary early in the 2.x release cycle.

## Engines

The Engines feature was first proposed as an [RFC][engines-rfc] last year, and work on the feature itself will likely begin very soon.

We expect the Engines feature to land in Canary early in the 2.x release cycle.

[engines-rfc]: https://github.com/tomdale/rfcs/blob/master/active/0000-engines.md
60 changes: 59 additions & 1 deletion source/stylesheets/blog.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,63 @@ article.blog-post {
ul > li {
list-style: disc;
}
}

.chapter {
$h3-indent: 32px;
$body-indent: $h3-indent;

h1 {
padding-bottom: 0.5em;
}

ul, ol {
margin-left: $body-indent;
margin-bottom: 28px;

li {
font-size: 15px;
margin: 10px 0 10px 0;

p {
padding-left: 7px;
}
}
}
}

table {
width: 100%;

margin: 1em 0;
tbody tr{
background: rgba(255, 249, 249, 0.56);
border-bottom: 1px solid rgba(223, 215, 212, 0.28);
}

thead {
background-color: #f9e7e4;
}

th {
font-weight: bold;
}

th, td {
padding: 5px 10px;
}

&.specific {
th, td {
padding: 5px 6px;
}
}
}

.note {
background: rgba(0,0,0, 0.2);

&::before {
content: "Note"
}
}
}
Loading

0 comments on commit 3bd5ef6

Please sign in to comment.