0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-17 23:44:39 -05:00

Merge pull request #2357 from ErisDS/ember-with-proto

[Ember.js] merging prototype
This commit is contained in:
Hannah Wolfe 2014-03-09 20:43:08 +00:00
commit 106ee21cbf
43 changed files with 652 additions and 24 deletions

View file

@ -450,6 +450,9 @@ var path = require('path'),
// ### Config for grunt-contrib-clean
// Clean up files as part of other tasks
clean: {
built: {
src: ['core/built/**']
},
release: {
src: ['<%= paths.releaseBuild %>/**']
},
@ -517,7 +520,7 @@ var path = require('path'),
'bower_components/lodash/dist/lodash.underscore.js',
'bower_components/backbone/backbone.js',
'bower_components/handlebars.js/dist/handlebars.runtime.js',
'bower_components/handlebars/handlebars.runtime.js',
'bower_components/moment/moment.js',
'bower_components/jquery-file-upload/js/jquery.fileupload.js',
'bower_components/codemirror/lib/codemirror.js',
@ -568,9 +571,21 @@ var path = require('path'),
'core/built/scripts/vendor-ember.js': [
'core/client/assets/vendor/loader.js',
'bower_components/jquery/dist/jquery.js',
'bower_components/handlebars.js/dist/handlebars.js',
'bower_components/handlebars/handlebars.js',
'bower_components/ember/ember.js',
'bower_components/ember-resolver/dist/ember-resolver.js'
'bower_components/ember-resolver/dist/ember-resolver.js',
'bower_components/ic-ajax/dist/globals/main.js',
'bower_components/codemirror/lib/codemirror.js',
'bower_components/codemirror/addon/mode/overlay.js',
'bower_components/codemirror/mode/markdown/markdown.js',
'bower_components/codemirror/mode/gfm/gfm.js',
'bower_components/showdown/src/showdown.js',
'core/clientold/assets/lib/showdown/extensions/ghostdown.js',
'core/shared/lib/showdown/extensions/typography.js',
'core/shared/lib/showdown/extensions/github.js',
'bower_components/moment/moment.js'
]
}
},
@ -584,7 +599,7 @@ var path = require('path'),
'bower_components/lodash/dist/lodash.underscore.js',
'bower_components/backbone/backbone.js',
'bower_components/handlebars.js/dist/handlebars.runtime.js',
'bower_components/handlebars/handlebars.runtime.js',
'bower_components/moment/moment.js',
'bower_components/jquery-file-upload/js/jquery.fileupload.js',
'bower_components/codemirror/lib/codemirror.js',

View file

@ -8,6 +8,7 @@
"ember-resolver": "git://github.com/stefanpenner/ember-jj-abrams-resolver.git#9805033c178e7f857f801359664adb599444b430",
"fastclick": "1.0.0",
"handlebars": "~1.1.2",
"ic-ajax": "1.0.1",
"iCheck": "1.0.1",
"jquery": "1.11.0",
"jquery-file-upload": "9.5.6",

View file

@ -1,6 +1,5 @@
/*global Ember */
import Resolver from 'ember/resolver';
import initFixtures from 'ghost/fixtures/init';
var App = Ember.Application.extend({
/**
@ -11,8 +10,10 @@ var App = Ember.Application.extend({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS: true,
modulePrefix: 'ghost', // TODO: loaded via config
modulePrefix: 'ghost',
Resolver: Resolver['default']
});
initFixtures();
export default App;

View file

@ -0,0 +1,44 @@
/* global CodeMirror*/
var onChangeHandler = function (cm) {
cm.component.set('value', cm.getDoc().getValue());
};
var onScrollHandler = function (cm) {
var scrollInfo = cm.getScrollInfo(),
percentage = scrollInfo.top / scrollInfo.height,
component = cm.component;
// throttle scroll updates
component.throttle = Ember.run.throttle(component, function () {
this.set('scrollPosition', percentage);
}, 50);
};
var Codemirror = Ember.TextArea.extend({
initCodemirror: function () {
// create codemirror
this.codemirror = CodeMirror.fromTextArea(this.get('element'), {
lineWrapping: true
});
this.codemirror.component = this; // save reference to this
// propagate changes to value property
this.codemirror.on('change', onChangeHandler);
// on scroll update scrollPosition property
this.codemirror.on('scroll', onScrollHandler);
}.on('didInsertElement'),
removeThrottle: function () {
Ember.run.cancel(this.throttle);
}.on('willDestroyElement'),
removeCodemirrorHandlers: function () {
// not sure if this is needed.
this.codemirror.off('change', onChangeHandler);
this.codemirror.off('scroll', onScrollHandler);
}.on('willDestroyElement')
});
export default Codemirror;

View file

@ -0,0 +1,11 @@
var Markdown = Ember.Component.extend({
adjustScrollPosition: function () {
var scrollWrapper = this.$('.entry-preview-content').get(0),
// calculate absolute scroll position from percentage
scrollPixel = scrollWrapper.scrollHeight * this.get('scrollPosition');
scrollWrapper.scrollTop = scrollPixel; // adjust scroll position
}.observes('scrollPosition')
});
export default Markdown;

View file

@ -1,5 +0,0 @@
export default Ember.Component.extend({
time: function () {
return new Date();
}.property()
});

View file

@ -1,3 +0,0 @@
export default Ember.Controller.extend({
message: 'its a new beginning.'
});

View file

@ -0,0 +1,8 @@
var equal = Ember.computed.equal;
var PostController = Ember.ObjectController.extend({
isPublished: equal('status', 'published'),
isDraft: equal('status', 'draft')
});
export default PostController;

View file

@ -0,0 +1,32 @@
/*global ic */
import postFixtures from 'ghost/fixtures/posts';
var post = function (id) {
return {
response: postFixtures.findBy('id', id),
jqXHR: {},
textStatus: 'success'
};
};
var posts = function () {
return {
response: {
'posts': postFixtures,
'page': 1,
'limit': 15,
'pages': 1,
'total': 2
},
jqXHR: {},
textStatus: 'success'
};
};
var defineFixtures = function () {
ic.ajax.defineFixture('/ghost/api/v0.1/posts', posts());
ic.ajax.defineFixture('/ghost/api/v0.1/posts/1', post(1));
ic.ajax.defineFixture('/ghost/api/v0.1/posts/2', post(2));
};
export default defineFixtures;

View file

@ -0,0 +1,143 @@
var posts = [
{
"id": 2,
"uuid": "4dc16b9e-bf90-44c9-97c5-40a0a81e8297",
"title": "Ghost Ember Demo Post",
"slug": "ghost-ember-demo-post",
"markdown": "Lorem **ipsum** dolor sit amet, consectetur adipiscing elit. Fusce id felis nec est suscipit scelerisque vitae eu arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam erat volutpat. Sed pellentesque metus vel velit tincidunt aliquet. Nunc condimentum tempus convallis. Sed tincidunt, leo et congue blandit, lorem tortor imperdiet sapien, et porttitor turpis nisl sed tellus. In ultrices urna sit amet mauris suscipit adipiscing.",
"html": "<p>Lorem <strong>ipsum<\/strong> dolor sit amet, consectetur adipiscing elit. Fusce id felis nec est suscipit scelerisque vitae eu arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam erat volutpat. Sed pellentesque metus vel velit tincidunt aliquet. Nunc condimentum tempus convallis. Sed tincidunt, leo et congue blandit, lorem tortor imperdiet sapien, et porttitor turpis nisl sed tellus. In ultrices urna sit amet mauris suscipit adipiscing.<\/p>",
"image": null,
"featured": 0,
"page": 0,
"status": "draft",
"language": "en_US",
"meta_title": null,
"meta_description": null,
"author_id": 1,
"created_at": "2014-02-15T23:27:08.000Z",
"created_by": 1,
"updated_at": "2014-02-15T23:27:08.000Z",
"updated_by": 1,
"published_at": null,
"published_by": null,
"author": {
"id": 1,
"uuid": "ba9c67e4-8046-4b8c-9349-0eed3cca7529",
"name": "manuel_mitasch",
"slug": "manuel_mitasch",
"email": "manuel@cms.mine.nu",
"image": null,
"cover": null,
"bio": null,
"website": null,
"location": null,
"accessibility": null,
"status": "active",
"language": "en_US",
"meta_title": null,
"meta_description": null,
"created_at": "2014-02-15T20:02:25.000Z",
"updated_at": "2014-02-15T20:02:25.000Z"
},
"user": {
"id": 1,
"uuid": "ba9c67e4-8046-4b8c-9349-0eed3cca7529",
"name": "manuel_mitasch",
"slug": "manuel_mitasch",
"email": "manuel@cms.mine.nu",
"image": null,
"cover": null,
"bio": null,
"website": null,
"location": null,
"accessibility": null,
"status": "active",
"language": "en_US",
"meta_title": null,
"meta_description": null,
"created_at": "2014-02-15T20:02:25.000Z",
"updated_at": "2014-02-15T20:02:25.000Z"
},
"tags": [
]
},
{
"id": 1,
"uuid": "4b96025d-050c-47ff-8bd4-047e4843b302",
"title": "Welcome to Ghost",
"slug": "welcome-to-ghost",
"markdown": "You're live! Nice. We've put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at `<your blog URL>\/ghost\/`. When you arrive, you can select this post from a list on the left and see a preview of it on the right. Click the little pencil icon at the top of the preview to edit this post and read the next section!\n\n## Getting Started\n\nGhost uses something called Markdown for writing. Essentially, it's a shorthand way to manage your post formatting as you write!\n\nWriting in Markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use *shortcuts* to **style** your content. For example, a list:\n\n* Item number one\n* Item number two\n * A nested item\n* A final item\n\nor with numbers!\n\n1. Remember to buy some milk\n2. Drink the milk\n3. Tweet that I remembered to buy the milk, and drank it\n\n### Links\n\nWant to link to a source? No problem. If you paste in url, like http:\/\/ghost.org - it'll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here's a link to [the Ghost website](http:\/\/ghost.org). Neat.\n\n### What about Images?\n\nImages work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:\n\n![The Ghost Logo](https:\/\/ghost.org\/images\/ghost.png)\n\nNot sure which image you want to use yet? That's ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:\n\n![A bowl of bananas]\n\n\n### Quoting\n\nSometimes a link isn't enough, you want to quote someone on what they've said. It was probably very wisdomous. Is wisdomous a word? Find out in a future release when we introduce spellcheck! For now - it's definitely a word.\n\n> Wisdomous - it's definitely a word.\n\n### Working with Code\n\nGot a streak of geek? We've got you covered there, too. You can write inline `<code>` blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.\n\n .awesome-thing {\n display: block;\n width: 100%;\n }\n\n### Ready for a Break? \n\nThrow 3 or more dashes down on any new line and you've got yourself a fancy new divider. Aw yeah.\n\n---\n\n### Advanced Usage\n\nThere's one fantastic secret about Markdown. If you want, you can write plain old HTML and it'll still work! Very flexible.\n\n<input type=\"text\" placeholder=\"I'm an input field!\" \/>\n\nThat should be enough to get you started. Have fun - and let us know what you think :)",
"html": "<p>You're live! Nice. We've put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at <code>&lt;your blog URL&gt;\/ghost\/<\/code>. When you arrive, you can select this post from a list on the left and see a preview of it on the right. Click the little pencil icon at the top of the preview to edit this post and read the next section!<\/p>\n\n<h2 id=\"gettingstarted\">Getting Started<\/h2>\n\n<p>Ghost uses something called Markdown for writing. Essentially, it's a shorthand way to manage your post formatting as you write!<\/p>\n\n<p>Writing in Markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use <em>shortcuts<\/em> to <strong>style<\/strong> your content. For example, a list:<\/p>\n\n<ul>\n<li>Item number one<\/li>\n<li>Item number two\n<ul><li>A nested item<\/li><\/ul><\/li>\n<li>A final item<\/li>\n<\/ul>\n\n<p>or with numbers!<\/p>\n\n<ol>\n<li>Remember to buy some milk <\/li>\n<li>Drink the milk <\/li>\n<li>Tweet that I remembered to buy the milk, and drank it<\/li>\n<\/ol>\n\n<h3 id=\"links\">Links<\/h3>\n\n<p>Want to link to a source? No problem. If you paste in url, like <a href='http:\/\/ghost.org'>http:\/\/ghost.org<\/a> - it'll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here's a link to <a href=\"http:\/\/ghost.org\">the Ghost website<\/a>. Neat.<\/p>\n\n<h3 id=\"whataboutimages\">What about Images?<\/h3>\n\n<p>Images work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:<\/p>\n\n<p><img src=\"https:\/\/ghost.org\/images\/ghost.png\" alt=\"The Ghost Logo\" \/><\/p>\n\n<p>Not sure which image you want to use yet? That's ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:<\/p>\n\n<h3 id=\"quoting\">Quoting<\/h3>\n\n<p>Sometimes a link isn't enough, you want to quote someone on what they've said. It was probably very wisdomous. Is wisdomous a word? Find out in a future release when we introduce spellcheck! For now - it's definitely a word.<\/p>\n\n<blockquote>\n <p>Wisdomous - it's definitely a word.<\/p>\n<\/blockquote>\n\n<h3 id=\"workingwithcode\">Working with Code<\/h3>\n\n<p>Got a streak of geek? We've got you covered there, too. You can write inline <code>&lt;code&gt;<\/code> blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.<\/p>\n\n<pre><code>.awesome-thing {\n display: block;\n width: 100%;\n}\n<\/code><\/pre>\n\n<h3 id=\"readyforabreak\">Ready for a Break?<\/h3>\n\n<p>Throw 3 or more dashes down on any new line and you've got yourself a fancy new divider. Aw yeah.<\/p>\n\n<hr \/>\n\n<h3 id=\"advancedusage\">Advanced Usage<\/h3>\n\n<p>There's one fantastic secret about Markdown. If you want, you can write plain old HTML and it'll still work! Very flexible.<\/p>\n\n<p><input type=\"text\" placeholder=\"I'm an input field!\" \/><\/p>\n\n<p>That should be enough to get you started. Have fun - and let us know what you think :)<\/p>",
"image": null,
"featured": 0,
"page": 0,
"status": "published",
"language": "en_US",
"meta_title": null,
"meta_description": null,
"author_id": 1,
"created_at": "2014-02-15T20:02:01.000Z",
"created_by": 1,
"updated_at": "2014-02-15T20:02:01.000Z",
"updated_by": 1,
"published_at": "2014-02-15T20:02:01.000Z",
"published_by": 1,
"author": {
"id": 1,
"uuid": "ba9c67e4-8046-4b8c-9349-0eed3cca7529",
"name": "manuel_mitasch",
"slug": "manuel_mitasch",
"email": "manuel@cms.mine.nu",
"image": null,
"cover": null,
"bio": null,
"website": null,
"location": null,
"accessibility": null,
"status": "active",
"language": "en_US",
"meta_title": null,
"meta_description": null,
"created_at": "2014-02-15T20:02:25.000Z",
"updated_at": "2014-02-15T20:02:25.000Z"
},
"user": {
"id": 1,
"uuid": "ba9c67e4-8046-4b8c-9349-0eed3cca7529",
"name": "manuel_mitasch",
"slug": "manuel_mitasch",
"email": "manuel@cms.mine.nu",
"image": null,
"cover": null,
"bio": null,
"website": null,
"location": null,
"accessibility": null,
"status": "active",
"language": "en_US",
"meta_title": null,
"meta_description": null,
"created_at": "2014-02-15T20:02:25.000Z",
"updated_at": "2014-02-15T20:02:25.000Z"
},
"tags": [
{
"id": 1,
"uuid": "406edaaf-5b1c-4199-b297-2af90b1de1a7",
"name": "Getting Started",
"slug": "getting-started",
"description": null,
"parent_id": null,
"meta_title": null,
"meta_description": null,
"created_at": "2014-02-15T20:02:01.000Z",
"created_by": 1,
"updated_at": "2014-02-15T20:02:01.000Z",
"updated_by": 1
}
]
}
];
export default posts;

View file

@ -0,0 +1,7 @@
import count from 'ghost/utils/word-count';
var countWords = Ember.Handlebars.makeBoundHelper(function (markdown) {
return count(markdown);
});
export default countWords;

View file

@ -0,0 +1,8 @@
/* global Showdown, Handlebars */
var showdown = new Showdown.converter();
var formatMarkdown = Ember.Handlebars.makeBoundHelper(function (markdown) {
return new Handlebars.SafeString(showdown.makeHtml(markdown));
});
export default formatMarkdown;

View file

@ -0,0 +1,9 @@
/* global moment */
var formatTimeago = Ember.Handlebars.makeBoundHelper(function (timeago) {
return moment(timeago).fromNow();
// stefanpenner says cool for small number of timeagos.
// For large numbers moment sucks => single Ember.Object based clock better
// https://github.com/manuelmitasch/ghost-admin-ember-demo/commit/fba3ab0a59238290c85d4fa0d7c6ed1be2a8a82e#commitcomment-5396524
});
export default formatTimeago;

View file

@ -0,0 +1,27 @@
// mixin used for routes that need to set a css className on the body tag
var styleBody = Ember.Mixin.create({
activate: function () {
var cssClasses = this.get('classNames');
if (cssClasses) {
Ember.run.schedule('afterRender', null, function () {
cssClasses.forEach(function (curClass) {
Ember.$('body').addClass(curClass);
});
});
}
},
deactivate: function () {
var cssClasses = this.get('classNames');
Ember.run.schedule('afterRender', null, function () {
cssClasses.forEach(function (curClass) {
Ember.$('body').removeClass(curClass);
});
});
}
});
export default styleBody;

View file

@ -0,0 +1,5 @@
var PostModel = Ember.Object.extend({
});
export default PostModel;

View file

@ -3,8 +3,17 @@
// ensure we don't share routes between all Router instances
var Router = Ember.Router.extend();
Router.reopen({
//location: 'history', // use HTML5 History API instead of hash-tag based URLs
rootURL: '/ghost/ember/' // admin interface lives under sub-directory /ghost
});
Router.map(function () {
'use strict';
this.resource('posts', { path: '/' }, function () {
this.route('post', { path: ':post_id' });
});
this.resource('editor', { path: '/editor/:post_id' });
this.route('new', { path: '/editor' });
});
export default Router;

View file

@ -0,0 +1,12 @@
import ajax from 'ghost/utils/ajax';
import styleBody from 'ghost/mixins/style-body';
var EditorRoute = Ember.Route.extend(styleBody, {
classNames: ['editor'],
model: function (params) {
return ajax('/ghost/api/v0.1/posts/' + params.post_id);
}
});
export default EditorRoute;

View file

@ -0,0 +1,20 @@
import ajax from 'ghost/utils/ajax';
import styleBody from 'ghost/mixins/style-body';
var PostsRoute = Ember.Route.extend(styleBody, {
classNames: ['manage'],
model: function () {
return ajax('/ghost/api/v0.1/posts').then(function (response) {
return response.posts;
});
},
actions: {
openEditor: function (post) {
this.transitionTo('editor', post);
}
}
});
export default PostsRoute;

View file

@ -0,0 +1,12 @@
var PostsIndexRoute = Ember.Route.extend({
// redirect to first post subroute
redirect: function () {
var firstPost = (this.modelFor('posts') || []).get('firstObject');
if (firstPost) {
this.transitionTo('posts.post', firstPost);
}
}
});
export default PostsIndexRoute;

View file

@ -0,0 +1,8 @@
/*global ajax */
var PostsPostRoute = Ember.Route.extend({
model: function (params) {
return ajax('/ghost/api/v0.1/posts/' + params.post_id);
}
});
export default PostsPostRoute;

View file

@ -0,0 +1,51 @@
<header class="floatingheader">
<button class="button-back" href="#">Back</button>
<a class="unfeatured" href="#" title="Feature this post">
<span class="hidden">Star</span>
</a>
<small>
<span class="status">Written</span>
<span class="normal">by</span>
<span class="author">{{author.name}}</span>
</small>
<section class="post-controls">
{{#link-to "editor" this class="post-edit" title="Edit Post"}}
<span class="hidden">Edit Post</span>
{{/link-to}}
<a class="post-settings" href="#" data-toggle=".post-settings-menu" title="Post Settings"><span class="hidden">Post Settings</span></a>
<div class="post-settings-menu menu-drop-right overlay" style="display: none;">
<form>
<table class="plain">
<tbody>
<tr class="post-setting">
<td class="post-setting-label">
<label for="url">URL</label>
</td>
<td class="post-setting-field">
<input id="url" class="post-setting-slug" type="text" value="">
</td>
</tr>
<tr class="post-setting">
<td class="post-setting-label">
<label for="pub-date">Pub Date</label>
</td>
<td class="post-setting-field">
<input id="pub-date" class="post-setting-date" type="text" value="" placeholder="17 Feb 14 @ 02:35"><!--<span class="post-setting-calendar"></span>-->
</td>
</tr>
<tr class="post-setting">
<td class="post-setting-label">
<span class="label">Static Page</span>
</td>
<td class="post-setting-item">
<input id="static-page" class="post-setting-static-page" type="checkbox" value="">
<label class="checkbox" for="static-page"></label>
</td>
</tr>
</tbody>
</table>
</form>
<a class="delete" href="#">Delete This Post</a>
</div>
</section>
</header>

View file

@ -0,0 +1,8 @@
<header id="global-header" class="navbar">
<nav id="global-nav" role="navigation">
<ul id="main-menu" >
<li class="content">{{#link-to "posts"}}Content{{/link-to}}</li>
<li class="editor">{{#link-to "new"}}New post{{/link-to}}</li>
</ul>
</nav>
</header>

View file

@ -0,0 +1,58 @@
<footer id="publish-bar">
<nav>
<section id="entry-tags" href="#" class="left">
<label class="tag-label" for="tags" title="Tags"><span class="hidden">Tags</span></label>
<div class="tags">Nothing implemented</div>
<input type="hidden" class="tags-holder" id="tags-holder">
<input class="tag-input" id="tags" type="text" data-input-behaviour="tag" />
<ul class="suggestions overlay"></ul>
</section>
<div class="right">
<section id="entry-controls">
<a class="post-settings" href="#" data-toggle=".post-settings-menu" title="Post Settings"><span class="hidden">Post Settings</span></a>
<div class="post-settings-menu menu-right overlay">
<form>
<table class="plain">
<tr class="post-setting">
<td class="post-setting-label">
<label for="url">URL</label>
</td>
<td class="post-setting-field">
<input id="url" class="post-setting-slug" type="text" placeholder="" value="" />
</td>
</tr>
<tr class="post-setting">
<td class="post-setting-label">
<label for="pub-date">Pub Date</label>
</td>
<td class="post-setting-field">
<input id="pub-date" class="post-setting-date" type="text" placeholder="Now" value=""><!--<span class="post-setting-calendar"></span>-->
</td>
</tr>
<tr class="post-setting">
<td class="post-setting-label">
<span class="label">Static Page</span>
</td>
<td class="post-setting-item">
<input id="static-page" class="post-setting-static-page" type="checkbox" value="">
<label class="checkbox" for="static-page"></label>
</td>
</tr>
</table>
</form>
<a class="delete" href="#">Delete This Post</a>
</div>
</section>
<section id="entry-actions" class="js-publish-splitbutton splitbutton-save">
<button type="button" class="js-publish-button button-save"></button>
<a class="options up" data-toggle="ul" href="#" title="Post Settings"><span class="hidden">Post Settings</span></a>
<ul class="editor-options overlay" style="display:none">
<li data-set-status="published"><a href="#"></a></li>
<li data-set-status="draft"><a href="#"></a></li>
</ul>
</section>
</div>
</nav>
</footer>

8
core/client/templates/application.hbs Executable file → Normal file
View file

@ -1,5 +1,5 @@
<h2 id='title'>Welcome to Ghost on Ember.js</h2>
{{partial "navbar"}}
{{message}}
{{outlet}}
<main role="main" id="main">
{{outlet}}
</main>

View file

@ -0,0 +1,5 @@
<section class="entry-preview-content">
<div class="rendered-markdown">
{{format-markdown markdown}}
</div>
</section>

View file

@ -1 +0,0 @@
Time is now {{time}}

View file

@ -0,0 +1,66 @@
<style>
/* Put your CSS here */
/*
@keyframes domChanged { from { background: yellow; } }
@-webkit-keyframes domChanged { from { background: yellow; } }
.ember-view { animation: domChanged 1s; -webkit-animation: domChanged 1s; }
*/
@font-face {
font-family: "Icons";
src: url("https://testblog111.ghost.io/ghost/fonts/icons.woff") format('woff');
}
/*
Cosmetic changes to ghost styles, that help during development.
The contents should be solved properly or moved into the other assets.
*/
.post-settings-menu {
display: none !important;
}
#entry-markdown, .entry-preview,
.CodeMirror.cm-s-default {
height: 500px !important;
}
.editor .entry-title {
box-shadow: none !important;
background: none !important;
padding: 0 !important;
height: auto !important;
}
.editor input {
-webkit-transition: none;
-moz-transition: none;
transition: none;
}
</style>
<section class="entry-container">
<header>
<section class="box entry-title">
{{input type="text" id="entry-title" placeholder="Your Post Title" value=title tabindex="1"}}
</section>
</header>
<section class="entry-markdown active">
<header class="floatingheader">
<small>Markdown</small>
<a class="markdown-help" href="#"><span class="hidden">What is Markdown?</span></a>
</header>
<section id="entry-markdown-content" class="entry-markdown-content">
{{-codemirror value=markdown scrollPosition=view.scrollPosition}}
</section>
</section>
<section class="entry-preview">
<header class="floatingheader">
<small>Preview <span class="entry-word-count js-entry-word-count">{{count-words markdown}} words</span></small>
</header>
{{-markdown markdown=markdown scrollPosition=view.scrollPosition}}
</section>
</section>
{{partial 'publish-bar'}}

View file

@ -0,0 +1,5 @@
<h1>Sorry, Something went wrong</h1>
{{message}}
<pre>
{{stack}}
</pre>

View file

@ -1,3 +0,0 @@
<em>This is the index route</em>
{{time-now}}

View file

@ -0,0 +1 @@
<h1>Loading...</h1>

View file

@ -0,0 +1 @@
TODO

View file

@ -0,0 +1,36 @@
<section class="content-view-container">
<section class="content-list js-content-list">
<header class="floatingheader">
<section class="content-filter">
<small>All Posts</small>
</section>
{{#link-to "new" class="button button-add" title="New Post"}}New Post{{/link-to}}
</header>
<section class="content-list-content">
<ol class="posts-list">
{{#each itemController="posts/post"}}
{{#view "post-item-view" tagName="li" post=this}} <!-- needed because of "active" class on li item -->
{{#link-to 'posts.post' this class="permalink" title="Edit this post"}}
<h3 class="entry-title">{{title}}</h3>
<section class="entry-meta">
<span class="status">
{{#if isDraft}}
<span class="draft">Draft</span>
{{/if}}
{{#if isPublished}}
<time datetime="{{unbound published_at}}" class="date published">
Published {{format-timeago published_at}}
</time>
{{/if}}
</span>
</section>
{{/link-to}}
{{/view}}
{{/each}}
</ol>
</section>
</section>
<section class="content-preview js-content-preview">
{{outlet}}
</section>
</section>

View file

@ -0,0 +1,8 @@
{{partial "floating-header"}}
<section class="content-preview-content">
<div class="wrapper">
<h1>{{title}}</h1>
{{format-markdown markdown}}
</div>
</section>

View file

@ -0,0 +1,4 @@
/* global ic */
export default window.ajax = function () {
return ic.ajax.request.apply(null, arguments);
};

View file

@ -0,0 +1,6 @@
export default function (s) {
s = s.replace(/(^\s*)|(\s*$)/gi, ""); // exclude start and end white-space
s = s.replace(/[ ]{2,}/gi, " "); // 2 or more space to 1
s = s.replace(/\n /, "\n"); // exclude newline with a start spacing
return s.split(' ').length;
}

View file

@ -0,0 +1,3 @@
export default Ember.View.extend({
scrollPosition: 0 // percentage of scroll position
});

View file

@ -0,0 +1,7 @@
export default Ember.View.extend({
classNameBindings: ['active'],
active: function () {
return this.get('childViews.firstObject.active');
}.property('childViews.firstObject.active')
});

View file

@ -0,0 +1,9 @@
import itemView from 'ghost/views/item-view';
var PostItemView = itemView.extend({
openEditor: function () {
this.get('controller').send('openEditor', this.get('post')); // send action to handle transition to editor route
}.on("doubleClick")
});
export default PostItemView;